forge-openclaw-plugin 0.2.58 → 0.2.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/assets/{board-BAxNp060.js → board-B1V3M__K.js} +1 -2
  2. package/dist/assets/index-BwKAPo98.css +1 -0
  3. package/dist/assets/{index-NZwTuYPs.js → index-Dy7c-dRY.js} +50 -51
  4. package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js +0 -1
  5. package/dist/assets/{motion-B9BeeSmV.js → motion-CltSTItx.js} +1 -2
  6. package/dist/assets/{table-kY1tUKX5.js → table-B-VrSFx8.js} +1 -2
  7. package/dist/assets/{ui-FaWfAb5Q.js → ui-DUqM4jkt.js} +1 -2
  8. package/dist/assets/{vendor-CUxVKN94.js → vendor-C0otBhgu.js} +1 -2
  9. package/dist/gamification-previews/dark-fantasy-mascot.webp +0 -0
  10. package/dist/gamification-previews/dramatic-smithie-mascot.webp +0 -0
  11. package/dist/gamification-previews/mind-locksmith-mascot.webp +0 -0
  12. package/dist/index.html +7 -7
  13. package/dist/server/server/migrations/058_gamification_theme_preference.sql +1 -1
  14. package/dist/server/server/src/app.js +27 -0
  15. package/dist/server/server/src/repositories/settings.js +1 -1
  16. package/dist/server/server/src/services/gamification-assets.js +231 -0
  17. package/dist/server/server/src/types.js +1 -1
  18. package/dist/server/server/src/web.js +15 -2
  19. package/dist/server/src/lib/api.js +9 -0
  20. package/dist/server/src/lib/schemas.js +1 -1
  21. package/openclaw.plugin.json +1 -1
  22. package/package.json +1 -1
  23. package/server/index.js +1 -0
  24. package/server/migrations/058_gamification_theme_preference.sql +1 -1
  25. package/dist/assets/board-BAxNp060.js.map +0 -1
  26. package/dist/assets/index-B5Yt4i07.css +0 -1
  27. package/dist/assets/index-NZwTuYPs.js.map +0 -1
  28. package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js.map +0 -1
  29. package/dist/assets/motion-B9BeeSmV.js.map +0 -1
  30. package/dist/assets/table-kY1tUKX5.js.map +0 -1
  31. package/dist/assets/ui-FaWfAb5Q.js.map +0 -1
  32. package/dist/assets/vendor-CUxVKN94.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import{r as j}from"./vendor-CUxVKN94.js";/**
1
+ import{r as j}from"./vendor-C0otBhgu.js";/**
2
2
  * table-core
3
3
  *
4
4
  * Copyright (c) TanStack
@@ -20,4 +20,3 @@ import{r as j}from"./vendor-CUxVKN94.js";/**
20
20
  *
21
21
  * @license MIT
22
22
  */function ut(e,o){return e?tt(e)?j.createElement(e,o):e:null}function tt(e){return nt(e)||typeof e=="function"||ot(e)}function nt(e){return typeof e=="function"&&(()=>{const o=Object.getPrototypeOf(e);return o.prototype&&o.prototype.isReactComponent})()}function ot(e){return typeof e=="object"&&typeof e.$$typeof=="symbol"&&["react.memo","react.forward_ref"].includes(e.$$typeof.description)}function st(e){const o={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[t]=j.useState(()=>({current:et(o)})),[n,i]=j.useState(()=>t.current.initialState);return t.current.setOptions(r=>({...r,...e,state:{...n,...e.state},onStateChange:l=>{i(l),e.onStateChange==null||e.onStateChange(l)}})),t.current}export{rt as c,ut as f,lt as g,st as u};
23
- //# sourceMappingURL=table-kY1tUKX5.js.map
@@ -1,4 +1,4 @@
1
- import{r as a,j as g,b as Ce,a as Qe,c as Je,d as et,_ as tt,u as nt,e as _,s as Se,f as rt,g as ot,h as at}from"./vendor-CUxVKN94.js";function O(e,t,{checkForDefaultPrevented:n=!0}={}){return function(o){if(e==null||e(o),n===!1||!o.defaultPrevented)return t==null?void 0:t(o)}}function ue(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function Re(...e){return t=>{let n=!1;const r=e.map(o=>{const i=ue(o,t);return!n&&typeof i=="function"&&(n=!0),i});if(n)return()=>{for(let o=0;o<r.length;o++){const i=r[o];typeof i=="function"?i():ue(e[o],null)}}}}function I(...e){return a.useCallback(Re(...e),e)}function it(e,t){const n=a.createContext(t),r=i=>{const{children:c,...s}=i,d=a.useMemo(()=>s,Object.values(s));return g.jsx(n.Provider,{value:d,children:c})};r.displayName=e+"Provider";function o(i){const c=a.useContext(n);if(c)return c;if(t!==void 0)return t;throw new Error(`\`${i}\` must be used within \`${e}\``)}return[r,o]}function st(e,t=[]){let n=[];function r(i,c){const s=a.createContext(c),d=n.length;n=[...n,c];const l=v=>{var E;const{scope:h,children:p,...R}=v,u=((E=h==null?void 0:h[e])==null?void 0:E[d])||s,m=a.useMemo(()=>R,Object.values(R));return g.jsx(u.Provider,{value:m,children:p})};l.displayName=i+"Provider";function f(v,h){var u;const p=((u=h==null?void 0:h[e])==null?void 0:u[d])||s,R=a.useContext(p);if(R)return R;if(c!==void 0)return c;throw new Error(`\`${v}\` must be used within \`${i}\``)}return[l,f]}const o=()=>{const i=n.map(c=>a.createContext(c));return function(s){const d=(s==null?void 0:s[e])||i;return a.useMemo(()=>({[`__scope${e}`]:{...s,[e]:d}}),[s,d])}};return o.scopeName=e,[r,ct(o,...t)]}function ct(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const r=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(i){const c=r.reduce((s,{useScope:d,scopeName:l})=>{const v=d(i)[`__scope${l}`];return{...s,...v}},{});return a.useMemo(()=>({[`__scope${t.scopeName}`]:c}),[c])}};return n.scopeName=t.scopeName,n}var j=globalThis!=null&&globalThis.document?a.useLayoutEffect:()=>{},ut=Ce[" useId ".trim().toString()]||(()=>{}),lt=0;function q(e){const[t,n]=a.useState(ut());return j(()=>{n(r=>r??String(lt++))},[e]),e||(t?`radix-${t}`:"")}var dt=Ce[" useInsertionEffect ".trim().toString()]||j;function ft({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){const[o,i,c]=vt({defaultProp:t,onChange:n}),s=e!==void 0,d=s?e:o;{const f=a.useRef(e!==void 0);a.useEffect(()=>{const v=f.current;v!==s&&console.warn(`${r} is changing from ${v?"controlled":"uncontrolled"} to ${s?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=s},[s,r])}const l=a.useCallback(f=>{var v;if(s){const h=mt(f)?f(e):f;h!==e&&((v=c.current)==null||v.call(c,h))}else i(f)},[s,e,i,c]);return[d,l]}function vt({defaultProp:e,onChange:t}){const[n,r]=a.useState(e),o=a.useRef(n),i=a.useRef(t);return dt(()=>{i.current=t},[t]),a.useEffect(()=>{var c;o.current!==n&&((c=i.current)==null||c.call(i,n),o.current=n)},[n,o]),[n,r,i]}function mt(e){return typeof e=="function"}function we(e){const t=gt(e),n=a.forwardRef((r,o)=>{const{children:i,...c}=r,s=a.Children.toArray(i),d=s.find(pt);if(d){const l=d.props.children,f=s.map(v=>v===d?a.Children.count(l)>1?a.Children.only(null):a.isValidElement(l)?l.props.children:null:v);return g.jsx(t,{...c,ref:o,children:a.isValidElement(l)?a.cloneElement(l,void 0,f):null})}return g.jsx(t,{...c,ref:o,children:i})});return n.displayName=`${e}.Slot`,n}function gt(e){const t=a.forwardRef((n,r)=>{const{children:o,...i}=n;if(a.isValidElement(o)){const c=yt(o),s=Et(i,o.props);return o.type!==a.Fragment&&(s.ref=r?Re(r,c):c),a.cloneElement(o,s)}return a.Children.count(o)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var ht=Symbol("radix.slottable");function pt(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===ht}function Et(e,t){const n={...t};for(const r in t){const o=e[r],i=t[r];/^on[A-Z]/.test(r)?o&&i?n[r]=(...s)=>{const d=i(...s);return o(...s),d}:o&&(n[r]=o):r==="style"?n[r]={...o,...i}:r==="className"&&(n[r]=[o,i].filter(Boolean).join(" "))}return{...e,...n}}function yt(e){var r,o;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(o=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:o.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var bt=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],D=bt.reduce((e,t)=>{const n=we(`Primitive.${t}`),r=a.forwardRef((o,i)=>{const{asChild:c,...s}=o,d=c?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),g.jsx(d,{...s,ref:i})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function Ct(e,t){e&&Qe.flushSync(()=>e.dispatchEvent(t))}function B(e){const t=a.useRef(e);return a.useEffect(()=>{t.current=e}),a.useMemo(()=>(...n)=>{var r;return(r=t.current)==null?void 0:r.call(t,...n)},[])}function St(e,t=globalThis==null?void 0:globalThis.document){const n=B(e);a.useEffect(()=>{const r=o=>{o.key==="Escape"&&n(o)};return t.addEventListener("keydown",r,{capture:!0}),()=>t.removeEventListener("keydown",r,{capture:!0})},[n,t])}var Rt="DismissableLayer",re="dismissableLayer.update",wt="dismissableLayer.pointerDownOutside",Pt="dismissableLayer.focusOutside",le,Pe=a.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),Ne=a.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:o,onFocusOutside:i,onInteractOutside:c,onDismiss:s,...d}=e,l=a.useContext(Pe),[f,v]=a.useState(null),h=(f==null?void 0:f.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,p]=a.useState({}),R=I(t,y=>v(y)),u=Array.from(l.layers),[m]=[...l.layersWithOutsidePointerEventsDisabled].slice(-1),E=u.indexOf(m),b=f?u.indexOf(f):-1,C=l.layersWithOutsidePointerEventsDisabled.size>0,S=b>=E,w=xt(y=>{const T=y.target,L=[...l.branches].some(W=>W.contains(T));!S||L||(o==null||o(y),c==null||c(y),y.defaultPrevented||s==null||s())},h),P=Ot(y=>{const T=y.target;[...l.branches].some(W=>W.contains(T))||(i==null||i(y),c==null||c(y),y.defaultPrevented||s==null||s())},h);return St(y=>{b===l.layers.size-1&&(r==null||r(y),!y.defaultPrevented&&s&&(y.preventDefault(),s()))},h),a.useEffect(()=>{if(f)return n&&(l.layersWithOutsidePointerEventsDisabled.size===0&&(le=h.body.style.pointerEvents,h.body.style.pointerEvents="none"),l.layersWithOutsidePointerEventsDisabled.add(f)),l.layers.add(f),de(),()=>{n&&l.layersWithOutsidePointerEventsDisabled.size===1&&(h.body.style.pointerEvents=le)}},[f,h,n,l]),a.useEffect(()=>()=>{f&&(l.layers.delete(f),l.layersWithOutsidePointerEventsDisabled.delete(f),de())},[f,l]),a.useEffect(()=>{const y=()=>p({});return document.addEventListener(re,y),()=>document.removeEventListener(re,y)},[]),g.jsx(D.div,{...d,ref:R,style:{pointerEvents:C?S?"auto":"none":void 0,...e.style},onFocusCapture:O(e.onFocusCapture,P.onFocusCapture),onBlurCapture:O(e.onBlurCapture,P.onBlurCapture),onPointerDownCapture:O(e.onPointerDownCapture,w.onPointerDownCapture)})});Ne.displayName=Rt;var Nt="DismissableLayerBranch",Dt=a.forwardRef((e,t)=>{const n=a.useContext(Pe),r=a.useRef(null),o=I(t,r);return a.useEffect(()=>{const i=r.current;if(i)return n.branches.add(i),()=>{n.branches.delete(i)}},[n.branches]),g.jsx(D.div,{...e,ref:o})});Dt.displayName=Nt;function xt(e,t=globalThis==null?void 0:globalThis.document){const n=B(e),r=a.useRef(!1),o=a.useRef(()=>{});return a.useEffect(()=>{const i=s=>{if(s.target&&!r.current){let d=function(){De(wt,n,l,{discrete:!0})};const l={originalEvent:s};s.pointerType==="touch"?(t.removeEventListener("click",o.current),o.current=d,t.addEventListener("click",o.current,{once:!0})):d()}else t.removeEventListener("click",o.current);r.current=!1},c=window.setTimeout(()=>{t.addEventListener("pointerdown",i)},0);return()=>{window.clearTimeout(c),t.removeEventListener("pointerdown",i),t.removeEventListener("click",o.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function Ot(e,t=globalThis==null?void 0:globalThis.document){const n=B(e),r=a.useRef(!1);return a.useEffect(()=>{const o=i=>{i.target&&!r.current&&De(Pt,n,{originalEvent:i},{discrete:!1})};return t.addEventListener("focusin",o),()=>t.removeEventListener("focusin",o)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function de(){const e=new CustomEvent(re);document.dispatchEvent(e)}function De(e,t,n,{discrete:r}){const o=n.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&o.addEventListener(e,t,{once:!0}),r?Ct(o,i):o.dispatchEvent(i)}var Q="focusScope.autoFocusOnMount",J="focusScope.autoFocusOnUnmount",fe={bubbles:!1,cancelable:!0},Tt="FocusScope",xe=a.forwardRef((e,t)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:o,onUnmountAutoFocus:i,...c}=e,[s,d]=a.useState(null),l=B(o),f=B(i),v=a.useRef(null),h=I(t,u=>d(u)),p=a.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;a.useEffect(()=>{if(r){let u=function(C){if(p.paused||!s)return;const S=C.target;s.contains(S)?v.current=S:x(v.current,{select:!0})},m=function(C){if(p.paused||!s)return;const S=C.relatedTarget;S!==null&&(s.contains(S)||x(v.current,{select:!0}))},E=function(C){if(document.activeElement===document.body)for(const w of C)w.removedNodes.length>0&&x(s)};document.addEventListener("focusin",u),document.addEventListener("focusout",m);const b=new MutationObserver(E);return s&&b.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",u),document.removeEventListener("focusout",m),b.disconnect()}}},[r,s,p.paused]),a.useEffect(()=>{if(s){me.add(p);const u=document.activeElement;if(!s.contains(u)){const E=new CustomEvent(Q,fe);s.addEventListener(Q,l),s.dispatchEvent(E),E.defaultPrevented||(At(_t(Oe(s)),{select:!0}),document.activeElement===u&&x(s))}return()=>{s.removeEventListener(Q,l),setTimeout(()=>{const E=new CustomEvent(J,fe);s.addEventListener(J,f),s.dispatchEvent(E),E.defaultPrevented||x(u??document.body,{select:!0}),s.removeEventListener(J,f),me.remove(p)},0)}}},[s,l,f,p]);const R=a.useCallback(u=>{if(!n&&!r||p.paused)return;const m=u.key==="Tab"&&!u.altKey&&!u.ctrlKey&&!u.metaKey,E=document.activeElement;if(m&&E){const b=u.currentTarget,[C,S]=It(b);C&&S?!u.shiftKey&&E===S?(u.preventDefault(),n&&x(C,{select:!0})):u.shiftKey&&E===C&&(u.preventDefault(),n&&x(S,{select:!0})):E===b&&u.preventDefault()}},[n,r,p.paused]);return g.jsx(D.div,{tabIndex:-1,...c,ref:h,onKeyDown:R})});xe.displayName=Tt;function At(e,{select:t=!1}={}){const n=document.activeElement;for(const r of e)if(x(r,{select:t}),document.activeElement!==n)return}function It(e){const t=Oe(e),n=ve(t,e),r=ve(t.reverse(),e);return[n,r]}function Oe(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const o=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||o?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function ve(e,t){for(const n of e)if(!Lt(n,{upTo:t}))return n}function Lt(e,{upTo:t}){if(getComputedStyle(e).visibility==="hidden")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display==="none")return!0;e=e.parentElement}return!1}function Mt(e){return e instanceof HTMLInputElement&&"select"in e}function x(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&Mt(e)&&t&&e.select()}}var me=Ft();function Ft(){let e=[];return{add(t){const n=e[0];t!==n&&(n==null||n.pause()),e=ge(e,t),e.unshift(t)},remove(t){var n;e=ge(e,t),(n=e[0])==null||n.resume()}}}function ge(e,t){const n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function _t(e){return e.filter(t=>t.tagName!=="A")}var kt="Portal",Te=a.forwardRef((e,t)=>{var s;const{container:n,...r}=e,[o,i]=a.useState(!1);j(()=>i(!0),[]);const c=n||o&&((s=globalThis==null?void 0:globalThis.document)==null?void 0:s.body);return c?Je.createPortal(g.jsx(D.div,{...r,ref:t}),c):null});Te.displayName=kt;function Wt(e,t){return a.useReducer((n,r)=>t[n][r]??n,e)}var H=e=>{const{present:t,children:n}=e,r=jt(t),o=typeof n=="function"?n({present:r.isPresent}):a.Children.only(n),i=I(r.ref,Bt(o));return typeof n=="function"||r.isPresent?a.cloneElement(o,{ref:i}):null};H.displayName="Presence";function jt(e){const[t,n]=a.useState(),r=a.useRef(null),o=a.useRef(e),i=a.useRef("none"),c=e?"mounted":"unmounted",[s,d]=Wt(c,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return a.useEffect(()=>{const l=$(r.current);i.current=s==="mounted"?l:"none"},[s]),j(()=>{const l=r.current,f=o.current;if(f!==e){const h=i.current,p=$(l);e?d("MOUNT"):p==="none"||(l==null?void 0:l.display)==="none"?d("UNMOUNT"):d(f&&h!==p?"ANIMATION_OUT":"UNMOUNT"),o.current=e}},[e,d]),j(()=>{if(t){let l;const f=t.ownerDocument.defaultView??window,v=p=>{const u=$(r.current).includes(CSS.escape(p.animationName));if(p.target===t&&u&&(d("ANIMATION_END"),!o.current)){const m=t.style.animationFillMode;t.style.animationFillMode="forwards",l=f.setTimeout(()=>{t.style.animationFillMode==="forwards"&&(t.style.animationFillMode=m)})}},h=p=>{p.target===t&&(i.current=$(r.current))};return t.addEventListener("animationstart",h),t.addEventListener("animationcancel",v),t.addEventListener("animationend",v),()=>{f.clearTimeout(l),t.removeEventListener("animationstart",h),t.removeEventListener("animationcancel",v),t.removeEventListener("animationend",v)}}else d("ANIMATION_END")},[t,d]),{isPresent:["mounted","unmountSuspended"].includes(s),ref:a.useCallback(l=>{r.current=l?getComputedStyle(l):null,n(l)},[])}}function $(e){return(e==null?void 0:e.animationName)||"none"}function Bt(e){var r,o;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(o=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:o.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var ee=0;function Ut(){a.useEffect(()=>{const e=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",e[0]??he()),document.body.insertAdjacentElement("beforeend",e[1]??he()),ee++,()=>{ee===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(t=>t.remove()),ee--}},[])}function he(){const e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}var G="right-scroll-bar-position",Y="width-before-scroll-bar",$t="with-scroll-bars-hidden",Vt="--removed-body-scroll-bar-size",Ae=et(),te=function(){},z=a.forwardRef(function(e,t){var n=a.useRef(null),r=a.useState({onScrollCapture:te,onWheelCapture:te,onTouchMoveCapture:te}),o=r[0],i=r[1],c=e.forwardProps,s=e.children,d=e.className,l=e.removeScrollBar,f=e.enabled,v=e.shards,h=e.sideCar,p=e.noRelative,R=e.noIsolation,u=e.inert,m=e.allowPinchZoom,E=e.as,b=E===void 0?"div":E,C=e.gapMode,S=tt(e,["forwardProps","children","className","removeScrollBar","enabled","shards","sideCar","noRelative","noIsolation","inert","allowPinchZoom","as","gapMode"]),w=h,P=nt([n,t]),y=_(_({},S),o);return a.createElement(a.Fragment,null,f&&a.createElement(w,{sideCar:Ae,removeScrollBar:l,shards:v,noRelative:p,noIsolation:R,inert:u,setCallbacks:i,allowPinchZoom:!!m,lockRef:n,gapMode:C}),c?a.cloneElement(a.Children.only(s),_(_({},y),{ref:P})):a.createElement(b,_({},y,{className:d,ref:P}),s))});z.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1};z.classNames={fullWidth:Y,zeroRight:G};var Kt={left:0,top:0,right:0,gap:0},ne=function(e){return parseInt(e||"",10)||0},Gt=function(e){var t=window.getComputedStyle(document.body),n=t[e==="padding"?"paddingLeft":"marginLeft"],r=t[e==="padding"?"paddingTop":"marginTop"],o=t[e==="padding"?"paddingRight":"marginRight"];return[ne(n),ne(r),ne(o)]},Yt=function(e){if(e===void 0&&(e="margin"),typeof window>"u")return Kt;var t=Gt(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Xt=Se(),k="data-scroll-locked",Ht=function(e,t,n,r){var o=e.left,i=e.top,c=e.right,s=e.gap;return n===void 0&&(n="margin"),`
1
+ import{r as a,j as g,b as Ce,a as Qe,c as Je,d as et,_ as tt,u as nt,e as _,s as Se,f as rt,g as ot,h as at}from"./vendor-C0otBhgu.js";function O(e,t,{checkForDefaultPrevented:n=!0}={}){return function(o){if(e==null||e(o),n===!1||!o.defaultPrevented)return t==null?void 0:t(o)}}function ue(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function Re(...e){return t=>{let n=!1;const r=e.map(o=>{const i=ue(o,t);return!n&&typeof i=="function"&&(n=!0),i});if(n)return()=>{for(let o=0;o<r.length;o++){const i=r[o];typeof i=="function"?i():ue(e[o],null)}}}}function I(...e){return a.useCallback(Re(...e),e)}function it(e,t){const n=a.createContext(t),r=i=>{const{children:c,...s}=i,d=a.useMemo(()=>s,Object.values(s));return g.jsx(n.Provider,{value:d,children:c})};r.displayName=e+"Provider";function o(i){const c=a.useContext(n);if(c)return c;if(t!==void 0)return t;throw new Error(`\`${i}\` must be used within \`${e}\``)}return[r,o]}function st(e,t=[]){let n=[];function r(i,c){const s=a.createContext(c),d=n.length;n=[...n,c];const l=v=>{var E;const{scope:h,children:p,...R}=v,u=((E=h==null?void 0:h[e])==null?void 0:E[d])||s,m=a.useMemo(()=>R,Object.values(R));return g.jsx(u.Provider,{value:m,children:p})};l.displayName=i+"Provider";function f(v,h){var u;const p=((u=h==null?void 0:h[e])==null?void 0:u[d])||s,R=a.useContext(p);if(R)return R;if(c!==void 0)return c;throw new Error(`\`${v}\` must be used within \`${i}\``)}return[l,f]}const o=()=>{const i=n.map(c=>a.createContext(c));return function(s){const d=(s==null?void 0:s[e])||i;return a.useMemo(()=>({[`__scope${e}`]:{...s,[e]:d}}),[s,d])}};return o.scopeName=e,[r,ct(o,...t)]}function ct(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const r=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(i){const c=r.reduce((s,{useScope:d,scopeName:l})=>{const v=d(i)[`__scope${l}`];return{...s,...v}},{});return a.useMemo(()=>({[`__scope${t.scopeName}`]:c}),[c])}};return n.scopeName=t.scopeName,n}var j=globalThis!=null&&globalThis.document?a.useLayoutEffect:()=>{},ut=Ce[" useId ".trim().toString()]||(()=>{}),lt=0;function q(e){const[t,n]=a.useState(ut());return j(()=>{n(r=>r??String(lt++))},[e]),e||(t?`radix-${t}`:"")}var dt=Ce[" useInsertionEffect ".trim().toString()]||j;function ft({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){const[o,i,c]=vt({defaultProp:t,onChange:n}),s=e!==void 0,d=s?e:o;{const f=a.useRef(e!==void 0);a.useEffect(()=>{const v=f.current;v!==s&&console.warn(`${r} is changing from ${v?"controlled":"uncontrolled"} to ${s?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=s},[s,r])}const l=a.useCallback(f=>{var v;if(s){const h=mt(f)?f(e):f;h!==e&&((v=c.current)==null||v.call(c,h))}else i(f)},[s,e,i,c]);return[d,l]}function vt({defaultProp:e,onChange:t}){const[n,r]=a.useState(e),o=a.useRef(n),i=a.useRef(t);return dt(()=>{i.current=t},[t]),a.useEffect(()=>{var c;o.current!==n&&((c=i.current)==null||c.call(i,n),o.current=n)},[n,o]),[n,r,i]}function mt(e){return typeof e=="function"}function we(e){const t=gt(e),n=a.forwardRef((r,o)=>{const{children:i,...c}=r,s=a.Children.toArray(i),d=s.find(pt);if(d){const l=d.props.children,f=s.map(v=>v===d?a.Children.count(l)>1?a.Children.only(null):a.isValidElement(l)?l.props.children:null:v);return g.jsx(t,{...c,ref:o,children:a.isValidElement(l)?a.cloneElement(l,void 0,f):null})}return g.jsx(t,{...c,ref:o,children:i})});return n.displayName=`${e}.Slot`,n}function gt(e){const t=a.forwardRef((n,r)=>{const{children:o,...i}=n;if(a.isValidElement(o)){const c=yt(o),s=Et(i,o.props);return o.type!==a.Fragment&&(s.ref=r?Re(r,c):c),a.cloneElement(o,s)}return a.Children.count(o)>1?a.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var ht=Symbol("radix.slottable");function pt(e){return a.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===ht}function Et(e,t){const n={...t};for(const r in t){const o=e[r],i=t[r];/^on[A-Z]/.test(r)?o&&i?n[r]=(...s)=>{const d=i(...s);return o(...s),d}:o&&(n[r]=o):r==="style"?n[r]={...o,...i}:r==="className"&&(n[r]=[o,i].filter(Boolean).join(" "))}return{...e,...n}}function yt(e){var r,o;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(o=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:o.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var bt=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],D=bt.reduce((e,t)=>{const n=we(`Primitive.${t}`),r=a.forwardRef((o,i)=>{const{asChild:c,...s}=o,d=c?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),g.jsx(d,{...s,ref:i})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function Ct(e,t){e&&Qe.flushSync(()=>e.dispatchEvent(t))}function B(e){const t=a.useRef(e);return a.useEffect(()=>{t.current=e}),a.useMemo(()=>(...n)=>{var r;return(r=t.current)==null?void 0:r.call(t,...n)},[])}function St(e,t=globalThis==null?void 0:globalThis.document){const n=B(e);a.useEffect(()=>{const r=o=>{o.key==="Escape"&&n(o)};return t.addEventListener("keydown",r,{capture:!0}),()=>t.removeEventListener("keydown",r,{capture:!0})},[n,t])}var Rt="DismissableLayer",re="dismissableLayer.update",wt="dismissableLayer.pointerDownOutside",Pt="dismissableLayer.focusOutside",le,Pe=a.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),Ne=a.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:o,onFocusOutside:i,onInteractOutside:c,onDismiss:s,...d}=e,l=a.useContext(Pe),[f,v]=a.useState(null),h=(f==null?void 0:f.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,p]=a.useState({}),R=I(t,y=>v(y)),u=Array.from(l.layers),[m]=[...l.layersWithOutsidePointerEventsDisabled].slice(-1),E=u.indexOf(m),b=f?u.indexOf(f):-1,C=l.layersWithOutsidePointerEventsDisabled.size>0,S=b>=E,w=xt(y=>{const T=y.target,L=[...l.branches].some(W=>W.contains(T));!S||L||(o==null||o(y),c==null||c(y),y.defaultPrevented||s==null||s())},h),P=Ot(y=>{const T=y.target;[...l.branches].some(W=>W.contains(T))||(i==null||i(y),c==null||c(y),y.defaultPrevented||s==null||s())},h);return St(y=>{b===l.layers.size-1&&(r==null||r(y),!y.defaultPrevented&&s&&(y.preventDefault(),s()))},h),a.useEffect(()=>{if(f)return n&&(l.layersWithOutsidePointerEventsDisabled.size===0&&(le=h.body.style.pointerEvents,h.body.style.pointerEvents="none"),l.layersWithOutsidePointerEventsDisabled.add(f)),l.layers.add(f),de(),()=>{n&&l.layersWithOutsidePointerEventsDisabled.size===1&&(h.body.style.pointerEvents=le)}},[f,h,n,l]),a.useEffect(()=>()=>{f&&(l.layers.delete(f),l.layersWithOutsidePointerEventsDisabled.delete(f),de())},[f,l]),a.useEffect(()=>{const y=()=>p({});return document.addEventListener(re,y),()=>document.removeEventListener(re,y)},[]),g.jsx(D.div,{...d,ref:R,style:{pointerEvents:C?S?"auto":"none":void 0,...e.style},onFocusCapture:O(e.onFocusCapture,P.onFocusCapture),onBlurCapture:O(e.onBlurCapture,P.onBlurCapture),onPointerDownCapture:O(e.onPointerDownCapture,w.onPointerDownCapture)})});Ne.displayName=Rt;var Nt="DismissableLayerBranch",Dt=a.forwardRef((e,t)=>{const n=a.useContext(Pe),r=a.useRef(null),o=I(t,r);return a.useEffect(()=>{const i=r.current;if(i)return n.branches.add(i),()=>{n.branches.delete(i)}},[n.branches]),g.jsx(D.div,{...e,ref:o})});Dt.displayName=Nt;function xt(e,t=globalThis==null?void 0:globalThis.document){const n=B(e),r=a.useRef(!1),o=a.useRef(()=>{});return a.useEffect(()=>{const i=s=>{if(s.target&&!r.current){let d=function(){De(wt,n,l,{discrete:!0})};const l={originalEvent:s};s.pointerType==="touch"?(t.removeEventListener("click",o.current),o.current=d,t.addEventListener("click",o.current,{once:!0})):d()}else t.removeEventListener("click",o.current);r.current=!1},c=window.setTimeout(()=>{t.addEventListener("pointerdown",i)},0);return()=>{window.clearTimeout(c),t.removeEventListener("pointerdown",i),t.removeEventListener("click",o.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function Ot(e,t=globalThis==null?void 0:globalThis.document){const n=B(e),r=a.useRef(!1);return a.useEffect(()=>{const o=i=>{i.target&&!r.current&&De(Pt,n,{originalEvent:i},{discrete:!1})};return t.addEventListener("focusin",o),()=>t.removeEventListener("focusin",o)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function de(){const e=new CustomEvent(re);document.dispatchEvent(e)}function De(e,t,n,{discrete:r}){const o=n.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&o.addEventListener(e,t,{once:!0}),r?Ct(o,i):o.dispatchEvent(i)}var Q="focusScope.autoFocusOnMount",J="focusScope.autoFocusOnUnmount",fe={bubbles:!1,cancelable:!0},Tt="FocusScope",xe=a.forwardRef((e,t)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:o,onUnmountAutoFocus:i,...c}=e,[s,d]=a.useState(null),l=B(o),f=B(i),v=a.useRef(null),h=I(t,u=>d(u)),p=a.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;a.useEffect(()=>{if(r){let u=function(C){if(p.paused||!s)return;const S=C.target;s.contains(S)?v.current=S:x(v.current,{select:!0})},m=function(C){if(p.paused||!s)return;const S=C.relatedTarget;S!==null&&(s.contains(S)||x(v.current,{select:!0}))},E=function(C){if(document.activeElement===document.body)for(const w of C)w.removedNodes.length>0&&x(s)};document.addEventListener("focusin",u),document.addEventListener("focusout",m);const b=new MutationObserver(E);return s&&b.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",u),document.removeEventListener("focusout",m),b.disconnect()}}},[r,s,p.paused]),a.useEffect(()=>{if(s){me.add(p);const u=document.activeElement;if(!s.contains(u)){const E=new CustomEvent(Q,fe);s.addEventListener(Q,l),s.dispatchEvent(E),E.defaultPrevented||(At(_t(Oe(s)),{select:!0}),document.activeElement===u&&x(s))}return()=>{s.removeEventListener(Q,l),setTimeout(()=>{const E=new CustomEvent(J,fe);s.addEventListener(J,f),s.dispatchEvent(E),E.defaultPrevented||x(u??document.body,{select:!0}),s.removeEventListener(J,f),me.remove(p)},0)}}},[s,l,f,p]);const R=a.useCallback(u=>{if(!n&&!r||p.paused)return;const m=u.key==="Tab"&&!u.altKey&&!u.ctrlKey&&!u.metaKey,E=document.activeElement;if(m&&E){const b=u.currentTarget,[C,S]=It(b);C&&S?!u.shiftKey&&E===S?(u.preventDefault(),n&&x(C,{select:!0})):u.shiftKey&&E===C&&(u.preventDefault(),n&&x(S,{select:!0})):E===b&&u.preventDefault()}},[n,r,p.paused]);return g.jsx(D.div,{tabIndex:-1,...c,ref:h,onKeyDown:R})});xe.displayName=Tt;function At(e,{select:t=!1}={}){const n=document.activeElement;for(const r of e)if(x(r,{select:t}),document.activeElement!==n)return}function It(e){const t=Oe(e),n=ve(t,e),r=ve(t.reverse(),e);return[n,r]}function Oe(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const o=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||o?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function ve(e,t){for(const n of e)if(!Lt(n,{upTo:t}))return n}function Lt(e,{upTo:t}){if(getComputedStyle(e).visibility==="hidden")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display==="none")return!0;e=e.parentElement}return!1}function Mt(e){return e instanceof HTMLInputElement&&"select"in e}function x(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&Mt(e)&&t&&e.select()}}var me=Ft();function Ft(){let e=[];return{add(t){const n=e[0];t!==n&&(n==null||n.pause()),e=ge(e,t),e.unshift(t)},remove(t){var n;e=ge(e,t),(n=e[0])==null||n.resume()}}}function ge(e,t){const n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function _t(e){return e.filter(t=>t.tagName!=="A")}var kt="Portal",Te=a.forwardRef((e,t)=>{var s;const{container:n,...r}=e,[o,i]=a.useState(!1);j(()=>i(!0),[]);const c=n||o&&((s=globalThis==null?void 0:globalThis.document)==null?void 0:s.body);return c?Je.createPortal(g.jsx(D.div,{...r,ref:t}),c):null});Te.displayName=kt;function Wt(e,t){return a.useReducer((n,r)=>t[n][r]??n,e)}var H=e=>{const{present:t,children:n}=e,r=jt(t),o=typeof n=="function"?n({present:r.isPresent}):a.Children.only(n),i=I(r.ref,Bt(o));return typeof n=="function"||r.isPresent?a.cloneElement(o,{ref:i}):null};H.displayName="Presence";function jt(e){const[t,n]=a.useState(),r=a.useRef(null),o=a.useRef(e),i=a.useRef("none"),c=e?"mounted":"unmounted",[s,d]=Wt(c,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return a.useEffect(()=>{const l=$(r.current);i.current=s==="mounted"?l:"none"},[s]),j(()=>{const l=r.current,f=o.current;if(f!==e){const h=i.current,p=$(l);e?d("MOUNT"):p==="none"||(l==null?void 0:l.display)==="none"?d("UNMOUNT"):d(f&&h!==p?"ANIMATION_OUT":"UNMOUNT"),o.current=e}},[e,d]),j(()=>{if(t){let l;const f=t.ownerDocument.defaultView??window,v=p=>{const u=$(r.current).includes(CSS.escape(p.animationName));if(p.target===t&&u&&(d("ANIMATION_END"),!o.current)){const m=t.style.animationFillMode;t.style.animationFillMode="forwards",l=f.setTimeout(()=>{t.style.animationFillMode==="forwards"&&(t.style.animationFillMode=m)})}},h=p=>{p.target===t&&(i.current=$(r.current))};return t.addEventListener("animationstart",h),t.addEventListener("animationcancel",v),t.addEventListener("animationend",v),()=>{f.clearTimeout(l),t.removeEventListener("animationstart",h),t.removeEventListener("animationcancel",v),t.removeEventListener("animationend",v)}}else d("ANIMATION_END")},[t,d]),{isPresent:["mounted","unmountSuspended"].includes(s),ref:a.useCallback(l=>{r.current=l?getComputedStyle(l):null,n(l)},[])}}function $(e){return(e==null?void 0:e.animationName)||"none"}function Bt(e){var r,o;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(o=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:o.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var ee=0;function Ut(){a.useEffect(()=>{const e=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",e[0]??he()),document.body.insertAdjacentElement("beforeend",e[1]??he()),ee++,()=>{ee===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(t=>t.remove()),ee--}},[])}function he(){const e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}var G="right-scroll-bar-position",Y="width-before-scroll-bar",$t="with-scroll-bars-hidden",Vt="--removed-body-scroll-bar-size",Ae=et(),te=function(){},z=a.forwardRef(function(e,t){var n=a.useRef(null),r=a.useState({onScrollCapture:te,onWheelCapture:te,onTouchMoveCapture:te}),o=r[0],i=r[1],c=e.forwardProps,s=e.children,d=e.className,l=e.removeScrollBar,f=e.enabled,v=e.shards,h=e.sideCar,p=e.noRelative,R=e.noIsolation,u=e.inert,m=e.allowPinchZoom,E=e.as,b=E===void 0?"div":E,C=e.gapMode,S=tt(e,["forwardProps","children","className","removeScrollBar","enabled","shards","sideCar","noRelative","noIsolation","inert","allowPinchZoom","as","gapMode"]),w=h,P=nt([n,t]),y=_(_({},S),o);return a.createElement(a.Fragment,null,f&&a.createElement(w,{sideCar:Ae,removeScrollBar:l,shards:v,noRelative:p,noIsolation:R,inert:u,setCallbacks:i,allowPinchZoom:!!m,lockRef:n,gapMode:C}),c?a.cloneElement(a.Children.only(s),_(_({},y),{ref:P})):a.createElement(b,_({},y,{className:d,ref:P}),s))});z.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1};z.classNames={fullWidth:Y,zeroRight:G};var Kt={left:0,top:0,right:0,gap:0},ne=function(e){return parseInt(e||"",10)||0},Gt=function(e){var t=window.getComputedStyle(document.body),n=t[e==="padding"?"paddingLeft":"marginLeft"],r=t[e==="padding"?"paddingTop":"marginTop"],o=t[e==="padding"?"paddingRight":"marginRight"];return[ne(n),ne(r),ne(o)]},Yt=function(e){if(e===void 0&&(e="margin"),typeof window>"u")return Kt;var t=Gt(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Xt=Se(),k="data-scroll-locked",Ht=function(e,t,n,r){var o=e.left,i=e.top,c=e.right,s=e.gap;return n===void 0&&(n="margin"),`
2
2
  .`.concat($t,` {
3
3
  overflow: hidden `).concat(r,`;
4
4
  padding-right: `).concat(s,"px ").concat(r,`;
@@ -43,4 +43,3 @@ import{r as a,j as g,b as Ce,a as Qe,c as Je,d as et,_ as tt,u as nt,e as _,s as
43
43
  If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
44
44
 
45
45
  For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return a.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},En="DialogDescriptionWarning",yn=({contentRef:e,descriptionId:t})=>{const r=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${qe(En).contentName}}.`;return a.useEffect(()=>{var i;const o=(i=e.current)==null?void 0:i.getAttribute("aria-describedby");t&&o&&(document.getElementById(t)||console.warn(r))},[r,e,t]),null},Sn=ke,Rn=je,wn=Ue,Pn=$e,Nn=Ve,Dn=Ge,xn=Xe,On=ze;export{Nn as C,xn as D,Pn as O,wn as P,Sn as R,Dn as T,On as a,Rn as b};
46
- //# sourceMappingURL=ui-FaWfAb5Q.js.map
@@ -1313,5 +1313,4 @@ Make sure your charset is UTF-8`);a=(a>>>8&255)*192+(a&255),r.put(a,13)}},V_=n,V
1313
1313
  The chosen QR Code version cannot contain this amount of data.
1314
1314
  Minimum version required to store current data is: `+R+`.
1315
1315
  `);const N=E(M,D,j),$=e.getSymbolSize(M),I=new r($);return m(I,M),b(I),y(I,M),x(I,D,0),M>=7&&w(I,M),C(I,N),isNaN(P)&&(P=s.getBestMask(I,x.bind(null,I,D))),s.applyMask(P,I),x(I,D,P),{modules:I,version:M,errorCorrectionLevel:D,maskPattern:P,segments:j}}return k_.create=function(M,D){if(typeof M>"u"||M==="")throw new Error("No input text");let P=t.M,j,R;return typeof D<"u"&&(P=t.from(D.errorCorrectionLevel,t.M),j=f.from(D.version),R=s.from(D.maskPattern),D.toSJISFunc&&e.setToSJISFunction(D.toSJISFunc)),k(M,j,P,R)},k_}var Y_={},W_={},j4;function WH(){return j4||(j4=1,(function(e){function t(n){if(typeof n=="number"&&(n=n.toString()),typeof n!="string")throw new Error("Color should be defined as hex string");let r=n.slice().replace("#","").split("");if(r.length<3||r.length===5||r.length>8)throw new Error("Invalid hex color: "+n);(r.length===3||r.length===4)&&(r=Array.prototype.concat.apply([],r.map(function(a){return[a,a]}))),r.length===6&&r.push("F","F");const i=parseInt(r.join(""),16);return{r:i>>24&255,g:i>>16&255,b:i>>8&255,a:i&255,hex:"#"+r.slice(0,6).join("")}}e.getOptions=function(r){r||(r={}),r.color||(r.color={});const i=typeof r.margin>"u"||r.margin===null||r.margin<0?4:r.margin,a=r.width&&r.width>=21?r.width:void 0,s=r.scale||4;return{width:a,scale:a?4:s,margin:i,color:{dark:t(r.color.dark||"#000000ff"),light:t(r.color.light||"#ffffffff")},type:r.type,rendererOpts:r.rendererOpts||{}}},e.getScale=function(r,i){return i.width&&i.width>=r+i.margin*2?i.width/(r+i.margin*2):i.scale},e.getImageWidth=function(r,i){const a=e.getScale(r,i);return Math.floor((r+i.margin*2)*a)},e.qrToImageData=function(r,i,a){const s=i.modules.size,u=i.modules.data,c=e.getScale(s,a),f=Math.floor((s+a.margin*2)*c),h=a.margin*c,p=[a.color.light,a.color.dark];for(let g=0;g<f;g++)for(let m=0;m<f;m++){let b=(g*f+m)*4,y=a.color.light;if(g>=h&&m>=h&&g<f-h&&m<f-h){const w=Math.floor((g-h)/c),x=Math.floor((m-h)/c);y=p[u[w*s+x]?1:0]}r[b++]=y.r,r[b++]=y.g,r[b++]=y.b,r[b]=y.a}}})(W_)),W_}var z4;function ADe(){return z4||(z4=1,(function(e){const t=WH();function n(i,a,s){i.clearRect(0,0,a.width,a.height),a.style||(a.style={}),a.height=s,a.width=s,a.style.height=s+"px",a.style.width=s+"px"}function r(){try{return document.createElement("canvas")}catch{throw new Error("You need to specify a canvas element")}}e.render=function(a,s,u){let c=u,f=s;typeof c>"u"&&(!s||!s.getContext)&&(c=s,s=void 0),s||(f=r()),c=t.getOptions(c);const h=t.getImageWidth(a.modules.size,c),p=f.getContext("2d"),g=p.createImageData(h,h);return t.qrToImageData(g.data,a,c),n(p,f,h),p.putImageData(g,0,0),f},e.renderToDataURL=function(a,s,u){let c=u;typeof c>"u"&&(!s||!s.getContext)&&(c=s,s=void 0),c||(c={});const f=e.render(a,s,c),h=c.type||"image/png",p=c.rendererOpts||{};return f.toDataURL(h,p.quality)}})(Y_)),Y_}var X_={},$4;function ODe(){if($4)return X_;$4=1;const e=WH();function t(i,a){const s=i.a/255,u=a+'="'+i.hex+'"';return s<1?u+" "+a+'-opacity="'+s.toFixed(2).slice(1)+'"':u}function n(i,a,s){let u=i+a;return typeof s<"u"&&(u+=" "+s),u}function r(i,a,s){let u="",c=0,f=!1,h=0;for(let p=0;p<i.length;p++){const g=Math.floor(p%a),m=Math.floor(p/a);!g&&!f&&(f=!0),i[p]?(h++,p>0&&g>0&&i[p-1]||(u+=f?n("M",g+s,.5+m+s):n("m",c,0),c=0,f=!1),g+1<a&&i[p+1]||(u+=n("h",h),h=0)):c++}return u}return X_.render=function(a,s,u){const c=e.getOptions(s),f=a.modules.size,h=a.modules.data,p=f+c.margin*2,g=c.color.light.a?"<path "+t(c.color.light,"fill")+' d="M0 0h'+p+"v"+p+'H0z"/>':"",m="<path "+t(c.color.dark,"stroke")+' d="'+r(h,f,c.margin)+'"/>',b='viewBox="0 0 '+p+" "+p+'"',w='<svg xmlns="http://www.w3.org/2000/svg" '+(c.width?'width="'+c.width+'" height="'+c.width+'" ':"")+b+' shape-rendering="crispEdges">'+g+m+`</svg>
1316
- `;return typeof u=="function"&&u(null,w),w},X_}var B4;function CDe(){if(B4)return Bc;B4=1;const e=sDe(),t=EDe(),n=ADe(),r=ODe();function i(a,s,u,c,f){const h=[].slice.call(arguments,1),p=h.length,g=typeof h[p-1]=="function";if(!g&&!e())throw new Error("Callback required as last argument");if(g){if(p<2)throw new Error("Too few arguments provided");p===2?(f=u,u=s,s=c=void 0):p===3&&(s.getContext&&typeof f>"u"?(f=c,c=void 0):(f=c,c=u,u=s,s=void 0))}else{if(p<1)throw new Error("Too few arguments provided");return p===1?(u=s,s=c=void 0):p===2&&!s.getContext&&(c=u,u=s,s=void 0),new Promise(function(m,b){try{const y=t.create(u,c);m(a(y,s,c))}catch(y){b(y)}})}try{const m=t.create(u,c);f(null,a(m,s,c))}catch(m){f(m)}}return Bc.create=t.create,Bc.toCanvas=i.bind(null,n.render),Bc.toDataURL=i.bind(null,n.renderToDataURL),Bc.toString=i.bind(null,function(a,s,u){return r.render(a,u)}),Bc}var TDe=CDe();const JIe=Ur(TDe);export{fPe as $,LPe as A,lPe as B,pPe as C,xRe as D,iRe as E,JPe as F,oNe as G,gNe as H,uA as I,iNe as J,MNe as K,R5 as L,iPe as M,YNe as N,sRe as O,QNe as P,oRe as Q,Qt as R,NRe as S,qRe as T,uPe as U,xNe as V,tIe as W,nIe as X,DPe as Y,rIe as Z,VY as _,T0 as a,xPe as a$,dPe as a0,MRe as a1,ERe as a2,aIe as a3,aPe as a4,aNe as a5,ZNe as a6,CPe as a7,rPe as a8,mPe as a9,APe as aA,vPe as aB,uRe as aC,mIe as aD,vIe as aE,un as aF,Bp as aG,No as aH,Zh as aI,pee as aJ,gIe as aK,Mp as aL,ce as aM,fK as aN,pK as aO,sPe as aP,NNe as aQ,GPe as aR,pNe as aS,gPe as aT,Dp as aU,BDe as aV,IDe as aW,jDe as aX,$De as aY,LDe as aZ,SPe as a_,dIe as aa,oIe as ab,cIe as ac,lIe as ad,hIe as ae,fIe as af,uIe as ag,Ae as ah,sIe as ai,WRe as aj,VPe as ak,lNe as al,sNe as am,WNe as an,QRe as ao,ONe as ap,JRe as aq,KRe as ar,hNe as as,UNe as at,HNe as au,Na as av,jY as aw,URe as ax,nRe as ay,jRe as az,sV as b,dRe as b$,fNe as b0,JDe as b1,XRe as b2,Ny as b3,Ke as b4,VNe as b5,PPe as b6,gRe as b7,qDe as b8,PNe as b9,wPe as bA,QPe as bB,eNe as bC,wNe as bD,WIe as bE,zt as bF,yIe as bG,wIe as bH,bIe as bI,My as bJ,pRe as bK,_Re as bL,BNe as bM,BPe as bN,mRe as bO,IPe as bP,Mwe as bQ,Ns as bR,OIe as bS,z1e as bT,cxe as bU,zDe as bV,FNe as bW,FPe as bX,XIe as bY,jNe as bZ,VRe as b_,xIe as ba,eRe as bb,ORe as bc,MPe as bd,HRe as be,zPe as bf,yRe as bg,qPe as bh,ANe as bi,YPe as bj,tRe as bk,UDe as bl,yPe as bm,_Pe as bn,TPe as bo,GRe as bp,JNe as bq,PRe as br,LNe as bs,rNe as bt,SIe as bu,YIe as bv,WSe as bw,s_e as bx,zxe as by,OPe as bz,VDe as c,cPe as c$,SNe as c0,oPe as c1,nPe as c2,$Ne as c3,RNe as c4,KPe as c5,ZIe as c6,bPe as c7,DRe as c8,$Pe as c9,kPe as cA,RPe as cB,JIe as cC,aRe as cD,TRe as cE,NPe as cF,rRe as cG,kRe as cH,DNe as cI,GNe as cJ,vRe as cK,eIe as cL,YRe as cM,cNe as cN,WPe as cO,ZRe as cP,CNe as cQ,mNe as cR,KIe as cS,RSe as cT,bae as cU,Noe as cV,Poe as cW,hPe as cX,LRe as cY,kNe as cZ,uNe as c_,bRe as ca,ePe as cb,ENe as cc,UPe as cd,RRe as ce,$Re as cf,vNe as cg,qNe as ch,INe as ci,QIe as cj,IRe as ck,_Ne as cl,XPe as cm,fRe as cn,jPe as co,VIe as cp,EPe as cq,wRe as cr,XNe as cs,HPe as ct,yNe as cu,nNe as cv,tPe as cw,dNe as cx,CRe as cy,bNe as cz,WDe as d,SRe as d0,zNe as d1,HDe as d2,fY as d3,FDe as d4,PDe as d5,MDe as d6,lK as d7,NDe as d8,GDe as d9,ny as e,KDe as f,XDe as g,QDe as h,Ot as i,ne as j,RDe as k,BRe as l,tNe as m,ZPe as n,TNe as o,lRe as p,zRe as q,_ as r,ZDe as s,iIe as t,YDe as u,KNe as v,FRe as w,cRe as x,hRe as y,ARe as z};
1317
- //# sourceMappingURL=vendor-CUxVKN94.js.map
1316
+ `;return typeof u=="function"&&u(null,w),w},X_}var B4;function CDe(){if(B4)return Bc;B4=1;const e=sDe(),t=EDe(),n=ADe(),r=ODe();function i(a,s,u,c,f){const h=[].slice.call(arguments,1),p=h.length,g=typeof h[p-1]=="function";if(!g&&!e())throw new Error("Callback required as last argument");if(g){if(p<2)throw new Error("Too few arguments provided");p===2?(f=u,u=s,s=c=void 0):p===3&&(s.getContext&&typeof f>"u"?(f=c,c=void 0):(f=c,c=u,u=s,s=void 0))}else{if(p<1)throw new Error("Too few arguments provided");return p===1?(u=s,s=c=void 0):p===2&&!s.getContext&&(c=u,u=s,s=void 0),new Promise(function(m,b){try{const y=t.create(u,c);m(a(y,s,c))}catch(y){b(y)}})}try{const m=t.create(u,c);f(null,a(m,s,c))}catch(m){f(m)}}return Bc.create=t.create,Bc.toCanvas=i.bind(null,n.render),Bc.toDataURL=i.bind(null,n.renderToDataURL),Bc.toString=i.bind(null,function(a,s,u){return r.render(a,u)}),Bc}var TDe=CDe();const JIe=Ur(TDe);export{MNe as $,KNe as A,FRe as B,pPe as C,HPe as D,cRe as E,JPe as F,oNe as G,gNe as H,hRe as I,ARe as J,LPe as K,R5 as L,lPe as M,YNe as N,xRe as O,QNe as P,oRe as Q,Qt as R,ERe as S,qRe as T,iRe as U,uA as V,tIe as W,nIe as X,iNe as Y,rIe as Z,VY as _,T0 as a,SPe as a$,iPe as a0,sRe as a1,uPe as a2,xNe as a3,DPe as a4,fPe as a5,dPe as a6,MRe as a7,aPe as a8,aNe as a9,URe as aA,nRe as aB,jRe as aC,APe as aD,vPe as aE,uRe as aF,mIe as aG,vIe as aH,un as aI,Bp as aJ,No as aK,Zh as aL,pee as aM,gIe as aN,ce as aO,fK as aP,pK as aQ,sPe as aR,NNe as aS,GPe as aT,pNe as aU,gPe as aV,Dp as aW,BDe as aX,IDe as aY,$De as aZ,LDe as a_,ZNe as aa,CPe as ab,rPe as ac,mPe as ad,dIe as ae,oIe as af,cIe as ag,lIe as ah,hIe as ai,fIe as aj,uIe as ak,Ae as al,sIe as am,WRe as an,VPe as ao,lNe as ap,sNe as aq,WNe as ar,QRe as as,ONe as at,JRe as au,KRe as av,hNe as aw,UNe as ax,HNe as ay,jY as az,sV as b,VRe as b$,xPe as b0,fNe as b1,JDe as b2,XRe as b3,Ny as b4,Ke as b5,VNe as b6,PPe as b7,gRe as b8,qDe as b9,OPe as bA,wPe as bB,QPe as bC,eNe as bD,wNe as bE,WIe as bF,zt as bG,yIe as bH,wIe as bI,bIe as bJ,My as bK,pRe as bL,_Re as bM,BNe as bN,BPe as bO,mRe as bP,IPe as bQ,Mwe as bR,Ns as bS,OIe as bT,z1e as bU,cxe as bV,zDe as bW,FNe as bX,FPe as bY,XIe as bZ,jNe as b_,PNe as ba,xIe as bb,eRe as bc,ORe as bd,MPe as be,HRe as bf,zPe as bg,yRe as bh,qPe as bi,ANe as bj,YPe as bk,tRe as bl,UDe as bm,yPe as bn,_Pe as bo,TPe as bp,GRe as bq,JNe as br,PRe as bs,LNe as bt,rNe as bu,SIe as bv,YIe as bw,WSe as bx,s_e as by,zxe as bz,VDe as c,cPe as c$,dRe as c0,SNe as c1,oPe as c2,nPe as c3,$Ne as c4,RNe as c5,KPe as c6,ZIe as c7,bPe as c8,DRe as c9,kPe as cA,RPe as cB,JIe as cC,aRe as cD,TRe as cE,NPe as cF,rRe as cG,kRe as cH,DNe as cI,GNe as cJ,vRe as cK,eIe as cL,YRe as cM,cNe as cN,WPe as cO,ZRe as cP,CNe as cQ,mNe as cR,KIe as cS,RSe as cT,bae as cU,Noe as cV,Poe as cW,hPe as cX,LRe as cY,kNe as cZ,uNe as c_,$Pe as ca,bRe as cb,ePe as cc,ENe as cd,UPe as ce,RRe as cf,$Re as cg,vNe as ch,qNe as ci,INe as cj,QIe as ck,IRe as cl,_Ne as cm,XPe as cn,fRe as co,jPe as cp,VIe as cq,EPe as cr,wRe as cs,XNe as ct,yNe as cu,nNe as cv,tPe as cw,dNe as cx,CRe as cy,bNe as cz,WDe as d,SRe as d0,zNe as d1,HDe as d2,fY as d3,FDe as d4,PDe as d5,MDe as d6,lK as d7,NDe as d8,GDe as d9,ny as e,KDe as f,XDe as g,QDe as h,Ot as i,ne as j,aIe as k,RDe as l,Mp as m,jDe as n,NRe as o,Na as p,BRe as q,_ as r,ZDe as s,iIe as t,YDe as u,tNe as v,ZPe as w,TNe as x,lRe as y,zRe as z};
package/dist/index.html CHANGED
@@ -13,14 +13,14 @@
13
13
  />
14
14
  <link rel="icon" type="image/png" href="/forge/assets/favicon-BCHm9dUV.ico" />
15
15
  <link rel="alternate icon" href="/forge/assets/favicon-BCHm9dUV.ico" />
16
- <script type="module" crossorigin src="/forge/assets/index-NZwTuYPs.js"></script>
17
- <link rel="modulepreload" crossorigin href="/forge/assets/vendor-CUxVKN94.js">
18
- <link rel="modulepreload" crossorigin href="/forge/assets/board-BAxNp060.js">
19
- <link rel="modulepreload" crossorigin href="/forge/assets/ui-FaWfAb5Q.js">
20
- <link rel="modulepreload" crossorigin href="/forge/assets/motion-B9BeeSmV.js">
21
- <link rel="modulepreload" crossorigin href="/forge/assets/table-kY1tUKX5.js">
16
+ <script type="module" crossorigin src="/forge/assets/index-Dy7c-dRY.js"></script>
17
+ <link rel="modulepreload" crossorigin href="/forge/assets/vendor-C0otBhgu.js">
18
+ <link rel="modulepreload" crossorigin href="/forge/assets/board-B1V3M__K.js">
19
+ <link rel="modulepreload" crossorigin href="/forge/assets/ui-DUqM4jkt.js">
20
+ <link rel="modulepreload" crossorigin href="/forge/assets/motion-CltSTItx.js">
21
+ <link rel="modulepreload" crossorigin href="/forge/assets/table-B-VrSFx8.js">
22
22
  <link rel="stylesheet" crossorigin href="/forge/assets/vendor-DT3pnAKJ.css">
23
- <link rel="stylesheet" crossorigin href="/forge/assets/index-B5Yt4i07.css">
23
+ <link rel="stylesheet" crossorigin href="/forge/assets/index-BwKAPo98.css">
24
24
  </head>
25
25
  <body class="bg-canvas text-ink antialiased">
26
26
  <div id="root"></div>
@@ -1,2 +1,2 @@
1
1
  ALTER TABLE app_settings
2
- ADD COLUMN gamification_theme TEXT NOT NULL DEFAULT 'dark-fantasy';
2
+ ADD COLUMN gamification_theme TEXT NOT NULL DEFAULT 'dramatic-smithie';
@@ -40,6 +40,7 @@ import { createCalendarEvent, createTaskTimebox, createWorkBlockTemplate, delete
40
40
  import { getDashboard } from "./services/dashboard.js";
41
41
  import { getOverviewContext, getRiskContext, getTodayContext } from "./services/context.js";
42
42
  import { buildGamificationCatalogPayload, buildGamificationOverview, buildGamificationProfile, buildXpMetricsPayloadModel, LockedGamificationCosmeticError, updateGamificationEquipmentSelection } from "./services/gamification.js";
43
+ import { getGamificationAssetStatus, installGamificationAssetStyle } from "./services/gamification-assets.js";
43
44
  import { getInsightsPayload } from "./services/insights.js";
44
45
  import { buildLifeForcePayload, createFatigueSignal, listLifeForceTemplates, resolveLifeForceUser, updateLifeForceProfile, updateLifeForceTemplate } from "./services/life-force.js";
45
46
  import { createEntities, deleteEntities, deleteEntity, getSettingsBinPayload, restoreEntities, searchEntities, updateEntities } from "./services/entity-crud.js";
@@ -9137,6 +9138,32 @@ export async function buildServer(options = {}) {
9137
9138
  catalog: buildGamificationCatalogPayload(filterOwnedEntities("goal", listGoals(), userIds), filterOwnedEntities("task", listTasks({ userIds }), userIds), filterOwnedEntities("habit", listHabits(), userIds), { userIds })
9138
9139
  };
9139
9140
  });
9141
+ app.get("/api/v1/gamification/assets", async () => ({
9142
+ assets: await getGamificationAssetStatus()
9143
+ }));
9144
+ app.post("/api/v1/gamification/assets/install", async (request, reply) => {
9145
+ requireOperatorSession(request.headers, {
9146
+ route: "/api/v1/gamification/assets/install"
9147
+ });
9148
+ const input = z
9149
+ .object({
9150
+ style: z.enum(["dark-fantasy", "dramatic-smithie", "mind-locksmith"])
9151
+ })
9152
+ .parse(request.body ?? {});
9153
+ try {
9154
+ return {
9155
+ style: await installGamificationAssetStyle(input.style)
9156
+ };
9157
+ }
9158
+ catch (error) {
9159
+ reply.code(502);
9160
+ return {
9161
+ error: error instanceof Error
9162
+ ? error.message
9163
+ : "Could not install gamification assets."
9164
+ };
9165
+ }
9166
+ });
9140
9167
  app.get("/api/v1/gamification/equipment", async (request) => {
9141
9168
  const userIds = resolveScopedUserIds(request.query);
9142
9169
  const catalog = buildGamificationCatalogPayload(filterOwnedEntities("goal", listGoals(), userIds), filterOwnedEntities("task", listTasks({ userIds }), userIds), filterOwnedEntities("habit", listHabits(), userIds), { userIds });
@@ -473,7 +473,7 @@ function ensureSettingsRow(now = new Date().toISOString()) {
473
473
  id, operator_name, operator_email, operator_title, theme_preference, gamification_theme, locale_preference, goal_drift_alerts,
474
474
  daily_quest_reminders, achievement_celebrations, max_active_tasks, time_accounting_mode, integrity_score, last_audit_at, created_at, updated_at
475
475
  ) VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
476
- .run("Master Architect", "architect@kineticforge.ai", "Local-first operator", "obsidian", "dark-fantasy", "en", 1, 1, 1, 2, "split", 98, now, now, now);
476
+ .run("Master Architect", "architect@kineticforge.ai", "Local-first operator", "obsidian", "dramatic-smithie", "en", 1, 1, 1, 2, "split", 98, now, now, now);
477
477
  }
478
478
  function readSettingsRow() {
479
479
  ensureSettingsRow();
@@ -0,0 +1,231 @@
1
+ import { createHash } from "node:crypto";
2
+ import { spawnSync } from "node:child_process";
3
+ import { existsSync } from "node:fs";
4
+ import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
5
+ import path from "node:path";
6
+ import AdmZip from "adm-zip";
7
+ import { getEffectiveDataRoot } from "../db.js";
8
+ import { GAMIFICATION_CATALOG, GAMIFICATION_MASCOT_KEYS } from "../../../src/lib/gamification-catalog.js";
9
+ const assetVersion = "0.2.59";
10
+ const defaultReleaseBaseUrl = "https://github.com/albertbuchard/forge/releases/download/forge-gamification-assets-v0.2.59";
11
+ const styleDefinitions = [
12
+ {
13
+ id: "dramatic-smithie",
14
+ label: "Fantasy",
15
+ description: "Warm, lighthearted 3D forge art with expressive mascot reactions and playful trophies.",
16
+ previewUrl: "/gamification-previews/dramatic-smithie-mascot.webp",
17
+ fileName: `forge-gamification-dramatic-smithie-${assetVersion}.zip`,
18
+ sha256: "407c98a89626d723f9f92e79411df7c999458459c96e0e09e73020b3d3ce14c0"
19
+ },
20
+ {
21
+ id: "dark-fantasy",
22
+ label: "Dark Fantasy",
23
+ description: "Obsidian iron, ember gold, high-pressure streak energy, and mythic trophy silhouettes.",
24
+ previewUrl: "/gamification-previews/dark-fantasy-mascot.webp",
25
+ fileName: `forge-gamification-dark-fantasy-${assetVersion}.zip`,
26
+ sha256: "9545900906784a23d15f4536eb8c32683ffff0ef42006d06c70cea101c1db570"
27
+ },
28
+ {
29
+ id: "mind-locksmith",
30
+ label: "Mind Locksmith",
31
+ description: "Modern locksmith-of-the-mind art for planning, memory, Psyche, health, and agent work.",
32
+ previewUrl: "/gamification-previews/mind-locksmith-mascot.webp",
33
+ fileName: `forge-gamification-mind-locksmith-${assetVersion}.zip`,
34
+ sha256: "cfdfd4259145e589e6e0fba8e1deb69d30931cfabbe6d626c0053e4f4cfe5f10"
35
+ }
36
+ ];
37
+ export const defaultGamificationAssetStyle = "dramatic-smithie";
38
+ function getCustomReleaseBaseUrl() {
39
+ return process.env.FORGE_GAMIFICATION_ASSET_BASE_URL?.trim().replace(/\/+$/, "");
40
+ }
41
+ function getDownloadUrl(style) {
42
+ const customReleaseBaseUrl = getCustomReleaseBaseUrl();
43
+ return `${customReleaseBaseUrl ?? defaultReleaseBaseUrl}/${style.fileName}`;
44
+ }
45
+ function getStyleDefinition(styleId) {
46
+ const style = styleDefinitions.find((candidate) => candidate.id === styleId);
47
+ if (!style) {
48
+ throw new Error(`Unknown gamification asset style: ${styleId}`);
49
+ }
50
+ return style;
51
+ }
52
+ function getExpectedSpritePaths(styleId) {
53
+ const itemAssetKeys = [
54
+ ...new Set(GAMIFICATION_CATALOG.map((item) => item.assetKey))
55
+ ];
56
+ const expectedPaths = new Set();
57
+ for (const key of itemAssetKeys) {
58
+ expectedPaths.add(`themes/${styleId}/items/${key}-256.webp`);
59
+ expectedPaths.add(`themes/${styleId}/items/${key}-512.webp`);
60
+ }
61
+ for (const key of GAMIFICATION_MASCOT_KEYS) {
62
+ expectedPaths.add(`themes/${styleId}/mascots/${key}-256.webp`);
63
+ expectedPaths.add(`themes/${styleId}/mascots/${key}-512.webp`);
64
+ }
65
+ return expectedPaths;
66
+ }
67
+ function assertSafeRelativePath(relativePath) {
68
+ if (relativePath.startsWith("/") ||
69
+ relativePath.includes("\\") ||
70
+ relativePath.split("/").some((segment) => segment === "..")) {
71
+ throw new Error(`Unsafe gamification asset path: ${relativePath}`);
72
+ }
73
+ }
74
+ function getStyleRoot(styleId) {
75
+ const style = getStyleDefinition(styleId);
76
+ return path.join(getEffectiveDataRoot(), "runtime-assets", "gamification", "styles", `${style.id}-${assetVersion}-${style.sha256.slice(0, 16)}`);
77
+ }
78
+ function getMarkerPath(styleId) {
79
+ return path.join(getStyleRoot(styleId), ".forge-gamification-style-ready.json");
80
+ }
81
+ async function countReadableFiles(root, relativePaths) {
82
+ let count = 0;
83
+ for (const relativePath of relativePaths) {
84
+ try {
85
+ await access(path.join(root, relativePath));
86
+ count += 1;
87
+ }
88
+ catch {
89
+ // Missing files are reported through the count.
90
+ }
91
+ }
92
+ return count;
93
+ }
94
+ async function readInstalledAt(styleId) {
95
+ try {
96
+ const marker = JSON.parse(await readFile(getMarkerPath(styleId), "utf8"));
97
+ return typeof marker.installedAt === "string" ? marker.installedAt : null;
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ }
103
+ async function getStyleStatus(styleId) {
104
+ const style = getStyleDefinition(styleId);
105
+ const expectedPaths = getExpectedSpritePaths(style.id);
106
+ const root = getStyleRoot(style.id);
107
+ const spriteCount = existsSync(getMarkerPath(style.id))
108
+ ? await countReadableFiles(root, expectedPaths)
109
+ : 0;
110
+ const installed = spriteCount === expectedPaths.size;
111
+ return {
112
+ ...style,
113
+ downloadUrl: getDownloadUrl(style),
114
+ installed,
115
+ spriteCount,
116
+ expectedSpriteCount: expectedPaths.size,
117
+ installedAt: installed ? await readInstalledAt(style.id) : null
118
+ };
119
+ }
120
+ export async function getGamificationAssetStatus() {
121
+ const styles = await Promise.all(styleDefinitions.map((style) => getStyleStatus(style.id)));
122
+ return {
123
+ version: assetVersion,
124
+ defaultStyle: defaultGamificationAssetStyle,
125
+ styles
126
+ };
127
+ }
128
+ function buildDownloadHeaders(url) {
129
+ const headers = {
130
+ Accept: "application/octet-stream"
131
+ };
132
+ const token = resolveGithubTokenForDownload(url);
133
+ if (token && /github\.com/i.test(url)) {
134
+ headers.Authorization = `Bearer ${token}`;
135
+ }
136
+ return headers;
137
+ }
138
+ function resolveGithubTokenForDownload(url) {
139
+ if (!/github\.com/i.test(url)) {
140
+ return undefined;
141
+ }
142
+ const envToken = process.env.FORGE_GAMIFICATION_GITHUB_TOKEN ?? process.env.GITHUB_TOKEN;
143
+ if (envToken?.trim()) {
144
+ return envToken.trim();
145
+ }
146
+ const result = spawnSync("gh", ["auth", "token"], {
147
+ encoding: "utf8",
148
+ stdio: ["ignore", "pipe", "ignore"]
149
+ });
150
+ const cliToken = result.status === 0 ? result.stdout.trim() : "";
151
+ return cliToken || undefined;
152
+ }
153
+ function validateArchive(styleId, archive) {
154
+ const expectedPaths = getExpectedSpritePaths(styleId);
155
+ const entriesByName = new Map(archive
156
+ .getEntries()
157
+ .filter((entry) => !entry.isDirectory)
158
+ .map((entry) => {
159
+ assertSafeRelativePath(entry.entryName);
160
+ return [entry.entryName, entry];
161
+ }));
162
+ const missing = [...expectedPaths].filter((entryName) => !entriesByName.has(entryName));
163
+ const unexpected = [...entriesByName.keys()].filter((entryName) => !expectedPaths.has(entryName));
164
+ if (missing.length > 0 || unexpected.length > 0) {
165
+ throw new Error(`Invalid gamification style archive for ${styleId}. Missing ${missing.length}, unexpected ${unexpected.length}.`);
166
+ }
167
+ return { expectedPaths, entriesByName };
168
+ }
169
+ export async function installGamificationAssetStyle(styleId, fetchImpl = fetch) {
170
+ const style = getStyleDefinition(styleId);
171
+ const downloadUrl = getDownloadUrl(style);
172
+ const response = await fetchImpl(downloadUrl, {
173
+ headers: buildDownloadHeaders(downloadUrl)
174
+ });
175
+ if (!response.ok) {
176
+ throw new Error(`Could not download gamification assets (${response.status} ${response.statusText}).`);
177
+ }
178
+ const archivePayload = Buffer.from(await response.arrayBuffer());
179
+ const actualSha256 = createHash("sha256").update(archivePayload).digest("hex");
180
+ if (actualSha256 !== style.sha256) {
181
+ throw new Error(`Gamification asset checksum mismatch for ${style.id}. Expected ${style.sha256}, got ${actualSha256}.`);
182
+ }
183
+ const archive = new AdmZip(archivePayload);
184
+ const { expectedPaths, entriesByName } = validateArchive(style.id, archive);
185
+ const targetRoot = getStyleRoot(style.id);
186
+ await rm(targetRoot, { recursive: true, force: true });
187
+ for (const relativePath of expectedPaths) {
188
+ const entry = entriesByName.get(relativePath);
189
+ if (!entry) {
190
+ throw new Error(`Missing gamification archive entry: ${relativePath}`);
191
+ }
192
+ const targetPath = path.join(targetRoot, relativePath);
193
+ await mkdir(path.dirname(targetPath), { recursive: true });
194
+ await writeFile(targetPath, entry.getData());
195
+ }
196
+ await writeFile(getMarkerPath(style.id), `${JSON.stringify({
197
+ style: style.id,
198
+ version: assetVersion,
199
+ sha256: style.sha256,
200
+ spriteCount: expectedPaths.size,
201
+ installedAt: new Date().toISOString(),
202
+ source: downloadUrl
203
+ }, null, 2)}\n`, "utf8");
204
+ return getStyleStatus(style.id);
205
+ }
206
+ export async function resolveGamificationSpriteAssetPath(relativeSpritePath) {
207
+ const safePath = relativeSpritePath.replace(/^\/+/, "");
208
+ try {
209
+ assertSafeRelativePath(safePath);
210
+ }
211
+ catch {
212
+ return path.join(getEffectiveDataRoot(), "runtime-assets", "missing-gamification-asset");
213
+ }
214
+ const match = /^themes\/([^/]+)\//.exec(safePath);
215
+ if (!match) {
216
+ return path.join(getEffectiveDataRoot(), "runtime-assets", "missing-gamification-asset");
217
+ }
218
+ const styleId = match[1];
219
+ const style = styleDefinitions.find((candidate) => candidate.id === styleId);
220
+ if (!style) {
221
+ return path.join(getEffectiveDataRoot(), "runtime-assets", "missing-gamification-asset");
222
+ }
223
+ if (!getExpectedSpritePaths(style.id).has(safePath)) {
224
+ return path.join(getEffectiveDataRoot(), "runtime-assets", "missing-gamification-asset");
225
+ }
226
+ const status = await getStyleStatus(style.id);
227
+ if (!status.installed) {
228
+ return path.join(getEffectiveDataRoot(), "runtime-assets", "missing-gamification-asset");
229
+ }
230
+ return path.join(getStyleRoot(style.id), safePath);
231
+ }
@@ -2690,7 +2690,7 @@ export const settingsPayloadSchema = z.object({
2690
2690
  notifications: notificationPreferencesSchema,
2691
2691
  execution: executionSettingsSchema,
2692
2692
  themePreference: themePreferenceSchema,
2693
- gamificationTheme: gamificationThemeSchema.default("dark-fantasy"),
2693
+ gamificationTheme: gamificationThemeSchema.default("dramatic-smithie"),
2694
2694
  customTheme: customThemeSchema.nullable(),
2695
2695
  localePreference: appLocaleSchema,
2696
2696
  security: z.object({
@@ -5,6 +5,7 @@ import { existsSync } from "node:fs";
5
5
  import { access, readFile } from "node:fs/promises";
6
6
  import path from "node:path";
7
7
  import { setTimeout as delay } from "node:timers/promises";
8
+ import { resolveGamificationSpriteAssetPath } from "./services/gamification-assets.js";
8
9
  const distDir = path.join(process.cwd(), "dist");
9
10
  const packagedRuntimeDistDir = path.join(process.cwd(), "plugins", "forge-codex", "runtime", "dist");
10
11
  const contentTypes = {
@@ -14,9 +15,11 @@ const contentTypes = {
14
15
  ".json": "application/json; charset=utf-8",
15
16
  ".map": "application/json; charset=utf-8",
16
17
  ".svg": "image/svg+xml",
18
+ ".webp": "image/webp",
17
19
  ".woff": "font/woff",
18
20
  ".woff2": "font/woff2"
19
21
  };
22
+ const gamificationSpriteRoutePrefix = "/gamification/sprites/";
20
23
  function normalizeBasePath(value) {
21
24
  if (!value || value === "/") {
22
25
  return "/";
@@ -110,6 +113,13 @@ function resolveAsset(clientDir, requestPath) {
110
113
  const safePath = requestPath.replace(/^\/+/, "");
111
114
  return path.join(clientDir, safePath);
112
115
  }
116
+ async function resolveBuiltAsset(clientDir, requestPath) {
117
+ if (requestPath.startsWith(gamificationSpriteRoutePrefix)) {
118
+ const relativeSpritePath = requestPath.slice(gamificationSpriteRoutePrefix.length);
119
+ return resolveGamificationSpriteAssetPath(relativeSpritePath);
120
+ }
121
+ return resolveAsset(clientDir, requestPath);
122
+ }
113
123
  async function getClientDir() {
114
124
  try {
115
125
  await access(path.join(distDir, "index.html"));
@@ -328,7 +338,10 @@ async function serveAsset(requestPath, reply, options) {
328
338
  return { error: "Not found" };
329
339
  }
330
340
  const normalizedRequestPath = stripBasePath(requestTarget.pathname, getDefaultBasePath());
331
- const devWebOrigin = await options.devWebRuntime.ensureReady();
341
+ const handlesLocalGamificationSprite = normalizedRequestPath.startsWith(gamificationSpriteRoutePrefix);
342
+ const devWebOrigin = handlesLocalGamificationSprite
343
+ ? null
344
+ : await options.devWebRuntime.ensureReady();
332
345
  if (devWebOrigin) {
333
346
  try {
334
347
  return await proxyDevAsset({
@@ -344,7 +357,7 @@ async function serveAsset(requestPath, reply, options) {
344
357
  }
345
358
  }
346
359
  const clientDir = await getClientDir();
347
- const assetPath = resolveAsset(clientDir, normalizedRequestPath);
360
+ const assetPath = await resolveBuiltAsset(clientDir, normalizedRequestPath);
348
361
  const ext = path.extname(assetPath);
349
362
  try {
350
363
  const payload = await readFile(assetPath);
@@ -2063,6 +2063,15 @@ export function getGamificationCatalog(userIds) {
2063
2063
  const suffix = search.toString() ? `?${search}` : "";
2064
2064
  return request(`/api/v1/gamification/catalog${suffix}`);
2065
2065
  }
2066
+ export function getGamificationAssetStatus() {
2067
+ return request("/api/v1/gamification/assets");
2068
+ }
2069
+ export function installGamificationAssetStyle(style) {
2070
+ return request("/api/v1/gamification/assets/install", {
2071
+ method: "POST",
2072
+ body: JSON.stringify({ style })
2073
+ });
2074
+ }
2066
2075
  export function getGamificationEquipment(userIds) {
2067
2076
  const search = new URLSearchParams();
2068
2077
  appendUserIds(search, coerceUserIds(userIds));
@@ -56,7 +56,7 @@ export const settingsMutationSchema = z.object({
56
56
  timeAccountingMode: z.enum(["split", "parallel", "primary_only"])
57
57
  }),
58
58
  themePreference: forgeThemePreferenceSchema,
59
- gamificationTheme: gamificationThemeSchema.default("dark-fantasy"),
59
+ gamificationTheme: gamificationThemeSchema.default("dramatic-smithie"),
60
60
  customTheme: forgeCustomThemeSchema.nullable().optional(),
61
61
  localePreference: appLocaleSchema,
62
62
  calendarProviders: z
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.58",
5
+ "version": "0.2.60",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.58",
3
+ "version": "0.2.60",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/server/index.js CHANGED
@@ -13,6 +13,7 @@ const devModeFlag = (process.env.FORGE_OPENCLAW_DEV ?? "").trim().toLowerCase();
13
13
  const useDevRuntime = devModeFlag === "1" || devModeFlag === "true" || devModeFlag === "yes";
14
14
 
15
15
  if (!useDevRuntime) {
16
+ process.chdir(packageRoot);
16
17
  await import(pathToFileURL(builtRuntimeEntry).href);
17
18
  } else {
18
19
  if (!existsSync(devRuntimeEntry) || !existsSync(devDataRootWrapper) || !existsSync(tsxCliEntry)) {
@@ -1,2 +1,2 @@
1
1
  ALTER TABLE app_settings
2
- ADD COLUMN gamification_theme TEXT NOT NULL DEFAULT 'dark-fantasy';
2
+ ADD COLUMN gamification_theme TEXT NOT NULL DEFAULT 'dramatic-smithie';