Date: Mon, 19 Oct 2026 16:48:13 -0400
Subject: [PATCH 15/26] GitHub social preview image, 1280x640, from the
banner's mark, wordmark and tagline
---
.github/social-preview.png | Bin 0 -> 23453 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 .github/social-preview.png
diff --git a/.github/social-preview.png b/.github/social-preview.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b2752ed41179d27953cb1a291de7958716994db
GIT binary patch
literal 23453
zcmeFZ`#;nF8$Uj!(os?+
znvX!B1HhO2LO2crFHLKNbP&k$nXcv?6JI2CG~nxH(^RpY#ZT%_L_pNwb5}*Z$iX=t
z!rB40w<{(~e+(qVeA-w3GJ?(71UcX$bW3E*5ea>0G+RN8dN=G^34f_xM@BURJgXSdHN%z|Dw?K;3Vb2
z&4Qo1A0d0cdxCQS*+3z}he2$>>t~yNw}BVXl~16Ptk)x=Aa>v-?Ek>a5grLe}fvugvJQ1BeB?MY%-)-QTW}%>yS9%p()E^4mS}E@m
zVaSWH5X{Du1N1UOb7eEvkO76S&l>ibm;U<~!auKX@pFOp0U})kM7nPYQ8%ewCT@0#
z|JRS-B?gT6PKM>b_CbgtDBMm0SND;JM1qtO#Mj
zIzS6P)eb=y^E?1?fI#(mCqetJUreL<5J+R+x{ZS2|9+Uid&e?bZ5s`B^!xW?pe^D!
z>G|dEbfN6xgh*B}hL~Oiu_ruw6WsB;2B*s&0s?^wj<8+$>Lqx~qoQg)4{N3qyC;h%
zN3w^I+Ili|@==V%$H_`d?c+^is*xUTN%m&S-pHiv80Ce6R00&8nve}Vg2xcVapNNg
z(|WV&y1|jh3DKahdSRSQIIVua&fAORIFrb*K5}I_U;3}4tEZ!shAS6_n;x$GTvr8M
zfCQSU@62XG^D1S!hQ?+1hBg3I_CEf&BFO>j;1Y;%9SQneweZU)-%cksd--Qq(P?(=
z(cO+(-ec&OgwyzJMn3H>)KL+M=vwOyj^+0HdWBPccV#7!W$Vs86$WKa<~Q<*s^RaQ
zL555D*zc`?$&|g%{>D4|zos4rz5Md^{y5|$s0dS0xQX8=?!3HC(u+D-W3wDez}2mL
zV2?Jv+wMp2mF;-#lom|vesiJ}Ioj`VkAKEre{s2SrJ8e0?%31>uOnFQ@I0VRKS21#
z!Y5n2>>>GAU*Yh9JMn~<`yme?;$g;ys)bdH-#QMw{Hl?l3PN7eHl^17YIJnnY1!`u
zr&A%t8^O;D6T6FxbRUX=*xLa=~7sjOj6ujy5GZIO)}G?2$gRks12i>kv}FibC(D9B$CQDZoFEa*vb$;Y!XD!k*NT
z@_Z%AqGz7*BeAR26DP5cLcw!%G}6N{+4kcIe9$L<6HFibc=qWzn)fJNh%aV6W}3uVU+(Q(iG=t2Q~A2NT*d)SF&hRO1A`
z=k#S~6N`Z4fIYtFQ+_8AFXdQ11Mv;=#;WZ&Bs+G=WWIb3`2UOxg3-M)0W+GoIP2=)
zC&V{ro>OrP)pjM+FQP{g#cWJ`6Y^E_{xQ(&wd3(Mj6CcyA+$87{;R5rw^k7Kzp|5^
zZjwbk5)jN-CT<-P(gNt&^9-I5(BfL_d~sYa$|czou!_+z@RZj8*x4FF7wyM=+>D$z#e5_|mQ|CR@F&*M#ZyMQEz(gDCX*8h|O|R;-54NV{t20AWuG>g^?5nR0kUXCT**PWhUI%Bx
z7p)PazRFMo1Ad1&AE%Y%;mVAD61!4djPG&h(!(%RqVbzsi;MR`90fPoE=YO0r=RB4
zTRWMWzfjDyNw!rEk2~DMHR~w*=xIXgNSN^qz?(U+etX|rueXRtZgC+)AV;uAphMGMUb)>$-H
zmHOflUFy0_7XQ|60LsE4~THj+xC-Dfm4%5
z7jl~0TlgA=T4H4I1xpo^B>*~NSCOJjs^^g4gy%-6ORL*T-UeO4m)KY&NJ_Bj
zRIJ@q3#-BZRafGDdkjzZpk+I;2q
zr()zJJgG5mE6|#S5yaK@m(;tUTNYg<0FoyF{Nhst;H@>FXFNbq#|7I{M?TisDp#&H
zDVWeVi@)S1<
z^yNHT&niEu<&t$F#Xyc|qQ4dT8hf(eW_m0iXrfx3;o2HSY=Q|5)peEv26xQfq$+BY
zn8kg5#ri3mUtqAZ!?Lzx#rH35@ho#A4p74@@XYQp@uPJG#!hHlz20Dq3f
zFp8M=c&o#RZpQ1qW%A}&0fS)T^+9API_CGca4G^qT*8P9do*uA5?*!low>De;VTTL
zcQj+NbUZsnO}1429qHGk_m+hdNi-c=AuY*eJ-z$ri~gqpOlo$hth@F0q=~Z8U0AsV
z1v0pu?$5De0@+JV?^Gvj4+%wC5KE7Wx66mo>tF<%GtnFPR;)l&pw>9}w5Nb`6j
zMMOA)t}}?RaS_3ZM#RMg2lj=9rOx|BB7$gg%g8y7!66jP(XLmTx51lT%!pLV)3Jx!
zo3fKRu1&(|I-GO)`Jms)fa7$mv4ek2ISj2^&TT6wU2Fy3U#}%Nd676JV2<wuw)}Z%P^+MbUQ?U-Sy5!&2U4kGIxLy}dn2_esW3
zW#{y%2&8!xdq~M%i9pA%WT!FJKz0rDN_x-$pz{)STU=R*>F5mLK%$7TeN#X=QkzVm
z;#MEdEfnLc%i{=%^n$#KGg2;xt+WRB#sl8sKR7uN3oHA|sJl@<_jYEpe9mCm@gA3~
zz;B)~H>j=x-dTxSHJ`@~0d+R5FRdLt?8ABxgsNO*$y8X)W;2nT+UHmOE6G`Q5??76vnpwHRyWcv0^
zCmKUtpHy|kk^t*cp?ul%JK7CE|7_=eofGD~;PpINLa}OqwNj0EIQ6QMtzv5bX!WLv
z(DtlYZ~wd!^9;^ny5`ta02zmcw|#|C?E5dymBx=H-hwpy+3_SO?(#=;=i^TT5f!CG
zGAlpEAqf|y=_kVxO`zjU~#
zRWIAa%9z+*Oi`m5JcXq-z?NPtt$6~>%zV(Ao(70nkt*%t^bE+Edl0X!%t_o259LdW
zq%m)co{JIFy8wfQRK<8C#;nS6?XlQ)qPNLIFbdX8&HEvHe3QQs=1|Mbt6!HbT!Fp`eS
zd(DH0a7tS1nqkT*P}&Xqw6#;HvoQ5OHc_Cato2*++|%80#Yt2z{+^$A+L@~_P4<|-
zrV(lyyhpy*#7B!@q|
z(D+g!V?S>yNq*rJtR$HE#4!?)`s!7YYm~Oq>W16H)d3c!)3ef3!K29D=y$G&)iUo>*()UvK7qq
z(l7`EPTQ;FzH*2{uOp(SL
zx4!w$xyZH;Wek;rpUwb8Ao7slEi3T4axrkK2(oX28^74Lhth@g;-ie`@B4ZV!%!~)
zDz7^+RJ*jpDKB_HMqfx^QX<_j(L3Vd1!8*f3BNb;Jv@pp9ilKDwE|TS`1`e12A^M=
zxYw__YkL7LKs@+3CbM#8L{io=h9co<4xwaQoUMgLuc+uib~1?Mv5
ztKNK#*HmuKDa6?R)xR0+=9)Y&iq@Yw6XSeYBOBQhoKCHjL#K*HbW1AKr-^Rvo_hf=
ziX_Ise*i)v7j_<_k(i`EGA`!Jqasp(@W|H#ajXj~&Gg(^j;Ao=JmZA!R}IB<*%);9
zc$b;FSPpjP-Bs}bT01}LXfgx&Fp4Br-*$?819c~l)uz;hN2@Uuf(7+wzU(;oB5ujtBk*R
z_ie!UBD^Eu4tCaZX~yOyIAYL2J>kDgx7ijHvrRqUrDB``%~M~idjHICy3Vh>ERu@k
zO)pao@=!9FB)*M-wS?C^kO(p*Y<#(L5p9g5e|R(NfH`~lqX^~80qGra%Gsx2N4o?n
z7v3e(@+IlVag7BJVir|;7<(&d%x&5!Z2VCSa#9(cI=>^R_$1L%Jw5iM-*vFI<4nv(
zAveeXm>RMQ$yqHg&CI(*v>*81w;B(LG7&e2wS*t0UylIAG*K06e16d#rKdjlspW(UhqeQv%!bbbqGs!X^U{(exWvZg|(@(qTW1C}(iNnp|SdNdx
zgO!R@*sKEXS#qK
zce(Kgp#4ktUozoVgmV!K?7RXq_m60IU1^f=(D(tsY?!=<6VNdcAPA6m4U&^nw?-oH
zD0$-BhWM#6U6S25PN4NFgW8+=np)Kk-b8wzgVJjnr5lchmYr^%sgcR|gh>
z1meSY%7<{dy%UO-TJXHTbZ^3MsVQzme$hYW8_4Y&a^XV}g+HVY=;m4f6b98$F~w%A
zLN$A+2oT`GF_0%Q9d<|weOIoxJTpmzGJwy{Bn!(zmA|=IV{gZHR7RJ;q!KOpOV2l$
zCUU>`p}wb->7vH(McD-WdMN^(uK?6#rgK6_P>`EzWIY#F+do}q96l)*hZ}zUiW5rmvijJHTj7Q_IqNleFQVKFKlsNZFs_X)uxn}%%
zV8bsQOv;Evo{I&^z3R8xSI_!DdoUiP&m!ZRIx0$22#emSleDS(*o+4SPBC-800ux`^)rXZoI%*>;hFQ`jR*Pl_~HZ@pUUHStvLQYo#P
zjB!QhzVL9gOM|-uy?d3K>GJ5mWlH8FoTK)CDe@%dQY-TdM?7^Bk8gIL1|lVBeBYO-g#>O$9~@Ko7d67QoauN;l|+b}Z^
z;`4l)Ym_7puD@?vs{((Jw5D>un&h2&!+=9|uMa2%Q%hIo8ti9cdQ1qAL-_vD%
z1x{iLdX^^bLLRU7x~F$R*M56-z$A>^IlaQTE%2V@DsDNyDm0pOX
zIRykpby&>gg_CwN)h2j)i#&+A3w6WyyOhM0rZ^Sv1SevCD)M?;So15=r5vl~6kU^%
zYt)RQbPzDld1=i7N(=+J`PY}e^VoorVjdfWU3>LPONHrr$^H`F42zp7YsyGtDtzF6
zgR!6><>&HCM>V^4%2m}`r*C+kX_gkC7sakfPL&xCB1%6Z@gKFqb}v%QHYFCsfg_`X
zc;LqmNErYSZp#Beki?}2zw6_g2wJ?g*Ys&lM!dy<8}6&0BnqknE~tft8yu3;%cmfv
zs6f302HNWtZD&S;el0Xfl|{?b;*9wba7;=#K5grmV`k@u;fFra4hcbiw^5qVB29h}
z>77iQ?Wt%{ccHmvI@PXUM2lA=Gd;VC*BpVoGP{8M%M*N)Ds#vtjb(zpUG+T+c+>G^
zLt{qLVCXa5fkDpWk_PnCA{sn$Kdw_?1?d2YKR*si9FOi$gvk`DO>9}P`cXdyMETlt
zqwADN`Zt7g+M)5!&rr5F_FiyR{cU#&QhEXII8g+&V`_npcUG=8m%G}#`X>OT)9{9zFp
zxlY9h{ED9qB6;ut@J~YKM;dohA)$GMpg__;5&E-xa
zSrJB{RX94v!9T7gl^&z*Kl#U3He8wJ<@TGAy(T!9YHB{gBDYUN21pft1QB4qn!V%6
zpa~UhSi3z&M1g$
zD>ZeaVP&}#|NY3zsvm&m1`G@e-(%irw7>c|iud!UqD6L{WOjTKJc!VQ
z@_6Ix>2oDFofIkPk&U0w{Gv8f~8`cgOR|?ptS&X{3Vf*^$JLXoj
zPM&Ol@kcH`gva%rO&QSbgf5#B%8aWP%S*yP3#0X`Bs|Xmfd)7d+DxO*?)iX6mtiF}
zsn2XJZ&ho+w9CHhTR$f-N15%sk*3bO1hg0f1mukJ{@q|_M0m$;K(dgL)c5p}%;z8a
z*p4Pz`}@H=l}XXa&bf#B)gQgBJ?8D6=t!Yo*XAXA-}iL1d&0jdPPsLA&IBMNgU^dH
z0IYdVo$9~u;9v0bN!Rw(%>$x}FuCG$5LRf-+<3qMrpzzLG`Dy!+K`3Y!*9Rt6j1gq
z1NsucxQg+PQr+S?#&eaTp}r0;!QHEr1XTi+fC;bF$`4tBm4PxV%z#E@Z=a*ce~AG5
zV<#{0%(cHg1bKY|*<%JMAz`L=De~5z$o^*>8GCS)FK#SD@?CaUjzjYx9VhE%yfhle
zYI)5Dam?3HN4S=~q!I!)9ktay_pp=oi3T-ZHqPQyQpwF)RZhtms5h+%5
ze8}E8gH3Ox=IF^sl7gFHSn)Q?Po7H7=rsQ)M;hzOzhT*QR(RQLELSsLVkAL_fnf22
zZ)AT5J~g!j*#(9ObUgoP%)jOwuf={w5!MS&%D;k6eF0Whq(oU18v~3|kcF?`Eyijb
z16g5vHm;fzw8MfD+D87^qfuZE+h>Af1t*+A%U4ZyGJ64EfY<2$rmI&->Wf=<9q_4;
zm^2%D&LyH`_srf>+Ezx}1@o~l{mD8hAy!Z|xp8?TGX@QBE%GO&vYeCFUWPv(;>Rj|-_;Ah
zinIvFCbyFG6~}vYgmNY7W(ik0=7QJBX{sHb3vh!ru|*D{rs*k&A+&6hUj30L`6w+5cxykr(Vf&co}5eDBFMViHvm6_?m?
zVbgo)B%2NU%lxVOm&K;b)f=_YyxI}05M|)e((j%3rCpZra8HdE--EyM)LlK2k=`+$
zaAYav>3{j|puz434`9LyK$00H+OPd^T2=pua7=zS58y@gJHQgeQC3HNRz*k5pJ!s9
zibS)bAf|2tYn>o>-}!on7k#-w2XwddyyUF{-vZ80B!SRWp+GDrk)W1mug
zQShy`pTR1DCHqa`e}mcmYNKQNE$uiywhFzfsCNqsjlqH*u0AI!vCOvsb9+3sw(Q{&
z@A9oqQGkk6kSu-&q#}wm_CMhZ@DsFkqp(iAq;0Bag5n?G_-EwuiuApJ^SgypR+`s*
zF{Lb~Pr+p{IyjSe+I7@{1eVHssq;q@r@Bhu_+3&MHjFPF-XR`b^3~EbF=2;vj
z-K-r!U%m&BIZetcSRBwio9kAys~sp&_M#OOWuMVAc%u!Du#k
z{@SZaeDL@KPoYB0M-KO*K!%fL>U;4QS?`V5Z@8ikIKfr_Xshh~euAlj9
zmb?P%vpEW9%7a_a+MD!Qzqu)auB8J=RKc54qJKK6-%6D!{VX=YH9l
zHp3|2H1t}ZzuxwT*E`@1d
zIwY!Vs&G-YqZH1&w6!WuUSe{Er-7<0w{S2+-~?x!%b&_i`i^sk}tN$#|A%
z*U;ddynJL8bZvOQ)B~Vhl|7+#X0`F11;GC(!m4glZtxy0pubiMZ&ScAvPg##3DH7z
z=|o(xxc+p+=ND%+>PIZA=Xdg$fT=6$lpgnKhRG^r!%`6&iUigYoGd}lrMto&{~%1{
zIOQT%+?L%qg^16M_UmuFS9YgNiys`D0+c&dKTZGYGg!+@9pOFPLeV*Y7py%f$3^+<
zd-_h7WY~^F(?1Lk>_*fj9Pj?fn&taNJvllEVKz7}AK=Z-{jIsRSv3fbBOG=RAxaY6
z&os;Y5=KJlJZ)98&EhxN7e#>0lqVw|3+4f5E#3o0=Y?%o;)8P&X-QcRQl_Jb-w|_q
zUEhd5V39dVqLLc9KtA^K_T}aJ4=Q3$of?@JdVwg4#83}~r|{j2CWaC7xR
z`quQx`V0VMlB%~R%uRvjfdQbtPGzz&*njRhH19mCJ=`*5`KVitv?A#uQcJ@WXU8-p
z&E*r`(@$=?bM^0z@dpRL5U6yQ&YO&N-RX8)*EL6YUjtfP@jvtIko>-(Im<{=mZws^
z2x2M49ZVEPzfSwRXloxfRHQyk{Fi5@mG@11Uh0BNpK{}|eP+94uc^XwSunPj@Xs93
z5rcoVr3ZQ}%UT>+SSStV`E}1~y|u;l@Qj@Q&7TVywXTY|2-GF*{nl$;KF3ihvJZNo
z;fWRNT(hlJ-iTIXumSpoOpo-E4Ey3K-%tr!s`3%3=E^Hwx`_E+9_gD`?3*17VC#fo
z7u)|#Onw6f?E(k*Cboir^(<$E9{y(}1Uf%FX~a*l=+E6{QD>R=atNU8IVNTe$UagC@*f6l&BdY-y=_
z`JDGTkFlv+x?aCCWO@db-af`54LV;4n?!?dXsb=V!_YUE16()meR{9F<9bQkSvz`q
z%tesI1g5JO0=D6FW8c8ZXoaj?l@fK~uMXGI@)>HAzR6+#Ns?wPlrN%#=Dm@AFW@x7
z@;Si;aI=4nWa@HNpuzgEcZnK|^xRsmuD$9VK9etf*sT9Me6I9!EF8od{LM_TIEnSD
zB`#?+!e!y74AY$!7aLfhbp62P{7b~EF5A&Zm;EAmMVgPEGBZ^XxvF#(F=*yB6XWhfnq~0hn6cvbwamMed&(EO3Kn2qS^=K&on^ZWGe)1-G$=3
z`NfBI!pfXTntbP6hxP^&t;eboGQ{_snNKKjnLy*cBu&Jg{s-kK9k&jZ^^{8h{n3S+
z=0-pnSL&_3!>2EZI=gx_>(&4<93ReF7i_Z0jjYoNmHZp%&QPX!>weY9eiREj%#F8F
zn~V~u4UXCGtOcaC&OL@x?%m+K$;q*^UJ&LUr%APs54~`=rny6HZ-tX=DWKTvY9rg3
zrutkZQB?auYtDCzh?Q%vuu}6QT8QX843~b&+^!OoTu?i<0-%Hx}H{i-6Exfh!5r`2juiKe#y9|O+z*b`X
zz6Or{g20-}xTkTZ>WTAP{&~fd@Pz9`WhIPHp0QD+8g
z)<&U6KJx?7X1;m@*!}`mL4zhIrKL5Xh4E)9uh>UsJ
z@+T9eD#U_f&(Zcjkq{u2qf_UnPMr;j%=}_M^E0l#OU4FazCE@=
zZ~?^+02X;;updexRR{lFN&rzZX|^i!%nWt>554dLx7evo@M^4`8gz8;JopFGt7)|D
z+B3c%Djo(+rUV5)z4PnJ7X8N)ti3;6x;S!O>v7A85!upnqtX)CyXAF3IW(q%6GHuH
zzRSn?{9^C+LRPoP(n9lL+olch(PjjV$wq!(4yT&xoZNG~ri6FsTO>x#%z
z&!iwdyOKI!UxR7p3j{Ek(Y11C^3Phay)>pN^qH5{gg7FS4@yJ>)#WkNw!#9?iaQ^l
zdBT)^hlS=oJg$PY+9PatAmfnPNBnCi+vqi~-~BtS6{L0+G)k*=tVsT$183(Q(_%wE
zwNcJ}Rb{QAT4Z-$aN&$O+B912gYKUGxt_XYn?-J@UOH#3xk>xHTx2V2p$qKRiAr>_
zMsjaoE?j#D5_7SmuB9*adCfi4vfQMB7!trbR=iS+5b{Avi+gRsMbCbH6jt2_$YS9L
z>E-{R11e7T$sBC1RnlXcbyjV@fiZ3W7R_S*8amno5Q^1N4~+;}gkNQk!h$8@fmTDR
z#3_8Pfhx7%E1gm1I9LRpt2TuL+(_@(A-iXga0Q&8s(0Ws@=p5QrlU>IPo=(<%s$#)
z>Mcl4qYArVV`3V=!6)Ro=~p!h_|laO!OAA9AO@dw-(U(C>0NzUF_)`;i|1$IXRKwk
zx+gU`sTS<}!A^Dq6ILV)_t<|H6nNtBj|{xiSeJybPAkE?ltLt}@V9MTNBvJ|#
zR;&g*kE6xi`od=M<_@Wh;%HzKc^-3=sV$rn(bZU!HW+_hqkzNBKpD0nGSo^VqyuZO
z3O{Kr7r6Yj(4}}TSJ-qJnEb**S&^iWEC1sE4l83tQV-T|5YKWckBzn)3)fyv@Noq>
zYiIsC5ON#Xwy1AZeIHaRc=1Fm
z-376871NvZPGhy*-uxCOuoh2YyXM&}Mt7o`lO0dS*o?q`5s|Wz96J>?{tWLKM4IKF
z(+`-c91#fuGSFHT+)56Y4eOO3^SuuwQQv_9
z;?B}TE&D4oyfBr>u7_{3SsQ|ga;q6rORgYo#?Q>-J4MlT;(z+D|0o#n#P8Bdt@Z-!
z64$o)|1h6#gQg=qfh$GJCtL-VC)Xs^)_|^=5TJzKllwLdx3J|EaLUGhh|ocKgjJ3q
zcRG1#R8n9m-mhjD8*Sm8GjaKr^tFtRqZYPV&%DA#wk%D;DhiFnzIJ#IYKg5Z_K)?P
zSaW{OvF{IqotdeO;c72CZkHjR(!ccLKasgA9OBVT(MGlTveT=LbA(Xbk$WxOEEAdK
z7G)R+b400E4r1M@-J7N0msDM#bU1U-CiqP-Rf~_0cWzbh$2fV;&_%rUKtPSG=)ROs
zF=1Fq%UN@U4v^a=C5@h^F`wnElRX!QdY;m?m18x#d0}TJmK|_g0bBxDwdg^!aB3_j
zC*L(#FBXH-SKhzIn{INxk7lQ`7vpIKK0oNL7q%5Z0is4`La*%>NCsG$PcV2B;u>J7
zqPOj^^X_~jZm;=DxWBl;e79CTuRulIY`?hwy0+yS>v}{;3s4+BfSQs|)Hq0g`xOb<
z{f$A8B)5TWW6(nh0LsdQ*#k+It4D1>z5v^2ACS{yP@+!Psr+9vQORGsLS>j1=iEAuvTPsSr=Jc
zs#fn3z`#xjq8zaZ?DSUw+r#`co#lT$rgy^omlJbEwdwZPXYSR@DM8Fm!k0wrw7OS&
ztUEEEt$mcI7ig4<=zf!V{p*6)5ubXUdt-$qD#n4Ae&|Ub&CDS-Y4v>
zza~T1Y)V^9ghebr(lf}-$6me
zz*`9WZOvJ%JwEO9PVF}(;18x`t77{2N2)84_081U8$kO1`#CEWIzosnrNAvW
z_~LBO{A@`kfwgx9TnKU7Nt^`w$q9SNU5~g@bYAE<$>Y)@tL?l;CLnE|G)G~wJx7r}Hyh?9nZMIyO-&{Jdm{6BanF2`i9z!6djaK`kP6T_0{w|Y
zy>1^H-k0_5-iKdf;z^u=wN=bLp)a{qfxyF{*vLsR>+iVPE`Wf)1Kk@Q*ce4>prWri
zQ~bI9Q;^3Pkkr_fbFMtc!Q>*PWb-JE#RY2C>b|HR5~R9IVL*I9+AGyO2iN1bOZ|zk
zAo+M6LCEL5x0GCaj8|)}i$I)ib&^&9MQyhP-W8(PNYbhV$pg@;gCV6kp(C(iy~W}o
z*NYqGi&(#i>DJ#mJB}itE5IHKNOV>iWW{>g0r|YI!@Kk9GX4?mh|N*uz`BvUoT`7-
zDLs|qGrdmqFhC@Pn5Y=JeO=)y~oRKO;5f@iS93j@F^i?^VJS{_ha&-@B4v%^KN7B!+qZ0Sn+SMNzr{v>(k{fIug1uI8MA>6GVag@Paa%2Sp#q#)#qxuf
zkP$JA;3{fD#KobC2Adrv?N4sNohcOG!zib3E`6GOHvtWwqL)exc*4k?(HO;7(ZC&{
z5w8?GHGY16)9~rQrBaj{v@U+%$LuA;J409;oTB@5sN%6UAK_kL?eI;KGqWRj;f&aU
z??6MU$fcHs?=zukzVB~tQ{RYtT7OzpKv^FvmvAFo75-bIu+fhiLQ
zK7?R)5Nh2wuTJ!`v&%f<9<{f%NAHtoTtSpq7Gj=HS>}S5syA`jxpM%~+Lp6u1M0%T
zm4!n>fl>%~qc2rr_NLx%^`+6uxUfM<(`b*4?aXv0!
zHoZTW>3UUmi@q+|7OlObcT-SUZTc!MS!veZ1ec~nXRc8=vro_@^HI!Q${Zwy|JXq&
zqbNr-_fQCp27E)1L2Va|@3ia&?M~8B92SjPpPyf9#7PG3$;>eWZXnzwy=p`6VA^rS!tM9#|`Ih`0gM?XxUtNdEc0J!6|DjyJVEM6G1y)
z&V11kMP&lY{+)#o6w#iVz6qg#|E^sr(@Xb4s
z*A1(P-yLOLIN#ajUKIo9g|c4-V=k{7Y_>e(H7%R>0#+Ih^_hzu>t%9xj27_N2GQU`
z5q>adAjaO$l&o%fg;zx}c-GFll7|uoA=?4Nl(;ZKe}^smtT`p^hrF50R>G#wB6cfy
zo_3S(yesM?skEfTh@h`b0o8j0jOcF*g{h?V!5c!0^#nHUvzC!3(=DR-&V_OTYgVSf
z9yRX1u_2GZg3&$Rj8et~FK#N!V0#M>!vp~rb_SM(_Qr+sY6BpCk5*2lYqQ&Jl9`$7
zgjEy*X#3qa7PBPz*rwcNkHjl)*2uy&elDj4ED07-?x|kj%Pod{T9=8RAzV@+{s5Fq
zDzTtPkN7X3IGeKLhQ@}L+$YmJvZ#k?&vn8#hU{>9bUzsA~avkR-)Ozb!R{;
zWr_YfF)gPpu5$oe$KbluQWb-jaon{eSFJ^m0-JE#wF+v`fO%@)rS{Z~wUXnshc_F)
z>9$$32aqcm_1v&icLuX;8|7Mf)VG23al5f0d1IO
zj`r2hH|M9-gC}p78>K9#kUa>x3mhQQA6$Rz1+4A2e{}Vo)D;+wtGMjqMTdELlig|6
zz5VeBAlQop16LYk;Wd3~S1+B<4Pyh4uy7JU!X5k@XoH1UyZY*CERg+Ln^GQ<-%7!P
z(gj~>cGD8D)*rKD_#xKpoPTsKXQAplT)-ec1`I)lVS<}{KYb(k$6&X!deWTeE(U9(
zIohJ-@E8Y_13C_xnJ0Xkv^gyn781X&ewB(EFiWq4P0F1YY08eC<=+JE%+5xHxYi7`
zI$hVO?VORT8_}gcB6l^|yvMA)a~#spGNhsEgQV-n2c13i9X;Vhf=H%c&sl{{8iQ)1?-CQr|t(=p*q;X*7f7
zECcTxrXD*R7l)oPq;1tt`vQ-MZN{Wv@Yrs`Tz><
zlG|BGRW4DDZ~VN|p2iYy{GDU+P_}=&Ip^*9hNjOAHMRi@PwybC73WDxb&~U~ue1Hb
z6~Ax!YwQ03uztYpVq={bGStYdcP{|%UcK$pt5)n991j=Z{N8%E&i|I2_==*(7Qpwp
ziXe#2>OSC2@1ev!{)i`$$w%WgN<`Ug5Q6%S7yGda^B3mRi|X(i@vvOHXCSJdq)w!Y
zyCMR1=vU|RI}sZ)sQXMZfY|D^C+hgNe=q
z_ElS;YxZRN8l&R;bplHLFh=AV-=yXWf6!3Yq&4TQR??+cg+{;ll8b_WN~XzdtwRF*
z%RMQj#yZTabJd0})w=0TmuO6}AhkW570pkdl;Gdp|4b;%zgmY+AhU0NU?cVMhOaW^
z99g|j+nPXV%Fc7R+qhL%6!u#Gb%lRDZ)#{;~lgW9QTpc(iH>@Cj01hNG=rF&j!>Qgd=vskLlYY$hL$cWGhVP_0%yP4m{P5C_
zUoKQ&A4m+ivRuzjGqAUee--PG_9^|9`5oV1&e+zqH5p~bb6d<&AiZ
z`$!q8_|T=NDz~Beb-3i1nfzk1jnq9-pw>qx)@P>3=Sk&K8+~&Iyi~D{`Jx>zPWjJW
zvg;%!=_-ye*;g{!4$-lVq@UtgB;QpfSlZK4E?e3!_nOfKc(?4-5n3|8>!v^b_`%of
z%fN}U8O)Siyh7A+VmU$qjT+8r^zE)py0xK`xvPOlqixF_UeHi|m@1oGp@tVFftlN%
z$jeqbZh}
zQU`)K_X>!wzWbh(`OZ4(SyZbB3tq>lc$eJp*!+n
z{@ph_%R)qDExau&7oG@7%fnC<|FKH3uqU**ukjjr{ukub8pZn;WCwk#2eEJ|zN}ze
zMjpu#=#BQ;<_-5a7KDwML<<8>sA{-G1yBHJsHX$qZ$Wut+)UntzhMx^AzM=|50<
zu*s-oRRJWG$|9#j1$UA8x@at5DLKYAu7FSKqdJ@`tPPo2}bD|7q_i)IqN5knyJdNGJc)8
ziM}3*GD$+&N!{`T&tt!y5Zw(xus?kh#w9#JV5E}Uxjj6iXj6knh9kzQ>zs?31fh}o_
zGaWySAUF)GfWSaAkHixt`mu^pheT4&a^7lV;s6iKuPZV{%zwwayJXL)#rmarc2z?2
zQhhfjw>WUC8@afZ7erii|DYd>&IZ({alM3kVS^lXe1|eEC_{V*J!T(@F}K>6`zihV!rXHbU7a
z`bX3DQgFlfCVHf))H*W_GsFFJqH81i}RP~U{0Lx0mK$ewUp5@D@
zO|_46V<%hNJ6A0~rbtvruQK|wf*L7m0m7PsWXeT*dde-2Elqwx6Utwz!UEiXw^5gx
zk{PrM;KSdD=c?f1U+scW7E@I&wLYrf^b@*<+}N11qQMtS56;J);Ygvnf`*FzxEuM7
z*59s{vav>6Dbzjrkdv)(iv=X{jj8UIj6l`0l=bDw?9r~X0!$8&2K!a69OuigP>}79
zklcw4N}oXhk$de&3C48|VPwvkHIeY6!qojb&Cl@2(|M*EY#4^vwG;BQH8BNJmC(2X
z6g7Yi?!_5;K#0YLhV!#q
zyPEh=_AqE+oM;n|I%`fIjNi~@knaNdtGI2eG9$>^;ap5B2KawXB;U4~mTmgFSwY$g
z=gWhvbVhX;hVjM_&{trf3#6?N`|5S?G*sXb8_n&7Qfjz|DEs&>nwh$g0DbmXn6Kyv
zixx>q4e2o`ZB5~;E70DZL9GyDp>YfW@A@1@o}p(*Xteb>lzuh6&HePpm3v3xwI}4j
z-j+QBJu@Pfg-)u#Pd5AzbUPGo?*}vw#iL#O=6AZUkP>jcp1%hfu}wI32e+lJX8oe9~GO-k=
zhU6S-iw~-+i?M`x)*cjb7KmOP(L<;kJdp=Ev)ZelYzX`7{ku;+weUiUg*x>#FwN$l
zk%O7B0BMZEOFEyKjb?$$un=IbhVjMvX&|v
zQmvp>hpHs5i!|*bLZS?FsN*UkwbUF@44^$y?&4BST3~h
zJ8_D{AbaNhBYH&+6Y!V}WM@G^!G8akw&(I*4uPka=PaJSoH02sK#(^G@)(I#E%%9-
z5Fv8CB6pp1&_Yu5u|%${6k=A6U#M7k9V?
zd6*Q4Z;q`Dwmj;jkL1Qi-_?rSl7Zx;#&?y;`uv!%jP&MG6eLb-EPupxR-e{=8=Bpl
zAG&&HPKZZ)Bu&uWlrp`p4%yEsyN>j~4I;ChUe`EV(9bEAuglvi4B-RUvh@7eugVi}
zBz5oj-tFly$9qYG4RfnaNDvrZQ0AHm<6RFo
zR4?QSJK}+CiIc^WWK4sj_0EH9#0~`em{=&oQKWF91pj-6g+JPW=(Kx2b;@ki1?dnh
z7G?|+1+w!dV`wzC&jZ|E5+mHs?+mCl$K%B*?r%hKbXuMpk~dT3wQtnXOhQ#PeHcSk
z=-t8eqt^IWOAa@9%H!-r4eF3K?tov}jheD?5|#;TvE($5f?TRNtXY>~vj^Bi&TJk_
zS+P+Uc~+`&s@-E#Lk+%Fc`*F$GbR*`a@(`*+RONg1b9z}JXJ0M{tn$`XLr->CW|w<
z-le=K676BC^3Thpm8!}8RGK}!mJv~uR-bpvT7(oOHl4FSh;Gh2wf>(*X(h3?bV1Lv
z%Tq{BIGl0$6cBo@`k`!chr0M}nn_bo>uKTY49D*b&Y)bw^>xbCJF}L#aRRSv$?r+_
zt1`DbR7fk9u#w9=2z+SX4)A1|lZ0bj;VtCM#CN{_wP@`}q$Xi}bjw
zA%de_(bZf=Ma3S%qH!2P*aG_d>DM
zmS+n`@h^BJ0pfm)pt3gEM{aj|4AEhSWoNGa5r-horTdr#$US
z388*ckLDlpPrEd6IN00?hUuJTfkugG`a^~@Dq0bqZqLLj7cym|WyLBWqA$2Ip@@lf
z-k8ftqPx01q46Nt@&}yFHv)}00uR}U2RynZsK&)aKX=}xej7)aAmRS%NZqC55NT86NGTXOiK9Y5v7wBCD6Bx8XaH
zyi!y7_Nz*+pJwz5owY^-comMQ44I*UjB)31&xC$zPcz$Xsvj|J)ErY3m5*iq)gQUD
zT1~dq@}53X4aOrRe?xus%Mj{h%<3|+$5V~{mK}x8BXEWyaXBrAq^5m^Q|#0)L{WpB
zuOUDB0EG$JN)V%5fw>GYfp~$IHb~d^V1S&2=vYA>e+~wSp%;jY^Zgi1K~1sykeCESPo~1Ze3zc(ww)0w%AQx>;a?oOIN&($1U9o3Ma1*i47bT>{czvpVQl0T?!`
d;{QA>)TsO2VUa~5E2
Date: Mon, 19 Oct 2026 16:55:50 -0400
Subject: [PATCH 16/26] SEO: cross-links, searched post titles, breadcrumb and
FAQ schema, llms-full.txt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Integration pages link to the matching blog posts, and the books and
public-pages docs link the posts they explain. /open links the TrustMRR
comparison.
- Nav and footer Docs links go to /docs/connectors instead of the /docs
redirect. The footer adds Benchmarks (/data), and its column titles are
h2 so pages keep an unbroken heading outline.
- Posts use the wordings people search: the Stripe books post names the
Stripe Connector by QuickBooks, the tax post names the T2125 and
Schedule C, and the token post's price section names Claude and OpenAI
API pricing. Post title tags drop the " · OpenProfit" suffix.
- Descriptions over 155 characters are trimmed, and the changelog's is
longer. Comparison pages show when they were last updated.
- JSON-LD: breadcrumbs on docs, integration, comparison and blog pages,
FAQPage from an integration page's common questions, TechArticle on docs.
- The sitemap gives blog URLs a lastmod. /llms-full.txt joins the markdown
of every page /llms.txt lists.
---
src/components/landing/footer.tsx | 5 ++-
src/components/landing/nav.tsx | 2 +-
src/content/blog/ai-token-cost-per-user.md | 2 +-
src/content/blog/stripe-quickbooks-xero.md | 12 +++---
.../blog/tax-lines-for-software-costs.md | 4 +-
src/content/changelog.md | 2 +-
src/content/compare/baremetrics.md | 4 +-
src/content/compare/profitwell.md | 4 +-
src/content/compare/spreadsheet.md | 2 +
src/content/data.md | 2 +-
src/content/integrations/anthropic.md | 2 +
src/content/integrations/firecrawl.md | 2 +-
src/content/integrations/lemonsqueezy.md | 2 +
src/content/integrations/mongodb.md | 2 +-
src/content/integrations/openai.md | 2 +-
src/content/integrations/openrouter.md | 2 +
src/content/integrations/paddle.md | 2 +
src/content/integrations/polar.md | 2 +
src/content/integrations/railway.md | 2 +
src/content/integrations/stripe.md | 2 +
src/docs/books.md | 4 +-
src/docs/public-pages.md | 2 +
src/lib/app.ts | 18 +++++++++
src/lib/content.ts | 12 ++++++
src/routeTree.gen.ts | 21 ++++++++++
src/routes/blog.$slug.tsx | 38 +++++++++++--------
src/routes/compare.$slug.tsx | 22 ++++++++---
src/routes/docs.$slug.tsx | 30 ++++++++++++---
src/routes/integrations.$slug.tsx | 38 ++++++++++++++++---
src/routes/llms-full[.]txt.ts | 29 ++++++++++++++
src/routes/llms[.]txt.ts | 2 +-
src/routes/open.tsx | 8 ++++
src/routes/sitemap[.]xml.ts | 9 ++++-
src/server/content.functions.ts | 10 ++++-
34 files changed, 245 insertions(+), 57 deletions(-)
create mode 100644 src/routes/llms-full[.]txt.ts
diff --git a/src/components/landing/footer.tsx b/src/components/landing/footer.tsx
index c0c73b9..a1c59e9 100644
--- a/src/components/landing/footer.tsx
+++ b/src/components/landing/footer.tsx
@@ -9,6 +9,7 @@ const COLUMNS: [string, [string, string][]][] = [
["Integrations", "/integrations"],
["Public pages", "/docs/public-pages"],
["Profit database", "/open"],
+ ["Benchmarks", "/data"],
["Pricing", "/#pricing"],
["Changelog", "/changelog"],
["Blog", "/blog"],
@@ -17,7 +18,7 @@ const COLUMNS: [string, [string, string][]][] = [
[
"Developers",
[
- ["Docs", "/docs"],
+ ["Docs", "/docs/connectors"],
["Self-host", "/docs/self-host"],
["GitHub", GITHUB_URL],
],
@@ -55,7 +56,7 @@ export function Footer() {
{COLUMNS.map(([title, links]) => (
-
{title}
+
{title}
{links.map(([label, href]) => (
diff --git a/src/components/landing/nav.tsx b/src/components/landing/nav.tsx
index 9c5d982..bdc5f8e 100644
--- a/src/components/landing/nav.tsx
+++ b/src/components/landing/nav.tsx
@@ -9,7 +9,7 @@ const LINKS = [
["Product", "/#product"],
["Integrations", "/integrations"],
["Pricing", "/#pricing"],
- ["Docs", "/docs"],
+ ["Docs", "/docs/connectors"],
["Blog", "/blog"],
];
diff --git a/src/content/blog/ai-token-cost-per-user.md b/src/content/blog/ai-token-cost-per-user.md
index b04dffd..a12c982 100644
--- a/src/content/blog/ai-token-cost-per-user.md
+++ b/src/content/blog/ai-token-cost-per-user.md
@@ -22,7 +22,7 @@ Cost per user per month = calls per month × cost of one call
Prices are per million tokens, so divide by 1,000,000. If you use prompt caching, add a line for cached input, which the provider bills at a lower rate when you resend the same prompt prefix.
-## Token prices in October 2026
+## Claude and OpenAI API pricing in October 2026
Standard prices per million tokens, from the [Claude pricing page](https://claude.com/pricing) and the [OpenAI pricing page](https://developers.openai.com/api/docs/pricing) on October 19, 2026:
diff --git a/src/content/blog/stripe-quickbooks-xero.md b/src/content/blog/stripe-quickbooks-xero.md
index 6e42815..eab278d 100644
--- a/src/content/blog/stripe-quickbooks-xero.md
+++ b/src/content/blog/stripe-quickbooks-xero.md
@@ -1,13 +1,13 @@
---
-title: How to get Stripe into QuickBooks or Xero
-description: A Stripe payout is net of fees and refunds, so the deposit isn't your revenue. The entries your books need, and four ways to get Stripe into QuickBooks or Xero.
+title: Stripe QuickBooks and Xero integration: four ways compared
+description: A Stripe payout is net of fees and refunds. The entries your books need, and four ways in, from the Stripe Connector by QuickBooks to Xero's Stripe feed.
date: 2026-10-08
author: Raphael Morency
---
-# How to get Stripe into QuickBooks or Xero
+# Stripe QuickBooks and Xero integration: four ways compared
-Stripe pays you a payout net of its fees, refunds and disputes, so the deposit in your bank isn't your revenue. QuickBooks or Xero needs your gross sales, fees and refunds on separate lines, and the payout recorded as a transfer to your bank. This guide shows the entries, then compares four ways to make them: QuickBooks' own Stripe integration, Xero's Stripe feed, a sync app, and a monthly journal file from OpenProfit.
+Stripe pays you a payout net of its fees, refunds and disputes, so the deposit in your bank isn't your revenue. QuickBooks or Xero needs your gross sales, fees and refunds on separate lines, and the payout recorded as a transfer to your bank. This guide shows the entries, then compares four ways to make them: the Stripe Connector by QuickBooks, Xero's Stripe feed, a sync app, and a monthly journal file from OpenProfit.
## Why the deposit isn't your revenue
@@ -46,9 +46,9 @@ Three more things change the entries:
Each option below records the same entries. They differ in detail, price and which costs they cover.
-### QuickBooks' own Stripe integration
+### Stripe Connector by QuickBooks
-Intuit's [Stripe connection for QuickBooks Online](https://quickbooks.intuit.com/learn-support/en-us/help-article/manage-integrations/connect-manage-stripe-transactions-quickbooks/L10TzOVcN_US_en_US) imports sales, refunds, payouts and adjustments. Each sale shows its gross amount, fee and net, with the fee posted to a "Stripe Fees" expense account. Each payout becomes a deposit linked to the sales and fees inside it.
+Intuit's [Stripe Connector by QuickBooks](https://quickbooks.intuit.com/learn-support/en-us/help-article/manage-integrations/connect-manage-stripe-transactions-quickbooks/L10TzOVcN_US_en_US) imports sales, refunds, payouts and adjustments. Each sale shows its gross amount, fee and net, with the fee posted to a "Stripe Fees" expense account. Each payout becomes a deposit linked to the sales and fees inside it.
Its help article, updated September 21, 2026, lists these limits:
diff --git a/src/content/blog/tax-lines-for-software-costs.md b/src/content/blog/tax-lines-for-software-costs.md
index 2bc652f..dcc0f1c 100644
--- a/src/content/blog/tax-lines-for-software-costs.md
+++ b/src/content/blog/tax-lines-for-software-costs.md
@@ -1,11 +1,11 @@
---
-title: Which tax line do OpenAI, Vercel and Stripe fees go on?
+title: T2125 and Schedule C lines for OpenAI, Vercel and Stripe fees
description: The T2125, TP-80, GIFI, Schedule C and Form 1120 lines for AI APIs, hosting, payment fees, refunds, contractors and a laptop, checked against the 2025 forms.
date: 2026-10-08
author: Raphael Morency
---
-# Which tax line do OpenAI, Vercel and Stripe fees go on?
+# T2125 and Schedule C lines for OpenAI, Vercel and Stripe fees
No tax form has a line for AI APIs, hosting or email. In Canada they go under other expenses (T2125 line 9270, TP-80 line 246), or computer-related expenses (GIFI code 9150) for a corporation. In the US they go in Part V of Schedule C, or on line 26 of Form 1120. Payment fees, refunds, contractors and a laptop each have a better line, listed below.
diff --git a/src/content/changelog.md b/src/content/changelog.md
index 528445d..1f3ed05 100644
--- a/src/content/changelog.md
+++ b/src/content/changelog.md
@@ -1,6 +1,6 @@
---
title: Changelog
-description: What's new in OpenProfit. Every release, newest first.
+description: Every OpenProfit release, newest first, from Books and the tax report to flat costs, alert emails and chart fixes.
---
# Changelog
diff --git a/src/content/compare/baremetrics.md b/src/content/compare/baremetrics.md
index 1c92b19..3e717a4 100644
--- a/src/content/compare/baremetrics.md
+++ b/src/content/compare/baremetrics.md
@@ -1,10 +1,12 @@
---
title: OpenProfit vs Baremetrics
-description: Baremetrics is hosted subscription analytics priced by your ARR. OpenProfit reads your AI and hosting bills, shows profit per product, and gives you the numbers for your tax return.
+description: Baremetrics is subscription analytics priced by your ARR. OpenProfit adds your AI and hosting bills, profit per product, and your tax return numbers.
---
# OpenProfit vs Baremetrics
+Updated October 9, 2026.
+
Baremetrics is hosted subscription analytics with add-ons for failed-payment recovery, cancellation insights and forecasting. OpenProfit is an open-source app that pulls your revenue and your costs from the services you use, shows profit for every product you run, and gives you the numbers for your tax return.
Both show MRR. They part ways on costs. Baremetrics reads your expenses from QuickBooks or Xero on its top plan, once your books close. OpenProfit reads them from the providers that bill you, and writes the journal you import into QuickBooks or Xero.
diff --git a/src/content/compare/profitwell.md b/src/content/compare/profitwell.md
index d0d1aec..d274d1d 100644
--- a/src/content/compare/profitwell.md
+++ b/src/content/compare/profitwell.md
@@ -1,10 +1,12 @@
---
title: OpenProfit vs ProfitWell Metrics
-description: ProfitWell Metrics tracks subscription revenue for free. OpenProfit adds your costs, from AI providers to hosting, and shows profit per product. Here's how they differ.
+description: ProfitWell Metrics tracks subscription revenue for free. OpenProfit adds your costs, from AI providers to hosting, and shows profit per product.
---
# OpenProfit vs ProfitWell Metrics
+Updated October 6, 2026.
+
ProfitWell Metrics, now part of Paddle, is free subscription revenue reporting: MRR, churn, upgrades, lifetime value. OpenProfit answers a different question. It puts your revenue next to every bill you pay and shows what each product keeps.
If you only need revenue metrics, ProfitWell Metrics is free and mature. If you want to know whether a product is profitable after its OpenAI, Vercel and Railway bills, that's what OpenProfit is for.
diff --git a/src/content/compare/spreadsheet.md b/src/content/compare/spreadsheet.md
index 5d1cdc6..dbf9e17 100644
--- a/src/content/compare/spreadsheet.md
+++ b/src/content/compare/spreadsheet.md
@@ -5,6 +5,8 @@ description: What a profit spreadsheet costs you each month, what OpenProfit doe
# OpenProfit vs a spreadsheet
+Updated October 9, 2026.
+
Most people who run a few software products track profit the same way: a spreadsheet with a row per month, revenue copied from Stripe, costs copied from each billing page. It works the first month. By the third, it's out of date.
## What the spreadsheet costs you
diff --git a/src/content/data.md b/src/content/data.md
index aa4ad54..fecb00b 100644
--- a/src/content/data.md
+++ b/src/content/data.md
@@ -1,6 +1,6 @@
---
title: Benchmarks
-description: Monthly revenue, gross margin and cost shares of the products on OpenProfit, grouped by monthly recurring revenue (MRR). The numbers come from Stripe, OpenAI and the other providers' APIs.
+description: Monthly revenue, gross margin and cost shares of the products on OpenProfit, grouped by MRR, from Stripe, OpenAI and other provider APIs.
---
## Download
diff --git a/src/content/integrations/anthropic.md b/src/content/integrations/anthropic.md
index f6607fd..c35c6c7 100644
--- a/src/content/integrations/anthropic.md
+++ b/src/content/integrations/anthropic.md
@@ -34,6 +34,8 @@ The key is stored encrypted and used only to read the cost report.
Workspaces are how Anthropic groups usage, so they're how OpenProfit maps it. Give each product its own workspace and its own API key, then assign the workspace to the product on the connection's page. Unassigned workspaces stay under Unassigned.
+[AI token cost per user](/blog/ai-token-cost-per-user) shows how to work out what each of your users costs in Claude tokens before you set a price.
+
## Common questions
**I use Claude through AWS Bedrock or Google Vertex.** Those charges appear on your AWS or Google Cloud bill, not in Anthropic's cost report. Add them as a flat monthly cost until a connector for those clouds exists.
diff --git a/src/content/integrations/firecrawl.md b/src/content/integrations/firecrawl.md
index 16da2df..b10cdb3 100644
--- a/src/content/integrations/firecrawl.md
+++ b/src/content/integrations/firecrawl.md
@@ -3,7 +3,7 @@ title: Track Firecrawl costs per API key
name: Firecrawl
kind: cost
summary: Plan fee and extra credits per billing period, split by API key.
-description: See what each Firecrawl API key costs per billing period, estimated from credit usage and Firecrawl's published prices, next to the revenue of the product it serves.
+description: What each Firecrawl API key costs per billing period, estimated from credit usage and Firecrawl's prices, next to the revenue of the product it serves.
---
# Track Firecrawl costs per API key
diff --git a/src/content/integrations/lemonsqueezy.md b/src/content/integrations/lemonsqueezy.md
index 0e69638..8fffe5b 100644
--- a/src/content/integrations/lemonsqueezy.md
+++ b/src/content/integrations/lemonsqueezy.md
@@ -41,3 +41,5 @@ A test mode key reads your test mode data instead.
## Revenue per product
Each Lemon Squeezy product appears on the connection's page. Assign it to a product and its revenue follows, past sales included. Revenue that isn't tied to a Lemon Squeezy product gets its own row on the same page.
+
+[Lemon Squeezy vs Stripe](/blog/stripe-polar-paddle-lemon-squeezy-fees) compares Lemon Squeezy's fee, tax handling and payout terms with Stripe, Polar and Paddle.
diff --git a/src/content/integrations/mongodb.md b/src/content/integrations/mongodb.md
index 2fc5be5..a054317 100644
--- a/src/content/integrations/mongodb.md
+++ b/src/content/integrations/mongodb.md
@@ -3,7 +3,7 @@ title: Track MongoDB Atlas costs per project
name: MongoDB Atlas
kind: cost
summary: Daily invoice line items per project and SKU, including the current month.
-description: See what each MongoDB Atlas project costs per day, from your Atlas invoices, next to the revenue of the product it serves. Connect with a billing-only service account.
+description: What each MongoDB Atlas project costs per day, from your Atlas invoices, next to the revenue of its product. Connect with a billing-only service account.
---
# Track MongoDB Atlas costs per project
diff --git a/src/content/integrations/openai.md b/src/content/integrations/openai.md
index 77821d4..5956bb2 100644
--- a/src/content/integrations/openai.md
+++ b/src/content/integrations/openai.md
@@ -34,7 +34,7 @@ The key is stored encrypted and used only to read costs.
Each OpenAI project appears on the connection's page with this month's spend. Point a project at the product it serves, and its costs land on that product from then on, history included. Projects you leave unassigned stay under Unassigned until you decide. If you run one product, everything goes to it by default.
-Three products on one OpenAI account, one project each, and you see which one pays for its tokens.
+Three products on one OpenAI account, one project each, and you see which one pays for its tokens. To turn a project's spend into a price, see [AI token cost per user](/blog/ai-token-cost-per-user).
## Common questions
diff --git a/src/content/integrations/openrouter.md b/src/content/integrations/openrouter.md
index a014672..09b1437 100644
--- a/src/content/integrations/openrouter.md
+++ b/src/content/integrations/openrouter.md
@@ -37,3 +37,5 @@ OpenRouter serves activity only to management keys, and offers no read-only vari
## Costs per product
Each API key with spend appears on the connection's page under the hash OpenRouter's API uses to identify it. Assign a key to a product and its costs follow, past days included. Activity without a key stays under Unassigned.
+
+[AI token cost per user](/blog/ai-token-cost-per-user) shows how to turn a key's spend into a cost per user before you set a price.
diff --git a/src/content/integrations/paddle.md b/src/content/integrations/paddle.md
index 9788959..94d943b 100644
--- a/src/content/integrations/paddle.md
+++ b/src/content/integrations/paddle.md
@@ -33,3 +33,5 @@ A sandbox key (`pdl_sdbx_…`) reads your sandbox account instead.
## Revenue per product
Paddle revenue goes to the product you pick on the connection's page. If you run one Paddle account per product, connect each one and point it at its product.
+
+[Paddle vs Stripe](/blog/stripe-polar-paddle-lemon-squeezy-fees) compares Paddle's fee, tax handling and payout terms with Stripe, Polar and Lemon Squeezy.
diff --git a/src/content/integrations/polar.md b/src/content/integrations/polar.md
index 84e49c7..19fc9e6 100644
--- a/src/content/integrations/polar.md
+++ b/src/content/integrations/polar.md
@@ -33,3 +33,5 @@ A token with only `organizations:read` and `metrics:read` still syncs Polar's da
## Revenue per product
Polar revenue goes to the product you pick on the connection's page. One Polar organization per product keeps the split exact.
+
+[Polar vs Stripe](/blog/stripe-polar-paddle-lemon-squeezy-fees) compares Polar's fee, tax handling and payout terms with Stripe, Paddle and Lemon Squeezy.
diff --git a/src/content/integrations/railway.md b/src/content/integrations/railway.md
index 3a51f39..0498ce1 100644
--- a/src/content/integrations/railway.md
+++ b/src/content/integrations/railway.md
@@ -35,3 +35,5 @@ Credits, discounts and domains aren't in the usage data, so the total can still
## Costs per product
Each Railway project appears on the connection's page. Assign it to a product and its usage follows, past months included.
+
+Railway can take your workloads offline at a hard usage limit. [Spend limits vs budget alerts](/blog/spend-limits-budget-alerts) covers what to set it to.
diff --git a/src/content/integrations/stripe.md b/src/content/integrations/stripe.md
index dff300c..4a94a85 100644
--- a/src/content/integrations/stripe.md
+++ b/src/content/integrations/stripe.md
@@ -29,3 +29,5 @@ A restricted key can't move money or change your account.
## Revenue per product
Stripe revenue goes to the product you pick on the connection's page. If you run one Stripe account per product, connect each and point it at its product.
+
+A Stripe payout arrives net of fees and refunds. [Stripe to QuickBooks or Xero](/blog/stripe-quickbooks-xero) covers the entries your books need, and [Stripe vs Polar vs Paddle vs Lemon Squeezy](/blog/stripe-polar-paddle-lemon-squeezy-fees) compares what you keep from each sale.
diff --git a/src/docs/books.md b/src/docs/books.md
index c7eeab3..8cae117 100644
--- a/src/docs/books.md
+++ b/src/docs/books.md
@@ -28,6 +28,8 @@ Costs without an API go on the **Costs** page. Choose **One time** for a single
4. Leave **Product** on **All** for your books. A journal for one product leaves out shared costs, so import it only if that product is its own company.
5. Click **Download**.
+The QuickBooks and Xero files leave out what the bank feed already records. [Stripe to QuickBooks or Xero](/blog/stripe-quickbooks-xero) explains the entries behind a Stripe payout and how the Stripe Connector by QuickBooks compares.
+
Exporting a whole month closes it. The same month always exports the same file, and if a provider changes its numbers later, your next export adds an adjustment for the difference.
### Import into QuickBooks Online
@@ -66,7 +68,7 @@ Pick the year at the top of **Tax report**. The report lists each line of your f
| United States, no company or a single-member LLC | Schedule C |
| United States, company | Form 1120, with the 1120-S and 1065 equivalents |
-A line marked **Our choice** has no official home for that cost, such as AI usage or payment fees, and the note says why OpenProfit picked it. If you incorporated during the year, the report splits at that date.
+A line marked **Our choice** has no official home for that cost, such as AI usage or payment fees, and the note says why OpenProfit picked it. [T2125 and Schedule C lines for OpenAI, Vercel and Stripe fees](/blog/tax-lines-for-software-costs) explains each choice with its CRA, Revenu Québec or IRS source. If you incorporated during the year, the report splits at that date.
Equipment follows your country's rules. In Canada, a computer is class 50. In the United States, an item up to $2,500 is deducted in full under the de minimis safe harbor, and the report writes the election statement you attach to your return.
diff --git a/src/docs/public-pages.md b/src/docs/public-pages.md
index b0c1aa3..b43004e 100644
--- a/src/docs/public-pages.md
+++ b/src/docs/public-pages.md
@@ -56,3 +56,5 @@ The badge refreshes within five minutes of a sync. Links shared on social sites
- Its first revenue is at least 30 days old
Each tab lists only the products whose mode shows that number, so a Growth and margin page appears on the margin and growth tabs. Rankings count only costs read from provider APIs. Self-reported costs show on the product’s page but not on the leaderboard. Products on self-hosted instances don’t appear.
+
+For an example, see [OpenProfit's own page](https://openprofit.dev/p/lobbystack/openprofit). [An open-source TrustMRR alternative](/blog/trustmrr-alternative) compares OpenProfit's verified profit with TrustMRR's verified revenue.
diff --git a/src/lib/app.ts b/src/lib/app.ts
index d727fe4..33562bd 100644
--- a/src/lib/app.ts
+++ b/src/lib/app.ts
@@ -65,6 +65,24 @@ export function seo({
};
}
+// A JSON-LD script for a route's head `scripts`.
+export const jsonLd = (data: object) => ({
+ type: "application/ld+json",
+ children: JSON.stringify({ "@context": "https://schema.org", ...data }),
+});
+
+// Breadcrumb trail shown in search results:
+// https://developers.google.com/search/docs/appearance/structured-data/breadcrumb
+export const breadcrumbs = (trail: [name: string, path: string][]) => ({
+ "@type": "BreadcrumbList",
+ itemListElement: trail.map(([name, path], i) => ({
+ "@type": "ListItem",
+ position: i + 1,
+ name,
+ item: `${SITE_URL}${path}`,
+ })),
+});
+
export const NOINDEX = { meta: [{ name: "robots", content: "noindex" }] };
// Where to go after signing in (`?redirect=`): a path on this site, never
diff --git a/src/lib/content.ts b/src/lib/content.ts
index 6ed1aa3..5b9d939 100644
--- a/src/lib/content.ts
+++ b/src/lib/content.ts
@@ -57,6 +57,18 @@ export function parse(slug: string, raw: string): Page {
};
}
+// Question and answer pairs from a "## Common questions" section, written as
+// "**Question?** Answer" paragraphs, for FAQPage structured data. Markdown
+// links and emphasis become plain text.
+export function faqOf(body: string) {
+ const section =
+ body.split(/^## Common questions$/m)[1]?.split(/^## /m)[0] ?? "";
+ return [...section.matchAll(/^\*\*(.+?\?)\*\* (.+)$/gm)].map(([, q, a]) => ({
+ q,
+ a: a.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[*`]/g, ""),
+ }));
+}
+
const load = (files: Record) =>
Object.entries(files).map(([path, raw]) =>
parse(path.split("/").pop()?.replace(/\.md$/, "") ?? path, raw),
diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts
index b539257..c04e2d5 100644
--- a/src/routeTree.gen.ts
+++ b/src/routeTree.gen.ts
@@ -16,6 +16,7 @@ import { Route as CliRouteImport } from './routes/cli'
import { Route as CookiesRouteImport } from './routes/cookies'
import { Route as DemoRouteImport } from './routes/demo'
import { Route as DocsRouteImport } from './routes/docs'
+import { Route as LlmsFullDottxtRouteImport } from './routes/llms-full[.]txt'
import { Route as LlmsDottxtRouteImport } from './routes/llms[.]txt'
import { Route as LoginRouteImport } from './routes/login'
import { Route as McpRouteImport } from './routes/mcp'
@@ -105,6 +106,11 @@ const DocsRoute = DocsRouteImport.update({
path: '/docs',
getParentRoute: () => rootRouteImport,
} as any)
+const LlmsFullDottxtRoute = LlmsFullDottxtRouteImport.update({
+ id: '/llms-full.txt',
+ path: '/llms-full.txt',
+ getParentRoute: () => rootRouteImport,
+} as any)
const LlmsDottxtRoute = LlmsDottxtRouteImport.update({
id: '/llms.txt',
path: '/llms.txt',
@@ -381,6 +387,7 @@ export interface FileRoutesByFullPath {
'/cookies': typeof CookiesRoute
'/demo': typeof DemoRouteWithChildren
'/docs': typeof DocsRouteWithChildren
+ '/llms-full.txt': typeof LlmsFullDottxtRoute
'/llms.txt': typeof LlmsDottxtRoute
'/login': typeof LoginRoute
'/mcp': typeof McpRoute
@@ -440,6 +447,7 @@ export interface FileRoutesByTo {
'/changelog': typeof ChangelogRoute
'/cli': typeof CliRoute
'/cookies': typeof CookiesRoute
+ '/llms-full.txt': typeof LlmsFullDottxtRoute
'/llms.txt': typeof LlmsDottxtRoute
'/login': typeof LoginRoute
'/mcp': typeof McpRoute
@@ -503,6 +511,7 @@ export interface FileRoutesById {
'/cookies': typeof CookiesRoute
'/demo': typeof DemoRouteWithChildren
'/docs': typeof DocsRouteWithChildren
+ '/llms-full.txt': typeof LlmsFullDottxtRoute
'/llms.txt': typeof LlmsDottxtRoute
'/login': typeof LoginRoute
'/mcp': typeof McpRoute
@@ -567,6 +576,7 @@ export interface FileRouteTypes {
| '/cookies'
| '/demo'
| '/docs'
+ | '/llms-full.txt'
| '/llms.txt'
| '/login'
| '/mcp'
@@ -626,6 +636,7 @@ export interface FileRouteTypes {
| '/changelog'
| '/cli'
| '/cookies'
+ | '/llms-full.txt'
| '/llms.txt'
| '/login'
| '/mcp'
@@ -688,6 +699,7 @@ export interface FileRouteTypes {
| '/cookies'
| '/demo'
| '/docs'
+ | '/llms-full.txt'
| '/llms.txt'
| '/login'
| '/mcp'
@@ -751,6 +763,7 @@ export interface RootRouteChildren {
CookiesRoute: typeof CookiesRoute
DemoRoute: typeof DemoRouteWithChildren
DocsRoute: typeof DocsRouteWithChildren
+ LlmsFullDottxtRoute: typeof LlmsFullDottxtRoute
LlmsDottxtRoute: typeof LlmsDottxtRoute
LoginRoute: typeof LoginRoute
McpRoute: typeof McpRoute
@@ -840,6 +853,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DocsRouteImport
parentRoute: typeof rootRouteImport
}
+ '/llms-full.txt': {
+ id: '/llms-full.txt'
+ path: '/llms-full.txt'
+ fullPath: '/llms-full.txt'
+ preLoaderRoute: typeof LlmsFullDottxtRouteImport
+ parentRoute: typeof rootRouteImport
+ }
'/llms.txt': {
id: '/llms.txt'
path: '/llms.txt'
@@ -1290,6 +1310,7 @@ const rootRouteChildren: RootRouteChildren = {
CookiesRoute: CookiesRoute,
DemoRoute: DemoRouteWithChildren,
DocsRoute: DocsRouteWithChildren,
+ LlmsFullDottxtRoute: LlmsFullDottxtRoute,
LlmsDottxtRoute: LlmsDottxtRoute,
LoginRoute: LoginRoute,
McpRoute: McpRoute,
diff --git a/src/routes/blog.$slug.tsx b/src/routes/blog.$slug.tsx
index 42b6809..2eb42f8 100644
--- a/src/routes/blog.$slug.tsx
+++ b/src/routes/blog.$slug.tsx
@@ -1,6 +1,6 @@
import { createFileRoute } from "@tanstack/react-router";
import { ContentPage } from "#/components/content-page";
-import { SITE_URL, seo } from "#/lib/app";
+import { breadcrumbs, jsonLd, SITE_URL, seo } from "#/lib/app";
import { dayLabel } from "#/lib/format";
import { getPost } from "#/server/content.functions";
@@ -11,25 +11,33 @@ export const Route = createFileRoute("/blog/$slug")({
p
? {
...seo({
- title: `${p.title} · OpenProfit`,
+ // Post titles run near Google's 60-character cutoff, so no suffix.
+ title: p.title,
description: p.description,
path: `/blog/${p.slug}`,
}),
// schema.org BlogPosting: https://schema.org/BlogPosting
scripts: [
- {
- type: "application/ld+json",
- children: JSON.stringify({
- "@context": "https://schema.org",
- "@type": "BlogPosting",
- headline: p.title,
- description: p.description,
- datePublished: p.date,
- url: `${SITE_URL}/blog/${p.slug}`,
- author: { "@type": "Person", name: p.author },
- publisher: { "@type": "Organization", name: "Lobbystack Inc." },
- }),
- },
+ jsonLd({
+ "@graph": [
+ breadcrumbs([
+ ["Blog", "/blog"],
+ [p.title, `/blog/${p.slug}`],
+ ]),
+ {
+ "@type": "BlogPosting",
+ headline: p.title,
+ description: p.description,
+ datePublished: p.date,
+ url: `${SITE_URL}/blog/${p.slug}`,
+ author: { "@type": "Person", name: p.author },
+ publisher: {
+ "@type": "Organization",
+ name: "Lobbystack Inc.",
+ },
+ },
+ ],
+ }),
],
}
: {},
diff --git a/src/routes/compare.$slug.tsx b/src/routes/compare.$slug.tsx
index 2258071..48c5683 100644
--- a/src/routes/compare.$slug.tsx
+++ b/src/routes/compare.$slug.tsx
@@ -1,6 +1,6 @@
import { createFileRoute } from "@tanstack/react-router";
import { ContentPage } from "#/components/content-page";
-import { seo } from "#/lib/app";
+import { breadcrumbs, jsonLd, seo } from "#/lib/app";
import { getContentPage } from "#/server/content.functions";
export const Route = createFileRoute("/compare/$slug")({
@@ -9,11 +9,21 @@ export const Route = createFileRoute("/compare/$slug")({
// No loader data on a 404.
head: ({ loaderData: p }) =>
p
- ? seo({
- title: `${p.title} · OpenProfit`,
- description: p.description,
- path: `/compare/${p.slug}`,
- })
+ ? {
+ ...seo({
+ title: `${p.title} · OpenProfit`,
+ description: p.description,
+ path: `/compare/${p.slug}`,
+ }),
+ scripts: [
+ jsonLd(
+ breadcrumbs([
+ ["OpenProfit", "/"],
+ [p.title, `/compare/${p.slug}`],
+ ]),
+ ),
+ ],
+ }
: {},
component: () => ,
});
diff --git a/src/routes/docs.$slug.tsx b/src/routes/docs.$slug.tsx
index 8290d04..cc01168 100644
--- a/src/routes/docs.$slug.tsx
+++ b/src/routes/docs.$slug.tsx
@@ -1,5 +1,5 @@
import { createFileRoute } from "@tanstack/react-router";
-import { seo } from "#/lib/app";
+import { breadcrumbs, jsonLd, SITE_URL, seo } from "#/lib/app";
import { getContentPage } from "#/server/content.functions";
export const Route = createFileRoute("/docs/$slug")({
@@ -8,11 +8,29 @@ export const Route = createFileRoute("/docs/$slug")({
// No loader data on a 404.
head: ({ loaderData: p }) =>
p
- ? seo({
- title: `${p.title} · OpenProfit docs`,
- description: p.description,
- path: `/docs/${p.slug}`,
- })
+ ? {
+ ...seo({
+ title: `${p.title} · OpenProfit docs`,
+ description: p.description,
+ path: `/docs/${p.slug}`,
+ }),
+ scripts: [
+ jsonLd({
+ "@graph": [
+ breadcrumbs([
+ ["Docs", "/docs/connectors"],
+ [p.title, `/docs/${p.slug}`],
+ ]),
+ {
+ "@type": "TechArticle",
+ headline: p.title,
+ description: p.description,
+ url: `${SITE_URL}/docs/${p.slug}`,
+ },
+ ],
+ }),
+ ],
+ }
: {},
component: Page,
});
diff --git a/src/routes/integrations.$slug.tsx b/src/routes/integrations.$slug.tsx
index f6ce5ef..83ae12f 100644
--- a/src/routes/integrations.$slug.tsx
+++ b/src/routes/integrations.$slug.tsx
@@ -1,7 +1,7 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { ContentPage } from "#/components/content-page";
import { providerName } from "#/components/provider-logo";
-import { seo } from "#/lib/app";
+import { breadcrumbs, jsonLd, seo } from "#/lib/app";
import { getContentPage } from "#/server/content.functions";
export const Route = createFileRoute("/integrations/$slug")({
@@ -10,11 +10,37 @@ export const Route = createFileRoute("/integrations/$slug")({
// No loader data on a 404.
head: ({ loaderData: p }) =>
p
- ? seo({
- title: `${p.title} · OpenProfit`,
- description: p.description,
- path: `/integrations/${p.slug}`,
- })
+ ? {
+ ...seo({
+ title: `${p.title} · OpenProfit`,
+ description: p.description,
+ path: `/integrations/${p.slug}`,
+ }),
+ scripts: [
+ jsonLd({
+ "@graph": [
+ breadcrumbs([
+ ["Integrations", "/integrations"],
+ [providerName(p.slug), `/integrations/${p.slug}`],
+ ]),
+ // Read by AI answer engines; Google shows FAQ results
+ // only for government and health sites.
+ ...(p.faq.length
+ ? [
+ {
+ "@type": "FAQPage",
+ mainEntity: p.faq.map(({ q, a }) => ({
+ "@type": "Question",
+ name: q,
+ acceptedAnswer: { "@type": "Answer", text: a },
+ })),
+ },
+ ]
+ : []),
+ ],
+ }),
+ ],
+ }
: {},
component: Integration,
});
diff --git a/src/routes/llms-full[.]txt.ts b/src/routes/llms-full[.]txt.ts
new file mode 100644
index 0000000..29fa7d7
--- /dev/null
+++ b/src/routes/llms-full[.]txt.ts
@@ -0,0 +1,29 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { COMPARISONS, INTEGRATIONS, POSTS } from "#/lib/content";
+import { DOCS } from "#/lib/docs";
+
+// Every page listed in /llms.txt, as one markdown file (llms-full.txt).
+const PATHS = [
+ "/",
+ "/security",
+ ...DOCS.map((d) => `/docs/${d.slug}`),
+ ...INTEGRATIONS.map((p) => `/integrations/${p.slug}`),
+ ...COMPARISONS.map((p) => `/compare/${p.slug}`),
+ ...POSTS.map((p) => `/blog/${p.slug}`),
+];
+
+export const Route = createFileRoute("/llms-full.txt")({
+ server: {
+ handlers: {
+ GET: async () => {
+ const { markdownFor } = await import("#/server/markdown.server");
+ const body = PATHS.flatMap((p) => markdownFor(p) ?? []).join(
+ "\n\n---\n\n",
+ );
+ return new Response(`${body}\n`, {
+ headers: { "Content-Type": "text/plain; charset=utf-8" },
+ });
+ },
+ },
+ },
+});
diff --git a/src/routes/llms[.]txt.ts b/src/routes/llms[.]txt.ts
index 730ac6f..b200d43 100644
--- a/src/routes/llms[.]txt.ts
+++ b/src/routes/llms[.]txt.ts
@@ -12,7 +12,7 @@ const BODY = [
"",
`> ${SITE_DESCRIPTION}`,
"",
- "OpenProfit is open source under the MIT license and runs as one Docker image. Request any page below with `Accept: text/markdown` to get it as markdown.",
+ `OpenProfit is open source under the MIT license and runs as one Docker image. Request any page below with \`Accept: text/markdown\` to get it as markdown, or read them all at ${SITE_URL}/llms-full.txt.`,
"",
"## Product",
"",
diff --git a/src/routes/open.tsx b/src/routes/open.tsx
index 925dc9e..327c741 100644
--- a/src/routes/open.tsx
+++ b/src/routes/open.tsx
@@ -175,6 +175,14 @@ function Open() {
>
Publish yours
+ , or see{" "}
+
+ how this compares with TrustMRR
+
.
diff --git a/src/routes/sitemap[.]xml.ts b/src/routes/sitemap[.]xml.ts
index 2c359b3..fb57c33 100644
--- a/src/routes/sitemap[.]xml.ts
+++ b/src/routes/sitemap[.]xml.ts
@@ -19,6 +19,13 @@ const STATIC = [
"/security",
];
+// Only pages with a real date get : the posts, and the blog index
+// at its newest post.
+const LASTMOD = new Map([
+ ["/blog", POSTS[0]?.meta.date],
+ ...POSTS.map((p) => [`/blog/${p.slug}`, p.meta.date] as const),
+]);
+
export const Route = createFileRoute("/sitemap.xml")({
server: {
handlers: {
@@ -44,7 +51,7 @@ export const Route = createFileRoute("/sitemap.xml")({
...pub.map((r) => `/p/${r.ws}/${r.p}`),
];
return new Response(
- `\n\n${paths.map((p) => ` ${SITE_URL}${p} `).join("\n")}\n \n`,
+ `\n\n${paths.map((p) => ` ${SITE_URL}${p} ${LASTMOD.get(p) ? `${LASTMOD.get(p)} ` : ""} `).join("\n")}\n \n`,
{
headers: {
"Content-Type": "application/xml; charset=utf-8",
diff --git a/src/server/content.functions.ts b/src/server/content.functions.ts
index 5538625..e84f820 100644
--- a/src/server/content.functions.ts
+++ b/src/server/content.functions.ts
@@ -1,7 +1,13 @@
import { notFound } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
-import { CHANGELOG, COMPARISONS, INTEGRATIONS, POSTS } from "#/lib/content";
+import {
+ CHANGELOG,
+ COMPARISONS,
+ faqOf,
+ INTEGRATIONS,
+ POSTS,
+} from "#/lib/content";
import { DOCS } from "#/lib/docs";
import { LEGAL } from "#/lib/legal";
@@ -32,7 +38,7 @@ export const getContentPage = createServerFn({ method: "GET" })
: COMPARISONS;
const p = list.find((x) => x.slug === data.slug);
if (!p) throw notFound();
- return page(p);
+ return { ...page(p), faq: faqOf(p.body) };
});
export const getPost = createServerFn({ method: "GET" })
From 2d69f4d3078ad2bc8cc34063253ab11223425bde Mon Sep 17 00:00:00 2001
From: morencyr
Date: Mon, 19 Oct 2026 17:07:16 -0400
Subject: [PATCH 17/26] Integrations: fuller Cloudflare, DigitalOcean, Twilio
and Vercel pages
Each page now says which lines OpenProfit reads, how to create the
narrowest key, how costs map to products, and what the provider's API
leaves out, with common questions and links to the related blog post and
docs. Claims come from the connector code and the providers' own docs.
---
src/content/integrations/cloudflare.md | 36 ++++++++++++++++++------
src/content/integrations/digitalocean.md | 27 +++++++++++++-----
src/content/integrations/twilio.md | 30 ++++++++++++++------
src/content/integrations/vercel.md | 32 +++++++++++++--------
4 files changed, 89 insertions(+), 36 deletions(-)
diff --git a/src/content/integrations/cloudflare.md b/src/content/integrations/cloudflare.md
index af3abd2..e5d61a9 100644
--- a/src/content/integrations/cloudflare.md
+++ b/src/content/integrations/cloudflare.md
@@ -1,27 +1,45 @@
---
-title: Track Cloudflare costs
+title: Cloudflare usage and costs by zone
name: Cloudflare
kind: cost
summary: Billable usage, or invoices where usage isn't available.
-description: Bring your Cloudflare Workers, R2 and plan charges into the same view as your revenue. Connect with a read-only API token.
+description: Your Cloudflare Workers, R2 and other usage costs by day and zone, next to the revenue of each product. Connect with a read-only API token.
---
# Track Cloudflare costs
-Workers, R2, Images and the zone plans each bill separately on Cloudflare. OpenProfit reads them through the API and adds them to your costs, per day where Cloudflare reports usage, per invoice where it doesn't.
+Cloudflare shows usage costs under **Manage Account → Billing → Billable Usage**, by product, for the whole account. OpenProfit reads that usage through Cloudflare's API, splits it by zone, and sets each zone's costs against the revenue of the product it serves.
## What it reads
-OpenProfit first asks for billable usage, which gives daily amounts per product. Some accounts don't expose usage through the API; for those it reads billing history instead, one line per invoice item.
+OpenProfit first asks for billable usage. For each day it records:
+
+- the amount, in the currency Cloudflare bills you;
+- the Cloudflare service the usage belongs to;
+- the zone, when Cloudflare attributes the usage to one.
+
+Cloudflare updates this data once a day, and its total for a closed billing period matches the usage charges on that period's invoice.
+
+The API covers self-serve accounts. When Cloudflare refuses the request, OpenProfit reads the account's billing history instead: one line per entry, dated the day Cloudflare charged it, with no zone. The first sync asks for two years, or one year on the hosted Free plan.
## Connect it
-1. In the Cloudflare dashboard, open **My Profile → API Tokens** and create a custom token with two permissions: **Account · Billing · Read** and **Account · Account Settings · Read**.
-2. In OpenProfit, open **Connections → Cloudflare** and paste the token. Add the account id if the token can see more than one account.
-3. Press **Test**, then **Connect**.
+1. In the Cloudflare dashboard, open **My Profile → API Tokens**, click **Create Token** and start a custom token.
+2. Add two permissions: **Account · Billing · Read** and **Account · Account Settings · Read**.
+3. Under **Account Resources**, include only the account you want to read.
+4. In OpenProfit, open **Connections → Cloudflare** and paste the token. Skip the account id when the token covers one account.
+5. Press **Test**, then **Connect**. The test shows the account's name.
-The token can read billing and account names. It can't change anything.
+The token can read billing but can't change anything.
## Costs per product
-Where Cloudflare attributes usage to a zone, the zone appears on the connection's page and you assign it to a product. Account-wide charges stay under Unassigned.
+Each zone with usage this month appears on the connection's page with its spend. Assign a zone to a product and its costs follow, past days included. Usage outside any zone, and every line from billing history, sits in a **Not in a zone** row. That row follows the product you pick for it, or stays under Unassigned.
+
+The sample stack in [the monthly cost of running a SaaS](/blog/saas-running-costs) runs DNS on Cloudflare's free plan. [Connecting providers](/docs/connectors) covers sync timing and flat costs.
+
+## Common questions
+
+**Why don't my plan or domain show up?** Billable usage covers usage charges, and a zone plan or domain renewal isn't usage. Add it as a flat cost on the **Costs** page.
+
+**Can I use an account API token?** No. OpenProfit checks the token against Cloudflare's user token endpoint, so create it under **My Profile → API Tokens**.
diff --git a/src/content/integrations/digitalocean.md b/src/content/integrations/digitalocean.md
index bd91828..a24df02 100644
--- a/src/content/integrations/digitalocean.md
+++ b/src/content/integrations/digitalocean.md
@@ -15,21 +15,34 @@ DigitalOcean sends one invoice for the whole account. OpenProfit splits it by pr
OpenProfit reads your invoice items through DigitalOcean's billing API. For each month it records:
- the amount in US dollars, summed per project and product;
-- the product, such as Droplets, Kubernetes Clusters or Managed Databases;
+- the product, as the invoice names it, such as Kubernetes Clusters or Floating IPs;
- the DigitalOcean project the resources belong to.
-Past months come from the issued invoice. The current month comes from the invoice preview, which DigitalOcean updates daily, so this month's figure grows until the invoice closes.
+DigitalOcean invoices on the first day of each month for the month before. The current month comes from the invoice preview, which DigitalOcean generates daily, so this month's figure grows until the invoice arrives and replaces it.
+
+The first sync reads two years of invoices, or one year on the hosted Free plan. Later syncs reread the current month, and last month early in a new month, to pick up the issued invoice.
+
+In the last 30 days view, OpenProfit spreads each month's total across its days.
## Connect it
-1. In DigitalOcean, open **API → Tokens** and generate a personal access token. Under **Custom Scopes**, tick **billing:read** and **account:read**.
-2. In OpenProfit, open **Connections → DigitalOcean** and paste the token.
-3. Press **Test**, then **Connect**. The test shows your team name.
+1. In the DigitalOcean control panel, open **Account → API**. On the **Tokens** tab, click **Generate New Token**.
+2. Name the token and choose an expiration. Under **Scopes**, select **Custom Scopes** and tick `billing:read` and `account:read`, nothing else.
+3. In OpenProfit, open **Connections → DigitalOcean** and paste the token.
+4. Press **Test**, then **Connect**. The test shows your team name.
+
+Both scopes are read-only. One covers invoices, the other the account details the test shows.
## Costs per product
-Each DigitalOcean project appears on the connection's page. Assign it to a product and its costs follow, past months included. Invoice items without a project stay under Unassigned.
+Each DigitalOcean project with costs this month appears on the connection's page. Assign it to a product and its costs follow, past months included. Invoice items without a project sit in a **Not in a project** row, which follows the product you pick for it or stays under Unassigned.
+
+In the sample stack from [the monthly cost of running a SaaS](/blog/saas-running-costs), payment fees and analytics cost more than hosting and the database at 100 and 1,000 customers. [Connecting providers](/docs/connectors) covers sync timing and flat costs.
## Common questions
-**Why don't I see daily figures?** DigitalOcean itemizes costs per project only on invoices, and invoices cover a month.
+**Why don't I see daily figures?** OpenProfit reads invoices, and each DigitalOcean invoice covers one month. The current month's preview still updates every day.
+
+**Where do taxes go?** DigitalOcean's invoice data lists taxes as their own item with no project, so they land in the **Not in a project** row.
+
+**What if one project runs everything?** Its costs go to one product. Move each product's resources into its own DigitalOcean project to split them.
diff --git a/src/content/integrations/twilio.md b/src/content/integrations/twilio.md
index 1a5d23a..e9f8eff 100644
--- a/src/content/integrations/twilio.md
+++ b/src/content/integrations/twilio.md
@@ -8,21 +8,35 @@ description: See what Twilio charges you per day for messages, calls and numbers
# Track Twilio costs per day
-Twilio charges per message, minute and phone number. OpenProfit reads the daily total and puts it next to the revenue of the product that sends those messages.
+Twilio charges per message, minute and phone number, and its usage records split that spend into dozens of categories. OpenProfit reads one daily total and puts it next to the revenue of the product that sends those messages.
## What it reads
-OpenProfit reads Twilio's daily usage records in the total price category. For each day it records the cost of all usage on the account and its subaccounts, in the currency Twilio bills you.
+OpenProfit reads Twilio's daily usage records in the `totalprice` category. Each day becomes one cost line, labeled **Usage**, with the price of all usage on the account and its subaccounts, in the currency Twilio bills you.
-Twilio's other usage categories overlap, so adding them up counts some costs twice. The total price category avoids that and includes costs that sit in no other category.
+The other categories overlap (`calls` contains `calls-inbound`), and some costs sit in no category. Adding categories up counts some charges twice and misses others.
+
+Twilio dates usage records by GMT day, and OpenProfit keeps those dates, so a California evening's usage can land on the next day.
+
+The first sync reads up to two years of records, or one year on the hosted Free plan. Every later sync rereads the last three days, so a revised day replaces the earlier figure.
## Connect it
-1. In the Twilio Console, open **Account settings → API keys & auth tokens** and create an API key. Pick **Restricted** as the key type.
-2. Under **Permissions**, grant `/twilio/billing/usage/read` and nothing else.
-3. In OpenProfit, open **Connections → Twilio** and paste your Account SID, the key's SID and its secret.
-4. Press **Test**, then **Connect**.
+1. In the Twilio Console, open **Settings → Account settings → API keys & auth tokens**.
+2. Select the **United States (US1)** region and click **Create API key**. A key works only in the region you created it in, and OpenProfit calls US1.
+3. Pick **Restricted** as the key type. Under **Permissions**, grant `/twilio/billing/usage/read` and nothing else.
+4. Copy the key's SID and secret before you click **Finish**.
+5. In OpenProfit, open **Connections → Twilio** and paste your Account SID, the key's SID and its secret.
+6. Press **Test**, then **Connect**. A usage-only key can't read the account's name, so the test shows a shortened Account SID.
## Costs per product
-Twilio reports one total per day. Pick the product it serves at the top of the connection's page and every day goes to it. If several products share the account, the total stays in the shared bucket.
+Twilio reports one total per day. Pick the product it serves at the top of the connection's page, and every day moves to that product, history included. If your workspace has one product, the connection starts on it.
+
+[The monthly cost of running a SaaS](/blog/saas-running-costs) prices the rest of a typical stack, from hosting to payment fees. [Connecting providers](/docs/connectors) covers sync timing and costs that have no API.
+
+## Common questions
+
+**Does it include subaccounts?** Yes. Twilio's usage records include every subaccount by default, and OpenProfit reads them through the main account.
+
+**Can I split one Twilio account between two products?** No. The daily total has no breakdown by app, so a connection goes to one product or stays Unassigned.
diff --git a/src/content/integrations/vercel.md b/src/content/integrations/vercel.md
index bb4504e..ee5c8c2 100644
--- a/src/content/integrations/vercel.md
+++ b/src/content/integrations/vercel.md
@@ -1,9 +1,9 @@
---
-title: Track Vercel costs per project
+title: Vercel usage and costs by project
name: Vercel
kind: cost
summary: Daily charges per project, read from Vercel's billing API.
-description: See what each Vercel project costs per day, from functions to bandwidth, next to the revenue of the product it hosts.
+description: Your Vercel usage and costs by day and project, from functions to bandwidth, next to the revenue of the product each project hosts.
---
# Track Vercel costs per project
@@ -12,24 +12,32 @@ A Vercel invoice is one number for the whole team. OpenProfit breaks it down by
## What it reads
-OpenProfit reads Vercel's billing charges, which Vercel publishes in the FOCUS format for cloud costs. For each charge it records:
+OpenProfit reads Vercel's billing charges API, which returns each day's charges in FOCUS, an open format for cloud cost data. For each charge it records:
-- the day and the amount billed;
-- the service, such as functions, edge requests or bandwidth;
-- the project, when Vercel attributes the charge to one.
+- the day and the amount billed, in US dollars;
+- the service Vercel names on the charge;
+- the project, from the project id and name Vercel tags the charge with.
-Charges that belong to the team as a whole, like the seat price of a Pro plan, have no project. They stay under Unassigned.
+Every charge with a nonzero amount counts, whatever its category: usage, purchases, taxes, credits or adjustments. Each sync after the first rereads the last three days, so a revised day replaces the earlier figure.
## Connect it
-1. In Vercel, open **Account Settings → Tokens** and create a token scoped to the team you want to read. Your role on that team needs billing access.
-2. In OpenProfit, open **Connections → Vercel** and paste the token. Add the team id if the token can see more than one team.
-3. Press **Test**, then **Connect**.
+1. In Vercel, open the **Account Tokens** page in your personal account's settings.
+2. Name the token. Under **Scope**, pick the team, then **All Projects**. A token scoped to one project can't read team-level data such as billing.
+3. Choose an expiration, click **Create** and copy the token.
+4. In OpenProfit, open **Connections → Vercel** and paste it. Leave the team id empty to read your default team, or paste the id from the team's settings.
+5. Press **Test**, then **Connect**. The test shows your username and the team id.
+
+Your team role must be one that can read billing: Owner, Member, Developer, Security, Billing or Enterprise Viewer.
## Costs per product
-Each project that has charges appears on the connection's page. Assign it to a product once and its costs follow from then on, including past days.
+Each project with charges this month appears on the connection's page. Assign it to a product and its costs follow, past days included. Charges without a project tag sit in a **Not in a project** row, which follows the product you pick for it or stays under Unassigned.
+
+In [the monthly cost of running a SaaS](/blog/saas-running-costs), Vercel Pro costs $20 a month at 100 customers and $40 at 1,000. [Connecting providers](/docs/connectors) covers sync timing and flat costs.
## Common questions
-**I'm on the Hobby plan.** Hobby has no charges to read. The connector is useful once a team is on a paid plan.
+**Does it work on the Hobby plan?** Hobby is free and has no billing cycle, so there are no charges to read. Connect the team once it moves to a paid plan.
+
+**Can OpenProfit stop a runaway Vercel bill?** No, it reads charges after Vercel records them. To cap spend, turn on **Pause Production Deployments** under **Settings → Billing → Spend Management**. [Spend limits vs budget alerts](/blog/spend-limits-budget-alerts) covers what to set.
From 51b38620a21964a1884fd38870bc474a92f1dab0 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Mon, 19 Oct 2026 17:15:44 -0400
Subject: [PATCH 18/26] Vercel and Cloudflare: fix backfill and reread ranges
Vercel's FOCUS charges endpoint accepts at most one year per request.
The connector asked for the whole 730-day backfill in one call (366
days on the free plan), so first and full syncs could fail. It now
requests 365-day chunks and merges the lines.
Cloudflare's billable-usage endpoint returns nothing unless the range
includes a subscription's billing cycle anchor day. The 3-day reread
usually missed it, so regular syncs stored no usage after the first.
The connector now reads the anchor from billable-usage/info, starts
the request at the last anchor day on or before the range, and drops
lines before the range. A 4xx from either call still falls back to
billing history.
---
src/connectors/cloudflare.ts | 31 ++++++++++++++++++++++++++++-
src/connectors/vercel.ts | 38 ++++++++++++++++++++++++------------
2 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/src/connectors/cloudflare.ts b/src/connectors/cloudflare.ts
index c5ddcca..7e362c0 100644
--- a/src/connectors/cloudflare.ts
+++ b/src/connectors/cloudflare.ts
@@ -40,6 +40,18 @@ type Usage = {
ZoneId?: string;
ZoneName?: string;
};
+type Info = { subscriptions?: { billing_cycle_anchor_timestamp: string }[] };
+
+// The latest day on or before `date` (YYYY-MM-DD) that falls on the anchor's
+// day of the month. 62 days back always reaches any day, the 31st included.
+function anchorOnOrBefore(date: string, anchor: string) {
+ const dom = new Date(anchor).getUTCDate();
+ let t = Date.parse(`${date}T00:00:00Z`);
+ for (let i = 0; i < 62 && new Date(t).getUTCDate() !== dom; i++)
+ t -= 86_400_000;
+ return new Date(t).toISOString().slice(0, 10);
+}
+
type Invoice = {
id: string;
amount: number;
@@ -79,13 +91,30 @@ export const cloudflare = register({
const id = await accountId(c);
const out: CostLine[] = [];
try {
+ // The range must include a subscription's billing cycle anchor day,
+ // or the API returns no usage, so it starts at the last anchor day
+ // on or before `from`; lines before `from` are dropped.
+ // https://developers.cloudflare.com/api/resources/billing/subresources/usage/methods/get_account_usage_v1/
+ const info = await getJson>(
+ `${BASE}/accounts/${id}/billable-usage/info`,
+ { headers: headers(c) },
+ );
+ let from = range.from;
+ for (const s of info.result?.subscriptions ?? []) {
+ const day = anchorOnOrBefore(
+ range.from,
+ s.billing_cycle_anchor_timestamp,
+ );
+ if (day < from) from = day;
+ }
const u = await getJson>(
- `${BASE}/accounts/${id}/billable-usage?from=${range.from}&to=${range.to}`,
+ `${BASE}/accounts/${id}/billable-usage?from=${from}&to=${range.to}`,
{ headers: headers(c) },
);
for (const r of u.result ?? []) {
if (!r.BilledCost) continue;
const date = r.ChargePeriodStart.slice(0, 10);
+ if (date < range.from) continue;
out.push({
externalId: `usage:${date}:${r.ServiceName}:${r.ChargeDescription ?? ""}:${r.ZoneId ?? ""}`,
date,
diff --git a/src/connectors/vercel.ts b/src/connectors/vercel.ts
index 40d0121..717487e 100644
--- a/src/connectors/vercel.ts
+++ b/src/connectors/vercel.ts
@@ -10,6 +10,9 @@ import {
const BASE = "https://api.vercel.com";
const headers = (c: Credentials) => ({ Authorization: `Bearer ${c.token}` });
+const DAY = 86_400_000;
+// 365 days fits the 1-year limit in leap years too.
+const YEAR = 365 * DAY;
type Charge = {
BilledCost: number;
@@ -64,22 +67,31 @@ export const vercel = register({
const team = await teamId(c);
return { label: `${u.user.username} · ${team}` };
},
- // FOCUS charges, one JSON object per line.
+ // FOCUS charges, one JSON object per line. One request covers at most a
+ // year, so a two-year backfill takes several, each [from, to) in UTC.
+ // https://vercel.com/docs/rest-api/reference/endpoints/billing/list-focus-billing-charges
async fetchCosts(c, range: SyncRange) {
const team = await teamId(c);
- const to = new Date(
- Date.parse(`${range.to}T00:00:00Z`) + 86_400_000,
- ).toISOString();
- const res = await fetch(
- `${BASE}/v1/billing/charges?teamId=${team}&from=${range.from}T00:00:00.000Z&to=${to}`,
- { headers: headers(c) },
- );
- if (!res.ok)
- throw new ConnectorError(
- `${res.status} ${await res.text().catch(() => "")}`.slice(0, 200),
- res.status,
+ const end = Date.parse(`${range.to}T00:00:00Z`) + DAY;
+ let text = "";
+ for (
+ let start = Date.parse(`${range.from}T00:00:00Z`);
+ start < end;
+ start += YEAR
+ ) {
+ const from = new Date(start).toISOString();
+ const to = new Date(Math.min(start + YEAR, end)).toISOString();
+ const res = await fetch(
+ `${BASE}/v1/billing/charges?teamId=${team}&from=${from}&to=${to}`,
+ { headers: headers(c) },
);
- const text = await res.text();
+ if (!res.ok)
+ throw new ConnectorError(
+ `${res.status} ${await res.text().catch(() => "")}`.slice(0, 200),
+ res.status,
+ );
+ text += `${await res.text()}\n`;
+ }
const out: CostLine[] = [];
for (const line of text.split("\n")) {
if (!line.trim()) continue;
From 796bd571740b4f55a74ab2c0b9dfdd2195f5dda5 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Mon, 19 Oct 2026 17:15:44 -0400
Subject: [PATCH 19/26] Vercel and Cloudflare: fix backfill and reread ranges
Vercel's FOCUS charges endpoint accepts at most one year per request.
The connector asked for the whole 730-day backfill in one call (366
days on the free plan), so first and full syncs could fail. It now
requests 365-day chunks and merges the lines.
Cloudflare's billable-usage endpoint returns nothing unless the range
includes a subscription's billing cycle anchor day. The 3-day reread
usually missed it, so regular syncs stored no usage after the first.
The connector now reads the anchor from billable-usage/info, starts
the request at the last anchor day on or before the range, and drops
lines before the range. A 4xx from either call still falls back to
billing history.
---
src/connectors/cloudflare.ts | 31 ++++++++++++++++++++++++++++-
src/connectors/vercel.ts | 38 ++++++++++++++++++++++++------------
2 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/src/connectors/cloudflare.ts b/src/connectors/cloudflare.ts
index c5ddcca..7e362c0 100644
--- a/src/connectors/cloudflare.ts
+++ b/src/connectors/cloudflare.ts
@@ -40,6 +40,18 @@ type Usage = {
ZoneId?: string;
ZoneName?: string;
};
+type Info = { subscriptions?: { billing_cycle_anchor_timestamp: string }[] };
+
+// The latest day on or before `date` (YYYY-MM-DD) that falls on the anchor's
+// day of the month. 62 days back always reaches any day, the 31st included.
+function anchorOnOrBefore(date: string, anchor: string) {
+ const dom = new Date(anchor).getUTCDate();
+ let t = Date.parse(`${date}T00:00:00Z`);
+ for (let i = 0; i < 62 && new Date(t).getUTCDate() !== dom; i++)
+ t -= 86_400_000;
+ return new Date(t).toISOString().slice(0, 10);
+}
+
type Invoice = {
id: string;
amount: number;
@@ -79,13 +91,30 @@ export const cloudflare = register({
const id = await accountId(c);
const out: CostLine[] = [];
try {
+ // The range must include a subscription's billing cycle anchor day,
+ // or the API returns no usage, so it starts at the last anchor day
+ // on or before `from`; lines before `from` are dropped.
+ // https://developers.cloudflare.com/api/resources/billing/subresources/usage/methods/get_account_usage_v1/
+ const info = await getJson>(
+ `${BASE}/accounts/${id}/billable-usage/info`,
+ { headers: headers(c) },
+ );
+ let from = range.from;
+ for (const s of info.result?.subscriptions ?? []) {
+ const day = anchorOnOrBefore(
+ range.from,
+ s.billing_cycle_anchor_timestamp,
+ );
+ if (day < from) from = day;
+ }
const u = await getJson>(
- `${BASE}/accounts/${id}/billable-usage?from=${range.from}&to=${range.to}`,
+ `${BASE}/accounts/${id}/billable-usage?from=${from}&to=${range.to}`,
{ headers: headers(c) },
);
for (const r of u.result ?? []) {
if (!r.BilledCost) continue;
const date = r.ChargePeriodStart.slice(0, 10);
+ if (date < range.from) continue;
out.push({
externalId: `usage:${date}:${r.ServiceName}:${r.ChargeDescription ?? ""}:${r.ZoneId ?? ""}`,
date,
diff --git a/src/connectors/vercel.ts b/src/connectors/vercel.ts
index 40d0121..717487e 100644
--- a/src/connectors/vercel.ts
+++ b/src/connectors/vercel.ts
@@ -10,6 +10,9 @@ import {
const BASE = "https://api.vercel.com";
const headers = (c: Credentials) => ({ Authorization: `Bearer ${c.token}` });
+const DAY = 86_400_000;
+// 365 days fits the 1-year limit in leap years too.
+const YEAR = 365 * DAY;
type Charge = {
BilledCost: number;
@@ -64,22 +67,31 @@ export const vercel = register({
const team = await teamId(c);
return { label: `${u.user.username} · ${team}` };
},
- // FOCUS charges, one JSON object per line.
+ // FOCUS charges, one JSON object per line. One request covers at most a
+ // year, so a two-year backfill takes several, each [from, to) in UTC.
+ // https://vercel.com/docs/rest-api/reference/endpoints/billing/list-focus-billing-charges
async fetchCosts(c, range: SyncRange) {
const team = await teamId(c);
- const to = new Date(
- Date.parse(`${range.to}T00:00:00Z`) + 86_400_000,
- ).toISOString();
- const res = await fetch(
- `${BASE}/v1/billing/charges?teamId=${team}&from=${range.from}T00:00:00.000Z&to=${to}`,
- { headers: headers(c) },
- );
- if (!res.ok)
- throw new ConnectorError(
- `${res.status} ${await res.text().catch(() => "")}`.slice(0, 200),
- res.status,
+ const end = Date.parse(`${range.to}T00:00:00Z`) + DAY;
+ let text = "";
+ for (
+ let start = Date.parse(`${range.from}T00:00:00Z`);
+ start < end;
+ start += YEAR
+ ) {
+ const from = new Date(start).toISOString();
+ const to = new Date(Math.min(start + YEAR, end)).toISOString();
+ const res = await fetch(
+ `${BASE}/v1/billing/charges?teamId=${team}&from=${from}&to=${to}`,
+ { headers: headers(c) },
);
- const text = await res.text();
+ if (!res.ok)
+ throw new ConnectorError(
+ `${res.status} ${await res.text().catch(() => "")}`.slice(0, 200),
+ res.status,
+ );
+ text += `${await res.text()}\n`;
+ }
const out: CostLine[] = [];
for (const line of text.split("\n")) {
if (!line.trim()) continue;
From 134ad0b0760cf063c6f3f7fcd2f4bc2709bb889b Mon Sep 17 00:00:00 2001
From: morencyr
Date: Mon, 19 Oct 2026 21:25:43 -0400
Subject: [PATCH 20/26] Run on Bun: package manager, dev server, scripts and
production
- bun.lock replaces pnpm-lock.yaml, migrated with the same versions.
Workspaces move to package.json.
- Vite runs under `bun --bun`. Scripts run with `bun` instead of tsx.
- Nitro builds with the `bun` preset. The Docker image is
oven/bun:1.3-alpine and starts `bun .output/server/index.mjs`.
- CI installs Bun with oven-sh/setup-bun. The CLI package tests run
with `bun test`; the published CLI still targets Node 20.
- postinstall relinks node_modules/.bin/intent: @tanstack/devtools-vite
ships a stale `intent` bin that Bun links in its place.
---
.claude/launch.json | 4 +-
.dockerignore | 3 +-
.github/workflows/check.yml | 16 +-
CLAUDE.md | 42 +-
CONTRIBUTING.md | 28 +-
Dockerfile | 20 +-
README.md | 12 +-
bun.lock | 1216 ++++
package.json | 21 +-
packages/cli/package.json | 2 +-
packages/cli/test/env.test.mjs | 2 +-
pnpm-lock.yaml | 5691 -----------------
pnpm-workspace.yaml | 6 -
scripts/benchmarks.ts | 2 +-
scripts/check-books-close.ts | 2 +-
scripts/check-books-export.ts | 2 +-
scripts/check-books-tax.ts | 2 +-
scripts/check-books.ts | 2 +-
scripts/seed.ts | 2 +-
src/db/index.ts | 2 +-
.../p.$workspace.$product_.badge[.]svg.ts | 2 +-
src/server/edge.server.ts | 2 +-
src/server/scheduler.ts | 2 +-
src/server/seed.server.ts | 2 +-
vite.config.ts | 2 +
25 files changed, 1309 insertions(+), 5778 deletions(-)
create mode 100644 bun.lock
delete mode 100644 pnpm-lock.yaml
delete mode 100644 pnpm-workspace.yaml
diff --git a/.claude/launch.json b/.claude/launch.json
index 80eeee4..397d2fa 100644
--- a/.claude/launch.json
+++ b/.claude/launch.json
@@ -3,8 +3,8 @@
"configurations": [
{
"name": "dev",
- "runtimeExecutable": "pnpm",
- "runtimeArgs": ["dev"],
+ "runtimeExecutable": "bun",
+ "runtimeArgs": ["run", "dev"],
"port": 3000
}
]
diff --git a/.dockerignore b/.dockerignore
index 06c92a8..d9ea975 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -6,4 +6,5 @@ data
design
.env
.git
-packages
+packages/*/*
+!packages/*/package.json
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 59ae4b8..9fb046c 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -10,13 +10,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - uses: pnpm/action-setup@v4
- - uses: actions/setup-node@v4
+ - uses: oven-sh/setup-bun@v2
with:
- node-version: 22
- cache: pnpm
- - run: pnpm install --frozen-lockfile
- - run: pnpm check
- - run: npx tsc --noEmit
- - run: pnpm build
- - run: pnpm --dir packages/cli build && pnpm --dir packages/cli test
+ bun-version-file: package.json
+ - run: bun install --frozen-lockfile
+ - run: bun run check
+ - run: bunx --bun tsc --noEmit
+ - run: bun run build
+ - run: cd packages/cli && bun run build && bun run test
diff --git a/CLAUDE.md b/CLAUDE.md
index 79ec327..8d977ab 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -7,21 +7,29 @@ OpenProfit: open-source finance dashboard for developers. Pulls revenue (Stripe,
## Commands
```bash
-pnpm dev # http://localhost:3000
-pnpm check # Biome lint + format check (CI runs this)
-npx biome check --write src # apply formatting; Biome rewrites files to tabs/double quotes
-npx tsc --noEmit # typecheck (CI runs this)
-pnpm build # production build into .output (CI runs this)
-pnpm db:generate # write a migration after editing src/db/schema.ts
-pnpm db:seed # demo workspace; `pnpm db:seed --owner=you@example.com` attaches it to a user
+bun run dev # http://localhost:3000
+bun run check # Biome lint + format check (CI runs this)
+bunx biome check --write src # apply formatting; Biome rewrites files to tabs/double quotes
+bunx --bun tsc --noEmit # typecheck (CI runs this)
+bun run build # production build into .output (CI runs this)
+bun run db:generate # write a migration after editing src/db/schema.ts
+bun run db:seed # demo workspace; `bun run db:seed --owner=you@example.com` attaches it to a user
```
+Bun is the package manager and the runtime everywhere:
+
+- Vite runs under `bun --bun`, so dev and the prerender run in Bun.
+- Scripts run as TypeScript with `bun scripts/seed.ts`. Bun loads `.env` itself.
+- Nitro builds with its `bun` preset. Production runs `bun .output/server/index.mjs`.
+- `bun run build` runs the app build. `bun build` is Bun's own bundler.
+- `postinstall` points `node_modules/.bin/intent` at `@tanstack/intent`. `@tanstack/devtools-vite` ships a broken `intent` bin, and Bun links that one otherwise.
+
There is no test suite. Verify changes in the browser and with a production build when touching bundling, the database or `src/start.ts`.
Production-build smoke test with a throwaway embedded DB:
```bash
-PORT=3200 SYNC_SCHEDULER=off DATABASE_URL=/tmp/op-test node .output/server/index.mjs
+PORT=3200 SYNC_SCHEDULER=off DATABASE_URL=/tmp/op-test bun .output/server/index.mjs
```
Local sign-in without email: request a link on /login (or POST /api/auth/sign-in/magic-link) and read the URL from the dev server log. Same on Railway via `railway logs | grep magic-link`.
@@ -30,8 +38,8 @@ Local sign-in without email: request a link on /login (or POST /api/auth/sign-in
Don't write framework code from memory. TanStack ships versioned agent skills inside its packages, and a project hook (`.claude/settings.json`, `.intent/hooks/`) lists them at session start and blocks edits until the guidance is checked.
-- TanStack Start and Router: load the matching skill first (`pnpm exec intent list`, then `pnpm exec intent load #`). `package.json#intent.skills` lists the allowed skill sources; add a TanStack package there when the app starts using it.
-- Anything the skills don't cover: read the docs for the installed version, e.g. `pnpm dlx @tanstack/cli search-docs "" --library start --framework react` and `pnpm dlx @tanstack/cli doc `. When docs and the installed source disagree, the source in `node_modules` wins.
+- TanStack Start and Router: load the matching skill first (`bunx @tanstack/intent list`, then `bunx @tanstack/intent load #`). `package.json#intent.skills` lists the allowed skill sources; add a TanStack package there when the app starts using it.
+- Anything the skills don't cover: read the docs for the installed version, e.g. `bunx @tanstack/cli search-docs "" --library start --framework react` and `bunx @tanstack/cli doc `. When docs and the installed source disagree, the source in `node_modules` wins.
- Other libraries (Better Auth, Drizzle, PostHog, provider APIs): read their current docs before using an API, and cite the page in a short comment where the behaviour isn't obvious.
@@ -39,8 +47,8 @@ Don't write framework code from memory. TanStack ships versioned agent skills in
Use the repository’s installed Intent. If it is unavailable, report the missing dependency instead of downloading a replacement.
Before editing files for a substantial task:
-- Run `pnpm exec intent list` from the workspace root to see available local skills.
-- If a listed skill matches the task, run `pnpm exec intent load #` before changing files.
+- Run `bunx @tanstack/intent list` from the workspace root to see available local skills.
+- If a listed skill matches the task, run `bunx @tanstack/intent load #` before changing files.
- Use the loaded `SKILL.md` guidance while making the change.
- Monorepos: when working across packages, run the skill check from the workspace root and prefer the local skill for the package being changed.
- Multiple matches: prefer the most specific local skill for the package or concern you are changing; load additional skills only when the task spans multiple packages or concerns.
@@ -50,7 +58,7 @@ Before editing files for a substantial task:
- Postgres everywhere through Drizzle (`src/db/schema.ts`, `src/db/auth-schema.ts`). `DATABASE_URL` starting with `postgres://` uses `pg`; anything else is a directory for **PGlite** (embedded Postgres, default `./data/openprofit`). Hosted uses Railway Postgres.
- Migrations in `./drizzle` run at import time of `src/db/index.ts` (skip with `SKIP_MIGRATIONS=1`). Don't use `drizzle-kit push`; PGlite rejects its multi-statement queries.
-- **PGlite allows one process per data directory.** Running a script (`db:seed`, a tsx one-off) while `pnpm dev` is up hangs or fails. Killing a process mid-write (`kill -9`) can corrupt the directory. Stop dev cleanly first. One-off scripts must end with `process.exit(0)` or PGlite keeps them alive. SIGTERM and SIGINT close the database and exit (`src/db/index.ts`); without that, PGlite's timer keeps the process alive until Docker kills it.
+- **PGlite allows one process per data directory.** Running a script (`db:seed`, a one-off script) while `bun run dev` is up hangs or fails. Killing a process mid-write (`kill -9`) can corrupt the directory. Stop dev cleanly first. One-off scripts must end with `process.exit(0)` or PGlite keeps them alive. SIGTERM and SIGINT close the database and exit (`src/db/index.ts`); without that, PGlite's timer keeps the process alive until Docker kills it.
- PGlite is excluded from Vite `optimizeDeps` and externalized from the Nitro server bundle in `vite.config.ts`; bundling it drops its wasm/data files and the server crashes on start. Keep both. `@resvg/resvg-wasm` (social images, `src/server/images.server.ts`) is externalized for the same reason.
- Money is integer cents. Each line stores the source amount and a `*_base_cents` amount in the workspace's base currency (Frankfurter/ECB daily rates, cached in `fx_rates`). Changing the base currency reconverts every line (`settings.functions.ts`).
- Every table carries `workspace_id`.
@@ -64,10 +72,10 @@ Before editing files for a substantial task:
- **Product mapping.** Cost lines carry a provider sub-unit (OpenAI project, Vercel project, Anthropic workspace, Railway project, Cloudflare zone). `product_mappings` maps sub-units to products, and an unmapped sub-unit is unassigned: there is no fallback. `connections.product_id` covers lines with no sub-unit (every line, for providers without sub-units); on a connection's first sync, every sub-unit it reports is mapped to that product. Unassigned lines fall into an "Unassigned" bucket (id `unassigned`). The sidebar switcher picks a product (cookie `op_product`, `currentProduct()`); Overview, Costs and Connections narrow to it, and none picked means All.
- **Overview** (`src/server/overview.server.ts`): grouped monthly sums over 24 months; tiles compare the selected period with the equal period before, the chart's dotted line is the same months a year earlier. Period comes from the `?period=` search param.
- **Cloud mode** (`APP_MODE=cloud`): plans and limits in `src/lib/plans.ts`, Polar checkout/portal and webhook in `src/server/billing.server.ts` and `src/routes/api/polar/webhook.ts` (Standard Webhooks signature, `whsec_` secrets are base64). Inert in self-host.
-- **Public demo** (`/demo`, `src/server/demo.server.ts`): the app's pages over one `demo = true` workspace with no members, rebuilt hourly by the seed generator (`src/server/seed.server.ts`, also behind `pnpm db:seed`). Read server functions take `{ demo: true }`; `currentWorkspace()` never returns the demo, so mutations can't reach it. On with `APP_MODE=cloud` or `DEMO=on`.
+- **Public demo** (`/demo`, `src/server/demo.server.ts`): the app's pages over one `demo = true` workspace with no members, rebuilt hourly by the seed generator (`src/server/seed.server.ts`, also behind `bun run db:seed`). Read server functions take `{ demo: true }`; `currentWorkspace()` never returns the demo, so mutations can't reach it. On with `APP_MODE=cloud` or `DEMO=on`.
- **Edge middleware** in `src/server/edge.server.ts` (a Nitro plugin that puts itself ahead of Nitro's static files): www to apex redirect, markdown responses for `Accept: text/markdown` (sources mapped in `src/server/markdown.server.ts`; add new public pages there), RFC 8288 `Link` headers, and serving the prerendered pages. It must stay free of database imports, so pages with live data (`/open`, `/p/...`) answer markdown from their own route `GET` handler and call `next()` for HTML.
-- **Request middleware** in `src/start.ts` (`createMiddleware({ type: "request" })`): tracing, gzip of server-rendered HTML/XML/JSON, and `Cache-Control: no-store` on /app, /onboarding and server function responses. Redirect responses must pass through unchanged: Start serializes server function redirects after the middleware. Start's CSRF check for server functions is added there explicitly, because a custom `createStart` drops the default. Request middleware runs under `pnpm dev` too.
-- **Prerendering.** `pnpm build` prerenders the pages that have markdown (landing, docs, integrations, comparisons, changelog, legal) with TanStack Start's `prerender` option; the `PRERENDER` pattern in `vite.config.ts` must match `markdownFor`. Nitro builds its static file list before those files exist, so the edge middleware serves them (brotli or gzip, compressed once per process). Prerendered HTML can't hold per-request data: the root route has no loader, and analytics settings are fetched after hydration. Server routes import the database inside their handlers so the prerender never opens it.
+- **Request middleware** in `src/start.ts` (`createMiddleware({ type: "request" })`): tracing, gzip of server-rendered HTML/XML/JSON, and `Cache-Control: no-store` on /app, /onboarding and server function responses. Redirect responses must pass through unchanged: Start serializes server function redirects after the middleware. Start's CSRF check for server functions is added there explicitly, because a custom `createStart` drops the default. Request middleware runs under `bun run dev` too.
+- **Prerendering.** `bun run build` prerenders the pages that have markdown (landing, docs, integrations, comparisons, changelog, legal) with TanStack Start's `prerender` option; the `PRERENDER` pattern in `vite.config.ts` must match `markdownFor`. Nitro builds its static file list before those files exist, so the edge middleware serves them (brotli or gzip, compressed once per process). Prerendered HTML can't hold per-request data: the root route has no loader, and analytics settings are fetched after hydration. Server routes import the database inside their handlers so the prerender never opens it.
- **Auth:** Better Auth with magic link plus GitHub/Google when their env vars are set (`src/lib/auth.ts`). Emails go through Resend when `RESEND_API_KEY` is set, otherwise they print to the server log.
## Content and SEO
@@ -81,7 +89,7 @@ Before editing files for a substantial task:
- Tokens in `src/styles.css`: paper/ink with neutrals mixed from them, light and dark (`.dark` class, toggled in `src/lib/theme.ts`). Change the system tokens, not individual components.
- One typeface: Geist. `--font-mono` points at Geist; numbers use the `num` utility (tabular figures). No serif or monospaced faces.
- Interaction rules live in `src/styles.css`, not components: press feedback on every button, visible keyboard focus, `display` utility for type 36px and up (tighter tracking), `chrome` for translucent sticky bars, `pressable` for links styled as buttons, `rise` for the one-time landing entrance, and `--ease-out` / `--ease-in-out` curves (UI motion stays under 300 ms; frequent actions like switching metric tiles don't animate beyond the chart), and reduced-motion, reduced-transparency and high-contrast overrides.
-- UI components are shadcn on Base UI (`components.json`: style `base-nova`), with their source in `src/components/ui/`. Each file is tuned to the tokens (no shadows, the app's heights and type sizes), so pages use variants such as `` and never restyle a component at the call site; change the variant in the component file instead. Add components with `pnpm dlx shadcn@latest add ` and answer no when it offers to overwrite an existing file. Base UI specifics: buttons default to `type="button"`, so a submit button needs `type="submit"`; a link that looks like a button is the router `Link` (or the landing `Href`) with `className={buttonVariants(...)}`, not `Button` with `render`, which would give it `role="button"`. `biome.json` relaxes a few lint rules for `src/components/ui` only.
+- UI components are shadcn on Base UI (`components.json`: style `base-nova`), with their source in `src/components/ui/`. Each file is tuned to the tokens (no shadows, the app's heights and type sizes), so pages use variants such as `` and never restyle a component at the call site; change the variant in the component file instead. Add components with `bunx shadcn@latest add ` and answer no when it offers to overwrite an existing file. Base UI specifics: buttons default to `type="button"`, so a submit button needs `type="submit"`; a link that looks like a button is the router `Link` (or the landing `Href`) with `className={buttonVariants(...)}`, not `Button` with `render`, which would give it `role="button"`. `biome.json` relaxes a few lint rules for `src/components/ui` only.
- Charts are shadcn `Chart` (Recharts) in `src/components/dashboard/area-chart-recharts.tsx`, loaded lazily through `area-chart.tsx` so pages don't wait for Recharts.
- Destructive actions (removing a connection, product or flat cost) confirm first in an `AlertDialog` (`useConfirm` in `src/components/app/confirm.tsx`) and say what happens to the data.
- No all-caps text anywhere. Headings weight 400. No shadows or gradients on the marketing pages, no emoji.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 62311d7..760551b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,26 +4,26 @@ Issues and pull requests are welcome. Connectors are the most useful contributio
## Set up a development environment
-You need Node 22 and pnpm. Install the dependencies, copy `.env.example`, and generate a key with the `node` line:
+You need [Bun](https://bun.com) 1.3 or later. Install the dependencies, copy `.env.example`, and generate a key with the `bun -e` line:
```bash
-pnpm install
+bun install
cp .env.example .env
-node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
-pnpm dev
+bun -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
+bun run dev
```
Paste the key into `SECRET_KEY` in `.env` before you start the server. It encrypts provider credentials, and saving a connection fails without it. The app runs at http://localhost:3000.
-To sign in without an email provider, enter any address on `/login`. With `RESEND_API_KEY` unset, the server prints the sign-in link to the `pnpm dev` output. Open it, then create a workspace on the onboarding page.
+To sign in without an email provider, enter any address on `/login`. With `RESEND_API_KEY` unset, the server prints the sign-in link to the `bun run dev` output. Open it, then create a workspace on the onboarding page.
-For a workspace with a year of demo numbers, stop `pnpm dev` and run `pnpm db:seed`. After you sign in once, `pnpm db:seed --owner=you@example.com` adds your user to it.
+For a workspace with a year of demo numbers, stop `bun run dev` and run `bun run db:seed`. After you sign in once, `bun run db:seed --owner=you@example.com` adds your user to it.
### The local database
Local development uses PGlite, an embedded Postgres stored in `./data/openprofit`. Only one process can open that directory at a time:
-- Stop `pnpm dev` before you run `pnpm db:seed` or any script that imports `src/db`, or the script hangs
+- Stop `bun run dev` before you run `bun run db:seed` or any script that imports `src/db`, or the script hangs
- Stop processes with Ctrl+C. A `kill -9` during a write can corrupt the directory
- End one-off scripts with `process.exit(0)`, or PGlite keeps them running
- Delete `./data/openprofit` to start over
@@ -33,12 +33,12 @@ Local development uses PGlite, an embedded Postgres stored in `./data/openprofit
CI runs three commands on every pull request. Run them before you push:
```bash
-pnpm check # Biome lint and format
-npx tsc --noEmit # typecheck
-pnpm build # production build
+bun run check # Biome lint and format
+bunx --bun tsc --noEmit # typecheck
+bun run build # production build
```
-`npx biome check --write src` fixes formatting. Biome uses tabs and double quotes. The repository has no test suite, so check your change in the browser as well.
+`bunx biome check --write src` fixes formatting. Biome uses tabs and double quotes. The repository has no test suite, so check your change in the browser as well.
## Build a connector
@@ -246,7 +246,7 @@ Never log credentials, put them in a URL, or include them in an error message. S
### Test against a real account
-Call the connector from a one-off script before you try the UI. Importing `#/connectors` doesn't open the database, so the script runs alongside `pnpm dev`. Save it as `check.ts` at the repository root and keep it out of your commit:
+Call the connector from a one-off script before you try the UI. Importing `#/connectors` doesn't open the database, so the script runs alongside `bun run dev`. Save it as `check.ts` at the repository root and keep it out of your commit:
```ts
import { connector } from "#/connectors";
@@ -265,12 +265,12 @@ console.log(lines?.length, "lines");
Run it with `EXAMPLE_TOKEN` in `.env`:
```bash
-npx tsx --env-file=.env check.ts
+bun check.ts
```
Compare the totals with the provider's billing page for the same month. Run it twice and check that both runs return the same `externalId` values.
-Then test the full flow in `pnpm dev`:
+Then test the full flow in `bun run dev`:
1. Open **Connections**, pick your provider, paste the key and click **Test**. Check the label.
2. Click **Connect**. The first sync runs before the page returns. If it fails, the dev server log shows `[sync] first sync example:` with the error.
diff --git a/Dockerfile b/Dockerfile
index ccf9623..b18040b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,21 +1,21 @@
# Single-container self-host. PGlite data lives on the /app/data volume.
-FROM node:22-alpine AS build
+FROM oven/bun:1.3-alpine AS build
WORKDIR /app
-RUN corepack enable
-COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
-RUN pnpm install --frozen-lockfile
+COPY package.json bun.lock ./
+COPY packages/cli/package.json packages/cli/
+RUN bun install --frozen-lockfile
COPY . .
-RUN pnpm build
+RUN bun run build
-FROM node:22-alpine
+FROM oven/bun:1.3-alpine
WORKDIR /app
ENV NODE_ENV=production
ENV DATABASE_URL=/app/data/openprofit
ENV PORT=3000
-RUN corepack enable
-COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
-RUN pnpm install --frozen-lockfile --prod
+COPY package.json bun.lock ./
+COPY packages/cli/package.json packages/cli/
+RUN bun install --frozen-lockfile --production --ignore-scripts
COPY drizzle ./drizzle
COPY --from=build /app/.output ./.output
EXPOSE 3000
-CMD ["node", ".output/server/index.mjs"]
+CMD ["bun", ".output/server/index.mjs"]
diff --git a/README.md b/README.md
index 314b3c1..d490eca 100644
--- a/README.md
+++ b/README.md
@@ -136,22 +136,22 @@ Postgres everywhere: PGlite embedded for self-host and local development, a Post
## Development
-Node 22 and pnpm.
+[Bun](https://bun.com) 1.3 or later.
```bash
-pnpm install
+bun install
cp .env.example .env # set SECRET_KEY
-pnpm db:seed # a demo workspace with a year of numbers
-pnpm dev
+bun run db:seed # a demo workspace with a year of numbers
+bun run dev
```
Sign in once at http://localhost:3000/login, then attach the demo workspace to your user:
```bash
-pnpm db:seed --owner=you@example.com
+bun run db:seed --owner=you@example.com
```
-Checks: `pnpm check` (Biome), `npx tsc --noEmit`, `pnpm build`. After a schema change, `pnpm db:generate` writes a migration; migrations run when the server starts.
+Checks: `bun run check` (Biome), `bunx --bun tsc --noEmit`, `bun run build`. After a schema change, `bun run db:generate` writes a migration; migrations run when the server starts.
## Contributing
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..932985f
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,1216 @@
+{
+ "lockfileVersion": 1,
+ "configVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "openprofit-app",
+ "dependencies": {
+ "@base-ui/react": "^1.8.0",
+ "@better-auth/drizzle-adapter": "^1.7.7",
+ "@electric-sql/pglite": "^0.5.8",
+ "@fontsource-variable/geist": "^5.3.0",
+ "@modelcontextprotocol/server": "^2.3.1",
+ "@opentelemetry/api": "^1.9.1",
+ "@opentelemetry/api-logs": "^0.222.0",
+ "@opentelemetry/exporter-logs-otlp-http": "^0.222.0",
+ "@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
+ "@opentelemetry/resources": "^2.11.0",
+ "@opentelemetry/sdk-logs": "^0.222.0",
+ "@opentelemetry/sdk-trace-base": "^2.11.0",
+ "@resvg/resvg-wasm": "2.6.2",
+ "@tailwindcss/vite": "^4.1.18",
+ "@tanstack/react-devtools": "0.10.13",
+ "@tanstack/react-router": "1.170.41",
+ "@tanstack/react-router-devtools": "1.167.2",
+ "@tanstack/react-start": "1.168.60",
+ "better-auth": "^1.7.7",
+ "class-variance-authority": "^0.7.1",
+ "cmdk": "^1.1.1",
+ "cn": "^0.4.0",
+ "croner": "^10.0.1",
+ "drizzle-orm": "^0.45.3",
+ "lucide-react": "^0.577.0",
+ "marked": "^18.0.14",
+ "nitro": "3.0.260610-beta",
+ "pg": "^8.23.1",
+ "posthog-js": "^1.436.1",
+ "posthog-node": "^5.55.0",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0",
+ "recharts": "3.8.0",
+ "simple-icons": "^16.34.0",
+ "tailwindcss": "^4.1.18",
+ "tw-animate-css": "^1.3.6",
+ "zod": "^4.6.5",
+ },
+ "devDependencies": {
+ "@biomejs/biome": "2.4.5",
+ "@tailwindcss/typography": "^0.5.16",
+ "@tanstack/devtools-vite": "0.8.5",
+ "@tanstack/intent": "^0.5.4",
+ "@tanstack/router-cli": "^1.132.0",
+ "@types/node": "^22.10.2",
+ "@types/pg": "^8.23.1",
+ "@types/react": "^19.2.0",
+ "@types/react-dom": "^19.2.0",
+ "@vitejs/plugin-react": "^6.0.1",
+ "drizzle-kit": "^0.31.11",
+ "typescript": "^6.0.2",
+ "vite": "^8.0.0",
+ },
+ },
+ "packages/cli": {
+ "name": "openprofit",
+ "version": "0.1.0",
+ "bin": {
+ "openprofit": "dist/cli.js",
+ },
+ "dependencies": {
+ "@modelcontextprotocol/client": "^2.3.1",
+ "@modelcontextprotocol/server": "^2.3.1",
+ "zod": "^4.6.5",
+ },
+ "devDependencies": {
+ "@types/node": "^22.20.5",
+ "typescript": "^6.0.3",
+ },
+ },
+ },
+ "packages": {
+ "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "7.29.7", "js-tokens": "4.0.0", "picocolors": "1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="],
+
+ "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="],
+
+ "@babel/core": ["@babel/core@7.29.7", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/generator": "7.29.8", "@babel/helper-compilation-targets": "7.29.7", "@babel/helper-module-transforms": "7.29.7", "@babel/helpers": "7.29.7", "@babel/parser": "7.29.9", "@babel/template": "7.29.7", "@babel/traverse": "7.29.8", "@babel/types": "7.29.8", "@jridgewell/remapping": "2.3.5", "convert-source-map": "2.0.0", "debug": "4.4.3", "gensync": "1.0.0-beta.2", "json5": "2.2.3", "semver": "6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="],
+
+ "@babel/generator": ["@babel/generator@7.29.8", "", { "dependencies": { "@babel/parser": "7.29.9", "@babel/types": "7.29.8", "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/trace-mapping": "0.3.31", "jsesc": "3.1.0" } }, "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg=="],
+
+ "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "7.29.7", "@babel/helper-validator-option": "7.29.7", "browserslist": "4.29.3", "lru-cache": "5.1.1", "semver": "6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="],
+
+ "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="],
+
+ "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "7.29.8", "@babel/types": "7.29.8" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="],
+
+ "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "7.29.7", "@babel/helper-validator-identifier": "7.29.7", "@babel/traverse": "7.29.8" }, "peerDependencies": { "@babel/core": "7.29.7" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="],
+
+ "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="],
+
+ "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="],
+
+ "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="],
+
+ "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "7.29.7", "@babel/types": "7.29.8" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="],
+
+ "@babel/parser": ["@babel/parser@7.29.9", "", { "dependencies": { "@babel/types": "7.29.8" }, "bin": "./bin/babel-parser.js" }, "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA=="],
+
+ "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="],
+
+ "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/parser": "7.29.9", "@babel/types": "7.29.8" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="],
+
+ "@babel/traverse": ["@babel/traverse@7.29.8", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/generator": "7.29.8", "@babel/helper-globals": "7.29.7", "@babel/parser": "7.29.9", "@babel/template": "7.29.7", "@babel/types": "7.29.8", "debug": "4.4.3" } }, "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg=="],
+
+ "@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "7.29.7", "@babel/helper-validator-identifier": "7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="],
+
+ "@base-ui/react": ["@base-ui/react@1.8.0", "", { "dependencies": { "@babel/runtime": "7.29.7", "@base-ui/utils": "0.4.0", "@floating-ui/react-dom": "2.1.9", "@floating-ui/utils": "0.2.12", "use-sync-external-store": "1.7.0" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q=="],
+
+ "@base-ui/utils": ["@base-ui/utils@0.4.0", "", { "dependencies": { "@babel/runtime": "7.29.7", "@floating-ui/utils": "0.2.12", "reselect": "5.3.0", "use-sync-external-store": "1.7.0" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw=="],
+
+ "@better-auth/core": ["@better-auth/core@1.7.7", "", { "dependencies": { "@opentelemetry/semantic-conventions": "1.43.0", "@standard-schema/spec": "1.1.0", "zod": "4.6.5" }, "optionalDependencies": { "@opentelemetry/api": "1.9.1" }, "peerDependencies": { "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.2", "better-call": "1.4.0", "jose": "6.2.12", "kysely": "0.29.6", "nanostores": "1.5.4" } }, "sha512-srgFzHEjB2WWlokFz1i4BfG41sNhsA105Pukgqu6RrEh5A+LSkzf1mCHydVipkjt9l5qswtBMi7IL6ouHbZL4Q=="],
+
+ "@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.7.7", "", { "optionalDependencies": { "drizzle-orm": "0.45.3" }, "peerDependencies": { "@better-auth/core": "1.7.7", "@better-auth/utils": "0.4.2" } }, "sha512-qon0U94PR5FQysuyGoAlGVQpIIiNg5dtDpwjE63sN/HjoRWZadZzHPcS9mn7JsJyQZK6iTNhd7LD0AaXt2f78w=="],
+
+ "@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.7.7", "", { "optionalDependencies": { "kysely": "0.29.6" }, "peerDependencies": { "@better-auth/core": "1.7.7", "@better-auth/utils": "0.4.2" } }, "sha512-9FONOCgOcrQI9wJ5v1oDGIg9sT7pa9RjZZQ4fsCTudo8R87SrIGNUvUxDFTJhZvUblvFfGaIBR9Vb8LA+8bqLQ=="],
+
+ "@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.7.7", "", { "peerDependencies": { "@better-auth/core": "1.7.7", "@better-auth/utils": "0.4.2" } }, "sha512-FqKFEe+b5tXXV0gRbyirca+qXgMpLOeJ8Wk19yykb/scQKy0WJ4k22WzEV3TTPctQV9DZhwCXPlDtQhnlOv5Gg=="],
+
+ "@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.7.7", "", { "peerDependencies": { "@better-auth/core": "1.7.7", "@better-auth/utils": "0.4.2" } }, "sha512-ZnVDuRrXqbf0oHphrEN27oTImNH5NTO26dtWatq5cXyYAsH7goof9QIoTOmxTbBxUQahKBw9T6+9h6n+RtOE+g=="],
+
+ "@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.7.7", "", { "peerDependencies": { "@better-auth/core": "1.7.7", "@better-auth/utils": "0.4.2" } }, "sha512-4YcnrcVdvWiAZw0sZl63tWUClPXg5r3QsLn7C2sG7kKEBY06zOng0ibecyxRBixKq1zE1ceHuEUqez5Rhi+nQA=="],
+
+ "@better-auth/telemetry": ["@better-auth/telemetry@1.7.7", "", { "peerDependencies": { "@better-auth/core": "1.7.7", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.2" } }, "sha512-PaRA6i+kAioVYmza2gHPcdrxP0hAotph4KV9hft2GeNJq+AZXDiBu3FuLM9HxvcmiZeUT74Vufqd9ypmB8veTA=="],
+
+ "@better-auth/utils": ["@better-auth/utils@0.4.2", "", { "dependencies": { "@noble/hashes": "2.4.0" } }, "sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A=="],
+
+ "@better-fetch/fetch": ["@better-fetch/fetch@1.3.2", "", {}, "sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow=="],
+
+ "@biomejs/biome": ["@biomejs/biome@2.4.5", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.5", "@biomejs/cli-darwin-x64": "2.4.5", "@biomejs/cli-linux-arm64": "2.4.5", "@biomejs/cli-linux-arm64-musl": "2.4.5", "@biomejs/cli-linux-x64": "2.4.5", "@biomejs/cli-linux-x64-musl": "2.4.5", "@biomejs/cli-win32-arm64": "2.4.5", "@biomejs/cli-win32-x64": "2.4.5" }, "bin": { "biome": "bin/biome" } }, "sha512-OWNCyMS0Q011R6YifXNOg6qsOg64IVc7XX6SqGsrGszPbkVCoaO7Sr/lISFnXZ9hjQhDewwZ40789QmrG0GYgQ=="],
+
+ "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lGS4Nd5O3KQJ6TeWv10mElnx1phERhBxqGP/IKq0SvZl78kcWDFMaTtVK+w3v3lusRFxJY78n07PbKplirsU5g=="],
+
+ "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-6MoH4tyISIBNkZ2Q5T1R7dLd5BsITb2yhhhrU9jHZxnNSNMWl+s2Mxu7NBF8Y3a7JJcqq9nsk8i637z4gqkJxQ=="],
+
+ "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-U1GAG6FTjhAO04MyH4xn23wRNBkT6H7NentHh+8UxD6ShXKBm5SY4RedKJzkUThANxb9rUKIPc7B8ew9Xo/cWg=="],
+
+ "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-iqLDgpzobG7gpBF0fwEVS/LT8kmN7+S0E2YKFDtqliJfzNLnAiV2Nnyb+ehCDCJgAZBASkYHR2o60VQWikpqIg=="],
+
+ "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.5", "", { "os": "linux", "cpu": "x64" }, "sha512-NdODlSugMzTlENPTa4z0xB82dTUlCpsrOxc43///aNkTLblIYH4XpYflBbf5ySlQuP8AA4AZd1qXhV07IdrHdQ=="],
+
+ "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.5", "", { "os": "linux", "cpu": "x64" }, "sha512-NlKa7GpbQmNhZf9kakQeddqZyT7itN7jjWdakELeXyTU3pg/83fTysRRDPJD0akTfKDl6vZYNT9Zqn4MYZVBOA=="],
+
+ "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-EBfrTqRIWOFSd7CQb/0ttjHMR88zm3hGravnDwUA9wHAaCAYsULKDebWcN5RmrEo1KBtl/gDVJMrFjNR0pdGUw=="],
+
+ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.5", "", { "os": "win32", "cpu": "x64" }, "sha512-Pmhv9zT95YzECfjEHNl3mN9Vhusw9VA5KHY0ZvlGsxsjwS5cb7vpRnHzJIv0vG7jB0JI7xEaMH9ddfZm/RozBw=="],
+
+ "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
+
+ "@electric-sql/pglite": ["@electric-sql/pglite@0.5.8", "", {}, "sha512-n9tsbUOhwx2epK1V0ZG9Ar4SHWUju04dhmzZXiSBXwBoleOvIfals33NAaWgagQVAL4Rbvx/Ptsu3P+pA09f6Q=="],
+
+ "@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "2.8.1" } }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="],
+
+ "@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
+
+ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="],
+
+ "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "0.18.20", "source-map-support": "0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="],
+
+ "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "3.3.2", "get-tsconfig": "4.14.3" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="],
+
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
+
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
+
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
+
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
+
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
+
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
+
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
+
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
+
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
+
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
+
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
+
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
+
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
+
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
+
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
+
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
+
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
+
+ "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
+
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
+
+ "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
+
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
+
+ "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
+
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
+
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
+
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
+
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
+
+ "@floating-ui/core": ["@floating-ui/core@1.8.0", "", { "dependencies": { "@floating-ui/utils": "0.2.12" } }, "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ=="],
+
+ "@floating-ui/dom": ["@floating-ui/dom@1.8.0", "", { "dependencies": { "@floating-ui/core": "1.8.0", "@floating-ui/utils": "0.2.12" } }, "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg=="],
+
+ "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.9", "", { "dependencies": { "@floating-ui/dom": "1.8.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg=="],
+
+ "@floating-ui/utils": ["@floating-ui/utils@0.2.12", "", {}, "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww=="],
+
+ "@fontsource-variable/geist": ["@fontsource-variable/geist@5.3.0", "", {}, "sha512-j0m+vLQuG5XAYoHtGCVu0spvlGreR3EzpECUVzkFmI1mTVnAO38l/NEPDCFgZ177JxzYJCLSmTQibIiYPilGrA=="],
+
+ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.6.0", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
+
+ "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
+
+ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
+
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.6.0", "", {}, "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw=="],
+
+ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "3.1.2", "@jridgewell/sourcemap-codec": "1.6.0" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
+ "@modelcontextprotocol/client": ["@modelcontextprotocol/client@2.3.1", "", { "dependencies": { "@modelcontextprotocol/core": "2.3.1", "cross-spawn": "7.0.6", "eventsource": "3.0.7", "eventsource-parser": "3.1.1", "jose": "6.2.12", "pkce-challenge": "5.0.1", "zod": "4.6.5" } }, "sha512-mIGZXpHsjnZ6lD+gD/WCMpR5k8yVQQ8nNFH1N0Srf7AvnwTUMYD6pvTY8ng2+He5FfV7YMZLmrjL7cLa/cc3dQ=="],
+
+ "@modelcontextprotocol/core": ["@modelcontextprotocol/core@2.3.1", "", { "dependencies": { "zod": "4.6.5" } }, "sha512-laVmIhPGpWi7rG9q+0UigblRN0Hws/Yjlb6qLFtVqryXVLkc4h+yN8z731POD2LnAGQlFe7/tXhUm7Bi0YB91g=="],
+
+ "@modelcontextprotocol/server": ["@modelcontextprotocol/server@2.3.1", "", { "dependencies": { "@modelcontextprotocol/core": "2.3.1", "zod": "4.6.5" } }, "sha512-e59MfWuSssj6DoQ96JCTqdW1AXT5/XtnTl0WWd6MU1Ka434fFUGGosCLJbGNySDhHGvxQWoRWK137FXYFkYNWw=="],
+
+ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.4", "", { "dependencies": { "@tybys/wasm-util": "0.10.4" }, "peerDependencies": { "@emnapi/core": "1.11.3", "@emnapi/runtime": "1.11.3" } }, "sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g=="],
+
+ "@neodrag/core": ["@neodrag/core@3.0.0-next.11", "", {}, "sha512-3WQWxyrbxiaK9zS5JU2wJsW2gpoQlZBXVghduBh61JpqaeE0T0cte8R0qYK2RuJo3J2TYQYqxO19CpG/C1i5eg=="],
+
+ "@neodrag/solid": ["@neodrag/solid@3.0.0-next.11", "", { "peerDependencies": { "@neodrag/core": "3.0.0-next.11", "solid-js": "1.9.15" } }, "sha512-vCBIn/pimjWMQ6vhTS2/O1XNAwzVtc4eUhdbQ91WykbZWWqQ5NocDXt/1OdYrEkeRzJcpCv8wEz5PnMkgKP81Q=="],
+
+ "@noble/ciphers": ["@noble/ciphers@2.4.0", "", {}, "sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw=="],
+
+ "@noble/hashes": ["@noble/hashes@2.4.0", "", {}, "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA=="],
+
+ "@oozcitak/dom": ["@oozcitak/dom@2.0.2", "", { "dependencies": { "@oozcitak/infra": "2.0.2", "@oozcitak/url": "3.0.0", "@oozcitak/util": "10.0.0" } }, "sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w=="],
+
+ "@oozcitak/infra": ["@oozcitak/infra@2.0.2", "", { "dependencies": { "@oozcitak/util": "10.0.0" } }, "sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA=="],
+
+ "@oozcitak/url": ["@oozcitak/url@3.0.0", "", { "dependencies": { "@oozcitak/infra": "2.0.2", "@oozcitak/util": "10.0.0" } }, "sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ=="],
+
+ "@oozcitak/util": ["@oozcitak/util@10.0.0", "", {}, "sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA=="],
+
+ "@opentelemetry/api": ["@opentelemetry/api@1.9.1", "", {}, "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q=="],
+
+ "@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.222.0", "", { "dependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-9mb1If+IF6u0ZVXkHQ6ogEae5HwA6ajIVUgpSDQyRASxft6BSXHvBvPooRle3yFN/fKnCdSOnuu0OC3PLcF6+g=="],
+
+ "@opentelemetry/core": ["@opentelemetry/core@2.11.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "1.43.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA=="],
+
+ "@opentelemetry/exporter-logs-otlp-http": ["@opentelemetry/exporter-logs-otlp-http@0.222.0", "", { "dependencies": { "@opentelemetry/otlp-exporter-base": "0.222.0", "@opentelemetry/otlp-transformer": "0.222.0", "@opentelemetry/sdk-logs": "0.222.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-GqwLZohJTf/sttYlOpT1oFTJ9ScYaKnk0sOx4Qe/+KmXYVOa+v94cfnkUkFKDuvTODWhCL50Hz3gvsZD6ngQpg=="],
+
+ "@opentelemetry/exporter-trace-otlp-http": ["@opentelemetry/exporter-trace-otlp-http@0.222.0", "", { "dependencies": { "@opentelemetry/otlp-exporter-base": "0.222.0", "@opentelemetry/otlp-transformer": "0.222.0", "@opentelemetry/sdk-trace": "2.11.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-RCnPWcHppwiquQ+cV3nWvNwdf0MG1w26e5jewW2T83nTZOlXgcg88sY9ulCVgagGHcq1mj0L0GP6YHgzk2v8oA=="],
+
+ "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.222.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/otlp-transformer": "0.222.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-YbywG3veEm2Fb6TbdxRkuquWob6eVWXuA8/Ba1tXz9jHfUqpdE3keilOHEtPboC4CvS1bjeeVfNkWGOOrLj+lw=="],
+
+ "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.222.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.222.0", "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0", "@opentelemetry/sdk-logs": "0.222.0", "@opentelemetry/sdk-metrics": "2.11.0", "@opentelemetry/sdk-trace": "2.11.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-/F3BZ89+CJQnZkMh2tCrtcdB+XT2Dxhj4FFE+WPQ//413hmFL0/RfEX6vgOIWGhiSzrkHWTK3+6SiT7K5/g/jQ=="],
+
+ "@opentelemetry/resources": ["@opentelemetry/resources@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/semantic-conventions": "1.43.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-Ie7+8q8MDF4FAEQCKVMTx3ReUvxiIAgIiiW3c9JdmP8+HMcDy20puT+AHjexnExgnbvBxjQ9fjkFDWrikJ2jQA=="],
+
+ "@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.222.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.222.0", "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0", "@opentelemetry/semantic-conventions": "1.43.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-+19YHODIjaUCArxleaJtuufFZVpz/xvvK+VllQqE+W8hHolxdoRwHfK/s667zezwh1hkx6FFF+oYzetYgqK+Bg=="],
+
+ "@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-7GXXcObyHyDUUSG+L+kJoquty01bzm7ivE7+SSgXXJcHuPzGviptxwARmI2c+bnnxjexGQbJnyNlN8HxBP/Y7A=="],
+
+ "@opentelemetry/sdk-trace": ["@opentelemetry/sdk-trace@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0", "@opentelemetry/semantic-conventions": "1.43.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-fFnTqGm8/G73GQVnxYi7LXa1ZVYEUvgL6XI1LpvV0bPC7WQ/ZGgKxCSl8FnlZBKto9JHHEFTO6s6CUpvvtwFrA=="],
+
+ "@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.11.0", "", { "dependencies": { "@opentelemetry/core": "2.11.0", "@opentelemetry/resources": "2.11.0", "@opentelemetry/sdk-trace": "2.11.0", "@opentelemetry/semantic-conventions": "1.43.0" }, "peerDependencies": { "@opentelemetry/api": "1.9.1" } }, "sha512-H19x/TX/LZdqiYOjM7fqtSxwlplC5pgelavqbQdHbhdq0q/AI/TGkM2dfGuuynTXmJPeF2HoZVoPDu+TGoW78A=="],
+
+ "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.43.0", "", {}, "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg=="],
+
+ "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.120.0", "", { "os": "android", "cpu": "arm" }, "sha512-WU3qtINx802wOl8RxAF1v0VvmC2O4D9M8Sv486nLeQ7iPHVmncYZrtBhB4SYyX+XZxj2PNnCcN+PW21jHgiOxg=="],
+
+ "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.120.0", "", { "os": "android", "cpu": "arm64" }, "sha512-SEf80EHdhlbjZEgzeWm0ZA/br4GKMenDW3QB/gtyeTV1gStvvZeFi40ioHDZvds2m4Z9J1bUAUL8yn1/+A6iGg=="],
+
+ "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.120.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-xVrrbCai8R8CUIBu3CjryutQnEYhZqs1maIqDvtUCFZb8vY33H7uh9mHpL3a0JBIKoBUKjPH8+rzyAeXnS2d6A=="],
+
+ "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.120.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-xyHBbnJ6mydnQUH7MAcafOkkrNzQC6T+LXgDH/3InEq2BWl/g424IMRiJVSpVqGjB+p2bd0h0WRR8iIwzjU7rw=="],
+
+ "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.120.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMnVRllquXUYTeNfFKmxTTEdZ/ix1nLl0ducDzMSREoWYGVIHnOOxoKMWlCOvRr9Wk/HZqo2rh1jeumbPGPV9A=="],
+
+ "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.120.0", "", { "os": "linux", "cpu": "arm" }, "sha512-tkvn2CQ7QdcsMnpfiX3fd3wA3EFsWKYlcQzq9cFw/xc89Al7W6Y4O0FgLVkVQpo0Tnq/qtE1XfkJOnRRA9S/NA=="],
+
+ "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.120.0", "", { "os": "linux", "cpu": "arm" }, "sha512-WN5y135Ic42gQDk9grbwY9++fDhqf8knN6fnP+0WALlAUh4odY/BDK1nfTJRSfpJD9P3r1BwU0m3pW2DU89whQ=="],
+
+ "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.120.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-1GgQBCcXvFMw99EPdMy+4NZ3aYyXsxjf9kbUUg8HuAy3ZBXzOry5KfFEzT9nqmgZI1cuetvApkiJBZLAPo8uaw=="],
+
+ "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.120.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gmMQ70gsPdDBgpcErvJEoWNBr7bJooSLlvOBVBSGfOzlP5NvJ3bFvnUeZZ9d+dPrqSngtonf7nyzWUTUj/U+lw=="],
+
+ "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.120.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-T/kZuU0ajop0xhzVMwH5r3srC9Nqup5HaIo+3uFjIN5uPxa0LvSxC1ZqP4aQGJVW5G0z8/nCkjIfSMS91P/wzw=="],
+
+ "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.120.0", "", { "os": "linux", "cpu": "none" }, "sha512-vn21KXLAXzaI3N5CZWlBr1iWeXLl9QFIMor7S1hUjUGTeUuWCoE6JZB040/ZNDwf+JXPX8Ao9KbmJq9FMC2iGw=="],
+
+ "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.120.0", "", { "os": "linux", "cpu": "none" }, "sha512-SUbUxlar007LTGmSLGIC5x/WJvwhdX+PwNzFJ9f/nOzZOrCFbOT4ikt7pJIRg1tXVsEfzk5mWpGO1NFiSs4PIw=="],
+
+ "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.120.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hYiPJTxyfJY2+lMBFk3p2bo0R9GN+TtpPFlRqVchL1qvLG+pznstramHNvJlw9AjaoRUHwp9IKR7UZQnRPGjgQ=="],
+
+ "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.120.0", "", { "os": "linux", "cpu": "x64" }, "sha512-q+5jSVZkprJCIy3dzJpApat0InJaoxQLsJuD6DkX8hrUS61z2lHQ1Fe9L2+TYbKHXCLWbL0zXe7ovkIdopBGMQ=="],
+
+ "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.120.0", "", { "os": "linux", "cpu": "x64" }, "sha512-D9QDDZNnH24e7X4ftSa6ar/2hCavETfW3uk0zgcMIrZNy459O5deTbWrjGzZiVrSWigGtlQwzs2McBP0QsfV1w=="],
+
+ "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.120.0", "", { "os": "none", "cpu": "arm64" }, "sha512-TBU8ZwOUWAOUWVfmI16CYWbvh4uQb9zHnGBHsw5Cp2JUVG044OIY1CSHODLifqzQIMTXvDvLzcL89GGdUIqNrA=="],
+
+ "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.120.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "1.2.4" }, "cpu": "none" }, "sha512-WG/FOZgDJCpJnuF3ToG/K28rcOmSY7FmFmfBKYb2fmLyhDzPpUldFGV7/Fz4ru0Iz/v4KPmf8xVgO8N3lO4KHA=="],
+
+ "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.120.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1T0HKGcsz/BKo77t7+89L8Qvu4f9DoleKWHp3C5sJEcbCjDOLx3m9m722bWZTY+hANlUEs+yjlK+lBFsA+vrVQ=="],
+
+ "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.120.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-L7vfLzbOXsjBXV0rv/6Y3Jd9BRjPeCivINZAqrSyAOZN3moCopDN+Psq9ZrGNZtJzP8946MtlRFZ0Als0wBCOw=="],
+
+ "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.120.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ys+upfqNtSu58huAhJMBKl3XCkGzyVFBlMlGPzHeFKgpFF/OdgNs1MMf8oaJIbgMH8ZxgGF7qfue39eJohmKIg=="],
+
+ "@oxc-project/types": ["@oxc-project/types@0.152.0", "", {}, "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw=="],
+
+ "@posthog/browser-common": ["@posthog/browser-common@0.9.1", "", { "dependencies": { "@posthog/core": "1.56.0", "@posthog/types": "1.413.0" } }, "sha512-Dl8uV2OZAxfHfWyC7K0Y3HtT7ld+WGLbXIwgCgAGziOMGDIa/bepCRrCxy7IxsEzqY1HOrq/VDdcoNN7hBTSQQ=="],
+
+ "@posthog/core": ["@posthog/core@1.56.0", "", { "dependencies": { "@posthog/types": "1.413.0" } }, "sha512-WNlOoFQbOZyJzX54DhAslSpTjwDyXX5VLuRFNJjv172uOE9qHVUvtZAPP9dHZdq2HZkkLjbY27idH7UhzKSBVA=="],
+
+ "@posthog/types": ["@posthog/types@1.413.0", "", {}, "sha512-tYAVzNojWckuG/wxBB0fwE70sFruQQq4xbhkci7eH2ARU3mMfUTkvpN1HwBMpm0AtbxidLiH0IFvagmdJ8opPw=="],
+
+ "@radix-ui/primitive": ["@radix-ui/primitive@1.1.7", "", {}, "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q=="],
+
+ "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.5", "", { "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA=="],
+
+ "@radix-ui/react-context": ["@radix-ui/react-context@1.2.2", "", { "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA=="],
+
+ "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.2.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-context": "1.2.2", "@radix-ui/react-dismissable-layer": "1.1.20", "@radix-ui/react-focus-guards": "1.1.6", "@radix-ui/react-focus-scope": "1.2.0", "@radix-ui/react-id": "1.1.4", "@radix-ui/react-portal": "1.1.18", "@radix-ui/react-presence": "1.1.11", "@radix-ui/react-primitive": "2.1.11", "@radix-ui/react-slot": "1.4.0", "@radix-ui/react-use-controllable-state": "1.2.6", "@radix-ui/react-use-layout-effect": "1.1.4", "aria-hidden": "1.2.6", "react-remove-scroll": "2.7.2" }, "optionalDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-l5CX8HdNL+9cc4s7HkNyplumSA3FIx68sg9dttBHKr286fRBwq1MBniDVTeI/tkof92/APntMQvC1YG1Khb0Cg=="],
+
+ "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.20", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-primitive": "2.1.11", "@radix-ui/react-use-callback-ref": "1.1.4", "@radix-ui/react-use-effect-event": "0.0.5" }, "optionalDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-35WHRrycfnj2m4LvPiKMKHGLM3Y2WvUA744CkRdxjs1BGDX1c8PVMfmiSGTUwnHRbqdtIoxveYTXvcJSt7VfgQ=="],
+
+ "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.6", "", { "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ=="],
+
+ "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-primitive": "2.1.11", "@radix-ui/react-use-callback-ref": "1.1.4" }, "optionalDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-I5S7vsAOozx2lWSBAyuXjWIJ/A8qx4fjbv6115WoaRYQSb1yZDaeNHonUAQzXyE8oD+0whJHbQRl4HIE2gQ0Xw=="],
+
+ "@radix-ui/react-id": ["@radix-ui/react-id@1.1.4", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.4" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA=="],
+
+ "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.18", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.11", "@radix-ui/react-use-layout-effect": "1.1.4" }, "optionalDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-ygFIJ+QXNKf72AAq8x3hd22+ws7pYpmc1S0E4kW0Je+qD4qEb3FvxeKVQRGrVDMOkQaYfsB+Qs+KDh81a1gAOw=="],
+
+ "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.11", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.4" }, "optionalDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA=="],
+
+ "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.11", "", { "dependencies": { "@radix-ui/react-slot": "1.4.0" }, "optionalDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-RzcaSw5aKl0OPhBJ1wbolKSF6nVvN+0o/QLeIVq+09npiPdnCkPggy2k6gI6yetxl4ZyrlBPYFgCB8BQJZwXcQ=="],
+
+ "@radix-ui/react-slot": ["@radix-ui/react-slot@1.4.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-IuMVHZ+Ah5fkctu3X3qeFrV/ZrBcuWuDTFUUPfS/L5hvoTjzhp/HdWGE14CsQombPdEidsa33HVlYZXi49PZ1Q=="],
+
+ "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.4", "", { "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ=="],
+
+ "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-use-effect-event": "0.0.5", "@radix-ui/react-use-layout-effect": "1.1.4" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ=="],
+
+ "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.5", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.4" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg=="],
+
+ "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.4", "", { "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw=="],
+
+ "@reduxjs/toolkit": ["@reduxjs/toolkit@2.13.0", "", { "dependencies": { "@standard-schema/spec": "1.1.0", "@standard-schema/utils": "0.3.0", "immer": "11.1.21", "redux": "5.0.1", "redux-thunk": "3.1.0", "reselect": "5.3.0" }, "optionalDependencies": { "react": "19.3.0", "react-redux": "9.3.0" } }, "sha512-f6jwVRfwW30+tnllz4YcsHHpPYYOE7abcHkyUCovD+P7DyhdAI5prz2Fh/8TLhakjpN+7aIEion1s5L/tvlYlA=="],
+
+ "@resvg/resvg-wasm": ["@resvg/resvg-wasm@2.6.2", "", {}, "sha512-FqALmHI8D4o6lk/LRWDnhw95z5eO+eAa6ORjVg09YRR7BkcM6oPHU9uyC0gtQG5vpFLvgpeU4+zEAz2H8APHNw=="],
+
+ "@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.12", "", { "os": "android", "cpu": "arm" }, "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A=="],
+
+ "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.12", "", { "os": "android", "cpu": "arm64" }, "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg=="],
+
+ "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w=="],
+
+ "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.2.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA=="],
+
+ "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.2.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ=="],
+
+ "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.2.12", "", { "os": "linux", "cpu": "arm" }, "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g=="],
+
+ "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.2.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw=="],
+
+ "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.2.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw=="],
+
+ "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.2.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ=="],
+
+ "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.2.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw=="],
+
+ "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.2.12", "", { "os": "linux", "cpu": "x64" }, "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw=="],
+
+ "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.2.12", "", { "os": "linux", "cpu": "x64" }, "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g=="],
+
+ "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.2.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA=="],
+
+ "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.2.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew=="],
+
+ "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.2.12", "", { "os": "win32", "cpu": "x64" }, "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ=="],
+
+ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="],
+
+ "@solid-primitives/event-listener": ["@solid-primitives/event-listener@2.4.6", "", { "dependencies": { "@solid-primitives/utils": "6.4.1" }, "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-5I0YJcTVYIWoMmgBSROBZGcz+ymhew/pGTg2dHW74BUjFKsV8Li4bOZYl0YAGP4mHw5o4UBd9/BEesqBci3wxw=="],
+
+ "@solid-primitives/keyboard": ["@solid-primitives/keyboard@1.3.7", "", { "dependencies": { "@solid-primitives/event-listener": "2.4.6", "@solid-primitives/rootless": "1.5.4", "@solid-primitives/utils": "6.4.1" }, "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-558RPNYnXx4nGh537DSqAn4xMrC8iFipl/5+xzgzWoTNFst4RnUN3BOLmtDjJ0UGGoQXVMALYR3bNOHM0xnt1Q=="],
+
+ "@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.2.0", "", { "dependencies": { "@solid-primitives/event-listener": "2.4.6", "@solid-primitives/rootless": "1.5.4", "@solid-primitives/static-store": "0.1.4", "@solid-primitives/utils": "6.4.1" }, "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-9Fuu/EWBeGj+atGHRJp70HKhdfalmpjwxY8a32NZixdLNmfCJ45AfhLQNr6uOzETbbiMx4iCKlTrJ8KZCHC2Ww=="],
+
+ "@solid-primitives/rootless": ["@solid-primitives/rootless@1.5.4", "", { "dependencies": { "@solid-primitives/utils": "6.4.1" }, "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-TOIZa1VUfVJ+9nkCcRajw3U4t9vBOP1HxX1WHNTbXq32mXwlqTvUnC4CRIilohcryBkT9u2ZkhUDSHRTaGp55g=="],
+
+ "@solid-primitives/static-store": ["@solid-primitives/static-store@0.1.4", "", { "dependencies": { "@solid-primitives/utils": "6.4.1" }, "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-LgtVaVBtB7EbmS4+M0b8xY5Iq6pUWXBsIC4VgtrFKDGDdyCaDt88sHk0fUlx1Enxm/XZnZyLXJABRoa39RjJqA=="],
+
+ "@solid-primitives/utils": ["@solid-primitives/utils@6.4.1", "", { "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-ISSB5QX1qP2ynrheIpYwc4oKR5Ny4siNuUyf1qZniy+Il+p/PtDB0QK1Dnle8noiHpwRD3gpPdubOC3qI/Zamg=="],
+
+ "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
+
+ "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
+
+ "@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "enhanced-resolve": "5.26.0", "jiti": "2.7.0", "lightningcss": "1.32.0", "magic-string": "0.30.21", "source-map-js": "1.2.2", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="],
+
+ "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="],
+
+ "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.3", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="],
+
+ "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="],
+
+ "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="],
+
+ "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="],
+
+ "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="],
+
+ "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="],
+
+ "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="],
+
+ "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="],
+
+ "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="],
+
+ "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.3", "", { "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="],
+
+ "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="],
+
+ "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="],
+
+ "@tailwindcss/typography": ["@tailwindcss/typography@0.5.20", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": "4.3.3" } }, "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw=="],
+
+ "@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "8.3.2" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="],
+
+ "@tanstack/devtools": ["@tanstack/devtools@0.15.0", "", { "dependencies": { "@neodrag/core": "3.0.0-next.11", "@neodrag/solid": "3.0.0-next.11", "@solid-primitives/event-listener": "2.4.6", "@solid-primitives/keyboard": "1.3.7", "@solid-primitives/resize-observer": "2.2.0", "@tanstack/devtools-client": "0.0.8", "@tanstack/devtools-event-bus": "0.4.3", "@tanstack/devtools-ui": "0.7.1", "clsx": "2.1.1", "goober": "2.1.19" }, "peerDependencies": { "solid-js": "1.9.15" }, "bin": { "intent": "./bin/intent.js" } }, "sha512-KyS7Qi82Eq9yG8C+uae3ikAPb+D5rfzVhvOOjXVAHZ/64s6TWJlDWpREw1FrHIYZaI7paErpsExSSKlF5BKA/A=="],
+
+ "@tanstack/devtools-bundler-core": ["@tanstack/devtools-bundler-core@0.1.3", "", { "dependencies": { "@tanstack/devtools-client": "0.0.8", "@tanstack/devtools-event-bus": "0.4.3", "chalk": "5.6.2", "launch-editor": "2.14.1", "magic-string": "0.30.21", "oxc-parser": "0.120.0", "picomatch": "4.0.7" } }, "sha512-F0tlxIyfFqXkZ1mJP1EjtkiSeJA+ztXY2AYOHf7r4goCIEAOp86N9PFJ/yv8vu1TnmxGS6vKsZCS3Kyls9xQQA=="],
+
+ "@tanstack/devtools-client": ["@tanstack/devtools-client@0.0.8", "", { "dependencies": { "@tanstack/devtools-event-client": "0.5.0" } }, "sha512-cG3iZkGWCwN330bLBKa8+9r4Of2AXNoz2zUqcsy/4XsD3105ghVBx78cGyvJj9fSclNomPxoqAnDGXXhg1WLvA=="],
+
+ "@tanstack/devtools-event-bus": ["@tanstack/devtools-event-bus@0.4.3", "", { "dependencies": { "ws": "8.22.0" } }, "sha512-NeegBt5/n2E5q4DbrXHqECBq42+kDi6JBOp8/+RNqkIE+P4hJpbM36kGyjnGQFMWOoku31qhMyX9/48VuTTdmg=="],
+
+ "@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.5.0", "", { "bin": { "intent": "./bin/intent.js" } }, "sha512-H+OH3zC6Vhu/K0NaVfQKknEKawc/+2PT+D3SB3Ox0V8SiMlTo0abbmH2rH0721R2aNYbjdMXA1oENOd8E2UVoA=="],
+
+ "@tanstack/devtools-ui": ["@tanstack/devtools-ui@0.7.1", "", { "dependencies": { "clsx": "2.1.1", "dayjs": "1.11.23", "goober": "2.1.19" }, "peerDependencies": { "solid-js": "1.9.15" } }, "sha512-3xQ/ezZ2qVNszhjpCN2N3jn7uHc2J1PMgcyjHzH4XZBt9xAQyMMcPNoR2cd7rzReyxWoJpZUWiDBmOJiCtLj9A=="],
+
+ "@tanstack/devtools-vite": ["@tanstack/devtools-vite@0.8.5", "", { "dependencies": { "@tanstack/devtools-bundler-core": "0.1.3", "@tanstack/devtools-client": "0.0.8", "@tanstack/devtools-event-bus": "0.4.3", "chalk": "5.6.2" }, "peerDependencies": { "vite": "8.3.2" }, "bin": { "intent": "./bin/intent.js" } }, "sha512-xaifCEmiwwzizlbp973oISXNsnmuU/BugLa66gryAZaPJJ/qo1kJd2DxY5X960eHwmyIS3SN0KYrL3/aRhucmA=="],
+
+ "@tanstack/history": ["@tanstack/history@1.162.4", "", {}, "sha512-utTS5L2OkeYUzXGohL1Z8sefu1GLNOJcxe8Hd6iIdc/Xo1K1nDB2JEp4iSFhvYh33xKC9V91TxrS8qfrpoKobQ=="],
+
+ "@tanstack/intent": ["@tanstack/intent@0.5.4", "", { "bin": { "intent": "dist/cli.mjs" } }, "sha512-veyJDHwIHrylKucn8UgLlMYZbhLZ3gO1OlYiXLcmIKazCd8bTDXRfcWvmwNK3q63jS8K40pYudZV3HQPbHsBWg=="],
+
+ "@tanstack/react-devtools": ["@tanstack/react-devtools@0.10.13", "", { "dependencies": { "@tanstack/devtools": "0.15.0" }, "peerDependencies": { "@types/react": "19.3.0", "@types/react-dom": "19.3.0", "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-r0cdB/14+st2Vxl/1Bodlyq4VC8pf9SykLQDYbGHDc1+V146WQo5B3KlYLkfyxD9Q/6+9NPRQHZyl8fvZVMdRA=="],
+
+ "@tanstack/react-router": ["@tanstack/react-router@1.170.41", "", { "dependencies": { "@tanstack/history": "1.162.4", "@tanstack/react-store": "0.11.2", "@tanstack/router-core": "1.171.34", "isbot": "5.2.2" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-Mpvw8Wm5MGDbTqI8Yc9flLKxbOHwoWocv0H2aGKcgw2a017oK5nZWqa954P+DrUx/8fI98YNywnHP5XcD3tQ9w=="],
+
+ "@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.167.2", "", { "dependencies": { "@tanstack/router-devtools-core": "1.168.2" }, "optionalDependencies": { "@tanstack/router-core": "1.171.34" }, "peerDependencies": { "@tanstack/react-router": "1.170.41", "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-VuoqB7OhDUrBa4WOFSKiAQ8xI8sJpeZdo9sYE1hQa89iMuVFUQu1iWE4iCiQhB+6TYOZDZ9e+iHKxYjop4ZVYw=="],
+
+ "@tanstack/react-start": ["@tanstack/react-start@1.168.60", "", { "dependencies": { "@tanstack/react-router": "1.170.41", "@tanstack/react-start-client": "1.168.39", "@tanstack/react-start-rsc": "0.1.59", "@tanstack/react-start-server": "1.167.46", "@tanstack/router-utils": "1.162.3", "@tanstack/start-client-core": "1.170.34", "@tanstack/start-plugin-core": "1.171.49", "@tanstack/start-server-core": "1.169.39", "pathe": "2.0.3" }, "optionalDependencies": { "vite": "8.3.2" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-WMOM0Xlh2lPbVlbjYM6uOxOpiaWRPvODm/dwkLsGKq5tjyHOHZmKckJgwlrZl7OQUqFlOZHYj8bKUTgoeg8cUQ=="],
+
+ "@tanstack/react-start-client": ["@tanstack/react-start-client@1.168.39", "", { "dependencies": { "@tanstack/react-router": "1.170.41", "@tanstack/router-core": "1.171.34", "@tanstack/start-client-core": "1.170.34" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-Uby0uo37JlQgUKHU0snDwH9nYiEeAjm9+7pUOFgycU/UszEILC2SO2DSCoNnCMuHKj9z+4URKzBYIP2exT9+wg=="],
+
+ "@tanstack/react-start-rsc": ["@tanstack/react-start-rsc@0.1.59", "", { "dependencies": { "@tanstack/react-router": "1.170.41", "@tanstack/router-core": "1.171.34", "@tanstack/router-utils": "1.162.3", "@tanstack/start-client-core": "1.170.34", "@tanstack/start-fn-stubs": "1.162.0", "@tanstack/start-plugin-core": "1.171.49", "@tanstack/start-storage-context": "1.167.36", "pathe": "2.0.3" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-M2Lqxkk5C1zQncQs5paqX+/OLdOht51pg6D84YfLMrNsjhU/nzb6wd92MIja0mi5i23+L+fxLLjQYR2DObjBlw=="],
+
+ "@tanstack/react-start-server": ["@tanstack/react-start-server@1.167.46", "", { "dependencies": { "@tanstack/react-router": "1.170.41", "@tanstack/router-core": "1.171.34", "@tanstack/start-server-core": "1.169.39" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-K7z8xBOEdp8u5CZCxWrbS0tFtk5XZGMdhssLeZlRZKlLDbX7BKLdMtJ7th5sR6QVt9MTUAg3LcoqvJMPSFF+lg=="],
+
+ "@tanstack/react-store": ["@tanstack/react-store@0.11.2", "", { "dependencies": { "@tanstack/store": "0.11.2", "use-sync-external-store": "1.7.0" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-oj5O5DmiMWE+ih+SioX2ayC1kbK7d3fpLx0B75fPJr9nY3zU+hoW010yr64qXsY/9fyiLVE2bn5mGNV3owm8RQ=="],
+
+ "@tanstack/router-cli": ["@tanstack/router-cli@1.167.40", "", { "dependencies": { "@tanstack/router-generator": "1.167.40", "chokidar": "5.0.0", "yargs": "17.7.3" }, "bin": { "tsr": "bin/tsr.cjs" } }, "sha512-KKX9hedstsc0eEKfUAwrwy7CLNXdSxjiBBq0uojnjMnOnraRXP9Nf+x6/ZsAultxHp7NhWfYddO8VdT0zAtUDg=="],
+
+ "@tanstack/router-core": ["@tanstack/router-core@1.171.34", "", { "dependencies": { "@tanstack/history": "1.162.4", "cookie-es": "3.1.1", "seroval": "1.6.8", "seroval-plugins": "1.6.8" } }, "sha512-X+19pGuuLVPvvAvPYw9v/+ktRk5cCll8AtfpBpOhDRmVgUMrfqze0467xtq8YRVVs/mmo5rVtWn/7Tp32RDBKw=="],
+
+ "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.168.2", "", { "dependencies": { "clsx": "2.1.1", "goober": "2.1.19" }, "optionalDependencies": { "csstype": "3.2.3" }, "peerDependencies": { "@tanstack/router-core": "1.171.34" } }, "sha512-pCCdQ5M/NUeWdiAbPmjyfcNdls6G4vaVlIQbPf1IqZk1FLYFr00aQvi578yUuWFBNM2KNS2QcwM1uPucbtGf5Q=="],
+
+ "@tanstack/router-generator": ["@tanstack/router-generator@1.167.40", "", { "dependencies": { "@babel/types": "7.29.8", "@tanstack/router-core": "1.171.34", "@tanstack/router-utils": "1.162.3", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "2.7.0", "magic-string": "0.30.21", "prettier": "3.9.9", "zod": "4.6.5" } }, "sha512-WkEueqEvsBBudzO0fx1nWfOmRNW8OAvBoVABTGls9bAWzjdC+KDGHvjCNrvn88ofs1F6gqL8aWnzKCbxW3dCyQ=="],
+
+ "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.42", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/template": "7.29.7", "@babel/types": "7.29.8", "@tanstack/router-core": "1.171.34", "@tanstack/router-generator": "1.167.40", "@tanstack/router-utils": "1.162.3", "chokidar": "5.0.0", "unplugin": "3.4.0", "zod": "4.6.5" }, "optionalDependencies": { "@tanstack/react-router": "1.170.41", "vite": "8.3.2" } }, "sha512-vAR5WXJh/ErseEWQftDhsJcr2c++ucRQ6FbqN3ygMO44+ZxxRfW3sIpZmddHROVSmBk8jc6MrwjTPNjVhd62Vw=="],
+
+ "@tanstack/router-utils": ["@tanstack/router-utils@1.162.3", "", { "dependencies": { "@babel/generator": "7.29.8", "@babel/parser": "7.29.9", "@babel/types": "7.29.8", "ansis": "4.4.0", "babel-dead-code-elimination": "1.0.12", "diff": "8.0.4", "pathe": "2.0.3", "tinyglobby": "0.2.17" } }, "sha512-Icb0xGuG1+54IV0WMLRcc3ErTx2HeJWyPG661FkQ8UT6guoBq1FJjFRqlG/JS0xi4mFFkBhvwO7tbLa32f3yxA=="],
+
+ "@tanstack/start-client-core": ["@tanstack/start-client-core@1.170.34", "", { "dependencies": { "@tanstack/router-core": "1.171.34", "@tanstack/start-fn-stubs": "1.162.0", "@tanstack/start-storage-context": "1.167.36", "seroval": "1.6.8" } }, "sha512-LfwZSbau2MLLZ/uPAoO+NC9fK3J66c0wLhnNQqIa+Goqw7bXPjkHwlsjY7evlUz1AnyhhQ1Qab95v+VmP0TZ9A=="],
+
+ "@tanstack/start-fn-stubs": ["@tanstack/start-fn-stubs@1.162.0", "", {}, "sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ=="],
+
+ "@tanstack/start-plugin-core": ["@tanstack/start-plugin-core@1.171.49", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/core": "7.29.7", "@babel/types": "7.29.8", "@jridgewell/remapping": "2.3.5", "@tanstack/router-core": "1.171.34", "@tanstack/router-generator": "1.167.40", "@tanstack/router-plugin": "1.168.42", "@tanstack/router-utils": "1.162.3", "@tanstack/start-server-core": "1.169.39", "exsolve": "1.1.3", "lightningcss": "1.33.0", "pathe": "2.0.3", "picomatch": "4.0.7", "seroval": "1.6.8", "source-map": "0.7.6", "srvx": "0.11.22", "tinyglobby": "0.2.17", "ufo": "1.6.4", "vitefu": "1.1.3", "xmlbuilder2": "4.0.3", "zod": "4.6.5" }, "optionalDependencies": { "vite": "8.3.2" } }, "sha512-HPOb7LnMc71k38cd5uvMybPPUU/Q/56KvSqQzSWz7cps1ZDFXaxUM6EFaFHLCdgTWqGexNGDdRE+sUVPVBM4Xg=="],
+
+ "@tanstack/start-server-core": ["@tanstack/start-server-core@1.169.39", "", { "dependencies": { "@tanstack/history": "1.162.4", "@tanstack/router-core": "1.171.34", "@tanstack/start-client-core": "1.170.34", "@tanstack/start-storage-context": "1.167.36", "fetchdts": "0.1.7", "h3-v2": "npm:h3@2.0.1-rc.20", "seroval": "1.6.8" } }, "sha512-pqqkxhXY46nuFSYt6TsMGyABiplUzHFHndKAlRRGC0fWDrJCH1koWxVMoxySa51ZETV79f/z73b5UZ1jfIkXwQ=="],
+
+ "@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.167.36", "", { "dependencies": { "@tanstack/router-core": "1.171.34" } }, "sha512-x+xCXK2GtFzY6NbXqAg8YpU6cwAjDfMeYSNzxfGzntpjbwBRHHrXeC/kYUnBBQCV7wK4kJ8vBBQGP0OyYTasUg=="],
+
+ "@tanstack/store": ["@tanstack/store@0.11.2", "", {}, "sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q=="],
+
+ "@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.162.0", "", {}, "sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA=="],
+
+ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.4", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A=="],
+
+ "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="],
+
+ "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="],
+
+ "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="],
+
+ "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "3.1.3" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="],
+
+ "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
+
+ "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "3.0.4" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
+
+ "@types/d3-shape": ["@types/d3-shape@3.2.0", "", { "dependencies": { "@types/d3-path": "3.1.1" } }, "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw=="],
+
+ "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="],
+
+ "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="],
+
+ "@types/node": ["@types/node@22.20.5", "", { "dependencies": { "undici-types": "6.21.0" } }, "sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA=="],
+
+ "@types/pg": ["@types/pg@8.23.1", "", { "dependencies": { "@types/node": "22.20.5", "pg-protocol": "1.16.1", "pg-types": "2.2.0" } }, "sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A=="],
+
+ "@types/react": ["@types/react@19.3.0", "", { "dependencies": { "csstype": "3.2.3" } }, "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg=="],
+
+ "@types/react-dom": ["@types/react-dom@19.3.0", "", { "peerDependencies": { "@types/react": "19.3.0" } }, "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q=="],
+
+ "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
+
+ "@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="],
+
+ "@vitejs/plugin-react": ["@vitejs/plugin-react@6.1.1", "", { "dependencies": { "@rolldown/pluginutils": "1.0.1" }, "peerDependencies": { "vite": "8.3.2" } }, "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw=="],
+
+ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
+ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
+
+ "ansis": ["ansis@4.4.0", "", {}, "sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA=="],
+
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
+
+ "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
+
+ "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/parser": "7.29.9", "@babel/traverse": "7.29.8", "@babel/types": "7.29.8" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="],
+
+ "baseline-browser-mapping": ["baseline-browser-mapping@2.11.27", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ=="],
+
+ "better-auth": ["better-auth@1.7.7", "", { "dependencies": { "@better-auth/core": "1.7.7", "@better-auth/drizzle-adapter": "1.7.7", "@better-auth/kysely-adapter": "1.7.7", "@better-auth/memory-adapter": "1.7.7", "@better-auth/mongo-adapter": "1.7.7", "@better-auth/prisma-adapter": "1.7.7", "@better-auth/telemetry": "1.7.7", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.2", "@noble/ciphers": "2.4.0", "@noble/hashes": "2.4.0", "better-call": "1.4.0", "defu": "6.1.7", "jose": "6.2.12", "kysely": "0.29.6", "nanostores": "1.5.4", "zod": "4.6.5" }, "optionalDependencies": { "@tanstack/react-start": "1.168.60", "drizzle-kit": "0.31.11", "drizzle-orm": "0.45.3", "pg": "8.23.1", "react": "19.3.0", "react-dom": "19.3.0", "solid-js": "1.9.15" } }, "sha512-Zhgxi/c5ylmfB/sX+nwnBbsFf/j6k0L8DvL6CJXZSrXgxc5pPMC/e7j812zNd4L4B4ELmdURCPw3X8nAOUdcjw=="],
+
+ "better-call": ["better-call@1.4.0", "", { "dependencies": { "@better-auth/utils": "0.5.0", "@better-fetch/fetch": "1.3.2", "rou3": "0.9.2", "set-cookie-parser": "3.1.2" }, "optionalDependencies": { "zod": "4.6.5" } }, "sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA=="],
+
+ "browserslist": ["browserslist@4.29.3", "", { "dependencies": { "baseline-browser-mapping": "2.11.27", "caniuse-lite": "1.0.30001814", "electron-to-chromium": "1.5.444", "node-releases": "2.0.57", "update-browserslist-db": "1.3.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA=="],
+
+ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
+
+ "caniuse-lite": ["caniuse-lite@1.0.30001814", "", {}, "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA=="],
+
+ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
+
+ "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "5.1.1" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="],
+
+ "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
+
+ "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "4.2.3", "strip-ansi": "6.0.1", "wrap-ansi": "7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
+
+ "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
+
+ "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-dialog": "1.2.0", "@radix-ui/react-id": "1.1.4", "@radix-ui/react-primitive": "2.1.11" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="],
+
+ "cn": ["cn@0.4.0", "", { "bin": { "cn": "bin/cn.mjs" } }, "sha512-qOAeUhPwPzBxx6jaeQdo646XIKliKHc2j1ZF7Ngb1o0pJZKH5gq8FkA0aVdUdPFUDXNXyUCXpCtoJISo6dhizg=="],
+
+ "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
+
+ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
+
+ "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
+
+ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
+
+ "cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="],
+
+ "core-js": ["core-js@3.50.0", "", {}, "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw=="],
+
+ "croner": ["croner@10.0.1", "", {}, "sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g=="],
+
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "3.1.1", "shebang-command": "2.0.0", "which": "2.0.2" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
+
+ "crossws": ["crossws@0.4.12", "", { "optionalDependencies": { "srvx": "0.11.22" } }, "sha512-aypfsr6t0uNvkqaZc6zvBfXzC6pLI0/sIulpkV6RwCVtZqG5ebBzv4weImKK0VNCj91Wl9F5j7p5WU4MNrybng=="],
+
+ "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
+
+ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
+
+ "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "2.0.3" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
+
+ "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
+
+ "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="],
+
+ "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="],
+
+ "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "3.1.0" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
+
+ "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
+
+ "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "3.2.4", "d3-format": "3.1.2", "d3-interpolate": "3.0.1", "d3-time": "3.1.0", "d3-time-format": "4.1.0" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
+
+ "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
+
+ "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "3.2.4" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
+
+ "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "3.1.0" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
+
+ "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
+
+ "dayjs": ["dayjs@1.11.23", "", {}, "sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ=="],
+
+ "db0": ["db0@0.3.4", "", { "optionalDependencies": { "@electric-sql/pglite": "0.5.8", "drizzle-orm": "0.45.3" } }, "sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw=="],
+
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
+
+ "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="],
+
+ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
+
+ "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
+
+ "diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="],
+
+ "dompurify": ["dompurify@3.4.16", "", { "optionalDependencies": { "@types/trusted-types": "2.0.7" } }, "sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ=="],
+
+ "drizzle-kit": ["drizzle-kit@0.31.11", "", { "dependencies": { "@drizzle-team/brocli": "0.10.2", "@esbuild-kit/esm-loader": "2.6.5", "esbuild": "0.25.12", "tsx": "4.23.15" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-YCYqxTLIB2OCqf6w9/Vef13baBVbwQIPcbT4Y56AfO6B9ajZhDhD8Jkveg/hJvT/iuMloKD/IYYkyMMNhr7Kqg=="],
+
+ "drizzle-orm": ["drizzle-orm@0.45.3", "", { "optionalDependencies": { "@electric-sql/pglite": "0.5.8", "@opentelemetry/api": "1.9.1", "@types/pg": "8.23.1", "kysely": "0.29.6", "pg": "8.23.1" } }, "sha512-CAloER21cDdcgZ1OmjrZX82EeRNsdP+y0onX/eyoYDaYzki/adrAa91lzM5jWh7zZPK4qUbw/6LGv9J+A+uizA=="],
+
+ "electron-to-chromium": ["electron-to-chromium@1.5.444", "", {}, "sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ=="],
+
+ "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "enhanced-resolve": ["enhanced-resolve@5.26.0", "", { "dependencies": { "graceful-fs": "4.2.11", "tapable": "2.3.3" } }, "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw=="],
+
+ "env-runner": ["env-runner@0.1.16", "", { "dependencies": { "crossws": "0.4.12", "exsolve": "1.1.3", "httpxy": "0.5.5", "srvx": "0.11.22" }, "bin": { "env-runner": "dist/cli.mjs" } }, "sha512-2LRJM4P2KLX6J83QZZrMqvgCDt/D5ea7wPcI3yYiy5cG/9rX5QwdwZFx0D7ktWnjdRyZxYjttGGorb5nFqb1CA=="],
+
+ "es-toolkit": ["es-toolkit@1.52.0", "", {}, "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA=="],
+
+ "esbuild": ["esbuild@0.25.12", "", { "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" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
+
+ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
+
+ "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
+
+ "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "3.1.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
+
+ "eventsource-parser": ["eventsource-parser@3.1.1", "", {}, "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ=="],
+
+ "exsolve": ["exsolve@1.1.3", "", {}, "sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA=="],
+
+ "fdir": ["fdir@6.5.0", "", { "optionalDependencies": { "picomatch": "4.0.7" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
+
+ "fetchdts": ["fetchdts@0.1.7", "", {}, "sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA=="],
+
+ "fflate": ["fflate@0.4.9", "", {}, "sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw=="],
+
+ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
+
+ "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
+
+ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
+
+ "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
+
+ "get-tsconfig": ["get-tsconfig@4.14.3", "", { "dependencies": { "resolve-pkg-maps": "1.0.0" } }, "sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA=="],
+
+ "goober": ["goober@2.1.19", "", { "peerDependencies": { "csstype": "3.2.3" } }, "sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg=="],
+
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
+
+ "h3": ["h3@2.0.1-rc.22", "", { "dependencies": { "rou3": "0.8.1", "srvx": "0.11.22" }, "optionalDependencies": { "crossws": "0.4.12" }, "bin": { "h3": "bin/h3.mjs" } }, "sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA=="],
+
+ "h3-v2": ["h3@2.0.1-rc.20", "", { "dependencies": { "rou3": "0.8.1", "srvx": "0.11.22" }, "optionalDependencies": { "crossws": "0.4.12" }, "bin": { "h3": "bin/h3.mjs" } }, "sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg=="],
+
+ "hookable": ["hookable@6.1.2", "", {}, "sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg=="],
+
+ "httpxy": ["httpxy@0.5.5", "", {}, "sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA=="],
+
+ "immer": ["immer@10.2.0", "", {}, "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="],
+
+ "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
+
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
+
+ "isbot": ["isbot@5.2.2", "", {}, "sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w=="],
+
+ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
+
+ "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="],
+
+ "jose": ["jose@6.2.12", "", {}, "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw=="],
+
+ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
+
+ "js-yaml": ["js-yaml@4.3.2", "", { "dependencies": { "argparse": "2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA=="],
+
+ "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
+
+ "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
+
+ "kysely": ["kysely@0.29.6", "", {}, "sha512-hHaB8C/rfzDDtr/t8YZwxAuPJTT0zHyaPoVzcXwDYhYNAgH/4sIfVhi/XLLIY+bL/FqaIJnjATDbi8ObSELmxg=="],
+
+ "launch-editor": ["launch-editor@2.14.1", "", { "dependencies": { "picocolors": "1.1.1", "shell-quote": "1.12.0" } }, "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA=="],
+
+ "lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="],
+
+ "lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="],
+
+ "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="],
+
+ "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.33.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ=="],
+
+ "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.33.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg=="],
+
+ "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.33.0", "", { "os": "linux", "cpu": "arm" }, "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ=="],
+
+ "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg=="],
+
+ "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ=="],
+
+ "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg=="],
+
+ "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw=="],
+
+ "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.33.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA=="],
+
+ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="],
+
+ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "3.1.1" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
+
+ "lucide-react": ["lucide-react@0.577.0", "", { "peerDependencies": { "react": "19.3.0" } }, "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A=="],
+
+ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.6.0" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
+
+ "marked": ["marked@18.0.14", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-mBHK6FBHuBAlhgRe88w9F0O1AbwwXJUcQibUbC/QcdTbVGAD7aWza+xt3N6oT/jCZx3/OMeS+8rnuiHZcQ9s7A=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "nanoid": ["nanoid@3.3.19", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug=="],
+
+ "nanostores": ["nanostores@1.5.4", "", {}, "sha512-4UXY7OAJEK0Y6V3SudBU7cXjAzTDc189R78dDOh0Xbm19gpKYto6WizSg58LJf12lTsRxKSLGyE117OiLpM4DQ=="],
+
+ "nf3": ["nf3@0.3.24", "", {}, "sha512-HxLK4bo+5jNsEETZp4w3tJblHOA9MCBY14IN9nZJJV8JDxt9yNIYxuBuLMjTAR5GFa3HL61+8VQDUrXv3/C8fw=="],
+
+ "nitro": ["nitro@3.0.260610-beta", "", { "dependencies": { "consola": "3.4.2", "crossws": "0.4.12", "db0": "0.3.4", "env-runner": "0.1.16", "h3": "2.0.1-rc.22", "hookable": "6.1.2", "nf3": "0.3.24", "ocache": "0.1.5", "ofetch": "2.0.0-alpha.3", "ohash": "2.0.12", "rolldown": "1.2.12", "srvx": "0.11.22", "unenv": "2.0.0-rc.24", "unstorage": "2.0.0-alpha.7" }, "optionalDependencies": { "jiti": "2.7.0", "vite": "8.3.2" }, "bin": { "nitro": "dist/cli/index.mjs" } }, "sha512-KPb4L5yaF/Rx/xoGMpgHRJvZhbhGiqbRKOwwPLCH9jKTKTsEUHLjnJas85AeCzaswqa8Wi52eQBtRsODC4PS0Q=="],
+
+ "node-releases": ["node-releases@2.0.57", "", {}, "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw=="],
+
+ "ocache": ["ocache@0.1.5", "", { "dependencies": { "ohash": "2.0.12" } }, "sha512-kNNnkkVQup/QDvmTz8Q84wc2ntiyoVHDxa6eHWKt5qdGAmFRBIxy83rxgCYEjW0x06UJ9E3P6VgM2yY4rOBH4w=="],
+
+ "ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="],
+
+ "ohash": ["ohash@2.0.12", "", {}, "sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw=="],
+
+ "openprofit": ["openprofit@workspace:packages/cli"],
+
+ "oxc-parser": ["oxc-parser@0.120.0", "", { "dependencies": { "@oxc-project/types": "0.120.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.120.0", "@oxc-parser/binding-android-arm64": "0.120.0", "@oxc-parser/binding-darwin-arm64": "0.120.0", "@oxc-parser/binding-darwin-x64": "0.120.0", "@oxc-parser/binding-freebsd-x64": "0.120.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.120.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.120.0", "@oxc-parser/binding-linux-arm64-gnu": "0.120.0", "@oxc-parser/binding-linux-arm64-musl": "0.120.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.120.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.120.0", "@oxc-parser/binding-linux-riscv64-musl": "0.120.0", "@oxc-parser/binding-linux-s390x-gnu": "0.120.0", "@oxc-parser/binding-linux-x64-gnu": "0.120.0", "@oxc-parser/binding-linux-x64-musl": "0.120.0", "@oxc-parser/binding-openharmony-arm64": "0.120.0", "@oxc-parser/binding-wasm32-wasi": "0.120.0", "@oxc-parser/binding-win32-arm64-msvc": "0.120.0", "@oxc-parser/binding-win32-ia32-msvc": "0.120.0", "@oxc-parser/binding-win32-x64-msvc": "0.120.0" } }, "sha512-WyPWZlcIm+Fkte63FGfgFB8mAAk33aH9h5N9lphXVOHSXEBFFsmYdOBedVKly363aWABjZdaj/m9lBfEY4wt+w=="],
+
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
+
+ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
+
+ "pg": ["pg@8.23.1", "", { "dependencies": { "pg-connection-string": "2.14.1", "pg-pool": "3.14.0", "pg-protocol": "1.16.1", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "1.4.1" } }, "sha512-aL96AHANtWjPLDOLqnhx+ngp9+UK7ETEU8VJrDCGvsSSi/mGLcWYsS6Herg7lmaBJe4uwrfqsa7gTEFaSizDoQ=="],
+
+ "pg-cloudflare": ["pg-cloudflare@1.4.1", "", {}, "sha512-6PQbsFWZcp9EmJEwy5cGQ2La+AMWpP46lgbb8X+U/XsHIUweYDNCpeuKck5RxL2MdVFi7krbbEi5nX4Zh7JhrQ=="],
+
+ "pg-connection-string": ["pg-connection-string@2.14.1", "", {}, "sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA=="],
+
+ "pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="],
+
+ "pg-pool": ["pg-pool@3.14.0", "", { "peerDependencies": { "pg": "8.23.1" } }, "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw=="],
+
+ "pg-protocol": ["pg-protocol@1.16.1", "", {}, "sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg=="],
+
+ "pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "2.0.0", "postgres-bytea": "1.0.1", "postgres-date": "1.0.7", "postgres-interval": "1.2.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="],
+
+ "pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "4.2.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="],
+
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
+
+ "picomatch": ["picomatch@4.0.7", "", {}, "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA=="],
+
+ "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="],
+
+ "postcss": ["postcss@8.5.28", "", { "dependencies": { "nanoid": "3.3.19", "picocolors": "1.1.1", "source-map-js": "1.2.2" } }, "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A=="],
+
+ "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "3.0.0", "util-deprecate": "1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
+
+ "postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
+
+ "postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="],
+
+ "postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="],
+
+ "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "4.0.2" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="],
+
+ "posthog-js": ["posthog-js@1.436.1", "", { "dependencies": { "@posthog/browser-common": "0.9.1", "@posthog/core": "1.56.0", "@posthog/types": "1.413.0", "core-js": "3.50.0", "dompurify": "3.4.16", "fflate": "0.4.9", "preact": "10.29.8", "query-selector-shadow-dom": "1.0.1", "web-vitals": "6.2.3", "web-vitals-soft-navs": "npm:web-vitals@6.2.1" }, "optionalDependencies": { "@types/react": "19.3.0", "react": "19.3.0" } }, "sha512-+uPcck+hcaBbjtxBwOtiiZ9BcBXyJmewumUMVP5MrIZO36BHHZ+SzvHTxFsA5soNbPo2fuLppsWfpNnuSjbNeA=="],
+
+ "posthog-node": ["posthog-node@5.55.0", "", { "dependencies": { "@posthog/core": "1.56.0" } }, "sha512-8dFtlDTqs0CKGZ8t4mUnk4NdShAgzru3B9D0MfM/NTBzlRyAjctivzWINLtMLRQxYjvgBohxy7RTwiQf4mPycQ=="],
+
+ "preact": ["preact@10.29.8", "", {}, "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q=="],
+
+ "prettier": ["prettier@3.9.9", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg=="],
+
+ "query-selector-shadow-dom": ["query-selector-shadow-dom@1.0.1", "", {}, "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw=="],
+
+ "react": ["react@19.3.0", "", {}, "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog=="],
+
+ "react-dom": ["react-dom@19.3.0", "", { "dependencies": { "scheduler": "0.28.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q=="],
+
+ "react-is": ["react-is@19.3.0", "", {}, "sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA=="],
+
+ "react-redux": ["react-redux@9.3.0", "", { "dependencies": { "@types/use-sync-external-store": "0.0.6", "use-sync-external-store": "1.7.0" }, "optionalDependencies": { "@types/react": "19.3.0", "redux": "5.0.1" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g=="],
+
+ "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "2.3.8", "react-style-singleton": "2.2.3", "tslib": "2.8.1", "use-callback-ref": "1.3.3", "use-sidecar": "1.1.3" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="],
+
+ "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "2.2.3", "tslib": "2.8.1" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
+
+ "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "1.0.1", "tslib": "2.8.1" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
+
+ "readdirp": ["readdirp@5.1.1", "", {}, "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA=="],
+
+ "recharts": ["recharts@3.8.0", "", { "dependencies": { "@reduxjs/toolkit": "2.13.0", "clsx": "2.1.1", "decimal.js-light": "2.5.1", "es-toolkit": "1.52.0", "eventemitter3": "5.0.4", "immer": "10.2.0", "react-redux": "9.3.0", "reselect": "5.1.1", "tiny-invariant": "1.3.3", "use-sync-external-store": "1.7.0", "victory-vendor": "37.3.6" }, "peerDependencies": { "react": "19.3.0", "react-dom": "19.3.0", "react-is": "19.3.0" } }, "sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ=="],
+
+ "redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="],
+
+ "redux-thunk": ["redux-thunk@3.1.0", "", { "peerDependencies": { "redux": "5.0.1" } }, "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw=="],
+
+ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
+
+ "reselect": ["reselect@5.1.1", "", {}, "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="],
+
+ "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
+
+ "rolldown": ["rolldown@1.2.12", "", { "dependencies": { "@oxc-project/types": "0.152.0", "@rolldown/pluginutils": "1.0.1" }, "optionalDependencies": { "@rolldown/binding-android-arm-eabi": "1.2.12", "@rolldown/binding-android-arm64": "1.2.12", "@rolldown/binding-darwin-arm64": "1.2.12", "@rolldown/binding-darwin-x64": "1.2.12", "@rolldown/binding-freebsd-x64": "1.2.12", "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", "@rolldown/binding-linux-arm64-gnu": "1.2.12", "@rolldown/binding-linux-arm64-musl": "1.2.12", "@rolldown/binding-linux-ppc64-gnu": "1.2.12", "@rolldown/binding-linux-s390x-gnu": "1.2.12", "@rolldown/binding-linux-x64-gnu": "1.2.12", "@rolldown/binding-linux-x64-musl": "1.2.12", "@rolldown/binding-openharmony-arm64": "1.2.12", "@rolldown/binding-win32-arm64-msvc": "1.2.12", "@rolldown/binding-win32-x64-msvc": "1.2.12" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ=="],
+
+ "rou3": ["rou3@0.9.2", "", {}, "sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ=="],
+
+ "scheduler": ["scheduler@0.28.0", "", {}, "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw=="],
+
+ "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
+
+ "seroval": ["seroval@1.6.8", "", {}, "sha512-HlSgSAkTk4EqHcje1ptJjfZi1YDv5KbhVJ/d3P7T/nAXua2VmDu+AKDX5VTdFfZf48nDkWB2TKYt0DrCSa+3wg=="],
+
+ "seroval-plugins": ["seroval-plugins@1.6.8", "", { "peerDependencies": { "seroval": "1.6.8" } }, "sha512-N7mWAMydj89EnYTHtRpS3LBrAz3J9O6oVrqpuXuvlAHfAUG8WEKqtbAd7SBiJNY5NfCAFhSdyAh7wI4Shjqy4g=="],
+
+ "set-cookie-parser": ["set-cookie-parser@3.1.2", "", {}, "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw=="],
+
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
+
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
+
+ "shell-quote": ["shell-quote@1.12.0", "", {}, "sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q=="],
+
+ "simple-icons": ["simple-icons@16.34.0", "", {}, "sha512-UTxKn0PVspk84B2hHF3Dqiqht1yDjJmDc/t4cO7PyCQxCMk6OjEu95pnpGjhLaGeQ4qBrGASbefTIe/+czrX7g=="],
+
+ "solid-js": ["solid-js@1.9.15", "", { "dependencies": { "csstype": "3.2.3", "seroval": "1.5.6", "seroval-plugins": "1.5.6" } }, "sha512-EeiY2xfpZJqPLjXspVEKjAII4yv8NyG//NxZ3IpOFHdUNnnTyL0uJOeS9LWGvA7cFCz5y94cjFwYlmw5Luncsg=="],
+
+ "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
+
+ "source-map-js": ["source-map-js@1.2.2", "", {}, "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw=="],
+
+ "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "1.1.2", "source-map": "0.6.1" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
+
+ "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
+
+ "srvx": ["srvx@0.11.22", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ=="],
+
+ "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "8.0.0", "is-fullwidth-code-point": "3.0.0", "strip-ansi": "6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
+ "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
+ "tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="],
+
+ "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
+
+ "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
+
+ "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "6.5.0", "picomatch": "4.0.7" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
+
+ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+
+ "tsx": ["tsx@4.23.15", "", { "dependencies": { "esbuild": "0.28.2" }, "optionalDependencies": { "fsevents": "2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw=="],
+
+ "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
+
+ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
+
+ "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="],
+
+ "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
+
+ "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="],
+
+ "unplugin": ["unplugin@3.4.0", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "picomatch": "4.0.7", "webpack-virtual-modules": "0.6.2" }, "optionalDependencies": { "esbuild": "0.28.2", "rolldown": "1.2.12", "vite": "8.3.2" } }, "sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w=="],
+
+ "unstorage": ["unstorage@2.0.0-alpha.7", "", { "optionalDependencies": { "chokidar": "5.0.0", "db0": "0.3.4", "ofetch": "2.0.0-alpha.3" } }, "sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog=="],
+
+ "update-browserslist-db": ["update-browserslist-db@1.3.3", "", { "dependencies": { "escalade": "3.2.0", "picocolors": "1.1.1" }, "peerDependencies": { "browserslist": "4.29.3" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ=="],
+
+ "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "2.8.1" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
+
+ "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "1.1.0", "tslib": "2.8.1" }, "optionalDependencies": { "@types/react": "19.3.0" }, "peerDependencies": { "react": "19.3.0" } }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
+
+ "use-sync-external-store": ["use-sync-external-store@1.7.0", "", { "peerDependencies": { "react": "19.3.0" } }, "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A=="],
+
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+
+ "victory-vendor": ["victory-vendor@37.3.6", "", { "dependencies": { "@types/d3-array": "3.2.2", "@types/d3-ease": "3.0.2", "@types/d3-interpolate": "3.0.4", "@types/d3-scale": "4.0.9", "@types/d3-shape": "3.2.0", "@types/d3-time": "3.0.4", "@types/d3-timer": "3.0.2", "d3-array": "3.2.4", "d3-ease": "3.0.1", "d3-interpolate": "3.0.1", "d3-scale": "4.0.2", "d3-shape": "3.2.0", "d3-time": "3.1.0", "d3-timer": "3.0.1" } }, "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ=="],
+
+ "vite": ["vite@8.3.2", "", { "dependencies": { "lightningcss": "1.33.0", "picomatch": "4.0.7", "postcss": "8.5.28", "rolldown": "1.2.12", "tinyglobby": "0.2.17" }, "optionalDependencies": { "@types/node": "22.20.5", "esbuild": "0.28.2", "fsevents": "2.3.3", "jiti": "2.7.0", "tsx": "4.23.15" }, "bin": { "vite": "bin/vite.js" } }, "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w=="],
+
+ "vitefu": ["vitefu@1.1.3", "", { "optionalDependencies": { "vite": "8.3.2" } }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="],
+
+ "web-vitals": ["web-vitals@6.2.3", "", {}, "sha512-Dmy+vdO1UPMqXiAtZSNayhl4f794Bxfd94W4HIj2HlYtczEQfEOon969memlcpcHrTuOKLa5baFjX7WbgmOq+A=="],
+
+ "web-vitals-soft-navs": ["web-vitals@6.2.1", "", {}, "sha512-rLcLXA2sx6+9dE88NHFubwTtGxpK4yYBLj6qHPdFoCaLr0cXGb4efOqtKLlm4loGA4OEKHIQKMKzZkKyOh5ctw=="],
+
+ "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
+
+ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
+
+ "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "4.3.0", "string-width": "4.2.3", "strip-ansi": "6.0.1" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
+
+ "ws": ["ws@8.22.0", "", {}, "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg=="],
+
+ "xmlbuilder2": ["xmlbuilder2@4.0.3", "", { "dependencies": { "@oozcitak/dom": "2.0.2", "@oozcitak/infra": "2.0.2", "@oozcitak/util": "10.0.0", "js-yaml": "4.3.2" } }, "sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA=="],
+
+ "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
+
+ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
+
+ "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
+
+ "yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "8.0.1", "escalade": "3.2.0", "get-caller-file": "2.0.5", "require-directory": "2.1.1", "string-width": "4.2.3", "y18n": "5.0.8", "yargs-parser": "21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="],
+
+ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
+
+ "zod": ["zod@4.6.5", "", {}, "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q=="],
+
+ "@base-ui/utils/reselect": ["reselect@5.3.0", "", {}, "sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg=="],
+
+ "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="],
+
+ "@reduxjs/toolkit/immer": ["immer@11.1.21", "", {}, "sha512-bZSadeCPGdaY5/qRLgr6mDSH1ra21rD3rqpiWk7+QTr4ayYPTE9qZYdLh/NdPhMe0wSrTvHD/Lk8q5EwhUs0aw=="],
+
+ "@reduxjs/toolkit/reselect": ["reselect@5.3.0", "", {}, "sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg=="],
+
+ "@tailwindcss/node/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
+
+ "better-call/@better-auth/utils": ["@better-auth/utils@0.5.0", "", { "dependencies": { "@noble/hashes": "2.4.0" } }, "sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA=="],
+
+ "h3/rou3": ["rou3@0.8.1", "", {}, "sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA=="],
+
+ "h3-v2/rou3": ["rou3@0.8.1", "", {}, "sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA=="],
+
+ "oxc-parser/@oxc-project/types": ["@oxc-project/types@0.120.0", "", {}, "sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg=="],
+
+ "solid-js/seroval": ["seroval@1.5.6", "", {}, "sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA=="],
+
+ "solid-js/seroval-plugins": ["seroval-plugins@1.5.6", "", { "peerDependencies": { "seroval": "1.5.6" } }, "sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ=="],
+
+ "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
+
+ "tsx/esbuild": ["esbuild@0.28.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.2", "@esbuild/android-arm": "0.28.2", "@esbuild/android-arm64": "0.28.2", "@esbuild/android-x64": "0.28.2", "@esbuild/darwin-arm64": "0.28.2", "@esbuild/darwin-x64": "0.28.2", "@esbuild/freebsd-arm64": "0.28.2", "@esbuild/freebsd-x64": "0.28.2", "@esbuild/linux-arm": "0.28.2", "@esbuild/linux-arm64": "0.28.2", "@esbuild/linux-ia32": "0.28.2", "@esbuild/linux-loong64": "0.28.2", "@esbuild/linux-mips64el": "0.28.2", "@esbuild/linux-ppc64": "0.28.2", "@esbuild/linux-riscv64": "0.28.2", "@esbuild/linux-s390x": "0.28.2", "@esbuild/linux-x64": "0.28.2", "@esbuild/netbsd-arm64": "0.28.2", "@esbuild/netbsd-x64": "0.28.2", "@esbuild/openbsd-arm64": "0.28.2", "@esbuild/openbsd-x64": "0.28.2", "@esbuild/openharmony-arm64": "0.28.2", "@esbuild/sunos-x64": "0.28.2", "@esbuild/win32-arm64": "0.28.2", "@esbuild/win32-ia32": "0.28.2", "@esbuild/win32-x64": "0.28.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA=="],
+
+ "unplugin/esbuild": ["esbuild@0.28.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.2", "@esbuild/android-arm": "0.28.2", "@esbuild/android-arm64": "0.28.2", "@esbuild/android-x64": "0.28.2", "@esbuild/darwin-arm64": "0.28.2", "@esbuild/darwin-x64": "0.28.2", "@esbuild/freebsd-arm64": "0.28.2", "@esbuild/freebsd-x64": "0.28.2", "@esbuild/linux-arm": "0.28.2", "@esbuild/linux-arm64": "0.28.2", "@esbuild/linux-ia32": "0.28.2", "@esbuild/linux-loong64": "0.28.2", "@esbuild/linux-mips64el": "0.28.2", "@esbuild/linux-ppc64": "0.28.2", "@esbuild/linux-riscv64": "0.28.2", "@esbuild/linux-s390x": "0.28.2", "@esbuild/linux-x64": "0.28.2", "@esbuild/netbsd-arm64": "0.28.2", "@esbuild/netbsd-x64": "0.28.2", "@esbuild/openbsd-arm64": "0.28.2", "@esbuild/openbsd-x64": "0.28.2", "@esbuild/openharmony-arm64": "0.28.2", "@esbuild/sunos-x64": "0.28.2", "@esbuild/win32-arm64": "0.28.2", "@esbuild/win32-ia32": "0.28.2", "@esbuild/win32-x64": "0.28.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA=="],
+
+ "vite/esbuild": ["esbuild@0.28.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.2", "@esbuild/android-arm": "0.28.2", "@esbuild/android-arm64": "0.28.2", "@esbuild/android-x64": "0.28.2", "@esbuild/darwin-arm64": "0.28.2", "@esbuild/darwin-x64": "0.28.2", "@esbuild/freebsd-arm64": "0.28.2", "@esbuild/freebsd-x64": "0.28.2", "@esbuild/linux-arm": "0.28.2", "@esbuild/linux-arm64": "0.28.2", "@esbuild/linux-ia32": "0.28.2", "@esbuild/linux-loong64": "0.28.2", "@esbuild/linux-mips64el": "0.28.2", "@esbuild/linux-ppc64": "0.28.2", "@esbuild/linux-riscv64": "0.28.2", "@esbuild/linux-s390x": "0.28.2", "@esbuild/linux-x64": "0.28.2", "@esbuild/netbsd-arm64": "0.28.2", "@esbuild/netbsd-x64": "0.28.2", "@esbuild/openbsd-arm64": "0.28.2", "@esbuild/openbsd-x64": "0.28.2", "@esbuild/openharmony-arm64": "0.28.2", "@esbuild/sunos-x64": "0.28.2", "@esbuild/win32-arm64": "0.28.2", "@esbuild/win32-ia32": "0.28.2", "@esbuild/win32-x64": "0.28.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.18.20", "", { "os": "android", "cpu": "arm64" }, "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.18.20", "", { "os": "android", "cpu": "x64" }, "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.18.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.18.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.18.20", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.18.20", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.18.20", "", { "os": "linux", "cpu": "arm" }, "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.18.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.18.20", "", { "os": "linux", "cpu": "ia32" }, "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.18.20", "", { "os": "linux", "cpu": "ppc64" }, "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.18.20", "", { "os": "linux", "cpu": "s390x" }, "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.18.20", "", { "os": "linux", "cpu": "x64" }, "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.18.20", "", { "os": "none", "cpu": "x64" }, "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.18.20", "", { "os": "openbsd", "cpu": "x64" }, "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.18.20", "", { "os": "sunos", "cpu": "x64" }, "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.18.20", "", { "os": "win32", "cpu": "arm64" }, "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.18.20", "", { "os": "win32", "cpu": "ia32" }, "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g=="],
+
+ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
+
+ "@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
+
+ "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="],
+
+ "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.28.2", "", { "os": "android", "cpu": "arm" }, "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg=="],
+
+ "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A=="],
+
+ "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.28.2", "", { "os": "android", "cpu": "x64" }, "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q=="],
+
+ "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw=="],
+
+ "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw=="],
+
+ "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw=="],
+
+ "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg=="],
+
+ "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.2", "", { "os": "linux", "cpu": "arm" }, "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w=="],
+
+ "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug=="],
+
+ "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ=="],
+
+ "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ=="],
+
+ "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA=="],
+
+ "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ=="],
+
+ "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA=="],
+
+ "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg=="],
+
+ "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.2", "", { "os": "linux", "cpu": "x64" }, "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ=="],
+
+ "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw=="],
+
+ "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.2", "", { "os": "none", "cpu": "x64" }, "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw=="],
+
+ "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ=="],
+
+ "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw=="],
+
+ "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q=="],
+
+ "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g=="],
+
+ "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ=="],
+
+ "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA=="],
+
+ "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="],
+
+ "unplugin/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="],
+
+ "unplugin/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.28.2", "", { "os": "android", "cpu": "arm" }, "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg=="],
+
+ "unplugin/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A=="],
+
+ "unplugin/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.28.2", "", { "os": "android", "cpu": "x64" }, "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q=="],
+
+ "unplugin/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw=="],
+
+ "unplugin/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw=="],
+
+ "unplugin/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw=="],
+
+ "unplugin/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg=="],
+
+ "unplugin/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.2", "", { "os": "linux", "cpu": "arm" }, "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w=="],
+
+ "unplugin/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug=="],
+
+ "unplugin/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ=="],
+
+ "unplugin/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ=="],
+
+ "unplugin/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA=="],
+
+ "unplugin/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ=="],
+
+ "unplugin/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA=="],
+
+ "unplugin/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg=="],
+
+ "unplugin/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.2", "", { "os": "linux", "cpu": "x64" }, "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ=="],
+
+ "unplugin/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw=="],
+
+ "unplugin/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.2", "", { "os": "none", "cpu": "x64" }, "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw=="],
+
+ "unplugin/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ=="],
+
+ "unplugin/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw=="],
+
+ "unplugin/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q=="],
+
+ "unplugin/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g=="],
+
+ "unplugin/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ=="],
+
+ "unplugin/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA=="],
+
+ "unplugin/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="],
+
+ "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="],
+
+ "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.28.2", "", { "os": "android", "cpu": "arm" }, "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg=="],
+
+ "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A=="],
+
+ "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.28.2", "", { "os": "android", "cpu": "x64" }, "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q=="],
+
+ "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw=="],
+
+ "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw=="],
+
+ "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw=="],
+
+ "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg=="],
+
+ "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.2", "", { "os": "linux", "cpu": "arm" }, "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w=="],
+
+ "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug=="],
+
+ "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ=="],
+
+ "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ=="],
+
+ "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA=="],
+
+ "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ=="],
+
+ "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA=="],
+
+ "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg=="],
+
+ "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.2", "", { "os": "linux", "cpu": "x64" }, "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ=="],
+
+ "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw=="],
+
+ "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.2", "", { "os": "none", "cpu": "x64" }, "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw=="],
+
+ "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ=="],
+
+ "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw=="],
+
+ "vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q=="],
+
+ "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g=="],
+
+ "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ=="],
+
+ "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA=="],
+
+ "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="],
+ }
+}
diff --git a/package.json b/package.json
index d5d2953..bb77d40 100644
--- a/package.json
+++ b/package.json
@@ -5,18 +5,22 @@
"imports": {
"#/*": "./src/*"
},
+ "workspaces": [
+ "packages/*"
+ ],
"scripts": {
- "dev": "vite dev --port 3000",
+ "dev": "bun --bun vite dev --port 3000",
"generate-routes": "tsr generate",
- "build": "vite build",
- "preview": "vite preview",
+ "build": "bun --bun vite build",
+ "preview": "bun --bun vite preview",
"format": "biome format",
"lint": "biome lint",
"check": "biome check",
- "start": "node .output/server/index.mjs",
- "db:seed": "tsx --env-file=.env scripts/seed.ts",
- "benchmarks": "tsx --env-file=.env scripts/benchmarks.ts",
- "db:generate": "drizzle-kit generate"
+ "start": "bun .output/server/index.mjs",
+ "db:seed": "bun scripts/seed.ts",
+ "benchmarks": "bun scripts/benchmarks.ts",
+ "db:generate": "bun --bun drizzle-kit generate",
+ "postinstall": "ln -sf ../@tanstack/intent/dist/cli.mjs node_modules/.bin/intent"
},
"dependencies": {
"@base-ui/react": "^1.8.0",
@@ -69,11 +73,10 @@
"@types/react-dom": "^19.2.0",
"@vitejs/plugin-react": "^6.0.1",
"drizzle-kit": "^0.31.11",
- "tsx": "^4.23.15",
"typescript": "^6.0.2",
"vite": "^8.0.0"
},
- "packageManager": "pnpm@11.1.3",
+ "packageManager": "bun@1.3.14",
"version": "0.1.0",
"intent": {
"skills": [
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 8b9ba59..a444af4 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -19,7 +19,7 @@
},
"scripts": {
"build": "tsc -p .",
- "test": "node --test",
+ "test": "bun test",
"prepack": "tsc -p ."
},
"dependencies": {
diff --git a/packages/cli/test/env.test.mjs b/packages/cli/test/env.test.mjs
index 7a564ba..ddfd7de 100644
--- a/packages/cli/test/env.test.mjs
+++ b/packages/cli/test/env.test.mjs
@@ -1,4 +1,4 @@
-// Run with `pnpm build && pnpm test` in packages/cli.
+// Run with `bun run build && bun run test` in packages/cli.
import assert from "node:assert/strict";
import { test } from "node:test";
import { parseEnv } from "../dist/lib.js";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
deleted file mode 100644
index d89501b..0000000
--- a/pnpm-lock.yaml
+++ /dev/null
@@ -1,5691 +0,0 @@
-lockfileVersion: '9.0'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-importers:
-
- .:
- dependencies:
- '@base-ui/react':
- specifier: ^1.8.0
- version: 1.8.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@better-auth/drizzle-adapter':
- specifier: ^1.7.7
- version: 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))
- '@electric-sql/pglite':
- specifier: ^0.5.8
- version: 0.5.8
- '@fontsource-variable/geist':
- specifier: ^5.3.0
- version: 5.3.0
- '@modelcontextprotocol/server':
- specifier: ^2.3.1
- version: 2.3.1
- '@opentelemetry/api':
- specifier: ^1.9.1
- version: 1.9.1
- '@opentelemetry/api-logs':
- specifier: ^0.222.0
- version: 0.222.0
- '@opentelemetry/exporter-logs-otlp-http':
- specifier: ^0.222.0
- version: 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/exporter-trace-otlp-http':
- specifier: ^0.222.0
- version: 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/resources':
- specifier: ^2.11.0
- version: 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-logs':
- specifier: ^0.222.0
- version: 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-trace-base':
- specifier: ^2.11.0
- version: 2.11.0(@opentelemetry/api@1.9.1)
- '@resvg/resvg-wasm':
- specifier: 2.6.2
- version: 2.6.2
- '@tailwindcss/vite':
- specifier: ^4.1.18
- version: 4.3.3(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- '@tanstack/react-devtools':
- specifier: 0.10.13
- version: 0.10.13(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(csstype@3.2.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(solid-js@1.9.15)
- '@tanstack/react-router':
- specifier: 1.170.41
- version: 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/react-router-devtools':
- specifier: 1.167.2
- version: 1.167.2(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(@tanstack/router-core@1.171.34)(csstype@3.2.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/react-start':
- specifier: 1.168.60
- version: 1.168.60(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- better-auth:
- specifier: ^1.7.7
- version: 1.7.7(@opentelemetry/api@1.9.1)(@tanstack/react-start@1.168.60(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)))(drizzle-kit@0.31.11)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))(pg@8.23.1)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(solid-js@1.9.15)
- class-variance-authority:
- specifier: ^0.7.1
- version: 0.7.1
- cmdk:
- specifier: ^1.1.1
- version: 1.1.1(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- cn:
- specifier: ^0.4.0
- version: 0.4.0
- croner:
- specifier: ^10.0.1
- version: 10.0.1
- drizzle-orm:
- specifier: ^0.45.3
- version: 0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)
- lucide-react:
- specifier: ^0.577.0
- version: 0.577.0(react@19.3.0)
- marked:
- specifier: ^18.0.14
- version: 18.0.14
- nitro:
- specifier: 3.0.260610-beta
- version: 3.0.260610-beta(@electric-sql/pglite@0.5.8)(chokidar@5.0.0)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))(jiti@2.7.0)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- pg:
- specifier: ^8.23.1
- version: 8.23.1
- posthog-js:
- specifier: ^1.436.1
- version: 1.436.1(@types/react@19.3.0)(react@19.3.0)
- posthog-node:
- specifier: ^5.55.0
- version: 5.55.0
- react:
- specifier: ^19.2.0
- version: 19.3.0
- react-dom:
- specifier: ^19.2.0
- version: 19.3.0(react@19.3.0)
- recharts:
- specifier: 3.8.0
- version: 3.8.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react-is@19.3.0)(react@19.3.0)(redux@5.0.1)
- simple-icons:
- specifier: ^16.34.0
- version: 16.34.0
- tailwindcss:
- specifier: ^4.1.18
- version: 4.3.3
- tw-animate-css:
- specifier: ^1.3.6
- version: 1.4.0
- zod:
- specifier: ^4.6.5
- version: 4.6.5
- devDependencies:
- '@biomejs/biome':
- specifier: 2.4.5
- version: 2.4.5
- '@tailwindcss/typography':
- specifier: ^0.5.16
- version: 0.5.20(tailwindcss@4.3.3)
- '@tanstack/devtools-vite':
- specifier: 0.8.5
- version: 0.8.5(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- '@tanstack/intent':
- specifier: ^0.5.4
- version: 0.5.4
- '@tanstack/router-cli':
- specifier: ^1.132.0
- version: 1.167.40
- '@types/node':
- specifier: ^22.10.2
- version: 22.20.5
- '@types/pg':
- specifier: ^8.23.1
- version: 8.23.1
- '@types/react':
- specifier: ^19.2.0
- version: 19.3.0
- '@types/react-dom':
- specifier: ^19.2.0
- version: 19.3.0(@types/react@19.3.0)
- '@vitejs/plugin-react':
- specifier: ^6.0.1
- version: 6.1.1(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- drizzle-kit:
- specifier: ^0.31.11
- version: 0.31.11
- tsx:
- specifier: ^4.23.15
- version: 4.23.15
- typescript:
- specifier: ^6.0.2
- version: 6.0.3
- vite:
- specifier: ^8.0.0
- version: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
-
- packages/cli:
- dependencies:
- '@modelcontextprotocol/client':
- specifier: ^2.3.1
- version: 2.3.1
- '@modelcontextprotocol/server':
- specifier: ^2.3.1
- version: 2.3.1
- zod:
- specifier: ^4.6.5
- version: 4.6.5
- devDependencies:
- '@types/node':
- specifier: ^22.20.5
- version: 22.20.5
- typescript:
- specifier: ^6.0.3
- version: 6.0.3
-
-packages:
-
- '@babel/code-frame@7.29.7':
- resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
- engines: {node: '>=6.9.0'}
-
- '@babel/compat-data@7.29.7':
- resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
- engines: {node: '>=6.9.0'}
-
- '@babel/core@7.29.7':
- resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
- engines: {node: '>=6.9.0'}
-
- '@babel/generator@7.29.8':
- resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-compilation-targets@7.29.7':
- resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-globals@7.29.7':
- resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-module-imports@7.29.7':
- resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-module-transforms@7.29.7':
- resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
-
- '@babel/helper-string-parser@7.29.7':
- resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-validator-identifier@7.29.7':
- resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-validator-option@7.29.7':
- resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helpers@7.29.7':
- resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==}
- engines: {node: '>=6.9.0'}
-
- '@babel/parser@7.29.9':
- resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==}
- engines: {node: '>=6.0.0'}
- hasBin: true
-
- '@babel/runtime@7.29.7':
- resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
- engines: {node: '>=6.9.0'}
-
- '@babel/template@7.29.7':
- resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
- engines: {node: '>=6.9.0'}
-
- '@babel/traverse@7.29.8':
- resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==}
- engines: {node: '>=6.9.0'}
-
- '@babel/types@7.29.8':
- resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
- engines: {node: '>=6.9.0'}
-
- '@base-ui/react@1.8.0':
- resolution: {integrity: sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==}
- engines: {node: '>=14.0.0'}
- peerDependencies:
- '@date-fns/tz': ^1.2.0
- '@types/react': ^17 || ^18 || ^19
- date-fns: ^4.0.0
- react: ^17 || ^18 || ^19
- react-dom: ^17 || ^18 || ^19
- peerDependenciesMeta:
- '@date-fns/tz':
- optional: true
- '@types/react':
- optional: true
- date-fns:
- optional: true
-
- '@base-ui/utils@0.4.0':
- resolution: {integrity: sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==}
- peerDependencies:
- '@types/react': ^17 || ^18 || ^19
- react: ^17 || ^18 || ^19
- react-dom: ^17 || ^18 || ^19
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@better-auth/core@1.7.7':
- resolution: {integrity: sha512-srgFzHEjB2WWlokFz1i4BfG41sNhsA105Pukgqu6RrEh5A+LSkzf1mCHydVipkjt9l5qswtBMi7IL6ouHbZL4Q==}
- peerDependencies:
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- '@opentelemetry/api': ^1.9.0
- better-call: 1.4.0
- jose: ^6.1.0
- kysely: ^0.28.5 || ^0.29.0
- nanostores: ^1.0.1
- peerDependenciesMeta:
- '@opentelemetry/api':
- optional: true
-
- '@better-auth/drizzle-adapter@1.7.7':
- resolution: {integrity: sha512-qon0U94PR5FQysuyGoAlGVQpIIiNg5dtDpwjE63sN/HjoRWZadZzHPcS9mn7JsJyQZK6iTNhd7LD0AaXt2f78w==}
- peerDependencies:
- '@better-auth/core': ^1.7.7
- '@better-auth/utils': 0.4.2
- drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
- peerDependenciesMeta:
- drizzle-orm:
- optional: true
-
- '@better-auth/kysely-adapter@1.7.7':
- resolution: {integrity: sha512-9FONOCgOcrQI9wJ5v1oDGIg9sT7pa9RjZZQ4fsCTudo8R87SrIGNUvUxDFTJhZvUblvFfGaIBR9Vb8LA+8bqLQ==}
- peerDependencies:
- '@better-auth/core': ^1.7.7
- '@better-auth/utils': 0.4.2
- kysely: ^0.28.17 || ^0.29.0
- peerDependenciesMeta:
- kysely:
- optional: true
-
- '@better-auth/memory-adapter@1.7.7':
- resolution: {integrity: sha512-FqKFEe+b5tXXV0gRbyirca+qXgMpLOeJ8Wk19yykb/scQKy0WJ4k22WzEV3TTPctQV9DZhwCXPlDtQhnlOv5Gg==}
- peerDependencies:
- '@better-auth/core': ^1.7.7
- '@better-auth/utils': 0.4.2
-
- '@better-auth/mongo-adapter@1.7.7':
- resolution: {integrity: sha512-ZnVDuRrXqbf0oHphrEN27oTImNH5NTO26dtWatq5cXyYAsH7goof9QIoTOmxTbBxUQahKBw9T6+9h6n+RtOE+g==}
- peerDependencies:
- '@better-auth/core': ^1.7.7
- '@better-auth/utils': 0.4.2
- mongodb: ^6.0.0 || ^7.0.0
- peerDependenciesMeta:
- mongodb:
- optional: true
-
- '@better-auth/prisma-adapter@1.7.7':
- resolution: {integrity: sha512-4YcnrcVdvWiAZw0sZl63tWUClPXg5r3QsLn7C2sG7kKEBY06zOng0ibecyxRBixKq1zE1ceHuEUqez5Rhi+nQA==}
- peerDependencies:
- '@better-auth/core': ^1.7.7
- '@better-auth/utils': 0.4.2
- '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
- prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
- peerDependenciesMeta:
- '@prisma/client':
- optional: true
- prisma:
- optional: true
-
- '@better-auth/telemetry@1.7.7':
- resolution: {integrity: sha512-PaRA6i+kAioVYmza2gHPcdrxP0hAotph4KV9hft2GeNJq+AZXDiBu3FuLM9HxvcmiZeUT74Vufqd9ypmB8veTA==}
- peerDependencies:
- '@better-auth/core': ^1.7.7
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
-
- '@better-auth/utils@0.4.2':
- resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==}
-
- '@better-auth/utils@0.5.0':
- resolution: {integrity: sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA==}
-
- '@better-fetch/fetch@1.3.2':
- resolution: {integrity: sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow==}
-
- '@biomejs/biome@2.4.5':
- resolution: {integrity: sha512-OWNCyMS0Q011R6YifXNOg6qsOg64IVc7XX6SqGsrGszPbkVCoaO7Sr/lISFnXZ9hjQhDewwZ40789QmrG0GYgQ==}
- engines: {node: '>=14.21.3'}
- hasBin: true
-
- '@biomejs/cli-darwin-arm64@2.4.5':
- resolution: {integrity: sha512-lGS4Nd5O3KQJ6TeWv10mElnx1phERhBxqGP/IKq0SvZl78kcWDFMaTtVK+w3v3lusRFxJY78n07PbKplirsU5g==}
- engines: {node: '>=14.21.3'}
- cpu: [arm64]
- os: [darwin]
-
- '@biomejs/cli-darwin-x64@2.4.5':
- resolution: {integrity: sha512-6MoH4tyISIBNkZ2Q5T1R7dLd5BsITb2yhhhrU9jHZxnNSNMWl+s2Mxu7NBF8Y3a7JJcqq9nsk8i637z4gqkJxQ==}
- engines: {node: '>=14.21.3'}
- cpu: [x64]
- os: [darwin]
-
- '@biomejs/cli-linux-arm64-musl@2.4.5':
- resolution: {integrity: sha512-iqLDgpzobG7gpBF0fwEVS/LT8kmN7+S0E2YKFDtqliJfzNLnAiV2Nnyb+ehCDCJgAZBASkYHR2o60VQWikpqIg==}
- engines: {node: '>=14.21.3'}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@biomejs/cli-linux-arm64@2.4.5':
- resolution: {integrity: sha512-U1GAG6FTjhAO04MyH4xn23wRNBkT6H7NentHh+8UxD6ShXKBm5SY4RedKJzkUThANxb9rUKIPc7B8ew9Xo/cWg==}
- engines: {node: '>=14.21.3'}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@biomejs/cli-linux-x64-musl@2.4.5':
- resolution: {integrity: sha512-NlKa7GpbQmNhZf9kakQeddqZyT7itN7jjWdakELeXyTU3pg/83fTysRRDPJD0akTfKDl6vZYNT9Zqn4MYZVBOA==}
- engines: {node: '>=14.21.3'}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@biomejs/cli-linux-x64@2.4.5':
- resolution: {integrity: sha512-NdODlSugMzTlENPTa4z0xB82dTUlCpsrOxc43///aNkTLblIYH4XpYflBbf5ySlQuP8AA4AZd1qXhV07IdrHdQ==}
- engines: {node: '>=14.21.3'}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@biomejs/cli-win32-arm64@2.4.5':
- resolution: {integrity: sha512-EBfrTqRIWOFSd7CQb/0ttjHMR88zm3hGravnDwUA9wHAaCAYsULKDebWcN5RmrEo1KBtl/gDVJMrFjNR0pdGUw==}
- engines: {node: '>=14.21.3'}
- cpu: [arm64]
- os: [win32]
-
- '@biomejs/cli-win32-x64@2.4.5':
- resolution: {integrity: sha512-Pmhv9zT95YzECfjEHNl3mN9Vhusw9VA5KHY0ZvlGsxsjwS5cb7vpRnHzJIv0vG7jB0JI7xEaMH9ddfZm/RozBw==}
- engines: {node: '>=14.21.3'}
- cpu: [x64]
- os: [win32]
-
- '@drizzle-team/brocli@0.10.2':
- resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
-
- '@electric-sql/pglite@0.5.8':
- resolution: {integrity: sha512-n9tsbUOhwx2epK1V0ZG9Ar4SHWUju04dhmzZXiSBXwBoleOvIfals33NAaWgagQVAL4Rbvx/Ptsu3P+pA09f6Q==}
-
- '@emnapi/core@1.11.3':
- resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==}
-
- '@emnapi/runtime@1.11.3':
- resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
-
- '@emnapi/wasi-threads@1.2.3':
- resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==}
-
- '@esbuild-kit/core-utils@3.3.2':
- resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==}
- deprecated: 'Merged into tsx: https://tsx.hirok.io'
-
- '@esbuild-kit/esm-loader@2.6.5':
- resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==}
- deprecated: 'Merged into tsx: https://tsx.hirok.io'
-
- '@esbuild/aix-ppc64@0.25.12':
- resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [aix]
-
- '@esbuild/aix-ppc64@0.28.2':
- resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [aix]
-
- '@esbuild/android-arm64@0.18.20':
- resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [android]
-
- '@esbuild/android-arm64@0.25.12':
- resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [android]
-
- '@esbuild/android-arm64@0.28.2':
- resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [android]
-
- '@esbuild/android-arm@0.18.20':
- resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [android]
-
- '@esbuild/android-arm@0.25.12':
- resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [android]
-
- '@esbuild/android-arm@0.28.2':
- resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [android]
-
- '@esbuild/android-x64@0.18.20':
- resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [android]
-
- '@esbuild/android-x64@0.25.12':
- resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [android]
-
- '@esbuild/android-x64@0.28.2':
- resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [android]
-
- '@esbuild/darwin-arm64@0.18.20':
- resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [darwin]
-
- '@esbuild/darwin-arm64@0.25.12':
- resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [darwin]
-
- '@esbuild/darwin-arm64@0.28.2':
- resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [darwin]
-
- '@esbuild/darwin-x64@0.18.20':
- resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [darwin]
-
- '@esbuild/darwin-x64@0.25.12':
- resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [darwin]
-
- '@esbuild/darwin-x64@0.28.2':
- resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [darwin]
-
- '@esbuild/freebsd-arm64@0.18.20':
- resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [freebsd]
-
- '@esbuild/freebsd-arm64@0.25.12':
- resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [freebsd]
-
- '@esbuild/freebsd-arm64@0.28.2':
- resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [freebsd]
-
- '@esbuild/freebsd-x64@0.18.20':
- resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [freebsd]
-
- '@esbuild/freebsd-x64@0.25.12':
- resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [freebsd]
-
- '@esbuild/freebsd-x64@0.28.2':
- resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [freebsd]
-
- '@esbuild/linux-arm64@0.18.20':
- resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [linux]
-
- '@esbuild/linux-arm64@0.25.12':
- resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [linux]
-
- '@esbuild/linux-arm64@0.28.2':
- resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [linux]
-
- '@esbuild/linux-arm@0.18.20':
- resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [linux]
-
- '@esbuild/linux-arm@0.25.12':
- resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [linux]
-
- '@esbuild/linux-arm@0.28.2':
- resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [linux]
-
- '@esbuild/linux-ia32@0.18.20':
- resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
-
- '@esbuild/linux-ia32@0.25.12':
- resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [linux]
-
- '@esbuild/linux-ia32@0.28.2':
- resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [linux]
-
- '@esbuild/linux-loong64@0.18.20':
- resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
- engines: {node: '>=12'}
- cpu: [loong64]
- os: [linux]
-
- '@esbuild/linux-loong64@0.25.12':
- resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
- engines: {node: '>=18'}
- cpu: [loong64]
- os: [linux]
-
- '@esbuild/linux-loong64@0.28.2':
- resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==}
- engines: {node: '>=18'}
- cpu: [loong64]
- os: [linux]
-
- '@esbuild/linux-mips64el@0.18.20':
- resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
- engines: {node: '>=12'}
- cpu: [mips64el]
- os: [linux]
-
- '@esbuild/linux-mips64el@0.25.12':
- resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
- engines: {node: '>=18'}
- cpu: [mips64el]
- os: [linux]
-
- '@esbuild/linux-mips64el@0.28.2':
- resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==}
- engines: {node: '>=18'}
- cpu: [mips64el]
- os: [linux]
-
- '@esbuild/linux-ppc64@0.18.20':
- resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [linux]
-
- '@esbuild/linux-ppc64@0.25.12':
- resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [linux]
-
- '@esbuild/linux-ppc64@0.28.2':
- resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [linux]
-
- '@esbuild/linux-riscv64@0.18.20':
- resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
- engines: {node: '>=12'}
- cpu: [riscv64]
- os: [linux]
-
- '@esbuild/linux-riscv64@0.25.12':
- resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
- engines: {node: '>=18'}
- cpu: [riscv64]
- os: [linux]
-
- '@esbuild/linux-riscv64@0.28.2':
- resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==}
- engines: {node: '>=18'}
- cpu: [riscv64]
- os: [linux]
-
- '@esbuild/linux-s390x@0.18.20':
- resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
- engines: {node: '>=12'}
- cpu: [s390x]
- os: [linux]
-
- '@esbuild/linux-s390x@0.25.12':
- resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
- engines: {node: '>=18'}
- cpu: [s390x]
- os: [linux]
-
- '@esbuild/linux-s390x@0.28.2':
- resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==}
- engines: {node: '>=18'}
- cpu: [s390x]
- os: [linux]
-
- '@esbuild/linux-x64@0.18.20':
- resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [linux]
-
- '@esbuild/linux-x64@0.25.12':
- resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [linux]
-
- '@esbuild/linux-x64@0.28.2':
- resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [linux]
-
- '@esbuild/netbsd-arm64@0.25.12':
- resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [netbsd]
-
- '@esbuild/netbsd-arm64@0.28.2':
- resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [netbsd]
-
- '@esbuild/netbsd-x64@0.18.20':
- resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [netbsd]
-
- '@esbuild/netbsd-x64@0.25.12':
- resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [netbsd]
-
- '@esbuild/netbsd-x64@0.28.2':
- resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [netbsd]
-
- '@esbuild/openbsd-arm64@0.25.12':
- resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openbsd]
-
- '@esbuild/openbsd-arm64@0.28.2':
- resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openbsd]
-
- '@esbuild/openbsd-x64@0.18.20':
- resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [openbsd]
-
- '@esbuild/openbsd-x64@0.25.12':
- resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [openbsd]
-
- '@esbuild/openbsd-x64@0.28.2':
- resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [openbsd]
-
- '@esbuild/openharmony-arm64@0.25.12':
- resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openharmony]
-
- '@esbuild/openharmony-arm64@0.28.2':
- resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openharmony]
-
- '@esbuild/sunos-x64@0.18.20':
- resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [sunos]
-
- '@esbuild/sunos-x64@0.25.12':
- resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [sunos]
-
- '@esbuild/sunos-x64@0.28.2':
- resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [sunos]
-
- '@esbuild/win32-arm64@0.18.20':
- resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [win32]
-
- '@esbuild/win32-arm64@0.25.12':
- resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [win32]
-
- '@esbuild/win32-arm64@0.28.2':
- resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [win32]
-
- '@esbuild/win32-ia32@0.18.20':
- resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [win32]
-
- '@esbuild/win32-ia32@0.25.12':
- resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [win32]
-
- '@esbuild/win32-ia32@0.28.2':
- resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [win32]
-
- '@esbuild/win32-x64@0.18.20':
- resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [win32]
-
- '@esbuild/win32-x64@0.25.12':
- resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [win32]
-
- '@esbuild/win32-x64@0.28.2':
- resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [win32]
-
- '@floating-ui/core@1.8.0':
- resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==}
-
- '@floating-ui/dom@1.8.0':
- resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==}
-
- '@floating-ui/react-dom@2.1.9':
- resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==}
- peerDependencies:
- react: '>=16.8.0'
- react-dom: '>=16.8.0'
-
- '@floating-ui/utils@0.2.12':
- resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
-
- '@fontsource-variable/geist@5.3.0':
- resolution: {integrity: sha512-j0m+vLQuG5XAYoHtGCVu0spvlGreR3EzpECUVzkFmI1mTVnAO38l/NEPDCFgZ177JxzYJCLSmTQibIiYPilGrA==}
-
- '@jridgewell/gen-mapping@0.3.13':
- resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
-
- '@jridgewell/remapping@2.3.5':
- resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
-
- '@jridgewell/resolve-uri@3.1.2':
- resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
- engines: {node: '>=6.0.0'}
-
- '@jridgewell/sourcemap-codec@1.6.0':
- resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==}
-
- '@jridgewell/trace-mapping@0.3.31':
- resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
-
- '@modelcontextprotocol/client@2.3.1':
- resolution: {integrity: sha512-mIGZXpHsjnZ6lD+gD/WCMpR5k8yVQQ8nNFH1N0Srf7AvnwTUMYD6pvTY8ng2+He5FfV7YMZLmrjL7cLa/cc3dQ==}
- engines: {node: '>=20'}
-
- '@modelcontextprotocol/core@2.3.1':
- resolution: {integrity: sha512-laVmIhPGpWi7rG9q+0UigblRN0Hws/Yjlb6qLFtVqryXVLkc4h+yN8z731POD2LnAGQlFe7/tXhUm7Bi0YB91g==}
- engines: {node: '>=20'}
-
- '@modelcontextprotocol/server@2.3.1':
- resolution: {integrity: sha512-e59MfWuSssj6DoQ96JCTqdW1AXT5/XtnTl0WWd6MU1Ka434fFUGGosCLJbGNySDhHGvxQWoRWK137FXYFkYNWw==}
- engines: {node: '>=20'}
-
- '@napi-rs/wasm-runtime@1.2.4':
- resolution: {integrity: sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==}
- engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
- peerDependencies:
- '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4
- '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4
-
- '@neodrag/core@3.0.0-next.11':
- resolution: {integrity: sha512-3WQWxyrbxiaK9zS5JU2wJsW2gpoQlZBXVghduBh61JpqaeE0T0cte8R0qYK2RuJo3J2TYQYqxO19CpG/C1i5eg==}
-
- '@neodrag/solid@3.0.0-next.11':
- resolution: {integrity: sha512-vCBIn/pimjWMQ6vhTS2/O1XNAwzVtc4eUhdbQ91WykbZWWqQ5NocDXt/1OdYrEkeRzJcpCv8wEz5PnMkgKP81Q==}
- peerDependencies:
- '@neodrag/core': 3.0.0-next.11
- solid-js: ^1.0.0
-
- '@noble/ciphers@2.4.0':
- resolution: {integrity: sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw==}
- engines: {node: '>= 20.19.0'}
-
- '@noble/hashes@2.4.0':
- resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==}
- engines: {node: '>= 20.19.0'}
-
- '@oozcitak/dom@2.0.2':
- resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==}
- engines: {node: '>=20.0'}
-
- '@oozcitak/infra@2.0.2':
- resolution: {integrity: sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==}
- engines: {node: '>=20.0'}
-
- '@oozcitak/url@3.0.0':
- resolution: {integrity: sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==}
- engines: {node: '>=20.0'}
-
- '@oozcitak/util@10.0.0':
- resolution: {integrity: sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==}
- engines: {node: '>=20.0'}
-
- '@opentelemetry/api-logs@0.222.0':
- resolution: {integrity: sha512-9mb1If+IF6u0ZVXkHQ6ogEae5HwA6ajIVUgpSDQyRASxft6BSXHvBvPooRle3yFN/fKnCdSOnuu0OC3PLcF6+g==}
- engines: {node: '>=8.0.0'}
-
- '@opentelemetry/api@1.9.1':
- resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
- engines: {node: '>=8.0.0'}
-
- '@opentelemetry/core@2.11.0':
- resolution: {integrity: sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': '>=1.0.0 <1.10.0'
-
- '@opentelemetry/exporter-logs-otlp-http@0.222.0':
- resolution: {integrity: sha512-GqwLZohJTf/sttYlOpT1oFTJ9ScYaKnk0sOx4Qe/+KmXYVOa+v94cfnkUkFKDuvTODWhCL50Hz3gvsZD6ngQpg==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': ^1.3.0
-
- '@opentelemetry/exporter-trace-otlp-http@0.222.0':
- resolution: {integrity: sha512-RCnPWcHppwiquQ+cV3nWvNwdf0MG1w26e5jewW2T83nTZOlXgcg88sY9ulCVgagGHcq1mj0L0GP6YHgzk2v8oA==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': ^1.3.0
-
- '@opentelemetry/otlp-exporter-base@0.222.0':
- resolution: {integrity: sha512-YbywG3veEm2Fb6TbdxRkuquWob6eVWXuA8/Ba1tXz9jHfUqpdE3keilOHEtPboC4CvS1bjeeVfNkWGOOrLj+lw==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': ^1.3.0
-
- '@opentelemetry/otlp-transformer@0.222.0':
- resolution: {integrity: sha512-/F3BZ89+CJQnZkMh2tCrtcdB+XT2Dxhj4FFE+WPQ//413hmFL0/RfEX6vgOIWGhiSzrkHWTK3+6SiT7K5/g/jQ==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': ^1.3.0
-
- '@opentelemetry/resources@2.11.0':
- resolution: {integrity: sha512-Ie7+8q8MDF4FAEQCKVMTx3ReUvxiIAgIiiW3c9JdmP8+HMcDy20puT+AHjexnExgnbvBxjQ9fjkFDWrikJ2jQA==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': '>=1.3.0 <1.10.0'
-
- '@opentelemetry/sdk-logs@0.222.0':
- resolution: {integrity: sha512-+19YHODIjaUCArxleaJtuufFZVpz/xvvK+VllQqE+W8hHolxdoRwHfK/s667zezwh1hkx6FFF+oYzetYgqK+Bg==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': '>=1.4.0 <1.10.0'
-
- '@opentelemetry/sdk-metrics@2.11.0':
- resolution: {integrity: sha512-7GXXcObyHyDUUSG+L+kJoquty01bzm7ivE7+SSgXXJcHuPzGviptxwARmI2c+bnnxjexGQbJnyNlN8HxBP/Y7A==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': '>=1.9.0 <1.10.0'
-
- '@opentelemetry/sdk-trace-base@2.11.0':
- resolution: {integrity: sha512-H19x/TX/LZdqiYOjM7fqtSxwlplC5pgelavqbQdHbhdq0q/AI/TGkM2dfGuuynTXmJPeF2HoZVoPDu+TGoW78A==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': '>=1.3.0 <1.10.0'
-
- '@opentelemetry/sdk-trace@2.11.0':
- resolution: {integrity: sha512-fFnTqGm8/G73GQVnxYi7LXa1ZVYEUvgL6XI1LpvV0bPC7WQ/ZGgKxCSl8FnlZBKto9JHHEFTO6s6CUpvvtwFrA==}
- engines: {node: ^18.19.0 || >=20.6.0}
- peerDependencies:
- '@opentelemetry/api': '>=1.3.0 <1.10.0'
-
- '@opentelemetry/semantic-conventions@1.43.0':
- resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==}
- engines: {node: '>=14'}
-
- '@oxc-parser/binding-android-arm-eabi@0.120.0':
- resolution: {integrity: sha512-WU3qtINx802wOl8RxAF1v0VvmC2O4D9M8Sv486nLeQ7iPHVmncYZrtBhB4SYyX+XZxj2PNnCcN+PW21jHgiOxg==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm]
- os: [android]
-
- '@oxc-parser/binding-android-arm64@0.120.0':
- resolution: {integrity: sha512-SEf80EHdhlbjZEgzeWm0ZA/br4GKMenDW3QB/gtyeTV1gStvvZeFi40ioHDZvds2m4Z9J1bUAUL8yn1/+A6iGg==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [android]
-
- '@oxc-parser/binding-darwin-arm64@0.120.0':
- resolution: {integrity: sha512-xVrrbCai8R8CUIBu3CjryutQnEYhZqs1maIqDvtUCFZb8vY33H7uh9mHpL3a0JBIKoBUKjPH8+rzyAeXnS2d6A==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [darwin]
-
- '@oxc-parser/binding-darwin-x64@0.120.0':
- resolution: {integrity: sha512-xyHBbnJ6mydnQUH7MAcafOkkrNzQC6T+LXgDH/3InEq2BWl/g424IMRiJVSpVqGjB+p2bd0h0WRR8iIwzjU7rw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [darwin]
-
- '@oxc-parser/binding-freebsd-x64@0.120.0':
- resolution: {integrity: sha512-UMnVRllquXUYTeNfFKmxTTEdZ/ix1nLl0ducDzMSREoWYGVIHnOOxoKMWlCOvRr9Wk/HZqo2rh1jeumbPGPV9A==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [freebsd]
-
- '@oxc-parser/binding-linux-arm-gnueabihf@0.120.0':
- resolution: {integrity: sha512-tkvn2CQ7QdcsMnpfiX3fd3wA3EFsWKYlcQzq9cFw/xc89Al7W6Y4O0FgLVkVQpo0Tnq/qtE1XfkJOnRRA9S/NA==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm]
- os: [linux]
-
- '@oxc-parser/binding-linux-arm-musleabihf@0.120.0':
- resolution: {integrity: sha512-WN5y135Ic42gQDk9grbwY9++fDhqf8knN6fnP+0WALlAUh4odY/BDK1nfTJRSfpJD9P3r1BwU0m3pW2DU89whQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm]
- os: [linux]
-
- '@oxc-parser/binding-linux-arm64-gnu@0.120.0':
- resolution: {integrity: sha512-1GgQBCcXvFMw99EPdMy+4NZ3aYyXsxjf9kbUUg8HuAy3ZBXzOry5KfFEzT9nqmgZI1cuetvApkiJBZLAPo8uaw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@oxc-parser/binding-linux-arm64-musl@0.120.0':
- resolution: {integrity: sha512-gmMQ70gsPdDBgpcErvJEoWNBr7bJooSLlvOBVBSGfOzlP5NvJ3bFvnUeZZ9d+dPrqSngtonf7nyzWUTUj/U+lw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@oxc-parser/binding-linux-ppc64-gnu@0.120.0':
- resolution: {integrity: sha512-T/kZuU0ajop0xhzVMwH5r3srC9Nqup5HaIo+3uFjIN5uPxa0LvSxC1ZqP4aQGJVW5G0z8/nCkjIfSMS91P/wzw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
-
- '@oxc-parser/binding-linux-riscv64-gnu@0.120.0':
- resolution: {integrity: sha512-vn21KXLAXzaI3N5CZWlBr1iWeXLl9QFIMor7S1hUjUGTeUuWCoE6JZB040/ZNDwf+JXPX8Ao9KbmJq9FMC2iGw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [riscv64]
- os: [linux]
- libc: [glibc]
-
- '@oxc-parser/binding-linux-riscv64-musl@0.120.0':
- resolution: {integrity: sha512-SUbUxlar007LTGmSLGIC5x/WJvwhdX+PwNzFJ9f/nOzZOrCFbOT4ikt7pJIRg1tXVsEfzk5mWpGO1NFiSs4PIw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [riscv64]
- os: [linux]
- libc: [musl]
-
- '@oxc-parser/binding-linux-s390x-gnu@0.120.0':
- resolution: {integrity: sha512-hYiPJTxyfJY2+lMBFk3p2bo0R9GN+TtpPFlRqVchL1qvLG+pznstramHNvJlw9AjaoRUHwp9IKR7UZQnRPGjgQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
-
- '@oxc-parser/binding-linux-x64-gnu@0.120.0':
- resolution: {integrity: sha512-q+5jSVZkprJCIy3dzJpApat0InJaoxQLsJuD6DkX8hrUS61z2lHQ1Fe9L2+TYbKHXCLWbL0zXe7ovkIdopBGMQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@oxc-parser/binding-linux-x64-musl@0.120.0':
- resolution: {integrity: sha512-D9QDDZNnH24e7X4ftSa6ar/2hCavETfW3uk0zgcMIrZNy459O5deTbWrjGzZiVrSWigGtlQwzs2McBP0QsfV1w==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@oxc-parser/binding-openharmony-arm64@0.120.0':
- resolution: {integrity: sha512-TBU8ZwOUWAOUWVfmI16CYWbvh4uQb9zHnGBHsw5Cp2JUVG044OIY1CSHODLifqzQIMTXvDvLzcL89GGdUIqNrA==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [openharmony]
-
- '@oxc-parser/binding-wasm32-wasi@0.120.0':
- resolution: {integrity: sha512-WG/FOZgDJCpJnuF3ToG/K28rcOmSY7FmFmfBKYb2fmLyhDzPpUldFGV7/Fz4ru0Iz/v4KPmf8xVgO8N3lO4KHA==}
- engines: {node: '>=14.0.0'}
- cpu: [wasm32]
-
- '@oxc-parser/binding-win32-arm64-msvc@0.120.0':
- resolution: {integrity: sha512-1T0HKGcsz/BKo77t7+89L8Qvu4f9DoleKWHp3C5sJEcbCjDOLx3m9m722bWZTY+hANlUEs+yjlK+lBFsA+vrVQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [win32]
-
- '@oxc-parser/binding-win32-ia32-msvc@0.120.0':
- resolution: {integrity: sha512-L7vfLzbOXsjBXV0rv/6Y3Jd9BRjPeCivINZAqrSyAOZN3moCopDN+Psq9ZrGNZtJzP8946MtlRFZ0Als0wBCOw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [ia32]
- os: [win32]
-
- '@oxc-parser/binding-win32-x64-msvc@0.120.0':
- resolution: {integrity: sha512-ys+upfqNtSu58huAhJMBKl3XCkGzyVFBlMlGPzHeFKgpFF/OdgNs1MMf8oaJIbgMH8ZxgGF7qfue39eJohmKIg==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [win32]
-
- '@oxc-project/types@0.120.0':
- resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==}
-
- '@oxc-project/types@0.152.0':
- resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==}
-
- '@posthog/browser-common@0.9.1':
- resolution: {integrity: sha512-Dl8uV2OZAxfHfWyC7K0Y3HtT7ld+WGLbXIwgCgAGziOMGDIa/bepCRrCxy7IxsEzqY1HOrq/VDdcoNN7hBTSQQ==}
-
- '@posthog/core@1.56.0':
- resolution: {integrity: sha512-WNlOoFQbOZyJzX54DhAslSpTjwDyXX5VLuRFNJjv172uOE9qHVUvtZAPP9dHZdq2HZkkLjbY27idH7UhzKSBVA==}
-
- '@posthog/types@1.413.0':
- resolution: {integrity: sha512-tYAVzNojWckuG/wxBB0fwE70sFruQQq4xbhkci7eH2ARU3mMfUTkvpN1HwBMpm0AtbxidLiH0IFvagmdJ8opPw==}
-
- '@radix-ui/primitive@1.1.7':
- resolution: {integrity: sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==}
-
- '@radix-ui/react-compose-refs@1.1.5':
- resolution: {integrity: sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-context@1.2.2':
- resolution: {integrity: sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-dialog@1.2.0':
- resolution: {integrity: sha512-l5CX8HdNL+9cc4s7HkNyplumSA3FIx68sg9dttBHKr286fRBwq1MBniDVTeI/tkof92/APntMQvC1YG1Khb0Cg==}
- 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
-
- '@radix-ui/react-dismissable-layer@1.1.20':
- resolution: {integrity: sha512-35WHRrycfnj2m4LvPiKMKHGLM3Y2WvUA744CkRdxjs1BGDX1c8PVMfmiSGTUwnHRbqdtIoxveYTXvcJSt7VfgQ==}
- 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
-
- '@radix-ui/react-focus-guards@1.1.6':
- resolution: {integrity: sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-focus-scope@1.2.0':
- resolution: {integrity: sha512-I5S7vsAOozx2lWSBAyuXjWIJ/A8qx4fjbv6115WoaRYQSb1yZDaeNHonUAQzXyE8oD+0whJHbQRl4HIE2gQ0Xw==}
- 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
-
- '@radix-ui/react-id@1.1.4':
- resolution: {integrity: sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-portal@1.1.18':
- resolution: {integrity: sha512-ygFIJ+QXNKf72AAq8x3hd22+ws7pYpmc1S0E4kW0Je+qD4qEb3FvxeKVQRGrVDMOkQaYfsB+Qs+KDh81a1gAOw==}
- 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
-
- '@radix-ui/react-presence@1.1.11':
- resolution: {integrity: sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==}
- 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
-
- '@radix-ui/react-primitive@2.1.11':
- resolution: {integrity: sha512-RzcaSw5aKl0OPhBJ1wbolKSF6nVvN+0o/QLeIVq+09npiPdnCkPggy2k6gI6yetxl4ZyrlBPYFgCB8BQJZwXcQ==}
- 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
-
- '@radix-ui/react-slot@1.4.0':
- resolution: {integrity: sha512-IuMVHZ+Ah5fkctu3X3qeFrV/ZrBcuWuDTFUUPfS/L5hvoTjzhp/HdWGE14CsQombPdEidsa33HVlYZXi49PZ1Q==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-use-callback-ref@1.1.4':
- resolution: {integrity: sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-use-controllable-state@1.2.6':
- resolution: {integrity: sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-use-effect-event@0.0.5':
- resolution: {integrity: sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@radix-ui/react-use-layout-effect@1.1.4':
- resolution: {integrity: sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@reduxjs/toolkit@2.13.0':
- resolution: {integrity: sha512-f6jwVRfwW30+tnllz4YcsHHpPYYOE7abcHkyUCovD+P7DyhdAI5prz2Fh/8TLhakjpN+7aIEion1s5L/tvlYlA==}
- peerDependencies:
- react: ^16.9.0 || ^17.0.0 || ^18 || ^19
- react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
- peerDependenciesMeta:
- react:
- optional: true
- react-redux:
- optional: true
-
- '@resvg/resvg-wasm@2.6.2':
- resolution: {integrity: sha512-FqALmHI8D4o6lk/LRWDnhw95z5eO+eAa6ORjVg09YRR7BkcM6oPHU9uyC0gtQG5vpFLvgpeU4+zEAz2H8APHNw==}
- engines: {node: '>= 10'}
-
- '@rolldown/binding-android-arm-eabi@1.2.12':
- resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm]
- os: [android]
-
- '@rolldown/binding-android-arm64@1.2.12':
- resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [android]
-
- '@rolldown/binding-darwin-arm64@1.2.12':
- resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [darwin]
-
- '@rolldown/binding-darwin-x64@1.2.12':
- resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [darwin]
-
- '@rolldown/binding-freebsd-x64@1.2.12':
- resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [freebsd]
-
- '@rolldown/binding-linux-arm-gnueabihf@1.2.12':
- resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm]
- os: [linux]
-
- '@rolldown/binding-linux-arm64-gnu@1.2.12':
- resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@rolldown/binding-linux-arm64-musl@1.2.12':
- resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@rolldown/binding-linux-ppc64-gnu@1.2.12':
- resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
-
- '@rolldown/binding-linux-s390x-gnu@1.2.12':
- resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
-
- '@rolldown/binding-linux-x64-gnu@1.2.12':
- resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@rolldown/binding-linux-x64-musl@1.2.12':
- resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@rolldown/binding-openharmony-arm64@1.2.12':
- resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [openharmony]
-
- '@rolldown/binding-win32-arm64-msvc@1.2.12':
- resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [arm64]
- os: [win32]
-
- '@rolldown/binding-win32-x64-msvc@1.2.12':
- resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- cpu: [x64]
- os: [win32]
-
- '@rolldown/pluginutils@1.0.1':
- resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
-
- '@solid-primitives/event-listener@2.4.6':
- resolution: {integrity: sha512-5I0YJcTVYIWoMmgBSROBZGcz+ymhew/pGTg2dHW74BUjFKsV8Li4bOZYl0YAGP4mHw5o4UBd9/BEesqBci3wxw==}
- peerDependencies:
- solid-js: ^1.6.12
-
- '@solid-primitives/keyboard@1.3.7':
- resolution: {integrity: sha512-558RPNYnXx4nGh537DSqAn4xMrC8iFipl/5+xzgzWoTNFst4RnUN3BOLmtDjJ0UGGoQXVMALYR3bNOHM0xnt1Q==}
- peerDependencies:
- solid-js: ^1.6.12
-
- '@solid-primitives/resize-observer@2.2.0':
- resolution: {integrity: sha512-9Fuu/EWBeGj+atGHRJp70HKhdfalmpjwxY8a32NZixdLNmfCJ45AfhLQNr6uOzETbbiMx4iCKlTrJ8KZCHC2Ww==}
- peerDependencies:
- solid-js: ^1.6.12
-
- '@solid-primitives/rootless@1.5.4':
- resolution: {integrity: sha512-TOIZa1VUfVJ+9nkCcRajw3U4t9vBOP1HxX1WHNTbXq32mXwlqTvUnC4CRIilohcryBkT9u2ZkhUDSHRTaGp55g==}
- peerDependencies:
- solid-js: ^1.6.12
-
- '@solid-primitives/static-store@0.1.4':
- resolution: {integrity: sha512-LgtVaVBtB7EbmS4+M0b8xY5Iq6pUWXBsIC4VgtrFKDGDdyCaDt88sHk0fUlx1Enxm/XZnZyLXJABRoa39RjJqA==}
- peerDependencies:
- solid-js: ^1.6.12
-
- '@solid-primitives/utils@6.4.1':
- resolution: {integrity: sha512-ISSB5QX1qP2ynrheIpYwc4oKR5Ny4siNuUyf1qZniy+Il+p/PtDB0QK1Dnle8noiHpwRD3gpPdubOC3qI/Zamg==}
- peerDependencies:
- solid-js: ^1.6.12
-
- '@standard-schema/spec@1.1.0':
- resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
-
- '@standard-schema/utils@0.3.0':
- resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
-
- '@tailwindcss/node@4.3.3':
- resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==}
-
- '@tailwindcss/oxide-android-arm64@4.3.3':
- resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==}
- engines: {node: '>= 20'}
- cpu: [arm64]
- os: [android]
-
- '@tailwindcss/oxide-darwin-arm64@4.3.3':
- resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==}
- engines: {node: '>= 20'}
- cpu: [arm64]
- os: [darwin]
-
- '@tailwindcss/oxide-darwin-x64@4.3.3':
- resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==}
- engines: {node: '>= 20'}
- cpu: [x64]
- os: [darwin]
-
- '@tailwindcss/oxide-freebsd-x64@4.3.3':
- resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==}
- engines: {node: '>= 20'}
- cpu: [x64]
- os: [freebsd]
-
- '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3':
- resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==}
- engines: {node: '>= 20'}
- cpu: [arm]
- os: [linux]
-
- '@tailwindcss/oxide-linux-arm64-gnu@4.3.3':
- resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==}
- engines: {node: '>= 20'}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@tailwindcss/oxide-linux-arm64-musl@4.3.3':
- resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==}
- engines: {node: '>= 20'}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@tailwindcss/oxide-linux-x64-gnu@4.3.3':
- resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==}
- engines: {node: '>= 20'}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@tailwindcss/oxide-linux-x64-musl@4.3.3':
- resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==}
- engines: {node: '>= 20'}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@tailwindcss/oxide-wasm32-wasi@4.3.3':
- resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==}
- engines: {node: '>=14.0.0'}
- cpu: [wasm32]
- bundledDependencies:
- - '@napi-rs/wasm-runtime'
- - '@emnapi/core'
- - '@emnapi/runtime'
- - '@tybys/wasm-util'
- - '@emnapi/wasi-threads'
- - tslib
-
- '@tailwindcss/oxide-win32-arm64-msvc@4.3.3':
- resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==}
- engines: {node: '>= 20'}
- cpu: [arm64]
- os: [win32]
-
- '@tailwindcss/oxide-win32-x64-msvc@4.3.3':
- resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==}
- engines: {node: '>= 20'}
- cpu: [x64]
- os: [win32]
-
- '@tailwindcss/oxide@4.3.3':
- resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==}
- engines: {node: '>= 20'}
-
- '@tailwindcss/typography@0.5.20':
- resolution: {integrity: sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==}
- peerDependencies:
- tailwindcss: '>=3.0.0 || >=4.0.0 || insiders'
-
- '@tailwindcss/vite@4.3.3':
- resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==}
- peerDependencies:
- vite: ^5.2.0 || ^6 || ^7 || ^8
-
- '@tanstack/devtools-bundler-core@0.1.3':
- resolution: {integrity: sha512-F0tlxIyfFqXkZ1mJP1EjtkiSeJA+ztXY2AYOHf7r4goCIEAOp86N9PFJ/yv8vu1TnmxGS6vKsZCS3Kyls9xQQA==}
- engines: {node: '>=18'}
-
- '@tanstack/devtools-client@0.0.8':
- resolution: {integrity: sha512-cG3iZkGWCwN330bLBKa8+9r4Of2AXNoz2zUqcsy/4XsD3105ghVBx78cGyvJj9fSclNomPxoqAnDGXXhg1WLvA==}
- engines: {node: '>=18'}
-
- '@tanstack/devtools-event-bus@0.4.3':
- resolution: {integrity: sha512-NeegBt5/n2E5q4DbrXHqECBq42+kDi6JBOp8/+RNqkIE+P4hJpbM36kGyjnGQFMWOoku31qhMyX9/48VuTTdmg==}
- engines: {node: '>=18'}
-
- '@tanstack/devtools-event-client@0.5.0':
- resolution: {integrity: sha512-H+OH3zC6Vhu/K0NaVfQKknEKawc/+2PT+D3SB3Ox0V8SiMlTo0abbmH2rH0721R2aNYbjdMXA1oENOd8E2UVoA==}
- engines: {node: '>=18'}
- hasBin: true
-
- '@tanstack/devtools-ui@0.7.1':
- resolution: {integrity: sha512-3xQ/ezZ2qVNszhjpCN2N3jn7uHc2J1PMgcyjHzH4XZBt9xAQyMMcPNoR2cd7rzReyxWoJpZUWiDBmOJiCtLj9A==}
- engines: {node: '>=18'}
- peerDependencies:
- solid-js: '>=1.9.7'
-
- '@tanstack/devtools-vite@0.8.5':
- resolution: {integrity: sha512-xaifCEmiwwzizlbp973oISXNsnmuU/BugLa66gryAZaPJJ/qo1kJd2DxY5X960eHwmyIS3SN0KYrL3/aRhucmA==}
- engines: {node: '>=18'}
- hasBin: true
- peerDependencies:
- vite: ^6.0.0 || ^7.0.0 || ^8.0.0
-
- '@tanstack/devtools@0.15.0':
- resolution: {integrity: sha512-KyS7Qi82Eq9yG8C+uae3ikAPb+D5rfzVhvOOjXVAHZ/64s6TWJlDWpREw1FrHIYZaI7paErpsExSSKlF5BKA/A==}
- engines: {node: '>=18'}
- hasBin: true
- peerDependencies:
- solid-js: '>=1.9.7'
-
- '@tanstack/history@1.162.4':
- resolution: {integrity: sha512-utTS5L2OkeYUzXGohL1Z8sefu1GLNOJcxe8Hd6iIdc/Xo1K1nDB2JEp4iSFhvYh33xKC9V91TxrS8qfrpoKobQ==}
- engines: {node: '>=20.19'}
-
- '@tanstack/intent@0.5.4':
- resolution: {integrity: sha512-veyJDHwIHrylKucn8UgLlMYZbhLZ3gO1OlYiXLcmIKazCd8bTDXRfcWvmwNK3q63jS8K40pYudZV3HQPbHsBWg==}
- engines: {node: '>=20.12.0'}
- hasBin: true
-
- '@tanstack/react-devtools@0.10.13':
- resolution: {integrity: sha512-r0cdB/14+st2Vxl/1Bodlyq4VC8pf9SykLQDYbGHDc1+V146WQo5B3KlYLkfyxD9Q/6+9NPRQHZyl8fvZVMdRA==}
- engines: {node: '>=18'}
- peerDependencies:
- '@types/react': '>=16.8'
- '@types/react-dom': '>=16.8'
- react: '>=16.8'
- react-dom: '>=16.8'
-
- '@tanstack/react-router-devtools@1.167.2':
- resolution: {integrity: sha512-VuoqB7OhDUrBa4WOFSKiAQ8xI8sJpeZdo9sYE1hQa89iMuVFUQu1iWE4iCiQhB+6TYOZDZ9e+iHKxYjop4ZVYw==}
- engines: {node: '>=20.19'}
- peerDependencies:
- '@tanstack/react-router': ^1.170.36
- '@tanstack/router-core': ^1.171.30
- react: '>=18.0.0 || >=19.0.0'
- react-dom: '>=18.0.0 || >=19.0.0'
- peerDependenciesMeta:
- '@tanstack/router-core':
- optional: true
-
- '@tanstack/react-router@1.170.41':
- resolution: {integrity: sha512-Mpvw8Wm5MGDbTqI8Yc9flLKxbOHwoWocv0H2aGKcgw2a017oK5nZWqa954P+DrUx/8fI98YNywnHP5XcD3tQ9w==}
- engines: {node: '>=20.19'}
- peerDependencies:
- react: '>=18.0.0 || >=19.0.0'
- react-dom: '>=18.0.0 || >=19.0.0'
-
- '@tanstack/react-start-client@1.168.39':
- resolution: {integrity: sha512-Uby0uo37JlQgUKHU0snDwH9nYiEeAjm9+7pUOFgycU/UszEILC2SO2DSCoNnCMuHKj9z+4URKzBYIP2exT9+wg==}
- engines: {node: '>=22.12.0'}
- peerDependencies:
- react: '>=18.0.0 || >=19.0.0'
- react-dom: '>=18.0.0 || >=19.0.0'
-
- '@tanstack/react-start-rsc@0.1.59':
- resolution: {integrity: sha512-M2Lqxkk5C1zQncQs5paqX+/OLdOht51pg6D84YfLMrNsjhU/nzb6wd92MIja0mi5i23+L+fxLLjQYR2DObjBlw==}
- engines: {node: '>=22.12.0'}
- peerDependencies:
- '@rspack/core': '>=2.0.0-0'
- '@vitejs/plugin-rsc': '>=0.5.30'
- react: '>=18.0.0 || >=19.0.0'
- react-dom: '>=18.0.0 || >=19.0.0'
- react-server-dom-rspack: '>=0.0.2'
- peerDependenciesMeta:
- '@rspack/core':
- optional: true
- '@vitejs/plugin-rsc':
- optional: true
- react-server-dom-rspack:
- optional: true
-
- '@tanstack/react-start-server@1.167.46':
- resolution: {integrity: sha512-K7z8xBOEdp8u5CZCxWrbS0tFtk5XZGMdhssLeZlRZKlLDbX7BKLdMtJ7th5sR6QVt9MTUAg3LcoqvJMPSFF+lg==}
- engines: {node: '>=22.12.0'}
- peerDependencies:
- react: '>=18.0.0 || >=19.0.0'
- react-dom: '>=18.0.0 || >=19.0.0'
-
- '@tanstack/react-start@1.168.60':
- resolution: {integrity: sha512-WMOM0Xlh2lPbVlbjYM6uOxOpiaWRPvODm/dwkLsGKq5tjyHOHZmKckJgwlrZl7OQUqFlOZHYj8bKUTgoeg8cUQ==}
- engines: {node: '>=22.12.0'}
- peerDependencies:
- '@rsbuild/core': ^2.0.0
- '@vitejs/plugin-rsc': '*'
- react: '>=18.0.0 || >=19.0.0'
- react-dom: '>=18.0.0 || >=19.0.0'
- vite: '>=7.0.0'
- peerDependenciesMeta:
- '@rsbuild/core':
- optional: true
- '@vitejs/plugin-rsc':
- optional: true
- vite:
- optional: true
-
- '@tanstack/react-store@0.11.2':
- resolution: {integrity: sha512-oj5O5DmiMWE+ih+SioX2ayC1kbK7d3fpLx0B75fPJr9nY3zU+hoW010yr64qXsY/9fyiLVE2bn5mGNV3owm8RQ==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
- '@tanstack/router-cli@1.167.40':
- resolution: {integrity: sha512-KKX9hedstsc0eEKfUAwrwy7CLNXdSxjiBBq0uojnjMnOnraRXP9Nf+x6/ZsAultxHp7NhWfYddO8VdT0zAtUDg==}
- engines: {node: '>=20.19'}
- hasBin: true
-
- '@tanstack/router-core@1.171.34':
- resolution: {integrity: sha512-X+19pGuuLVPvvAvPYw9v/+ktRk5cCll8AtfpBpOhDRmVgUMrfqze0467xtq8YRVVs/mmo5rVtWn/7Tp32RDBKw==}
- engines: {node: '>=20.19'}
-
- '@tanstack/router-devtools-core@1.168.2':
- resolution: {integrity: sha512-pCCdQ5M/NUeWdiAbPmjyfcNdls6G4vaVlIQbPf1IqZk1FLYFr00aQvi578yUuWFBNM2KNS2QcwM1uPucbtGf5Q==}
- engines: {node: '>=20.19'}
- peerDependencies:
- '@tanstack/router-core': ^1.171.30
- csstype: ^3.0.10
- peerDependenciesMeta:
- csstype:
- optional: true
-
- '@tanstack/router-generator@1.167.40':
- resolution: {integrity: sha512-WkEueqEvsBBudzO0fx1nWfOmRNW8OAvBoVABTGls9bAWzjdC+KDGHvjCNrvn88ofs1F6gqL8aWnzKCbxW3dCyQ==}
- engines: {node: '>=20.19'}
-
- '@tanstack/router-plugin@1.168.42':
- resolution: {integrity: sha512-vAR5WXJh/ErseEWQftDhsJcr2c++ucRQ6FbqN3ygMO44+ZxxRfW3sIpZmddHROVSmBk8jc6MrwjTPNjVhd62Vw==}
- engines: {node: '>=20.19'}
- peerDependencies:
- '@rsbuild/core': '>=1.0.2 || ^2.0.0'
- '@tanstack/react-router': ^1.170.41
- vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0'
- vite-plugin-solid: ^2.11.10 || ^3.0.0-0
- webpack: '>=5.92.0'
- peerDependenciesMeta:
- '@rsbuild/core':
- optional: true
- '@tanstack/react-router':
- optional: true
- vite:
- optional: true
- vite-plugin-solid:
- optional: true
- webpack:
- optional: true
-
- '@tanstack/router-utils@1.162.3':
- resolution: {integrity: sha512-Icb0xGuG1+54IV0WMLRcc3ErTx2HeJWyPG661FkQ8UT6guoBq1FJjFRqlG/JS0xi4mFFkBhvwO7tbLa32f3yxA==}
- engines: {node: '>=20.19'}
-
- '@tanstack/start-client-core@1.170.34':
- resolution: {integrity: sha512-LfwZSbau2MLLZ/uPAoO+NC9fK3J66c0wLhnNQqIa+Goqw7bXPjkHwlsjY7evlUz1AnyhhQ1Qab95v+VmP0TZ9A==}
- engines: {node: '>=22.12.0'}
-
- '@tanstack/start-fn-stubs@1.162.0':
- resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==}
- engines: {node: '>=22.12.0'}
-
- '@tanstack/start-plugin-core@1.171.49':
- resolution: {integrity: sha512-HPOb7LnMc71k38cd5uvMybPPUU/Q/56KvSqQzSWz7cps1ZDFXaxUM6EFaFHLCdgTWqGexNGDdRE+sUVPVBM4Xg==}
- engines: {node: '>=22.12.0'}
- peerDependencies:
- '@rsbuild/core': ^2.0.0
- vite: '>=7.0.0'
- peerDependenciesMeta:
- '@rsbuild/core':
- optional: true
- vite:
- optional: true
-
- '@tanstack/start-server-core@1.169.39':
- resolution: {integrity: sha512-pqqkxhXY46nuFSYt6TsMGyABiplUzHFHndKAlRRGC0fWDrJCH1koWxVMoxySa51ZETV79f/z73b5UZ1jfIkXwQ==}
- engines: {node: '>=22.12.0'}
-
- '@tanstack/start-storage-context@1.167.36':
- resolution: {integrity: sha512-x+xCXK2GtFzY6NbXqAg8YpU6cwAjDfMeYSNzxfGzntpjbwBRHHrXeC/kYUnBBQCV7wK4kJ8vBBQGP0OyYTasUg==}
- engines: {node: '>=22.12.0'}
-
- '@tanstack/store@0.11.2':
- resolution: {integrity: sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q==}
-
- '@tanstack/virtual-file-routes@1.162.0':
- resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==}
- engines: {node: '>=20.19'}
-
- '@tybys/wasm-util@0.10.4':
- resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==}
-
- '@types/d3-array@3.2.2':
- resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==}
-
- '@types/d3-color@3.1.3':
- resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
-
- '@types/d3-ease@3.0.2':
- resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
-
- '@types/d3-interpolate@3.0.4':
- resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
-
- '@types/d3-path@3.1.1':
- resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==}
-
- '@types/d3-scale@4.0.9':
- resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==}
-
- '@types/d3-shape@3.2.0':
- resolution: {integrity: sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==}
-
- '@types/d3-time@3.0.4':
- resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==}
-
- '@types/d3-timer@3.0.2':
- resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
-
- '@types/node@22.20.5':
- resolution: {integrity: sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==}
-
- '@types/pg@8.23.1':
- resolution: {integrity: sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==}
-
- '@types/react-dom@19.3.0':
- resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==}
- peerDependencies:
- '@types/react': ^19.3.0
-
- '@types/react@19.3.0':
- resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==}
-
- '@types/trusted-types@2.0.7':
- resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
-
- '@types/use-sync-external-store@0.0.6':
- resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
-
- '@vitejs/plugin-react@6.1.1':
- resolution: {integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==}
- engines: {node: ^20.19.0 || >=22.12.0}
- peerDependencies:
- '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0
- babel-plugin-react-compiler: ^1.0.0
- oxc-transform-react: ^0.145.0
- vite: ^8.0.0
- peerDependenciesMeta:
- '@rolldown/plugin-babel':
- optional: true
- babel-plugin-react-compiler:
- optional: true
- oxc-transform-react:
- optional: true
-
- ansi-regex@5.0.1:
- resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
- engines: {node: '>=8'}
-
- ansi-styles@4.3.0:
- resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
- engines: {node: '>=8'}
-
- ansis@4.4.0:
- resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==}
- engines: {node: '>=14'}
-
- argparse@2.0.1:
- resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
-
- aria-hidden@1.2.6:
- resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
- engines: {node: '>=10'}
-
- babel-dead-code-elimination@1.0.12:
- resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==}
-
- baseline-browser-mapping@2.11.27:
- resolution: {integrity: sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==}
- engines: {node: '>=6.0.0'}
- hasBin: true
-
- better-auth@1.7.7:
- resolution: {integrity: sha512-Zhgxi/c5ylmfB/sX+nwnBbsFf/j6k0L8DvL6CJXZSrXgxc5pPMC/e7j812zNd4L4B4ELmdURCPw3X8nAOUdcjw==}
- peerDependencies:
- '@lynx-js/react': '*'
- '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
- '@sveltejs/kit': ^2.0.0
- '@tanstack/react-start': ^1.0.0
- '@tanstack/solid-start': ^1.0.0
- drizzle-kit: '>=0.31.4 || >=1.0.0-beta.1'
- drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
- mongodb: ^6.0.0 || ^7.0.0
- mysql2: ^3.0.0
- next: ^14.0.0 || ^15.0.0 || ^16.0.0
- pg: ^8.0.0
- prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
- react: ^18.0.0 || ^19.0.0
- react-dom: ^18.0.0 || ^19.0.0
- solid-js: ^1.0.0
- svelte: ^4.0.0 || ^5.0.0
- vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
- vue: ^3.0.0
- peerDependenciesMeta:
- '@lynx-js/react':
- optional: true
- '@prisma/client':
- optional: true
- '@sveltejs/kit':
- optional: true
- '@tanstack/react-start':
- optional: true
- '@tanstack/solid-start':
- optional: true
- drizzle-kit:
- optional: true
- drizzle-orm:
- optional: true
- mongodb:
- optional: true
- mysql2:
- optional: true
- next:
- optional: true
- pg:
- optional: true
- prisma:
- optional: true
- react:
- optional: true
- react-dom:
- optional: true
- solid-js:
- optional: true
- svelte:
- optional: true
- vitest:
- optional: true
- vue:
- optional: true
-
- better-call@1.4.0:
- resolution: {integrity: sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==}
- peerDependencies:
- zod: ^4.0.0
- peerDependenciesMeta:
- zod:
- optional: true
-
- browserslist@4.29.3:
- resolution: {integrity: sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==}
- engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
- hasBin: true
-
- buffer-from@1.1.2:
- resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
-
- caniuse-lite@1.0.30001814:
- resolution: {integrity: sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==}
-
- chalk@5.6.2:
- resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
- engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
-
- chokidar@5.0.0:
- resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
- engines: {node: '>= 20.19.0'}
-
- class-variance-authority@0.7.1:
- resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
-
- cliui@8.0.1:
- resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
- engines: {node: '>=12'}
-
- clsx@2.1.1:
- resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
- engines: {node: '>=6'}
-
- cmdk@1.1.1:
- resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==}
- peerDependencies:
- react: ^18 || ^19 || ^19.0.0-rc
- react-dom: ^18 || ^19 || ^19.0.0-rc
-
- cn@0.4.0:
- resolution: {integrity: sha512-qOAeUhPwPzBxx6jaeQdo646XIKliKHc2j1ZF7Ngb1o0pJZKH5gq8FkA0aVdUdPFUDXNXyUCXpCtoJISo6dhizg==}
- engines: {node: '>=20'}
- hasBin: true
-
- color-convert@2.0.1:
- resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
- engines: {node: '>=7.0.0'}
-
- color-name@1.1.4:
- resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-
- consola@3.4.2:
- resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
- engines: {node: ^14.18.0 || >=16.10.0}
-
- convert-source-map@2.0.0:
- resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
-
- cookie-es@3.1.1:
- resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==}
-
- core-js@3.50.0:
- resolution: {integrity: sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==}
-
- croner@10.0.1:
- resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==}
- engines: {node: '>=18.0'}
-
- cross-spawn@7.0.6:
- resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
- engines: {node: '>= 8'}
-
- crossws@0.4.12:
- resolution: {integrity: sha512-aypfsr6t0uNvkqaZc6zvBfXzC6pLI0/sIulpkV6RwCVtZqG5ebBzv4weImKK0VNCj91Wl9F5j7p5WU4MNrybng==}
- peerDependencies:
- srvx: '>=0.11.5'
- peerDependenciesMeta:
- srvx:
- optional: true
-
- cssesc@3.0.0:
- resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
- engines: {node: '>=4'}
- hasBin: true
-
- csstype@3.2.3:
- resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
-
- d3-array@3.2.4:
- resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
- engines: {node: '>=12'}
-
- d3-color@3.1.0:
- resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
- engines: {node: '>=12'}
-
- d3-ease@3.0.1:
- resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
- engines: {node: '>=12'}
-
- d3-format@3.1.2:
- resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==}
- engines: {node: '>=12'}
-
- d3-interpolate@3.0.1:
- resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
- engines: {node: '>=12'}
-
- d3-path@3.1.0:
- resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
- engines: {node: '>=12'}
-
- d3-scale@4.0.2:
- resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
- engines: {node: '>=12'}
-
- d3-shape@3.2.0:
- resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
- engines: {node: '>=12'}
-
- d3-time-format@4.1.0:
- resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
- engines: {node: '>=12'}
-
- d3-time@3.1.0:
- resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
- engines: {node: '>=12'}
-
- d3-timer@3.0.1:
- resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
- engines: {node: '>=12'}
-
- dayjs@1.11.23:
- resolution: {integrity: sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==}
-
- db0@0.3.4:
- resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==}
- peerDependencies:
- '@electric-sql/pglite': '*'
- '@libsql/client': '*'
- better-sqlite3: '*'
- drizzle-orm: '*'
- mysql2: '*'
- sqlite3: '*'
- peerDependenciesMeta:
- '@electric-sql/pglite':
- optional: true
- '@libsql/client':
- optional: true
- better-sqlite3:
- optional: true
- drizzle-orm:
- optional: true
- mysql2:
- optional: true
- sqlite3:
- optional: true
-
- debug@4.4.3:
- resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
-
- decimal.js-light@2.5.1:
- resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
-
- defu@6.1.7:
- resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
-
- detect-libc@2.1.2:
- resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
- engines: {node: '>=8'}
-
- detect-node-es@1.1.0:
- resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
-
- diff@8.0.4:
- resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
- engines: {node: '>=0.3.1'}
-
- dompurify@3.4.16:
- resolution: {integrity: sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==}
-
- drizzle-kit@0.31.11:
- resolution: {integrity: sha512-YCYqxTLIB2OCqf6w9/Vef13baBVbwQIPcbT4Y56AfO6B9ajZhDhD8Jkveg/hJvT/iuMloKD/IYYkyMMNhr7Kqg==}
- hasBin: true
-
- drizzle-orm@0.45.3:
- resolution: {integrity: sha512-CAloER21cDdcgZ1OmjrZX82EeRNsdP+y0onX/eyoYDaYzki/adrAa91lzM5jWh7zZPK4qUbw/6LGv9J+A+uizA==}
- peerDependencies:
- '@aws-sdk/client-rds-data': '>=3'
- '@cloudflare/workers-types': '>=4'
- '@electric-sql/pglite': '>=0.2.0'
- '@libsql/client': '>=0.10.0'
- '@libsql/client-wasm': '>=0.10.0'
- '@neondatabase/serverless': '>=0.10.0'
- '@netlify/db': '>=0.4.0'
- '@op-engineering/op-sqlite': '>=2'
- '@opentelemetry/api': ^1.4.1
- '@planetscale/database': '>=1.13'
- '@prisma/client': '*'
- '@tidbcloud/serverless': '*'
- '@types/better-sqlite3': '*'
- '@types/pg': '*'
- '@types/sql.js': '*'
- '@upstash/redis': '>=1.34.7'
- '@vercel/postgres': '>=0.8.0'
- '@xata.io/client': '*'
- better-sqlite3: '>=7'
- bun-types: '*'
- expo-sqlite: '>=14.0.0'
- gel: '>=2'
- knex: '*'
- kysely: '*'
- mysql2: '>=2'
- pg: '>=8'
- postgres: '>=3'
- prisma: '*'
- sql.js: '>=1'
- sqlite3: '>=5'
- peerDependenciesMeta:
- '@aws-sdk/client-rds-data':
- optional: true
- '@cloudflare/workers-types':
- optional: true
- '@electric-sql/pglite':
- optional: true
- '@libsql/client':
- optional: true
- '@libsql/client-wasm':
- optional: true
- '@neondatabase/serverless':
- optional: true
- '@netlify/db':
- optional: true
- '@op-engineering/op-sqlite':
- optional: true
- '@opentelemetry/api':
- optional: true
- '@planetscale/database':
- optional: true
- '@prisma/client':
- optional: true
- '@tidbcloud/serverless':
- optional: true
- '@types/better-sqlite3':
- optional: true
- '@types/pg':
- optional: true
- '@types/sql.js':
- optional: true
- '@upstash/redis':
- optional: true
- '@vercel/postgres':
- optional: true
- '@xata.io/client':
- optional: true
- better-sqlite3:
- optional: true
- bun-types:
- optional: true
- expo-sqlite:
- optional: true
- gel:
- optional: true
- knex:
- optional: true
- kysely:
- optional: true
- mysql2:
- optional: true
- pg:
- optional: true
- postgres:
- optional: true
- prisma:
- optional: true
- sql.js:
- optional: true
- sqlite3:
- optional: true
-
- electron-to-chromium@1.5.444:
- resolution: {integrity: sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ==}
-
- emoji-regex@8.0.0:
- resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
-
- enhanced-resolve@5.26.0:
- resolution: {integrity: sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==}
- engines: {node: '>=10.13.0'}
-
- env-runner@0.1.16:
- resolution: {integrity: sha512-2LRJM4P2KLX6J83QZZrMqvgCDt/D5ea7wPcI3yYiy5cG/9rX5QwdwZFx0D7ktWnjdRyZxYjttGGorb5nFqb1CA==}
- hasBin: true
- peerDependencies:
- '@netlify/runtime': ^4.1.23
- '@vercel/queue': '>=0.2.0'
- miniflare: ^4.20260515.0
- wrangler: ^4.0.0
- peerDependenciesMeta:
- '@netlify/runtime':
- optional: true
- '@vercel/queue':
- optional: true
- miniflare:
- optional: true
- wrangler:
- optional: true
-
- es-toolkit@1.52.0:
- resolution: {integrity: sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==}
-
- esbuild@0.18.20:
- resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
- engines: {node: '>=12'}
- hasBin: true
-
- esbuild@0.25.12:
- resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
- engines: {node: '>=18'}
- hasBin: true
-
- esbuild@0.28.2:
- resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==}
- engines: {node: '>=18'}
- hasBin: true
-
- escalade@3.2.0:
- resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
- engines: {node: '>=6'}
-
- eventemitter3@5.0.4:
- resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
-
- eventsource-parser@3.1.1:
- resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==}
- engines: {node: '>=18.0.0'}
-
- eventsource@3.0.7:
- resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
- engines: {node: '>=18.0.0'}
-
- exsolve@1.1.3:
- resolution: {integrity: sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==}
-
- fdir@6.5.0:
- resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
- engines: {node: '>=12.0.0'}
- peerDependencies:
- picomatch: ^3 || ^4
- peerDependenciesMeta:
- picomatch:
- optional: true
-
- fetchdts@0.1.7:
- resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==}
-
- fflate@0.4.9:
- resolution: {integrity: sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw==}
-
- fsevents@2.3.3:
- resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
-
- gensync@1.0.0-beta.2:
- resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
- engines: {node: '>=6.9.0'}
-
- get-caller-file@2.0.5:
- resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
- engines: {node: 6.* || 8.* || >= 10.*}
-
- get-nonce@1.0.1:
- resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
- engines: {node: '>=6'}
-
- get-tsconfig@4.14.3:
- resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==}
-
- goober@2.1.19:
- resolution: {integrity: sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg==}
- peerDependencies:
- csstype: ^3.0.10
-
- graceful-fs@4.2.11:
- resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
-
- h3@2.0.1-rc.20:
- resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==}
- engines: {node: '>=20.11.1'}
- hasBin: true
- peerDependencies:
- crossws: ^0.4.1
- peerDependenciesMeta:
- crossws:
- optional: true
-
- h3@2.0.1-rc.22:
- resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==}
- engines: {node: '>=20.11.1'}
- hasBin: true
- peerDependencies:
- crossws: ^0.4.1
- peerDependenciesMeta:
- crossws:
- optional: true
-
- hookable@6.1.2:
- resolution: {integrity: sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==}
-
- httpxy@0.5.5:
- resolution: {integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==}
-
- immer@10.2.0:
- resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==}
-
- immer@11.1.21:
- resolution: {integrity: sha512-bZSadeCPGdaY5/qRLgr6mDSH1ra21rD3rqpiWk7+QTr4ayYPTE9qZYdLh/NdPhMe0wSrTvHD/Lk8q5EwhUs0aw==}
-
- internmap@2.0.3:
- resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
- engines: {node: '>=12'}
-
- is-fullwidth-code-point@3.0.0:
- resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
- engines: {node: '>=8'}
-
- isbot@5.2.2:
- resolution: {integrity: sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w==}
- engines: {node: '>=18'}
-
- isexe@2.0.0:
- resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
-
- jiti@2.7.0:
- resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
- hasBin: true
-
- jose@6.2.12:
- resolution: {integrity: sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==}
-
- js-tokens@4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
-
- js-yaml@4.3.2:
- resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==}
- hasBin: true
-
- jsesc@3.1.0:
- resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
- engines: {node: '>=6'}
- hasBin: true
-
- json5@2.2.3:
- resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
- engines: {node: '>=6'}
- hasBin: true
-
- kysely@0.29.6:
- resolution: {integrity: sha512-hHaB8C/rfzDDtr/t8YZwxAuPJTT0zHyaPoVzcXwDYhYNAgH/4sIfVhi/XLLIY+bL/FqaIJnjATDbi8ObSELmxg==}
- engines: {node: '>=22.0.0'}
-
- launch-editor@2.14.1:
- resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==}
-
- lightningcss-android-arm64@1.32.0:
- resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [android]
-
- lightningcss-android-arm64@1.33.0:
- resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [android]
-
- lightningcss-darwin-arm64@1.32.0:
- resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [darwin]
-
- lightningcss-darwin-arm64@1.33.0:
- resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [darwin]
-
- lightningcss-darwin-x64@1.32.0:
- resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [darwin]
-
- lightningcss-darwin-x64@1.33.0:
- resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [darwin]
-
- lightningcss-freebsd-x64@1.32.0:
- resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [freebsd]
-
- lightningcss-freebsd-x64@1.33.0:
- resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [freebsd]
-
- lightningcss-linux-arm-gnueabihf@1.32.0:
- resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm]
- os: [linux]
-
- lightningcss-linux-arm-gnueabihf@1.33.0:
- resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm]
- os: [linux]
-
- lightningcss-linux-arm64-gnu@1.32.0:
- resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- lightningcss-linux-arm64-gnu@1.33.0:
- resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- lightningcss-linux-arm64-musl@1.32.0:
- resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- lightningcss-linux-arm64-musl@1.33.0:
- resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- lightningcss-linux-x64-gnu@1.32.0:
- resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- lightningcss-linux-x64-gnu@1.33.0:
- resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- lightningcss-linux-x64-musl@1.32.0:
- resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- lightningcss-linux-x64-musl@1.33.0:
- resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- lightningcss-win32-arm64-msvc@1.32.0:
- resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [win32]
-
- lightningcss-win32-arm64-msvc@1.33.0:
- resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
- engines: {node: '>= 12.0.0'}
- cpu: [arm64]
- os: [win32]
-
- lightningcss-win32-x64-msvc@1.32.0:
- resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [win32]
-
- lightningcss-win32-x64-msvc@1.33.0:
- resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
- engines: {node: '>= 12.0.0'}
- cpu: [x64]
- os: [win32]
-
- lightningcss@1.32.0:
- resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
- engines: {node: '>= 12.0.0'}
-
- lightningcss@1.33.0:
- resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
- engines: {node: '>= 12.0.0'}
-
- lru-cache@5.1.1:
- resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
-
- lucide-react@0.577.0:
- resolution: {integrity: sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==}
- peerDependencies:
- react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
- magic-string@0.30.21:
- resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
-
- marked@18.0.14:
- resolution: {integrity: sha512-mBHK6FBHuBAlhgRe88w9F0O1AbwwXJUcQibUbC/QcdTbVGAD7aWza+xt3N6oT/jCZx3/OMeS+8rnuiHZcQ9s7A==}
- engines: {node: '>= 20'}
- hasBin: true
-
- ms@2.1.3:
- resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
-
- nanoid@3.3.19:
- resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
-
- nanostores@1.5.4:
- resolution: {integrity: sha512-4UXY7OAJEK0Y6V3SudBU7cXjAzTDc189R78dDOh0Xbm19gpKYto6WizSg58LJf12lTsRxKSLGyE117OiLpM4DQ==}
- engines: {node: ^20.0.0 || >=22.0.0}
-
- nf3@0.3.24:
- resolution: {integrity: sha512-HxLK4bo+5jNsEETZp4w3tJblHOA9MCBY14IN9nZJJV8JDxt9yNIYxuBuLMjTAR5GFa3HL61+8VQDUrXv3/C8fw==}
-
- nitro@3.0.260610-beta:
- resolution: {integrity: sha512-KPb4L5yaF/Rx/xoGMpgHRJvZhbhGiqbRKOwwPLCH9jKTKTsEUHLjnJas85AeCzaswqa8Wi52eQBtRsODC4PS0Q==}
- engines: {node: ^20.19.0 || >=22.12.0}
- hasBin: true
- peerDependencies:
- '@vercel/queue': ^0.3.0
- dotenv: '*'
- giget: '*'
- jiti: ^2.7.0
- rollup: ^4.61.1
- vite: ^7 || ^8
- xml2js: ^0.6.2
- zephyr-agent: ^0.2.0
- peerDependenciesMeta:
- '@vercel/queue':
- optional: true
- dotenv:
- optional: true
- giget:
- optional: true
- jiti:
- optional: true
- rollup:
- optional: true
- vite:
- optional: true
- xml2js:
- optional: true
- zephyr-agent:
- optional: true
-
- node-releases@2.0.57:
- resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==}
- engines: {node: '>=18'}
-
- ocache@0.1.5:
- resolution: {integrity: sha512-kNNnkkVQup/QDvmTz8Q84wc2ntiyoVHDxa6eHWKt5qdGAmFRBIxy83rxgCYEjW0x06UJ9E3P6VgM2yY4rOBH4w==}
-
- ofetch@2.0.0-alpha.3:
- resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==}
-
- ohash@2.0.12:
- resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==}
-
- oxc-parser@0.120.0:
- resolution: {integrity: sha512-WyPWZlcIm+Fkte63FGfgFB8mAAk33aH9h5N9lphXVOHSXEBFFsmYdOBedVKly363aWABjZdaj/m9lBfEY4wt+w==}
- engines: {node: ^20.19.0 || >=22.12.0}
-
- path-key@3.1.1:
- resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
- engines: {node: '>=8'}
-
- pathe@2.0.3:
- resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
-
- pg-cloudflare@1.4.1:
- resolution: {integrity: sha512-6PQbsFWZcp9EmJEwy5cGQ2La+AMWpP46lgbb8X+U/XsHIUweYDNCpeuKck5RxL2MdVFi7krbbEi5nX4Zh7JhrQ==}
-
- pg-connection-string@2.14.1:
- resolution: {integrity: sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA==}
-
- pg-int8@1.0.1:
- resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
- engines: {node: '>=4.0.0'}
-
- pg-pool@3.14.0:
- resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==}
- peerDependencies:
- pg: '>=8.0'
-
- pg-protocol@1.16.1:
- resolution: {integrity: sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg==}
-
- pg-types@2.2.0:
- resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
- engines: {node: '>=4'}
-
- pg@8.23.1:
- resolution: {integrity: sha512-aL96AHANtWjPLDOLqnhx+ngp9+UK7ETEU8VJrDCGvsSSi/mGLcWYsS6Herg7lmaBJe4uwrfqsa7gTEFaSizDoQ==}
- engines: {node: '>= 16.0.0'}
- peerDependencies:
- pg-native: '>=3.0.1'
- peerDependenciesMeta:
- pg-native:
- optional: true
-
- pgpass@1.0.5:
- resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
-
- picocolors@1.1.1:
- resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
-
- picomatch@4.0.7:
- resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
- engines: {node: '>=12'}
-
- pkce-challenge@5.0.1:
- resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
- engines: {node: '>=16.20.0'}
-
- postcss-selector-parser@6.0.10:
- resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
- engines: {node: '>=4'}
-
- postcss@8.5.28:
- resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==}
- engines: {node: ^10 || ^12 || >=14}
-
- postgres-array@2.0.0:
- resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
- engines: {node: '>=4'}
-
- postgres-bytea@1.0.1:
- resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==}
- engines: {node: '>=0.10.0'}
-
- postgres-date@1.0.7:
- resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
- engines: {node: '>=0.10.0'}
-
- postgres-interval@1.2.0:
- resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
- engines: {node: '>=0.10.0'}
-
- posthog-js@1.436.1:
- resolution: {integrity: sha512-+uPcck+hcaBbjtxBwOtiiZ9BcBXyJmewumUMVP5MrIZO36BHHZ+SzvHTxFsA5soNbPo2fuLppsWfpNnuSjbNeA==}
- peerDependencies:
- '@types/react': '>=16.8.0'
- react: '>=16.8.0'
- peerDependenciesMeta:
- '@types/react':
- optional: true
- react:
- optional: true
-
- posthog-node@5.55.0:
- resolution: {integrity: sha512-8dFtlDTqs0CKGZ8t4mUnk4NdShAgzru3B9D0MfM/NTBzlRyAjctivzWINLtMLRQxYjvgBohxy7RTwiQf4mPycQ==}
- engines: {node: ^20.20.0 || >=22.22.0}
- peerDependencies:
- rxjs: ^7.0.0
- peerDependenciesMeta:
- rxjs:
- optional: true
-
- preact@10.29.8:
- resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==}
- peerDependencies:
- preact-render-to-string: '>=5'
- peerDependenciesMeta:
- preact-render-to-string:
- optional: true
-
- prettier@3.9.9:
- resolution: {integrity: sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==}
- engines: {node: '>=14'}
- hasBin: true
-
- query-selector-shadow-dom@1.0.1:
- resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==}
-
- react-dom@19.3.0:
- resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==}
- peerDependencies:
- react: ^19.3.0
-
- react-is@19.3.0:
- resolution: {integrity: sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==}
-
- react-redux@9.3.0:
- resolution: {integrity: sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==}
- peerDependencies:
- '@types/react': ^18.2.25 || ^19
- react: ^18.0 || ^19
- redux: ^5.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
- redux:
- optional: true
-
- react-remove-scroll-bar@2.3.8:
- resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- react-remove-scroll@2.7.2:
- resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- react-style-singleton@2.2.3:
- resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- react@19.3.0:
- resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==}
- engines: {node: '>=0.10.0'}
-
- readdirp@5.1.1:
- resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==}
- engines: {node: '>= 20.19.0'}
-
- recharts@3.8.0:
- resolution: {integrity: sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==}
- engines: {node: '>=18'}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
- redux-thunk@3.1.0:
- resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
- peerDependencies:
- redux: ^5.0.0
-
- redux@5.0.1:
- resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
-
- require-directory@2.1.1:
- resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
- engines: {node: '>=0.10.0'}
-
- reselect@5.1.1:
- resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
-
- reselect@5.3.0:
- resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==}
-
- resolve-pkg-maps@1.0.0:
- resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
-
- rolldown@1.2.12:
- resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==}
- engines: {node: ^20.19.0 || >=22.12.0}
- hasBin: true
-
- rou3@0.8.1:
- resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==}
-
- rou3@0.9.2:
- resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==}
-
- scheduler@0.28.0:
- resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==}
-
- semver@6.3.1:
- resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
- hasBin: true
-
- seroval-plugins@1.5.6:
- resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==}
- engines: {node: '>=10'}
- peerDependencies:
- seroval: ^1.0
-
- seroval-plugins@1.6.8:
- resolution: {integrity: sha512-N7mWAMydj89EnYTHtRpS3LBrAz3J9O6oVrqpuXuvlAHfAUG8WEKqtbAd7SBiJNY5NfCAFhSdyAh7wI4Shjqy4g==}
- engines: {node: '>=10'}
- peerDependencies:
- seroval: ^1.0
-
- seroval@1.5.6:
- resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==}
- engines: {node: '>=10'}
-
- seroval@1.6.8:
- resolution: {integrity: sha512-HlSgSAkTk4EqHcje1ptJjfZi1YDv5KbhVJ/d3P7T/nAXua2VmDu+AKDX5VTdFfZf48nDkWB2TKYt0DrCSa+3wg==}
- engines: {node: '>=10'}
-
- set-cookie-parser@3.1.2:
- resolution: {integrity: sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==}
-
- shebang-command@2.0.0:
- resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
- engines: {node: '>=8'}
-
- shebang-regex@3.0.0:
- resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
- engines: {node: '>=8'}
-
- shell-quote@1.12.0:
- resolution: {integrity: sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==}
- engines: {node: '>= 0.4'}
-
- simple-icons@16.34.0:
- resolution: {integrity: sha512-UTxKn0PVspk84B2hHF3Dqiqht1yDjJmDc/t4cO7PyCQxCMk6OjEu95pnpGjhLaGeQ4qBrGASbefTIe/+czrX7g==}
- engines: {node: '>=0.12.18'}
-
- solid-js@1.9.15:
- resolution: {integrity: sha512-EeiY2xfpZJqPLjXspVEKjAII4yv8NyG//NxZ3IpOFHdUNnnTyL0uJOeS9LWGvA7cFCz5y94cjFwYlmw5Luncsg==}
-
- source-map-js@1.2.2:
- resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
- engines: {node: '>=0.10.0'}
-
- source-map-support@0.5.21:
- resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
-
- source-map@0.6.1:
- resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
- engines: {node: '>=0.10.0'}
-
- source-map@0.7.6:
- resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
- engines: {node: '>= 12'}
-
- split2@4.2.0:
- resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
- engines: {node: '>= 10.x'}
-
- srvx@0.11.22:
- resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==}
- engines: {node: '>=20.16.0'}
- hasBin: true
-
- string-width@4.2.3:
- resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
- engines: {node: '>=8'}
-
- strip-ansi@6.0.1:
- resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
- engines: {node: '>=8'}
-
- tailwindcss@4.3.3:
- resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==}
-
- tapable@2.3.3:
- resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
- engines: {node: '>=6'}
-
- tiny-invariant@1.3.3:
- resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
-
- tinyglobby@0.2.17:
- resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
- engines: {node: '>=12.0.0'}
-
- tslib@2.8.1:
- resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
-
- tsx@4.23.15:
- resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==}
- engines: {node: '>=18.0.0'}
- hasBin: true
-
- tw-animate-css@1.4.0:
- resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==}
-
- typescript@6.0.3:
- resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
- engines: {node: '>=14.17'}
- hasBin: true
-
- ufo@1.6.4:
- resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
-
- undici-types@6.21.0:
- resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
-
- unenv@2.0.0-rc.24:
- resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
-
- unplugin@3.4.0:
- resolution: {integrity: sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==}
- engines: {node: ^20.19.0 || >=22.12.0}
- peerDependencies:
- '@farmfe/core': '*'
- '@rsbuild/core': '*'
- '@rspack/core': '*'
- bun-types-no-globals: '*'
- esbuild: '*'
- rolldown: '*'
- rollup: '*'
- unloader: '*'
- vite: '*'
- webpack: '*'
- peerDependenciesMeta:
- '@farmfe/core':
- optional: true
- '@rsbuild/core':
- optional: true
- '@rspack/core':
- optional: true
- bun-types-no-globals:
- optional: true
- esbuild:
- optional: true
- rolldown:
- optional: true
- rollup:
- optional: true
- unloader:
- optional: true
- vite:
- optional: true
- webpack:
- optional: true
-
- unstorage@2.0.0-alpha.7:
- resolution: {integrity: sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==}
- peerDependencies:
- '@azure/app-configuration': ^1.11.0
- '@azure/cosmos': ^4.9.1
- '@azure/data-tables': ^13.3.2
- '@azure/identity': ^4.13.0
- '@azure/keyvault-secrets': ^4.10.0
- '@azure/storage-blob': ^12.31.0
- '@capacitor/preferences': ^6 || ^7 || ^8
- '@deno/kv': '>=0.13.0'
- '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0
- '@planetscale/database': ^1.19.0
- '@upstash/redis': ^1.36.2
- '@vercel/blob': '>=0.27.3'
- '@vercel/functions': ^2.2.12 || ^3.0.0
- '@vercel/kv': ^1.0.1
- aws4fetch: ^1.0.20
- chokidar: ^4 || ^5
- db0: '>=0.3.4'
- idb-keyval: ^6.2.2
- ioredis: ^5.9.3
- lru-cache: ^11.2.6
- mongodb: ^6 || ^7
- ofetch: '*'
- uploadthing: ^7.7.4
- peerDependenciesMeta:
- '@azure/app-configuration':
- optional: true
- '@azure/cosmos':
- optional: true
- '@azure/data-tables':
- optional: true
- '@azure/identity':
- optional: true
- '@azure/keyvault-secrets':
- optional: true
- '@azure/storage-blob':
- optional: true
- '@capacitor/preferences':
- optional: true
- '@deno/kv':
- optional: true
- '@netlify/blobs':
- optional: true
- '@planetscale/database':
- optional: true
- '@upstash/redis':
- optional: true
- '@vercel/blob':
- optional: true
- '@vercel/functions':
- optional: true
- '@vercel/kv':
- optional: true
- aws4fetch:
- optional: true
- chokidar:
- optional: true
- db0:
- optional: true
- idb-keyval:
- optional: true
- ioredis:
- optional: true
- lru-cache:
- optional: true
- mongodb:
- optional: true
- ofetch:
- optional: true
- uploadthing:
- optional: true
-
- update-browserslist-db@1.3.3:
- resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==}
- hasBin: true
- peerDependencies:
- browserslist: '>= 4.21.0'
-
- use-callback-ref@1.3.3:
- resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- use-sidecar@1.1.3:
- resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
- engines: {node: '>=10'}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- use-sync-external-store@1.7.0:
- resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
- util-deprecate@1.0.2:
- resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
-
- victory-vendor@37.3.6:
- resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==}
-
- vite@8.3.2:
- resolution: {integrity: sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==}
- engines: {node: ^20.19.0 || >=22.12.0}
- hasBin: true
- peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
- '@vitejs/devtools': ^0.7.1
- esbuild: ^0.27.0 || ^0.28.0
- jiti: '>=1.21.0'
- less: ^4.0.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
- '@vitejs/devtools':
- optional: true
- esbuild:
- optional: true
- jiti:
- optional: true
- less:
- optional: true
- sass:
- optional: true
- sass-embedded:
- optional: true
- stylus:
- optional: true
- sugarss:
- optional: true
- terser:
- optional: true
- tsx:
- optional: true
- yaml:
- optional: true
-
- vitefu@1.1.3:
- resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==}
- peerDependencies:
- vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
- peerDependenciesMeta:
- vite:
- optional: true
-
- web-vitals@6.2.1:
- resolution: {integrity: sha512-rLcLXA2sx6+9dE88NHFubwTtGxpK4yYBLj6qHPdFoCaLr0cXGb4efOqtKLlm4loGA4OEKHIQKMKzZkKyOh5ctw==}
-
- web-vitals@6.2.3:
- resolution: {integrity: sha512-Dmy+vdO1UPMqXiAtZSNayhl4f794Bxfd94W4HIj2HlYtczEQfEOon969memlcpcHrTuOKLa5baFjX7WbgmOq+A==}
-
- webpack-virtual-modules@0.6.2:
- resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
-
- which@2.0.2:
- resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
- engines: {node: '>= 8'}
- hasBin: true
-
- wrap-ansi@7.0.0:
- resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
- engines: {node: '>=10'}
-
- ws@8.22.0:
- resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==}
- engines: {node: '>=10.0.0'}
- peerDependencies:
- bufferutil: ^4.0.1
- utf-8-validate: '>=5.0.2'
- peerDependenciesMeta:
- bufferutil:
- optional: true
- utf-8-validate:
- optional: true
-
- xmlbuilder2@4.0.3:
- resolution: {integrity: sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==}
- engines: {node: '>=20.0'}
-
- xtend@4.0.2:
- resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
- engines: {node: '>=0.4'}
-
- y18n@5.0.8:
- resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
- engines: {node: '>=10'}
-
- yallist@3.1.1:
- resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
-
- yargs-parser@21.1.1:
- resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
- engines: {node: '>=12'}
-
- yargs@17.7.3:
- resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==}
- engines: {node: '>=12'}
-
- zod@4.6.5:
- resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==}
-
-snapshots:
-
- '@babel/code-frame@7.29.7':
- dependencies:
- '@babel/helper-validator-identifier': 7.29.7
- js-tokens: 4.0.0
- picocolors: 1.1.1
-
- '@babel/compat-data@7.29.7': {}
-
- '@babel/core@7.29.7':
- dependencies:
- '@babel/code-frame': 7.29.7
- '@babel/generator': 7.29.8
- '@babel/helper-compilation-targets': 7.29.7
- '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7)
- '@babel/helpers': 7.29.7
- '@babel/parser': 7.29.9
- '@babel/template': 7.29.7
- '@babel/traverse': 7.29.8
- '@babel/types': 7.29.8
- '@jridgewell/remapping': 2.3.5
- convert-source-map: 2.0.0
- debug: 4.4.3
- gensync: 1.0.0-beta.2
- json5: 2.2.3
- semver: 6.3.1
- transitivePeerDependencies:
- - supports-color
-
- '@babel/generator@7.29.8':
- dependencies:
- '@babel/parser': 7.29.9
- '@babel/types': 7.29.8
- '@jridgewell/gen-mapping': 0.3.13
- '@jridgewell/trace-mapping': 0.3.31
- jsesc: 3.1.0
-
- '@babel/helper-compilation-targets@7.29.7':
- dependencies:
- '@babel/compat-data': 7.29.7
- '@babel/helper-validator-option': 7.29.7
- browserslist: 4.29.3
- lru-cache: 5.1.1
- semver: 6.3.1
-
- '@babel/helper-globals@7.29.7': {}
-
- '@babel/helper-module-imports@7.29.7':
- dependencies:
- '@babel/traverse': 7.29.8
- '@babel/types': 7.29.8
- transitivePeerDependencies:
- - supports-color
-
- '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
- dependencies:
- '@babel/core': 7.29.7
- '@babel/helper-module-imports': 7.29.7
- '@babel/helper-validator-identifier': 7.29.7
- '@babel/traverse': 7.29.8
- transitivePeerDependencies:
- - supports-color
-
- '@babel/helper-string-parser@7.29.7': {}
-
- '@babel/helper-validator-identifier@7.29.7': {}
-
- '@babel/helper-validator-option@7.29.7': {}
-
- '@babel/helpers@7.29.7':
- dependencies:
- '@babel/template': 7.29.7
- '@babel/types': 7.29.8
-
- '@babel/parser@7.29.9':
- dependencies:
- '@babel/types': 7.29.8
-
- '@babel/runtime@7.29.7': {}
-
- '@babel/template@7.29.7':
- dependencies:
- '@babel/code-frame': 7.29.7
- '@babel/parser': 7.29.9
- '@babel/types': 7.29.8
-
- '@babel/traverse@7.29.8':
- dependencies:
- '@babel/code-frame': 7.29.7
- '@babel/generator': 7.29.8
- '@babel/helper-globals': 7.29.7
- '@babel/parser': 7.29.9
- '@babel/template': 7.29.7
- '@babel/types': 7.29.8
- debug: 4.4.3
- transitivePeerDependencies:
- - supports-color
-
- '@babel/types@7.29.8':
- dependencies:
- '@babel/helper-string-parser': 7.29.7
- '@babel/helper-validator-identifier': 7.29.7
-
- '@base-ui/react@1.8.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@babel/runtime': 7.29.7
- '@base-ui/utils': 0.4.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@floating-ui/react-dom': 2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@floating-ui/utils': 0.2.12
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- use-sync-external-store: 1.7.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@base-ui/utils@0.4.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@babel/runtime': 7.29.7
- '@floating-ui/utils': 0.2.12
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- reselect: 5.3.0
- use-sync-external-store: 1.7.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)':
- dependencies:
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- '@opentelemetry/semantic-conventions': 1.43.0
- '@standard-schema/spec': 1.1.0
- better-call: 1.4.0(zod@4.6.5)
- jose: 6.2.12
- kysely: 0.29.6
- nanostores: 1.5.4
- zod: 4.6.5
- optionalDependencies:
- '@opentelemetry/api': 1.9.1
-
- '@better-auth/drizzle-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))':
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/utils': 0.4.2
- optionalDependencies:
- drizzle-orm: 0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)
-
- '@better-auth/kysely-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(kysely@0.29.6)':
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/utils': 0.4.2
- optionalDependencies:
- kysely: 0.29.6
-
- '@better-auth/memory-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)':
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/utils': 0.4.2
-
- '@better-auth/mongo-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)':
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/utils': 0.4.2
-
- '@better-auth/prisma-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)':
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/utils': 0.4.2
-
- '@better-auth/telemetry@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)':
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
-
- '@better-auth/utils@0.4.2':
- dependencies:
- '@noble/hashes': 2.4.0
-
- '@better-auth/utils@0.5.0':
- dependencies:
- '@noble/hashes': 2.4.0
-
- '@better-fetch/fetch@1.3.2': {}
-
- '@biomejs/biome@2.4.5':
- optionalDependencies:
- '@biomejs/cli-darwin-arm64': 2.4.5
- '@biomejs/cli-darwin-x64': 2.4.5
- '@biomejs/cli-linux-arm64': 2.4.5
- '@biomejs/cli-linux-arm64-musl': 2.4.5
- '@biomejs/cli-linux-x64': 2.4.5
- '@biomejs/cli-linux-x64-musl': 2.4.5
- '@biomejs/cli-win32-arm64': 2.4.5
- '@biomejs/cli-win32-x64': 2.4.5
-
- '@biomejs/cli-darwin-arm64@2.4.5':
- optional: true
-
- '@biomejs/cli-darwin-x64@2.4.5':
- optional: true
-
- '@biomejs/cli-linux-arm64-musl@2.4.5':
- optional: true
-
- '@biomejs/cli-linux-arm64@2.4.5':
- optional: true
-
- '@biomejs/cli-linux-x64-musl@2.4.5':
- optional: true
-
- '@biomejs/cli-linux-x64@2.4.5':
- optional: true
-
- '@biomejs/cli-win32-arm64@2.4.5':
- optional: true
-
- '@biomejs/cli-win32-x64@2.4.5':
- optional: true
-
- '@drizzle-team/brocli@0.10.2': {}
-
- '@electric-sql/pglite@0.5.8': {}
-
- '@emnapi/core@1.11.3':
- dependencies:
- '@emnapi/wasi-threads': 1.2.3
- tslib: 2.8.1
- optional: true
-
- '@emnapi/runtime@1.11.3':
- dependencies:
- tslib: 2.8.1
- optional: true
-
- '@emnapi/wasi-threads@1.2.3':
- dependencies:
- tslib: 2.8.1
- optional: true
-
- '@esbuild-kit/core-utils@3.3.2':
- dependencies:
- esbuild: 0.18.20
- source-map-support: 0.5.21
-
- '@esbuild-kit/esm-loader@2.6.5':
- dependencies:
- '@esbuild-kit/core-utils': 3.3.2
- get-tsconfig: 4.14.3
-
- '@esbuild/aix-ppc64@0.25.12':
- optional: true
-
- '@esbuild/aix-ppc64@0.28.2':
- optional: true
-
- '@esbuild/android-arm64@0.18.20':
- optional: true
-
- '@esbuild/android-arm64@0.25.12':
- optional: true
-
- '@esbuild/android-arm64@0.28.2':
- optional: true
-
- '@esbuild/android-arm@0.18.20':
- optional: true
-
- '@esbuild/android-arm@0.25.12':
- optional: true
-
- '@esbuild/android-arm@0.28.2':
- optional: true
-
- '@esbuild/android-x64@0.18.20':
- optional: true
-
- '@esbuild/android-x64@0.25.12':
- optional: true
-
- '@esbuild/android-x64@0.28.2':
- optional: true
-
- '@esbuild/darwin-arm64@0.18.20':
- optional: true
-
- '@esbuild/darwin-arm64@0.25.12':
- optional: true
-
- '@esbuild/darwin-arm64@0.28.2':
- optional: true
-
- '@esbuild/darwin-x64@0.18.20':
- optional: true
-
- '@esbuild/darwin-x64@0.25.12':
- optional: true
-
- '@esbuild/darwin-x64@0.28.2':
- optional: true
-
- '@esbuild/freebsd-arm64@0.18.20':
- optional: true
-
- '@esbuild/freebsd-arm64@0.25.12':
- optional: true
-
- '@esbuild/freebsd-arm64@0.28.2':
- optional: true
-
- '@esbuild/freebsd-x64@0.18.20':
- optional: true
-
- '@esbuild/freebsd-x64@0.25.12':
- optional: true
-
- '@esbuild/freebsd-x64@0.28.2':
- optional: true
-
- '@esbuild/linux-arm64@0.18.20':
- optional: true
-
- '@esbuild/linux-arm64@0.25.12':
- optional: true
-
- '@esbuild/linux-arm64@0.28.2':
- optional: true
-
- '@esbuild/linux-arm@0.18.20':
- optional: true
-
- '@esbuild/linux-arm@0.25.12':
- optional: true
-
- '@esbuild/linux-arm@0.28.2':
- optional: true
-
- '@esbuild/linux-ia32@0.18.20':
- optional: true
-
- '@esbuild/linux-ia32@0.25.12':
- optional: true
-
- '@esbuild/linux-ia32@0.28.2':
- optional: true
-
- '@esbuild/linux-loong64@0.18.20':
- optional: true
-
- '@esbuild/linux-loong64@0.25.12':
- optional: true
-
- '@esbuild/linux-loong64@0.28.2':
- optional: true
-
- '@esbuild/linux-mips64el@0.18.20':
- optional: true
-
- '@esbuild/linux-mips64el@0.25.12':
- optional: true
-
- '@esbuild/linux-mips64el@0.28.2':
- optional: true
-
- '@esbuild/linux-ppc64@0.18.20':
- optional: true
-
- '@esbuild/linux-ppc64@0.25.12':
- optional: true
-
- '@esbuild/linux-ppc64@0.28.2':
- optional: true
-
- '@esbuild/linux-riscv64@0.18.20':
- optional: true
-
- '@esbuild/linux-riscv64@0.25.12':
- optional: true
-
- '@esbuild/linux-riscv64@0.28.2':
- optional: true
-
- '@esbuild/linux-s390x@0.18.20':
- optional: true
-
- '@esbuild/linux-s390x@0.25.12':
- optional: true
-
- '@esbuild/linux-s390x@0.28.2':
- optional: true
-
- '@esbuild/linux-x64@0.18.20':
- optional: true
-
- '@esbuild/linux-x64@0.25.12':
- optional: true
-
- '@esbuild/linux-x64@0.28.2':
- optional: true
-
- '@esbuild/netbsd-arm64@0.25.12':
- optional: true
-
- '@esbuild/netbsd-arm64@0.28.2':
- optional: true
-
- '@esbuild/netbsd-x64@0.18.20':
- optional: true
-
- '@esbuild/netbsd-x64@0.25.12':
- optional: true
-
- '@esbuild/netbsd-x64@0.28.2':
- optional: true
-
- '@esbuild/openbsd-arm64@0.25.12':
- optional: true
-
- '@esbuild/openbsd-arm64@0.28.2':
- optional: true
-
- '@esbuild/openbsd-x64@0.18.20':
- optional: true
-
- '@esbuild/openbsd-x64@0.25.12':
- optional: true
-
- '@esbuild/openbsd-x64@0.28.2':
- optional: true
-
- '@esbuild/openharmony-arm64@0.25.12':
- optional: true
-
- '@esbuild/openharmony-arm64@0.28.2':
- optional: true
-
- '@esbuild/sunos-x64@0.18.20':
- optional: true
-
- '@esbuild/sunos-x64@0.25.12':
- optional: true
-
- '@esbuild/sunos-x64@0.28.2':
- optional: true
-
- '@esbuild/win32-arm64@0.18.20':
- optional: true
-
- '@esbuild/win32-arm64@0.25.12':
- optional: true
-
- '@esbuild/win32-arm64@0.28.2':
- optional: true
-
- '@esbuild/win32-ia32@0.18.20':
- optional: true
-
- '@esbuild/win32-ia32@0.25.12':
- optional: true
-
- '@esbuild/win32-ia32@0.28.2':
- optional: true
-
- '@esbuild/win32-x64@0.18.20':
- optional: true
-
- '@esbuild/win32-x64@0.25.12':
- optional: true
-
- '@esbuild/win32-x64@0.28.2':
- optional: true
-
- '@floating-ui/core@1.8.0':
- dependencies:
- '@floating-ui/utils': 0.2.12
-
- '@floating-ui/dom@1.8.0':
- dependencies:
- '@floating-ui/core': 1.8.0
- '@floating-ui/utils': 0.2.12
-
- '@floating-ui/react-dom@2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@floating-ui/dom': 1.8.0
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
-
- '@floating-ui/utils@0.2.12': {}
-
- '@fontsource-variable/geist@5.3.0': {}
-
- '@jridgewell/gen-mapping@0.3.13':
- dependencies:
- '@jridgewell/sourcemap-codec': 1.6.0
- '@jridgewell/trace-mapping': 0.3.31
-
- '@jridgewell/remapping@2.3.5':
- dependencies:
- '@jridgewell/gen-mapping': 0.3.13
- '@jridgewell/trace-mapping': 0.3.31
-
- '@jridgewell/resolve-uri@3.1.2': {}
-
- '@jridgewell/sourcemap-codec@1.6.0': {}
-
- '@jridgewell/trace-mapping@0.3.31':
- dependencies:
- '@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.6.0
-
- '@modelcontextprotocol/client@2.3.1':
- dependencies:
- '@modelcontextprotocol/core': 2.3.1
- cross-spawn: 7.0.6
- eventsource: 3.0.7
- eventsource-parser: 3.1.1
- jose: 6.2.12
- pkce-challenge: 5.0.1
- zod: 4.6.5
-
- '@modelcontextprotocol/core@2.3.1':
- dependencies:
- zod: 4.6.5
-
- '@modelcontextprotocol/server@2.3.1':
- dependencies:
- '@modelcontextprotocol/core': 2.3.1
- zod: 4.6.5
-
- '@napi-rs/wasm-runtime@1.2.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)':
- dependencies:
- '@emnapi/core': 1.11.3
- '@emnapi/runtime': 1.11.3
- '@tybys/wasm-util': 0.10.4
- optional: true
-
- '@neodrag/core@3.0.0-next.11': {}
-
- '@neodrag/solid@3.0.0-next.11(@neodrag/core@3.0.0-next.11)(solid-js@1.9.15)':
- dependencies:
- '@neodrag/core': 3.0.0-next.11
- solid-js: 1.9.15
-
- '@noble/ciphers@2.4.0': {}
-
- '@noble/hashes@2.4.0': {}
-
- '@oozcitak/dom@2.0.2':
- dependencies:
- '@oozcitak/infra': 2.0.2
- '@oozcitak/url': 3.0.0
- '@oozcitak/util': 10.0.0
-
- '@oozcitak/infra@2.0.2':
- dependencies:
- '@oozcitak/util': 10.0.0
-
- '@oozcitak/url@3.0.0':
- dependencies:
- '@oozcitak/infra': 2.0.2
- '@oozcitak/util': 10.0.0
-
- '@oozcitak/util@10.0.0': {}
-
- '@opentelemetry/api-logs@0.222.0':
- dependencies:
- '@opentelemetry/api': 1.9.1
-
- '@opentelemetry/api@1.9.1': {}
-
- '@opentelemetry/core@2.11.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/semantic-conventions': 1.43.0
-
- '@opentelemetry/exporter-logs-otlp-http@0.222.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.1)
-
- '@opentelemetry/exporter-trace-otlp-http@0.222.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.1)
-
- '@opentelemetry/otlp-exporter-base@0.222.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.1)
-
- '@opentelemetry/otlp-transformer@0.222.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/api-logs': 0.222.0
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-metrics': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.1)
-
- '@opentelemetry/resources@2.11.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/semantic-conventions': 1.43.0
-
- '@opentelemetry/sdk-logs@0.222.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/api-logs': 0.222.0
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/semantic-conventions': 1.43.0
-
- '@opentelemetry/sdk-metrics@2.11.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.1)
-
- '@opentelemetry/sdk-trace-base@2.11.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/semantic-conventions': 1.43.0
-
- '@opentelemetry/sdk-trace@2.11.0(@opentelemetry/api@1.9.1)':
- dependencies:
- '@opentelemetry/api': 1.9.1
- '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.1)
- '@opentelemetry/semantic-conventions': 1.43.0
-
- '@opentelemetry/semantic-conventions@1.43.0': {}
-
- '@oxc-parser/binding-android-arm-eabi@0.120.0':
- optional: true
-
- '@oxc-parser/binding-android-arm64@0.120.0':
- optional: true
-
- '@oxc-parser/binding-darwin-arm64@0.120.0':
- optional: true
-
- '@oxc-parser/binding-darwin-x64@0.120.0':
- optional: true
-
- '@oxc-parser/binding-freebsd-x64@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-arm-gnueabihf@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-arm-musleabihf@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-arm64-gnu@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-arm64-musl@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-ppc64-gnu@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-riscv64-gnu@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-riscv64-musl@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-s390x-gnu@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-x64-gnu@0.120.0':
- optional: true
-
- '@oxc-parser/binding-linux-x64-musl@0.120.0':
- optional: true
-
- '@oxc-parser/binding-openharmony-arm64@0.120.0':
- optional: true
-
- '@oxc-parser/binding-wasm32-wasi@0.120.0(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)':
- dependencies:
- '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
- transitivePeerDependencies:
- - '@emnapi/core'
- - '@emnapi/runtime'
- optional: true
-
- '@oxc-parser/binding-win32-arm64-msvc@0.120.0':
- optional: true
-
- '@oxc-parser/binding-win32-ia32-msvc@0.120.0':
- optional: true
-
- '@oxc-parser/binding-win32-x64-msvc@0.120.0':
- optional: true
-
- '@oxc-project/types@0.120.0': {}
-
- '@oxc-project/types@0.152.0': {}
-
- '@posthog/browser-common@0.9.1':
- dependencies:
- '@posthog/core': 1.56.0
- '@posthog/types': 1.413.0
-
- '@posthog/core@1.56.0':
- dependencies:
- '@posthog/types': 1.413.0
-
- '@posthog/types@1.413.0': {}
-
- '@radix-ui/primitive@1.1.7': {}
-
- '@radix-ui/react-compose-refs@1.1.5(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-context@1.2.2(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-dialog@1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@radix-ui/primitive': 1.1.7
- '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-context': 1.2.2(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-dismissable-layer': 1.1.20(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-focus-scope': 1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-id': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-portal': 1.1.18(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-presence': 1.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-slot': 1.4.0(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- aria-hidden: 1.2.6
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- react-remove-scroll: 2.7.2(@types/react@19.3.0)(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
-
- '@radix-ui/react-dismissable-layer@1.1.20(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@radix-ui/primitive': 1.1.7
- '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
-
- '@radix-ui/react-focus-guards@1.1.6(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-focus-scope@1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
-
- '@radix-ui/react-id@1.1.4(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-portal@1.1.18(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
-
- '@radix-ui/react-presence@1.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
-
- '@radix-ui/react-primitive@2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@radix-ui/react-slot': 1.4.0(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
-
- '@radix-ui/react-slot@1.4.0(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-use-callback-ref@1.1.4(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-use-controllable-state@1.2.6(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- '@radix-ui/primitive': 1.1.7
- '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-use-effect-event@0.0.5(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@radix-ui/react-use-layout-effect@1.1.4(@types/react@19.3.0)(react@19.3.0)':
- dependencies:
- react: 19.3.0
- optionalDependencies:
- '@types/react': 19.3.0
-
- '@reduxjs/toolkit@2.13.0(react-redux@9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1))(react@19.3.0)':
- dependencies:
- '@standard-schema/spec': 1.1.0
- '@standard-schema/utils': 0.3.0
- immer: 11.1.21
- redux: 5.0.1
- redux-thunk: 3.1.0(redux@5.0.1)
- reselect: 5.3.0
- optionalDependencies:
- react: 19.3.0
- react-redux: 9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1)
-
- '@resvg/resvg-wasm@2.6.2': {}
-
- '@rolldown/binding-android-arm-eabi@1.2.12':
- optional: true
-
- '@rolldown/binding-android-arm64@1.2.12':
- optional: true
-
- '@rolldown/binding-darwin-arm64@1.2.12':
- optional: true
-
- '@rolldown/binding-darwin-x64@1.2.12':
- optional: true
-
- '@rolldown/binding-freebsd-x64@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-arm-gnueabihf@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-arm64-gnu@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-arm64-musl@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-ppc64-gnu@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-s390x-gnu@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-x64-gnu@1.2.12':
- optional: true
-
- '@rolldown/binding-linux-x64-musl@1.2.12':
- optional: true
-
- '@rolldown/binding-openharmony-arm64@1.2.12':
- optional: true
-
- '@rolldown/binding-win32-arm64-msvc@1.2.12':
- optional: true
-
- '@rolldown/binding-win32-x64-msvc@1.2.12':
- optional: true
-
- '@rolldown/pluginutils@1.0.1': {}
-
- '@solid-primitives/event-listener@2.4.6(solid-js@1.9.15)':
- dependencies:
- '@solid-primitives/utils': 6.4.1(solid-js@1.9.15)
- solid-js: 1.9.15
-
- '@solid-primitives/keyboard@1.3.7(solid-js@1.9.15)':
- dependencies:
- '@solid-primitives/event-listener': 2.4.6(solid-js@1.9.15)
- '@solid-primitives/rootless': 1.5.4(solid-js@1.9.15)
- '@solid-primitives/utils': 6.4.1(solid-js@1.9.15)
- solid-js: 1.9.15
-
- '@solid-primitives/resize-observer@2.2.0(solid-js@1.9.15)':
- dependencies:
- '@solid-primitives/event-listener': 2.4.6(solid-js@1.9.15)
- '@solid-primitives/rootless': 1.5.4(solid-js@1.9.15)
- '@solid-primitives/static-store': 0.1.4(solid-js@1.9.15)
- '@solid-primitives/utils': 6.4.1(solid-js@1.9.15)
- solid-js: 1.9.15
-
- '@solid-primitives/rootless@1.5.4(solid-js@1.9.15)':
- dependencies:
- '@solid-primitives/utils': 6.4.1(solid-js@1.9.15)
- solid-js: 1.9.15
-
- '@solid-primitives/static-store@0.1.4(solid-js@1.9.15)':
- dependencies:
- '@solid-primitives/utils': 6.4.1(solid-js@1.9.15)
- solid-js: 1.9.15
-
- '@solid-primitives/utils@6.4.1(solid-js@1.9.15)':
- dependencies:
- solid-js: 1.9.15
-
- '@standard-schema/spec@1.1.0': {}
-
- '@standard-schema/utils@0.3.0': {}
-
- '@tailwindcss/node@4.3.3':
- dependencies:
- '@jridgewell/remapping': 2.3.5
- enhanced-resolve: 5.26.0
- jiti: 2.7.0
- lightningcss: 1.32.0
- magic-string: 0.30.21
- source-map-js: 1.2.2
- tailwindcss: 4.3.3
-
- '@tailwindcss/oxide-android-arm64@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-darwin-arm64@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-darwin-x64@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-freebsd-x64@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-linux-arm64-gnu@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-linux-arm64-musl@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-linux-x64-gnu@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-linux-x64-musl@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-wasm32-wasi@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-win32-arm64-msvc@4.3.3':
- optional: true
-
- '@tailwindcss/oxide-win32-x64-msvc@4.3.3':
- optional: true
-
- '@tailwindcss/oxide@4.3.3':
- optionalDependencies:
- '@tailwindcss/oxide-android-arm64': 4.3.3
- '@tailwindcss/oxide-darwin-arm64': 4.3.3
- '@tailwindcss/oxide-darwin-x64': 4.3.3
- '@tailwindcss/oxide-freebsd-x64': 4.3.3
- '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3
- '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3
- '@tailwindcss/oxide-linux-arm64-musl': 4.3.3
- '@tailwindcss/oxide-linux-x64-gnu': 4.3.3
- '@tailwindcss/oxide-linux-x64-musl': 4.3.3
- '@tailwindcss/oxide-wasm32-wasi': 4.3.3
- '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3
- '@tailwindcss/oxide-win32-x64-msvc': 4.3.3
-
- '@tailwindcss/typography@0.5.20(tailwindcss@4.3.3)':
- dependencies:
- postcss-selector-parser: 6.0.10
- tailwindcss: 4.3.3
-
- '@tailwindcss/vite@4.3.3(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@tailwindcss/node': 4.3.3
- '@tailwindcss/oxide': 4.3.3
- tailwindcss: 4.3.3
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
-
- '@tanstack/devtools-bundler-core@0.1.3(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)':
- dependencies:
- '@tanstack/devtools-client': 0.0.8
- '@tanstack/devtools-event-bus': 0.4.3
- chalk: 5.6.2
- launch-editor: 2.14.1
- magic-string: 0.30.21
- oxc-parser: 0.120.0(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
- picomatch: 4.0.7
- transitivePeerDependencies:
- - '@emnapi/core'
- - '@emnapi/runtime'
- - bufferutil
- - utf-8-validate
-
- '@tanstack/devtools-client@0.0.8':
- dependencies:
- '@tanstack/devtools-event-client': 0.5.0
-
- '@tanstack/devtools-event-bus@0.4.3':
- dependencies:
- ws: 8.22.0
- transitivePeerDependencies:
- - bufferutil
- - utf-8-validate
-
- '@tanstack/devtools-event-client@0.5.0': {}
-
- '@tanstack/devtools-ui@0.7.1(csstype@3.2.3)(solid-js@1.9.15)':
- dependencies:
- clsx: 2.1.1
- dayjs: 1.11.23
- goober: 2.1.19(csstype@3.2.3)
- solid-js: 1.9.15
- transitivePeerDependencies:
- - csstype
-
- '@tanstack/devtools-vite@0.8.5(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@tanstack/devtools-bundler-core': 0.1.3(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
- '@tanstack/devtools-client': 0.0.8
- '@tanstack/devtools-event-bus': 0.4.3
- chalk: 5.6.2
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
- transitivePeerDependencies:
- - '@emnapi/core'
- - '@emnapi/runtime'
- - bufferutil
- - utf-8-validate
-
- '@tanstack/devtools@0.15.0(csstype@3.2.3)(solid-js@1.9.15)':
- dependencies:
- '@neodrag/core': 3.0.0-next.11
- '@neodrag/solid': 3.0.0-next.11(@neodrag/core@3.0.0-next.11)(solid-js@1.9.15)
- '@solid-primitives/event-listener': 2.4.6(solid-js@1.9.15)
- '@solid-primitives/keyboard': 1.3.7(solid-js@1.9.15)
- '@solid-primitives/resize-observer': 2.2.0(solid-js@1.9.15)
- '@tanstack/devtools-client': 0.0.8
- '@tanstack/devtools-event-bus': 0.4.3
- '@tanstack/devtools-ui': 0.7.1(csstype@3.2.3)(solid-js@1.9.15)
- clsx: 2.1.1
- goober: 2.1.19(csstype@3.2.3)
- solid-js: 1.9.15
- transitivePeerDependencies:
- - bufferutil
- - csstype
- - utf-8-validate
-
- '@tanstack/history@1.162.4': {}
-
- '@tanstack/intent@0.5.4': {}
-
- '@tanstack/react-devtools@0.10.13(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(csstype@3.2.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(solid-js@1.9.15)':
- dependencies:
- '@tanstack/devtools': 0.15.0(csstype@3.2.3)(solid-js@1.9.15)
- '@types/react': 19.3.0
- '@types/react-dom': 19.3.0(@types/react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- transitivePeerDependencies:
- - bufferutil
- - csstype
- - solid-js
- - utf-8-validate
-
- '@tanstack/react-router-devtools@1.167.2(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(@tanstack/router-core@1.171.34)(csstype@3.2.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@tanstack/react-router': 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/router-devtools-core': 1.168.2(@tanstack/router-core@1.171.34)(csstype@3.2.3)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- '@tanstack/router-core': 1.171.34
- transitivePeerDependencies:
- - csstype
-
- '@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@tanstack/history': 1.162.4
- '@tanstack/react-store': 0.11.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/router-core': 1.171.34
- isbot: 5.2.2
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
-
- '@tanstack/react-start-client@1.168.39(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@tanstack/react-router': 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/router-core': 1.171.34
- '@tanstack/start-client-core': 1.170.34
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
-
- '@tanstack/react-start-rsc@0.1.59(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@tanstack/react-router': 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/router-core': 1.171.34
- '@tanstack/router-utils': 1.162.3
- '@tanstack/start-client-core': 1.170.34
- '@tanstack/start-fn-stubs': 1.162.0
- '@tanstack/start-plugin-core': 1.171.49(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- '@tanstack/start-storage-context': 1.167.36
- pathe: 2.0.3
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- transitivePeerDependencies:
- - '@farmfe/core'
- - '@rsbuild/core'
- - bun-types-no-globals
- - crossws
- - esbuild
- - rolldown
- - rollup
- - supports-color
- - unloader
- - vite
- - vite-plugin-solid
- - webpack
-
- '@tanstack/react-start-server@1.167.46(crossws@0.4.12(srvx@0.11.22))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@tanstack/react-router': 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/router-core': 1.171.34
- '@tanstack/start-server-core': 1.169.39(crossws@0.4.12(srvx@0.11.22))
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- transitivePeerDependencies:
- - crossws
-
- '@tanstack/react-start@1.168.60(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@tanstack/react-router': 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/react-start-client': 1.168.39(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/react-start-rsc': 0.1.59(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- '@tanstack/react-start-server': 1.167.46(crossws@0.4.12(srvx@0.11.22))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@tanstack/router-utils': 1.162.3
- '@tanstack/start-client-core': 1.170.34
- '@tanstack/start-plugin-core': 1.171.49(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- '@tanstack/start-server-core': 1.169.39(crossws@0.4.12(srvx@0.11.22))
- pathe: 2.0.3
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- optionalDependencies:
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
- transitivePeerDependencies:
- - '@farmfe/core'
- - '@rspack/core'
- - bun-types-no-globals
- - crossws
- - esbuild
- - react-server-dom-rspack
- - rolldown
- - rollup
- - supports-color
- - unloader
- - vite-plugin-solid
- - webpack
-
- '@tanstack/react-store@0.11.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
- dependencies:
- '@tanstack/store': 0.11.2
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- use-sync-external-store: 1.7.0(react@19.3.0)
-
- '@tanstack/router-cli@1.167.40':
- dependencies:
- '@tanstack/router-generator': 1.167.40
- chokidar: 5.0.0
- yargs: 17.7.3
- transitivePeerDependencies:
- - supports-color
-
- '@tanstack/router-core@1.171.34':
- dependencies:
- '@tanstack/history': 1.162.4
- cookie-es: 3.1.1
- seroval: 1.6.8
- seroval-plugins: 1.6.8(seroval@1.6.8)
-
- '@tanstack/router-devtools-core@1.168.2(@tanstack/router-core@1.171.34)(csstype@3.2.3)':
- dependencies:
- '@tanstack/router-core': 1.171.34
- clsx: 2.1.1
- goober: 2.1.19(csstype@3.2.3)
- optionalDependencies:
- csstype: 3.2.3
-
- '@tanstack/router-generator@1.167.40':
- dependencies:
- '@babel/types': 7.29.8
- '@tanstack/router-core': 1.171.34
- '@tanstack/router-utils': 1.162.3
- '@tanstack/virtual-file-routes': 1.162.0
- jiti: 2.7.0
- magic-string: 0.30.21
- prettier: 3.9.9
- zod: 4.6.5
- transitivePeerDependencies:
- - supports-color
-
- '@tanstack/router-plugin@1.168.42(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@babel/core': 7.29.7
- '@babel/template': 7.29.7
- '@babel/types': 7.29.8
- '@tanstack/router-core': 1.171.34
- '@tanstack/router-generator': 1.167.40
- '@tanstack/router-utils': 1.162.3
- chokidar: 5.0.0
- unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- zod: 4.6.5
- optionalDependencies:
- '@tanstack/react-router': 1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
- transitivePeerDependencies:
- - '@farmfe/core'
- - '@rspack/core'
- - bun-types-no-globals
- - esbuild
- - rolldown
- - rollup
- - supports-color
- - unloader
-
- '@tanstack/router-utils@1.162.3':
- dependencies:
- '@babel/generator': 7.29.8
- '@babel/parser': 7.29.9
- '@babel/types': 7.29.8
- ansis: 4.4.0
- babel-dead-code-elimination: 1.0.12
- diff: 8.0.4
- pathe: 2.0.3
- tinyglobby: 0.2.17
- transitivePeerDependencies:
- - supports-color
-
- '@tanstack/start-client-core@1.170.34':
- dependencies:
- '@tanstack/router-core': 1.171.34
- '@tanstack/start-fn-stubs': 1.162.0
- '@tanstack/start-storage-context': 1.167.36
- seroval: 1.6.8
-
- '@tanstack/start-fn-stubs@1.162.0': {}
-
- '@tanstack/start-plugin-core@1.171.49(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@babel/code-frame': 7.29.7
- '@babel/core': 7.29.7
- '@babel/types': 7.29.8
- '@jridgewell/remapping': 2.3.5
- '@tanstack/router-core': 1.171.34
- '@tanstack/router-generator': 1.167.40
- '@tanstack/router-plugin': 1.168.42(@tanstack/react-router@1.170.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- '@tanstack/router-utils': 1.162.3
- '@tanstack/start-server-core': 1.169.39(crossws@0.4.12(srvx@0.11.22))
- exsolve: 1.1.3
- lightningcss: 1.33.0
- pathe: 2.0.3
- picomatch: 4.0.7
- seroval: 1.6.8
- source-map: 0.7.6
- srvx: 0.11.22
- tinyglobby: 0.2.17
- ufo: 1.6.4
- vitefu: 1.1.3(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- xmlbuilder2: 4.0.3
- zod: 4.6.5
- optionalDependencies:
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
- transitivePeerDependencies:
- - '@farmfe/core'
- - '@rspack/core'
- - '@tanstack/react-router'
- - bun-types-no-globals
- - crossws
- - esbuild
- - rolldown
- - rollup
- - supports-color
- - unloader
- - vite-plugin-solid
- - webpack
-
- '@tanstack/start-server-core@1.169.39(crossws@0.4.12(srvx@0.11.22))':
- dependencies:
- '@tanstack/history': 1.162.4
- '@tanstack/router-core': 1.171.34
- '@tanstack/start-client-core': 1.170.34
- '@tanstack/start-storage-context': 1.167.36
- fetchdts: 0.1.7
- h3-v2: h3@2.0.1-rc.20(crossws@0.4.12(srvx@0.11.22))
- seroval: 1.6.8
- transitivePeerDependencies:
- - crossws
-
- '@tanstack/start-storage-context@1.167.36':
- dependencies:
- '@tanstack/router-core': 1.171.34
-
- '@tanstack/store@0.11.2': {}
-
- '@tanstack/virtual-file-routes@1.162.0': {}
-
- '@tybys/wasm-util@0.10.4':
- dependencies:
- tslib: 2.8.1
- optional: true
-
- '@types/d3-array@3.2.2': {}
-
- '@types/d3-color@3.1.3': {}
-
- '@types/d3-ease@3.0.2': {}
-
- '@types/d3-interpolate@3.0.4':
- dependencies:
- '@types/d3-color': 3.1.3
-
- '@types/d3-path@3.1.1': {}
-
- '@types/d3-scale@4.0.9':
- dependencies:
- '@types/d3-time': 3.0.4
-
- '@types/d3-shape@3.2.0':
- dependencies:
- '@types/d3-path': 3.1.1
-
- '@types/d3-time@3.0.4': {}
-
- '@types/d3-timer@3.0.2': {}
-
- '@types/node@22.20.5':
- dependencies:
- undici-types: 6.21.0
-
- '@types/pg@8.23.1':
- dependencies:
- '@types/node': 22.20.5
- pg-protocol: 1.16.1
- pg-types: 2.2.0
-
- '@types/react-dom@19.3.0(@types/react@19.3.0)':
- dependencies:
- '@types/react': 19.3.0
-
- '@types/react@19.3.0':
- dependencies:
- csstype: 3.2.3
-
- '@types/trusted-types@2.0.7':
- optional: true
-
- '@types/use-sync-external-store@0.0.6': {}
-
- '@vitejs/plugin-react@6.1.1(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))':
- dependencies:
- '@rolldown/pluginutils': 1.0.1
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
-
- ansi-regex@5.0.1: {}
-
- ansi-styles@4.3.0:
- dependencies:
- color-convert: 2.0.1
-
- ansis@4.4.0: {}
-
- argparse@2.0.1: {}
-
- aria-hidden@1.2.6:
- dependencies:
- tslib: 2.8.1
-
- babel-dead-code-elimination@1.0.12:
- dependencies:
- '@babel/core': 7.29.7
- '@babel/parser': 7.29.9
- '@babel/traverse': 7.29.8
- '@babel/types': 7.29.8
- transitivePeerDependencies:
- - supports-color
-
- baseline-browser-mapping@2.11.27: {}
-
- better-auth@1.7.7(@opentelemetry/api@1.9.1)(@tanstack/react-start@1.168.60(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)))(drizzle-kit@0.31.11)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))(pg@8.23.1)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(solid-js@1.9.15):
- dependencies:
- '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4)
- '@better-auth/drizzle-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))
- '@better-auth/kysely-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(kysely@0.29.6)
- '@better-auth/memory-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)
- '@better-auth/mongo-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)
- '@better-auth/prisma-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)
- '@better-auth/telemetry': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.4))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)
- '@better-auth/utils': 0.4.2
- '@better-fetch/fetch': 1.3.2
- '@noble/ciphers': 2.4.0
- '@noble/hashes': 2.4.0
- better-call: 1.4.0(zod@4.6.5)
- defu: 6.1.7
- jose: 6.2.12
- kysely: 0.29.6
- nanostores: 1.5.4
- zod: 4.6.5
- optionalDependencies:
- '@tanstack/react-start': 1.168.60(crossws@0.4.12(srvx@0.11.22))(esbuild@0.28.2)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))
- drizzle-kit: 0.31.11
- drizzle-orm: 0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)
- pg: 8.23.1
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- solid-js: 1.9.15
- transitivePeerDependencies:
- - '@opentelemetry/api'
-
- better-call@1.4.0(zod@4.6.5):
- dependencies:
- '@better-auth/utils': 0.5.0
- '@better-fetch/fetch': 1.3.2
- rou3: 0.9.2
- set-cookie-parser: 3.1.2
- optionalDependencies:
- zod: 4.6.5
-
- browserslist@4.29.3:
- dependencies:
- baseline-browser-mapping: 2.11.27
- caniuse-lite: 1.0.30001814
- electron-to-chromium: 1.5.444
- node-releases: 2.0.57
- update-browserslist-db: 1.3.3(browserslist@4.29.3)
-
- buffer-from@1.1.2: {}
-
- caniuse-lite@1.0.30001814: {}
-
- chalk@5.6.2: {}
-
- chokidar@5.0.0:
- dependencies:
- readdirp: 5.1.1
-
- class-variance-authority@0.7.1:
- dependencies:
- clsx: 2.1.1
-
- cliui@8.0.1:
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
-
- clsx@2.1.1: {}
-
- cmdk@1.1.1(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0):
- dependencies:
- '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-dialog': 1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- '@radix-ui/react-id': 1.1.4(@types/react@19.3.0)(react@19.3.0)
- '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- transitivePeerDependencies:
- - '@types/react'
- - '@types/react-dom'
-
- cn@0.4.0: {}
-
- color-convert@2.0.1:
- dependencies:
- color-name: 1.1.4
-
- color-name@1.1.4: {}
-
- consola@3.4.2: {}
-
- convert-source-map@2.0.0: {}
-
- cookie-es@3.1.1: {}
-
- core-js@3.50.0: {}
-
- croner@10.0.1: {}
-
- cross-spawn@7.0.6:
- dependencies:
- path-key: 3.1.1
- shebang-command: 2.0.0
- which: 2.0.2
-
- crossws@0.4.12(srvx@0.11.22):
- optionalDependencies:
- srvx: 0.11.22
-
- cssesc@3.0.0: {}
-
- csstype@3.2.3: {}
-
- d3-array@3.2.4:
- dependencies:
- internmap: 2.0.3
-
- d3-color@3.1.0: {}
-
- d3-ease@3.0.1: {}
-
- d3-format@3.1.2: {}
-
- d3-interpolate@3.0.1:
- dependencies:
- d3-color: 3.1.0
-
- d3-path@3.1.0: {}
-
- d3-scale@4.0.2:
- dependencies:
- d3-array: 3.2.4
- d3-format: 3.1.2
- d3-interpolate: 3.0.1
- d3-time: 3.1.0
- d3-time-format: 4.1.0
-
- d3-shape@3.2.0:
- dependencies:
- d3-path: 3.1.0
-
- d3-time-format@4.1.0:
- dependencies:
- d3-time: 3.1.0
-
- d3-time@3.1.0:
- dependencies:
- d3-array: 3.2.4
-
- d3-timer@3.0.1: {}
-
- dayjs@1.11.23: {}
-
- db0@0.3.4(@electric-sql/pglite@0.5.8)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)):
- optionalDependencies:
- '@electric-sql/pglite': 0.5.8
- drizzle-orm: 0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)
-
- debug@4.4.3:
- dependencies:
- ms: 2.1.3
-
- decimal.js-light@2.5.1: {}
-
- defu@6.1.7: {}
-
- detect-libc@2.1.2: {}
-
- detect-node-es@1.1.0: {}
-
- diff@8.0.4: {}
-
- dompurify@3.4.16:
- optionalDependencies:
- '@types/trusted-types': 2.0.7
-
- drizzle-kit@0.31.11:
- dependencies:
- '@drizzle-team/brocli': 0.10.2
- '@esbuild-kit/esm-loader': 2.6.5
- esbuild: 0.25.12
- tsx: 4.23.15
-
- drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1):
- optionalDependencies:
- '@electric-sql/pglite': 0.5.8
- '@opentelemetry/api': 1.9.1
- '@types/pg': 8.23.1
- kysely: 0.29.6
- pg: 8.23.1
-
- electron-to-chromium@1.5.444: {}
-
- emoji-regex@8.0.0: {}
-
- enhanced-resolve@5.26.0:
- dependencies:
- graceful-fs: 4.2.11
- tapable: 2.3.3
-
- env-runner@0.1.16:
- dependencies:
- crossws: 0.4.12(srvx@0.11.22)
- exsolve: 1.1.3
- httpxy: 0.5.5
- srvx: 0.11.22
-
- es-toolkit@1.52.0: {}
-
- esbuild@0.18.20:
- optionalDependencies:
- '@esbuild/android-arm': 0.18.20
- '@esbuild/android-arm64': 0.18.20
- '@esbuild/android-x64': 0.18.20
- '@esbuild/darwin-arm64': 0.18.20
- '@esbuild/darwin-x64': 0.18.20
- '@esbuild/freebsd-arm64': 0.18.20
- '@esbuild/freebsd-x64': 0.18.20
- '@esbuild/linux-arm': 0.18.20
- '@esbuild/linux-arm64': 0.18.20
- '@esbuild/linux-ia32': 0.18.20
- '@esbuild/linux-loong64': 0.18.20
- '@esbuild/linux-mips64el': 0.18.20
- '@esbuild/linux-ppc64': 0.18.20
- '@esbuild/linux-riscv64': 0.18.20
- '@esbuild/linux-s390x': 0.18.20
- '@esbuild/linux-x64': 0.18.20
- '@esbuild/netbsd-x64': 0.18.20
- '@esbuild/openbsd-x64': 0.18.20
- '@esbuild/sunos-x64': 0.18.20
- '@esbuild/win32-arm64': 0.18.20
- '@esbuild/win32-ia32': 0.18.20
- '@esbuild/win32-x64': 0.18.20
-
- esbuild@0.25.12:
- 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
-
- esbuild@0.28.2:
- optionalDependencies:
- '@esbuild/aix-ppc64': 0.28.2
- '@esbuild/android-arm': 0.28.2
- '@esbuild/android-arm64': 0.28.2
- '@esbuild/android-x64': 0.28.2
- '@esbuild/darwin-arm64': 0.28.2
- '@esbuild/darwin-x64': 0.28.2
- '@esbuild/freebsd-arm64': 0.28.2
- '@esbuild/freebsd-x64': 0.28.2
- '@esbuild/linux-arm': 0.28.2
- '@esbuild/linux-arm64': 0.28.2
- '@esbuild/linux-ia32': 0.28.2
- '@esbuild/linux-loong64': 0.28.2
- '@esbuild/linux-mips64el': 0.28.2
- '@esbuild/linux-ppc64': 0.28.2
- '@esbuild/linux-riscv64': 0.28.2
- '@esbuild/linux-s390x': 0.28.2
- '@esbuild/linux-x64': 0.28.2
- '@esbuild/netbsd-arm64': 0.28.2
- '@esbuild/netbsd-x64': 0.28.2
- '@esbuild/openbsd-arm64': 0.28.2
- '@esbuild/openbsd-x64': 0.28.2
- '@esbuild/openharmony-arm64': 0.28.2
- '@esbuild/sunos-x64': 0.28.2
- '@esbuild/win32-arm64': 0.28.2
- '@esbuild/win32-ia32': 0.28.2
- '@esbuild/win32-x64': 0.28.2
-
- escalade@3.2.0: {}
-
- eventemitter3@5.0.4: {}
-
- eventsource-parser@3.1.1: {}
-
- eventsource@3.0.7:
- dependencies:
- eventsource-parser: 3.1.1
-
- exsolve@1.1.3: {}
-
- fdir@6.5.0(picomatch@4.0.7):
- optionalDependencies:
- picomatch: 4.0.7
-
- fetchdts@0.1.7: {}
-
- fflate@0.4.9: {}
-
- fsevents@2.3.3:
- optional: true
-
- gensync@1.0.0-beta.2: {}
-
- get-caller-file@2.0.5: {}
-
- get-nonce@1.0.1: {}
-
- get-tsconfig@4.14.3:
- dependencies:
- resolve-pkg-maps: 1.0.0
-
- goober@2.1.19(csstype@3.2.3):
- dependencies:
- csstype: 3.2.3
-
- graceful-fs@4.2.11: {}
-
- h3@2.0.1-rc.20(crossws@0.4.12(srvx@0.11.22)):
- dependencies:
- rou3: 0.8.1
- srvx: 0.11.22
- optionalDependencies:
- crossws: 0.4.12(srvx@0.11.22)
-
- h3@2.0.1-rc.22(crossws@0.4.12(srvx@0.11.22)):
- dependencies:
- rou3: 0.8.1
- srvx: 0.11.22
- optionalDependencies:
- crossws: 0.4.12(srvx@0.11.22)
-
- hookable@6.1.2: {}
-
- httpxy@0.5.5: {}
-
- immer@10.2.0: {}
-
- immer@11.1.21: {}
-
- internmap@2.0.3: {}
-
- is-fullwidth-code-point@3.0.0: {}
-
- isbot@5.2.2: {}
-
- isexe@2.0.0: {}
-
- jiti@2.7.0: {}
-
- jose@6.2.12: {}
-
- js-tokens@4.0.0: {}
-
- js-yaml@4.3.2:
- dependencies:
- argparse: 2.0.1
-
- jsesc@3.1.0: {}
-
- json5@2.2.3: {}
-
- kysely@0.29.6: {}
-
- launch-editor@2.14.1:
- dependencies:
- picocolors: 1.1.1
- shell-quote: 1.12.0
-
- lightningcss-android-arm64@1.32.0:
- optional: true
-
- lightningcss-android-arm64@1.33.0:
- optional: true
-
- lightningcss-darwin-arm64@1.32.0:
- optional: true
-
- lightningcss-darwin-arm64@1.33.0:
- optional: true
-
- lightningcss-darwin-x64@1.32.0:
- optional: true
-
- lightningcss-darwin-x64@1.33.0:
- optional: true
-
- lightningcss-freebsd-x64@1.32.0:
- optional: true
-
- lightningcss-freebsd-x64@1.33.0:
- optional: true
-
- lightningcss-linux-arm-gnueabihf@1.32.0:
- optional: true
-
- lightningcss-linux-arm-gnueabihf@1.33.0:
- optional: true
-
- lightningcss-linux-arm64-gnu@1.32.0:
- optional: true
-
- lightningcss-linux-arm64-gnu@1.33.0:
- optional: true
-
- lightningcss-linux-arm64-musl@1.32.0:
- optional: true
-
- lightningcss-linux-arm64-musl@1.33.0:
- optional: true
-
- lightningcss-linux-x64-gnu@1.32.0:
- optional: true
-
- lightningcss-linux-x64-gnu@1.33.0:
- optional: true
-
- lightningcss-linux-x64-musl@1.32.0:
- optional: true
-
- lightningcss-linux-x64-musl@1.33.0:
- optional: true
-
- lightningcss-win32-arm64-msvc@1.32.0:
- optional: true
-
- lightningcss-win32-arm64-msvc@1.33.0:
- optional: true
-
- lightningcss-win32-x64-msvc@1.32.0:
- optional: true
-
- lightningcss-win32-x64-msvc@1.33.0:
- optional: true
-
- lightningcss@1.32.0:
- dependencies:
- detect-libc: 2.1.2
- optionalDependencies:
- lightningcss-android-arm64: 1.32.0
- lightningcss-darwin-arm64: 1.32.0
- lightningcss-darwin-x64: 1.32.0
- lightningcss-freebsd-x64: 1.32.0
- lightningcss-linux-arm-gnueabihf: 1.32.0
- lightningcss-linux-arm64-gnu: 1.32.0
- lightningcss-linux-arm64-musl: 1.32.0
- lightningcss-linux-x64-gnu: 1.32.0
- lightningcss-linux-x64-musl: 1.32.0
- lightningcss-win32-arm64-msvc: 1.32.0
- lightningcss-win32-x64-msvc: 1.32.0
-
- lightningcss@1.33.0:
- dependencies:
- detect-libc: 2.1.2
- optionalDependencies:
- lightningcss-android-arm64: 1.33.0
- lightningcss-darwin-arm64: 1.33.0
- lightningcss-darwin-x64: 1.33.0
- lightningcss-freebsd-x64: 1.33.0
- lightningcss-linux-arm-gnueabihf: 1.33.0
- lightningcss-linux-arm64-gnu: 1.33.0
- lightningcss-linux-arm64-musl: 1.33.0
- lightningcss-linux-x64-gnu: 1.33.0
- lightningcss-linux-x64-musl: 1.33.0
- lightningcss-win32-arm64-msvc: 1.33.0
- lightningcss-win32-x64-msvc: 1.33.0
-
- lru-cache@5.1.1:
- dependencies:
- yallist: 3.1.1
-
- lucide-react@0.577.0(react@19.3.0):
- dependencies:
- react: 19.3.0
-
- magic-string@0.30.21:
- dependencies:
- '@jridgewell/sourcemap-codec': 1.6.0
-
- marked@18.0.14: {}
-
- ms@2.1.3: {}
-
- nanoid@3.3.19: {}
-
- nanostores@1.5.4: {}
-
- nf3@0.3.24: {}
-
- nitro@3.0.260610-beta(@electric-sql/pglite@0.5.8)(chokidar@5.0.0)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))(jiti@2.7.0)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)):
- dependencies:
- consola: 3.4.2
- crossws: 0.4.12(srvx@0.11.22)
- db0: 0.3.4(@electric-sql/pglite@0.5.8)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))
- env-runner: 0.1.16
- h3: 2.0.1-rc.22(crossws@0.4.12(srvx@0.11.22))
- hookable: 6.1.2
- nf3: 0.3.24
- ocache: 0.1.5
- ofetch: 2.0.0-alpha.3
- ohash: 2.0.12
- rolldown: 1.2.12
- srvx: 0.11.22
- unenv: 2.0.0-rc.24
- unstorage: 2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4(@electric-sql/pglite@0.5.8)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)))(ofetch@2.0.0-alpha.3)
- optionalDependencies:
- jiti: 2.7.0
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@electric-sql/pglite'
- - '@libsql/client'
- - '@netlify/blobs'
- - '@netlify/runtime'
- - '@planetscale/database'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/functions'
- - '@vercel/kv'
- - aws4fetch
- - better-sqlite3
- - chokidar
- - drizzle-orm
- - idb-keyval
- - ioredis
- - lru-cache
- - miniflare
- - mongodb
- - mysql2
- - sqlite3
- - uploadthing
- - wrangler
-
- node-releases@2.0.57: {}
-
- ocache@0.1.5:
- dependencies:
- ohash: 2.0.12
-
- ofetch@2.0.0-alpha.3: {}
-
- ohash@2.0.12: {}
-
- oxc-parser@0.120.0(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3):
- dependencies:
- '@oxc-project/types': 0.120.0
- optionalDependencies:
- '@oxc-parser/binding-android-arm-eabi': 0.120.0
- '@oxc-parser/binding-android-arm64': 0.120.0
- '@oxc-parser/binding-darwin-arm64': 0.120.0
- '@oxc-parser/binding-darwin-x64': 0.120.0
- '@oxc-parser/binding-freebsd-x64': 0.120.0
- '@oxc-parser/binding-linux-arm-gnueabihf': 0.120.0
- '@oxc-parser/binding-linux-arm-musleabihf': 0.120.0
- '@oxc-parser/binding-linux-arm64-gnu': 0.120.0
- '@oxc-parser/binding-linux-arm64-musl': 0.120.0
- '@oxc-parser/binding-linux-ppc64-gnu': 0.120.0
- '@oxc-parser/binding-linux-riscv64-gnu': 0.120.0
- '@oxc-parser/binding-linux-riscv64-musl': 0.120.0
- '@oxc-parser/binding-linux-s390x-gnu': 0.120.0
- '@oxc-parser/binding-linux-x64-gnu': 0.120.0
- '@oxc-parser/binding-linux-x64-musl': 0.120.0
- '@oxc-parser/binding-openharmony-arm64': 0.120.0
- '@oxc-parser/binding-wasm32-wasi': 0.120.0(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
- '@oxc-parser/binding-win32-arm64-msvc': 0.120.0
- '@oxc-parser/binding-win32-ia32-msvc': 0.120.0
- '@oxc-parser/binding-win32-x64-msvc': 0.120.0
- transitivePeerDependencies:
- - '@emnapi/core'
- - '@emnapi/runtime'
-
- path-key@3.1.1: {}
-
- pathe@2.0.3: {}
-
- pg-cloudflare@1.4.1:
- optional: true
-
- pg-connection-string@2.14.1: {}
-
- pg-int8@1.0.1: {}
-
- pg-pool@3.14.0(pg@8.23.1):
- dependencies:
- pg: 8.23.1
-
- pg-protocol@1.16.1: {}
-
- pg-types@2.2.0:
- dependencies:
- pg-int8: 1.0.1
- postgres-array: 2.0.0
- postgres-bytea: 1.0.1
- postgres-date: 1.0.7
- postgres-interval: 1.2.0
-
- pg@8.23.1:
- dependencies:
- pg-connection-string: 2.14.1
- pg-pool: 3.14.0(pg@8.23.1)
- pg-protocol: 1.16.1
- pg-types: 2.2.0
- pgpass: 1.0.5
- optionalDependencies:
- pg-cloudflare: 1.4.1
-
- pgpass@1.0.5:
- dependencies:
- split2: 4.2.0
-
- picocolors@1.1.1: {}
-
- picomatch@4.0.7: {}
-
- pkce-challenge@5.0.1: {}
-
- postcss-selector-parser@6.0.10:
- dependencies:
- cssesc: 3.0.0
- util-deprecate: 1.0.2
-
- postcss@8.5.28:
- dependencies:
- nanoid: 3.3.19
- picocolors: 1.1.1
- source-map-js: 1.2.2
-
- postgres-array@2.0.0: {}
-
- postgres-bytea@1.0.1: {}
-
- postgres-date@1.0.7: {}
-
- postgres-interval@1.2.0:
- dependencies:
- xtend: 4.0.2
-
- posthog-js@1.436.1(@types/react@19.3.0)(react@19.3.0):
- dependencies:
- '@posthog/browser-common': 0.9.1
- '@posthog/core': 1.56.0
- '@posthog/types': 1.413.0
- core-js: 3.50.0
- dompurify: 3.4.16
- fflate: 0.4.9
- preact: 10.29.8
- query-selector-shadow-dom: 1.0.1
- web-vitals: 6.2.3
- web-vitals-soft-navs: web-vitals@6.2.1
- optionalDependencies:
- '@types/react': 19.3.0
- react: 19.3.0
- transitivePeerDependencies:
- - preact-render-to-string
-
- posthog-node@5.55.0:
- dependencies:
- '@posthog/core': 1.56.0
-
- preact@10.29.8: {}
-
- prettier@3.9.9: {}
-
- query-selector-shadow-dom@1.0.1: {}
-
- react-dom@19.3.0(react@19.3.0):
- dependencies:
- react: 19.3.0
- scheduler: 0.28.0
-
- react-is@19.3.0: {}
-
- react-redux@9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1):
- dependencies:
- '@types/use-sync-external-store': 0.0.6
- react: 19.3.0
- use-sync-external-store: 1.7.0(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
- redux: 5.0.1
-
- react-remove-scroll-bar@2.3.8(@types/react@19.3.0)(react@19.3.0):
- dependencies:
- react: 19.3.0
- react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.0)
- tslib: 2.8.1
- optionalDependencies:
- '@types/react': 19.3.0
-
- react-remove-scroll@2.7.2(@types/react@19.3.0)(react@19.3.0):
- dependencies:
- react: 19.3.0
- react-remove-scroll-bar: 2.3.8(@types/react@19.3.0)(react@19.3.0)
- react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.0)
- tslib: 2.8.1
- use-callback-ref: 1.3.3(@types/react@19.3.0)(react@19.3.0)
- use-sidecar: 1.1.3(@types/react@19.3.0)(react@19.3.0)
- optionalDependencies:
- '@types/react': 19.3.0
-
- react-style-singleton@2.2.3(@types/react@19.3.0)(react@19.3.0):
- dependencies:
- get-nonce: 1.0.1
- react: 19.3.0
- tslib: 2.8.1
- optionalDependencies:
- '@types/react': 19.3.0
-
- react@19.3.0: {}
-
- readdirp@5.1.1: {}
-
- recharts@3.8.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react-is@19.3.0)(react@19.3.0)(redux@5.0.1):
- dependencies:
- '@reduxjs/toolkit': 2.13.0(react-redux@9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1))(react@19.3.0)
- clsx: 2.1.1
- decimal.js-light: 2.5.1
- es-toolkit: 1.52.0
- eventemitter3: 5.0.4
- immer: 10.2.0
- react: 19.3.0
- react-dom: 19.3.0(react@19.3.0)
- react-is: 19.3.0
- react-redux: 9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1)
- reselect: 5.1.1
- tiny-invariant: 1.3.3
- use-sync-external-store: 1.7.0(react@19.3.0)
- victory-vendor: 37.3.6
- transitivePeerDependencies:
- - '@types/react'
- - redux
-
- redux-thunk@3.1.0(redux@5.0.1):
- dependencies:
- redux: 5.0.1
-
- redux@5.0.1: {}
-
- require-directory@2.1.1: {}
-
- reselect@5.1.1: {}
-
- reselect@5.3.0: {}
-
- resolve-pkg-maps@1.0.0: {}
-
- rolldown@1.2.12:
- dependencies:
- '@oxc-project/types': 0.152.0
- '@rolldown/pluginutils': 1.0.1
- optionalDependencies:
- '@rolldown/binding-android-arm-eabi': 1.2.12
- '@rolldown/binding-android-arm64': 1.2.12
- '@rolldown/binding-darwin-arm64': 1.2.12
- '@rolldown/binding-darwin-x64': 1.2.12
- '@rolldown/binding-freebsd-x64': 1.2.12
- '@rolldown/binding-linux-arm-gnueabihf': 1.2.12
- '@rolldown/binding-linux-arm64-gnu': 1.2.12
- '@rolldown/binding-linux-arm64-musl': 1.2.12
- '@rolldown/binding-linux-ppc64-gnu': 1.2.12
- '@rolldown/binding-linux-s390x-gnu': 1.2.12
- '@rolldown/binding-linux-x64-gnu': 1.2.12
- '@rolldown/binding-linux-x64-musl': 1.2.12
- '@rolldown/binding-openharmony-arm64': 1.2.12
- '@rolldown/binding-win32-arm64-msvc': 1.2.12
- '@rolldown/binding-win32-x64-msvc': 1.2.12
-
- rou3@0.8.1: {}
-
- rou3@0.9.2: {}
-
- scheduler@0.28.0: {}
-
- semver@6.3.1: {}
-
- seroval-plugins@1.5.6(seroval@1.5.6):
- dependencies:
- seroval: 1.5.6
-
- seroval-plugins@1.6.8(seroval@1.6.8):
- dependencies:
- seroval: 1.6.8
-
- seroval@1.5.6: {}
-
- seroval@1.6.8: {}
-
- set-cookie-parser@3.1.2: {}
-
- shebang-command@2.0.0:
- dependencies:
- shebang-regex: 3.0.0
-
- shebang-regex@3.0.0: {}
-
- shell-quote@1.12.0: {}
-
- simple-icons@16.34.0: {}
-
- solid-js@1.9.15:
- dependencies:
- csstype: 3.2.3
- seroval: 1.5.6
- seroval-plugins: 1.5.6(seroval@1.5.6)
-
- source-map-js@1.2.2: {}
-
- source-map-support@0.5.21:
- dependencies:
- buffer-from: 1.1.2
- source-map: 0.6.1
-
- source-map@0.6.1: {}
-
- source-map@0.7.6: {}
-
- split2@4.2.0: {}
-
- srvx@0.11.22: {}
-
- string-width@4.2.3:
- dependencies:
- emoji-regex: 8.0.0
- is-fullwidth-code-point: 3.0.0
- strip-ansi: 6.0.1
-
- strip-ansi@6.0.1:
- dependencies:
- ansi-regex: 5.0.1
-
- tailwindcss@4.3.3: {}
-
- tapable@2.3.3: {}
-
- tiny-invariant@1.3.3: {}
-
- tinyglobby@0.2.17:
- dependencies:
- fdir: 6.5.0(picomatch@4.0.7)
- picomatch: 4.0.7
-
- tslib@2.8.1: {}
-
- tsx@4.23.15:
- dependencies:
- esbuild: 0.28.2
- optionalDependencies:
- fsevents: 2.3.3
-
- tw-animate-css@1.4.0: {}
-
- typescript@6.0.3: {}
-
- ufo@1.6.4: {}
-
- undici-types@6.21.0: {}
-
- unenv@2.0.0-rc.24:
- dependencies:
- pathe: 2.0.3
-
- unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)):
- dependencies:
- '@jridgewell/remapping': 2.3.5
- picomatch: 4.0.7
- webpack-virtual-modules: 0.6.2
- optionalDependencies:
- esbuild: 0.28.2
- rolldown: 1.2.12
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
-
- unstorage@2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4(@electric-sql/pglite@0.5.8)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1)))(ofetch@2.0.0-alpha.3):
- optionalDependencies:
- chokidar: 5.0.0
- db0: 0.3.4(@electric-sql/pglite@0.5.8)(drizzle-orm@0.45.3(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(kysely@0.29.6)(pg@8.23.1))
- ofetch: 2.0.0-alpha.3
-
- update-browserslist-db@1.3.3(browserslist@4.29.3):
- dependencies:
- browserslist: 4.29.3
- escalade: 3.2.0
- picocolors: 1.1.1
-
- use-callback-ref@1.3.3(@types/react@19.3.0)(react@19.3.0):
- dependencies:
- react: 19.3.0
- tslib: 2.8.1
- optionalDependencies:
- '@types/react': 19.3.0
-
- use-sidecar@1.1.3(@types/react@19.3.0)(react@19.3.0):
- dependencies:
- detect-node-es: 1.1.0
- react: 19.3.0
- tslib: 2.8.1
- optionalDependencies:
- '@types/react': 19.3.0
-
- use-sync-external-store@1.7.0(react@19.3.0):
- dependencies:
- react: 19.3.0
-
- util-deprecate@1.0.2: {}
-
- victory-vendor@37.3.6:
- dependencies:
- '@types/d3-array': 3.2.2
- '@types/d3-ease': 3.0.2
- '@types/d3-interpolate': 3.0.4
- '@types/d3-scale': 4.0.9
- '@types/d3-shape': 3.2.0
- '@types/d3-time': 3.0.4
- '@types/d3-timer': 3.0.2
- d3-array: 3.2.4
- d3-ease: 3.0.1
- d3-interpolate: 3.0.1
- d3-scale: 4.0.2
- d3-shape: 3.2.0
- d3-time: 3.1.0
- d3-timer: 3.0.1
-
- vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15):
- dependencies:
- lightningcss: 1.33.0
- picomatch: 4.0.7
- postcss: 8.5.28
- rolldown: 1.2.12
- tinyglobby: 0.2.17
- optionalDependencies:
- '@types/node': 22.20.5
- esbuild: 0.28.2
- fsevents: 2.3.3
- jiti: 2.7.0
- tsx: 4.23.15
-
- vitefu@1.1.3(vite@8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)):
- optionalDependencies:
- vite: 8.3.2(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)
-
- web-vitals@6.2.1: {}
-
- web-vitals@6.2.3: {}
-
- webpack-virtual-modules@0.6.2: {}
-
- which@2.0.2:
- dependencies:
- isexe: 2.0.0
-
- wrap-ansi@7.0.0:
- dependencies:
- ansi-styles: 4.3.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
-
- ws@8.22.0: {}
-
- xmlbuilder2@4.0.3:
- dependencies:
- '@oozcitak/dom': 2.0.2
- '@oozcitak/infra': 2.0.2
- '@oozcitak/util': 10.0.0
- js-yaml: 4.3.2
-
- xtend@4.0.2: {}
-
- y18n@5.0.8: {}
-
- yallist@3.1.1: {}
-
- yargs-parser@21.1.1: {}
-
- yargs@17.7.3:
- dependencies:
- cliui: 8.0.1
- escalade: 3.2.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- string-width: 4.2.3
- y18n: 5.0.8
- yargs-parser: 21.1.1
-
- zod@4.6.5: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
deleted file mode 100644
index 79ae338..0000000
--- a/pnpm-workspace.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-packages:
- - packages/*
-allowBuilds:
- core-js: false
- esbuild: true
- lightningcss: true
diff --git a/scripts/benchmarks.ts b/scripts/benchmarks.ts
index 814e78d..19ea117 100644
--- a/scripts/benchmarks.ts
+++ b/scripts/benchmarks.ts
@@ -1,5 +1,5 @@
// Computes the benchmark percentiles for one month, by default the last
-// complete one: `pnpm benchmarks` or `pnpm benchmarks --month=2026-09`.
+// complete one: `bun run benchmarks` or `bun run benchmarks --month=2026-09`.
// With PGlite, stop the dev server first.
import assert from "node:assert/strict";
import { bandFor, percentile } from "#/lib/benchmarks";
diff --git a/scripts/check-books-close.ts b/scripts/check-books-close.ts
index 0d98ced..80617d2 100644
--- a/scripts/check-books-close.ts
+++ b/scripts/check-books-close.ts
@@ -1,5 +1,5 @@
// Checks month closing and adjustments in src/server/books.server.ts on a
-// scratch database. Run: DATABASE_URL=/tmp/books-check SYNC_SCHEDULER=off npx tsx scripts/check-books-close.ts
+// scratch database. Run: DATABASE_URL=/tmp/books-check SYNC_SCHEDULER=off bun scripts/check-books-close.ts
import assert from "node:assert/strict";
const { db, schema } = await import("../src/db/index.ts");
const { exportJournal } = await import("../src/server/books.server.ts");
diff --git a/scripts/check-books-export.ts b/scripts/check-books-export.ts
index 7c29da8..410d879 100644
--- a/scripts/check-books-export.ts
+++ b/scripts/check-books-export.ts
@@ -1,5 +1,5 @@
// Checks the journal files in src/server/books-export.server.ts on a scratch
-// database. Run: DATABASE_URL=/tmp/books-export-check SYNC_SCHEDULER=off npx tsx scripts/check-books-export.ts
+// database. Run: DATABASE_URL=/tmp/books-export-check SYNC_SCHEDULER=off bun scripts/check-books-export.ts
import assert from "node:assert/strict";
const { db, schema } = await import("../src/db/index.ts");
const { journalCsv } = await import("../src/server/books-export.server.ts");
diff --git a/scripts/check-books-tax.ts b/scripts/check-books-tax.ts
index 3ed7cf0..668bbe4 100644
--- a/scripts/check-books-tax.ts
+++ b/scripts/check-books-tax.ts
@@ -1,5 +1,5 @@
// Checks the tax report (src/server/tax.server.ts, src/lib/tax.ts) on a scratch
-// database. Run: DATABASE_URL=/tmp/books-tax-check SYNC_SCHEDULER=off npx tsx scripts/check-books-tax.ts
+// database. Run: DATABASE_URL=/tmp/books-tax-check SYNC_SCHEDULER=off bun scripts/check-books-tax.ts
import assert from "node:assert/strict";
const { db, schema } = await import("../src/db/index.ts");
diff --git a/scripts/check-books.ts b/scripts/check-books.ts
index 0a6f835..3be6782 100644
--- a/scripts/check-books.ts
+++ b/scripts/check-books.ts
@@ -1,5 +1,5 @@
// Checks the journal rules in src/lib/books.ts (docs/BOOKS.md).
-// Run: npx tsx scripts/check-books.ts
+// Run: bun scripts/check-books.ts
import assert from "node:assert/strict";
import {
adjustments,
diff --git a/scripts/seed.ts b/scripts/seed.ts
index fd9aa82..8527c55 100644
--- a/scripts/seed.ts
+++ b/scripts/seed.ts
@@ -1,4 +1,4 @@
-// Seeds one workspace with twelve months of numbers. Run with `pnpm db:seed`.
+// Seeds one workspace with twelve months of numbers. Run with `bun run db:seed`.
import { eq } from "drizzle-orm";
import { authSchema, db, schema } from "#/db";
import { seedWorkspace } from "#/server/seed.server";
diff --git a/src/db/index.ts b/src/db/index.ts
index 4e87467..1f1cbd8 100644
--- a/src/db/index.ts
+++ b/src/db/index.ts
@@ -40,7 +40,7 @@ export const db: NodePgDatabase =
pgDb ?? (pgliteDb as unknown as NodePgDatabase);
export type Db = typeof db;
-// Migrations in ./drizzle run once at start. `pnpm db:generate` writes a
+// Migrations in ./drizzle run once at start. `bun run db:generate` writes a
// new one after a schema change.
if (process.env.SKIP_MIGRATIONS !== "1") {
const opts = { migrationsFolder: "drizzle" };
diff --git a/src/routes/p.$workspace.$product_.badge[.]svg.ts b/src/routes/p.$workspace.$product_.badge[.]svg.ts
index 624051b..ddc7b58 100644
--- a/src/routes/p.$workspace.$product_.badge[.]svg.ts
+++ b/src/routes/p.$workspace.$product_.badge[.]svg.ts
@@ -1,6 +1,6 @@
import { createFileRoute } from "@tanstack/react-router";
-// Embeddable badge for a public product page. Under `pnpm dev`, Nitro treats
+// Embeddable badge for a public product page. Under `bun run dev`, Nitro treats
// image requests for .svg and .png paths as static files and answers 404
// (nitro/dist/_build/vite.dev.mjs); production serves them. To test in dev:
// curl -H "Sec-Fetch-Dest: document" .
diff --git a/src/server/edge.server.ts b/src/server/edge.server.ts
index b90f4d6..66740bb 100644
--- a/src/server/edge.server.ts
+++ b/src/server/edge.server.ts
@@ -7,7 +7,7 @@ import { markdownFor } from "./markdown.server";
// The build prerenders every page that has a markdown version. Nitro lists
// its static files before those pages are written, so they are served from
-// here, read and compressed once per process. `node .output/server/index.mjs`
+// here, read and compressed once per process. `bun .output/server/index.mjs`
// puts them in .output/public; anywhere else (dev, the prerender itself) the
// read fails and the page renders on the server.
const PUBLIC = join(dirname(process.argv[1] ?? ""), "../public");
diff --git a/src/server/scheduler.ts b/src/server/scheduler.ts
index 4071609..ce34caa 100644
--- a/src/server/scheduler.ts
+++ b/src/server/scheduler.ts
@@ -37,7 +37,7 @@ export function startScheduler() {
);
});
// Hosted, the 3rd of each month: last month's benchmarks, once its last
- // days have synced. `pnpm benchmarks` runs it by hand.
+ // days have synced. `bun run benchmarks` runs it by hand.
const benchmarks = new Cron(
"0 5 3 * *",
{
diff --git a/src/server/seed.server.ts b/src/server/seed.server.ts
index 1256fe4..7d40c2e 100644
--- a/src/server/seed.server.ts
+++ b/src/server/seed.server.ts
@@ -4,7 +4,7 @@ import { splitCents } from "#/connectors/types";
import { type db, schema } from "#/db";
import { encrypt } from "#/lib/crypto";
-// Sample numbers for `pnpm db:seed` and the public demo: two years ending
+// Sample numbers for `bun run db:seed` and the public demo: two years ending
// this month, so charts have a year-earlier line, three products, Stripe for
// revenue, seven cost providers and a few flat costs.
diff --git a/vite.config.ts b/vite.config.ts
index c5ae484..ee85242 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -29,6 +29,8 @@ const config = defineConfig({
},
}),
nitro({
+ // TanStack Start hosting guide: the Bun preset serves with Bun.serve.
+ preset: "bun",
// PGlite and resvg (social images) ship wasm next to their JS;
// bundling drops it.
rollupConfig: {
From 7cadbcbe3af2efc3279e4a089254376e46a81c91 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Mon, 19 Oct 2026 21:36:34 -0400
Subject: [PATCH 21/26] Books: fee math, POST exports and a re-sync migration
- Payment fees are gross minus refunds minus net, so a provider's
balance moves by net. Stripe's other charges and lost disputes count
as payment fees.
- A yearly flat cost's 12 months add up to the yearly amount.
- The export summary keeps a group's bank and other entries apart.
- The journal export takes POST, since a whole-workspace export closes
the month.
- With no country set, the tax report is a plain profit and loss, and a
USD workspace exports US dates.
- Changing the base currency reconverts gross, refunds and payouts, and
reopens exported months.
- Onboarding asks for the incorporation date. Equipment must be a
one-time cost.
- The books read each span once. Unquoted Bank of Canada days are held
for an hour.
- Polar sync drops old-format lines across the whole reread window.
- 0012 re-syncs the whole history of Stripe and Paddle connections and of
every connection in a CAD workspace. It sets last_synced_at to 1, not
null, so the sync skips first-sync sub-unit mapping and analytics.
---
docs/BOOKS.md | 4 +-
drizzle/0012_books_resync.sql | 14 +
drizzle/meta/0012_snapshot.json | 3005 +++++++++++++++++++++++++++++
drizzle/meta/_journal.json | 7 +
scripts/check-books-close.ts | 10 +
scripts/check-books-tax.ts | 5 +-
scripts/check-books.ts | 16 +
src/components/books/export.tsx | 2 +-
src/content/changelog.md | 4 +-
src/lib/books.ts | 27 +-
src/lib/costs.ts | 3 +
src/routes/api/journal[.]csv.ts | 2 +-
src/routes/app/costs.tsx | 4 +
src/routes/onboarding.tsx | 20 +-
src/server/books-export.server.ts | 8 +-
src/server/books.server.ts | 214 +-
src/server/costs.functions.ts | 4 +-
src/server/fx.server.ts | 11 +-
src/server/mcp.server.ts | 1 +
src/server/settings.functions.ts | 39 +-
src/server/sync.server.ts | 62 +-
src/server/tax.server.ts | 34 +-
22 files changed, 3321 insertions(+), 175 deletions(-)
create mode 100644 drizzle/0012_books_resync.sql
create mode 100644 drizzle/meta/0012_snapshot.json
diff --git a/docs/BOOKS.md b/docs/BOOKS.md
index 0d87063..96734e3 100644
--- a/docs/BOOKS.md
+++ b/docs/BOOKS.md
@@ -23,7 +23,7 @@ A setting with a start date supports one change. Two changes in a year would nee
## Data the connectors add
-- `revenue_lines.gross_base_cents`, `fees_base_cents`, `refunds_base_cents`: written by the sync at the line's rate, like `net_base_cents`. Older rows are null until the next full sync; readers derive them from the net rate when net is not zero.
+- `revenue_lines.gross_base_cents`, `fees_base_cents`, `refunds_base_cents`: written by the sync at the line's rate, like `net_base_cents`. Older rows are null until the next full sync; readers derive them from the net rate when net is not zero. The books don't read `fees_base_cents`: fees are gross − refunds − net.
- `revenue_lines.service_start`, `service_end`: the period a payment covers, `[start, end)`. Null means the payment is earned on its date.
- `payouts`: money a payment provider sent to a bank account. Stripe and Polar.
- Bank of Canada daily rates for workspaces in CAD (Income Tax Folio S5-F4-C1, ¶1.4). Other currencies keep ECB rates.
@@ -62,7 +62,7 @@ All amounts are in the workspace currency. Every entry balances. "Payer" is `owe
| Event | Debit | Credit |
|---|---|---|
-| Payment received (on its date) | `balance:` gross − refunds − fees + tax; `payment_fees` fees; `refunds` refunds | `deferred_revenue` gross; `sales_tax_owed` tax (only when the provider does not remit tax) |
+| Payment received (on its date) | `balance:` net + tax; `payment_fees` gross − refunds − net (the provider's fees, its other charges and lost disputes); `refunds` refunds | `deferred_revenue` gross; `sales_tax_owed` tax (only when the provider does not remit tax) |
| Revenue earned (each month of the service period, by days) | `deferred_revenue` | `sales` |
| Payout to a bank account | `company_bank` (incorporated) or `owner_draws` | `balance:` |
| Usage cost (on its date) | expense account | `balance:` |
diff --git a/drizzle/0012_books_resync.sql b/drizzle/0012_books_resync.sql
new file mode 100644
index 0000000..db0e317
--- /dev/null
+++ b/drizzle/0012_books_resync.sql
@@ -0,0 +1,14 @@
+-- Reread the plan's whole history on the next scheduled sync for:
+-- Stripe and Paddle, whose payouts and service periods are new (0010), and
+-- every connection in a CAD workspace, so its stored lines convert at the
+-- Bank of Canada rates (0011).
+-- 1, not null: a last sync that old makes syncRange read the whole history,
+-- while null would count as a first sync, which maps unassigned sub-units to
+-- the connection's product and records first-sync analytics again.
+-- Connections that never synced keep null.
+UPDATE "connections" SET "last_synced_at" = 1
+WHERE "last_synced_at" IS NOT NULL
+ AND (
+ "provider" IN ('stripe', 'paddle')
+ OR "workspace_id" IN (SELECT "id" FROM "workspaces" WHERE "base_currency" = 'CAD')
+ );
diff --git a/drizzle/meta/0012_snapshot.json b/drizzle/meta/0012_snapshot.json
new file mode 100644
index 0000000..310aee0
--- /dev/null
+++ b/drizzle/meta/0012_snapshot.json
@@ -0,0 +1,3005 @@
+{
+ "id": "b82ee309-97fd-4993-8bdd-bbf2710ec14c",
+ "prevId": "751ff482-32f6-45aa-a5bf-159c86616617",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.alert_channels": {
+ "name": "alert_channels",
+ "schema": "",
+ "columns": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "slack_webhook": {
+ "name": "slack_webhook",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "webhook_url": {
+ "name": "webhook_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "webhook_secret": {
+ "name": "webhook_secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sms_phone": {
+ "name": "sms_phone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sms_code_hash": {
+ "name": "sms_code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sms_code_expires_at": {
+ "name": "sms_code_expires_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sms_verified_at": {
+ "name": "sms_verified_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sms_month": {
+ "name": "sms_month",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sms_count": {
+ "name": "sms_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "alert_channels_workspace_id_workspaces_id_fk": {
+ "name": "alert_channels_workspace_id_workspaces_id_fk",
+ "tableFrom": "alert_channels",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.alert_rules": {
+ "name": "alert_rules",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "threshold": {
+ "name": "threshold",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "channel": {
+ "name": "channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'email'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "alert_rules_workspace_id_workspaces_id_fk": {
+ "name": "alert_rules_workspace_id_workspaces_id_fk",
+ "tableFrom": "alert_rules",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.alerts": {
+ "name": "alerts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule_id": {
+ "name": "rule_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "detail": {
+ "name": "detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tone": {
+ "name": "tone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'ink'"
+ },
+ "opened_at": {
+ "name": "opened_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "alerts_ws_open_key": {
+ "name": "alerts_ws_open_key",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"alerts\".\"resolved_at\" is null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "alerts_workspace_id_workspaces_id_fk": {
+ "name": "alerts_workspace_id_workspaces_id_fk",
+ "tableFrom": "alerts",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "alerts_rule_id_alert_rules_id_fk": {
+ "name": "alerts_rule_id_alert_rules_id_fk",
+ "tableFrom": "alerts",
+ "columnsFrom": [
+ "rule_id"
+ ],
+ "tableTo": "alert_rules",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.api_tokens": {
+ "name": "api_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'read'"
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_client_id": {
+ "name": "oauth_client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_hash": {
+ "name": "refresh_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "api_tokens_hash": {
+ "name": "api_tokens_hash",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "api_tokens_refresh": {
+ "name": "api_tokens_refresh",
+ "columns": [
+ {
+ "expression": "refresh_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "api_tokens_workspace_id_workspaces_id_fk": {
+ "name": "api_tokens_workspace_id_workspaces_id_fk",
+ "tableFrom": "api_tokens",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.audit_events": {
+ "name": "audit_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_kind": {
+ "name": "actor_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target": {
+ "name": "target",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "detail": {
+ "name": "detail",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "audit_ws_created": {
+ "name": "audit_ws_created",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "audit_events_workspace_id_workspaces_id_fk": {
+ "name": "audit_events_workspace_id_workspaces_id_fk",
+ "tableFrom": "audit_events",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.benchmark_snapshots": {
+ "name": "benchmark_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "month": {
+ "name": "month",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "band": {
+ "name": "band",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metric": {
+ "name": "metric",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "n": {
+ "name": "n",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "p25": {
+ "name": "p25",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "p50": {
+ "name": "p50",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "p75": {
+ "name": "p75",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "p90": {
+ "name": "p90",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "computed_at": {
+ "name": "computed_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "benchmarks_month_band_metric": {
+ "name": "benchmarks_month_band_metric",
+ "columns": [
+ {
+ "expression": "month",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "band",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "metric",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.cli_logins": {
+ "name": "cli_logins",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "device_code_hash": {
+ "name": "device_code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_code": {
+ "name": "user_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_ip": {
+ "name": "requested_ip",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approved_at": {
+ "name": "approved_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "api_token_id": {
+ "name": "api_token_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "cli_logins_device": {
+ "name": "cli_logins_device",
+ "columns": [
+ {
+ "expression": "device_code_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cli_logins_user_code": {
+ "name": "cli_logins_user_code",
+ "columns": [
+ {
+ "expression": "user_code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "cli_logins_workspace_id_workspaces_id_fk": {
+ "name": "cli_logins_workspace_id_workspaces_id_fk",
+ "tableFrom": "cli_logins",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "cli_logins_api_token_id_api_tokens_id_fk": {
+ "name": "cli_logins_api_token_id_api_tokens_id_fk",
+ "tableFrom": "cli_logins",
+ "columnsFrom": [
+ "api_token_id"
+ ],
+ "tableTo": "api_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.connect_links": {
+ "name": "connect_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "api_token_id": {
+ "name": "api_token_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "used_at": {
+ "name": "used_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "connect_links_hash": {
+ "name": "connect_links_hash",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connect_links_workspace_id_workspaces_id_fk": {
+ "name": "connect_links_workspace_id_workspaces_id_fk",
+ "tableFrom": "connect_links",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connect_links_api_token_id_api_tokens_id_fk": {
+ "name": "connect_links_api_token_id_api_tokens_id_fk",
+ "tableFrom": "connect_links",
+ "columnsFrom": [
+ "api_token_id"
+ ],
+ "tableTo": "api_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connect_links_connection_id_connections_id_fk": {
+ "name": "connect_links_connection_id_connections_id_fk",
+ "tableFrom": "connect_links",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.connections": {
+ "name": "connections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "auth_kind": {
+ "name": "auth_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credentials": {
+ "name": "credentials",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "product_id": {
+ "name": "product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cadence_minutes": {
+ "name": "cadence_minutes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 360
+ },
+ "paid_with": {
+ "name": "paid_with",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'personal'"
+ },
+ "paid_with_since": {
+ "name": "paid_with_since",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "connections_ws": {
+ "name": "connections_ws",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connections_workspace_id_workspaces_id_fk": {
+ "name": "connections_workspace_id_workspaces_id_fk",
+ "tableFrom": "connections",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connections_product_id_products_id_fk": {
+ "name": "connections_product_id_products_id_fk",
+ "tableFrom": "connections",
+ "columnsFrom": [
+ "product_id"
+ ],
+ "tableTo": "products",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.cost_lines": {
+ "name": "cost_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "product_id": {
+ "name": "product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_base_cents": {
+ "name": "amount_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service": {
+ "name": "service",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sub_unit_id": {
+ "name": "sub_unit_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sub_unit_label": {
+ "name": "sub_unit_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "cost_ws_ext": {
+ "name": "cost_ws_ext",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_ws_date": {
+ "name": "cost_ws_date",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "cost_lines_workspace_id_workspaces_id_fk": {
+ "name": "cost_lines_workspace_id_workspaces_id_fk",
+ "tableFrom": "cost_lines",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "cost_lines_connection_id_connections_id_fk": {
+ "name": "cost_lines_connection_id_connections_id_fk",
+ "tableFrom": "cost_lines",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "cost_lines_product_id_products_id_fk": {
+ "name": "cost_lines_product_id_products_id_fk",
+ "tableFrom": "cost_lines",
+ "columnsFrom": [
+ "product_id"
+ ],
+ "tableTo": "products",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.flat_costs": {
+ "name": "flat_costs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "product_id": {
+ "name": "product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_base_cents": {
+ "name": "amount_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "interval": {
+ "name": "interval",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "starts_on": {
+ "name": "starts_on",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ends_on": {
+ "name": "ends_on",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "paid_with": {
+ "name": "paid_with",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'personal'"
+ },
+ "paid_with_since": {
+ "name": "paid_with_since",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "flat_costs_workspace_id_workspaces_id_fk": {
+ "name": "flat_costs_workspace_id_workspaces_id_fk",
+ "tableFrom": "flat_costs",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "flat_costs_product_id_products_id_fk": {
+ "name": "flat_costs_product_id_products_id_fk",
+ "tableFrom": "flat_costs",
+ "columnsFrom": [
+ "product_id"
+ ],
+ "tableTo": "products",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.fx_rates": {
+ "name": "fx_rates",
+ "schema": "",
+ "columns": {
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base": {
+ "name": "base",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rate": {
+ "name": "rate",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "fx_rates_date_base_currency_pk": {
+ "name": "fx_rates_date_base_currency_pk",
+ "columns": [
+ "date",
+ "base",
+ "currency"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.journal_exports": {
+ "name": "journal_exports",
+ "schema": "",
+ "columns": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "month": {
+ "name": "month",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entries": {
+ "name": "entries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "exported_at": {
+ "name": "exported_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "journal_exports_workspace_id_workspaces_id_fk": {
+ "name": "journal_exports_workspace_id_workspaces_id_fk",
+ "tableFrom": "journal_exports",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {
+ "journal_exports_workspace_id_month_pk": {
+ "name": "journal_exports_workspace_id_month_pk",
+ "columns": [
+ "workspace_id",
+ "month"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.metric_snapshots": {
+ "name": "metric_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metric": {
+ "name": "metric",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "snap_conn_date_metric": {
+ "name": "snap_conn_date_metric",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "metric",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "metric_snapshots_workspace_id_workspaces_id_fk": {
+ "name": "metric_snapshots_workspace_id_workspaces_id_fk",
+ "tableFrom": "metric_snapshots",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "metric_snapshots_connection_id_connections_id_fk": {
+ "name": "metric_snapshots_connection_id_connections_id_fk",
+ "tableFrom": "metric_snapshots",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.oauth_clients": {
+ "name": "oauth_clients",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "redirect_uris": {
+ "name": "redirect_uris",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.oauth_codes": {
+ "name": "oauth_codes",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "code_hash": {
+ "name": "code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_name": {
+ "name": "client_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "redirect_uri": {
+ "name": "redirect_uri",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code_challenge": {
+ "name": "code_challenge",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "api_token_id": {
+ "name": "api_token_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "used_at": {
+ "name": "used_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "oauth_codes_hash": {
+ "name": "oauth_codes_hash",
+ "columns": [
+ {
+ "expression": "code_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "oauth_codes_workspace_id_workspaces_id_fk": {
+ "name": "oauth_codes_workspace_id_workspaces_id_fk",
+ "tableFrom": "oauth_codes",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "oauth_codes_api_token_id_api_tokens_id_fk": {
+ "name": "oauth_codes_api_token_id_api_tokens_id_fk",
+ "tableFrom": "oauth_codes",
+ "columnsFrom": [
+ "api_token_id"
+ ],
+ "tableTo": "api_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.payouts": {
+ "name": "payouts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_base_cents": {
+ "name": "amount_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "payouts_conn_ext": {
+ "name": "payouts_conn_ext",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "payouts_ws_date": {
+ "name": "payouts_ws_date",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "payouts_workspace_id_workspaces_id_fk": {
+ "name": "payouts_workspace_id_workspaces_id_fk",
+ "tableFrom": "payouts",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "payouts_connection_id_connections_id_fk": {
+ "name": "payouts_connection_id_connections_id_fk",
+ "tableFrom": "payouts",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.product_mappings": {
+ "name": "product_mappings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sub_unit_id": {
+ "name": "sub_unit_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sub_unit_label": {
+ "name": "sub_unit_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "product_id": {
+ "name": "product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "mappings_conn_unit": {
+ "name": "mappings_conn_unit",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sub_unit_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "product_mappings_workspace_id_workspaces_id_fk": {
+ "name": "product_mappings_workspace_id_workspaces_id_fk",
+ "tableFrom": "product_mappings",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "product_mappings_connection_id_connections_id_fk": {
+ "name": "product_mappings_connection_id_connections_id_fk",
+ "tableFrom": "product_mappings",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "product_mappings_product_id_products_id_fk": {
+ "name": "product_mappings_product_id_products_id_fk",
+ "tableFrom": "product_mappings",
+ "columnsFrom": [
+ "product_id"
+ ],
+ "tableTo": "products",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.products": {
+ "name": "products",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "public_page": {
+ "name": "public_page",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'off'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "products_ws_slug": {
+ "name": "products_ws_slug",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "products_workspace_id_workspaces_id_fk": {
+ "name": "products_workspace_id_workspaces_id_fk",
+ "tableFrom": "products",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.revenue_lines": {
+ "name": "revenue_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "product_id": {
+ "name": "product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "gross_cents": {
+ "name": "gross_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fees_cents": {
+ "name": "fees_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "refunds_cents": {
+ "name": "refunds_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "net_cents": {
+ "name": "net_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "net_base_cents": {
+ "name": "net_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tax_cents": {
+ "name": "tax_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tax_base_cents": {
+ "name": "tax_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "gross_base_cents": {
+ "name": "gross_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "fees_base_cents": {
+ "name": "fees_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refunds_base_cents": {
+ "name": "refunds_base_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "service_start": {
+ "name": "service_start",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "service_end": {
+ "name": "service_end",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'other'"
+ },
+ "sub_unit_id": {
+ "name": "sub_unit_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sub_unit_label": {
+ "name": "sub_unit_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "revenue_conn_ext": {
+ "name": "revenue_conn_ext",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "revenue_ws_date": {
+ "name": "revenue_ws_date",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "revenue_lines_workspace_id_workspaces_id_fk": {
+ "name": "revenue_lines_workspace_id_workspaces_id_fk",
+ "tableFrom": "revenue_lines",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "revenue_lines_connection_id_connections_id_fk": {
+ "name": "revenue_lines_connection_id_connections_id_fk",
+ "tableFrom": "revenue_lines",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "revenue_lines_product_id_products_id_fk": {
+ "name": "revenue_lines_product_id_products_id_fk",
+ "tableFrom": "revenue_lines",
+ "columnsFrom": [
+ "product_id"
+ ],
+ "tableTo": "products",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sync_runs": {
+ "name": "sync_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lines_written": {
+ "name": "lines_written",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sync_runs_connection_id_connections_id_fk": {
+ "name": "sync_runs_connection_id_connections_id_fk",
+ "tableFrom": "sync_runs",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.telemetry_pings": {
+ "name": "telemetry_pings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "instance": {
+ "name": "instance",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "seen_at": {
+ "name": "seen_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_members": {
+ "name": "workspace_members",
+ "schema": "",
+ "columns": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'owner'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workspace_members_workspace_id_workspaces_id_fk": {
+ "name": "workspace_members_workspace_id_workspaces_id_fk",
+ "tableFrom": "workspace_members",
+ "columnsFrom": [
+ "workspace_id"
+ ],
+ "tableTo": "workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {
+ "workspace_members_workspace_id_user_id_pk": {
+ "name": "workspace_members_workspace_id_user_id_pk",
+ "columns": [
+ "workspace_id",
+ "user_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspaces": {
+ "name": "workspaces",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base_currency": {
+ "name": "base_currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'USD'"
+ },
+ "plan": {
+ "name": "plan",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'free'"
+ },
+ "weekly_email": {
+ "name": "weekly_email",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "weekly_day": {
+ "name": "weekly_day",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "weekly_hour": {
+ "name": "weekly_hour",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 9
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'UTC'"
+ },
+ "weekly_sent_at": {
+ "name": "weekly_sent_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "telemetry": {
+ "name": "telemetry",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "benchmarks": {
+ "name": "benchmarks",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "demo": {
+ "name": "demo",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "incorporated_on": {
+ "name": "incorporated_on",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "country": {
+ "name": "country",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "region": {
+ "name": "region",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "book_accounts": {
+ "name": "book_accounts",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "(extract(epoch from now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "workspaces_slug_unique": {
+ "name": "workspaces_slug_unique",
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "account_userId_idx": {
+ "name": "account_userId_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "account_user_id_user_id_fk": {
+ "name": "account_user_id_user_id_fk",
+ "tableFrom": "account",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "session_userId_idx": {
+ "name": "session_userId_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "session_user_id_user_id_fk": {
+ "name": "session_user_id_user_id_fk",
+ "tableFrom": "session",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "session_token_unique": {
+ "name": "session_token_unique",
+ "columns": [
+ "token"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "analytics": {
+ "name": "analytics",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verification": {
+ "name": "verification",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "verification_identifier_idx": {
+ "name": "verification_identifier_idx",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "views": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
index 306761c..3702eba 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -85,6 +85,13 @@
"when": 1791431020772,
"tag": "0011_boc_rates",
"breakpoints": true
+ },
+ {
+ "idx": 12,
+ "version": "7",
+ "when": 1792459991866,
+ "tag": "0012_books_resync",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/scripts/check-books-close.ts b/scripts/check-books-close.ts
index 80617d2..5177e05 100644
--- a/scripts/check-books-close.ts
+++ b/scripts/check-books-close.ts
@@ -28,5 +28,15 @@ assert(oct.some((e) => e.group === "earn:stripe"));
// Exporting November doesn't repeat the September adjustment.
const nov = await exportJournal(ws, "2026-11", { withBank: true });
assert(!nov.some((e) => e.group === "adjust:2026-09"));
+// A lost dispute (gross 0, net -6500 with a 1500 fee) leaves the Stripe
+// balance by its net, the part past the fee as a payment fee.
+await db.insert(schema.revenueLines).values({ workspaceId: ws.id, connectionId: stripe.id, date: "2026-06-10", currency: "USD", grossCents: 0, feesCents: 1500, netCents: -6500, netBaseCents: -6500, grossBaseCents: 0, feesBaseCents: 1500, refundsBaseCents: 0, externalId: "du_1" });
+const { booksInputs } = await import("../src/server/books.server.ts");
+const { journal } = await import("../src/lib/books.ts");
+const [june] = await booksInputs(ws, ["2026-06"]);
+const lines = journal(june).flatMap((e) => e.lines);
+const net = (a: string) => lines.filter((l) => l.account === a).reduce((x, l) => x + l.debit - l.credit, 0);
+assert.equal(net("balance:stripe"), -6500);
+assert.equal(net("payment_fees"), 6500);
console.log("close: ok");
process.exit(0);
diff --git a/scripts/check-books-tax.ts b/scripts/check-books-tax.ts
index 668bbe4..45bc761 100644
--- a/scripts/check-books-tax.ts
+++ b/scripts/check-books-tax.ts
@@ -154,9 +154,10 @@ const fr = await check("FR", { country: "FR" });
assert.deepEqual(fr.rep.parts[0].forms.map((f) => f.name), ["Profit and loss"]);
assert.equal(fr.rep.parts[0].depreciation.length, 0);
-// No country: nothing to map.
+// No country: the same plain profit and loss.
const none = await seed({ country: "" as string });
-assert.equal((await taxReport({ ...none, country: null }, 2025)).parts.length, 0);
+const noneRep = await taxReport({ ...none, country: null }, 2025);
+assert.deepEqual(noneRep.parts[0].forms.map((f) => f.name), ["Profit and loss"]);
// The rules on their own: declining balance and the dates around them.
const one = (country: string, date: string, cost: number, y: number, inc: string | null = null) =>
diff --git a/scripts/check-books.ts b/scripts/check-books.ts
index 3be6782..18efac7 100644
--- a/scripts/check-books.ts
+++ b/scripts/check-books.ts
@@ -95,6 +95,22 @@ assert(allBalanced(manual));
// The summary keeps every entry balanced.
assert(summarize([...dec, ...company], "2025-12").every(balanced));
+// A yearly cost's 12 months add up to it, rounding included.
+let yearly = 0;
+for (let m = 3; m <= 14; m++) {
+ const month = `${2026 + Math.floor((m - 1) / 12)}-${String(((m - 1) % 12) + 1).padStart(2, "0")}`;
+ const es = journal({ ...base, month, manual: [{ name: "Tool", productId: null, amount: 1000, interval: "year", startsOn: "2026-03-15", endsOn: null, category: "software", method: "personal", since: null }] });
+ yearly += sum(es, "software");
+}
+assert.equal(yearly, 1000);
+
+// A group's bank and other entries stay apart in the summary: two costs
+// with one name, one on the card and one from the company account.
+const twin = (method: "personal" | "company") => ({ name: "Domain", productId: null, amount: 1500, interval: "once" as const, startsOn: "2026-03-05", endsOn: null, category: "software" as const, method, since: null });
+const twins = summarize(journal({ ...base, month: "2026-03", incorporatedOn: "2026-02-01", manual: [twin("personal"), twin("company")] }), "2026-03");
+assert.equal(twins.length, 2);
+assert(twins.filter((e) => !e.bank).every((e) => !e.lines.some((l) => l.account === "company_bank")));
+
// A closed month that changed later goes out as one balanced adjustment,
// without the bank side for formats that leave it to the bank feed.
const before = totals(company);
diff --git a/src/components/books/export.tsx b/src/components/books/export.tsx
index 664c6d9..c663c22 100644
--- a/src/components/books/export.tsx
+++ b/src/components/books/export.tsx
@@ -124,7 +124,7 @@ export function BooksExport({ options }: { options: Options }) {
await save({ data: names });
setDirty(false);
}
- const res = await fetch(url);
+ const res = await fetch(url, { method: journal ? "POST" : "GET" });
if (!res.ok) return setError(await res.text());
const a = document.createElement("a");
a.href = URL.createObjectURL(await res.blob());
diff --git a/src/content/changelog.md b/src/content/changelog.md
index 528445d..4569c5c 100644
--- a/src/content/changelog.md
+++ b/src/content/changelog.md
@@ -11,8 +11,8 @@ Every release, newest first. The full history is in the [commit log on GitHub](h
- **Books.** A new **Books** page exports a month of revenue and costs as a journal for QuickBooks, Xero or any accounting software, and lists the year's numbers on the lines of your tax form: T2125 and TP-80, the T2's GIFI schedules, Schedule C or Form 1120. Tell OpenProfit whether you have a company and who pays each provider, and it records costs on your personal card as money the business owes you. Exporting a month closes it; later changes come as an adjustment in the next export. See [Books](/docs/books).
- **One-time costs and equipment.** A flat cost can be **One time**, with a category. Equipment is depreciated on the tax report instead of deducted at once.
-- **Payouts and service periods.** Stripe payouts and the period each Stripe and Paddle payment covers now sync, so the books spread a yearly plan over its months. Polar revenue comes from orders, with refunds on the day they happen; reconnect Polar with the **Orders** and **Refunds** read scopes to get them.
-- **Bank of Canada rates.** Workspaces in Canadian dollars convert at the Bank of Canada's daily rate, as the CRA asks, from each connection's next full sync.
+- **Payouts and service periods.** Stripe payouts and the period each Stripe and Paddle payment covers now sync, so the books spread a yearly plan over its months. OpenProfit rereads the whole history of your Stripe and Paddle connections to fill them in. Polar revenue comes from orders, with refunds on the day they happen; reconnect Polar with the **Orders** and **Refunds** read scopes to get them.
+- **Bank of Canada rates.** Workspaces in Canadian dollars convert at the Bank of Canada's daily rate, as the CRA asks. OpenProfit rereads each connection's history to convert past lines at that rate.
## October 7, 2026
diff --git a/src/lib/books.ts b/src/lib/books.ts
index a5f251b..e010ecc 100644
--- a/src/lib/books.ts
+++ b/src/lib/books.ts
@@ -69,12 +69,6 @@ const PROVIDER_ACCOUNT: Record = {
export const expenseAccount = (provider: string): ExpenseCategory =>
PROVIDER_ACCOUNT[provider] ?? "other";
-export function accountType(account: Account): AccountType {
- return account.startsWith("balance:")
- ? "asset"
- : ACCOUNTS[account as FixedAccount].type;
-}
-
// Default name, or the user's rename for their accounting software.
export function accountName(
account: Account,
@@ -182,7 +176,7 @@ export type BooksIn = {
const DAY = 86_400_000;
const days = (a: string, b: string) =>
Math.round((Date.parse(b) - Date.parse(a)) / DAY);
-const nextMonth = (m: string) => {
+export const nextMonth = (m: string) => {
const [y, mo] = m.split("-").map(Number);
return new Date(Date.UTC(y, mo, 1)).toISOString().slice(0, 7);
};
@@ -390,7 +384,16 @@ export function journal(input: BooksIn): Entry[] {
m.startsOn.slice(0, 7) <= month &&
(!m.endsOn || m.endsOn.slice(0, 7) >= month);
if (!active) continue;
- amount = m.interval === "year" ? Math.round(m.amount / 12) : m.amount;
+ // A yearly cost's k-th month of its year books the rounded share up
+ // to k minus the share before it, so its 12 months add up exactly.
+ const [y0, m0] = m.startsOn.split("-").map(Number);
+ const [y, mo] = month.split("-").map(Number);
+ const k = (((y - y0) * 12 + mo - m0) % 12) + 1;
+ amount =
+ m.interval === "year"
+ ? Math.round((m.amount * k) / 12) -
+ Math.round((m.amount * (k - 1)) / 12)
+ : m.amount;
}
if (!amount) continue;
const paidBy = payer(date, incorporatedOn, m.method, m.since);
@@ -435,11 +438,13 @@ export function journal(input: BooksIn): Entry[] {
}
// One entry per group, dated the end of the month: what the journal formats
-// export (one line per account and product).
+// export (one line per account and product). Bank and other entries of a
+// group stay apart, so the formats can still drop the bank ones.
export function summarize(entries: Entry[], month: string): Entry[] {
const groups = new Map();
for (const e of entries) {
- const g = groups.get(e.group) ?? {
+ const key = `${e.group}|${e.bank}`;
+ const g = groups.get(key) ?? {
date: monthEnd(month),
memo: e.memo,
group: e.group,
@@ -455,7 +460,7 @@ export function summarize(entries: Entry[], month: string): Entry[] {
same.credit += l.credit;
} else g.lines.push({ ...l });
}
- groups.set(e.group, g);
+ groups.set(key, g);
}
// A line's debit and credit net to one side.
return [...groups.values()].map((g) => ({
diff --git a/src/lib/costs.ts b/src/lib/costs.ts
index b9367c4..7fb8bff 100644
--- a/src/lib/costs.ts
+++ b/src/lib/costs.ts
@@ -30,6 +30,9 @@ export const FlatCostInput = z
paidWith: z.enum(["personal", "company"]).optional(),
paidWithSince: Day.nullable().optional(),
})
+ .refine((f) => f.category !== "equipment" || f.interval === "once", {
+ message: "Equipment is a one-time cost.",
+ })
.refine((f) => !f.endsOn || f.endsOn >= f.startsOn, {
message: "The end date is before the start date.",
});
diff --git a/src/routes/api/journal[.]csv.ts b/src/routes/api/journal[.]csv.ts
index b9d7301..d1bdeca 100644
--- a/src/routes/api/journal[.]csv.ts
+++ b/src/routes/api/journal[.]csv.ts
@@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/api/journal.csv")({
server: {
handlers: {
- GET: async ({ request }) => {
+ POST: async ({ request }) => {
// Imported here so pages that skip the database never open it.
const { journalDownload } = await import(
"#/server/books-export.server"
diff --git a/src/routes/app/costs.tsx b/src/routes/app/costs.tsx
index ecf4b9a..50e1859 100644
--- a/src/routes/app/costs.tsx
+++ b/src/routes/app/costs.tsx
@@ -194,6 +194,10 @@ function FlatCostForm({
setError("The end date is before the start date.");
return;
}
+ if (!once && v.category === "equipment") {
+ setError("Equipment is a one-time cost.");
+ return;
+ }
const data = {
name: v.name.trim(),
amountCents,
diff --git a/src/routes/onboarding.tsx b/src/routes/onboarding.tsx
index b0448f7..2563b3d 100644
--- a/src/routes/onboarding.tsx
+++ b/src/routes/onboarding.tsx
@@ -55,6 +55,7 @@ function Onboarding() {
const [name, setName] = useState("");
const [currency, setCurrency] = useState<(typeof CURRENCIES)[number]>("USD");
const [incorporated, setIncorporated] = useState(false);
+ const [incorporatedOn, setIncorporatedOn] = useState("");
const [heardFrom, setHeardFrom] = useState<(typeof HEARD_FROM)[number] | "">(
"",
);
@@ -69,7 +70,7 @@ function Onboarding() {
name,
currency,
timezone,
- incorporatedOn: incorporated ? localDay() : null,
+ incorporatedOn: incorporated ? incorporatedOn : null,
heardFrom: heardFrom || undefined,
},
});
@@ -129,6 +130,23 @@ function Onboarding() {
change it in Books.
+ {incorporated && (
+
+ Incorporated on
+ setIncorporatedOn(e.target.value)}
+ className="num"
+ />
+
+ Sales and costs before this date count as your own.
+
+
+ )}
{askHeardFrom && (
diff --git a/src/server/books-export.server.ts b/src/server/books-export.server.ts
index 9a8e7ed..2e109ca 100644
--- a/src/server/books-export.server.ts
+++ b/src/server/books-export.server.ts
@@ -155,12 +155,16 @@ export async function journalCsv(
month,
renames: ws.bookAccounts ?? {},
product: (id) => (id && names.get(id)) || null,
- dayFirst: Boolean(ws.country && ws.country !== "US"),
+ // With no country set, a USD workspace counts as being in the US.
+ dayFirst: ws.country ? ws.country !== "US" : ws.baseCurrency !== "USD",
});
return { csv: csvFile(rows) };
}
-// GET /api/journal.csv?month=YYYY-MM&format=quickbooks|xero|plain&product=id
+// POST /api/journal.csv?month=YYYY-MM&format=quickbooks|xero|plain&product=id
+// POST, because a whole-workspace export closes the month: the session
+// cookie (SameSite=Lax) doesn't go out on another site's POST, and link
+// prefetchers only GET.
export async function journalDownload(request: Request) {
const ws = await exportWorkspace(request);
if (!ws) return new Response("Sign in to export.", { status: 401 });
diff --git a/src/server/books.server.ts b/src/server/books.server.ts
index 1edff59..bc47885 100644
--- a/src/server/books.server.ts
+++ b/src/server/books.server.ts
@@ -8,6 +8,7 @@ import {
type Entry,
expenseAccount,
journal,
+ nextMonth,
summarize,
totals,
} from "#/lib/books";
@@ -18,24 +19,15 @@ import type { Workspace } from "./workspace.server";
// Loads the data for the books (docs/BOOKS.md) and runs the journal in
// src/lib/books.ts.
-const nextMonth = (m: string) => {
- const [y, mo] = m.split("-").map(Number);
- return new Date(Date.UTC(y, mo, 1)).toISOString().slice(0, 7);
-};
-
type RevenueRow = typeof schema.revenueLines.$inferSelect;
-// Gross, fees and refunds in base cents. Rows synced before the base
-// columns derive them from the net (or tax) rate.
+// Gross and refunds in base cents. Rows synced before the base columns
+// derive them from the net (or tax) rate. Fees are whatever net leaves out
+// of them, Stripe's own charges and lost disputes included, so a provider's
+// balance moves by net.
// ponytail: a fully refunded payment with no tax has no rate; it counts
// at 1:1 until the next full sync fills the base columns.
function baseAmounts(l: RevenueRow, baseCurrency: string) {
- if (l.grossBaseCents !== null)
- return {
- gross: l.grossBaseCents,
- fees: l.feesBaseCents ?? 0,
- refunds: l.refundsBaseCents ?? 0,
- };
const rate =
l.currency === baseCurrency
? 1
@@ -44,25 +36,26 @@ function baseAmounts(l: RevenueRow, baseCurrency: string) {
: l.taxCents
? l.taxBaseCents / l.taxCents
: 1;
- return {
- gross: Math.round(l.grossCents * rate),
- fees: Math.round(l.feesCents * rate),
- refunds: Math.round(l.refundsCents * rate),
- };
+ const gross = l.grossBaseCents ?? Math.round(l.grossCents * rate);
+ const refunds = l.refundsBaseCents ?? Math.round(l.refundsCents * rate);
+ return { gross, refunds, fees: gross - refunds - l.netBaseCents };
}
-export async function booksInput(
+// The books input for each month, from one read of the span they cover.
+export async function booksInputs(
ws: Workspace,
- month: string,
+ months: string[],
productId: string | null = null,
-): Promise {
- const first = `${month}-01`;
- const after = `${nextMonth(month)}-01`;
+): Promise {
+ if (!months.length) return [];
+ const sorted = [...months].sort();
+ const first = `${sorted[0]}-01`;
+ const after = `${nextMonth(sorted[sorted.length - 1])}-01`;
const only = (col: PgColumn) => (productId ? eq(col, productId) : undefined);
const r = schema.revenueLines;
const c = schema.costLines;
const [revenue, costs, payouts, flats, conns] = await Promise.all([
- // Paid in the month, or earning in it.
+ // Paid in the span, or earning in it.
db
.select({ line: r, provider: schema.connections.provider })
.from(r)
@@ -122,50 +115,65 @@ export async function booksInput(
.map((x) => x.id),
);
const conn = new Map(conns.map((x) => [x.id, x]));
- return {
- month,
- incorporatedOn: ws.incorporatedOn,
- providerName,
- revenue: revenue.map(({ line, provider }) => ({
- date: line.date,
- provider,
- productId: line.productId,
- ...baseAmounts(line, ws.baseCurrency),
- tax: line.taxBaseCents,
- remitsTax: remits.has(provider),
- serviceStart: line.serviceStart,
- serviceEnd: line.serviceEnd,
- })),
- costs: costs.map((x) => {
- const k = x.connectionId ? conn.get(x.connectionId) : undefined;
- return {
- date: x.date,
- provider: x.provider,
- productId: x.productId,
- amount: x.amountBaseCents,
- method: k?.paidWith ?? "personal",
- since: k?.paidWithSince ?? null,
- };
- }),
- payouts: payouts.map(({ p, provider }) => ({
- date: p.date,
- provider,
- amount: p.amountBaseCents,
- })),
- manual: flats.map((f) => ({
- name: f.name,
- productId: f.productId,
- amount: f.amountBaseCents ?? f.amountCents,
- interval: f.interval,
- startsOn: f.startsOn,
- endsOn: f.endsOn,
- category:
- f.category ??
- (f.provider === "manual" ? "other" : expenseAccount(f.provider)),
- method: f.paidWith,
- since: f.paidWithSince,
- })),
- };
+ const revenueIn = revenue.map(({ line, provider }) => ({
+ date: line.date,
+ provider,
+ productId: line.productId,
+ ...baseAmounts(line, ws.baseCurrency),
+ tax: line.taxBaseCents,
+ remitsTax: remits.has(provider),
+ serviceStart: line.serviceStart,
+ serviceEnd: line.serviceEnd,
+ }));
+ const costsIn = costs.map((x) => {
+ const k = x.connectionId ? conn.get(x.connectionId) : undefined;
+ return {
+ date: x.date,
+ provider: x.provider,
+ productId: x.productId,
+ amount: x.amountBaseCents,
+ method: k?.paidWith ?? "personal",
+ since: k?.paidWithSince ?? null,
+ };
+ });
+ const payoutsIn = payouts.map(({ p, provider }) => ({
+ date: p.date,
+ provider,
+ amount: p.amountBaseCents,
+ }));
+ const manual = flats.map((f) => ({
+ name: f.name,
+ productId: f.productId,
+ amount: f.amountBaseCents ?? f.amountCents,
+ interval: f.interval,
+ startsOn: f.startsOn,
+ endsOn: f.endsOn,
+ category: f.category ?? expenseAccount(f.provider),
+ method: f.paidWith,
+ since: f.paidWithSince,
+ }));
+ return months.map((month) => {
+ const from = `${month}-01`;
+ const to = `${nextMonth(month)}-01`;
+ const inMonth = (x: { date: string }) => x.date >= from && x.date < to;
+ return {
+ month,
+ incorporatedOn: ws.incorporatedOn,
+ providerName,
+ // Paid in the month, or earning in it.
+ revenue: revenueIn.filter(
+ (x) =>
+ inMonth(x) ||
+ (x.serviceStart !== null &&
+ x.serviceEnd !== null &&
+ x.serviceStart < to &&
+ x.serviceEnd > from),
+ ),
+ costs: costsIn.filter(inMonth),
+ payouts: payoutsIn.filter(inMonth),
+ manual,
+ };
+ });
}
// The year's depreciation under the workspace's tax rules (src/lib/tax.ts),
@@ -183,22 +191,12 @@ export const yearDepreciation = (ws: Workspace, input: BooksIn) =>
: undefined;
// The month's journal, summarized: one entry per source. December carries
-// the year's depreciation unless `depreciation` overrides it.
-export async function monthEntries(
- ws: Workspace,
- month: string,
- productId: string | null = null,
- depreciation?: number,
-) {
- const input = await booksInput(ws, month, productId);
- return summarize(
- journal({
- ...input,
- depreciation: depreciation ?? yearDepreciation(ws, input),
- }),
- month,
+// the year's depreciation.
+const entriesOf = (ws: Workspace, input: BooksIn) =>
+ summarize(
+ journal({ ...input, depreciation: yearDepreciation(ws, input) }),
+ input.month,
);
-}
// The journal for an export. A whole-workspace export closes the month:
// exporting it again gives the same entries, and later changes to a closed
@@ -208,14 +206,14 @@ export async function monthEntries(
export async function exportJournal(
ws: Workspace,
month: string,
- opts: { productId?: string | null; withBank: boolean; depreciation?: number },
+ opts: { productId?: string | null; withBank: boolean },
): Promise {
const keep = (es: Entry[]) =>
opts.withBank ? es : es.filter((e) => !e.bank);
- if (opts.productId)
- return keep(
- await monthEntries(ws, month, opts.productId, opts.depreciation),
- );
+ if (opts.productId) {
+ const [input] = await booksInputs(ws, [month], opts.productId);
+ return keep(entriesOf(ws, input));
+ }
const exported = await db.query.journalExports.findMany({
where: eq(schema.journalExports.workspaceId, ws.id),
@@ -223,27 +221,32 @@ export async function exportJournal(
const stored = exported.find((x) => x.month === month);
if (stored) return keep(stored.entries as Entry[]);
- const entries = await monthEntries(ws, month, null, opts.depreciation);
// Closed months before this one, as exported plus their adjustments so
// far, against what the data says now.
- for (const closed of exported
+ const closed = exported
.filter((x) => x.month < month)
- .sort((a, b) => a.month.localeCompare(b.month))) {
+ .sort((a, b) => a.month.localeCompare(b.month));
+ const [input, ...nows] = await booksInputs(ws, [
+ month,
+ ...closed.map((x) => x.month),
+ ]);
+ const entries = entriesOf(ws, input);
+ closed.forEach((c, i) => {
const sent = [
- ...(closed.entries as Entry[]).filter(
- (e) => !e.group.startsWith("adjust:"),
- ),
+ ...(c.entries as Entry[]).filter((e) => !e.group.startsWith("adjust:")),
...exported.flatMap((x) =>
- (x.entries as Entry[]).filter(
- (e) => e.group === `adjust:${closed.month}`,
- ),
+ (x.entries as Entry[]).filter((e) => e.group === `adjust:${c.month}`),
),
];
- const now = await monthEntries(ws, closed.month);
entries.push(
- ...adjustments(totals(sent), totals(now), `${month}-01`, closed.month),
+ ...adjustments(
+ totals(sent),
+ totals(entriesOf(ws, nows[i])),
+ `${month}-01`,
+ c.month,
+ ),
);
- }
+ });
await db
.insert(schema.journalExports)
.values({
@@ -258,10 +261,9 @@ export async function exportJournal(
// Twelve months of journal entries, for the tax report. Closes nothing.
export async function yearEntries(ws: Workspace, year: number) {
- const out: Entry[] = [];
- for (let m = 1; m <= 12; m++)
- out.push(
- ...(await monthEntries(ws, `${year}-${String(m).padStart(2, "0")}`)),
- );
- return out;
+ const months = Array.from(
+ { length: 12 },
+ (_, i) => `${year}-${String(i + 1).padStart(2, "0")}`,
+ );
+ return (await booksInputs(ws, months)).flatMap((i) => entriesOf(ws, i));
}
diff --git a/src/server/costs.functions.ts b/src/server/costs.functions.ts
index 52e58dd..5f1b7f9 100644
--- a/src/server/costs.functions.ts
+++ b/src/server/costs.functions.ts
@@ -64,9 +64,7 @@ export const getFlatCosts = createServerFn({ method: "GET" })
interval: f.interval,
startsOn: f.startsOn,
endsOn: f.endsOn,
- category:
- f.category ??
- (f.provider === "manual" ? "other" : expenseAccount(f.provider)),
+ category: f.category ?? expenseAccount(f.provider),
paidWith: f.paidWith,
paidWithSince: f.paidWithSince,
})),
diff --git a/src/server/fx.server.ts b/src/server/fx.server.ts
index 31f0272..dec8b7b 100644
--- a/src/server/fx.server.ts
+++ b/src/server/fx.server.ts
@@ -20,7 +20,7 @@ export async function convert(
return Math.round(cents * rate);
}
-async function rateFor(
+export async function rateFor(
date: string,
from: string,
to: string,
@@ -61,8 +61,13 @@ async function rateFor(
// requests. Today and later are cached only once quoted: the Bank publishes
// each afternoon, and the sync rereads the last days. Null when the Bank
// doesn't publish the currency (DKK, CZK...) or has no rate on or before the
-// date; Frankfurter covers those.
+// date; Frankfurter covers those. A day not yet quoted is held in memory for
+// an hour at the preceding rate, so a sync doesn't ask again for each line.
+const unquoted = new Map();
async function bankOfCanada(date: string, from: string) {
+ const key = `${from}:${date}`;
+ const held = unquoted.get(key);
+ if (held && held.until > Date.now()) return held.rate ?? null;
const series = `FX${from}CAD`;
const today = iso(Date.now());
const at = Date.parse(date);
@@ -94,5 +99,7 @@ async function bankOfCanada(date: string, from: string) {
}
if (rows.length)
await db.insert(schema.fxRates).values(rows).onConflictDoNothing();
+ if (!rows.some((r) => r.date === date))
+ unquoted.set(key, { rate, until: Date.now() + 3_600_000 });
return rate ?? null;
}
diff --git a/src/server/mcp.server.ts b/src/server/mcp.server.ts
index 16624ae..837433e 100644
--- a/src/server/mcp.server.ts
+++ b/src/server/mcp.server.ts
@@ -966,6 +966,7 @@ function build({ authInfo, requestInfo }: McpRequestContext) {
starts_on: f.startsOn,
ends_on: f.endsOn,
product_id: f.productId,
+ category: f.category,
...Object.fromEntries(
Object.entries(patch).filter(([, v]) => v !== undefined),
),
diff --git a/src/server/settings.functions.ts b/src/server/settings.functions.ts
index 248f2c4..e457ab3 100644
--- a/src/server/settings.functions.ts
+++ b/src/server/settings.functions.ts
@@ -7,7 +7,7 @@ import { PLANS } from "#/lib/plans";
import { requireUser } from "./auth.server";
import { isCloud } from "./billing.server";
import { convert } from "./fx.server";
-import { syncConnection } from "./sync.server";
+import { revenueBase, syncConnection } from "./sync.server";
import { currentWorkspace } from "./workspace.server";
export type Settings = {
@@ -117,20 +117,7 @@ export const updateSettings = createServerFn({ method: "POST" })
for (const l of rev) {
await db
.update(schema.revenueLines)
- .set({
- netBaseCents: await convert(
- l.netCents,
- l.currency,
- data.currency,
- l.date,
- ),
- taxBaseCents: await convert(
- l.taxCents,
- l.currency,
- data.currency,
- l.date,
- ),
- })
+ .set(await revenueBase(l, data.currency))
.where(eq(schema.revenueLines.id, l.id));
}
for (const l of cost) {
@@ -148,6 +135,28 @@ export const updateSettings = createServerFn({ method: "POST" })
}
// Flat costs have no date of their own; they convert at today's rate.
const today = new Date().toISOString().slice(0, 10);
+ // A payout still on its way converts at today's rate, as in the sync.
+ const payouts = await db.query.payouts.findMany({
+ where: eq(schema.payouts.workspaceId, ws.id),
+ });
+ for (const p of payouts) {
+ await db
+ .update(schema.payouts)
+ .set({
+ amountBaseCents: await convert(
+ p.amountCents,
+ p.currency,
+ data.currency,
+ p.date < today ? p.date : today,
+ ),
+ })
+ .where(eq(schema.payouts.id, p.id));
+ }
+ // Exported months hold entries in the old currency, so they reopen:
+ // adjustments against them would mix the two.
+ await db
+ .delete(schema.journalExports)
+ .where(eq(schema.journalExports.workspaceId, ws.id));
const flats = await db.query.flatCosts.findMany({
where: eq(schema.flatCosts.workspaceId, ws.id),
});
diff --git a/src/server/sync.server.ts b/src/server/sync.server.ts
index b063d84..8ba44e0 100644
--- a/src/server/sync.server.ts
+++ b/src/server/sync.server.ts
@@ -6,6 +6,7 @@ import {
inArray,
isNotNull,
like,
+ lt,
lte,
ne,
or,
@@ -15,6 +16,7 @@ import { connector, connectors } from "#/connectors";
import {
ConnectorError,
type Credentials,
+ type RevenueLine,
type Snapshot,
type SyncRange,
} from "#/connectors/types";
@@ -23,7 +25,7 @@ import { decrypt } from "#/lib/crypto";
import { evaluateAlerts } from "./alerts.server";
import { captureForWorkspace } from "./analytics.server";
import { isCloud } from "./billing.server";
-import { convert } from "./fx.server";
+import { convert, rateFor } from "./fx.server";
import { traced } from "./observability.server";
type Connection = typeof schema.connections.$inferSelect;
@@ -53,6 +55,32 @@ export function syncRange(
return { from: isoDay(from), to: isoDay(now) };
}
+// A revenue line's base-cents columns, at one rate for its day. The sync
+// and a base currency change both write them through here.
+export async function revenueBase(
+ l: Pick<
+ RevenueLine,
+ | "currency"
+ | "date"
+ | "grossCents"
+ | "feesCents"
+ | "refundsCents"
+ | "netCents"
+ | "taxCents"
+ >,
+ to: string,
+) {
+ const rate = l.currency === to ? 1 : await rateFor(l.date, l.currency, to);
+ const base = (cents = 0) => Math.round(cents * rate);
+ return {
+ netBaseCents: base(l.netCents),
+ grossBaseCents: base(l.grossCents),
+ feesBaseCents: base(l.feesCents),
+ refundsBaseCents: base(l.refundsCents),
+ taxBaseCents: base(l.taxCents),
+ };
+}
+
// Pull one connection. Lines are upserted by external id, so re-running a
// range is safe. `full` rereads the plan's whole history.
export async function syncConnection(
@@ -115,8 +143,6 @@ export async function syncConnection(
if (c.fetchRevenue) {
const lines = await c.fetchRevenue(creds, range);
for (const l of lines) {
- const base = (cents: number) =>
- convert(cents, l.currency, ws.baseCurrency, l.date);
const line = {
productId: productFor(l.subUnitId, l.subUnitLabel),
date: l.date,
@@ -125,12 +151,8 @@ export async function syncConnection(
feesCents: l.feesCents,
refundsCents: l.refundsCents,
netCents: l.netCents,
- netBaseCents: await base(l.netCents),
- grossBaseCents: await base(l.grossCents),
- feesBaseCents: await base(l.feesCents),
- refundsBaseCents: await base(l.refundsCents),
+ ...(await revenueBase(l, ws.baseCurrency)),
taxCents: l.taxCents ?? 0,
- taxBaseCents: await base(l.taxCents ?? 0),
serviceStart: l.serviceStart ?? null,
serviceEnd: l.serviceEnd ?? null,
kind: l.kind,
@@ -160,6 +182,30 @@ export async function syncConnection(
window,
new Set(lines.map((l) => l.externalId)),
);
+ // Lines under the current ids replace legacy ones as far back as the
+ // fetch read, which can start before the range (Polar rereads 21
+ // days of orders).
+ const prefix = c.legacyIds;
+ const oldest = lines.reduce(
+ (a, l) => (l.date < a ? l.date : a),
+ range.from,
+ );
+ if (
+ legacy &&
+ prefix !== undefined &&
+ oldest < range.from &&
+ !lines.some((l) => l.externalId.startsWith(prefix))
+ )
+ await db
+ .delete(schema.revenueLines)
+ .where(
+ and(
+ eq(schema.revenueLines.connectionId, conn.id),
+ like(schema.revenueLines.externalId, `${prefix}%`),
+ gte(schema.revenueLines.date, oldest),
+ lt(schema.revenueLines.date, range.from),
+ ),
+ );
}
if (c.fetchPayouts) {
diff --git a/src/server/tax.server.ts b/src/server/tax.server.ts
index 278faf5..8d61393 100644
--- a/src/server/tax.server.ts
+++ b/src/server/tax.server.ts
@@ -1,13 +1,12 @@
import { eq, min } from "drizzle-orm";
import { db, schema } from "#/db";
-import { type Entry, journal } from "#/lib/books";
+import { type Entry, journal, nextMonth } from "#/lib/books";
import { providerName } from "#/lib/providers";
import {
amounts,
balances,
deMinimisElection,
depreciation,
- type Equipment,
equipmentOf,
type Form,
form1120,
@@ -21,7 +20,7 @@ import {
total,
tp80,
} from "#/lib/tax";
-import { booksInput, yearDepreciation } from "./books.server";
+import { booksInputs, yearDepreciation } from "./books.server";
import type { Workspace } from "./workspace.server";
// The yearly tax report (docs/BOOKS.md "Tax report"): the journal's totals
@@ -63,10 +62,6 @@ const INVOICES: Record = {
supabase: "https://supabase.com/dashboard/org/_/billing#invoices",
};
-const nextMonth = (m: string) => {
- const [y, mo] = m.split("-").map(Number);
- return new Date(Date.UTC(y, mo, 1)).toISOString().slice(0, 7);
-};
const dayBefore = (d: string) =>
new Date(Date.parse(d) - 86_400_000).toISOString().slice(0, 10);
@@ -132,28 +127,29 @@ export async function taxReport(ws: Workspace, year: number) {
currency: ws.baseCurrency,
invoices,
};
- if (!ws.country) return { ...base, parts: [] };
-
const start = `${year}-01-01`;
const end = `${year}-12-31`;
const inc =
ws.incorporatedOn && ws.incorporatedOn <= end ? ws.incorporatedOn : null;
// A company's balance sheet adds up everything since the first month.
- const entries: Entry[] = [];
- let equipment: Equipment[] = [];
+ const months: string[] = [];
for (
let m = inc && first && first < `${year}-01` ? first : `${year}-01`;
m <= `${year}-12`;
m = nextMonth(m)
- ) {
- const input = await booksInput(ws, m);
- if (m === `${year}-12`) equipment = equipmentOf(input.manual);
- entries.push(
- ...journal({ ...input, depreciation: yearDepreciation(ws, input) }),
- );
- }
- const rows = depreciation(ws.country, ws.incorporatedOn, equipment, year);
+ )
+ months.push(m);
+ const inputs = await booksInputs(ws, months);
+ const entries: Entry[] = inputs.flatMap((input) =>
+ journal({ ...input, depreciation: yearDepreciation(ws, input) }),
+ );
+ const rows = depreciation(
+ ws.country,
+ ws.incorporatedOn,
+ equipmentOf(inputs[inputs.length - 1].manual),
+ year,
+ );
const between = (a: string, b: string) =>
entries.filter((e) => e.date >= a && e.date <= b);
From b22ad1ea18691e9d00e439d6778fdecbf75a2582 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Mon, 19 Oct 2026 22:04:57 -0400
Subject: [PATCH 22/26] Docs: base currency changes reopen exported months;
image runs on Bun
The currency section says a reopened month exports in full again, so you
delete the earlier import first. The changelog tells self-hosters who
override the container command to use bun.
---
src/content/changelog.md | 4 ++++
src/docs/connectors.md | 2 ++
2 files changed, 6 insertions(+)
diff --git a/src/content/changelog.md b/src/content/changelog.md
index 67c4d91..1e1cef4 100644
--- a/src/content/changelog.md
+++ b/src/content/changelog.md
@@ -7,6 +7,10 @@ description: Every OpenProfit release, newest first, from Books and the tax repo
Every release, newest first. The full history is in the [commit log on GitHub](https://github.com/morencyr/openprofit/commits/main).
+## October 19, 2026
+
+- **Docker image on Bun.** The image runs on Bun instead of Node.js. If your setup overrides the container command or runs `node` inside the container, switch to `bun`.
+
## October 8, 2026
- **Books.** A new **Books** page exports a month of revenue and costs as a journal for QuickBooks, Xero or any accounting software, and lists the year's numbers on the lines of your tax form: T2125 and TP-80, the T2's GIFI schedules, Schedule C or Form 1120. Tell OpenProfit whether you have a company and who pays each provider, and it records costs on your personal card as money the business owes you. Exporting a month closes it; later changes come as an adjustment in the next export. See [Books](/docs/books).
diff --git a/src/docs/connectors.md b/src/docs/connectors.md
index c3629f1..716db25 100644
--- a/src/docs/connectors.md
+++ b/src/docs/connectors.md
@@ -96,3 +96,5 @@ OpenProfit counts a monthly or yearly cost in every month from its start date to
Each workspace has one base currency, set during onboarding and editable in **Settings**. OpenProfit converts every line in another currency at the European Central Bank (ECB) rate for that line’s date. A workspace in Canadian dollars uses the Bank of Canada’s daily rate instead, as the Canada Revenue Agency (CRA) asks. Currencies the Bank doesn’t publish still use the ECB rate.
Flat costs have no date of their own, so they convert at the rate of the day you save them. When you change the base currency, every stored line converts again at its own date’s rate, and flat costs at that day’s rate.
+
+Changing the base currency also reopens every month you exported from [Books](/docs/books). The next export of a reopened month includes all its entries again, in the new currency. Delete the earlier import from your accounting software first, or it counts that month twice.
From b4e8c937098ed08b46389dc32b9e79def586f174 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Thu, 22 Oct 2026 12:48:45 -0400
Subject: [PATCH 23/26] Move hosting from Railway to Dokploy behind Cloudflare
CI runs the checks before publishing the image, then calls the Dokploy
deploy webhook. CLIENT_IP_HEADER reads the client's address from a CDN
header such as cf-connecting-ip. Docs, privacy and security pages name
OVH and Cloudflare in place of Railway.
---
.github/workflows/check.yml | 4 ++--
.github/workflows/docker.yml | 16 ++++++++++++++++
CLAUDE.md | 10 ++++++----
README.md | 2 +-
src/docs/environment.md | 1 +
src/docs/self-host.md | 13 ++++++++++++-
src/legal/privacy.md | 7 ++++---
src/legal/security.md | 2 +-
src/server/ratelimit.server.ts | 8 ++++++++
9 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 9fb046c..98f848e 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -1,9 +1,9 @@
name: Check
+# Pushes to main run this through docker.yml, which deploys only when it passes.
on:
- push:
- branches: [main]
pull_request:
+ workflow_call:
jobs:
check:
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 7ae35c0..a957fee 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -6,7 +6,11 @@ on:
tags: ["v*"]
jobs:
+ check:
+ uses: ./.github/workflows/check.yml
+
build:
+ needs: check
runs-on: ubuntu-latest
permissions:
contents: read
@@ -35,3 +39,15 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
+
+ # openprofit.dev runs this image on Dokploy. Its deploy webhook pulls :latest.
+ deploy:
+ needs: build
+ if: github.ref == 'refs/heads/main'
+ runs-on: ubuntu-latest
+ steps:
+ - env:
+ DOKPLOY_DEPLOY_WEBHOOK: ${{ secrets.DOKPLOY_DEPLOY_WEBHOOK }}
+ run: |
+ if [ -z "$DOKPLOY_DEPLOY_WEBHOOK" ]; then echo "DOKPLOY_DEPLOY_WEBHOOK is not set; skipping"; exit 0; fi
+ curl -fsS -X POST "$DOKPLOY_DEPLOY_WEBHOOK"
diff --git a/CLAUDE.md b/CLAUDE.md
index aff71f5..91b817d 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2,7 +2,7 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
-OpenProfit: open-source finance for developers. Pulls revenue (Stripe, Polar, Paddle, Lemon Squeezy, RevenueCat) and costs (OpenAI, Anthropic, Vercel, Cloudflare, Railway and more) from provider APIs, assigns them to products, shows profit per product, and turns the same lines into books and tax-form numbers. One TanStack Start app serves the landing page, docs, blog, marketing content and the app. Hosted at openprofit.dev (Railway), self-hostable as one Docker image. Repo: github.com/morencyr/openprofit. Operator: Lobbystack Inc.
+OpenProfit: open-source finance for developers. Pulls revenue (Stripe, Polar, Paddle, Lemon Squeezy, RevenueCat) and costs (OpenAI, Anthropic, Vercel, Cloudflare, Railway and more) from provider APIs, assigns them to products, shows profit per product, and turns the same lines into books and tax-form numbers. One TanStack Start app serves the landing page, docs, blog, marketing content and the app. Hosted at openprofit.dev (Dokploy on an OVH server, behind Cloudflare), self-hostable as one Docker image. Repo: github.com/morencyr/openprofit. Operator: Lobbystack Inc.
## Commands
@@ -34,7 +34,7 @@ Production-build smoke test with a throwaway embedded DB:
PORT=3200 SYNC_SCHEDULER=off DATABASE_URL=/tmp/op-test bun .output/server/index.mjs
```
-Local sign-in without email: request a link on /login (or POST /api/auth/sign-in/magic-link) and read the URL from the dev server log. Same on Railway via `railway logs | grep magic-link`.
+Local sign-in without email: request a link on /login (or POST /api/auth/sign-in/magic-link) and read the URL from the dev server log. In production, search the Dokploy app's logs for `magic-link`.
## Library docs before code
@@ -58,7 +58,7 @@ Before editing files for a substantial task:
## Database
-- Postgres everywhere through Drizzle (`src/db/schema.ts`, `src/db/auth-schema.ts`). `DATABASE_URL` starting with `postgres://` uses `pg`; anything else is a directory for **PGlite** (embedded Postgres, default `./data/openprofit`). Hosted uses Railway Postgres.
+- Postgres everywhere through Drizzle (`src/db/schema.ts`, `src/db/auth-schema.ts`). `DATABASE_URL` starting with `postgres://` uses `pg`; anything else is a directory for **PGlite** (embedded Postgres, default `./data/openprofit`). Hosted uses a Postgres 18 service on Dokploy.
- Migrations in `./drizzle` run at import time of `src/db/index.ts` (skip with `SKIP_MIGRATIONS=1`). Don't use `drizzle-kit push`; PGlite rejects its multi-statement queries.
- **PGlite allows one process per data directory.** Running a script (`db:seed`, a one-off script) while `bun run dev` is up hangs or fails. Killing a process mid-write (`kill -9`) can corrupt the directory. Stop dev cleanly first. One-off scripts must end with `process.exit(0)` or PGlite keeps them alive. SIGTERM and SIGINT close the database and exit (`src/db/index.ts`); without that, PGlite's timer keeps the process alive until Docker kills it.
- PGlite is excluded from Vite `optimizeDeps` and externalized from the Nitro server bundle in `vite.config.ts`; bundling it drops its wasm/data files and the server crashes on start. Keep both. `@resvg/resvg-wasm` (social images, `src/server/images.server.ts`) is externalized for the same reason.
@@ -103,4 +103,6 @@ Before editing files for a substantial task:
## Deploy
-Push to `main` runs CI (`.github/workflows/check.yml`) and publishes `ghcr.io/morencyr/openprofit:latest`. Railway's `web` service (project `openprofit`, plus a Postgres service) deploys from the repo's `main` branch with Wait for CI on: each push waits for the GitHub checks, then deploys, and a failed check blocks it. Don't deploy production with `railway up`; it uploads the local working tree, uncommitted changes included. Railway's edge caches `.xml` responses, so give those an explicit `Cache-Control`.
+Pull requests run `.github/workflows/check.yml`. A push to `main` runs `.github/workflows/docker.yml`: the same checks, then it publishes `ghcr.io/morencyr/openprofit:latest`, then calls the Dokploy deploy webhook (secret `DOKPLOY_DEPLOY_WEBHOOK`). A failed check stops the image and the deploy.
+
+Production runs on Dokploy at deploy.lobbystack.com: project `OpenProfit`, application `web` (Docker source, that image, port 3000) and a `postgres` service (Postgres 18, reached over `dokploy-network`). Env vars live on the Dokploy application. The server's firewall admits ports 80 and 443 from Cloudflare only, so openprofit.dev's DNS is on Cloudflare (proxied, SSL mode Full) and the app reads the client's address from `CLIENT_IP_HEADER=cf-connecting-ip`. Records for mail (iCloud), Resend (`send`) and the PostHog proxy (`e`) stay DNS-only. Cloudflare may cache `.xml` responses, so give those an explicit `Cache-Control`.
diff --git a/README.md b/README.md
index de1c0ab..5ef4b0a 100644
--- a/README.md
+++ b/README.md
@@ -120,7 +120,7 @@ docker run -d \
Open http://localhost:3000/login and enter your email. Without an email provider the sign-in link prints in `docker logs openprofit`. Set `RESEND_API_KEY` and `EMAIL_FROM` to send it by mail. Point `DATABASE_URL` at a `postgres://` server to use your own database.
-The [self-host guide](https://openprofit.dev/docs/self-host) covers updates and Railway. The [environment reference](https://openprofit.dev/docs/environment) lists every variable.
+The [self-host guide](https://openprofit.dev/docs/self-host) covers updates, Dokploy and Railway. The [environment reference](https://openprofit.dev/docs/environment) lists every variable.
## How it works
diff --git a/src/docs/environment.md b/src/docs/environment.md
index a485d93..6f10234 100644
--- a/src/docs/environment.md
+++ b/src/docs/environment.md
@@ -32,6 +32,7 @@ Sign-in from the CLI and agent sign-up are rate-limited per IP address. Behind a
| Variable | Default | Purpose |
| --- | --- | --- |
| `TRUST_PROXY` | None | The number of proxies in front of the instance, usually `1`. OpenProfit then reads the client's address from `X-Forwarded-For`. Leave it unset when nothing sits in front, or clients can fake their address. Not needed on Railway |
+| `CLIENT_IP_HEADER` | None | A header your CDN sets to the client's address, such as `cf-connecting-ip` for Cloudflare. It takes precedence over `TRUST_PROXY`. Set it only when your firewall admits the CDN's addresses alone, or clients can fake their address |
## Email and sign-in
diff --git a/src/docs/self-host.md b/src/docs/self-host.md
index c505cd9..e20b8cb 100644
--- a/src/docs/self-host.md
+++ b/src/docs/self-host.md
@@ -65,9 +65,20 @@ docker rm -f openprofit
Then run the `docker run` command from [Start the container](#start-the-container) again. Schema changes apply when the new container starts.
+## Deploy on Dokploy
+
+The hosted version at openprofit.dev runs this same image on Dokploy. To do the same:
+
+1. In a project, add a Postgres database and deploy it.
+2. Add an application with the Docker provider and the image `ghcr.io/morencyr/openprofit:latest`.
+3. Set `DATABASE_URL` to the database's internal connection string, and set `SECRET_KEY` and `APP_URL` as described above. Traefik sits in front, so set `TRUST_PROXY=1`.
+4. Add your domain with port `3000` and HTTPS, then deploy.
+
+To redeploy when a new image comes out, call the deploy webhook from the application's **Deployments** tab after each push.
+
## Deploy on Railway
-The hosted version at openprofit.dev runs this same image on Railway. To do the same:
+To run the image on Railway:
1. Create a service from the image `ghcr.io/morencyr/openprofit:latest`.
2. Add a Postgres database to the project.
diff --git a/src/legal/privacy.md b/src/legal/privacy.md
index dd1d90b..7599b53 100644
--- a/src/legal/privacy.md
+++ b/src/legal/privacy.md
@@ -1,6 +1,6 @@
# Privacy Policy
-Last updated: October 9, 2026. Added the Bank of Canada to section 3.
+Last updated: October 22, 2026. Moved hosting from Railway to OVH and added Cloudflare to section 3.
This policy explains what personal information OpenProfit collects, why, and what you can do about it. OpenProfit is operated by Lobbystack Inc., Montreal, Quebec, Canada ("we", "us"). It covers the hosted service at openprofit.dev. If you run the open-source software on your own server, we receive nothing from it unless you switch on the usage ping described in section 5.
@@ -45,7 +45,8 @@ We do not sell personal information and we do not share it with advertisers. We
| Service | Purpose | Location |
| --- | --- | --- |
-| Railway | Hosting and database | United States |
+| OVH US LLC | Hosting and database | United States |
+| Cloudflare, Inc. | Network in front of the Service; it sees each request, including your IP address | United States, served from its global network |
| Polar Software Inc. | Payments, invoices, tax, as merchant of record | United States and EU |
| Resend | Sending sign-in links, alerts and the weekly email | United States |
| PostHog Inc. | Product analytics, web analytics without cookies, and session replay while Analytics is on; server logs and error reports | United States |
@@ -53,7 +54,7 @@ We do not sell personal information and we do not share it with advertisers. We
| Frankfurter (European Central Bank data) | Exchange rates; receives no personal data | EU |
| Bank of Canada | Exchange rates into Canadian dollars; receives no personal data | Canada |
-When we send browser analytics through PostHog's managed reverse proxy, the requests pass through Cloudflare, Inc., which PostHog lists as its subprocessor for that service.
+Browser analytics we send through PostHog's managed reverse proxy also pass through Cloudflare, Inc., which PostHog lists as its subprocessor for that service.
Each provider you connect receives API calls from us using your credential. Those calls contain nothing about you beyond the credential itself.
diff --git a/src/legal/security.md b/src/legal/security.md
index 59e081d..e7b8a59 100644
--- a/src/legal/security.md
+++ b/src/legal/security.md
@@ -69,7 +69,7 @@ A self-hosted copy sends us nothing unless you switch on its daily usage ping, w
- You sign in with an email link, GitHub or Google. OpenProfit stores no passwords.
- Product analytics record what you do in the app, never amounts, keys or data from your providers. Switch them off in **Settings**.
-- The hosted version runs on Railway in the United States. The [Privacy Policy](/privacy) lists every company that handles your data, and the [Cookie Policy](/cookies) lists each cookie.
+- The hosted version runs on OVH servers in the United States, behind Cloudflare. The [Privacy Policy](/privacy) lists every company that handles your data, and the [Cookie Policy](/cookies) lists each cookie.
- To delete a workspace or your account, email hello@openprofit.dev.
## Report a vulnerability
diff --git a/src/server/ratelimit.server.ts b/src/server/ratelimit.server.ts
index 52290c9..d9257fb 100644
--- a/src/server/ratelimit.server.ts
+++ b/src/server/ratelimit.server.ts
@@ -4,6 +4,9 @@ import { getRequestIP } from "@tanstack/react-start/server";
// - Railway's edge sets X-Real-IP to the client's address, overwriting what
// the client sent, and services behind it can't be reached directly:
// https://docs.railway.com/networking/public-networking/specs-and-limits
+// - CLIENT_IP_HEADER=name: a CDN in front sets this header to the client's
+// address (Cloudflare's CF-Connecting-IP). Only safe when the server
+// accepts traffic from that CDN alone, since anyone else could send it.
// - TRUST_PROXY=N: the instance sits behind N reverse proxies (nginx, Caddy,
// Traefik, a load balancer), each appending the address it saw to
// X-Forwarded-For. The Nth entry from the end is the client; entries
@@ -11,8 +14,13 @@ import { getRequestIP } from "@tanstack/react-start/server";
// - Otherwise the client could send either header, so the socket counts.
const raw = process.env.TRUST_PROXY;
const hops = raw === "true" ? 1 : Math.max(0, Math.floor(Number(raw)) || 0);
+const ipHeader = process.env.CLIENT_IP_HEADER?.trim().toLowerCase();
export function clientIp(request: Request) {
+ if (ipHeader) {
+ const ip = request.headers.get(ipHeader)?.trim();
+ if (ip) return ip;
+ }
if (process.env.RAILWAY_ENVIRONMENT_ID) {
const real = request.headers.get("x-real-ip");
if (real) return real;
From 68f25e88bd1568750f341934e6a52a5bf3e983d4 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Thu, 22 Oct 2026 12:52:27 -0400
Subject: [PATCH 24/26] CLAUDE.md: openprofit.dev is registered through Railway
Domains
---
CLAUDE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 91b817d..edb9526 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -105,4 +105,4 @@ Before editing files for a substantial task:
Pull requests run `.github/workflows/check.yml`. A push to `main` runs `.github/workflows/docker.yml`: the same checks, then it publishes `ghcr.io/morencyr/openprofit:latest`, then calls the Dokploy deploy webhook (secret `DOKPLOY_DEPLOY_WEBHOOK`). A failed check stops the image and the deploy.
-Production runs on Dokploy at deploy.lobbystack.com: project `OpenProfit`, application `web` (Docker source, that image, port 3000) and a `postgres` service (Postgres 18, reached over `dokploy-network`). Env vars live on the Dokploy application. The server's firewall admits ports 80 and 443 from Cloudflare only, so openprofit.dev's DNS is on Cloudflare (proxied, SSL mode Full) and the app reads the client's address from `CLIENT_IP_HEADER=cf-connecting-ip`. Records for mail (iCloud), Resend (`send`) and the PostHog proxy (`e`) stay DNS-only. Cloudflare may cache `.xml` responses, so give those an explicit `Cache-Control`.
+Production runs on Dokploy at deploy.lobbystack.com: project `OpenProfit`, application `web` (Docker source, that image, port 3000) and a `postgres` service (Postgres 18, reached over `dokploy-network`). Env vars live on the Dokploy application. The server's firewall admits ports 80 and 443 from Cloudflare only, so openprofit.dev's DNS is on Cloudflare (proxied, SSL mode Full). The domain is registered through Railway Domains (workspace level, not tied to a project), with its nameservers delegated to Cloudflare and the app reads the client's address from `CLIENT_IP_HEADER=cf-connecting-ip`. Records for mail (iCloud), Resend (`send`) and the PostHog proxy (`e`) stay DNS-only. Cloudflare may cache `.xml` responses, so give those an explicit `Cache-Control`.
From 3e7b48f30ccc2eb526e8efd0e0bbc685576b924e Mon Sep 17 00:00:00 2001
From: morencyr
Date: Fri, 23 Oct 2026 03:00:10 -0400
Subject: [PATCH 25/26] Add a script that re-encrypts stored secrets under a
new SECRET_KEY
scripts/rotate-secret-key.ts decrypts connection credentials and the
alert channels' Slack and webhook values with OLD_SECRET_KEY and
encrypts them with SECRET_KEY, in one transaction. --dry-run rolls
back. Values the new key already opens are skipped, so reruns are safe.
encrypt and decrypt take an optional key for it.
---
scripts/rotate-secret-key.ts | 80 ++++++++++++++++++++++++++++++++++++
src/docs/environment.md | 2 +-
src/lib/crypto.ts | 23 +++++++----
3 files changed, 96 insertions(+), 9 deletions(-)
create mode 100644 scripts/rotate-secret-key.ts
diff --git a/scripts/rotate-secret-key.ts b/scripts/rotate-secret-key.ts
new file mode 100644
index 0000000..c7837be
--- /dev/null
+++ b/scripts/rotate-secret-key.ts
@@ -0,0 +1,80 @@
+// Re-encrypts every stored secret from OLD_SECRET_KEY to SECRET_KEY: connection
+// credentials and the alert channels' Slack and webhook values.
+//
+// OLD_SECRET_KEY= SECRET_KEY= SYNC_SCHEDULER=off \
+// DATABASE_URL= bun scripts/rotate-secret-key.ts [--dry-run]
+//
+// One transaction: a value that neither key opens aborts the whole run and
+// nothing is written. Values the new key already opens are left as they are,
+// so a second run is safe. Stop the app first (PGlite allows one process),
+// then start it with the new SECRET_KEY. Sessions and pending SMS codes are
+// signed with the key, so everyone signs in again.
+import { eq } from "drizzle-orm";
+import { db, schema } from "#/db";
+import { decrypt, encrypt, importSecret } from "#/lib/crypto";
+
+const dryRun = process.argv.includes("--dry-run");
+if (process.env.OLD_SECRET_KEY === process.env.SECRET_KEY)
+ throw new Error("OLD_SECRET_KEY and SECRET_KEY are the same");
+const oldKey = await importSecret(process.env.OLD_SECRET_KEY);
+const newKey = await importSecret(process.env.SECRET_KEY);
+
+// The value under the new key, or null when it already is.
+async function reencrypt(payload: string, where: string) {
+ if (await decrypt(payload, newKey).then(() => true, () => false)) return null;
+ const value = await decrypt(payload, oldKey).catch(() => {
+ throw new Error(`${where}: neither key decrypts it`);
+ });
+ return encrypt(value, newKey);
+}
+
+const counts = { connections: 0, channels: 0, current: 0 };
+
+await db.transaction(async (tx) => {
+ const conns = await tx
+ .select({
+ id: schema.connections.id,
+ credentials: schema.connections.credentials,
+ })
+ .from(schema.connections);
+ for (const c of conns) {
+ const credentials = await reencrypt(c.credentials, `connection ${c.id}`);
+ if (!credentials) {
+ counts.current++;
+ continue;
+ }
+ await tx
+ .update(schema.connections)
+ .set({ credentials })
+ .where(eq(schema.connections.id, c.id));
+ counts.connections++;
+ }
+
+ const channels = await tx.select().from(schema.alertChannels);
+ for (const ch of channels) {
+ const set: Partial = {};
+ for (const field of ["slackWebhook", "webhookUrl", "webhookSecret"] as const) {
+ const payload = ch[field];
+ if (!payload) continue;
+ const next = await reencrypt(payload, `${field} of workspace ${ch.workspaceId}`);
+ if (next) set[field] = next;
+ else counts.current++;
+ }
+ if (Object.keys(set).length === 0) continue;
+ await tx
+ .update(schema.alertChannels)
+ .set(set)
+ .where(eq(schema.alertChannels.workspaceId, ch.workspaceId));
+ counts.channels++;
+ }
+
+ if (dryRun) tx.rollback();
+}).catch((e) => {
+ // Drizzle's rollback() throws to end the transaction.
+ if (!(dryRun && e?.constructor?.name === "TransactionRollbackError")) throw e;
+});
+
+console.log(
+ `${dryRun ? "Dry run: would re-encrypt" : "Re-encrypted"} ${counts.connections} connections and ${counts.channels} alert channel rows; ${counts.current} values already used the new key.`,
+);
+process.exit(0);
diff --git a/src/docs/environment.md b/src/docs/environment.md
index 6f10234..27e4a1b 100644
--- a/src/docs/environment.md
+++ b/src/docs/environment.md
@@ -14,7 +14,7 @@ An instance doesn’t start correctly without these two:
| Variable | Default | Purpose |
| --- | --- | --- |
-| `SECRET_KEY` | None | 32 random bytes encoded as base64. Encrypts provider keys and signs sessions. Changing it makes stored provider keys unreadable |
+| `SECRET_KEY` | None | 32 random bytes encoded as base64. Encrypts provider keys and signs sessions. To change it, stop the app and run `OLD_SECRET_KEY= SECRET_KEY= bun scripts/rotate-secret-key.ts` against the database, or the app can't read the stored provider keys. Everyone signs in again |
| `APP_URL` | `http://localhost:3000` | Public address of the instance. Sign-in links point here |
## Database
diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts
index 87faeed..935b2da 100644
--- a/src/lib/crypto.ts
+++ b/src/lib/crypto.ts
@@ -8,16 +8,20 @@ const dec = new TextDecoder();
let cachedKey: CryptoKey | null = null;
-async function key() {
- if (cachedKey) return cachedKey;
- const raw = process.env.SECRET_KEY;
+// Imports a base64 SECRET_KEY. scripts/rotate-secret-key.ts passes the old
+// and new keys explicitly; everything else uses the one in the environment.
+export async function importSecret(raw: string | undefined) {
if (!raw) throw new Error("SECRET_KEY is not set");
const bytes = Uint8Array.from(atob(raw), (c) => c.charCodeAt(0));
if (bytes.length !== 32) throw new Error("SECRET_KEY must be 32 bytes");
- cachedKey = await crypto.subtle.importKey("raw", bytes, "AES-GCM", false, [
+ return crypto.subtle.importKey("raw", bytes, "AES-GCM", false, [
"encrypt",
"decrypt",
]);
+}
+
+async function key() {
+ cachedKey ??= await importSecret(process.env.SECRET_KEY);
return cachedKey;
}
@@ -25,23 +29,26 @@ const toB64 = (b: Uint8Array) => btoa(String.fromCharCode(...b));
const fromB64 = (s: string) => Uint8Array.from(atob(s), (c) => c.charCodeAt(0));
// Output: "v1.." with both parts base64.
-export async function encrypt(value: unknown) {
+export async function encrypt(value: unknown, k?: CryptoKey) {
const iv = crypto.getRandomValues(new Uint8Array(12));
const data = enc.encode(JSON.stringify(value));
const out = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
- await key(),
+ k ?? (await key()),
data,
);
return `v1.${toB64(iv)}.${toB64(new Uint8Array(out))}`;
}
-export async function decrypt(payload: string): Promise {
+export async function decrypt(
+ payload: string,
+ k?: CryptoKey,
+): Promise {
const [version, iv, body] = payload.split(".");
if (version !== "v1" || !iv || !body) throw new Error("Bad ciphertext");
const out = await crypto.subtle.decrypt(
{ name: "AES-GCM", iv: fromB64(iv) },
- await key(),
+ k ?? (await key()),
fromB64(body),
);
return JSON.parse(dec.decode(out)) as T;
From 4b5ef5d326006ab48a5ad71e86d9191e2896a055 Mon Sep 17 00:00:00 2001
From: morencyr
Date: Fri, 23 Oct 2026 11:13:46 -0400
Subject: [PATCH 26/26] Run on Bun 1.4.4 for CVE-2026-111497
Bun before 1.4.4 bundles a Brotli decoder with an out-of-bounds write.
fetch() decompresses response bodies, and hosted workspaces choose
their alert webhook URLs, so a workspace could answer with a crafted
body. The image now pins oven/bun:1.4.4-alpine instead of the 1.3 tag,
and packageManager pins the same version for CI.
---
Dockerfile | 4 ++--
package.json | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index b18040b..236c84a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Single-container self-host. PGlite data lives on the /app/data volume.
-FROM oven/bun:1.3-alpine AS build
+FROM oven/bun:1.4.4-alpine AS build
WORKDIR /app
COPY package.json bun.lock ./
COPY packages/cli/package.json packages/cli/
@@ -7,7 +7,7 @@ RUN bun install --frozen-lockfile
COPY . .
RUN bun run build
-FROM oven/bun:1.3-alpine
+FROM oven/bun:1.4.4-alpine
WORKDIR /app
ENV NODE_ENV=production
ENV DATABASE_URL=/app/data/openprofit
diff --git a/package.json b/package.json
index bb77d40..cf17890 100644
--- a/package.json
+++ b/package.json
@@ -76,7 +76,7 @@
"typescript": "^6.0.2",
"vite": "^8.0.0"
},
- "packageManager": "bun@1.3.14",
+ "packageManager": "bun@1.4.4",
"version": "0.1.0",
"intent": {
"skills": [