From e30a7d184b9e748154d06b12d58e88726e49cf7d Mon Sep 17 00:00:00 2001 From: leedj312 Date: Tue, 22 Jul 2025 15:57:20 +0900 Subject: [PATCH 01/27] =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=20=EC=9E=91=EC=97=85=EC=A4=91=20=EC=9E=91=EC=97=85=ED=95=B4?= =?UTF-8?q?=EC=95=BC=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 46 +++++++++++-------- .../prfmncSttn/chkgdnSttn/page.tsx | 2 + apps/wr/app/store/common/auth/index.tsx | 17 +------ 3 files changed, 29 insertions(+), 36 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 5a962fc0a..05714a336 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -47,8 +47,10 @@ export default function PublicReuseFaciltyInsert() { pubHasuSearch, pbnstRuseBizUpdate, } = useWrStore((state) => state); + const { t } = useTranslation("base"); const { pubFacHeadList, pbnstHasuResCount, pbnstHasuRes, pbnstRes } = pbnst; + const [, setCurrentTab] = useState("mng"); const [isRuseReg, setIsRuseReg] = useState<{ isModal: boolean; @@ -262,6 +264,13 @@ export default function PublicReuseFaciltyInsert() { isResetPage(false); }, [pageNation, pubHasuInit]); + const { auth } = useWrStore((state) => state); + const { mngAuthrtYn, inqAuthrtYn, regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn } =auth; + useEffect(() => { + console.log("auth", mngAuthrtYn, inqAuthrtYn, regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn); + }, [mngAuthrtYn, inqAuthrtYn, regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn]); + + return ( <> @@ -283,12 +292,12 @@ export default function PublicReuseFaciltyInsert() { className="" size={"sm"} onClick={() => { - if (searchTxt && searchTxt?.length > 0) { - pubHasuSearch(String(pageNation), "41", searchTxt); - } else { - pubHasuInit(String(pageNation), "41"); - } - isResetPage(true); + if (searchTxt && searchTxt?.length > 0) { + pubHasuSearch(String(pageNation), "41", searchTxt); + } else { + pubHasuInit(String(pageNation), "41"); + } + isResetPage(true); }} > 조회 @@ -319,19 +328,17 @@ export default function PublicReuseFaciltyInsert() {
- {/* */} - {" "} - {/* 높이 조정 */} - + {/* */} {/* 높이 조정 */} + {/* */}
@@ -377,7 +384,6 @@ export default function PublicReuseFaciltyInsert() { indexBiz={indexBiz} /> - ) : ( diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx index a2955f386..d5127f19d 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx @@ -99,7 +99,9 @@ export default function Page() { isRainSttn(true) rainChkSttnInit(1, rainPageSize, new Date().getFullYear().toString(), commonCd); setIsModal({ data: {}, open: false }); + } + }, [rainChkSttn.isInit, rainChkSttnInit, rainPageSize]); useEffect(() => { diff --git a/apps/wr/app/store/common/auth/index.tsx b/apps/wr/app/store/common/auth/index.tsx index 4e0b08d1b..21be6e01c 100644 --- a/apps/wr/app/store/common/auth/index.tsx +++ b/apps/wr/app/store/common/auth/index.tsx @@ -1,21 +1,6 @@ -import { getFetch, getFetchWithCount } from "@/components/lib/api"; +import { getFetchWithCount } from "@/components/lib/api"; import toast from "react-hot-toast"; -export const getMenuAuthrts = async (menuCd: number) => { - const response = await getFetch( - "LOCAL", - `/cms-service/api/v1/menu-authrts/pageinfo/${menuCd}` - ); - - authStateExport.auth = { - mngAuthrtYn: response[0].mngAuthrtYn, - inqAuthrtYn: response[0].mngAuthrtYn, - regAuthrtYn: response[0].mngAuthrtYn, - mdfcnAuthrtYn: response[0].mngAuthrtYn, - delAuthrtYn: response[0].mngAuthrtYn, - }; -}; - export type authState = { auth: { mngAuthrtYn: string; From accc3e0ef16b063064afef12d55bacabadad8292 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Wed, 23 Jul 2025 13:13:33 +0900 Subject: [PATCH 02/27] =?UTF-8?q?=EB=B9=97=EB=AC=BC=20=EC=97=91=EC=85=80?= =?UTF-8?q?=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/rainSttn/excel.tsx | 10 ++++++---- apps/wr/components/lib/func/TableData.tsx | 4 +++- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 1 + apps/wr/public/sample_rainSttn.xlsx | Bin 10734 -> 10810 bytes apps/wr/public/sample_rswtSttn.xlsx | Bin 10848 -> 10856 bytes 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx index 3de4ee1a6..b57e0edde 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx @@ -1,6 +1,7 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customRainBdst } from "../../fcltReg/rainReg"; - +import { bdstUsgCd } from "@/app/store/common/code/basicCode"; +//TODO: 공통코드시 삭제되니 수정 해야됨 export const excelRainSttnParsing = ( excel: { data: customRainBdst[] }, sidoCode: SelectDataType[], @@ -9,14 +10,15 @@ export const excelRainSttnParsing = ( const excelExportData: string[][] = []; excel.data.forEach((item) => { + console.log("item", item) excelExportData.push([ sidoCode.find((sido) => sido.val === item.ctpvCd?.toString())?.text ?? "", sggCode.find((sgg) => sgg.val === item.sggCd?.toString())?.text ?? "", item.bdstNm ?? "", item.daddr ?? "", - String(item.bdstInfoSn ?? ""), + bdstUsgCd.find((cd) => cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 String(item.frstArchPrmsnDt ?? ""), - String(item.archArea ?? ""), + String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]), String(item.chgBuilding.length > 0 ? "Y" : "N"), String(item.reuseBuilding?.[0]?.lawTrgtYn ?? ""), String(item.reuseBuilding?.[0]?.instlCmptnDt ?? ""), @@ -28,7 +30,7 @@ export const excelRainSttnParsing = ( String(item.reuseBuilding?.[0]?.rainyObj?.filtrTrtmfctPrs ?? ""), String(item.reuseBuilding?.[0]?.rainyObj?.dtfcltCpct ?? ""), String(item.reuseBuilding?.[0]?.instlCstSprtYn ?? ""), - String(item.reuseBuilding?.[0]?.instlCstSprtAmt ?? ""), + String(item.reuseBuilding?.[0]?.instlCstSprtAmt === -1 ? "확인불가" : String(item.reuseBuilding?.[0]?.instlCstSprtAmt) ?? ""), String(item.reuseBuilding?.[0]?.grntchBdstCertYn ?? ""), String(item.reuseBuilding?.[0]?.grntchBdstCertYr ?? ""), String(item.reuseBuilding?.[0]?.grntchBdstCertNo ?? ""), diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index 24e6349a9..4440e3e54 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -339,7 +339,9 @@ export const InputTableBody = ( // className={`${head.id !== "utztnUsgCd" ? "text-right" : "text-center"} !text-xl h-10 w-full`} className={`${textAlignClass} !text-xl h-10 w-full`} onChange={(e) => - handleChange(dataIndex, head.id, e.target.value, setInputData) + handleCommaNumberChange(e, val => + handleChange(dataIndex, head.id, String(val), setInputData) + ) } value={formatCommaNumber(data[head.id as keyof any]) ?? ""} maxLength={numSize} diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index 2b52bd50e..2da752028 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -511,6 +511,7 @@ export default function RainRegForm({ selectArray={code.bdstIncenYn} onSelectValue={readonly ? () => { } : field.onChange} value={field.value ?? code.yn[0]?.val} + readOnly={readonly} /> )} diff --git a/apps/wr/public/sample_rainSttn.xlsx b/apps/wr/public/sample_rainSttn.xlsx index f00a520cf6e2c26951ab8e345e30d95ce40b631f..f3e7a5ba86f0c084a54dc2c4470b6492cfb8d29d 100644 GIT binary patch delta 2799 zcmY+Gc{~#iAIGY*=il1#6b04dv%vt2D+=g=fkQ8Ez z+%z?&%sKiYcb=Z-kLUM1-+#ZK&tIR{>-~DO9NV18;FI`RKR07K5CEXE0RVge000ww z1|51g$R{*32#!Gomyzt!X|nvu>sk9U{5!z`(NcRx?!TXexPnGwQj7bbJie0|2FX&b$)~;ICGX;AZ zKVFff1g81Pj64;ByyJN#I3w|gyU`^lEk&#YKJ?<%kqFgR>UFuf+ZhGq&f`I+7IUP0 z-lnI-T(QccV2*#Hm}KOl5!jS*`(AWM?r7PeZ%={ZqLgiQ%9WP2M$0*9HM4Zf>-;8J z`*SI7sQb9i>2U{(SK?Ak*N};8*ABn1TDTNs$aRgCyZ*t;&t%eVdy)LNu5%5s^_&O+ zKU+EMd}M$5ZPnS=)6cVxi*)9T_t`0h$b7~mG82oTTs>j2<1$26NU8Zmgzyjw?&#m| zYv~Xnu7lcKHHJZ2Ytd}=D>xGu8E2gztg{igBaC@|+QV9U%EK-=O_P1;9x&dAX+ zfw2AiXZsWSb(8o?_xdXYDD>ZBA0LyRv+;wf*Y9+vp8x>FxJi;cQur?+BVOW$IzObJ zJi820@RwLTl}*KXHJEk8x(@`L@T@;_eGe7wGPWq8Bo`sgb=(lSh#1jS%=u^AQLS9` zCf!Hz)3emF+ao(n>~Udo(@h1&OlOH?rA7B)^3YH?=<(}Ro1fi>qsn?{ZR}u?V4Bq( zBFx*cM*J`vbKv{|frq7ZzUSW5v?1+qynWQ3)*{xVVX@PVpOBHYw zev--qd~;m;=#f)*ctf`QIVu;MevbU|W@baQBLAgi)#P&Vt+)%ZGXc0M{{%s4KRy_HA^uYO7X@4+*LDJycS5C9n5r7I?W)2y%~t+u%CA>Q4bAyZwVhHw zI>La>x{|$5IsU{H%9s=nJb6~@ji}P|=@a`@(O|(tvJ_888@%guo(rdi^uA;;##XzS zkll@5NADQ!X*^?`d(}bPmao?vOlvm|+@|R|rgvLMY5!3^UY{^YzU~n(Hnfy7zBZ54 z$V+mpp{?TwgL_$_3SVx9=<0QUi4cL23vb{Igu?1Q?;aqfLbX23=X90|EQ6#C7Ni5t zy%=cHS5+Lte7>feeAjja?B~-aF!hSa&Xq}c(_j=LiYLr1q|uKsfncr zl)4X#yc1o1%aTm!Z2FBuFsYbLxN#7C%yTMT)qhQq9RN@R0|4Rx(ke^>pYKAu%h2VI zrdJ+uWzo5OAKS)*azSW8Q$gAOP7t(9g!cD7BZIu-UE(}~@<_Y3Z#Ehwz+xuvvIfrEt>D>L(GItx( zOowyk3M+agCQ5 z!#9Y*Y@m#!cC3X}^C-mHIK4MkV+P@)q5HEHqwbbrCmbV7-s4}a-QcLE1z}=d`tfWD zr!^l^LQD1n<$MGJ>yr(!W|Ux6?KWjb%i1;&0d}+A^HEpss<`xE#ywYDe{8r4HpM4= zZ@-SXZ#wevum=@<*YR8C(x$$$ zxV4B}!^!qhJo0a%ak|{N{=9`IP><{KN}1b%kxYSeKy~c{H(CPqE&7yY)Y>Nt3O*_L z-Bp_%<2VWTr_!9ZdDSE~-`F@gP785yU$6MMAl@0LZ!yk;(F9b8CgNS!X-<~rMr<6` zT%P&eOmxaWEzXix-+LCqc4IWnm%iMWYG}nM=YbC3jXou5s;$TyH|QcBHiX#)OqZ=| zJ(}Qzv;7&dsAXSa37?O;kbdWF08Yff=1<1OR+wIEBqYbLmq-ba$2vRhjaldgH@8q5 zL6T!n^n%0Ffl=3rf0lr#YK)=~4KmFy3A{{)HetKFHpPm{ZY}1Ne%qvYehurbZu!io z;}MG&9<3>o?e7vob~5(G#l5^z;{-T+Il}yJD$`a^`g{1!a{o0-=^sJdvD^-xf;ytIOgfK_R(gL_JK5Osepqs2O@OUx|&`1ZoH!gmX!D#2!_L)HV|{_cwklh0ARjLLozm z?q)`EVWUu_Ia&U5R>ztj@^%jtTtcG6pQ$ta$Fl-j6x zM)gGKoAR2*U~=C~6zdFgM!~JHYD6zi+g!s@n3EkVi`4*Ot%l+BUA1ozN|~3RhMc*E z_^UzIx?nA=?tJ^Adt4KT_|W6uTzS42P*Wl<8IwrJ>ryETVg=p6Ypy)pj}@6OTm|UL z--=Ts+af4oTwCK-W@2TtP-OH{0~hzh;zUr{d0k%9!_wD9YMV@BdLFE*yJ^6$ZK|Mw zL*_~8elWpd>YUxD_Z?uS(ff58bJDQV^FxS>lzle$l~zvwpn^a5u0_Fx^i?8x)br}E zH?Kqk8O0wXIV0j7@RNEK$&SMv4x&4RAB(IdUvN&`M!v(v_id418GSEt2@R=c;f3ml zso!o{|Dj1_$`m|*x;MCMUk>m6r3gQQ4O*MM6DhDub1|OK>pW7Q)@k&TRp2`LUy~#e zmCs52;}igZ@Nd=l=XiKXGCZQBBp5%54JHAklB8kwz(G{4aI0f2(d9NNhU`~=5T^633-wtYd4?d&un z)pIF^a$KPkR<`K_9pwGqDINVNhKQfxGGA}2w|<~r-3f^Hq$3I6UOIi6ikeHt0b{QD z=3>s2HLC~7f!CBlEiHwv{+p(3C)I7aClTk}H?7pN3eZ*@T zFWM8}RW&bu4=cr-7KU~mY0T_&z`b&hfobS6We8MlPrPoKbCy%Z947tAdi8GSomM03 z;wC{UacE)1GAJuJN>9U?I5QCSFHDVHg*cxG`rXl zRlG3jv-JZdI}cUI#NO1J_19SfwUWgicj9G_b5dExl8z(i?S_r&BDb>fViSVF$N>)r zLe*iPr}aHzbt?#-kF%Qq^Xn{P}YdpOSdG>K~?>cQo(txg6)a%9U?qv-i^ zkgg%4ziAu#wVGe#33>=OI^(r$OAj&1jlZl*NYsgn5FufL(uC|yK%eXTh39@|&6!?w zx}6{;-!fUTxl(ZWa#mV{YLEQXp@VtYW# z(2Qb*B5~|J8mUe-7iwtt<%W%&gVw40u^lZQj>E8H9-*1_u=u$6)Y7SqDslrd?ja&4 z7jYT|uC2N6@3J%lZ(I#W64Ecqn-$Lo0cn5&bqSmg4_(X3&w%k+3d(!I2h{VeYHEHy zcTO<(bwy#9M!n>F`RfpLu8K zlaO4+`w?oe>p%W>_fDh1yDu{*YZi+9d6HGyC}9C7QNl-NMRyzq33`c!)b1}tnauB~ z2s{XrcvoA-O)U($pkV*u70YPCt|O5AWC@L6jRp3x{=rZkyd0kMVB0ufz)Tos``ei- zomspPZ|x^DsCzAJ%+O+g_crsz>UwkB_)L^$=bMP^yH4me@mxRK4q>e2Fj|u!*4l(3 zZMntSRSySJvY$;7lF6zxjV}{=kZmHHn2yv+L{Td`-(fzPuU!d~Vqcv=d(Ww<*IO~y zdm(n?J8d=RVIZy4zp%tV&xj`y+MUW7O9aLqvO3X`b+-Xnlh;&Z1CU}iiP;lvzUn!UCF%sCDPr|cj%~4 z`9xPp`kakhGf3q`C4D)lu4EB`ibZ$x%N-C4*+m+r_z#ZojWrhpt{3WzulRU~9l zxjj$iaEKs9*1k$g_ctKfZ0nS3LS^SkoSC`5Rq)suybZ0yRXYMx{^Aay86O|bwR!*X{k)e zS{uW~oN%&Ue(jjK_sF?-Y_*#8xUUKjUutr12VvADZMGalH0#NPSMAE`V)|WMBs7^h zCh21Veqz$c?c&Kkw~U_iq?3PSM2URz69l90cD~Er`laAL=9eY@6TxaB=>8G_IZ^Nf z!d>=OBxLPwTRL-Ghy*yRZa(bV{ASo zT@S{d{cZ7d+R}Hdlz){FCkMLV)J2{p4+j6_>X%0+&E^B2!3}>wAZ~6CqmOa*LbBc5 z5~7tr&Mg&hH^*@Peac*GNdJ^*ZjiQz+v1}B3jY1=J~s9%kdWT?BV3^`1s)Vf3_+r$ z1j?ewzoo8zswKlMQ{h`lvGC8SqoIB6n7nbQVHTr-0%=a#&?0z#S5sL@y4<6Qnraok zzEhzzQkm%7oCJw?4ugFvkmReUD9gcT-*9%H6C<#n%m4h?9_PZR@A`VfD%GB@1O7VBEy(GxacoI%qgz^mayaO|_aG*D zsYqH%I}FyxttvUN9c&-`Jb!P+kJ2=i{ybVhsJVfDHyoJq9a#PAF=x?Ss6Vh%Auh() zS>o665Pp|Et+I8kW)`AsJv=0c=f}?C4`Ig_#;^il5n(RO-pd5`iP~cv*9rG$oG$W* zIES0UB!I`;WWbg&Ua#Xiqx~7;2DI5A#(4vpVi3dFpd&j!LKeKH+5VKS6+GP|N)D72 z@}B;vcJAfLIHh;tq94eM^{N{+qEs$X-!5Fv)I(=(I67;88r68c@+LEv|2(oDrdnRA ze(A;nW=S;nuD}n6QCFM~d@ypo6t#52o`X}VDL1jr-DCNDsnCa$nKO6=M2T7gFZ)$% zAhhyZWl&VDp9Y#gBaM&zVV+iW``%hexKLF8_v8$E{V8*gLu0wF3$D@vuB6%qv9dE2TT2O4u}zHiE!Kf3Iodr%T(;&&c;Q^`m+U(6jwN99(Ygmas#tC< zD5~7IY1b3f@5nw>Htv=O5XYz0pBg(X=NzBHxBeV>wJ!#Ckm@XdQW zZ*cNc-Wa!%y!*tR%l06R)&o#mO}^{>@;WPbd(hDeO{E;*ild=H{H_Ur4k5ubeMXkTTGQ*6904ovO0!Wl9ZeJ1KWu=VOGFSVhij7aE`bKlNSGPC<6eHe~bU_ZNzhMC5gX(cZi$#L*6*{ jKl_Cf#7MXfo0l|kNE%LDge$WBkR=K!%5c@o|E2pA9VQ$f diff --git a/apps/wr/public/sample_rswtSttn.xlsx b/apps/wr/public/sample_rswtSttn.xlsx index d97a79b6de6b52df015f9960225de3d41cd5921a..cec85971d65b2710e68f9de5473fd808795f6264 100644 GIT binary patch delta 2950 zcmZveXEYlM8^;s1qLreF-QEx-K~XJA?AjN#N^PlCH9~OJYKT>Pq}+-)2I z0E9aTZd|E_5oSc4qYb|GTXmax+!YSkR}~A*#ctr^h|K2X=a0PW1+*|o{j?ITVph%R zzhWyKD|+-i)-2+C+84g((OAl^YZV!%RbX0C4Vc-!(AM5=&nl5N+1|d_l?EF%lqW7j zZ|!APNd^weIP9iSI`6oLhV_$KDmq>*LxwAjr*y!I>xX!FkI1f%;fCabh)D<9BV~{U}QHLCl zgp;&d*&1gk!HInIY6rE*I+l|_ziEeAo<7+R%_+O)(-#jq_U0>ujN2@{=HnYUSYiO5 zr*y7?Rl6jS?*xnUkrA-23<<4l!m&-vdtBS-Q-0?Pxn;`;Cq{P-wswj%p_M{@uNvan zXcThUkFUSWn9~uUurt{ECClh&gyA?#FO1yjuCZ>EbM{zA>+Ew$L`Lfs?mJ~sZSG7T zn12vFs-$(iktjRieSDqI8erYqZT7hWZ;x6`YndqAV8;ihku@91Ku7O!xm zp&8H3fYzZ-)m_1+;-%(PIij^M_R;jK9!8Rq!J0wH*0ggT#yf1_U11~+5F}m zsl4}UyWq#d);Vp+=zg^qcoY{92pwM_YOhg)x!u>sZfSCu zj-WHwps%(lo_;^1*pB5LbR}v%YgsjRG@1v5uRSN+;DzJ30t8*{`H3ph3Os zPDA9o!`W>5bHFq(=IW5K$QM(6Z9+)DZM?gJ3;M$6)E!0uK$oz^2gj}5;+VNJMvMAC_QLFuC8_3g8^z;3&N9Bp$!ysJv$MhYIVD9?T<>Qy6A44Ke ztul(c)BPdaOXWXY@FFO#y6F9B4Dn6-F^)cV>OxaNnTZRU=+)#r2 zCH(UnEj+jRwN-)`BdW<+bwP?)wp{t>o>5jlJfkqJkl6MnHsh=W-v!s&?M+)A)IN-V zF^@-~TExorBqx_u*e~h=cbYwlB=i#c*k{92A8@Oi!v3hT`SgVK%O-YzRXrS?Z;dl3 zwGB&>veS(ZuqousmF-+KJ5(q>^?|uEo0TtjDZ%bBpFdqG`D6SfVwFXaLMrSy9(`5> z>M2F0A_c5LawBh;!>lRT;K$*?cNAGNOY*O|poOFr zi(i!7zvlmKTbcU>*@lu^CHvQuraX>&`=JmyA1>qfeCT6Rb*K*C!3X=2%y3YY0 zf#;yVxqID^TI0)|Ncya_G~i}8#&;mU)H3jFDk(>4snd;CedCI^PWiwykM90#bQt`z zzfojP$!-nixJhVJ$EH94q2s{A4uRK6vyaHhwvIyDlqc zY>Hz_NMl-)pebq+H3#)oJ^NnkrR&c5{}50tqZRVw`#=-=vr|2BIj^HXzhc}FyLF8{Y{R+P&?^jN zZ+J;n{m@czdWcW>f@MRX4r|nsS6Gq^?_jqWYZTp!21eHwCEwv>-kCgPKvQFr+hG^L z9`~fXd~Z%1@}nmv8tEIYs=O{z{^TAHs-&%xPkqpgA{1 zhJEH{cLyK3;#1!&PtU0wWOxOp1yY&1Et7jq1vw!Ri^&zEQo1?V%d>?YN@a{y0!)fZ zc)ybW{Q-}JI!b6-pU!O2+h*@1mjShYuxGd01lU)z zhwFD=oS_Wam*v8qmKNNM3aV5ynmNZvHi=@SNT!tV(jQ&s^`LvLWM-RNZd9BaJ5MXx zQZ;g?S!|8EN!}&$>&}O?>yJZ2!d9)=CB|kF&WX!*A{9F9oD-6n2n*IlD2M*)(CwgE zOV~zA$@1F`#qgg%W?`zv3dc$5+p>d;6n>}-NS|BCIu?Zdlp%^V@|kO`Yd>yvx~-A& zo_^IKPTwX&!oaLW&;7%t!XE0RJK`OXP;?GLAR{>%_F*b4Z2$FJf(pV6Xh%pxm;fCJ z3kXrMe{0RJ2B(Vx0PKK&jwBQSc;qGR9}w*2>Q6w6K?MHO_P;>hf1-eSf<00~;O}>7 p0RaH(Un;}X7^ar>6W7*{ZtGM$t;uRT;%RxDdpldU;5i(+KUsaH*o z+xoW3YIVyjv9e|HYDHZy6z-{2)22izIt|Kovi^W54QfAcSevT@Lu0m~abxkJ3!_0Y z31RqMQ@Nq3m*;7cdOPMN?uL50D=MPlU1PH=(tg zjr$w%-`m^AF!Nx)Espxx?}8;l%-Sel(tfxHt_Pnx;){PL#m1gE39(Q}ko9cz;@~|j zLCN_9{geoT7_ZDRWhLrs6At&JDs^Vi>aJP=f+?H?5`WLnvb*OelL&iDf~S>Q-j`M* zr}7f+TIzD_&Uy$8qYU993o6F$!kb=8fOvP7Or`GpQ^V0foX1P1S{dh_+r=k!Wy_)b zaS5lDD10oZhMxg-HXZu=^C0R!lL^@9u7}FgorhVlmbSnN_#xDSq zp#v1NY7Ni_1zv#_JBO1$6=DVW4QGZTlcp7of6ZX3wkFAFB1JAzbq1iWNK=}SZLVFn z>*8dM1h5Z7@9_aJ-+%r7@#kN3Q;IXnmPMl(ZM0PO&M2&z?&WGW zf7NUws94R|JOJPHO{Q4pU>haj?iPFn-8lyGebN}Aa*&ELR$J+!V$cU8Qbh6?TAlL! zW;uf;ZcMjfA~KVN`Y|?`eTYGf@7xDU5%)Z1aAk&j*yyy zV^&sHl8eosA*UxP=h$C!6OHcCl5^tmP4#_t9?hu}8?b@)7sGxcg5A&98y zuuAm`*ZA_axOEo=eH*W%71%Y{2%z~OTxXG%vy(R%BY!jKILf*-G+~N$`6Z(ho{?g} zppUDfGZm7)10WsVN}!!cq@$9GCiR-P63=eP!c3=EY?0o*)_3vOvA~Trv5dcOy8)*27fI`~^Xj?9T?G|La0oiUpUE3Y_+;#!rcXhiD5pb`uTL9aA zAh2Bnfm7{Q8QV9Z=e7r#5C{Z4YLS(VxXLO*;^tWn*H3@EukAylIc19S&%{&! zbG%qbY0R(uO6Lig_|0k-aH%m#@tmofRbzzK@86IyooBFfl#?zQQ32SKfEh#`PJ z>b0OGDBdH47R6}7U1zQh{sohv0~879yh3eF1ONaxllK`Tf8sh2-QTMD2bcGQvGPO( zOc5S|BoGovvNlG5E4Jk;i#+D*Z%Z;Zw0x^(F`Ix-j!sM6NA0Hl>nn+!4<_=6rybXC zG+l?KAzw%7w&T7mM?bG!CznCG4q~3Nj{D7W_gDAFKkZL0-t!$}(gB4u@3=cDGwOMH zxMN9>H+aTUfB4UaizJZnD7Idn2^OsNq9pc6vw7(yL6o{ifr>xT;G0bpvH=hG2}`9B z5iAZQ>_6W{S$&d+PaKJ%mRjto`{ z7PC;YHI&J9RQgw(zboPdpe88hnxGVeP(~lD&*He_P6<@-Umasg=v2q>${^i#_5BcV zq-!=8&YEq4eJr2(=a@y?orK6&4RQf#P}!jC?*Yq0C0O^n}O^;u^GrRcQymn`rc-=PWSO(7*|Jz@llp_ zf9bg7*i=4B>#Qd6D6fw-6qML`4FzTPsb;?@waYrE~CF{)*{&6YRXM^(P5p`bGN4dt@D^8*YF zF)+fwEe6IIm|)-z1NRtsFu+l(GytjE)2uk&dDR*%WNsl(1#(d}M}xrMsy8C5FAU}U zn1YbQ_(^4JY zBlJdF1MR0zD0tk~84wCqxA7sN;CLG!5emk)@moT{|294$6kKoPb3(zBHvU8?e>k(| zyo5qevhgLM&{1rBOekDG8^0qIE*;=r<%e!N+rexvqYy^E4Ns+-CzY?hGZ=hR-sfrY z13@j!f-Rc{VjHEo6SIw;{owT=%zW5vs8u?dlON6QC`;MD&Aw>{Lh({yXrI@U>3nDeBv-MC2E?|m1 zemu;+H_Bm7?+m7F2VAlw&P;pDN%zSL;z=dY%a`m+jk!8SNYyKU@^t?Llc56?1R>V@ zZ?ktEH35IsxrMd^l|4BS+)#WA$=z0L(vU>EeS6bCtCa~p=ALtZ_uNaek zrzyskA3!o2d57}it~Qc6|1^878UJ8=zzHEUEWv*!;?aLyoy=3_IKWuAns3t=d$iOUF;qPBJe?IAN#DlrVo#s z6)G?ilH7)57A9mvW;97@vUqRD{_1ao^#wT$|Ce|dlKF<*(0D=PbV57>iVR_0QdxxMJQ4MSd*A2Pyt$#=_n=}UV#-mhXeos|0Vzc4FCWD z0000000000001bHDk&fw=)6L0O#}b{Hw^#)7ytkO0000000000007zth( From 0d48a0b579ec0b940391137c3d3065ee0504373d Mon Sep 17 00:00:00 2001 From: leedj312 Date: Wed, 23 Jul 2025 17:51:47 +0900 Subject: [PATCH 03/27] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EB=B3=84=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EA=B6=8C=ED=95=9C=EC=B2=B4?= =?UTF-8?q?=ED=81=AC,=20=EC=8B=9C=EC=84=A4=20=EB=93=B1=EB=A1=9D,=ED=98=84?= =?UTF-8?q?=ED=99=A9,=20=EC=88=98=EC=9A=94=EC=B2=98=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=20=EA=B9=8C=EC=A7=80=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/coSttn/page.tsx | 4 +++ .../app/ruseFcltMng/fcltReg/htdflReg/page.tsx | 13 ++++---- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 28 ++++++++--------- .../app/ruseFcltMng/fcltReg/rainReg/page.tsx | 27 +++++++++-------- .../app/ruseFcltMng/fcltReg/rswtReg/page.tsx | 6 +++- .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 24 ++++++++++++++- .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 30 +++++++------------ .../mngRegFormDetail/mngRegFormDetail.tsx | 19 +++++++++--- .../components/ui/searchInput/searchInput.tsx | 6 +++- .../ruseMngTableForm/ruseMngTableForm.tsx | 14 ++++++--- 10 files changed, 107 insertions(+), 64 deletions(-) diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index 992b1bdd1..8e2705450 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -33,6 +33,7 @@ import toast, { Toaster } from "react-hot-toast"; export default function CoSttn() { const { + auth, code, coSttn, coSttnInit, @@ -43,6 +44,7 @@ export default function CoSttn() { coSttnTxtSearch, demandCompList, } = useWrStore((state) => state); + const { regAuthrtYn, mdfcnAuthrtYn } = auth; const [bdstTable, setBdstTable] = useState(); const [pageNation, setPageNation] = useState(1); @@ -205,6 +207,7 @@ export default function CoSttn() { setUpdateData(undefined); setIsDmdModal({ ...isDmdModal, isMoal: true }); }} + disabled={regAuthrtYn === "N"} > 등록 @@ -222,6 +225,7 @@ export default function CoSttn() { }); } }} + disabled={mdfcnAuthrtYn === "N"} > 수정 diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx index 5d7480257..b0b2e7182 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -21,7 +21,7 @@ import { useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; export default function Home() { - const { code, htdfl, initHtdflReg, getHtdflBdstData, htdflNmSearch } = + const { auth,code, htdfl, initHtdflReg, getHtdflBdstData, htdflNmSearch } = useWrStore((state) => state); const [searchTxt, setSearchTxt] = useState(""); const [pageNation, setPageNation] = useState(1); @@ -30,12 +30,9 @@ export default function Home() { const [bdstTable, setbdstTable] = useState(); const [issNewReg, setIsNewReg] = useState(false); - // const [bdstChgProps, setBdstChgProps] = useState<{ - // isOpen: boolean; - // chgBuilding: chgBuilding[]; - // }>({ isOpen: false, chgBuilding: [] }); const { htdflRes ,htdflResCount} = htdfl; + const { regAuthrtYn, mdfcnAuthrtYn } = auth; useEffect(() => { if (!htdfl.isInit) { @@ -116,7 +113,10 @@ export default function Home() { > 조회 -
@@ -149,6 +149,7 @@ export default function Home() { diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 4ac167f3f..934946b74 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -38,6 +38,7 @@ import { useTranslation } from "react-i18next"; export default function PublicReuseFaciltyInsert() { const { + auth, code, pbnst, pubHasuInit, @@ -50,7 +51,7 @@ export default function PublicReuseFaciltyInsert() { const { t } = useTranslation("base"); const { pubFacHeadList, pbnstHasuResCount, pbnstHasuRes, pbnstRes } = pbnst; - + const { regAuthrtYn, mdfcnAuthrtYn } = auth; const [, setCurrentTab] = useState("mng"); const [isRuseReg, setIsRuseReg] = useState<{ isModal: boolean; @@ -264,13 +265,6 @@ export default function PublicReuseFaciltyInsert() { isResetPage(false); }, [pageNation, pubHasuInit]); - const { auth } = useWrStore((state) => state); - const { mngAuthrtYn, inqAuthrtYn, regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn } =auth; - useEffect(() => { - console.log("auth", mngAuthrtYn, inqAuthrtYn, regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn); - }, [mngAuthrtYn, inqAuthrtYn, regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn]); - - return ( <> @@ -292,13 +286,14 @@ export default function PublicReuseFaciltyInsert() { className="" size={"sm"} onClick={() => { - if (searchTxt && searchTxt?.length > 0) { - pubHasuSearch(String(pageNation), "41", searchTxt); - } else { - pubHasuInit(String(pageNation), "41"); - } - isResetPage(true); + if (searchTxt && searchTxt?.length > 0) { + pubHasuSearch(String(pageNation), "41", searchTxt); + } else { + pubHasuInit(String(pageNation), "41"); + } + isResetPage(true); }} + > 조회 @@ -316,6 +311,7 @@ export default function PublicReuseFaciltyInsert() { appendPbnstRuseFclt(); } }} + disabled={regAuthrtYn === "N"} > 신규등록 @@ -358,6 +354,7 @@ export default function PublicReuseFaciltyInsert() { size={"sm"} onClick={form.handleSubmit(onSubmit, onInvalid)} className="mr-5 mt-2" + disabled={mdfcnAuthrtYn === "N"} > 저장 @@ -371,7 +368,7 @@ export default function PublicReuseFaciltyInsert() { setIndexMng(index); }} indexMng={indexMng} - readonly={false} + readonly={mdfcnAuthrtYn === "N"} /> @@ -383,6 +380,7 @@ export default function PublicReuseFaciltyInsert() { }} indexMng={indexMng} indexBiz={indexBiz} + readonly={mdfcnAuthrtYn === "N"} /> diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index bd0b9bb8e..6bf250365 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -1,8 +1,6 @@ "use client"; import { useWrStore } from "@/app/store"; -import { - type customRainBdst, -} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { type customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { formatCommaNumber, tableData } from "@/components/lib/func/commom"; import RainRegForm from "@/components/ui/form/fcltReg/rainReg/rainRegForm"; import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; @@ -19,14 +17,19 @@ import { import ListDiv from "@common/business_components/ui/list_div"; import { Button } from "@common/components"; import { useEffect, useState } from "react"; -import { Toaster } from "react-hot-toast"; +import { Toaster } from "react-hot-toast"; export default function Home() { - const { rain, code, initRain, rainSearch, getRainData } = useWrStore( + const { auth, rain, code, initRain, rainSearch, getRainData } = useWrStore( (state) => { return state; } ); + + const { regAuthrtYn, mdfcnAuthrtYn } = auth; + + + const { rainRes, rainResCount } = rain; const [rainForm, setRainForm] = useState(); const [issNewReg, setIsNewReg] = useState(false); @@ -53,7 +56,6 @@ export default function Home() { return { ...item, archArea: formatCommaNumber(archArea), - }; } ); @@ -64,13 +66,10 @@ export default function Home() { } } }, [code, rainRes]); - const cellClick: (val: number | undefined) => void = ( - val - ) => { + const cellClick: (val: number | undefined) => void = (val) => { if (val !== undefined) { setRainForm(rainRes[val]); } - }; useEffect(() => { @@ -99,7 +98,7 @@ export default function Home() { size={"sm"} onClick={() => { rainSearch(searchTxt || "", 1, "41"); - //rainSearch(searchTxt || "", pageNation, "41"); + //rainSearch(searchTxt || "", pageNation, "41"); }} > 조회 @@ -107,7 +106,10 @@ export default function Home() { @@ -143,6 +145,7 @@ export default function Home() { diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx index b1d5cbb04..598ddfeca 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx @@ -20,9 +20,11 @@ import { useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; export default function Home() { - const { code, rswt, initRswt, rswtBdstSearch, getRswtBdstData } = useWrStore( + const { auth,code, rswt, initRswt, rswtBdstSearch, getRswtBdstData } = useWrStore( (state) => state ); + const { regAuthrtYn, mdfcnAuthrtYn } = auth; + const [rswtForm, setRswtForm] = useState(); const [searchTxt, setSearchTxt] = useState(); const [issNewReg, setIsNewReg] = useState(false); @@ -114,6 +116,7 @@ export default function Home() { size={"sm"} className="mr-4" onClick={() => setIsNewReg(!issNewReg)} + disabled={regAuthrtYn === "N"} > 신규등록 @@ -146,6 +149,7 @@ export default function Home() { diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 5c1edb471..2589422c8 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -44,6 +44,7 @@ export function PbnstBuseForm({ indexBiz = 0, setIndexBiz, form, + readonly = false, }: { formType: string; firstBizData?: fcBizType[]; @@ -51,6 +52,7 @@ export function PbnstBuseForm({ indexMng: number; indexBiz: number; setIndexBiz: (index: number) => void; + readonly?: boolean; }) { const { code, @@ -329,6 +331,7 @@ export function PbnstBuseForm({ onClick={addRuseFcltObj} type="button" size={commonButonSize} + disabled={readonly} > 추가 @@ -343,6 +346,7 @@ export function PbnstBuseForm({ sonClass="col-span-4" indexMng={indexMng} indexBiz={indexBiz} + readonly={readonly} />

재이용 원수취수 현황

@@ -394,6 +402,7 @@ export function PbnstBuseForm({ onClick={() => setIsFcOrgwts(true)} size={commonButonSize} className="" + disabled={readonly} > 추가등록 @@ -412,6 +421,7 @@ export function PbnstBuseForm({ indexMng={indexMng} formNm={"fcOrgwts"} indexBiz={indexBiz} + readonly={readonly} />

재이용 공급관로 설치 현황

@@ -424,6 +434,7 @@ export function PbnstBuseForm({ className="w-32" selectClass="w-full" onSelectValue={(val) => setPpiYn(String(val))} + readOnly={readonly} /> 추가등록 @@ -447,6 +459,7 @@ export function PbnstBuseForm({ size={commonButonSize} className="!text-xl !bg-red-500 !text-white ml-1" onClick={removeSelected} + disabled={readonly} > 삭제 @@ -471,6 +484,7 @@ export function PbnstBuseForm({ form={form} formNm={"pplInstls"} upHeadList={[]} + readonly={readonly} /> @@ -494,7 +508,7 @@ export function PbnstBuseForm({ sonClass="col-span-4" indexMng={indexMng} indexBiz={indexBiz} - readonly={false} + readonly={readonly} /> @@ -510,6 +524,7 @@ export function PbnstBuseForm({ }} size={commonButonSize} className="mt-6 mr-3" + disabled={readonly} > 수요처 추가 @@ -523,6 +538,7 @@ export function PbnstBuseForm({ }} size={commonButonSize} className="mt-6" + disabled={readonly} > 수요처 신규등록 @@ -575,6 +591,7 @@ export function PbnstBuseForm({ searchPk: item.dmdInfoId, }; })} + readonly={readonly} > )} @@ -611,6 +628,7 @@ export function PbnstBuseForm({ selectArray={code.dmdUszCd} onSelectValue={f.onChange} value={f.value ?? code.dmdUszCd[0]?.val} + readOnly={readonly} /> )} @@ -630,6 +648,7 @@ export function PbnstBuseForm({ f.onChange(date), }} selectClass={"rounded-lg !w-full"} + readOnly={readonly} /> )} @@ -652,6 +671,7 @@ export function PbnstBuseForm({ f.onChange(date), }} selectClass={"rounded-lg !w-full"} + readOnly={readonly} /> )} @@ -670,6 +690,7 @@ export function PbnstBuseForm({ handleCommaNumberChange(e, f.onChange); }} value={formatCommaNumber(f.value)} + readOnly={readonly} /> )} @@ -690,6 +711,7 @@ export function PbnstBuseForm({ f.onChange(val) } value={f.value ?? code.yn[0]?.val} + readOnly={readonly} /> )} diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index f7355bfd9..68d7634a0 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -41,13 +41,13 @@ export function PbnstMngForm({ formType, indexMng, setIndexMng, - readonly + readonly, }: { form: UseFormReturn<{ items: PbnstRegArrrayType }>; formType: string; indexMng: number; setIndexMng: (index: number) => void; - readonly:boolean + readonly: boolean; }) { const { code, pbnst, fileDelete, fileDownLoad } = useWrStore( (state) => state @@ -60,6 +60,7 @@ export function PbnstMngForm({ const [mngMtdCode, setMngMtdCode] = useState<{ name: string; val: SelectDataType[] }[]>(); + const { fields: fcOpersField, prepend, @@ -87,7 +88,6 @@ export function PbnstMngForm({ endDt: new Date(), }); //trigger(`items.${indexMng}.fcOpers`); - }; const removeSelected = () => { @@ -318,6 +318,7 @@ export function PbnstMngForm({ size={commonButonSize} className="!text-xl" onClick={plusHist} + disabled={readonly} > 추가등록 @@ -326,6 +327,7 @@ export function PbnstMngForm({ size={commonButonSize} className="!text-xl !bg-red-500 !text-white ml-1" onClick={removeSelected} + disabled={readonly} > 삭제 @@ -335,20 +337,11 @@ export function PbnstMngForm({
{ - return { - ...item, - readonly: true, - }; - }) - : pbnst.pbnstMngUpHeadList - } + tableData={form.getValues(`items.${indexMng}.fcOpers`) || []} + headList={pbnst.pbnstMngUpHeadList} upHeadList={pbnst.pbnstMngNm} code={mngMtdCode || []} - + readonly={readonly} indexMng={indexMng} form={form} formNm={"fcOpers"} @@ -372,7 +365,6 @@ export function PbnstMngForm({ maxLength={numSize} //입력제한 type="text" onChange={(e) => { - if (formType !== "sttn") handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} @@ -396,7 +388,6 @@ export function PbnstMngForm({ maxLength={numSize} //입력제한 type="text" onChange={(e) => { - if (formType !== "sttn") handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} @@ -419,7 +410,6 @@ export function PbnstMngForm({ maxLength={numSize} //입력제한 type="text" onChange={(e) => { - if (formType !== "sttn") handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} @@ -435,7 +425,7 @@ export function PbnstMngForm({
- {formType === "sttn" ? ( + {readonly ? ( relationfiles && relationfiles?.length > 0 ? ( <> @@ -472,7 +462,7 @@ export function PbnstMngForm({ )}
- {formType === "sttn" ? ( + {readonly ? ( planFiles && planFiles?.length > 0 ? ( <> diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx index 8ec7a5a05..2885c07a5 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx @@ -21,6 +21,7 @@ export default function MngRegFormDetail({ sonClass, indexBiz, indexMng, + readonly }: { formList: formDetailType[]; h1Title?: string; @@ -30,6 +31,7 @@ export default function MngRegFormDetail({ indexBiz?: number; indexMng?: number; sonClass?: string; + readonly?:boolean }) { const { code } = useWrStore((state) => state); @@ -67,7 +69,10 @@ export default function MngRegFormDetail({ field.onChange(date), }} selectClass={"w-full"} - disabled={formHead.option === "disabled" ? true : false} + readOnly={readonly + //|| formHead.option === "disabled" ? true : false + + } /> ) : formHead.type === "number" ? ( @@ -81,7 +86,9 @@ export default function MngRegFormDetail({ ); }} value={formatCommaNumber(field.value)} - readOnly={formHead.option === "readOnly" ? true : false} + readOnly={readonly + // || formHead.option === "readOnly" ? true : false + } disabled={formHead.option === "disabled" ? true : false} maxLength={numSize} /> @@ -103,7 +110,9 @@ export default function MngRegFormDetail({ } onSelectValue={field.onChange} value={field.value?.trim() ?? (Array.isArray(potentialOptions) && potentialOptions[0]?.val)} - readOnly={formHead.option === "readOnly"} + readOnly={readonly + // || formHead.option === "readOnly" + } /> ); })() @@ -113,7 +122,9 @@ export default function MngRegFormDetail({ type="text" value={field.value ?? ""} onChange={field.onChange} - readOnly={formHead.option === "readOnly" ? true : false} + readOnly={readonly + // || formHead.option === "readOnly" ? true : false + } disabled={formHead.option === "disabled" ? true : false} maxLength={txtSize} /> diff --git a/apps/wr/components/ui/searchInput/searchInput.tsx b/apps/wr/components/ui/searchInput/searchInput.tsx index be63b9685..f512516b8 100644 --- a/apps/wr/components/ui/searchInput/searchInput.tsx +++ b/apps/wr/components/ui/searchInput/searchInput.tsx @@ -1,3 +1,4 @@ +import { Input } from "@common/components/ui"; import React, { useCallback, useEffect, useRef, useState } from "react"; type SearchType = { @@ -10,6 +11,7 @@ type thisProps = { setValue: (searchNm?: string) => void; setRtnData: (rtnData: any) => void; searchList?: any[]; + readonly?:boolean }; export default function SearchInputText({ label = undefined, @@ -17,6 +19,7 @@ export default function SearchInputText({ setValue = () => {}, setRtnData = () => {}, searchList = undefined, + readonly = false, // 추가: readonly prop }: thisProps) { const [isOpen, setIsOpen] = useState(false); @@ -65,13 +68,14 @@ export default function SearchInputText({ return (
- setIsOpen(true)} */ className="w-full h-[3.2rem] !text-xl pl-3 text-gray-600 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder={`${label}을(를) 입력하세요`} + readOnly={readonly} // readonly 상태 적용 /> {isOpen && (
diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index 2efa1c795..b13160e8b 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -35,6 +35,7 @@ type RuseMngTableProps = { indexBiz?: number; form?: any; formNm?: string; + readonly?: boolean; }; const RuseMngTableForm = React.forwardRef( @@ -48,6 +49,7 @@ const RuseMngTableForm = React.forwardRef( form, formNm, indexBiz, + readonly= false }, ref ) => { @@ -111,7 +113,7 @@ const RuseMngTableForm = React.forwardRef( ? formatCommaNumber(field.value) : field.value || "" } - readOnly={head.readonly ? true : false} + readOnly={readonly|| head.readonly ? true : false} maxLength={head.maxLength?head.maxLength:15} /> ) : head.type === "select" ? ( @@ -132,7 +134,7 @@ const RuseMngTableForm = React.forwardRef( field.onChange(val); } }} - readOnly={head.readonly ? true : false} + readOnly={ readonly||head.readonly ? true : false} // Disabled prop removed as SelectBox does not support it > ) : head.type === "date" ? ( @@ -149,14 +151,18 @@ const RuseMngTableForm = React.forwardRef( }, }} selectClass={"w-full"} - readOnly={head.readonly ? true : false} + readOnly={readonly||head.readonly ? true : false} /> ) : head.type === "checkbox" ? ( { - field.onChange(checked); + if(readonly || head.readonly) { + return; + }else{ + field.onChange(checked); + } }} > ) : ( From bcdefaa828367b9ba5d7b309a819c9889fa8cf44 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Wed, 23 Jul 2025 17:58:07 +0900 Subject: [PATCH 04/27] =?UTF-8?q?=EC=9E=AC=EC=9D=B4=EC=9A=A9=EC=8B=A4?= =?UTF-8?q?=EC=A0=81=20=EB=93=B1=EB=A1=9D,=20=EC=A7=80=EB=8F=84=EC=A0=90?= =?UTF-8?q?=EA=B2=80=20=EB=93=B1=EB=A1=9D=20=EA=B6=8C=ED=95=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx | 7 +++++++ .../wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx | 9 ++++++--- apps/wr/components/lib/func/TableData.tsx | 4 +++- .../components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx | 7 +++++-- .../chkgdTable/guideDetailTable/guideDetailTable.tsx | 5 +++-- .../ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx | 5 ++++- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index 03397255c..d6fefe4d3 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -44,6 +44,7 @@ import { useTranslation } from "react-i18next"; export default function Page() { const { + auth, code, rainChkgdn, rswtChkgdn, @@ -64,6 +65,7 @@ export default function Page() { } = useWrStore((state) => { return state; }); + const { regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn } = auth; const [isRegExcel, setIsRegExcel] = useState(false); const [updateRainDetail, setUpdateRainDetail] = useState( [] @@ -301,6 +303,7 @@ export default function Page() { onClick={() => { clickDelete(deleteIdx, selFcltDiv); }} + disabled={delAuthrtYn === 'N'} > 삭제 @@ -313,6 +316,7 @@ export default function Page() { onClick={() => { chkUpdateTable(selFcltDiv); }} + disabled={mdfcnAuthrtYn === 'N'} > 저장 @@ -330,6 +334,7 @@ export default function Page() { onClick={() => { setIsRegExcel(!isRegExcel); }} + disabled={regAuthrtYn === 'N'} > 결과등록 @@ -354,6 +359,7 @@ export default function Page() { pageNation={rainPageNation} onPageChange={rainPageChange} pageCount={rainChkgdn.rainChkCount} + readonly={mdfcnAuthrtYn === 'N'} /> ) : ( setIsModal((prev) => ({ ...prev, open }))} + readonly={mdfcnAuthrtYn === 'N' ? false : true} /> } > diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 0572acce9..9ca1d60d2 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -38,10 +38,11 @@ import { useTranslation } from "react-i18next"; import { headMakeprfmnc } from "../chkgdnReg/TableHead"; export default function PrfmncPrfmncReg() { - const { prfmnc, prfmncHasuInit, prfmnRegData, prfmncHasuNmSearch } = useWrStore( + const { auth, prfmnc, prfmncHasuInit, prfmnRegData, prfmncHasuNmSearch } = useWrStore( (state) => state ); const { pbnstPrfmncHeadList, monthHeadList, prfmncRes, prfmncResCount } = prfmnc; + const { regAuthrtYn, mdfcnAuthrtYn } = auth; const [bdstTable, setbdstTable] = useState(); const [searchTxt, setSearchTxt] = useState(); const [isExcelOpen, setIsExcelOPen] = useState<{ @@ -92,7 +93,7 @@ export default function PrfmncPrfmncReg() { searchYear, pbnstRuseFcltId ) as unknown as PrfType - ,searchYear + , searchYear ); }; @@ -259,6 +260,7 @@ export default function PrfmncPrfmncReg() { onClick={() => { onSave(); }} + disabled={mdfcnAuthrtYn === 'N'} > 저장 @@ -272,6 +274,7 @@ export default function PrfmncPrfmncReg() { setIsExcelOPen({ ...isExcelOpen, isModal: true }); } }} + disabled={regAuthrtYn === 'N'} > 파일등록 @@ -321,7 +324,7 @@ export default function PrfmncPrfmncReg() { {headMakeprfmnc(monthHeadList, [])} - {InputTableBody(inputData ?? [], monthHeadList, setInputData)} + {InputTableBody(inputData ?? [], monthHeadList, setInputData, mdfcnAuthrtYn === 'N' ? false : true)} diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index 4440e3e54..192bc43c3 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -95,7 +95,8 @@ export const chRowspanTable = ( ) => void, toggleSelection: (pk: number, checked: boolean) => void, selectedIds: number[], - handleCellClick: (index: number, headId: string) => void + handleCellClick: (index: number, headId: string) => void, + disable? : boolean ) => { let order = 0 // rowspan된 셀 렌더링 여부 추적용 @@ -138,6 +139,7 @@ export const chRowspanTable = ( onCheckedChange={(checked) => toggleSelection(row.chkgdnSn, checked === true) } + disabled={disable} > ) : key === "order" ? ( ++order diff --git a/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx b/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx index 3675e3bfb..c528f5add 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx @@ -8,7 +8,7 @@ import { Button } from "@common/components/ui"; import React, { useEffect, useState } from "react"; import type { z } from "zod"; -export default function ChkgdModal({ type, obj, setIsModal }: { type: string; obj: any, setIsModal: (open: boolean) => void }) { +export default function ChkgdModal({ type, obj, setIsModal, readonly }: { type: string; obj: any, setIsModal: (open: boolean) => void, readonly: boolean }) { const { rainChkgdn, rswtChkgdn, @@ -247,7 +247,7 @@ export default function ChkgdModal({ type, obj, setIsModal }: { type: string; ob } > {!rainChkSttn.isSttn ? ( - ) : ( @@ -274,6 +274,7 @@ export default function ChkgdModal({ type, obj, setIsModal }: { type: string; ob setChGuidData={(data) => { setChGuidData(data); }} + readonly={readonly} />

@@ -288,6 +289,7 @@ export default function ChkgdModal({ type, obj, setIsModal }: { type: string; ob setChGuidData={(data) => { setChGuidData(data); }} + readonly={readonly} /> {type !== "RNB" && polutionData !== undefined ? ( @@ -310,6 +312,7 @@ export default function ChkgdModal({ type, obj, setIsModal }: { type: string; ob setChGuidData={(data) => { getPolutionData(data); }} + readonly={readonly} /> ); diff --git a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx index 7676f7e71..7522fdbfd 100644 --- a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx @@ -17,12 +17,14 @@ export function GuideDetailsTable({ headList, upheadList, setChGuidData, + readonly }: { chgRes: any[]; headList: TableUpperProps[]; upheadList: chHeadType[]; type: string; setChGuidData: (chgRes: any[]) => void; + readonly?: boolean; }) { const [inputData, setInputData] = useState(); @@ -30,7 +32,6 @@ export function GuideDetailsTable({ setInputData(chgRes); }, [chgRes]); - useEffect(() => { setChGuidData(inputData ?? []); @@ -43,7 +44,7 @@ export function GuideDetailsTable({ {headMakeprfmnc(headList, upheadList)} - {InputTableBody(inputData ?? [], headList, setInputData)} + {InputTableBody(inputData ?? [], headList, setInputData, readonly)}

diff --git a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx index f607c289e..f016a0cc3 100644 --- a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx @@ -25,6 +25,7 @@ export default function RainChkgdTable({ pageNation, onPageChange, pageCount, + readonly, }: { detailUp: (data: rainChkZodType[]) => void; handleClick?: (data: any) => void; @@ -33,6 +34,7 @@ export default function RainChkgdTable({ pageNation: number; onPageChange: (page: number) => void; pageCount: number; + readonly: boolean; }) { const { code, rainChkgdn, rainChkSttn, getRainSttnExcel } = useWrStore((state) => state); const [makeTableData, setMakeTableData] = useState([]); @@ -191,7 +193,8 @@ export default function RainChkgdTable({ handleChange, toggleSelection, selectedIds, - handleCellClick + handleCellClick, + readonly )} From 543fbb70ccf5d30abc847e54a7d6629821331ade Mon Sep 17 00:00:00 2001 From: leedj312 Date: Thu, 24 Jul 2025 09:33:52 +0900 Subject: [PATCH 05/27] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EB=94=94=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/store/store.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index 3ab1439ff..1bb7a03b7 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -195,7 +195,7 @@ export const StoreZus = ( getMiddleRegionCd(set); getUnitWaterShedCd(set); getEnvPartCd(set); - LoginApi.login({userId: "tuser10003", password: "test1234!"}) + LoginApi.login({userId: "admin1gmail", password: "test1234!"}) return { ...initState, ...comFcltSearchAction(set), From 1daa92501998495e444bf6e379aa51a4329aea16 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Thu, 24 Jul 2025 11:04:41 +0900 Subject: [PATCH 06/27] =?UTF-8?q?=EC=9E=A0=EC=9E=AC=EC=88=98=EC=9A=94?= =?UTF-8?q?=EC=B2=98=20=EA=B6=8C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wr/app/matMng/coMng/ldrmntCoSttn/page.tsx | 22 ++++--- .../sttn/sttnDetailModal/coDatailModal.tsx | 63 ++++++++++++++----- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx index 36a8b7151..8c4976e09 100644 --- a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -33,7 +33,7 @@ import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; export default function LdrmntCoSttn() { - const { code, ldrmnt, ldrmntInit, ldrmntSearch, ldrmntUpdate } = useWrStore( + const { auth, code, ldrmnt, ldrmntInit, ldrmntSearch, ldrmntUpdate } = useWrStore( (state) => state ); const { ldrmntRes, excelList, ldrmntResCount } = ldrmnt; @@ -47,6 +47,7 @@ export default function LdrmntCoSttn() { const [resetPage, isResetPage] = useState(false); const [isDownloadClicked, setIsDownloadClicked] = useState(false); const { t } = useTranslation('base'); + const { regAuthrtYn, mdfcnAuthrtYn } = auth; const excelClick = useCallback(() => { excelDownload( @@ -224,6 +225,7 @@ export default function LdrmntCoSttn() { onClick={() => { setIsExcelOpen({ isModal: true }); }} + disabled={regAuthrtYn === 'N'} > 엑셀등록 @@ -269,14 +271,16 @@ export default function LdrmntCoSttn() { setDetailModal({ ...detailModal, isOpen: !detailModal.isOpen }) }} bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"} - body={ { - const handleConfirm = async () => { - await ldrmntUpdate(value); - setDetailModal({ ...detailModal, isOpen: false }); - ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); - }; - confirmToast(t('isUpdateMsg'), handleConfirm); - }} />} + body={ { + const handleConfirm = async () => { + await ldrmntUpdate(value); + setDetailModal({ ...detailModal, isOpen: false }); + ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); + }} />} /> void; + onFormSubmit: (values: customLdrmnt) => void; + readonly?: boolean; }) { const defaultValues: z.infer = ldrmntZod.parse({}); const form = useForm>({ @@ -52,7 +55,11 @@ export default function CoDetailModal({

잠재수요처 상세정보

-
@@ -71,7 +78,6 @@ export default function CoDetailModal({ )} /> -
{ field.onChange(e.target.value); }} - value={field.value ?? ""} + value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -108,13 +115,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
-
)} @@ -151,6 +159,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -173,6 +182,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -193,6 +203,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -213,6 +224,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -235,12 +247,12 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
-
)} @@ -278,6 +291,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -298,6 +312,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -318,14 +333,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={13} + readOnly={readonly} /> )} />
- -
)} @@ -365,6 +380,7 @@ export default function CoDetailModal({ value={formatCommaNumber(field.value)} min={0} maxLength={8} + readOnly={readonly} /> )} @@ -386,6 +402,7 @@ export default function CoDetailModal({ value={formatCommaNumber(field.value)} min={0} maxLength={8} + readOnly={readonly} /> )} @@ -407,6 +424,7 @@ export default function CoDetailModal({ value={formatCommaNumber(field.value)} min={0} maxLength={8} + readOnly={readonly} /> )} @@ -434,7 +452,6 @@ export default function CoDetailModal({ />
-
)} @@ -471,6 +489,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -491,13 +510,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
-
)} @@ -534,6 +554,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -554,14 +575,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
- -
)} @@ -598,6 +619,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -618,14 +640,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
- -
)} @@ -662,6 +684,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -682,13 +705,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
-
)} @@ -725,6 +749,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -745,6 +770,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -767,6 +793,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} @@ -787,13 +814,13 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={txtSize} + readOnly={readonly} /> )} />
-
)} @@ -830,6 +858,7 @@ export default function CoDetailModal({ }} value={field.value ?? ""} maxLength={50} + readOnly={readonly} /> )} From 32b16055fb34e758084b993b8e786140048f5645 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Thu, 24 Jul 2025 11:05:19 +0900 Subject: [PATCH 07/27] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=ED=98=84=ED=99=A9=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 23 ++-- .../prfmncReg/pbnstPrfmncReg/page.tsx | 2 +- .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 129 +++++++++--------- .../sttn/pbnstSttnModal/pbnstSttnModal.tsx | 8 -- 4 files changed, 79 insertions(+), 83 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 9793a5116..2daef0074 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -1,6 +1,11 @@ "use client"; import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; +import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; +import { excelDownload, yearOptions } from "@/components/lib/func/commom"; +import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; +import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; import { ContentsDiv, SearchBaseForm, @@ -12,14 +17,9 @@ import { type ReturnType, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, Label } from "@common/components/ui"; -import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; -import { useCallback, useEffect, useRef, useState } from "react"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload, yearOptions } from "@/components/lib/func/commom"; -import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; -import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; +import { Button, Label } from "@common/components/ui"; +import { useCallback, useEffect, useRef, useState } from "react"; export default function PbnstSttn() { const { @@ -29,6 +29,7 @@ export default function PbnstSttn() { pbnSttnInit, getPbnStnDetail, getFlcts, + resetPbnstDetail } = useWrStore((state) => state); const { pbnstSttnRes, fclts, pbnstSttnResCount } = pbnstSttn; @@ -103,9 +104,6 @@ export default function PbnstSttn() { }); }, [pbnstSttn.pbnstDetail]); - useEffect(() => { - console.log("pbnDetaileData.isModal ", pbnDetaileData.isModal); - }, [pbnDetaileData.isModal]); return ( <> @@ -233,8 +231,9 @@ export default function PbnstSttn() { open={pbnDetaileData.isModal} onOpenChange={(open) => { //TODO:OPEN 상태 확인필요 - if(!open) - setPbnDetaileData({ data: {} as customPbnst, isModal: open }); + if (!open) + setPbnDetaileData({ data: {} as customPbnst, isModal: open }); + resetPbnstDetail(); }} /> diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 9ca1d60d2..c4e62a861 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -351,7 +351,7 @@ export default function PrfmncPrfmncReg() { } open={isExcelOpen.isModal} onOpenChange={() => { - setIsExcelOPen({ isModal: false, data: {} as FcPrfType }); + setIsExcelOPen({ ...isExcelOpen, isModal: false }); }} > diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index e94c7a002..3c59c9e3b 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -27,9 +27,9 @@ export type pbnstSttnState = { ruseGuranteeHeadList: TableUpperProps[] ruseDmdHeadList: TableUpperProps[] ruseFcltHeadList: TableUpperProps[] - pbnstSttnResCount:number; + pbnstSttnResCount: number; excelList: []; - fclts:string[] + fclts: string[] isInit: boolean; }; }; @@ -43,15 +43,15 @@ type pbnstSttnActions = { reurnValue: ReturnType, searchNm: string | undefined, year: string, - fclts:string[] + fclts: string[] ) => void; - getFlcts:()=>void; + getFlcts: () => void; pbnSttnInit: ( page: string, total: string, reurnValue: ReturnType, year: string, - flcts:string[] + flcts: string[] ) => void; getPbnStnDetail: (pbnstRuseFcltId: string) => void; pbnNmSearch: ( @@ -60,8 +60,9 @@ type pbnstSttnActions = { reurnValue: ReturnType, searchNm: string | undefined, year: string, - flcts:string[] + flcts: string[] ) => void; + resetPbnstDetail: () => void; }; export type pbnstSttnType = pbnstSttnState & pbnstSttnActions; @@ -77,11 +78,11 @@ export const pbnstSttnStateExport: pbnstSttnState = { ruseDmdHeadList: ruseDmdHeadListExport, ruseFcltHeadList: ruseFcltHeadListExport, pbnstSttnRes: [], - pbnstSttnResCount:1, + pbnstSttnResCount: 1, pbnstDetail: {} as customPbnst, pbnstSearchData: [], excelList: [], - fclts:[], + fclts: [], isInit: false, }, }; @@ -92,12 +93,12 @@ const hasuListFetch = async ( reurnValue: ReturnType, searchNm: string | undefined, year: string, - flcts:string[] + flcts: string[] ) => { let url = `/prcsFclt/ruseInfo/`; if (reurnValue.partValue === "A") { - url+=`${page}/${total}/${reurnValue.partValue}/${ + url += `${page}/${total}/${reurnValue.partValue}/${ // reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue }/0/1/SW` @@ -108,12 +109,12 @@ const hasuListFetch = async ( ? reurnValue.unitWaterShedValue : reurnValue.middleRegionValue }/0/1/SW` - } else if( reurnValue.partValue === 'G'){ + } else if (reurnValue.partValue === 'G') { url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW` - }else{ + } else { url += `1/2/A/0/0/1/SW` } @@ -121,8 +122,7 @@ const hasuListFetch = async ( url += "/" + searchNm } - console.log(' flcts ' ,flcts) - const pbnList = await postFectch(url, flcts,fetchType.COMMON); + const pbnList = await postFectch(url, flcts, fetchType.COMMON); const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}`, flcts, @@ -139,7 +139,7 @@ const hasuListFetch = async ( fclt.bscFctCd === item.pbnstRuseFcltId.substring(0, 11) ); - if(findData){ + if (findData) { const usage = item.prfList.reduce( (acc, cur) => { @@ -161,48 +161,42 @@ const hasuListFetch = async ( cur.rvrKeepUswtr + cur.indstUswtr; acc.total = acc.inUsage + acc.outUsage; - + return acc; }, { total: 0, inUsage: 0, outUsage: 0 } ); - console.log('findData ', findData) return { - rvbsn: findData?.rvbsn ||'-', - lgbsn: findData?.lgbsn||'-', - mdmbsn: findData?.mdmbsn||'-', - rgnNm: findData?.rgnNm||'-', - sido: findData?.sido||'-', - gugun: findData?.gugun||'-', - bscFctNm: findData?.bscFctNm||'-', - efflWqltStndrdNm: findData?.efflWqltStndrdNm||'-', - fctCpc: Number(findData?.fctCpc)||0, + rvbsn: findData?.rvbsn || '-', + lgbsn: findData?.lgbsn || '-', + mdmbsn: findData?.mdmbsn || '-', + rgnNm: findData?.rgnNm || '-', + sido: findData?.sido || '-', + gugun: findData?.gugun || '-', + bscFctNm: findData?.bscFctNm || '-', + efflWqltStndrdNm: findData?.efflWqltStndrdNm || '-', + fctCpc: Number(findData?.fctCpc) || 0, tel: findData?.tel ?? "-", - ruseUtztnFcltNm: item?.ruseUtztnFcltNm||'-', - fcltCpct: item?.fcltCpct||'-', - splyExtraCpct: item?.splyExtraCpct||'-', - ruseCpct: item?.ruseCpct||'-', - pbnstRuseFcltId: item.pbnstRuseFcltId||'-', + ruseUtztnFcltNm: item?.ruseUtztnFcltNm || '-', + fcltCpct: item?.fcltCpct || '-', + splyExtraCpct: item?.splyExtraCpct || '-', + ruseCpct: item?.ruseCpct || '-', + pbnstRuseFcltId: item.pbnstRuseFcltId || '-', usageTotal: usage?.total, inUsage: usage?.inUsage, outUsage: usage?.outUsage, - operMthd: item.operList[0]?.operMthd||'-', + operMthd: item.operList[0]?.operMthd || '-', rprtvBzenty: item.operList[0]?.rprtvBzenty, bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "", - searchNm: findData?.bscFctNm||'-', - searchPk: findData?.bscFctCd||'-', + searchNm: findData?.bscFctNm || '-', + searchPk: findData?.bscFctCd || '-', prfList: item?.prfList ?? [] }; } } ).filter(Boolean); - - - console.log( ' checkWrRegListRes ', getRuseList.data) - console.log( ' data ', data) - return data; }; @@ -210,12 +204,12 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( set: any ) => { return { - getFlcts:async ()=>{ - const fclts= await getFetch(fetchType.WR,'/reuseFc/pubFc') + getFlcts: async () => { + const fclts = await getFetch(fetchType.WR, '/reuseFc/pubFc') return set((state: pbnstSttnState) => ({ pbnstSttn: { ...state.pbnstSttn, - fclts:fclts + fclts: fclts }, })); }, @@ -239,11 +233,11 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( reurnValue: ReturnType, searchNm: string | undefined, year: string, - fclts:string[] + fclts: string[] ) => { try { - - + + const pbnstSttnRes = await hasuListFetch( page, total, @@ -265,7 +259,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }, }; }); - } else{ + } else { set((state: pbnstSttnState) => { return { @@ -273,8 +267,8 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( pbnstSttn: { ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes, - pbnstSttnResCount:pbnstSttnRes.length - // isInit: false, + pbnstSttnResCount: pbnstSttnRes.length + // isInit: false, }, }; }); @@ -283,31 +277,31 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log("error", erTxt); } }, - pbnSttnInit: async( + pbnSttnInit: async ( page: string, total: string, reurnValue: ReturnType, year: string, - fclts:string[] + fclts: string[] ) => { try { const pbnstSttnRes = await hasuListFetch( - page, - total, - reurnValue, - undefined, - year, - fclts - ); - console.log('pbnstSttnRes ' , pbnstSttnRes) - set( (state: pbnstSttnState) => { + page, + total, + reurnValue, + undefined, + year, + fclts + ); + set((state: pbnstSttnState) => { return { ...state, pbnstSttn: { ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes, - pbnstSttnResCount:pbnstSttnRes.length, + pbnstSttnResCount: pbnstSttnRes.length, isInit: false, + pbnstDetail: {} as customPbnst }, }; }); @@ -315,6 +309,17 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log("error", erTxt); } }, + resetPbnstDetail: async () => { + set((state: pbnstSttnState) => { + return { + ...state, + pbnstSttn: { + ...state.pbnstSttn, + pbnstDetail: {} as customPbnst + }, + }; + }) + }, getPbnStnDetail: async (pbnstRuseFcltId: string) => { try { let pbnstDetail = await getFetch("wr", `/reuseFc/pubFc/${pbnstRuseFcltId}`); @@ -340,7 +345,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( reurnValue: ReturnType, searchNm: string | undefined, year: string, - flcts:string[] + flcts: string[] ) => { try { @@ -359,7 +364,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( pbnstSttn: { ...state.pbnstSttn, pbnstSearchData: pbnstSttnRes, - pbnstSttnResCount:pbnstSttnRes.length, + pbnstSttnResCount: pbnstSttnRes.length, }, }; }); diff --git a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx index b23a52056..1a16c1fef 100644 --- a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx +++ b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx @@ -138,7 +138,6 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl }); }); } - console.log(tableData); if (tableData && tableData.length > 0) { setRuseTableData(tableData as any[]); } @@ -216,9 +215,6 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl (usageTotalObj as any)[key] = val; } const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; - console.log("inusageData", inUsageData) - console.log("outUsageData", outUsageData) - console.log("tableData", tableData) setPrfData({ inPrf: inUsageData, outPrf: outUsageData, @@ -248,10 +244,6 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl }, [data, form]) - - useEffect(() => { - console.log("prfData", prfData); - }, [prfData]) return ( <>
From bb4d7b9d5638d43a1220c16559cc6117a4d17c9c Mon Sep 17 00:00:00 2001 From: yschoi Date: Thu, 24 Jul 2025 13:38:40 +0900 Subject: [PATCH 08/27] =?UTF-8?q?=EB=AC=BC=EC=9E=AC=EC=9D=B4=EC=9A=A9?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=20=ED=8C=9D=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/popup/page.tsx | 158 ++++++++++++++++++ .../business_components/src/ui/map/Gis.js | 1 - 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 apps/wr/app/map/popup/page.tsx diff --git a/apps/wr/app/map/popup/page.tsx b/apps/wr/app/map/popup/page.tsx new file mode 100644 index 000000000..80830aa90 --- /dev/null +++ b/apps/wr/app/map/popup/page.tsx @@ -0,0 +1,158 @@ +"use client"; + +import Gis from "@common/business_components/ui/map/Gis"; +import { useEffect, useRef, useState, useCallback } from "react"; +import { mapService } from "../service"; +import NewWindowPopup from "../newWindowPopup"; +import GisApp from "@common/business_components/ui/map/lib/gis.core"; + +const Map = () => { + const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정 + const gisMaps = useRef(null); + const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 + const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태 + const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터 + const [checkedLayers, setCheckedLayers] = useState([]); + const [checkedLayersData, setCheckedLayersData] = useState([]); + + const fetchData = async () => { + try { + const response = await mapService.getLyrStngs(); + setTreeData(response); // API 응답 저장 + } catch (error) { + console.error("데이터 불러오기 실패:", error); + } + }; + + // 팝업 닫기 핸들러를 useCallback으로 메모이제이션 + const handlePopupClose = useCallback(() => { + setIsOpen(false); + setFeatureData(null); + }, []); + + // 컴포넌트 마운트 시 1회 실행 + useEffect(() => { + fetchData(); + }, []); + + // 체크된 레이어 정보를 받는 핸들러 + const handleCheckedLayersChange = (checkedIds: string[], checkedNodesData: any[]) => { + setCheckedLayers(checkedIds); + setCheckedLayersData(checkedNodesData); + }; + + // SearchModal, GisContent 등에서 호출 + const onFeatureSelect = (data: any) => { + const map = gisMaps.current; + if (!map) { + console.warn("지도가 초기화되지 않았습니다."); + return; + } + + // 항상 같은 select 객체 사용 + const select = GisApp.Module.select as any; + if (!select) return; + + // 1. 기존 선택 초기화 + select.resetSelectedFeature(); + + // 2. data가 OpenLayers Feature 인스턴스인지 확인 + let foundFeature: any = null; + if ( + data && + typeof data.getGeometry === "function" && + typeof data.setStyle === "function" + ) { + // 이미 Feature 인스턴스라면 그대로 사용 + foundFeature = data; + } else { + // 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용 + const featureId = data.fid || data.ftrIdn || data.id; + map + .getLayers() + .getArray() + .forEach((layer: any) => { + const source = layer.getSource?.(); + if (source?.getFeatureById) { + const feature = source.getFeatureById(String(featureId).trim()); + if (feature) foundFeature = feature; + } + }); + } + + // 3. 피처 선택 + if (foundFeature) { + const geometry = foundFeature.getGeometry(); + if (geometry) { + const extent = geometry.getExtent(); + + map.getView().fit(extent, { + duration: 300, + padding: [50, 50, 50, 50], + maxZoom: 16, + constrainResolution: true, + nearest: true, + }); + } + select.selectFeature(foundFeature, true); + } else { + console.warn("OpenLayers Feature를 찾을 수 없습니다:", data); + } + + setFeatureData(data); + setIsOpen(true); + setIsSearchModalOpen(false); + }; + + // MapSearchBar 래퍼 컴포넌트 + // const CustomMapSearchBar = (props: any) => { + // return ( + // + // ); + // }; + + return ( +
+ ( + // + // ) + // } + detailView={(props: any) =>( + + )} + onFeatureSelect={onFeatureSelect} + setIsOpen={setIsOpen} + setFeatureData={setFeatureData} + featureData={featureData} + setIsSearchModalOpen={setIsSearchModalOpen} + isOpen={isOpen} + isSearchModalOpen={isSearchModalOpen} + onCheckedLayersChange={handleCheckedLayersChange} + imgVisble={true} + /> +
+ ); +}; + +export default Map; diff --git a/packages/common/business_components/src/ui/map/Gis.js b/packages/common/business_components/src/ui/map/Gis.js index a723b2340..bf9522168 100644 --- a/packages/common/business_components/src/ui/map/Gis.js +++ b/packages/common/business_components/src/ui/map/Gis.js @@ -410,7 +410,6 @@ function Gis({ onFeatureSelect={handleFeatureSelect} /> )} - From f332d64aa65e91cb47d69276228ac40ef4a83289 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Thu, 24 Jul 2025 14:06:20 +0900 Subject: [PATCH 09/27] =?UTF-8?q?=EB=AC=BC=EC=9E=AC=EC=9D=B4=EC=9A=A9=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EB=B3=84=20=EB=93=B1=EB=A1=9D/=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EA=B6=8C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMat/coMatRvw/page.tsx | 829 +++++++++--------- .../wr/app/matMng/coMat/ruseRvwHstry/page.tsx | 5 +- .../ui/form/coMat/conCostForm/conCostForm.tsx | 63 +- 3 files changed, 458 insertions(+), 439 deletions(-) diff --git a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx index d33611128..8a965211c 100644 --- a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx @@ -41,9 +41,11 @@ import toast, { Toaster } from "react-hot-toast"; import { z } from "zod"; export default function CoMatRvw() { - const { code, coRvw, coMatRvwInit, coMatRvwSearch, coMatRvwInqua } = + const { auth, code, coRvw, coMatRvwInit, coMatRvwSearch, coMatRvwInqua } = useWrStore((state) => state); - const { coMatRvwRes,coMatRvwCount } = coRvw; + const { coMatRvwRes, coMatRvwCount } = coRvw; + const { regAuthrtYn } = auth; + //init, sub, match const initRef = useRef(false); const { coRvwHeadList } = coRvw; @@ -91,10 +93,9 @@ export default function CoMatRvw() { const form = useForm>({ resolver: zodResolver(DmdCoReqSchema), shouldUnregister: false, - // defaultValues: DmdCoReqSchema.parse({}) + // defaultValues: DmdCoReqSchema.parse({}) }); - const TableCellClick = (index: number) => { if (coMatRvwRes && coMatRvwRes[index]) { setSelectData(coMatRvwRes[index]); @@ -103,23 +104,21 @@ export default function CoMatRvw() { }; const useUsgCdWatch = useWatch({ control: form.control, name: "useUsgCd" }); useEffect(() => { - if (useUsgCdWatch) { form.setValue( "demandCst.usgPrcsProcs", - usageProcData?.find( - (item) => item.usage === useUsgCdWatch - )?.process ?? "" + usageProcData?.find((item) => item.usage === useUsgCdWatch)?.process ?? + "" ); } - }, [useUsgCdWatch, form,selectionVersion]); + }, [useUsgCdWatch, form, selectionVersion]); useEffect(() => { - if (coMatRvwRes&&coMatRvwRes.length > 0) { + if (coMatRvwRes && coMatRvwRes.length > 0) { const data = coMatRvwRes?.map((item) => { let flag = ""; - - flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg ||undefined); + + flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg || undefined); return { ...item, @@ -127,7 +126,7 @@ export default function CoMatRvw() { sggCd: item.demandCo?.sggCd, dmdCoNm: item.demandCo?.dmdCoNm, daddr: item.demandCo?.daddr, - telno: formatPhoneNumber(item?.demandCo?.telno||''), + telno: formatPhoneNumber(item?.demandCo?.telno || ""), dmndTmng: item?.dmndTmng, splyFcltFlg: flag, }; @@ -156,7 +155,6 @@ export default function CoMatRvw() { useEffect(() => { if (selectData) { - try { DmdCoReqSchema.parse(selectData); } catch (e) { @@ -164,15 +162,14 @@ export default function CoMatRvw() { console.log(e.flatten()); } } - form.reset( selectData); - setSelectionVersion((v) => v + 1); // 강제로 바뀌었다고 알리기 + form.reset(selectData); + setSelectionVersion((v) => v + 1); // 강제로 바뀌었다고 알리기 } }, [selectData, form]); return ( <>
-
<SearchDiv> @@ -195,7 +192,7 @@ export default function CoMatRvw() { <div className="col-span-7 w-full"> <div className="flex flex-row items-center"> <Label className="text-xl text-gray-600 mx-6"> - 수요신청년도 + 수요신청년도 </Label> <SelectBox className="h-full w-32 text-2xl" @@ -248,7 +245,10 @@ export default function CoMatRvw() { if (String(objSearch.city).length > 0) { con = String(objSearch.city); } - if (String(objSearch.sgg).length > 0 && String(objSearch.sgg) !== "0") { + if ( + String(objSearch.sgg).length > 0 && + String(objSearch.sgg) !== "0" + ) { con = String(objSearch.sgg); } getSearch(fromNum, toNum, con, dmdCoNm); @@ -279,403 +279,410 @@ export default function CoMatRvw() { TableCellClick(index); } }} - onPageChange={(val) => {setPageNatiion(val)}} + onPageChange={(val) => { + setPageNatiion(val); + }} ></UiTable> </ListDiv> <hr /> {/* <ScrollArea className="h-[49vh]"> */} - <ListDiv> - <h3 className="mt-4 ml-2 text-2xl font-medium text-label"> - 수요신청 상세현황 - </h3> - <Form {...form}> - <div className="grid grid-cols-12 gap-4 ml-4 mr-4"> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="dmndTmng" - render={({ field }) => ( - <FormUi label="요구시기"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(String(e.target.value)); - }} - value={ - moment(field.value).format("YYYY-MM-DD") ?? "" - } - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="dmndQty" - render={({ field }) => ( - <FormUi label="요구수량(m³/일)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="useUsgCd" - render={({ field }) => ( - <FormUi label="사용용도"> - <Input - placeholder="" - type="text" - step="0.1" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="wntUntprc" - render={({ field }) => ( - <FormUi label="희망단가(원/m3)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-12 w-full"> - <h1 className={formH1Class}>요구수질</h1> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="grssClfg" - render={({ field }) => ( - <FormUi label="총대장균군수 (개/100ml)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="combResdch" - render={({ field }) => ( - <FormUi label="결합잔류염소(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="trbt" - render={({ field }) => ( - <FormUi label="탁도(NTU)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="blgcOxygDmndQnt" - render={({ field }) => ( - <FormUi label="생물학적 산소요구량(BOD)(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="smll" - render={({ field }) => ( - <FormUi label="냄새"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="crmty" - render={({ field }) => ( - <FormUi label="색도(도)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="tn" - render={({ field }) => ( - <FormUi label="총질소 (T-N)(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="tph" - render={({ field }) => ( - <FormUi label="총인(T-P)(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="ph" - render={({ field }) => ( - <FormUi label="수소이온농도(pH)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="clIonQnt" - render={({ field }) => ( - <FormUi label="염화물(mgCL/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="cdtnv" - render={({ field }) => ( - <FormUi label="전기전도도(㎲/cm)"> - <Input - placeholder="" - type="number" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="rmrk" - render={({ field }) => ( - <FormUi label="비고"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-12 w-full"> - <h1 className={formH1Class}>공급처 후보지</h1> - </div> - <div className="col-span-4 mt-4"> - <FormField - control={form.control} - name={`demandMatching.splyCndtList.${0}`} - render={({ field }) => ( - <FormUi label="후보지1"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(String(e.target.value)); - }} - value={field.value ?? ""} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4 mt-4"> - <FormField - control={form.control} - name={`demandMatching.splyCndtList.${1}`} - render={({ field }) => ( - <FormUi label="후보지2"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4 mt-4"> - <FormField - control={form.control} - name={`demandMatching.splyCndtList.${2}`} - render={({ field }) => ( - <FormUi label="후보지3"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - readOnly - /> - </FormUi> - )} - /> - </div> + <ListDiv> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label"> + 수요신청 상세현황 + </h3> + <Form {...form}> + <div className="grid grid-cols-12 gap-4 ml-4 mr-4"> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="dmndTmng" + render={({ field }) => ( + <FormUi label="요구시기"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(String(e.target.value)); + }} + value={ + moment(field.value).format("YYYY-MM-DD") ?? "" + } + readOnly + /> + </FormUi> + )} + /> </div> - </Form> - <ConCostForm form={form} type={"mat"} selectionVersion={selectionVersion} /> - </ListDiv> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="dmndQty" + render={({ field }) => ( + <FormUi label="요구수량(m³/일)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="useUsgCd" + render={({ field }) => ( + <FormUi label="사용용도"> + <Input + placeholder="" + type="text" + step="0.1" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="wntUntprc" + render={({ field }) => ( + <FormUi label="희망단가(원/m3)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-12 w-full"> + <h1 className={formH1Class}>요구수질</h1> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="grssClfg" + render={({ field }) => ( + <FormUi label="총대장균군수 (개/100ml)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="combResdch" + render={({ field }) => ( + <FormUi label="결합잔류염소(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="trbt" + render={({ field }) => ( + <FormUi label="탁도(NTU)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="blgcOxygDmndQnt" + render={({ field }) => ( + <FormUi label="생물학적 산소요구량(BOD)(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="smll" + render={({ field }) => ( + <FormUi label="냄새"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="crmty" + render={({ field }) => ( + <FormUi label="색도(도)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="tn" + render={({ field }) => ( + <FormUi label="총질소 (T-N)(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="tph" + render={({ field }) => ( + <FormUi label="총인(T-P)(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="ph" + render={({ field }) => ( + <FormUi label="수소이온농도(pH)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="clIonQnt" + render={({ field }) => ( + <FormUi label="염화물(mgCL/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="cdtnv" + render={({ field }) => ( + <FormUi label="전기전도도(㎲/cm)"> + <Input + placeholder="" + type="number" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="rmrk" + render={({ field }) => ( + <FormUi label="비고"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-12 w-full"> + <h1 className={formH1Class}>공급처 후보지</h1> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name={`demandMatching.splyCndtList.${0}`} + render={({ field }) => ( + <FormUi label="후보지1"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(String(e.target.value)); + }} + value={field.value ?? ""} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name={`demandMatching.splyCndtList.${1}`} + render={({ field }) => ( + <FormUi label="후보지2"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name={`demandMatching.splyCndtList.${2}`} + render={({ field }) => ( + <FormUi label="후보지3"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + readOnly + /> + </FormUi> + )} + /> + </div> + </div> + </Form> + <ConCostForm + form={form} + type={"mat"} + selectionVersion={selectionVersion} + readonly={regAuthrtYn ==="N"} + /> + </ListDiv> {/* </ScrollArea> */} </div> </div> diff --git a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx index 1c034ac89..d1fa8f069 100644 --- a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx @@ -30,6 +30,7 @@ import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; export default function RuseRvwHstry() { const { + auth, code, ruseHist, ruseRvwHistInit, @@ -38,6 +39,8 @@ export default function RuseRvwHstry() { ruseRvwComplete, } = useWrStore((state) => state); const { rvwHistRes, ruseHistHeadList, rvwHistCount } = ruseHist; + const { regAuthrtYn } = auth; + const [pageNation, setPageNatiion] = useState<number>(1); const [dmdCoNm, setDmdCoNm] = useState<string>(""); @@ -305,7 +308,7 @@ export default function RuseRvwHstry() { > 조회 </Button> - <Button size={"sm"} onClick={confrirmToast}> + <Button size={"sm"} onClick={confrirmToast} disabled={regAuthrtYn==='N'}> 저장 </Button> </div> diff --git a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx index 9184f702f..5900014e0 100644 --- a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx +++ b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx @@ -31,10 +31,12 @@ export default function ConCostForm({ form, type, selectionVersion, + readonly = false, }: { form: UseFormReturn<DmdCoReqType>; type: string; selectionVersion: number; + readonly: boolean; }) { const { constCostRes, @@ -58,14 +60,11 @@ export default function ConCostForm({ } }, [ref, getConstCostFee, getRateFee]); - useEffect(() => { // 다른 행을 선택하면(selectionVersion 변경) 체크박스 상태를 초기화합니다. setCheckFinish(false); }, [selectionVersion]); - - const zipDowonLoad = () => { fetch(`/2024_constarctFeeProgram.zip`, {}).then(async (response) => { const blobRet = await response.blob(); @@ -165,29 +164,32 @@ export default function ConCostForm({ cstrnCst: value.demandCst.cstrnCst || 0, fcltSbsdCstrnCst: value.demandCst.fcltSbsdCstrnCst || 0, prcsFcltCpctCstrnCst: value.demandCst.prcsFcltCpctCstrnCst || 0, - flg: checkFinish?'Checked':'Sub', + flg: checkFinish ? "Checked" : "Sub", rgtr: TEST_UUID, }; if (checkFinish) { toast((t) => ( - <span className="flex flex-col items-center text-2xl" > - 검토완료 변경시 공사비는 변경할수 없습니다. + <span className="flex flex-col items-center text-2xl"> + 검토완료 변경시 공사비는 변경할수 없습니다. <br /> 진행하시겠습니까? <div className="flex gap-2 mt-2"> - <Button - size='sm' - - onClick={() => { - toast.dismiss(t.id); - coMatRvwUpdate("11000SW001R1", form.getValues("dmdInfoId"), data); - }} - > - 확인 - </Button> - <Button - size='sm' - onClick={() => toast.dismiss(t.id)}>취소</Button> + <Button + size="sm" + onClick={() => { + toast.dismiss(t.id); + coMatRvwUpdate( + "11000SW001R1", + form.getValues("dmdInfoId"), + data + ); + }} + > + 확인 + </Button> + <Button size="sm" onClick={() => toast.dismiss(t.id)}> + 취소 + </Button> </div> </span> )); @@ -229,6 +231,7 @@ export default function ConCostForm({ className="mr-3" size={"sm"} onClick={form.handleSubmit(onSubmit)} + disabled={readonly} > 저장 </Button> @@ -236,9 +239,14 @@ export default function ConCostForm({ <Checkbox className="ml-3 mr-6" checked={checkFinish} - onCheckedChange={(checked) => + onCheckedChange={ + (checked) => { + if (readonly) return; + setCheckFinish(checked === true); + } + // 'indeterminate' 상태를 무시하고 순수 boolean 값으로만 상태를 업데이트합니다. - setCheckFinish(checked === true)} + } ></Checkbox> <Label>관로 표준공사비 산정 프로그램</Label> <Button @@ -350,7 +358,7 @@ export default function ConCostForm({ type="number" step="0.001" onChange={(e) => { - console.log('dmndQty ', e) + console.log("dmndQty ", e); //field.onChange(Number(e.target.value) * 365 ); }} value={Number(field.value) * 365 || 0} @@ -377,7 +385,7 @@ export default function ConCostForm({ } childrenBody={ <> - <ConstCostFeeTable/> + <ConstCostFeeTable /> </> } bodyClassName={"w-[40vw] h-full"} @@ -414,8 +422,7 @@ export default function ConCostForm({ } childrenBody={ <> - <RateFeeTableModal/> - + <RateFeeTableModal /> </> } bodyClassName={"w-[22vw]"} @@ -476,8 +483,7 @@ export default function ConCostForm({ type="number" step="0.01" onChange={(e) => { - console.log('totalConstCost ', e) - + console.log("totalConstCost ", e); }} value={field.value ?? 0} readOnly @@ -521,6 +527,9 @@ export default function ConCostForm({ type="number" step="0.01" onChange={(e) => { + + if(readonly) return; + field.onChange(Number(e.target.value)); }} value={field.value ?? 0} From c5f4f6ddd0a867ffcc3479b8f5cf2266f2a53fe9 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Thu, 24 Jul 2025 14:09:43 +0900 Subject: [PATCH 10/27] =?UTF-8?q?=EB=AC=BC=EC=9E=AC=EC=9D=B4=EC=9A=A9=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B1=B4=EC=B6=95=EB=AC=BC=20=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=EC=97=AC=EB=B6=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index 6bf250365..e3daab9f9 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -56,6 +56,7 @@ export default function Home() { return { ...item, archArea: formatCommaNumber(archArea), + bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N", }; } ); From 8a2ed7df5882ae5ec5807391a4b2b6cb4596cef5 Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Thu, 24 Jul 2025 21:16:26 +0900 Subject: [PATCH 11/27] =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=20=ED=8C=9D=EC=97=85=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EC=A6=88=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 8 +++++++- apps/wr/app/map/newWindowPortal.tsx | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index faba4c81f..403401714 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -668,7 +668,13 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ return ( viewMode == 'nothing' ? <></> : - <NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보"> + <NewWindowPortal + onClose={memoizedOnClose} + title="시설 상세 정보" + width={viewMode == 'list' ? window.screen.availWidth : 900} + height={viewMode == 'list' ? window.screen.availHeight : 900} + resizable="no" + scrollbars="yes"> {/* 체크된 레이어에 따른 조건부 렌더링 */} {renderConditionalContent()} </NewWindowPortal> diff --git a/apps/wr/app/map/newWindowPortal.tsx b/apps/wr/app/map/newWindowPortal.tsx index fc28495ad..6d650e3b7 100644 --- a/apps/wr/app/map/newWindowPortal.tsx +++ b/apps/wr/app/map/newWindowPortal.tsx @@ -27,9 +27,13 @@ interface NewWindowPortalProps { children: React.ReactNode; onClose: () => void; title?: string; + width?: number; + height?: number; + resizable?: string; + scrollbars?: string; } -const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "Detail" }) => { +const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", width = 900, height = 800, resizable = "yes", scrollbars= "yes" }) => { const [container, setContainer] = useState<HTMLElement | null>(null); const newWindowRef = useRef<Window | null>(null); const onCloseRef = useRef(onClose); @@ -48,7 +52,8 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti if (newWindowRef.current && !newWindowRef.current.closed) return; // 1. 새 창을 열고 참조를 저장합니다. - newWindowRef.current = window.open('', title, 'width=900,height=800,resizable=yes,scrollbars=yes'); + const popupOptions = `width=${width},height=${height},resizable=${resizable},scrollbars=${scrollbars}`; + newWindowRef.current = window.open('', title, popupOptions); if (newWindowRef.current) { newWindowRef.current.document.title = title; From e9bfaa865a5f0908fd0a4d5fd71353d750080a32 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Fri, 25 Jul 2025 11:12:07 +0900 Subject: [PATCH 12/27] =?UTF-8?q?=EC=A7=80=EB=8F=84=20=ED=8C=9D=EC=97=85?= =?UTF-8?q?=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A1=B0=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=ED=81=B4=EB=A6=AD=EC=8B=9C=EC=97=90=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B0=80=EC=9A=B4=EB=8D=B0=EB=A1=9C=20?= =?UTF-8?q?=EC=98=A4=EB=8F=84=EB=A1=9D=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 5 ++--- apps/wr/app/map/newWindowPortal.tsx | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 403401714..e0e43931c 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -671,9 +671,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보" - width={viewMode == 'list' ? window.screen.availWidth : 900} - height={viewMode == 'list' ? window.screen.availHeight : 900} - resizable="no" + width={viewMode == 'list' ? window.screen.availWidth : 1000} + height={viewMode == 'list' ? window.screen.availHeight : layerId == '하수처리시설' && viewMode == 'detail' ? 450 : 900} scrollbars="yes"> {/* 체크된 레이어에 따른 조건부 렌더링 */} {renderConditionalContent()} diff --git a/apps/wr/app/map/newWindowPortal.tsx b/apps/wr/app/map/newWindowPortal.tsx index 6d650e3b7..b8da17d7b 100644 --- a/apps/wr/app/map/newWindowPortal.tsx +++ b/apps/wr/app/map/newWindowPortal.tsx @@ -33,7 +33,7 @@ interface NewWindowPortalProps { scrollbars?: string; } -const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", width = 900, height = 800, resizable = "yes", scrollbars= "yes" }) => { +const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", width = 900, height = 800, resizable = "yes", scrollbars = "yes" }) => { const [container, setContainer] = useState<HTMLElement | null>(null); const newWindowRef = useRef<Window | null>(null); const onCloseRef = useRef(onClose); @@ -50,14 +50,23 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti useEffect(() => { // 이미 창이 열려있으면 새로 열지 않음 if (newWindowRef.current && !newWindowRef.current.closed) return; + // 브라우저 화면 정보 + const screenLeft = window.screenLeft ?? window.screenX; + const screenTop = window.screenTop ?? window.screenY; + const screenWidth = window.innerWidth ?? document.documentElement.clientWidth; + const screenHeight = window.innerHeight ?? document.documentElement.clientHeight; + + // 중앙 위치 계산 + const left = screenLeft + (screenWidth - width) / 2; + const top = screenTop + (screenHeight - height) / 2; // 1. 새 창을 열고 참조를 저장합니다. - const popupOptions = `width=${width},height=${height},resizable=${resizable},scrollbars=${scrollbars}`; + const popupOptions = `width=${width},height=${height},left=${left}, top=${top}, resizable=${resizable},scrollbars=${scrollbars}`; newWindowRef.current = window.open('', title, popupOptions); - + if (newWindowRef.current) { newWindowRef.current.document.title = title; - + // 2. React 컴포넌트를 마운트할 컨테이너 div를 생성하여 새 창의 body에 추가합니다. const div = newWindowRef.current.document.createElement('div'); newWindowRef.current.document.body.appendChild(div); @@ -65,7 +74,6 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti // 3. 메인 창의 스타일을 새 창으로 복사합니다. (매우 중요) copyStyles(document, newWindowRef.current.document); - // 4. 사용자가 창을 닫을 때 부모에게 알리기 위한 이벤트 리스너를 설정합니다. // const handleUnload = () => { // onClose(); From 42795e517b29b5fade2ad56b7dcd1ad7ec920503 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Fri, 25 Jul 2025 13:06:19 +0900 Subject: [PATCH 13/27] =?UTF-8?q?x=EC=B6=95=20=EC=8A=A4=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index e0e43931c..4a3ad41bb 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -456,7 +456,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (isPrcsFclt) { if (viewMode == 'list') { return ( - <> + <div style={{overflowY:'auto'}}> <div className="flex justify-between items-center mb-4"> <Title title="하수처리시설 현황" /> </div> @@ -470,11 +470,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={hasuCellClick} onPageChange={setHasuPage} /> - </> + </div> ) } else { return ( - <> + <div style={{overflowX:'hidden'}}> <div className="flex justify-between items-center mb-4"> <Title title="하수처리시설 상세정보" /> </div> @@ -497,7 +497,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={() => { }} onPageChange={() => { }} /> - </> + </div> ) } } @@ -528,7 +528,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } else { // 재이용시설 목록 return ( - <> + <div style={{overflowY:'auto'}}> <div className="flex justify-between items-center"> <Title title="하수재이용시설 현황" /> {/* <div className="flex gap-2 mt-8"> @@ -550,7 +550,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ > <HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} /> </UiTable> - </> + </div> ); } } @@ -600,7 +600,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } else { // 중수도시설 목록 return ( - <> + <div style={{overflowY:'auto'}}> <div className="flex justify-between items-center"> <Title title="중수도시설 현황" /> {/* <div className="flex gap-2 mt-8"> @@ -622,7 +622,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ > <HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} /> </UiTable> - </> + </div> ); } } @@ -636,7 +636,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } else { // 온배수시설 목록 return ( - <> + <div style={{overflowY:'auto'}}> <div className="flex justify-between items-center"> <Title title="온배수시설 현황" /> {/* <div className="flex gap-2 mt-8"> @@ -658,7 +658,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ > <HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} /> </UiTable> - </> + </div> ); } } @@ -671,9 +671,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보" - width={viewMode == 'list' ? window.screen.availWidth : 1000} + width={viewMode == 'list' ? window.screen.availWidth : 1100} height={viewMode == 'list' ? window.screen.availHeight : layerId == '하수처리시설' && viewMode == 'detail' ? 450 : 900} - scrollbars="yes"> + scrollbars='yes' + resizable='no'> {/* 체크된 레이어에 따른 조건부 렌더링 */} {renderConditionalContent()} </NewWindowPortal> From f3ca55d183b72a4b807ece4f741cb25102e0573d Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Fri, 25 Jul 2025 14:07:25 +0900 Subject: [PATCH 14/27] =?UTF-8?q?=EB=B9=8C=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx | 1 + apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx | 4 +++- .../ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index d6fefe4d3..bf18d4d98 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -370,6 +370,7 @@ export default function Page() { pageNation={rswtPageNation} onPageChange={rswtPageChange} pageCount={rswtChkgdn.rswtChkCount} + readonly={mdfcnAuthrtYn === 'N'} /> )} </ListDiv> diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx index a2955f386..692623592 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx @@ -226,6 +226,7 @@ export default function Page() { pageNation={rainPageNation} onPageChange={rainPageChange} pageCount={rainChkSttn.rainChkCount} + readonly={true} /> ) : ( <RswtChkgdTable @@ -236,6 +237,7 @@ export default function Page() { pageNation={rswtPageNation} onPageChange={rswtPageChange} pageCount={rswtChkSttn.rswtChkCount} + readonly={true} /> )} </ListDiv> @@ -247,7 +249,7 @@ export default function Page() { setIsModal({ open: !open, data: {} }); }} bodyClass={"w-[80vw] max-w-none"} - body={<ChkgdModal type={selFcltDiv} obj={isModal.data} setIsModal={() => { }} />} + body={<ChkgdModal readonly={true} type={selFcltDiv} obj={isModal.data} setIsModal={() => { }} />} ></UiModal> <Toaster position="top-center" /> </ContentsDiv> diff --git a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx index 7cb647579..2bb3a645f 100644 --- a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx @@ -26,6 +26,7 @@ export default function RswtChkgdTable({ pageNation, onPageChange, pageCount, + readonly = false, }: { detaiRswtlUpdate: (data: rswtrChkDetailsZodType[]) => void; handleRswtClick?: (data: any) => void; @@ -34,6 +35,7 @@ export default function RswtChkgdTable({ pageNation: number; onPageChange: (page: number) => void; pageCount: number; + readonly:boolean }) { const { code, rswtChkgdn, rswtChkSttn, rswtChkPolAndGuide, getRswtSttnExcel } = useWrStore( (state) => state @@ -149,7 +151,8 @@ export default function RswtChkgdTable({ handleChange, toggleSelection, selectedIds, - handleCellClick + handleCellClick, + readonly )} </TableBody> </Table> From c29d191a5ec12dff7f0844935160a00f37f5ef72 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Fri, 25 Jul 2025 14:27:15 +0900 Subject: [PATCH 15/27] =?UTF-8?q?=EA=B3=84=EC=82=B0=EC=8B=9D=EC=97=90?= =?UTF-8?q?=EC=84=9C=20*365=20=EB=B9=BC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx index 5900014e0..43f707619 100644 --- a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx +++ b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx @@ -94,7 +94,7 @@ export default function ConCostForm({ return; } - const dmndQtyYear = dmndQtyWatch * 365; + const dmndQtyYear = dmndQtyWatch; if (usgPrcsProcs && usgPrcsProcs?.length > 0) { const firstProc = getConstFctCode(usgPrcsProcs?.split("+")[0] || "") || ""; @@ -361,7 +361,8 @@ export default function ConCostForm({ console.log("dmndQty ", e); //field.onChange(Number(e.target.value) * 365 ); }} - value={Number(field.value) * 365 || 0} + // value={Number(field.value) * 365 || 0} + value={Number(field.value) || 0} readOnly /> </FormUi> From d7233992fed24ad3f5cf38c1191028f8e0cfafe7 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 25 Jul 2025 14:30:33 +0900 Subject: [PATCH 16/27] =?UTF-8?q?[apps/cs]=20feat:=20=EC=A0=91=EC=86=8D?= =?UTF-8?q?=EC=9E=90=20=ED=86=B5=EA=B3=84=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user-statistics/page.tsx | 2 + .../cs/src/pages/user-statistics/api/index.ts | 1 + .../api/user-statistics-service.ts | 138 ++++++++ apps/cs/src/pages/user-statistics/index.ts | 1 + .../pages/user-statistics/model/chart-data.ts | 148 ++++++++ .../user-statistics/model/table-columns.ts | 39 +++ .../model/user-statistics-interface.ts | 56 +++ .../ui/user-statistics-page.tsx | 330 ++++++++++++++++++ 8 files changed, 715 insertions(+) create mode 100644 apps/cs/app/(with-base-layout)/user-statistics/page.tsx create mode 100644 apps/cs/src/pages/user-statistics/api/index.ts create mode 100644 apps/cs/src/pages/user-statistics/api/user-statistics-service.ts create mode 100644 apps/cs/src/pages/user-statistics/index.ts create mode 100644 apps/cs/src/pages/user-statistics/model/chart-data.ts create mode 100644 apps/cs/src/pages/user-statistics/model/table-columns.ts create mode 100644 apps/cs/src/pages/user-statistics/model/user-statistics-interface.ts create mode 100644 apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx diff --git a/apps/cs/app/(with-base-layout)/user-statistics/page.tsx b/apps/cs/app/(with-base-layout)/user-statistics/page.tsx new file mode 100644 index 000000000..125900022 --- /dev/null +++ b/apps/cs/app/(with-base-layout)/user-statistics/page.tsx @@ -0,0 +1,2 @@ +import { UserStatisticsPage } from "@/pages/user-statistics"; +export default UserStatisticsPage; diff --git a/apps/cs/src/pages/user-statistics/api/index.ts b/apps/cs/src/pages/user-statistics/api/index.ts new file mode 100644 index 000000000..802b91e30 --- /dev/null +++ b/apps/cs/src/pages/user-statistics/api/index.ts @@ -0,0 +1 @@ +export { UserStatisticsApi } from "./user-statistics-service"; diff --git a/apps/cs/src/pages/user-statistics/api/user-statistics-service.ts b/apps/cs/src/pages/user-statistics/api/user-statistics-service.ts new file mode 100644 index 000000000..10c90c024 --- /dev/null +++ b/apps/cs/src/pages/user-statistics/api/user-statistics-service.ts @@ -0,0 +1,138 @@ +import { + type AccessLog, + type AccessLogParams, + type AccessLogService, + type PageableList, +} from "../model/user-statistics-interface"; + +// 목 데이터 +const mockAccessLogs: AccessLog[] = [ + { + no: 1, + accessTime: "2024-01-15 14:30:25", + accessIp: "192.168.1.100", + accessRegion: "서울특별시", + urlPath: "/index", + browser: "Chrome", + site: "SITE1", + accessType: "메인", + }, + { + no: 2, + accessTime: "2024-01-15 14:28:15", + accessIp: "203.241.50.123", + accessRegion: "부산광역시", + urlPath: "/board/list", + browser: "Edge", + site: "SITE2", + accessType: "게시판", + }, + { + no: 3, + accessTime: "2024-01-15 14:25:42", + accessIp: "175.223.45.67", + accessRegion: "대구광역시", + urlPath: "/statistics", + browser: "Safari", + site: "SITE1", + accessType: "통계", + }, + { + no: 4, + accessTime: "2024-01-15 14:22:18", + accessIp: "211.252.87.45", + accessRegion: "인천광역시", + urlPath: "/contents/view", + browser: "Firefox", + site: "SITE3", + accessType: "컨텐츠", + }, + { + no: 5, + accessTime: "2024-01-15 14:20:33", + accessIp: "121.254.12.89", + accessRegion: "광주광역시", + urlPath: "/search", + browser: "Chrome", + site: "SITE1", + accessType: "검색", + }, +]; + +// 목 API 서비스 +class UserStatisticsApiImpl implements AccessLogService { + async getAccessLogList( + params: AccessLogParams, + ): Promise<PageableList<AccessLog>> { + // 실제 API 호출 대신 목 데이터 반환 + const { page = 0, size = 10 } = params; + + // 필터링 로직 (실제로는 서버에서 처리) + let filteredLogs = [...mockAccessLogs]; + + if (params.urlPath) { + filteredLogs = filteredLogs.filter((log) => + log.urlPath.toLowerCase().includes(params.urlPath!.toLowerCase()), + ); + } + + if (params.accessIp) { + filteredLogs = filteredLogs.filter((log) => + log.accessIp.includes(params.accessIp!), + ); + } + + if (params.accessRegion) { + filteredLogs = filteredLogs.filter((log) => + log.accessRegion.includes(params.accessRegion!), + ); + } + + if (params.browser) { + filteredLogs = filteredLogs.filter( + (log) => log.browser.toLowerCase() === params.browser!.toLowerCase(), + ); + } + + if (params.siteId) { + filteredLogs = filteredLogs.filter((log) => log.site === params.siteId); + } + + // 페이지네이션 + const start = page * size; + const end = start + size; + const paginatedLogs = filteredLogs.slice(start, end); + + // 목 응답 생성 + return { + content: paginatedLogs, + pageable: { + pageNumber: page, + pageSize: size, + sort: { + empty: true, + sorted: false, + unsorted: true, + }, + offset: page * size, + paged: true, + unpaged: false, + }, + last: (page + 1) * size >= filteredLogs.length, + totalPages: Math.ceil(filteredLogs.length / size), + totalElements: filteredLogs.length, + size, + number: page, + sort: { + empty: true, + sorted: false, + unsorted: true, + }, + first: page === 0, + numberOfElements: paginatedLogs.length, + empty: paginatedLogs.length === 0, + }; + } +} + +export const UserStatisticsApi = new UserStatisticsApiImpl(); diff --git a/apps/cs/src/pages/user-statistics/index.ts b/apps/cs/src/pages/user-statistics/index.ts new file mode 100644 index 000000000..6d4fc3a25 --- /dev/null +++ b/apps/cs/src/pages/user-statistics/index.ts @@ -0,0 +1 @@ +export { UserStatisticsPage } from "./ui/user-statistics-page"; diff --git a/apps/cs/src/pages/user-statistics/model/chart-data.ts b/apps/cs/src/pages/user-statistics/model/chart-data.ts new file mode 100644 index 000000000..c836a4e5d --- /dev/null +++ b/apps/cs/src/pages/user-statistics/model/chart-data.ts @@ -0,0 +1,148 @@ +import { type ChartData, type ChartOptions } from "chart.js"; + +// 일별 접속 현황 차트 데이터 +export const monthlyStatisticsData = { + labels: [ + "1일", + "2일", + "3일", + "4일", + "5일", + "6일", + "7일", + "8일", + "9일", + "10일", + "11일", + "12일", + "13일", + "14일", + "15일", + ], + datasets: [ + { + type: "bar" as const, + label: "페이지뷰", + data: [ + 850, 1000, 750, 750, 700, 750, 780, 800, 850, 900, 1200, 1700, 2300, + 2100, 2600, + ], + backgroundColor: "rgba(54, 162, 235, 0.8)", + order: 2, + }, + { + type: "line" as const, + label: "신규 접속자", + data: [ + 700, 600, 500, 550, 500, 550, 500, 550, 600, 850, 1200, 1500, 1700, + 2300, 2200, + ], + borderColor: "rgba(255, 99, 132, 0.8)", + borderWidth: 2, + tension: 0.4, + pointRadius: 3, + order: 0, + }, + { + type: "line" as const, + label: "총 접속자", + data: [ + 200, 300, 400, 500, 600, 500, 550, 500, 400, 500, 350, 800, 900, 1200, + 1300, + ], + borderColor: "rgba(75, 192, 192, 0.8)", + borderWidth: 2, + tension: 0.4, + pointRadius: 3, + order: 1, + }, + ], +}; + +export const monthlyStatisticsOptions: ChartOptions<"bar"> = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: "top" as const, + }, + tooltip: { + mode: "index" as const, + intersect: false, + }, + }, +}; + +// 사이트별 접속자 차트 데이터 +export const siteVisitorsData: ChartData<"bar"> = { + labels: ["SITE1", "SITE2", "SITE3", "SITE4", "SITE5"], + datasets: [ + { + label: "사이트별 접속자", + data: [2500, 2000, 1500, 1200, 800], + backgroundColor: [ + "rgba(54, 162, 235, 0.8)", + "rgba(153, 102, 255, 0.8)", + "rgba(255, 99, 132, 0.8)", + "rgba(255, 159, 64, 0.8)", + "rgba(255, 205, 86, 0.8)", + ], + borderWidth: 1, + }, + ], +}; + +export const siteVisitorsOptions: ChartOptions<"bar"> = { + responsive: true, + maintainAspectRatio: false, + indexAxis: "y" as const, + plugins: { + legend: { + display: false, + }, + }, +}; + +// 브라우저별 접속자 차트 데이터 +export const browserStatisticsData: ChartData<"doughnut"> = { + labels: ["Chrome", "Edge", "Safari", "Firefox", "Internet Explorer"], + datasets: [ + { + data: [45, 25, 15, 10, 5], + backgroundColor: [ + "rgba(54, 162, 235, 0.8)", + "rgba(153, 102, 255, 0.8)", + "rgba(255, 99, 132, 0.8)", + "rgba(255, 159, 64, 0.8)", + "rgba(255, 205, 86, 0.8)", + ], + borderColor: [ + "rgba(54, 162, 235, 1)", + "rgba(153, 102, 255, 1)", + "rgba(255, 99, 132, 1)", + "rgba(255, 159, 64, 1)", + "rgba(255, 205, 86, 1)", + ], + borderWidth: 1, + }, + ], +}; + +export const browserStatisticsOptions: ChartOptions<"doughnut"> = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: "bottom" as const, + }, + }, +}; + +export const chartData = { + monthlyStatisticsData, + monthlyStatisticsOptions, + siteVisitorsData, + siteVisitorsOptions, + browserStatisticsData, + browserStatisticsOptions, +}; diff --git a/apps/cs/src/pages/user-statistics/model/table-columns.ts b/apps/cs/src/pages/user-statistics/model/table-columns.ts new file mode 100644 index 000000000..c0d53380e --- /dev/null +++ b/apps/cs/src/pages/user-statistics/model/table-columns.ts @@ -0,0 +1,39 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { type AccessLog } from "./user-statistics-interface"; + +const columnHelper = createColumnHelper<AccessLog>(); + +export const columns = [ + columnHelper.accessor("no", { + header: "No", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("accessTime", { + header: "접속일시", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("accessIp", { + header: "접속IP", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("accessRegion", { + header: "접속지역", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("urlPath", { + header: "URL경로", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("browser", { + header: "브라우저", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("site", { + header: "사이트", + cell: (info) => info.getValue(), + }), + columnHelper.accessor("accessType", { + header: "메뉴명", + cell: (info) => info.getValue(), + }), +]; diff --git a/apps/cs/src/pages/user-statistics/model/user-statistics-interface.ts b/apps/cs/src/pages/user-statistics/model/user-statistics-interface.ts new file mode 100644 index 000000000..124d91044 --- /dev/null +++ b/apps/cs/src/pages/user-statistics/model/user-statistics-interface.ts @@ -0,0 +1,56 @@ +export interface AccessLog { + no: number; + accessTime: string; + accessIp: string; + accessRegion: string; + urlPath: string; + browser: string; + site: string; + accessType: string; +} + +export interface AccessLogParams { + page?: number; + size?: number; + urlPath?: string; + accessIp?: string; + accessRegion?: string; + browser?: string; + accessDateStart?: string; + accessDateEnd?: string; + siteId?: string; + sort?: string; +} + +export interface AccessLogService { + getAccessLogList(params: AccessLogParams): Promise<PageableList<AccessLog>>; +} + +export interface PageableList<T> { + content: T[]; + pageable: { + pageNumber: number; + pageSize: number; + sort: { + empty: boolean; + sorted: boolean; + unsorted: boolean; + }; + offset: number; + paged: boolean; + unpaged: boolean; + }; + last: boolean; + totalPages: number; + totalElements: number; + size: number; + number: number; + sort: { + empty: boolean; + sorted: boolean; + unsorted: boolean; + }; + first: boolean; + numberOfElements: number; + empty: boolean; +} diff --git a/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx b/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx new file mode 100644 index 000000000..4c45e04e2 --- /dev/null +++ b/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx @@ -0,0 +1,330 @@ +"use client"; + +import dayjs from "dayjs"; +import { useState } from "react"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; +import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; +import { + Button, + Input, + InputDatePicker, + Label, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@common/components"; +import { SiteSelect } from "@/entities/site"; +import { useDataTable } from "@/shared/lib"; +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement, + ArcElement, + Filler, + Legend, + Tooltip, + type ChartData, +} from "chart.js"; +import { Bar, Doughnut } from "react-chartjs-2"; +import { UserStatisticsApi } from "../api"; +import { chartData } from "../model/chart-data"; +import { columns } from "../model/table-columns"; +import { type AccessLogParams } from "../model/user-statistics-interface"; + +ChartJS.register( + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement, + ArcElement, + Filler, + Legend, + Tooltip, +); + +type DateRange = { + from?: Date | undefined; + to?: Date | undefined; +}; + +function UserStatisticsPage() { + const defaultDateRange: DateRange = { + from: dayjs().subtract(7, "day").toDate(), + to: dayjs().toDate(), + }; + + const [pagination, setPagination] = useState<PaginationState>({ + pageIndex: 0, + pageSize: 10, + }); + const [keywordType, setKeywordType] = useState(""); + const [keyword, setKeyword] = useState(""); + const [presetDateRange, setPresetDateRange] = useState("1W"); + const [dateRange, setDateRange] = useState<DateRange>(defaultDateRange); + const [searchParams, setSearchParams] = useState<AccessLogParams>({ + urlPath: "", + accessIp: "", + accessRegion: "", + browser: "", + accessDateStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), + accessDateEnd: dayjs().format("YYYY-MM-DD"), + sort: "accessTime,desc", + }); + + const query = useQuery({ + queryKey: ["user-statistics", searchParams, pagination], + queryFn: () => + UserStatisticsApi.getAccessLogList({ + ...searchParams, + page: pagination.pageIndex, + size: pagination.pageSize, + }), + placeholderData: keepPreviousData, + }); + + const { tableComponent, tableInstance: table } = useDataTable({ + query, + tableOptions: { + columns, + state: { + pagination, + }, + manualPagination: true, + getCoreRowModel: getCoreRowModel(), + onPaginationChange: setPagination, + }, + dataTableOptions: { + viewPagination: true, + }, + }); + + const handlePresetDateRange = (value: string) => { + let presetDateRange: DateRange | undefined; + switch (value) { + case "1W": + presetDateRange = { + from: dayjs().subtract(7, "day").toDate(), + to: dayjs().toDate(), + }; + break; + case "1M": + presetDateRange = { + from: dayjs().subtract(30, "day").toDate(), + to: dayjs().toDate(), + }; + break; + case "3M": + presetDateRange = { + from: dayjs().subtract(90, "day").toDate(), + to: dayjs().toDate(), + }; + break; + default: + presetDateRange = undefined; + } + setPresetDateRange(value); + setDateRange(presetDateRange || defaultDateRange); + }; + + const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); + + // 검색 조건에 따라 검색 파라미터 설정 + const params: AccessLogParams = { + sort: "accessTime,desc", + accessDateStart: dateRange.from + ? dayjs(dateRange.from).format("YYYY-MM-DD") + : "", + accessDateEnd: dateRange.to + ? dayjs(dateRange.to).format("YYYY-MM-DD") + : "", + }; + + // 검색어 타입에 따라 파라미터 설정 + switch (keywordType) { + case "urlPath": + params.urlPath = keyword; + break; + case "ip": + params.accessIp = keyword; + break; + case "region": + params.accessRegion = keyword; + break; + case "browser": + params.browser = keyword; + break; + } + + setSearchParams(params); + }; + + const handleReset = () => { + setKeywordType(""); + setKeyword(""); + setDateRange(defaultDateRange); + setPresetDateRange("1W"); + setSearchParams({ + urlPath: "", + accessIp: "", + accessRegion: "", + browser: "", + accessDateStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), + accessDateEnd: dayjs().format("YYYY-MM-DD"), + sort: "accessTime,desc", + }); + }; + + return ( + <div className="card card-border !mt-6"> + <div className="card card-border"> + <form onSubmit={handleSubmit} className="flex items-center gap-2 p-2"> + <Label className="mr-2">날짜</Label> + <Select value={presetDateRange} onValueChange={handlePresetDateRange}> + <SelectTrigger className="w-[12rem]"> + <SelectValue placeholder="기간 선택" className="w-[24rem]" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="1W">일주일</SelectItem> + <SelectItem value="1M">1개월</SelectItem> + <SelectItem value="3M">3개월</SelectItem> + </SelectContent> + </Select> + <InputDatePicker + value={dateRange.from} + onChange={(date) => { + setDateRange({ ...dateRange, from: date }); + setPresetDateRange(""); + }} + /> + ~ + <InputDatePicker + value={dateRange.to} + onChange={(date) => { + setDateRange({ ...dateRange, to: date }); + setPresetDateRange(""); + }} + /> + <Label className="ml-4 mr-2 text-label">사이트</Label> + <SiteSelect enabledAllSite className="w-[16rem]" /> + <Label className="ml-4 mr-2 text-label">검색</Label> + <Select + value={keywordType} + onValueChange={(value) => setKeywordType(value)} + > + <SelectTrigger className="h-[3.2rem] w-[10rem]"> + <SelectValue placeholder="선택" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="urlPath">URL경로</SelectItem> + <SelectItem value="ip">접속IP</SelectItem> + <SelectItem value="region">접속지역</SelectItem> + <SelectItem value="browser">브라우저</SelectItem> + </SelectContent> + </Select> + <Input + value={keyword} + onChange={(e) => setKeyword(e.target.value)} + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" + /> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> + </form> + </div> + + {/* 차트 영역 */} + <div className="grid grid-cols-2"> + {/* 일별 접속 현황 */} + <div className="card card-border"> + <div className="card-header"> + <h3 className="text-xl font-medium">일별 접속 현황</h3> + </div> + <div className="h-96 p-4"> + <Bar + data={chartData.monthlyStatisticsData as ChartData<"bar">} + options={chartData.monthlyStatisticsOptions} + /> + </div> + </div> + + <div className="grid grid-cols-2"> + {/* 사이트별 접속자 */} + <div className="card card-border"> + <div className="card-header"> + <h3 className="text-xl font-medium">사이트별 접속자</h3> + </div> + <div className="h-96 p-4"> + <Bar + data={chartData.siteVisitorsData} + options={chartData.siteVisitorsOptions} + /> + </div> + </div> + + {/* 브라우저별 접속자 */} + <div className="card card-border"> + <div className="card-header"> + <h3 className="text-xl font-medium">브라우저별 접속자</h3> + </div> + <div className="h-96 p-4"> + <Doughnut + data={chartData.browserStatisticsData} + options={chartData.browserStatisticsOptions} + /> + </div> + </div> + </div> + </div> + + {/* 접속 로그 상세 */} + <div className="card card-border"> + <div className="card-header"> + <div className="flex w-full items-center justify-between"> + <h3 className="text-2xl font-medium text-label">접속 로그 상세</h3> + <div className="flex gap-2"> + <Select + value={table.getState().pagination.pageSize.toString()} + onValueChange={(value) => { + table.setPageSize(parseInt(value)); + }} + > + <SelectTrigger className="h-[3.2rem] w-[12rem]"> + <SelectValue placeholder="페이지 크기" /> + </SelectTrigger> + <SelectContent> + {[10, 20, 30, 40, 50].map((pageSize) => ( + <SelectItem key={pageSize} value={pageSize.toString()}> + {pageSize}개씩 보기 + </SelectItem> + ))} + </SelectContent> + </Select> + </div> + </div> + </div> + <div className="card !m-[1.2rem] !p-0">{tableComponent}</div> + </div> + </div> + ); +} + +export { UserStatisticsPage }; From c0eb6b94cc77fe02fff99580001f5cc409ce4241 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Fri, 25 Jul 2025 14:46:28 +0900 Subject: [PATCH 17/27] =?UTF-8?q?=EA=B0=80=EB=AA=B8=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/drgtSttn/page.tsx | 17 +++++++++-------- apps/wr/app/store/matDmd/drgtSttn/index.tsx | 7 ++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx index 4e51a1ed8..be7210f3f 100644 --- a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx @@ -15,9 +15,9 @@ import { toast, Toaster } from "react-hot-toast"; export default function DrgtSttn() { const { code, drgt, drgtSearch, drgtModalSearch, drgtInit } = useWrStore((state) => state); const { drgtRes, drgtMoRes } = drgt; - const [fromDate, setFromDate] = useState<string>(); - const [toDate, setToDate] = useState<string>(); - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(); + const [fromDate, setFromDate] = useState<string>('202506'); + const [toDate, setToDate] = useState<string>('202506'); + const [selectSgg, setSelectSgg] = useState<SelectDataType[]>([{ val: '0', text: '전체' }]); const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); const [tableData, setTableData] = useState<customDrgt[]>(); const [selectedSgg, setSelectedSgg] = useState<string>(''); @@ -93,9 +93,9 @@ export default function DrgtSttn() { const cityValue = String(val); if (cityValue === "0") { - setSelectSgg([]); - setSelectedSgg(''); - setObjSearch({ city: cityValue, sgg: '' }); + setSelectSgg([{ val: '0', text: '전체' }]); + setSelectedSgg('0'); + setObjSearch({ city: cityValue, sgg: '0' }); } else { const data = getCity(cityValue, code.sggCd); setSelectSgg(data); @@ -136,14 +136,15 @@ export default function DrgtSttn() { selectClass={""} selectArray={code.cityCd || []} onSelectValue={getSelCity} + value={objSearch?.city ||code.cityCd[0]?.val ||""} /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-8" label="시군구" selectClass={""} - selectArray={selectSgg || []} + selectArray={selectSgg || [{ val: '0', text: '전체' }]} onSelectValue={getSgg} - value={selectedSgg} + value={selectedSgg ||'0'} /> <div className="col-span-5 w-auto"> <div className="flex flex-row items-center"> diff --git a/apps/wr/app/store/matDmd/drgtSttn/index.tsx b/apps/wr/app/store/matDmd/drgtSttn/index.tsx index fa1d3f894..f6257ebaf 100644 --- a/apps/wr/app/store/matDmd/drgtSttn/index.tsx +++ b/apps/wr/app/store/matDmd/drgtSttn/index.tsx @@ -98,9 +98,10 @@ export const drgtActionsExport: (set: any) => drgtActions = ( const year = today.getFullYear(); const month = String(today.getMonth() + 1).padStart(2, '0'); const formatted = `${year}${month}`; - const fromDate = formatted; - const toDate = formatted; - + let fromDate = formatted; + let toDate = formatted; + fromDate='202506' + toDate='202506' const drgtRes = await initFetch(fromDate, toDate, []); set((state: drgtState) => { return { From 78eb2d8fcda3b36e0f7e28f692720133cd56b53d Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 25 Jul 2025 15:11:41 +0900 Subject: [PATCH 18/27] =?UTF-8?q?[apps/cs]=20chore:=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EB=93=B1=EB=A1=9D=20=ED=8F=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/image/ui/create-page.tsx | 1 + apps/cs/src/pages/image/ui/image-form.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/cs/src/pages/image/ui/create-page.tsx b/apps/cs/src/pages/image/ui/create-page.tsx index e7dda81d5..3bb249d25 100644 --- a/apps/cs/src/pages/image/ui/create-page.tsx +++ b/apps/cs/src/pages/image/ui/create-page.tsx @@ -23,6 +23,7 @@ function CreatePage() { resolver: zodResolver(imageFormSchema), defaultValues: { atflYn: "Y", + useYn: "Y", }, }); diff --git a/apps/cs/src/pages/image/ui/image-form.tsx b/apps/cs/src/pages/image/ui/image-form.tsx index 1de7820c5..7430a21e1 100644 --- a/apps/cs/src/pages/image/ui/image-form.tsx +++ b/apps/cs/src/pages/image/ui/image-form.tsx @@ -124,6 +124,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { {...field} type="number" min={0} + max={9999} value={field.value ?? ""} onChange={(e) => field.onChange(parseInt(e.target.value)) From 393e174a6d0c1d104ad68148ef5884ed41abd5a9 Mon Sep 17 00:00:00 2001 From: 100JM <bjm_9310@naver.com> Date: Fri, 25 Jul 2025 17:39:13 +0900 Subject: [PATCH 19/27] =?UTF-8?q?=EC=97=B0=EA=B3=84=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/app/(with-base-layout)/link/page.tsx | 2 + .../link/register/[id]/page.tsx | 10 + .../(with-base-layout)/link/register/page.tsx | 2 + .../app/(with-base-layout)/linkLog/page.tsx | 2 + .../(with-base-layout)/linkParams/page.tsx | 2 + .../app/(with-base-layout)/linkStats/page.tsx | 2 + .../app/(with-base-layout)/linkTable/page.tsx | 2 + apps/cs/src/entities/link/api/link-service.ts | 191 +++++ apps/cs/src/entities/link/index.ts | 18 + .../src/entities/link/model/link-interface.ts | 235 ++++++ apps/cs/src/pages/link/index.ts | 3 + .../cs/src/pages/link/model/table-columns.tsx | 114 +++ apps/cs/src/pages/link/ui/link-form.tsx | 586 +++++++++++++++ apps/cs/src/pages/link/ui/link-page.tsx | 134 ++++ apps/cs/src/pages/link/ui/modify-page.tsx | 111 +++ apps/cs/src/pages/link/ui/regist-page.tsx | 64 ++ apps/cs/src/pages/linkLog/index.ts | 1 + .../src/pages/linkLog/model/table-columns.tsx | 55 ++ .../cs/src/pages/linkLog/ui/link-log-page.tsx | 189 +++++ apps/cs/src/pages/linkParams/index.ts | 1 + .../pages/linkParams/model/table-columns.tsx | 26 + .../linkParams/model/vrbl-table-columns.tsx | 98 +++ .../linkParams/ui/link-params-dialog.tsx | 347 +++++++++ .../pages/linkParams/ui/link-params-page.tsx | 405 ++++++++++ apps/cs/src/pages/linkStats/index.ts | 1 + .../pages/linkStats/ui/link-stats-page.tsx | 378 ++++++++++ apps/cs/src/pages/linkTable/index.ts | 1 + .../pages/linkTable/model/table-columns.tsx | 103 +++ .../pages/linkTable/ui/link-table-dialog.tsx | 501 ++++++++++++ .../pages/linkTable/ui/link-table-page.tsx | 710 ++++++++++++++++++ 30 files changed, 4294 insertions(+) create mode 100644 apps/cs/app/(with-base-layout)/link/page.tsx create mode 100644 apps/cs/app/(with-base-layout)/link/register/[id]/page.tsx create mode 100644 apps/cs/app/(with-base-layout)/link/register/page.tsx create mode 100644 apps/cs/app/(with-base-layout)/linkLog/page.tsx create mode 100644 apps/cs/app/(with-base-layout)/linkParams/page.tsx create mode 100644 apps/cs/app/(with-base-layout)/linkStats/page.tsx create mode 100644 apps/cs/app/(with-base-layout)/linkTable/page.tsx create mode 100644 apps/cs/src/entities/link/api/link-service.ts create mode 100644 apps/cs/src/entities/link/index.ts create mode 100644 apps/cs/src/entities/link/model/link-interface.ts create mode 100644 apps/cs/src/pages/link/index.ts create mode 100644 apps/cs/src/pages/link/model/table-columns.tsx create mode 100644 apps/cs/src/pages/link/ui/link-form.tsx create mode 100644 apps/cs/src/pages/link/ui/link-page.tsx create mode 100644 apps/cs/src/pages/link/ui/modify-page.tsx create mode 100644 apps/cs/src/pages/link/ui/regist-page.tsx create mode 100644 apps/cs/src/pages/linkLog/index.ts create mode 100644 apps/cs/src/pages/linkLog/model/table-columns.tsx create mode 100644 apps/cs/src/pages/linkLog/ui/link-log-page.tsx create mode 100644 apps/cs/src/pages/linkParams/index.ts create mode 100644 apps/cs/src/pages/linkParams/model/table-columns.tsx create mode 100644 apps/cs/src/pages/linkParams/model/vrbl-table-columns.tsx create mode 100644 apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx create mode 100644 apps/cs/src/pages/linkParams/ui/link-params-page.tsx create mode 100644 apps/cs/src/pages/linkStats/index.ts create mode 100644 apps/cs/src/pages/linkStats/ui/link-stats-page.tsx create mode 100644 apps/cs/src/pages/linkTable/index.ts create mode 100644 apps/cs/src/pages/linkTable/model/table-columns.tsx create mode 100644 apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx create mode 100644 apps/cs/src/pages/linkTable/ui/link-table-page.tsx diff --git a/apps/cs/app/(with-base-layout)/link/page.tsx b/apps/cs/app/(with-base-layout)/link/page.tsx new file mode 100644 index 000000000..c703d7fcf --- /dev/null +++ b/apps/cs/app/(with-base-layout)/link/page.tsx @@ -0,0 +1,2 @@ +import { LinkPage } from "@/pages/link"; +export default LinkPage; \ No newline at end of file diff --git a/apps/cs/app/(with-base-layout)/link/register/[id]/page.tsx b/apps/cs/app/(with-base-layout)/link/register/[id]/page.tsx new file mode 100644 index 000000000..b54d60cec --- /dev/null +++ b/apps/cs/app/(with-base-layout)/link/register/[id]/page.tsx @@ -0,0 +1,10 @@ +import { ModifyLinkPage as VModifyLinkPage } from "@/pages/link"; + +export default async function ModifyLinkPage({ + params, +}: { + params: Promise<{ id: string }>; +}) { + const { id } = await params; + return <VModifyLinkPage linkSn={id} />; +}; \ No newline at end of file diff --git a/apps/cs/app/(with-base-layout)/link/register/page.tsx b/apps/cs/app/(with-base-layout)/link/register/page.tsx new file mode 100644 index 000000000..a7be897af --- /dev/null +++ b/apps/cs/app/(with-base-layout)/link/register/page.tsx @@ -0,0 +1,2 @@ +import { RegistLinkPage } from "@/pages/link"; +export default RegistLinkPage; \ No newline at end of file diff --git a/apps/cs/app/(with-base-layout)/linkLog/page.tsx b/apps/cs/app/(with-base-layout)/linkLog/page.tsx new file mode 100644 index 000000000..bf10b7ba0 --- /dev/null +++ b/apps/cs/app/(with-base-layout)/linkLog/page.tsx @@ -0,0 +1,2 @@ +import { LinkLogPage } from "@/pages/linkLog"; +export default LinkLogPage; \ No newline at end of file diff --git a/apps/cs/app/(with-base-layout)/linkParams/page.tsx b/apps/cs/app/(with-base-layout)/linkParams/page.tsx new file mode 100644 index 000000000..a9e250bac --- /dev/null +++ b/apps/cs/app/(with-base-layout)/linkParams/page.tsx @@ -0,0 +1,2 @@ +import { LinkParamsPage } from "@/pages/linkParams"; +export default LinkParamsPage; \ No newline at end of file diff --git a/apps/cs/app/(with-base-layout)/linkStats/page.tsx b/apps/cs/app/(with-base-layout)/linkStats/page.tsx new file mode 100644 index 000000000..78acc9fc3 --- /dev/null +++ b/apps/cs/app/(with-base-layout)/linkStats/page.tsx @@ -0,0 +1,2 @@ +import { LinkStatsPage } from "@/pages/linkStats"; +export default LinkStatsPage; \ No newline at end of file diff --git a/apps/cs/app/(with-base-layout)/linkTable/page.tsx b/apps/cs/app/(with-base-layout)/linkTable/page.tsx new file mode 100644 index 000000000..df14e95e3 --- /dev/null +++ b/apps/cs/app/(with-base-layout)/linkTable/page.tsx @@ -0,0 +1,2 @@ +import { LinkTablePage } from "@/pages/linkTable"; +export default LinkTablePage; \ No newline at end of file diff --git a/apps/cs/src/entities/link/api/link-service.ts b/apps/cs/src/entities/link/api/link-service.ts new file mode 100644 index 000000000..c607dd2c7 --- /dev/null +++ b/apps/cs/src/entities/link/api/link-service.ts @@ -0,0 +1,191 @@ +import axios from "axios"; +import { + type LinkService, + type LinkSearchParam, + type LinkList, + type LinkFormData, + type LinkInfo, + type LinkLogList, + type LinkStatsList, + type LinkVrblList, + type LinkVrblFormData, + type LinkVrbl, + type LinkTable, + type LinkTableColumnsList, + type LinkTableColumns, + type LinkTableColData, + type LinkTableFormData, +} from "../model/link-interface"; + +export class LinkApiService implements LinkService { + public async getLinkList(params: LinkSearchParam): Promise<LinkList> { + const response = await axios.get<LinkList>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, + { params } + ); + return response.data; + } + + public async getLinkInfo(linkSn: string): Promise<LinkInfo> { + const response = await axios.get<LinkInfo>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkInfo/${linkSn}`, + ); + return response.data; + } + + public async linkQuickStart(linkSn: string): Promise<string> { + const response = await axios.patch<string>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/linkQuickStart/${linkSn}`, + ); + return response.data; + } + + public async updateLinkInfo(data: LinkFormData): Promise<void> { + await axios.put<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkInfo`, + data, + ); + } + + public async insertLinkInfo(data: LinkFormData): Promise<void> { + await axios.post<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkInfo`, + data, + ); + } + + public async deleteLink(linkSn: string): Promise<void> { + await axios.delete<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/deleteLink/${linkSn}`, + ); + } + + public async getLinkLogList(params: LinkSearchParam): Promise<LinkLogList> { + const response = await axios.get<LinkLogList>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/selectLinkLoglist`, + { params } + ); + return response.data; + } + + public async getLinkStatsList(params: LinkSearchParam): Promise<LinkStatsList> { + const response = await axios.get<LinkStatsList>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/selectLinkStats`, + { params } + ); + return response.data; + } + + public async getLinkVrblList(linkSn: string): Promise<LinkVrblList> { + const response = await axios.get<LinkVrblList>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkVrblList/${linkSn}`, + ); + return response.data; + } + + public async insertLinkVrbl(data: LinkVrblFormData): Promise<number> { + const response = await axios.post<number>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkVrbl`, + data, + ); + + return response.data; + } + + public async deleteLinkVrbl(data: string[]): Promise<void> { + await axios.delete<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/deleteLinkVrbl`, + { + data + } + ); + } + + public async getLinkVrblInfo(linkVrblSn: string): Promise<LinkVrbl> { + const response = await axios.get<LinkVrbl>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkVrblInfo/${linkVrblSn}`, + ); + return response.data; + } + + public async updateLinkVrblInfo(data: LinkVrblFormData): Promise<void> { + await axios.put<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkVrblInfo`, + data, + ); + } + + public async getLinkTableInfo(linkSn: string): Promise<LinkTable> { + const response = await axios.get<LinkTable>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo/${linkSn}`, + ); + return response.data; + } + + public async getLinkTableColList(linkSn: string): Promise<LinkTableColumnsList> { + const response = await axios.get<LinkTableColumnsList>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList/${linkSn}`, + ); + return response.data; + } + + public async getLinkTableColInfo(params: { colSn: string; tblSn:string; }): Promise<LinkTableColumns> { + const response = await axios.get<LinkTableColumns>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColInfo`, + { params } + ); + return response.data; + } + + public async insertLinkTableCol(data: LinkTableColData): Promise<void> { + await axios.post<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkTableCol`, + data + ); + } + + public async deleteLinkTableCol(data: string[]): Promise<void> { + await axios.delete<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/deleteLinkTableCol`, + { + data + }, + ); + } + + public async updateLinkTableCol(data: LinkTableColData): Promise<void> { + axios.put<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkTableCol`, + data, + ); + } + + public async insertLinkTableInfo(data: LinkTableFormData): Promise<void> { + await axios.post<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkTableInfo`, + data + ); + } + + public async updateLinkTableInfo(data: LinkTableFormData): Promise<void> { + await axios.put<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkTableInfo`, + data + ); + } + + public async countLinkTblNm(tblNm: string): Promise<{count: number, tbl_sn: string}> { + const response = await axios.get<{count: number, tbl_sn: string}>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/countLinkTblNm/${tblNm}`, + ); + return response.data; + } + + public async updateLinkResultCode(linkSn: string): Promise<void> { + await axios.patch<void>( + `${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkResultCode/${linkSn}`, + ); + } +} + +export const LinkApi = new LinkApiService(); \ No newline at end of file diff --git a/apps/cs/src/entities/link/index.ts b/apps/cs/src/entities/link/index.ts new file mode 100644 index 000000000..89d56aaa0 --- /dev/null +++ b/apps/cs/src/entities/link/index.ts @@ -0,0 +1,18 @@ +export { LinkApi } from "./api/link-service"; +export { + type LinkSearchParam, + type Link, + type LinkFormData, + type LinkLog, + type LinkStats, + type LinkVrbl, + type LinkVrblFormData, + type LinkTable, + type LinkTableColumns, + type LinkTableColData, + type LinkTableFormData, + linkFormSchema, + linkVrblFormSchema, + LinkTableColumnsSchema, + LinkTableSchema, +} from "./model/link-interface" \ No newline at end of file diff --git a/apps/cs/src/entities/link/model/link-interface.ts b/apps/cs/src/entities/link/model/link-interface.ts new file mode 100644 index 000000000..c4493a6c0 --- /dev/null +++ b/apps/cs/src/entities/link/model/link-interface.ts @@ -0,0 +1,235 @@ +import { z } from "zod"; +import type { PageableParams, PageableList } from "@/shared/model"; + +export interface Link { + link_sn: string; + link_nm: string; + link_clsf_cd: string; + link_url: string; + link_srvr_ip: string; + link_db_cd: string; + link_key: string; + link_id: string; + link_pswd: string; + link_cycle_stng: string; + srvc_usg: string; + last_link_rslt_cd: string; + last_link_excn_dt: string; + next_link_excn_dt: string; + last_link_err_cd: string; + mdfcn_dt: string; + mdfr: string; + link_batch_time: string; +} + +export interface LinkLog { + rownum: number; + link_sn: string; + link_nm: string; + link_rslt_cd: string; + err_cn: string; + link_err_cd: string; + log_crt_dt: string; +} + +export interface LinkInfo extends LinkFormData { + link_sn: string; + link_nm: string; + link_clsf_cd: string; + link_url: string; + link_srvr_ip: string; + link_db_cd: string; + link_key: string; + link_id: string; + link_pswd: string; + srvc_usg: string; + last_link_rslt_cd: string; + last_link_excn_dt: string; + next_link_excn_dt: string; + last_link_err_cd: string; + mdfcn_dt: string; + mdfr: string; + link_batch_time: number; +} + +export interface LinkStats { + link_sn: string; + link_nm: string; + count: number; +} + +export interface LinkVrbl { + link_vrbl_sn: string; + link_vrbl_nm: string; + link_vrbl_vl: string; + link_vrbl_cd: string; + link_vrbl_expln: string; + mdfcn_dt: string; + mdfr: string; +} + +export interface LinkTable { + link_nm: string; + link_sn: string; + tbl_sn: string; + sou_tbl_nm: string; + sou_tbl_korn_nm: string; + sou_tbl_expln: string; + trsf_tbl_nm: string; + trsf_tbl_korn_nm: string; + trsf_tbl_expln: string; +} + +export interface LinkTableColumns { + tbl_sn: string; + col_sn: string; + sou_col_nm: string; + sou_col_korn_nm: string; + sou_col_data_frm: string; + sou_col_sz: number; + trsf_col_nm: string; + trsf_col_korn_nm: string; + trsf_col_data_frm: string; + trsf_col_sz: number + pk_yn: string; + col_seq: number; + mdfcn_dt: string; + mdfr: string; +} + +export const linkFormSchema = z.object({ + link_clsf_cd: z.string().max(8).nullable().refine((val) => { + // 빈 값이나 "none" 값이면 false 반환 + return val && val !== "none"; + }, { + message: "연계 분류를 선택해주세요" + }), + link_sn: z.string().max(50).nullable().optional(), + link_nm: z.string().max(40, { message: '연계명은 40자 이하로 입력해 주세요.' }).nonempty({ message: '연계명은 필수입니다.' }), + link_url: z.string().max(1000, { message: '연계 URL은 1000자 이하로 입력해 주세요.' }).nonempty({ message: '연계 URL은 필수입니다.' }), + link_srvr_ip: z.string().max(20).nullable().optional(), + link_db_cd: z.string().max(10).nullable().optional(), + link_key: z.string().max(100, { message: '연계 KEY는 100자 이하로 입력해 주세요.' }).nonempty({ message: '연계 KEY는 필수입니다.' }), + link_id: z.string().max(20).nullable().optional(), + link_pswd: z.string().max(128).nullable().optional(), + srvc_usg: z.string().max(40).nullable().optional(), + last_link_rslt_cd: z.string().max(4).nullable().optional(), + last_link_excn_dt: z.string().max(40).nullable().optional(), + next_link_excn_dt: z.string().max(40).nullable().optional(), + last_link_err_cd: z.string().max(10).nullable().optional(), + mdfcn_dt: z.string().nullable().optional(), + mdfr: z.string().nullable().optional(), + link_batch_time: z.coerce.number().nullable().optional().refine((val) => { + if (val == null) return true; + return val >= 5; + }, { + message: "연계 주기는 5분 이상이어야 합니다." + }), +}); + +export const linkVrblFormSchema = z.object({ + link_sn: z.string().max(50).nullable().optional(), + link_vrbl_sn: z.string().max(50).nullable().optional(), + link_vrbl_nm: z.string().max(40, { message: '변수명은 40자 이하로 입력해 주세요.' }).nonempty({ message: '변수명은 필수입니다.' }), + link_vrbl_expln: z.string().max(4000, { message: '설명은 400자 이하로 입력해 주세요.' }).nullable().optional(), + link_vrbl_cd: z.string().max(10, { message: '변수코드는 10자 이하로 입력해 주세요.' }).nullable().optional(), + link_vrbl_vl: z.string().max(1000, { message: '변수값은 1000자 이하로 입력해 주세요.' }).nonempty({ message: '변수값은 필수입니다.' }), + mdfcn_dt: z.string().nullable().optional(), + mdfr: z.string().nullable().optional(), +}); + +export const LinkTableColumnsSchema = z.object({ + link_sn: z.string().max(50).nullable().optional(), + tbl_sn: z.string().max(50).nullable().optional(), + col_sn: z.string().max(50).nullable().optional(), + sou_col_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nullable().optional(), + sou_col_korn_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nullable().optional(), + sou_col_data_frm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nullable().optional(), + sou_col_sz: z.coerce.number().nullable().optional().refine((val) => { + if (val == null) return true; + return val.toString().replace('.', '').length <= 14; + }, { + message: '최대 14자리까지 입력 가능합니다.', + }), + pk_yn: z.string().max(1).nonempty(), + trsf_col_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nonempty({ message: '변환컬럼명은 필수입니다.' }), + trsf_col_korn_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nonempty({ message: '변환컬럼 한글명은 필수입니다.' }), + trsf_col_data_frm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nonempty({ message: '변환컬럼 데이터 형식은 필수입니다.' }), + trsf_col_sz: z.coerce.number().nullable().optional().refine((val) => { + if (val == null) return true; + return val.toString().replace('.', '').length <= 14; + }, { + message: '최대 14자리까지 입력 가능합니다.', + }), + col_seq: z.coerce.number().nullable().optional().refine((val) => { + if (val == null) return true; + return val > 0; + }, { + message: "컬럼 매칭 순서는 0 이상이어야 합니다." + }), + mdfcn_dt: z.string().nullable().optional(), + mdfr: z.string().nullable().optional(), +}); + +export const LinkTableSchema = z.object({ + link_sn: z.string().max(50).nullable().optional(), + tbl_sn: z.string().max(50).nullable().optional(), + link_nm: z.string().max(50).nullable().optional(), + sou_tbl_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nullable().optional(), + sou_tbl_korn_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nullable().optional(), + sou_tbl_expln: z.string().max(2000, { message: '설명은 2000자 이하로 입력해 주세요.' }).nullable().optional(), + trsf_tbl_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nonempty({ message: '변환테이블명은 필수입니다.' }), + trsf_tbl_korn_nm: z.string().max(40, { message: '40자 이하로 입력해 주세요.' }).nonempty({ message: '변환테이블 한글명은 필수입니다.' }), + trsf_tbl_expln: z.string().max(2000, { message: '설명은 2000자 이하로 입력해 주세요.' }).nullable().optional(), + mdfcn_dt: z.string().nullable().optional(), + mdfr: z.string().nullable().optional(), +}); + +interface LinkStatsListObject { + linkSuccStats: LinkStats[] | null; + linkFailStats: LinkStats[] | null; +} + +export interface LinkSearchParam extends PageableParams { + linkSn?: string; + linkNm?: string; + startDate?: string; + endDate?: string; + isSucc?: string; +} + +export type LinkFormData = z.infer<typeof linkFormSchema>; +export type LinkVrblFormData = z.infer<typeof linkVrblFormSchema>; +export type LinkTableColData = z.infer<typeof LinkTableColumnsSchema>; +export type LinkTableFormData = z.infer<typeof LinkTableSchema>; +export type LinkList = PageableList<Link>; +export type LinkLogList = PageableList<LinkLog>; +export type LinkStatsList = LinkStatsListObject; +export type LinkVrblList = PageableList<LinkVrbl>; +export type LinkTableColumnsList = PageableList<LinkTableColumns>; + +export interface LinkService { + getLinkList(params: LinkSearchParam): Promise<LinkList>; + getLinkInfo(params: string): Promise<LinkInfo>; + linkQuickStart(params: string): Promise<string>; + updateLinkInfo(data: LinkFormData): Promise<void>; + deleteLink(params: string): Promise<void>; + getLinkLogList(params: LinkSearchParam): Promise<LinkLogList>; + getLinkStatsList(params: LinkSearchParam): Promise<LinkStatsList>; + getLinkVrblList(params: string): Promise<LinkVrblList>; + insertLinkVrbl(data: LinkVrblFormData): Promise<number>; + deleteLinkVrbl(data: string[]): Promise<void>; + getLinkVrblInfo(params: string): Promise<LinkVrbl>; + updateLinkVrblInfo(data: LinkVrblFormData): Promise<void>; + getLinkTableInfo(params: string): Promise<LinkTable>; + getLinkTableColList(params: string): Promise<LinkTableColumnsList>; + getLinkTableColInfo(params: { colSn: string; tblSn: string; }): Promise<LinkTableColumns>; + insertLinkTableCol(data: LinkTableColData): Promise<void>; + deleteLinkTableCol(data: string[]): Promise<void>; + updateLinkTableCol(data: LinkTableColData): Promise<void>; + insertLinkTableInfo(data: LinkTableFormData): Promise<void>; + updateLinkTableInfo(data: LinkTableFormData): Promise<void>; + insertLinkInfo(data: LinkFormData): Promise<void>; + countLinkTblNm(tblNm: string): Promise<{ count: number, tbl_sn: string }>; + updateLinkResultCode(linkSn: string): Promise<void>; +} \ No newline at end of file diff --git a/apps/cs/src/pages/link/index.ts b/apps/cs/src/pages/link/index.ts new file mode 100644 index 000000000..6eac7d15c --- /dev/null +++ b/apps/cs/src/pages/link/index.ts @@ -0,0 +1,3 @@ +export { ModifyLinkPage } from "./ui/modify-page"; +export { RegistLinkPage } from "./ui/regist-page"; +export { LinkPage } from "./ui/link-page"; \ No newline at end of file diff --git a/apps/cs/src/pages/link/model/table-columns.tsx b/apps/cs/src/pages/link/model/table-columns.tsx new file mode 100644 index 000000000..8ea7e3fb6 --- /dev/null +++ b/apps/cs/src/pages/link/model/table-columns.tsx @@ -0,0 +1,114 @@ +import dayjs from "dayjs"; +import { createColumnHelper } from "@tanstack/react-table"; +import { type Link } from "@/entities/link"; +import { Button } from "@common/components"; +import { useMutation } from "@tanstack/react-query"; +import { LinkApi } from "@/entities/link"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; + +const columnHelper = createColumnHelper<Link>(); + +const convertMinutesToPeriod = (minutes: number): string => { + if (!minutes) return ''; + + const year = Math.floor(minutes / (525600)); // 365일 * 24시간 * 60분 + minutes = minutes % 525600; + + const month = Math.floor(minutes / (43200)); // 30일 * 24시간 * 60분 + minutes = minutes % 43200; + + const day = Math.floor(minutes / 1440); // 24시간 * 60분 + minutes = minutes % 1440; + + const hour = Math.floor(minutes / 60); + const minute = minutes % 60; + + const parts = []; + if (year > 0) parts.push(`${year}년`); + if (month > 0) parts.push(`${month}개월`); + if (day > 0) parts.push(`${day}일`); + if (hour > 0) parts.push(`${hour}시간`); + if (minute > 0) parts.push(`${minute}분`); + + return parts.join(' '); +}; + +const columns = [ + columnHelper.accessor((_, index) => index + 1, { + id: 'no', + header: 'NO', + }), + columnHelper.accessor('link_sn', { + id: 'link_sn', + header: '연계일련번호', + }), + columnHelper.accessor('link_nm', { + id: 'link_nm', + header: '연계 명', + }), + columnHelper.accessor('link_url', { + id: 'link_url', + header: '연계 URL', + cell: (info) => (info.getValue() ? info.getValue() : '-'), + }), + columnHelper.accessor('link_srvr_ip', { + id: 'link_srvr_ip', + header: '연계서버 IP', + cell: (info) => (info.getValue() ? info.getValue() : '-'), + }), + columnHelper.accessor('link_batch_time', { + id: 'link_batch_time', + header: '연계 주기', + cell: (info) => convertMinutesToPeriod(Number(info.getValue())), + }), + columnHelper.accessor('srvc_usg', { + id: 'srvc_usg', + header: '서비스용도', + cell: (info) => (info.getValue() ? info.getValue() : '-'), + }), + columnHelper.display({ + id: 'last_link_rslt_cd', + header: '연계상태', + cell: (info) => { + const resultCd = info.row.original.last_link_rslt_cd; + return <span className={`${(resultCd === 'SUCC') ? 'text-[rgb(53,162,235)]' : (resultCd === 'FAIL' ? 'text-[rgb(255,99,132)]' : 'text-[rgba(31,208,120,1)]')}`}>{resultCd === 'SUCC' ? '성공' : (resultCd === 'FAIL' ? '실패' : '대기')}</span> + }, + }), + columnHelper.accessor('last_link_excn_dt', { + id: 'last_link_excn_dt', + header: '최종연계일', + cell: (info) => (info.getValue() ? dayjs(info.getValue()).format('YYYY-MM-DD HH:mm') : '-'), + }), + columnHelper.display({ + id: 'quick_start_btn', + header: '즉시 실행', + cell: (info) => { + const row = info.row.original; + const { setMessage: alert } = useAlertStore((state) => state); + + const { mutateAsync: updateQuickStart } = useMutation({ + mutationFn: (linkSn: string) => LinkApi.linkQuickStart(linkSn), + onSuccess: (resut) => { + if (resut === 'succ') { + alert('즉시 실행 요청이 완료되었습니다.'); + } else { + alert('기존 요청이 실행 대기중입니다.'); + } + }, + onError: () => { + alert('즉시 실행 요청을 실패했습니다.'); + } + }); + + return ( + <Button color="sky" onClick={(e) => { + e.stopPropagation(); + updateQuickStart(row.link_sn); + } + }>즉시 실행</Button> + ) + } + }) +]; + +export { columns }; \ No newline at end of file diff --git a/apps/cs/src/pages/link/ui/link-form.tsx b/apps/cs/src/pages/link/ui/link-form.tsx new file mode 100644 index 000000000..a5f09af18 --- /dev/null +++ b/apps/cs/src/pages/link/ui/link-form.tsx @@ -0,0 +1,586 @@ +import { + Button, + Input, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, +} from "@common/components"; +import { FormItem, FormControl, FormField, Form } from "@/shared/ui/form"; +import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; +import type { UseFormReturn } from "react-hook-form"; +import { type LinkFormData } from "@/entities/link"; +import dayjs from "dayjs"; +import { useRouter } from "next/navigation"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { useState } from "react"; + + +type LinkFormProps = { + form: UseFormReturn<LinkFormData>; + linkSn?: string; + updateLinkInfo?: (data: LinkFormData) => void; + handleInsertLink?: (data: LinkFormData) => void; + deleteLink?: () => void; + updateLinkResultCode?: () => void; +} + +const LinkForm = ({ form, linkSn, updateLinkInfo, handleInsertLink, deleteLink, updateLinkResultCode }: LinkFormProps) => { + const isModifyMode = !!linkSn; + const router = useRouter(); + + const { confirm } = useConfirm(); + const [onConfirm, setOnConfirm] = useState(false); + + const handleConfirm = async (callback: () => Promise<void>) => { + setOnConfirm(true); + await callback(); + setOnConfirm(false); + }; + + const handleSubmit = async (data: LinkFormData) => { + const confirmMsg = !!linkSn ? '수정 하시겠습니까?' : '저장 하시겠습니까?'; + + await handleConfirm(async () => { + + if (await confirm(confirmMsg)) { + !!linkSn ? updateLinkInfo?.(data) : handleInsertLink?.(data); + } + }); + }; + + const handleDelete = async () => { + await handleConfirm(async () => { + if (await confirm('삭제하시겠습니까?')) { + deleteLink?.(); + } + }) + }; + + const convertMinutesToPeriod = (minutes: number) => { + if (!minutes) return { + year: 0, + month: 0, + day: 0, + hour: 0, + minute: 0 + }; + + const year = Math.floor(minutes / (525600)); // 365일 * 24시간 * 60분 + minutes = minutes % 525600; + + const month = Math.floor(minutes / (43200)); // 30일 * 24시간 * 60분 + minutes = minutes % 43200; + + const day = Math.floor(minutes / 1440); // 24시간 * 60분 + minutes = minutes % 1440; + + const hour = Math.floor(minutes / 60); + const minute = minutes % 60; + + const timeParts = { + year: year, + month: month, + day: day, + hour: hour, + minute: minute, + }; + + return timeParts; + }; + + return ( + <> + <Form {...form}> + <form onSubmit={form.handleSubmit(handleSubmit)}> + <div className="card"> + <Table variant="secondary"> + <colgroup> + <col width="20%" /> + <col width="80%" /> + </colgroup> + <TableBody> + {isModifyMode && + <TableRow> + <TableHead>연계 일련번호</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_sn" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="w-[12rem] !text-[1.3rem]" + disabled={true} + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + } + <TableRow> + <TableHead>* 연계 명</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.link_nm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_nm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 연계 분류</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_clsf_cd" + render={({ field }) => ( + <FormItem> + <FormControl> + <Select value={field.value ?? "none"} onValueChange={(value) => field.onChange(value)}> + <SelectTrigger id="link_clsf_cd" className="w-[20rem]"> + <SelectValue placeholder="전체"></SelectValue> + </SelectTrigger> + <SelectContent> + <SelectItem value="none">선택</SelectItem> + <SelectItem value="link0001">TIBERO 데이터베이스</SelectItem> + <SelectItem value="link0002">ORACLE 데이터베이스</SelectItem> + <SelectItem value="link0003">공공데이터 포털 API</SelectItem> + <SelectItem value="link0004">한강홍수통제소 API</SelectItem> + <SelectItem value="link0005">기상청 API</SelectItem> + <SelectItem value="link0006">국가지하수정보센터 API</SelectItem> + <SelectItem value="link0007">행정정보공동이용센터 연계</SelectItem> + </SelectContent> + </Select> + </FormControl> + {form.formState.errors.link_clsf_cd && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_clsf_cd.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 연계 URL</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_url" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.link_url && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_url.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>연계서버 IP</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_srvr_ip" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 연계 KEY</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_key" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.link_key && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_key.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>연계 ID</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_id" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>연계 비밀번호</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_pswd" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + type="password" + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>서비스 용도</TableHead> + <TableCell> + <FormField + control={form.control} + name="srvc_usg" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>연계 주기</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_batch_time" + render={({ field }) => { + const timeParts = convertMinutesToPeriod(Number(field.value)); + return ( + <FormItem> + <FormControl> + <div className="flex items-center gap-6"> + <div className="flex items-center"> + <Input + value={timeParts.year} + className="w-20 !text-[1.3rem]" + type="number" + min={0} + onChange={(e) => { + const total = (Number(e.target.value) * 525600) + + (timeParts.month * 43200) + + (timeParts.day * 1440) + + (timeParts.hour * 60) + + timeParts.minute; + field.onChange(total); + }} + /> + <span className="ml-2">년</span> + </div> + <div className="flex items-center"> + <Input + value={timeParts.month} + className="w-20 !text-[1.3rem]" + type="number" + min={0} + max={11} + onChange={(e) => { + const total = (timeParts.year * 525600) + + (Number(e.target.value) * 43200) + + (timeParts.day * 1440) + + (timeParts.hour * 60) + + timeParts.minute; + field.onChange(total); + }} + /> + <span className="ml-2">월</span> + </div> + <div className="flex items-center"> + <Input + value={timeParts.day} + className="w-20 !text-[1.3rem]" + type="number" + min={0} + max={30} + onChange={(e) => { + const total = (timeParts.year * 525600) + + (timeParts.month * 43200) + + (Number(e.target.value) * 1440) + + (timeParts.hour * 60) + + timeParts.minute; + field.onChange(total); + }} + /> + <span className="ml-2">일</span> + </div> + <div className="flex items-center"> + <Input + value={timeParts.hour} + className="w-20 !text-[1.3rem]" + type="number" + min={0} + max={23} + onChange={(e) => { + const total = (timeParts.year * 525600) + + (timeParts.month * 43200) + + (timeParts.day * 1440) + + (Number(e.target.value) * 60) + + timeParts.minute; + field.onChange(total); + }} + /> + <span className="ml-2">시간</span> + </div> + <div className="flex items-center"> + <Input + value={timeParts.minute} + className="w-20 !text-[1.3rem]" + type="number" + min={0} + max={59} + onChange={(e) => { + const total = (timeParts.year * 525600) + + (timeParts.month * 43200) + + (timeParts.day * 1440) + + (timeParts.hour * 60) + + Number(e.target.value); + field.onChange(total); + }} + /> + <span className="ml-2">분</span> + </div> + </div> + </FormControl> + {form.formState.errors.link_batch_time && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_batch_time.message} + </p> + )} + </FormItem> + ); + }} + /> + </TableCell> + </TableRow> + {isModifyMode && + <> + <TableRow> + <TableHead>연계 상태</TableHead> + <TableCell> + <FormField + control={form.control} + name="last_link_rslt_cd" + render={({ field }) => { + return ( + <FormItem> + <FormControl> + <div className="flex items-center gap-6"> + <Input + {...field} + value={field.value ? (field.value === 'SUCC' ? '성공' : (field.value === 'FAIL' ? '실패' : '대기')) : ''} + className="!text-[1.3rem] w-[15rem]" + disabled + /> + <Button color="green" type="button" onClick={() => updateLinkResultCode?.()}>대기로 전환</Button> + </div> + </FormControl> + </FormItem> + ); + }} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>최종 연계 실행일</TableHead> + <TableCell> + <FormField + control={form.control} + name="last_link_excn_dt" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ? dayjs(field.value).format('YYYY-MM-DD HH:mm:ss') : ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>다음 연계 실행일</TableHead> + <TableCell> + <FormField + control={form.control} + name="next_link_excn_dt" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ? dayjs(field.value).format('YYYY-MM-DD HH:mm:ss') : ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>수정자</TableHead> + <TableCell> + <FormField + control={form.control} + name="mdfr" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>수정일시</TableHead> + <TableCell> + <FormField + control={form.control} + name="mdfcn_dt" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ? dayjs(field.value).format('YYYY-MM-DD') : ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + </> + } + </TableBody> + </Table> + </div> + <div className="flex justify-center gap-4 pb-12 pt-10"> + <Button + size="lg" + color="white" + type="button" + onClick={() => router.back()} + > + 목록 + </Button> + <Button size="lg" type="submit"> + 저장 + </Button> + {isModifyMode && ( + <Button size="lg" color="red" type="button" onClick={handleDelete}> + 삭제 + </Button> + )} + </div> + </form> + </Form> + <ConfirmDialog open={onConfirm} /> + </> + ) +}; + +export default LinkForm; \ No newline at end of file diff --git a/apps/cs/src/pages/link/ui/link-page.tsx b/apps/cs/src/pages/link/ui/link-page.tsx new file mode 100644 index 000000000..ee5f4d93f --- /dev/null +++ b/apps/cs/src/pages/link/ui/link-page.tsx @@ -0,0 +1,134 @@ +"use client"; + +import "@common/assets/styles/grid.css"; + +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import { Button, DataTable, Input, Label, LoadingWithAnimation } from "@common/components"; +import { getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { LinkApi, type Link, type LinkSearchParam } from "@/entities/link"; +import { useQuery } from "@tanstack/react-query"; +import { columns } from "../model/table-columns"; +import { useQueryClient } from "@tanstack/react-query"; +import { useDataTable } from "@/shared/lib"; + +function LinkPage() { + const router = useRouter(); + const queryClient = useQueryClient(); + + const [linkSn, setLinkSn] = useState<string>(''); + const [linkNm, setLinkNm] = useState<string>(''); + + const [linkSearchParam, setLinkSearchParam] = useState<LinkSearchParam>({ + linkSn: '', + linkNm: '' + }); + + const query = useQuery({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, linkSearchParam], + queryFn: () => LinkApi.getLinkList(linkSearchParam), + }); + + const handleResetSearchParam = () => { + setLinkSn(''); + setLinkNm(''); + setLinkSearchParam({ + ...linkSearchParam, + linkSn: '', + linkNm: '', + }); + }; + + const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + setLinkSearchParam({ + ...linkSearchParam, + linkSn, + linkNm + }); + }; + + const handleRowClick = (link: Link) => { + queryClient.removeQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`], + }); + queryClient.removeQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkInfo`], + }); + router.push(`link/register/${link.link_sn}`); + }; + + const handleClickRegist = () => { + router.push('link/register'); + }; + + const { tableComponent } = useDataTable({ + query, + tableOptions: { + columns, + manualPagination: true, + enableMultiRowSelection: true, + getCoreRowModel: getCoreRowModel(), + }, + dataTableOptions: { + onRowClick: handleRowClick, + viewPagination: true, + }, + }); + + return ( + <div className="card card-border !mt-6"> + <div className="card card-border"> + <form className="flex items-center gap-2 p-2" onSubmit={handleSubmit}> + <Label htmlFor="liSnSearchInput" className="mr-2 text-label"> + 일련번호 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-4" + id="liSnSearchInput" + value={linkSn} + onChange={(e) => setLinkSn(e.target.value)} + autoComplete="off" + /> + <Label htmlFor="liNmSearchInput" className="mr-2 text-label"> + 연계 명 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-2" + id="liNmSearchInput" + value={linkNm} + onChange={(e) => setLinkNm(e.target.value)} + autoComplete="off" + /> + <Button color="green" className="h-[3.2rem]" type="button" onClick={handleResetSearchParam}> + 초기화 + </Button> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + </form> + </div> + <div className="card card-border flex flex-col h-[calc(100vh-28rem)]"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계 목록</h3> + <div> + <Button onClick={handleClickRegist}>등록</Button> + </div> + </div> + <div className="card !m-[1.2rem] overflow-auto h-full !p-0"> + {!query.isLoading ? + <div>{tableComponent}</div> + : + <div className="[data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center h-full"> + <div className="relative size-[5rem]"> + <LoadingWithAnimation color="primary" /> + </div> + </div> + } + </div> + </div> + </div> + ); +} + +export { LinkPage }; \ No newline at end of file diff --git a/apps/cs/src/pages/link/ui/modify-page.tsx b/apps/cs/src/pages/link/ui/modify-page.tsx new file mode 100644 index 000000000..a15fecb97 --- /dev/null +++ b/apps/cs/src/pages/link/ui/modify-page.tsx @@ -0,0 +1,111 @@ +"use client"; + +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { LinkApi, linkFormSchema, type LinkFormData } from "@/entities/link"; +import { useRouter } from "next/navigation"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import LinkForm from "./link-form"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { useEffect } from "react"; +import { getUserInfo } from "../../../../../../packages/common/components/src/api"; +import { AUTH_USER_ID } from "@/shared/config"; +import { getCookie } from "@common/components"; + +function ModifyLinkPage({ linkSn }: { linkSn: string }) { + const router = useRouter(); + const queryClient = useQueryClient(); + const { setMessage: alert } = useAlertStore((state) => state); + const userUniqId = getCookie(AUTH_USER_ID) ?? ""; + + // 컴포넌트 마운트 시 캐시 초기화 + useEffect(() => { + queryClient.removeQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkInfo`], + }); + }, [queryClient]); + + const { data: linkInfo, refetch } = useQuery({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkInfo`], + queryFn: () => LinkApi.getLinkInfo(linkSn), + enabled: !!linkSn, + }); + + const { mutateAsync: updateLinkInfo } = useMutation({ + mutationFn: (data: LinkFormData) => LinkApi.updateLinkInfo({ + ...data, + link_clsf_cd: data.link_clsf_cd !== 'none' ? data.link_clsf_cd : null, + mdfr: userUniqId + }), + onSuccess: () => { + alert('수정되었습니다.'); + router.push('/link'); + } + }); + + const { mutateAsync: deleteLink } = useMutation({ + mutationFn: () => LinkApi.deleteLink(linkSn), + onSuccess: () => { + alert('삭제되었습니다.', router.back); + } + }); + + const { mutateAsync: updateLinkResultCode } = useMutation({ + mutationFn: () => LinkApi.updateLinkResultCode(linkSn), + onSuccess: () => { + alert('대기로 전환되었습니다.'); + refetch(); + } + }); + + const fetchUserInfo = async (id: string) => { + const userData = await getUserInfo(); + return userData.userName; + }; + + const form = useForm<LinkFormData>({ + resolver: zodResolver(linkFormSchema), + defaultValues: {}, + }); + + useEffect(() => { + const applyFormData = async () => { + if (linkInfo) { + let newData = { ...linkInfo }; + + if (linkInfo.mdfr) { + const userName = await fetchUserInfo(linkInfo.mdfr); + newData = { + ...linkInfo, + mdfr: userName, + }; + } + + form.reset(newData); + + } + }; + + applyFormData(); + }, [linkInfo]); + + return ( + <> + <div className="card card-border !mb-0 !mt-6"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계정보 수정</h3> + </div> + <LinkForm + form={form} + linkSn={linkSn} + updateLinkInfo={updateLinkInfo} + deleteLink={deleteLink} + updateLinkResultCode={updateLinkResultCode} + /> + </div> + + </> + ); +}; + +export { ModifyLinkPage }; \ No newline at end of file diff --git a/apps/cs/src/pages/link/ui/regist-page.tsx b/apps/cs/src/pages/link/ui/regist-page.tsx new file mode 100644 index 000000000..6aa26e79e --- /dev/null +++ b/apps/cs/src/pages/link/ui/regist-page.tsx @@ -0,0 +1,64 @@ +"use client"; + +import { LinkApi, type LinkFormData, linkFormSchema } from "@/entities/link"; +import LinkForm from "./link-form"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import dayjs from "dayjs"; +import { useMutation } from "@tanstack/react-query"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { useRouter } from "next/navigation"; +import { AUTH_USER_ID } from "@/shared/config"; +import { getCookie } from "@common/components"; + +function RegistLinkPage() { + const { setMessage: alert } = useAlertStore((state) => state); + const router = useRouter(); + const userUniqId = getCookie(AUTH_USER_ID) ?? ""; + + const form = useForm<LinkFormData>({ + resolver: zodResolver(linkFormSchema), + defaultValues: { + link_nm: '', + link_url: '', + link_srvr_ip: '', + link_db_cd: '', + link_key: '', + link_id: '', + link_pswd: '', + srvc_usg: '', + link_batch_time: 5, + link_clsf_cd: 'none', + }, + }); + + const { mutate: insertLinkInfo } = useMutation({ + mutationFn: (data: LinkFormData) => LinkApi.insertLinkInfo(data), + onSuccess: () => { + alert('저장되었습니다.'); + router.push('/link'); + } + }); + + const handleInsertLink = (data: LinkFormData) => { + let insertData = { + ...data, + link_clsf_cd: data.link_clsf_cd !== 'none' ? data.link_clsf_cd : null, + next_link_excn_dt: dayjs().add(Number(data.link_batch_time), 'minute').format('YYYY-MM-DD HH:mm:ss'), + mdfr: userUniqId, + }; + + insertLinkInfo(insertData); + }; + + return ( + <div className="card card-border !mb-0 !mt-6"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계 등록</h3> + </div> + <LinkForm form={form} handleInsertLink={handleInsertLink} /> + </div> + ); +}; + +export { RegistLinkPage }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkLog/index.ts b/apps/cs/src/pages/linkLog/index.ts new file mode 100644 index 000000000..53ef1798e --- /dev/null +++ b/apps/cs/src/pages/linkLog/index.ts @@ -0,0 +1 @@ +export { LinkLogPage } from './ui/link-log-page'; \ No newline at end of file diff --git a/apps/cs/src/pages/linkLog/model/table-columns.tsx b/apps/cs/src/pages/linkLog/model/table-columns.tsx new file mode 100644 index 000000000..30e7fa702 --- /dev/null +++ b/apps/cs/src/pages/linkLog/model/table-columns.tsx @@ -0,0 +1,55 @@ +import dayjs from "dayjs"; +import { createColumnHelper } from "@tanstack/react-table"; +import { type LinkLog } from "@/entities/link"; + +const columnHelper = createColumnHelper<LinkLog>(); + +const columns = [ + columnHelper.accessor('rownum', { + id: 'rownum', + header: 'NO', + }), + columnHelper.accessor('link_sn', { + id: 'link_sn', + header: '연계일련번호', + }), + columnHelper.accessor('link_nm', { + id: 'link_nm', + header: '연계 명', + }), + columnHelper.display({ + id: 'link_rslt_cd', + header: '연계실행결과', + cell: (info) => { + const isSucc = info.row.original.link_rslt_cd.trim() === 'SUCC'; + return <span className={`${isSucc ? 'text-[rgb(53,162,235)]' : 'text-[rgb(255,99,132)]'}`}>{isSucc ? '성공' : '실패'}</span> + }, + }), + columnHelper.accessor('link_err_cd', { + id: 'link_err_cd', + header: '연계오류코드', + cell: (info) => (info.getValue() ? info.getValue() : '-'), + }), + columnHelper.accessor('err_cn', { + id: 'err_cn', + header: '연계오류메세지', + cell: (info) => ( + <div + className="max-w-[500px] truncate" + title={info.getValue() ?? ''} + > + {info.getValue() || '-'} + </div> + ), + }), + columnHelper.accessor('log_crt_dt', { + id: 'log_crt_dt', + header: '연계실행일자', + cell: (info) => { + const date = dayjs(info.getValue()); + return date.format('YYYY-MM-DD HH:mm'); + } + }), +]; + +export { columns }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkLog/ui/link-log-page.tsx b/apps/cs/src/pages/linkLog/ui/link-log-page.tsx new file mode 100644 index 000000000..dd39a4726 --- /dev/null +++ b/apps/cs/src/pages/linkLog/ui/link-log-page.tsx @@ -0,0 +1,189 @@ +"use client"; + +import "@common/assets/styles/grid.css"; + +import { useState } from "react"; +import { Button, Input, Label, DatePicker, Select, SelectTrigger, SelectContent, SelectItem, SelectValue, LoadingWithAnimation } from "@common/components"; +import { useQuery } from "@tanstack/react-query"; + +import { getCoreRowModel, type PaginationState, type RowSelectionState, } from "@tanstack/react-table"; +import { LinkApi, type LinkSearchParam } from "@/entities/link"; +import { columns } from "../model/table-columns"; +import dayjs from "dayjs"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { useDataTable } from "@/shared/lib"; + +function LinkLogPage() { + const { setMessage: alert } = useAlertStore((state) => state); + + const [linkSn, setLinkSn] = useState<string>(''); + const [linkNm, setLinkNm] = useState<string>(''); + const [isSucc, setIsSucc] = useState<string>('ALL'); + const [startDate, setStartDate] = useState<string>(dayjs().subtract(7, "day").format('YYYY-MM-DD')); + const [endDate, setEndDate] = useState<string>(dayjs().format('YYYY-MM-DD')); + + const [linkSearchParam, setLinkSearchParam] = useState<LinkSearchParam>({ + linkSn: '', + linkNm: '', + isSucc: '', + startDate: '', + endDate: '', + }); + + const [pagination, setPagination] = useState<PaginationState>({ + pageIndex: 0, + pageSize: 100, + }); + + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); + + const query = useQuery({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, linkSearchParam, pagination], + queryFn: () => + LinkApi.getLinkLogList({ + ...linkSearchParam, + page: pagination.pageIndex, + size: pagination.pageSize, + isSucc, + startDate, + endDate, + }), + }); + + const { tableComponent } = useDataTable({ + query, + tableOptions: { + columns, + state: { + pagination, + rowSelection, + }, + manualPagination: true, + enableMultiRowSelection: true, + getCoreRowModel: getCoreRowModel(), + onPaginationChange: setPagination, + onRowSelectionChange: setRowSelection, + }, + dataTableOptions: { + viewPagination: true, + }, + }); + + const handleResetSearchParam = () => { + setIsSucc('ALL'); + setLinkNm(''); + setLinkSn(''); + setStartDate(dayjs().subtract(7, "day").format('YYYY-MM-DD')); + setEndDate(dayjs().format('YYYY-MM-DD')); + setLinkSearchParam({ + ...linkSearchParam, + linkSn: '', + linkNm: '', + isSucc: 'ALL', + startDate: dayjs().subtract(7, "day").format('YYYY-MM-DD'), + endDate: dayjs().format('YYYY-MM-DD'), + }); + }; + + const handleSubmit = async (e?: React.FormEvent<HTMLFormElement>) => { + e?.preventDefault(); + + if (startDate && endDate) { + + if (startDate > endDate) { + alert('종료일이 시작일보다 이전일 수 없습니다.'); + return; + } else { + setPagination({ + ...pagination, + pageIndex: 0, + }); + setLinkSearchParam({ + ...linkSearchParam, + linkSn, + linkNm, + isSucc, + startDate, + endDate, + }); + } + } else { + alert('조회 날짜를 선택해주세요.'); + return; + } + }; + + return ( + <div className="card card-border !mt-6"> + <div className="card card-border"> + <form className="flex items-center gap-2 p-2" onSubmit={handleSubmit}> + <Label htmlFor="liSnSearchInput" className="mr-2 text-label"> + 일련번호 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-4" + id="liSnSearchInput" + value={linkSn} + onChange={(e) => setLinkSn(e.target.value)} + autoComplete="off" + /> + <Label htmlFor="liNmSearchInput" className="mr-2 text-label"> + 연계 명 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-4" + id="liNmSearchInput" + value={linkNm} + onChange={(e) => setLinkNm(e.target.value)} + autoComplete="off" + /> + <Label htmlFor="liResultCode" className="mr-2 text-label"> + 실행결과 + </Label> + <Select onValueChange={(e) => setIsSucc(e)} value={isSucc}> + <SelectTrigger id="liResultCode" className="w-[10rem] mr-4"> + <SelectValue placeholder="전체"></SelectValue> + </SelectTrigger> + <SelectContent> + <SelectItem value="ALL">전체</SelectItem> + <SelectItem value="SUCC">성공</SelectItem> + <SelectItem value="FAIL">실패</SelectItem> + </SelectContent> + </Select> + <Label htmlFor="sDateSearchInput" className="mx-2 text-label"> + 시작일 + </Label> + <DatePicker id="sDateSearchInput" mode={"single"} selected={dayjs(startDate).toDate()} onSelect={(e) => setStartDate(dayjs(e).format('YYYY-MM-DD'))} /> + <Label htmlFor="eDateSearchInput" className="mx-2 text-label"> + 종료일 + </Label> + <DatePicker id="eDateSearchInput" mode={"single"} className="mr-2" selected={dayjs(endDate).toDate()} onSelect={(e) => setEndDate(dayjs(e).format('YYYY-MM-DD'))} /> + <Button color="green" className="h-[3.2rem]" type="button" onClick={handleResetSearchParam}> + 초기화 + </Button> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + </form> + </div> + <div className="card card-border flex flex-col h-[calc(100vh-28rem)]"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">로그 목록 (검색 조건에 따른 건수 : {query.data?.totalElements.toLocaleString('ko-KR') ?? 0} )</h3> + </div> + <div className="card !m-[1.2rem] overflow-auto h-full !p-0"> + {query.isLoading ? + <div className="[data-theme='black']:bg-transparent rounded-lg p-10 h-full flex justify-center items-center"> + <div className="relative size-[5rem]"> + <LoadingWithAnimation color="primary" /> + </div> + </div> + : + <div>{tableComponent}</div> + } + </div> + </div> + </div> + ) +}; + +export { LinkLogPage }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkParams/index.ts b/apps/cs/src/pages/linkParams/index.ts new file mode 100644 index 000000000..bd233390f --- /dev/null +++ b/apps/cs/src/pages/linkParams/index.ts @@ -0,0 +1 @@ +export { LinkParamsPage } from './ui/link-params-page'; \ No newline at end of file diff --git a/apps/cs/src/pages/linkParams/model/table-columns.tsx b/apps/cs/src/pages/linkParams/model/table-columns.tsx new file mode 100644 index 000000000..a71a74e9d --- /dev/null +++ b/apps/cs/src/pages/linkParams/model/table-columns.tsx @@ -0,0 +1,26 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { type Link } from "@/entities/link"; + +const columnHelper = createColumnHelper<Link>(); + +const columns = [ + columnHelper.accessor((_, index) => index + 1, { + id: 'no', + header: 'NO', + }), + columnHelper.accessor('link_sn', { + id: 'link_sn', + header: '연계 일련번호', + }), + columnHelper.accessor('link_nm', { + id: 'link_nm', + header: '연계 명', + }), + columnHelper.accessor('srvc_usg', { + id: 'srvc_usg', + header: '서비스용도', + cell: (info) => (info.getValue() ? info.getValue() : '-'), + }), +]; + +export { columns }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkParams/model/vrbl-table-columns.tsx b/apps/cs/src/pages/linkParams/model/vrbl-table-columns.tsx new file mode 100644 index 000000000..26ccc7303 --- /dev/null +++ b/apps/cs/src/pages/linkParams/model/vrbl-table-columns.tsx @@ -0,0 +1,98 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { type LinkVrbl } from "@/entities/link"; +import { Checkbox } from "@common/components"; + +const columnHelper = createColumnHelper<LinkVrbl>(); + +function vrblColumns({ + selectedVrblIds, + setSelectedVrblIds, +}: { + selectedVrblIds: string[]; + setSelectedVrblIds: React.Dispatch<React.SetStateAction<string[]>>; +}) { + return [ + columnHelper.display({ + id: "select", + header: ({ table }) => { + const allRows = table.getRowModel().rows; + const allSelected = + allRows.length > 0 && + allRows.every((row) => + selectedVrblIds.includes(row.original.link_vrbl_sn) + ); + + return ( + <div className="flex justify-center items-center"> + <Checkbox + className="bg-white" + checked={ + allSelected + ? true + : false + } + onCheckedChange={(checked) => { + if (checked) { + setSelectedVrblIds(allRows.map((row) => row.original.link_vrbl_sn)); + } else { + setSelectedVrblIds([]); + } + }} + /> + </div> + ); + }, + cell: ({ row }) => { + const id = row.original.link_vrbl_sn; + const checked = selectedVrblIds.includes(id); + + return ( + <div className="flex justify-center items-center"> + <Checkbox + checked={checked} + onClick={(e) => e.stopPropagation()} + onCheckedChange={(checked) => { + setSelectedVrblIds((prev) => + checked ? [...prev, id] : prev.filter((x) => x !== id) + ); + }} + /> + </div> + ); + }, + }), + + columnHelper.accessor("link_vrbl_sn", { + id: "link_vrbl_sn", + header: "연계 변수 일련번호", + }), + columnHelper.accessor("link_vrbl_nm", { + id: "link_vrbl_nm", + header: "변수 명", + }), + columnHelper.accessor("link_vrbl_cd", { + id: "link_vrbl_cd", + header: "변수코드", + cell: (info) => (info.getValue() ? info.getValue() : '-'), + }), + columnHelper.accessor("link_vrbl_vl", { + id: "link_vrbl_vl", + header: "변수 값", + cell: (info) => (info.getValue() === 'now' ? '요청일자' : info.getValue() === 'nowMonth' ? '요청월' : info.getValue()), + }), + columnHelper.accessor("link_vrbl_expln", { + id: "link_vrbl_expln", + header: "설명", + cell: (info) => ( + <div + className="max-w-72 truncate" + title={info.getValue() ?? ''} + > + {info.getValue() || '-'} + </div> + ), + }), + ]; +} + +export { vrblColumns }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx b/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx new file mode 100644 index 000000000..f3fe466b8 --- /dev/null +++ b/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx @@ -0,0 +1,347 @@ +'use client'; + +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogClose, + Button, + Input, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Checkbox, + RadioGroup, + RadioGroupItem, + Label +} from "@common/components"; +import { FormItem, FormControl, FormField, Form } from "@/shared/ui/form"; +import { type LinkVrblFormData } from "@/entities/link"; +import dayjs from "dayjs"; +import type { UseFormReturn } from "react-hook-form"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { useState, useEffect } from "react"; +import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; + +type LinkParamsDialogProps = { + selectedLink: { + linkSn: string; + linkNm: string; + }; + form: UseFormReturn<LinkVrblFormData>; + insertLinkVrbl: (data: LinkVrblFormData) => void; + dialogOpen: boolean; + onOpenChange: (val: boolean) => void; + updateLinkVrbl: (data: LinkVrblFormData) => void; +} + +function LinkParamsDialog({ selectedLink, form, insertLinkVrbl, dialogOpen, onOpenChange, updateLinkVrbl }: LinkParamsDialogProps) { + + const isModifyMode = !!form.getValues('link_vrbl_sn'); + + const { confirm } = useConfirm(); + const [onConfirm, setOnConfirm] = useState<boolean>(false); + const [isToday, setIsToday] = useState<boolean>(false); + const [checkNowMonth, setCheckNowMonth] = useState<string>('now'); + + const handleConfirm = async (callback: () => Promise<void>) => { + setOnConfirm(true); + await callback(); + setOnConfirm(false); + }; + + function replaceEmptyWithNull<T extends Record<string, any>>(data: T): T { + const result = {} as T; + for (const [key, value] of Object.entries(data)) { + result[key as keyof T] = value === '' ? null : value; + } + return result; + }; + + const handleSubmit = async (data: LinkVrblFormData) => { + const confirmMsg = isModifyMode ? '수정 하시겠습니까?' : '저장 하시겠습니까?'; + + await handleConfirm(async () => { + const cleanData = replaceEmptyWithNull(data); + + if (await confirm(confirmMsg)) { + isModifyMode ? updateLinkVrbl(isToday ? { ...cleanData, link_vrbl_vl: checkNowMonth } : cleanData) : insertLinkVrbl(isToday ? { ...cleanData, link_vrbl_vl: checkNowMonth } : cleanData); + } + }); + }; + + const handleCheckTodayValue = (check: boolean | string) => { + if (check) { + setIsToday(true); + form.setValue('link_vrbl_vl', (checkNowMonth === 'now' ? '요청일자' : '요청월')); + } else { + setIsToday(false); + form.setValue('link_vrbl_vl', ''); + } + }; + + useEffect(() => { + if (!dialogOpen) { + setIsToday(false); + setCheckNowMonth('now'); + form.reset({ + link_vrbl_nm: '', + link_vrbl_expln: '', + link_vrbl_cd: '', + link_vrbl_vl: '', + }); + } + + if (isModifyMode && (form.getValues('link_vrbl_vl') === 'now' || form.getValues('link_vrbl_vl') === 'nowMonth')) { + setIsToday(true); + setCheckNowMonth(form.getValues('link_vrbl_vl')); + } + + }, [dialogOpen]); + + return ( + <Dialog + open={dialogOpen} + onOpenChange={(open) => { + onOpenChange(open); + }} + > + <DialogTrigger asChild> + <Button color="green" className="h-[3.2rem]" onClick={() => onOpenChange(true)}>행 추가</Button> + </DialogTrigger> + <DialogContent className="sm:max-w-[55rem]"> + <DialogHeader> + <DialogTitle> + {selectedLink.linkNm} ({selectedLink.linkSn}) + </DialogTitle> + </DialogHeader> + <Form {...form}> + <form onSubmit={form.handleSubmit(handleSubmit)}> + <div className="card"> + <Table variant="secondary"> + <colgroup> + <col width="30%" /> + <col width="70%" /> + </colgroup> + <TableBody> + {isModifyMode && + <TableRow> + <TableHead>변수 일련번호</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_vrbl_sn" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + } + <TableRow> + <TableHead>* 변수 명</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_vrbl_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.link_vrbl_nm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_vrbl_nm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>변수 설명</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_vrbl_expln" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.link_vrbl_expln && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_vrbl_expln.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>변수 코드</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_vrbl_cd" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.link_vrbl_cd && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_vrbl_cd.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 변수 값</TableHead> + <TableCell> + <FormField + control={form.control} + name="link_vrbl_vl" + render={({ field }) => ( + <FormItem> + <div className="flex items-center gap-x-2 mb-4"> + <Checkbox id="isToday" className="!border-gray-600" checked={isToday} onCheckedChange={(check) => handleCheckTodayValue(check)} /> + <label htmlFor="isToday" className="text-gray-600">변수 값이 오늘 날짜 일시 체크해 주세요.</label> + </div> + {isToday && + <div className="flex items-center gap-x-2 mb-4"> + <RadioGroup + name="checkNowMonth" + onValueChange={(value) => { + setCheckNowMonth(value); + form.setValue('link_vrbl_vl', (value === 'now' ? '요청일자' : '요청월')); + }} + > + <div className="flex items-center space-x-2"> + <RadioGroupItem value="now" id="now" checked={checkNowMonth === 'now'} /> + <Label htmlFor="now">요청일자(YYYY-MM-DD)</Label> + </div> + <div className="flex items-center space-x-2"> + <RadioGroupItem value="nowMonth" id="nowMonth" checked={checkNowMonth === 'nowMonth'} /> + <Label htmlFor="nowMonth">요청월(YYYY-MM)</Label> + </div> + </RadioGroup> + </div> + } + <FormControl> + <Input + {...field} + value={field.value ? (field.value === 'now' ? '요청일자' : field.value === 'nowMonth' ? '요청월' : field.value) : ''} + className={`!text-[1.3rem] ${isToday ? 'bg-gray-100' : ''}`} + autoComplete="off" + disabled={isToday} + /> + </FormControl> + {form.formState.errors.link_vrbl_vl && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.link_vrbl_vl.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + {isModifyMode && + <> + <TableRow> + <TableHead>수정자</TableHead> + <TableCell> + <FormField + control={form.control} + name="mdfr" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>수정일시</TableHead> + <TableCell> + <FormField + control={form.control} + name="mdfcn_dt" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ? dayjs(field.value).format('YYYY-MM-DD') : ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + </> + } + </TableBody> + </Table> + </div> + <DialogFooter> + <Button type="submit">저장</Button> + <DialogClose asChild> + <Button color="white">취소</Button> + </DialogClose> + </DialogFooter> + </form> + </Form> + <ConfirmDialog isOpen={onConfirm} /> + </DialogContent> + </Dialog> + ) +}; + +export { LinkParamsDialog }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkParams/ui/link-params-page.tsx b/apps/cs/src/pages/linkParams/ui/link-params-page.tsx new file mode 100644 index 000000000..82273de25 --- /dev/null +++ b/apps/cs/src/pages/linkParams/ui/link-params-page.tsx @@ -0,0 +1,405 @@ +'use client'; + +import { useState, useMemo } from "react"; +import { + Button, + DataTable, + Input, + Label, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + LoadingWithAnimation, +} from "@common/components"; +import { getCoreRowModel, useReactTable, type PaginationState, type RowSelectionState, } from "@tanstack/react-table"; +import { LinkApi, type Link, type LinkSearchParam, type LinkVrblFormData, linkVrblFormSchema } from "@/entities/link"; +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { columns } from "../model/table-columns"; +import { vrblColumns } from "../model/vrbl-table-columns"; +import { type LinkVrbl } from "@/entities/link"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { LinkParamsDialog } from "./link-params-dialog"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { getUserInfo } from "../../../../../../packages/common/components/src/api"; +import { AUTH_USER_ID } from "@/shared/config"; +import { getCookie } from "@common/components"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; +import { useDataTable } from "@/shared/lib"; + +function LinkParamsPage() { + const queryClient = useQueryClient(); + + const [linkSn, setLinkSn] = useState<string>(''); + const [linkNm, setLinkNm] = useState<string>(''); + + const [linkSearchParam, setLinkSearchParam] = useState<LinkSearchParam>({ + linkSn: '', + linkNm: '' + }); + + const [selectedLink, setSelectedLink] = useState<{ + linkSn: string; + linkNm: string; + }>({ + linkSn: '', + linkNm: '' + }); + + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); + + const [pagination, setPagination] = useState<PaginationState>({ + pageIndex: 0, + pageSize: 100, + }); + + const { confirm } = useConfirm(); + + const [selectedVrblIds, setSelectedVrblIds] = useState<string[]>([]); + const [isDBdata, setIsDBData] = useState<boolean>(false); + const [dialogOpen, setDialogOpen] = useState<boolean>(false); + const [onConfirm, setOnConfirm] = useState<boolean>(false); + + const userUniqId = getCookie(AUTH_USER_ID) ?? ""; + const { setMessage: alert } = useAlertStore((state) => state); + + const dbIdList = ['link0001', 'link0002']; + + // Link 목록 쿼리 + const query = useQuery({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, linkSearchParam], + queryFn: () => LinkApi.getLinkList({ + ...linkSearchParam, + page: pagination.pageIndex, + size: pagination.pageSize, + }), + }); + + // LinkVrbl 목록 쿼리 - 별도 관리 + const linkVrblQuery = useQuery({ + queryKey: ['linkVrblList', selectedLink.linkSn], + queryFn: () => LinkApi.getLinkVrblList(selectedLink.linkSn), + enabled: !!selectedLink.linkSn && !dbIdList.includes(selectedLink.linkSn), + staleTime: 0, // 항상 최신 데이터를 가져오도록 설정 + }); + + const handleResetSearchParam = () => { + setSelectedLink({ + linkSn: '', + linkNm: '' + }); + + setLinkSn(''); + setLinkNm(''); + setLinkSearchParam({ + ...linkSearchParam, + linkSn: '', + linkNm: '' + }); + }; + + const handleConfirm = async (callback: () => Promise<void>) => { + setOnConfirm(true); + await callback(); + setOnConfirm(false); + }; + + const { mutateAsync: insertLinkVrbl } = useMutation({ + mutationFn: async (data: LinkVrblFormData) => + await LinkApi.insertLinkVrbl({ + ...data, + link_sn: selectedLink.linkSn, + mdfr: userUniqId, + }), + onSuccess: async () => { + // 쿼리 무효화를 통한 최신 데이터 가져오기 + await queryClient.invalidateQueries({ + queryKey: ['linkVrblList', selectedLink.linkSn] + }); + setDialogOpen(false); + alert('저장되었습니다.'); + } + }); + + const { mutateAsync: updateLinkVrbl } = useMutation({ + mutationFn: async (data: LinkVrblFormData) => await LinkApi.updateLinkVrblInfo({ + ...data, + link_sn: selectedLink.linkSn, + mdfr: userUniqId, + }), + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: ['linkVrblList', selectedLink.linkSn] + }); + setDialogOpen(false); + alert('저장되었습니다.'); + } + }); + + const { mutateAsync: deleteLinkVrbl } = useMutation({ + mutationFn: async (data: string[]) => await LinkApi.deleteLinkVrbl(data), + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: ['linkVrblList', selectedLink.linkSn] + }); + setSelectedVrblIds([]); + alert('삭제되었습니다.'); + } + }); + + // linkVrblQuery의 데이터를 사용 + const tableData = useMemo(() => { + return linkVrblQuery.data?.content ?? []; + }, [linkVrblQuery.data]); + + const vrblCols = useMemo( + () => + vrblColumns({ + selectedVrblIds, + setSelectedVrblIds, + }), + [selectedVrblIds] + ); + + const vrblTable = useReactTable({ + data: tableData, + columns: vrblCols, + getCoreRowModel: getCoreRowModel(), + }); + + const form = useForm<LinkVrblFormData>({ + resolver: zodResolver(linkVrblFormSchema), + defaultValues: {}, + }); + + const handleRowClick = async (link: Link) => { + setSelectedLink({ + linkSn: link.link_sn, + linkNm: link.link_nm, + }); + + setSelectedVrblIds([]); + + if (dbIdList.includes(link.link_clsf_cd)) { + setIsDBData(true); + } else { + setIsDBData(false); + } + }; + + const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + + setSelectedLink({ + linkSn: '', + linkNm: '' + }); + + setLinkSearchParam({ + ...linkSearchParam, + linkSn, + linkNm + }); + }; + + const fetchUserInfo = async (id: string) => { + const userData = await getUserInfo(); + return userData.userName; + }; + + const handleDeleteParam = async () => { + if (selectedVrblIds.length === 0) { + alert('삭제할 파라미터를 선택해 주세요.'); + } else { + await handleConfirm(async () => { + if (await confirm('선택한 파라미터 정보를 삭제하시겠습니까?')) { + deleteLinkVrbl(selectedVrblIds); + } + }); + } + }; + + const handleVrblRowClick = async (data: LinkVrbl) => { + const linkVrblInfo = await LinkApi.getLinkVrblInfo(data.link_vrbl_sn); + + if (linkVrblInfo) { + let newData = { ...linkVrblInfo }; + + if (linkVrblInfo.mdfr) { + const userName = await fetchUserInfo(linkVrblInfo.mdfr); + newData = { + ...linkVrblInfo, + mdfr: userName, + }; + } + + form.reset(newData); + } + setDialogOpen(true); + }; + + const { tableComponent } = useDataTable({ + query, + tableOptions: { + columns, + state: { + pagination, + rowSelection, + }, + manualPagination: true, + enableMultiRowSelection: true, + getCoreRowModel: getCoreRowModel(), + onPaginationChange: setPagination, + onRowSelectionChange: setRowSelection, + }, + dataTableOptions: { + onRowClick: handleRowClick, + viewPagination: true, + }, + }); + + // LinkVrbl 데이터 표시 로직 + const renderLinkVrblContent = () => { + if (isDBdata) { + return ( + <div className="flex items-center justify-center mt-14 text-gray-500 text-3xl flex-1"> + 변수를 지원하지 않는 연계 데이터입니다. + </div> + ); + } + + if (!selectedLink.linkSn) { + return ( + <div className="flex items-center justify-center mt-14 text-gray-500 text-3xl flex-1"> + 연계 데이터를 선택해주세요. + </div> + ); + } + + if (linkVrblQuery.isLoading) { + return ( + <div className="[data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center h-full"> + <div className="relative size-[5rem]"> + <LoadingWithAnimation color="primary" /> + </div> + </div> + ); + } + + return ( + <> + <div className="mb-2 mt-14 flex justify-end items-center flex-none"> + {tableData.length > 0 && ( + <Button color="red" className="h-[3.2rem] mr-2" type="button" onClick={handleDeleteParam}> + 행 삭제 + </Button> + )} + <LinkParamsDialog + selectedLink={selectedLink} + form={form} + insertLinkVrbl={insertLinkVrbl} + dialogOpen={dialogOpen} + onOpenChange={setDialogOpen} + updateLinkVrbl={updateLinkVrbl} + /> + </div> + {tableData.length > 0 ? ( + <div className="overflow-auto flex-1 min-h-[300px]"> + <DataTable table={vrblTable} onRowClick={handleVrblRowClick} /> + </div> + ) : ( + <div className="flex items-center justify-center h-20 text-gray-500 text-3xl"> + 등록된 연계 변수가 없습니다. + </div> + )} + </> + ); + }; + + return ( + <div className="card card-border !mt-6"> + <div className="card card-border"> + <form className="flex items-center gap-2 p-2" onSubmit={handleSubmit}> + <Label htmlFor="liSnSearchInput" className="mr-2 text-label"> + 일련번호 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-4" + id="liSnSearchInput" + value={linkSn} + onChange={(e) => setLinkSn(e.target.value)} + autoComplete="off" + /> + <Label htmlFor="liNmSearchInput" className="mr-2 text-label"> + 연계 명 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-2" + id="liNmSearchInput" + value={linkNm} + onChange={(e) => setLinkNm(e.target.value)} + autoComplete="off" + /> + <Button color="green" className="h-[3.2rem]" type="button" onClick={handleResetSearchParam}> + 초기화 + </Button> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + </form> + </div> + <div className="card !mb-0 flex h-[calc(100vh-28rem)] gap-5 !p-0"> + <div className="card card-border w-1/2 !mx-0 flex flex-col"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계 목록</h3> + </div> + <div className="card !m-[1.2rem] overflow-auto !p-0 h-full"> + {!query.isLoading ? ( + <div>{tableComponent}</div> + ) : ( + <div className="[data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center h-full"> + <div className="relative size-[5rem]"> + <LoadingWithAnimation color="primary" /> + </div> + </div> + )} + </div> + </div> + <div className="card card-border w-1/2 !mx-0 flex flex-col"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계 변수 정보</h3> + </div> + <div className="card !m-[1.2rem] !p-0 overflow-auto h-full flex flex-col"> + <Table variant="secondary" className="flex-none"> + <colgroup> + <col width="20%" /> + <col width="80%" /> + </colgroup> + <TableBody> + <TableRow> + <TableHead>연계 일련번호</TableHead> + <TableCell> + {selectedLink.linkSn ? selectedLink.linkSn : '-'} + </TableCell> + </TableRow> + <TableRow> + <TableHead>연계 명</TableHead> + <TableCell> + {selectedLink.linkNm ? selectedLink.linkNm : '-'} + </TableCell> + </TableRow> + </TableBody> + </Table> + {renderLinkVrblContent()} + </div> + </div> + </div> + <ConfirmDialog isOpen={onConfirm} /> + </div> + ); +} + +export { LinkParamsPage }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkStats/index.ts b/apps/cs/src/pages/linkStats/index.ts new file mode 100644 index 000000000..4e3241a79 --- /dev/null +++ b/apps/cs/src/pages/linkStats/index.ts @@ -0,0 +1 @@ +export { LinkStatsPage } from './ui/link-stats-page'; \ No newline at end of file diff --git a/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx b/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx new file mode 100644 index 000000000..547b3766f --- /dev/null +++ b/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx @@ -0,0 +1,378 @@ +"use client"; + +import { useState, useEffect, useRef } from "react"; +import dayjs from "dayjs"; +import { LinkApi, type LinkStats, type LinkSearchParam } from "@/entities/link"; +import { Button, Label, DatePicker, LoadingWithAnimation } from "@common/components"; +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + Tooltip, + Legend, + type ChartOptions, + type Chart, +} from "chart.js"; +import { Line } from "react-chartjs-2"; +import { getCoreRowModel, type PaginationState, type RowSelectionState, } from "@tanstack/react-table"; +import { columns } from "@/pages/linkLog/model/table-columns"; +import { useDataTable } from "@/shared/lib"; +import { useQuery } from "@tanstack/react-query"; + +interface LinkStatsListObject { + linkSuccStats: LinkStats[] | null; + linkFailStats: LinkStats[] | null; +} + +function LinkStatsPage() { + + const succChartRef = useRef<Chart<"line"> | null>(null); + const failChartRef = useRef<Chart<"line"> | null>(null); + + const [startDate, setStartDate] = useState<string>(dayjs().subtract(7, "day").format('YYYY-MM-DD')); + const [endDate, setEndDate] = useState<string>(dayjs().format('YYYY-MM-DD')); + + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); + + const [pagination, setPagination] = useState<PaginationState>({ + pageIndex: 0, + pageSize: 100, + }); + + const [linkStatsList, setLinkStatsList] = useState<LinkStatsListObject | null>(null); + const [logQueryParam, setLogQueryParam] = useState<{ + isSucc: 'SUCC' | 'FAIL'; + linkSn?: string; + linkNm?: string; + } | null>(null); + + const query = useQuery({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, logQueryParam, pagination], + queryFn: () => + LinkApi.getLinkLogList({ + ...logQueryParam, + page: pagination.pageIndex, + size: pagination.pageSize, + startDate, + endDate, + }), + enabled: !!logQueryParam, + }); + + + const { tableComponent } = useDataTable({ + query, + tableOptions: { + columns, + state: { + pagination, + rowSelection, + }, + manualPagination: true, + enableMultiRowSelection: true, + getCoreRowModel: getCoreRowModel(), + onPaginationChange: setPagination, + onRowSelectionChange: setRowSelection, + }, + dataTableOptions: { + viewPagination: true, + }, + }); + + const [linkSearchParam, setLinkSearchParam] = useState<LinkSearchParam>({ + linkSn: '', + linkNm: '', + startDate: '', + endDate: '', + }); + + ChartJS.register( + LineElement, + CategoryScale, + LinearScale, + PointElement, + Tooltip, + Legend + ); + + const succData = { + labels: linkStatsList?.linkSuccStats?.map((e) => e.link_nm), + datasets: [ + { + label: '연계 성공', + data: linkStatsList?.linkSuccStats?.map((e) => e.count), + fill: false, + borderColor: 'rgb(53, 162, 235)', + backgroundColor: 'rgb(53, 162, 235)', + tension: 0.1, + pointRadius: 6, + pointHoverRadius: 8, + }, + ], + }; + + const succOptions: ChartOptions<'line'> = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: 'top', + }, + }, + scales: { + y: { + min: 0, + }, + }, + }; + + const failData = { + labels: linkStatsList?.linkFailStats?.map((e) => e.link_nm), + datasets: [ + { + label: '연계 실패', + data: linkStatsList?.linkFailStats?.map((e) => e.count), + fill: false, + borderColor: 'rgb(255, 99, 132)', + backgroundColor: 'rgb(255, 99, 132)', + tension: 0.1, + pointRadius: 6, + pointHoverRadius: 8, + }, + ], + }; + + const failOptions: ChartOptions<'line'> = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: 'top', + }, + }, + scales: { + y: { + min: 0, + }, + }, + }; + + const handleResetSearchParam = async () => { + setLinkSearchParam({ + linkSn: '', + linkNm: '', + startDate: dayjs().subtract(7, "day").format('YYYY-MM-DD'), + endDate: dayjs().format('YYYY-MM-DD'), + }); + + setLogQueryParam({ + isSucc: 'SUCC', + linkNm: '', + linkSn: '', + }); + + setStartDate(dayjs().subtract(7, "day").format('YYYY-MM-DD')); + setEndDate(dayjs().format('YYYY-MM-DD')); + + const data = await LinkApi.getLinkStatsList({ + ...linkSearchParam, + linkSn: '', + linkNm: '', + startDate: dayjs().subtract(7, "day").format('YYYY-MM-DD'), + endDate: dayjs().format('YYYY-MM-DD'), + }); + setLinkStatsList(data); + }; + + const handleSubmit = async (e?: React.FormEvent<HTMLFormElement>) => { + e?.preventDefault(); + + if (startDate && endDate) { + + if (startDate > endDate) { + alert('종료일이 시작일보다 이전일 수 없습니다.'); + return; + } else { + const data = await LinkApi.getLinkStatsList({ + ...linkSearchParam, + startDate, + endDate + }); + setLinkStatsList(data); + setLogQueryParam({ + isSucc: 'SUCC', + linkNm: '', + linkSn: '', + }); + setLinkSearchParam({ + ...linkSearchParam, + startDate, + endDate + }); + } + } else { + alert('조회 날짜를 선택해주세요.'); + return; + } + }; + + const handleSuccChartClick = async (event: React.MouseEvent<HTMLCanvasElement>) => { + if (!succChartRef.current) return; + + const chart = succChartRef.current; + + const points = chart.getElementsAtEventForMode( + event.nativeEvent, + "nearest", + { intersect: true }, + false + ); + + if (points[0] && linkStatsList?.linkSuccStats) { + const index = points[0].index; + setPagination({ + ...pagination, + pageIndex: 0, + pageSize: 100, + }); + setLogQueryParam({ + isSucc: 'SUCC', + linkNm: linkStatsList.linkSuccStats[index]?.link_nm, + linkSn: linkStatsList.linkSuccStats[index]?.link_sn, + }); + } + }; + + const handleFailChartClick = async (event: React.MouseEvent<HTMLCanvasElement>) => { + if (!failChartRef.current) return; + + const chart = failChartRef.current; + + const points = chart.getElementsAtEventForMode( + event.nativeEvent, + "nearest", + { intersect: true }, + false + ); + + if (points[0] && linkStatsList?.linkFailStats) { + const index = points[0].index; + setPagination({ + ...pagination, + pageIndex: 0, + pageSize: 100, + }); + setLogQueryParam({ + isSucc: 'FAIL', + linkNm: linkStatsList.linkFailStats[index]?.link_nm, + linkSn: linkStatsList.linkFailStats[index]?.link_sn, + }); + } + }; + + const handleSubmitToday = async () => { + const data = await LinkApi.getLinkStatsList({ + ...linkSearchParam, + startDate: dayjs().format('YYYY-MM-DD'), + endDate: dayjs().format('YYYY-MM-DD'), + }); + setEndDate(dayjs().format('YYYY-MM-DD')); + setStartDate(dayjs().format('YYYY-MM-DD')), + setLinkStatsList(data); + setLinkSearchParam({ + ...linkSearchParam, + startDate: dayjs().format('YYYY-MM-DD'), + endDate: dayjs().format('YYYY-MM-DD'), + }); + setLogQueryParam({ + isSucc: 'SUCC', + linkNm: '', + linkSn: '', + }); + }; + + useEffect(() => { + const fetchData = async () => { + const data = await LinkApi.getLinkStatsList({ + ...linkSearchParam, + startDate, + endDate + }); + setLinkStatsList(data); + }; + + setLinkSearchParam({ + ...linkSearchParam, + startDate, + endDate + }); + + fetchData(); + }, []); + + return ( + <div className="card !mb-0 !min-h-[calc(100vh-16.8rem)]"> + <div className="card card-border"> + <form className="flex items-center gap-2 p-2" onSubmit={handleSubmit}> + <Label htmlFor="sDateSearchInput" className="mx-2 text-label"> + 시작일 + </Label> + <DatePicker id="sDateSearchInput" mode={"single"} selected={dayjs(startDate).toDate()} onSelect={(e) => setStartDate(dayjs(e).format('YYYY-MM-DD'))} /> + <Label htmlFor="eDateSearchInput" className="mx-2 text-label"> + 종료일 + </Label> + <DatePicker id="eDateSearchInput" mode={"single"} className="mr-2" selected={dayjs(endDate).toDate()} onSelect={(e) => setEndDate(dayjs(e).format('YYYY-MM-DD'))} /> + <Button color="green" className="h-[3.2rem]" type="button" onClick={handleResetSearchParam}> + 초기화 + </Button> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + <Button className="h-[3.2rem]" type="button" onClick={handleSubmitToday}> + 오늘 날짜로 조회 + </Button> + </form> + </div> + <div className="card card-border"> + <div className="card !m-[1.2rem] !p-0 flex flex-col gap-y-8"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">조회 일자 : {`${linkSearchParam.startDate} ~ ${linkSearchParam.endDate}`}</h3> + </div> + <div className="h-[32rem] w-full"> + <Line ref={succChartRef} data={succData} options={succOptions} onClick={handleSuccChartClick} /> + </div> + <div className="h-[32rem]"> + <Line ref={failChartRef} data={failData} options={failOptions} onClick={handleFailChartClick} /> + </div> + </div> + <div className="card !m-[1.2rem] !p-0"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label"> + {logQueryParam?.linkNm ? `${logQueryParam.linkNm} 연계 ${logQueryParam.isSucc === 'FAIL' ? '실패' : '성공'} 로그 목록 (${linkSearchParam.startDate} ~ ${linkSearchParam.endDate}) - ${query.data?.totalElements.toLocaleString('ko-KR') ?? 0}건` : '로그 목록'} + </h3> + </div> + <div className="card !m-[1.2rem] h-[40rem] overflow-auto !p-0"> + {logQueryParam?.linkNm ? + query.isLoading ? + <div className="[data-theme='black']:bg-transparent rounded-lg p-10 h-full flex justify-center items-center"> + <div className="relative size-[5rem]"> + <LoadingWithAnimation color="primary" /> + </div> + </div> + : + <div>{tableComponent}</div> + : + <div className="flex items-center justify-center h-full text-gray-500 text-3xl"> + 차트 데이터를 선택해주세요. + </div> + } + </div> + </div> + </div> + </div> + ) +}; + +export { LinkStatsPage }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkTable/index.ts b/apps/cs/src/pages/linkTable/index.ts new file mode 100644 index 000000000..4677f1b52 --- /dev/null +++ b/apps/cs/src/pages/linkTable/index.ts @@ -0,0 +1 @@ +export { LinkTablePage} from "./ui/link-table-page"; \ No newline at end of file diff --git a/apps/cs/src/pages/linkTable/model/table-columns.tsx b/apps/cs/src/pages/linkTable/model/table-columns.tsx new file mode 100644 index 000000000..8c15ecd4b --- /dev/null +++ b/apps/cs/src/pages/linkTable/model/table-columns.tsx @@ -0,0 +1,103 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { type LinkTableColumns } from "@/entities/link"; +import { Checkbox } from "@common/components"; + +const columnHelper = createColumnHelper<LinkTableColumns>(); + +function tableColumns({ selectedColIds, setSelectedColIds }: { + selectedColIds: string[]; + setSelectedColIds: React.Dispatch<React.SetStateAction<string[]>>; +}) { + return [ + columnHelper.display({ + id: "select", + header: ({ table }) => { + const allRows = table.getRowModel().rows; + const allSelected = + allRows.length > 0 && + allRows.every((row) => + selectedColIds.includes(row.original.col_sn) + ); + + return ( + <div className="flex justify-center items-center"> + <Checkbox + className="bg-white" + checked={ + allSelected + ? true + : false + } + onCheckedChange={(checked) => { + if (checked) { + setSelectedColIds(allRows.map((row) => row.original.col_sn)); + } else { + setSelectedColIds([]); + } + }} + /> + </div> + ); + }, + cell: ({ row }) => { + const id = row.original.col_sn; + const checked = selectedColIds.includes(id); + + return ( + <div className="flex justify-center items-center"> + <Checkbox + checked={checked} + onClick={(e) => e.stopPropagation()} + onCheckedChange={(checked) => { + setSelectedColIds((prev) => + checked ? [...prev, id] : prev.filter((x) => x !== id) + ); + }} + /> + </div> + ); + }, + }), + columnHelper.accessor('col_sn', { + id: 'col_sn', + header: '컬럼 일련번호' + }), + columnHelper.accessor('sou_col_nm', { + id: 'sou_col_nm', + header: '원천컬럼명', + cell: (info) => info.getValue() ? info.getValue() : '-', + }), + columnHelper.accessor('sou_col_korn_nm', { + id: 'sou_col_korn_nm', + header: '원천컬럼 한글명', + cell: (info) => info.getValue() ? info.getValue() : '-', + }), + columnHelper.accessor('sou_col_sz', { + id: 'sou_col_sz', + header: '원천컬럼 크기', + cell: (info) => info.getValue() ? info.getValue() : '-', + }), + columnHelper.accessor('trsf_col_nm', { + id: 'trsf_col_nm', + header: '변환컬럼명', + cell: (info) => info.getValue() ? info.getValue() : '-', + }), + columnHelper.accessor('trsf_col_korn_nm', { + id: 'trsf_col_korn_nm', + header: '변환컬럼 한글명', + cell: (info) => info.getValue() ? info.getValue() : '-', + }), + columnHelper.accessor('trsf_col_sz', { + id: 'trsf_col_sz', + header: '변환컬럼 크기', + cell: (info) => info.getValue() ? info.getValue() : '-', + }), + columnHelper.accessor('pk_yn', { + id: 'pk_yn', + header: 'PK 여부', + cell: (info) => info.getValue() === 'Y' ? '예' : '아니오', + }), + ] +} + +export { tableColumns }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx b/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx new file mode 100644 index 000000000..9c27a38d9 --- /dev/null +++ b/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx @@ -0,0 +1,501 @@ +'use client'; + +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogClose, + Button, + Input, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, + Checkbox +} from "@common/components"; +import { FormItem, FormControl, FormField, Form } from "@/shared/ui/form"; +import { type LinkTableColData, type LinkTable } from "@/entities/link"; +import dayjs from "dayjs"; +import type { UseFormReturn } from "react-hook-form"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { useState, useEffect } from "react"; +import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; + +interface LinkTableDialogProps { + dialogOpen: boolean; + onOpenChange: (val: boolean) => void; + form: UseFormReturn<LinkTableColData>; + tableInfo: LinkTable; + insertLinkTableCol: (data: LinkTableColData) => void; + updateLinkTableCol: (data: LinkTableColData) => void; +} + +function LinkTableDialog({ dialogOpen, onOpenChange, form, tableInfo, insertLinkTableCol, updateLinkTableCol }: LinkTableDialogProps) { + + const isModifyMode = !!form.getValues('col_sn'); + + const { confirm } = useConfirm(); + const [onConfirm, setOnConfirm] = useState<boolean>(false); + const [useColSeq, setUseColSeq] = useState<boolean>(false); + + const handleConfirm = async (callback: () => Promise<void>) => { + setOnConfirm(true); + await callback(); + setOnConfirm(false); + }; + + const handleSubmit = async (data: LinkTableColData) => { + const confirmMsg = isModifyMode ? '수정 하시겠습니까?' : '저장 하시겠습니까?'; + + await handleConfirm(async () => { + if (await confirm(confirmMsg)) { + !isModifyMode + ? insertLinkTableCol({ + ...data, + link_sn: tableInfo.link_sn, + tbl_sn: tableInfo.tbl_sn, + }) + : updateLinkTableCol({ + ...data, + link_sn: tableInfo.link_sn, + tbl_sn: tableInfo.tbl_sn, + }); + } + }); + }; + + const handleCheckColSeqValue = (check: boolean | string) => { + if (check) { + setUseColSeq(false); + form.setValue('col_seq', null); + } else { + setUseColSeq(true); + } + }; + + useEffect(() => { + if (!dialogOpen) { + setUseColSeq(false); + form.reset({ + tbl_sn: '', + col_sn: '', + sou_col_nm: '', + sou_col_korn_nm: '', + sou_col_data_frm: '', + sou_col_sz: null, + trsf_col_nm: '', + trsf_col_korn_nm: '', + trsf_col_data_frm: '', + trsf_col_sz: null, + col_seq: null, + pk_yn: 'N', + mdfcn_dt: '', + mdfr: '', + }); + } + + if (isModifyMode && form.getValues('col_seq')) { + setUseColSeq(true); + } + + }, [dialogOpen]); + + return ( + <Dialog + open={dialogOpen} + onOpenChange={(open) => { + onOpenChange(open); + }} + > + <DialogTrigger asChild> + <Button color="green" className="h-[3.2rem]" onClick={() => onOpenChange(true)}>행 추가</Button> + </DialogTrigger> + <DialogContent className="sm:max-w-[55rem]"> + <DialogHeader> + <DialogTitle> + {tableInfo.trsf_tbl_korn_nm} ({tableInfo.tbl_sn}) + </DialogTitle> + </DialogHeader> + <Form {...form}> + <form onSubmit={form.handleSubmit(handleSubmit)}> + <div className="card"> + <Table variant="secondary"> + <colgroup> + <col width="30%" /> + <col width="70%" /> + </colgroup> + <TableBody> + {isModifyMode && + <TableRow> + <TableHead>컬럼 일련번호</TableHead> + <TableCell> + <FormField + control={form.control} + name="col_sn" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + } + <TableRow> + <TableHead>* 원천컬럼명</TableHead> + <TableCell> + <FormField + control={form.control} + name="sou_col_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.sou_col_nm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.sou_col_nm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 원천컬럼 한글명</TableHead> + <TableCell> + <FormField + control={form.control} + name="sou_col_korn_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.sou_col_korn_nm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.sou_col_korn_nm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 원천컬럼 데이터 형식</TableHead> + <TableCell> + <FormField + control={form.control} + name="sou_col_data_frm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.sou_col_data_frm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.sou_col_data_frm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>원천컬럼 크기</TableHead> + <TableCell> + <FormField + control={form.control} + name="sou_col_sz" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + type="number" + min={0} + max={99999999999999} + onChange={(e) => { + const onlyDigits = e.target.value.replace(/\D/g, "").slice(0, 14); + field.onChange(onlyDigits); // react-hook-form에 반영 + }} + /> + </FormControl> + <p className="text-gray-500 text-base pt-2"> + ※ 14자리까지 입력 가능합니다. + </p> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>PK 여부</TableHead> + <TableCell> + <FormField + control={form.control} + name="pk_yn" + render={({ field }) => ( + <FormItem> + <FormControl> + <Select value={field.value ?? "N"} onValueChange={field.onChange}> + <SelectTrigger id="liResultCode" className="w-[10rem] mr-4"> + <SelectValue placeholder="아니오"></SelectValue> + </SelectTrigger> + <SelectContent> + <SelectItem value="Y">예</SelectItem> + <SelectItem value="N">아니오</SelectItem> + </SelectContent> + </Select> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 변환컬럼명</TableHead> + <TableCell> + <FormField + control={form.control} + name="trsf_col_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.trsf_col_nm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.trsf_col_nm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 변환컬럼 한글명</TableHead> + <TableCell> + <FormField + control={form.control} + name="trsf_col_korn_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.trsf_col_korn_nm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.trsf_col_korn_nm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 변환컬럼 데이터 형식</TableHead> + <TableCell> + <FormField + control={form.control} + name="trsf_col_data_frm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + /> + </FormControl> + {form.formState.errors.trsf_col_data_frm && ( + <p className="text-red-500 text-base pt-2"> + {form.formState.errors.trsf_col_data_frm.message} + </p> + )} + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>변환컬럼 크기</TableHead> + <TableCell> + <FormField + control={form.control} + name="trsf_col_sz" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + type="number" + min={0} + max={99999999999999} + onChange={(e) => { + const onlyDigits = e.target.value.replace(/\D/g, "").slice(0, 14); + field.onChange(onlyDigits); // react-hook-form에 반영 + }} + /> + </FormControl> + <p className="text-gray-500 text-base pt-2"> + ※ 14자리까지 입력 가능합니다. + </p> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>컬럼 매칭 순서</TableHead> + <TableCell> + <FormField + control={form.control} + name="col_seq" + render={({ field }) => ( + <FormItem> + <div className="flex items-center gap-x-2 mb-4"> + <Checkbox id="useColSeq" className="!border-gray-600" checked={!useColSeq} onCheckedChange={(check) => handleCheckColSeqValue(check)} /> + <label htmlFor="useColSeq" className="text-gray-600">사용안함</label> + </div> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + autoComplete="off" + type="number" + min={0} + disabled={!useColSeq} + max={999} + onChange={(e) => { + const onlyDigits = e.target.value.replace(/\D/g, "").slice(0, 3); + field.onChange(onlyDigits); // react-hook-form에 반영 + }} + /> + </FormControl> + <p className="text-gray-500 text-base pt-2"> + ※ 3자리까지 입력 가능합니다. + </p> + </FormItem> + )} + /> + </TableCell> + </TableRow> + {isModifyMode && + <> + <TableRow> + <TableHead>수정자</TableHead> + <TableCell> + <FormField + control={form.control} + name="mdfr" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + <TableRow> + <TableHead>수정일시</TableHead> + <TableCell> + <FormField + control={form.control} + name="mdfcn_dt" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ? dayjs(field.value).format('YYYY-MM-DD') : ""} + className="!text-[1.3rem]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + </TableCell> + </TableRow> + </> + } + </TableBody> + </Table> + </div> + <DialogFooter> + <Button type="submit">저장</Button> + <DialogClose asChild> + <Button color="white">취소</Button> + </DialogClose> + </DialogFooter> + </form> + </Form> + <ConfirmDialog open={onConfirm} /> + </DialogContent> + </Dialog> + ) +} + +export { LinkTableDialog }; \ No newline at end of file diff --git a/apps/cs/src/pages/linkTable/ui/link-table-page.tsx b/apps/cs/src/pages/linkTable/ui/link-table-page.tsx new file mode 100644 index 000000000..cdb93b931 --- /dev/null +++ b/apps/cs/src/pages/linkTable/ui/link-table-page.tsx @@ -0,0 +1,710 @@ +'use client'; + +import { useState, useMemo } from "react"; +import { + Button, + DataTable, + Input, + Label, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + LoadingWithAnimation, +} from "@common/components"; +import { getCoreRowModel, type PaginationState, type RowSelectionState, useReactTable } from "@tanstack/react-table"; +import { LinkApi, type Link, type LinkSearchParam, type LinkTable, type LinkTableColumns, type LinkTableColData, type LinkTableFormData, LinkTableColumnsSchema, LinkTableSchema } from "@/entities/link"; +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { columns } from "../../linkParams/model/table-columns"; +import { tableColumns } from "../model/table-columns"; +import { LinkTableDialog } from "./link-table-dialog"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { getUserInfo } from "../../../../../../packages/common/components/src/api"; +import { AUTH_USER_ID } from "@/shared/config"; +import { getCookie } from "@common/components"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; +import { FormItem, FormControl, FormField, Form } from "@/shared/ui/form"; +import { useDataTable } from "@/shared/lib"; + +function LinkTablePage() { + const queryClient = useQueryClient(); + + const userUniqId = getCookie(AUTH_USER_ID) ?? ""; + + const [linkSn, setLinkSn] = useState<string>(''); + const [linkNm, setLinkNm] = useState<string>(''); + + const [linkSearchParam, setLinkSearchParam] = useState<LinkSearchParam>({ + linkSn: '', + linkNm: '' + }); + + const [selectedTableInfo, setSelectedTableInfo] = useState<LinkTable | null>(null); + const [tableColList, setTableColList] = useState<LinkTableColumns[]>([]); + const [dialogOpen, setDialogOpen] = useState<boolean>(false); + const [selectedColIds, setSelectedColIds] = useState<string[]>([]); + + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); + + const [pagination, setPagination] = useState<PaginationState>({ + pageIndex: 0, + pageSize: 100, + }); + + const { setMessage: alert } = useAlertStore((state) => state); + + const { confirm } = useConfirm(); + const [onConfirm, setOnConfirm] = useState<boolean>(false); + + const handleConfirm = async (callback: () => Promise<void>) => { + setOnConfirm(true); + await callback(); + setOnConfirm(false); + }; + + const query = useQuery({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, linkSearchParam], + queryFn: () => LinkApi.getLinkList({ + ...linkSearchParam, + page: pagination.pageIndex, + size: pagination.pageSize, + }), + }); + + const { mutateAsync: insertLinkTableCol } = useMutation({ + mutationFn: async (data: LinkTableColData) => await LinkApi.insertLinkTableCol({ + ...data, + mdfr: userUniqId, + }), + onSuccess: async () => { + if (selectedTableInfo) { + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo`] + }); + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList`] + }); + + const tableData = await LinkApi.getLinkTableInfo(selectedTableInfo.link_sn); + const tableColList = await LinkApi.getLinkTableColList(selectedTableInfo.link_sn); + + setSelectedTableInfo(tableData); + setTableColList(tableColList.content); + setSelectedColIds([]); + setDialogOpen(false); + alert('저장되었습니다.'); + } + } + }); + + const { mutateAsync: updateLinkTableCol } = useMutation({ + mutationFn: async (data: LinkTableColData) => await LinkApi.updateLinkTableCol({ + ...data, + mdfr: userUniqId, + }), + onSuccess: async () => { + if (selectedTableInfo) { + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo`] + }); + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList`] + }); + + const tableData = await LinkApi.getLinkTableInfo(selectedTableInfo.link_sn); + const tableColList = await LinkApi.getLinkTableColList(selectedTableInfo.link_sn); + + setSelectedTableInfo(tableData); + setTableColList(tableColList.content); + setSelectedColIds([]); + setDialogOpen(false); + alert('수정되었습니다.'); + } + } + }); + + const { mutateAsync: deleteLinkTableCol } = useMutation({ + mutationFn: async (data: string[]) => await LinkApi.deleteLinkTableCol(data), + onSuccess: async () => { + if (selectedTableInfo) { + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo`] + }); + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList`] + }); + + const tableData = await LinkApi.getLinkTableInfo(selectedTableInfo.link_sn); + const tableColList = await LinkApi.getLinkTableColList(selectedTableInfo.link_sn); + + setSelectedTableInfo(tableData); + setTableColList(tableColList.content); + setSelectedColIds([]); + setDialogOpen(false); + alert('삭제되었습니다.'); + } + } + }); + + const { mutateAsync: insertLinkTableInfo } = useMutation({ + mutationFn: async (data: LinkTableFormData) => await LinkApi.insertLinkTableInfo(data), + onSuccess: async () => { + if (selectedTableInfo) { + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo`] + }); + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList`] + }); + + const tableData = await LinkApi.getLinkTableInfo(selectedTableInfo.link_sn); + const tableColList = await LinkApi.getLinkTableColList(selectedTableInfo.link_sn); + + tableForm.reset({ + link_sn: tableData.link_sn, + link_nm: tableData.link_nm, + tbl_sn: tableData.tbl_sn ?? "", + sou_tbl_nm: tableData.sou_tbl_nm ?? "", + sou_tbl_korn_nm: tableData.sou_tbl_korn_nm ?? "", + sou_tbl_expln: tableData.sou_tbl_expln ?? "", + trsf_tbl_expln: tableData.trsf_tbl_expln ?? "", + trsf_tbl_nm: tableData.trsf_tbl_nm ?? "", + trsf_tbl_korn_nm: tableData.trsf_tbl_korn_nm ?? "", + }); + setSelectedTableInfo(tableData); + setTableColList(tableColList.content); + setSelectedColIds([]); + alert('저장되었습니다.'); + } + } + }); + + const { mutateAsync: updateLinkTableInfo } = useMutation({ + mutationFn: async (data: LinkTableFormData) => await LinkApi.updateLinkTableInfo(data), + onSuccess: async () => { + if (selectedTableInfo) { + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo`] + }); + await queryClient.invalidateQueries({ + queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList`] + }); + + const tableData = await LinkApi.getLinkTableInfo(selectedTableInfo.link_sn); + const tableColList = await LinkApi.getLinkTableColList(selectedTableInfo.link_sn); + + setSelectedTableInfo(tableData); + setTableColList(tableColList.content); + setSelectedColIds([]); + alert('수정되었습니다.'); + } + } + }); + + const tableCol = useMemo( + () => + tableColumns({ selectedColIds, setSelectedColIds }), + [selectedColIds] + ); + + const colTable = useReactTable({ + data: tableColList, + columns: tableCol, + getCoreRowModel: getCoreRowModel(), + }); + + const form = useForm<LinkTableColData>({ + resolver: zodResolver(LinkTableColumnsSchema), + defaultValues: { + pk_yn: "N" + } + }); + + const tableForm = useForm<LinkTableFormData>({ + resolver: zodResolver(LinkTableSchema), + defaultValues: {}, + }); + + const handleResetSearchParam = async () => { + setSelectedTableInfo(null); + setTableColList([]); + setLinkSn(''); + setLinkNm(''); + setLinkSearchParam({ + ...linkSearchParam, + linkSn: '', + linkNm: '', + }); + }; + + const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + setSelectedTableInfo(null); + setTableColList([]); + + setLinkSearchParam({ + ...linkSearchParam, + linkSn, + linkNm + }); + }; + + const handleRowClick = async (data: Link) => { + const tableData = await LinkApi.getLinkTableInfo(data.link_sn); + const tableColList = await LinkApi.getLinkTableColList(data.link_sn); + + setSelectedTableInfo(tableData); + setTableColList(tableColList.content); + setSelectedColIds([]); + + tableForm.reset({ + link_sn: tableData.link_sn, + link_nm: tableData.link_nm, + tbl_sn: tableData.tbl_sn ?? "", + sou_tbl_nm: tableData.sou_tbl_nm ?? "", + sou_tbl_korn_nm: tableData.sou_tbl_korn_nm ?? "", + sou_tbl_expln: tableData.sou_tbl_expln ?? "", + trsf_tbl_expln: tableData.trsf_tbl_expln ?? "", + trsf_tbl_nm: tableData.trsf_tbl_nm ?? "", + trsf_tbl_korn_nm: tableData.trsf_tbl_korn_nm ?? "", + }); + }; + + const handleColumnRowClick = async (data: LinkTableColumns) => { + const colInfo = await LinkApi.getLinkTableColInfo({ colSn: data.col_sn, tblSn: data.tbl_sn }); + + if (colInfo) { + let newData = { ...colInfo }; + + if (colInfo.mdfr) { + const userName = await fetchUserInfo(colInfo.mdfr); + newData = { + ...colInfo, + mdfr: userName, + }; + } + + form.reset(newData); + + } + setDialogOpen(true) + }; + + const fetchUserInfo = async (id: string) => { + const userData = await getUserInfo(); + return userData.userName; + }; + + const handleDeleteParam = async () => { + if (selectedColIds.length === 0) { + alert('삭제할 컬럼을 선택해 주세요.'); + } else { + await handleConfirm(async () => { + if (await confirm('선택한 컬럼 정보를 삭제하시겠습니까?')) { + deleteLinkTableCol(selectedColIds); + } + }); + } + }; + + const handleTableSubmit = async (data: LinkTableFormData) => { + const regTblInfo = await LinkApi.countLinkTblNm(data.trsf_tbl_nm); + const confirmMsg = (regTblInfo.count > 0 && data.trsf_tbl_nm !== selectedTableInfo?.trsf_tbl_nm) ? `이미 사용중인 테이블 명입니다. 해당 테이블 명으로 ${!data.tbl_sn ? '저장' : '수정'}하시겠습니까?` : `${!data.tbl_sn ? '저장' : '수정'}하시겠습니까?`; + if (!data.tbl_sn) { + await handleConfirm(async () => { + if (await confirm(confirmMsg)) { + insertLinkTableInfo({ + ...data, + mdfr: userUniqId, + tbl_sn: (regTblInfo.count > 0) ? regTblInfo.tbl_sn : "", + }); + } + }); + } else { + await handleConfirm(async () => { + if (await confirm(confirmMsg)) { + updateLinkTableInfo({ + ...data, + tbl_sn: (regTblInfo.count > 0) ? regTblInfo.tbl_sn : "", + mdfr: userUniqId, + }); + } + }); + } + + }; + + const { tableComponent } = useDataTable({ + query, + tableOptions: { + columns, + state: { + pagination, + rowSelection, + }, + manualPagination: true, + enableMultiRowSelection: true, + getCoreRowModel: getCoreRowModel(), + onPaginationChange: setPagination, + onRowSelectionChange: setRowSelection, + }, + dataTableOptions: { + onRowClick: handleRowClick, + viewPagination: true, + }, + }); + + return ( + <div className="card card-border !mt-6"> + <div className="card card-border"> + <form className="flex items-center gap-2 p-2" onSubmit={handleSubmit}> + <Label htmlFor="liSnSearchInput" className="mr-2 text-label"> + 일련번호 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-4" + id="liSnSearchInput" + value={linkSn} + onChange={(e) => setLinkSn(e.target.value)} + autoComplete="off" + /> + <Label htmlFor="liNmSearchInput" className="mr-2 text-label"> + 연계 명 + </Label> + <Input + className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem] mr-2" + id="liNmSearchInput" + value={linkNm} + onChange={(e) => setLinkNm(e.target.value)} + autoComplete="off" + /> + <Button color="green" className="h-[3.2rem]" type="button" onClick={handleResetSearchParam}> + 초기화 + </Button> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + </form> + </div> + <div className="card !mb-0 flex h-[calc(100vh-28rem)] gap-5 !p-0"> + <div className="card card-border w-1/2 !mx-0 flex flex-col"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계 목록</h3> + </div> + <div className="card !m-[1.2rem] overflow-auto !p-0 h-full"> + {!query.isLoading ? + <div>{tableComponent}</div> + : + <div className="[data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center h-full"> + <div className="relative size-[5rem]"> + <LoadingWithAnimation color="primary" /> + </div> + </div> + } + </div> + </div> + <div className="card card-border w-1/2 !mx-0 flex flex-col"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label">연계 테이블 정보</h3> + </div> + <div className="card !m-[1.2rem] !p-0 h-full overflow-auto flex flex-col"> + <Form {...tableForm}> + <form onSubmit={tableForm.handleSubmit(handleTableSubmit)}> + {selectedTableInfo && + <div className="flex justify-end mb-2"> + <Button className="h-[3.2rem]" type="submit" color={selectedTableInfo.tbl_sn ? "green" : "primary"}> + {selectedTableInfo.tbl_sn ? "수정" : "저장"} + </Button> + </div> + } + <Table variant="secondary" className="flex-none"> + <colgroup> + <col width="20%" /> + <col width="80%" /> + </colgroup> + <TableBody> + <TableRow> + <TableHead>연계 일련번호</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="link_sn" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>연계 명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="link_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + disabled + /> + </FormControl> + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>원천 테이블 명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="sou_tbl_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + placeholder={!field.value ? "-" : ""} + autoComplete="off" + /> + </FormControl> + {tableForm.formState.errors.sou_tbl_nm && ( + <p className="text-red-500 text-base pt-2"> + {tableForm.formState.errors.sou_tbl_nm.message} + </p> + )} + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>원천 테이블 한글명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="sou_tbl_korn_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + placeholder={!field.value ? "-" : ""} + autoComplete="off" + /> + </FormControl> + {tableForm.formState.errors.sou_tbl_korn_nm && ( + <p className="text-red-500 text-base pt-2"> + {tableForm.formState.errors.sou_tbl_korn_nm.message} + </p> + )} + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>원천 테이블 설명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="sou_tbl_expln" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + placeholder={!field.value ? "-" : ""} + autoComplete="off" + /> + </FormControl> + {tableForm.formState.errors.sou_tbl_expln && ( + <p className="text-red-500 text-base pt-2"> + {tableForm.formState.errors.sou_tbl_expln.message} + </p> + )} + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 변환 테이블 명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="trsf_tbl_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + placeholder={!field.value ? "-" : ""} + autoComplete="off" + /> + </FormControl> + {tableForm.formState.errors.trsf_tbl_nm && ( + <p className="text-red-500 text-base pt-2"> + {tableForm.formState.errors.trsf_tbl_nm.message} + </p> + )} + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>* 변환 테이블 한글명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="trsf_tbl_korn_nm" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + placeholder={!field.value ? "-" : ""} + autoComplete="off" + /> + </FormControl> + {tableForm.formState.errors.trsf_tbl_korn_nm && ( + <p className="text-red-500 text-base pt-2"> + {tableForm.formState.errors.trsf_tbl_korn_nm.message} + </p> + )} + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + <TableRow> + <TableHead>변환 테이블 설명</TableHead> + <TableCell className="!p-2"> + {selectedTableInfo ? + <FormField + control={tableForm.control} + name="trsf_tbl_expln" + render={({ field }) => ( + <FormItem> + <FormControl> + <Input + {...field} + value={field.value ?? ""} + className="!text-[1.3rem] w-[400px]" + placeholder={!field.value ? "-" : ""} + autoComplete="off" + /> + </FormControl> + {tableForm.formState.errors.trsf_tbl_expln && ( + <p className="text-red-500 text-base pt-2"> + {tableForm.formState.errors.trsf_tbl_expln.message} + </p> + )} + </FormItem> + )} + /> + : + <span className="px-2 py-[1.2rem]">-</span> + } + </TableCell> + </TableRow> + </TableBody> + </Table> + </form> + </Form> + {selectedTableInfo ? + <> + <div className="mb-2 mt-14 flex justify-end items-center flex-none"> + {tableColList.length > 0 && + <Button color="red" className="h-[3.2rem] mr-2" type="button" onClick={handleDeleteParam}> + 행 삭제 + </Button> + } + {selectedTableInfo.tbl_sn && + <LinkTableDialog dialogOpen={dialogOpen} onOpenChange={setDialogOpen} form={form} tableInfo={selectedTableInfo} insertLinkTableCol={insertLinkTableCol} updateLinkTableCol={updateLinkTableCol} /> + } + </div> + {selectedTableInfo.tbl_sn ? + (tableColList.length > 0 ? + <div className="flex-1 overflow-auto min-h-[300px]"> + <DataTable table={colTable} onRowClick={handleColumnRowClick} /> + </div> + : + <div className="flex items-center justify-center h-20 text-gray-500 text-3xl"> + 등록된 테이블 컬럼이 없습니다. + </div>) + : + <div className="flex items-center justify-center h-20 text-gray-500 text-3xl"> + 테이블 정보를 등록해주세요. + </div> + } + </> + : + <div className="flex items-center justify-center text-gray-500 text-3xl mt-14 flex-1"> + 연계 데이터를 선택해주세요. + </div> + } + </div> + </div> + </div> + <ConfirmDialog isOpen={onConfirm} /> + </div > + ) +}; + +export { LinkTablePage }; \ No newline at end of file From 60ae8c9e728cfbabe46cd9545c083b33c0264cfe Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Fri, 25 Jul 2025 18:08:28 +0900 Subject: [PATCH 20/27] =?UTF-8?q?=EC=88=98=EC=9A=94=EC=B2=98=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 226 +++++++++++++++++++++-------- 1 file changed, 167 insertions(+), 59 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 4a3ad41bb..40247c0df 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -7,12 +7,14 @@ import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; import { fetchType, getFetch, postFectch } from "@/components/lib/api"; -import { tableData } from "@/components/lib/func/commom"; +import { formatPhoneNumber, tableData } from "@/components/lib/func/commom"; import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; import { Title, UITab, UiTable } from '@common/business_components'; import { useGisContext } from "@common/business_components/ui/map/Gis"; +import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form'; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; +import moment from 'moment'; import React, { useCallback, useEffect, useState } from 'react'; interface NewWindowPopupProps { @@ -74,7 +76,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); - const { htdflSttnRes,htdflSttnResCount } = htdflSttn; + const { htdflSttnRes, htdflSttnResCount } = htdflSttn; const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [htdflPage, setHtdflPage] = useState(1) @@ -92,11 +94,31 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }>({ data: undefined }); const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); const [hasuPage, setHasuPage] = useState<number>(1); + + // 수요처관리 변수 + const { + coSttn, + coSttnInit, + coSttnSearch, + // getDemandCompList, + // regDemandCompany, + // updateDemandCompany, + // coSttnTxtSearch, + // demandCompList, + } = useWrStore((state) => state); + const [mngTable, setMngTable] = useState<DemandCompType[]>(); + const [mngPage, setMngPage] = useState(1); + const { coSttnRes, coSttnResCount, coSttHeadList } = coSttn; + const [isDmdModal, setIsDmdModal] = useState<{ + isMoal: boolean; + data: any | undefined; + }>({ isMoal: false, data: undefined}); + const [mngList, setMngList] = useState<DemandCompType[]>(coSttnRes || []); ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// const getSelectedLayers = () => { let result = null; const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 - let featureLayer: { get: (key: string) => any } = {get:()=> null}; + let featureLayer: { get: (key: string) => any } = { get: () => null }; layers.forEach((layer: any) => { const source = layer.getSource(); if (source && source.hasFeature && featureData @@ -122,13 +144,13 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON) setHasuList( rainRes.data.map((item: any) => { - return { - ...item, - fctCpc: Number(item.fctCpc) || 0, - ruse: item.ruse === false ? "N" : "Y", - }; - }) - ) + return { + ...item, + fctCpc: Number(item.fctCpc) || 0, + ruse: item.ruse === false ? "N" : "Y", + }; + }) + ) } catch (error) { console.error("Error fetching data:", error); } @@ -138,56 +160,63 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`) setRainList(res) } - else if(layerNm == '중수도시설'){ - const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`) + else if (layerNm == '중수도시설') { + const res = await getFetch(fetchType.WR, `/reuseFc/waterreuseFc/1/20/0/${featureCd}`) setRswtrList(res) } - else{ + else if(layerNm =='수요처'){ + const res = await getFetch(fetchType.WR, `/reuseFc/request/1/20/0/${featureCd}`) + setMngList(res) + } + else { const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`) setHtdflList(res) setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); } } // 상세 목록 데이터 상태 처리 - useEffect(()=>{ + useEffect(() => { if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] }); - },[hasuList]) - useEffect(()=>{ + }, [hasuList]) + useEffect(() => { if (rainList.length > 0) setRainDetailModal({ isOpen: true, data: rainList[0] }); - },[rainList]) - useEffect(()=>{ + }, [rainList]) + useEffect(() => { if (rswtrList.length > 0) setRswtrDetailModal({ isOpen: true, data: rswtrList[0] }); - },[rswtrList]) - useEffect(()=>{ + }, [rswtrList]) + useEffect(() => { if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] }); - },[htdflList]) + }, [htdflList]) + useEffect(() => { + if(mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] }); + },[mngList]) const layerId = getSelectedLayers(); - if (featureData && typeof featureData.getProperties === "function") { - const selectedVal = featureData.getProperties(); - let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null; - if (featureCd && featureCd !== fcltPk) { - if (layerId == '하수재이용시설') { - featureCd = selectedVal?.swtrmt_fclt_cd; - setFcltPk(featureCd); // 현재 호출된 featureCd 저장 - setActiveTab(featureCd) - fetchpbnstDetail(featureCd); // 상세정보 - } - else if (layerId == '하수처리시설') { - featureCd = selectedVal?.swtrmt_fclt_nm; - setFcltPk(featureCd); // 현재 호출된 featureCd 저장 - fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd); - } - else { - featureCd = selectedVal?.bdst_nm; - setFcltPk(featureCd) - if (layerId) { - detainSttn(featureCd, layerId); - } - } - setViewMode("detail") + if (featureData && typeof featureData.getProperties === "function") { + const selectedVal = featureData.getProperties(); + let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' || layerId == '수요처' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null; + if (featureCd && featureCd !== fcltPk) { + if (layerId == '하수재이용시설') { + featureCd = selectedVal?.swtrmt_fclt_cd; + setFcltPk(featureCd); // 현재 호출된 featureCd 저장 + setActiveTab(featureCd) + fetchpbnstDetail(featureCd); // 상세정보 } - } else if (layerId === null && seletectedLayerNm) { setViewMode("list") } + else if (layerId == '하수처리시설') { + featureCd = selectedVal?.swtrmt_fclt_nm; + setFcltPk(featureCd); // 현재 호출된 featureCd 저장 + fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd); + } + else { + featureCd = selectedVal?.bdst_nm; + setFcltPk(featureCd) + if (layerId) { + detainSttn(featureCd, layerId); + } + } + setViewMode("detail") + } + } else if (layerId === null && seletectedLayerNm) { setViewMode("list") } ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// @@ -210,7 +239,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ getFlcts() } }, [seletectedLayerNm, pbnstSttn.isInit, getFlcts]); - useEffect(()=>{ + useEffect(() => { pbnSttnInit("1", "15", { partValue: "A", sidoValue: '0', @@ -258,7 +287,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ String(new Date().getFullYear()), fclts ); }, [fclts, pbnstSttnSearch]); -// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제. + // FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제. // const excelClick = useCallback(() => { // // if (codeData) pbnstSttnSearch(1, "10000", codeData); // excelDownload( @@ -283,7 +312,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ onClose(); } } - + useEffect(() => { if (!rainSttn.isInit) { @@ -427,7 +456,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ useEffect(() => { pubHasuInit(String(hasuPage), "0"); }, [hasuPage, pubHasuInit]); - + const hasuCellClick = (index: number | undefined) => { if (index !== undefined && pbnstHasuRes !== undefined) { onFeatureSelect(pbnstHasuRes[index]); @@ -436,10 +465,42 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; ///////////////////////////////////////////// 하수처리 시설 ////////////////////////////////////////////////// + ///////////////////////////////////////////// 수요처 관리 ////////////////////////////////////////////////// + useEffect(() => { + if (!coSttn.isInit) { + coSttnInit("1", "13", "0"); + } + }, [coSttn.isInit, coSttnInit]); + const coMngCellClick = (index: number | undefined) => { + if (index !== undefined && mngTable !== undefined) { + onFeatureSelect(mngTable[index]); + onClose(); + } + }; + useEffect(() => { + if (coSttnRes) { + if (coSttnRes?.length > 0 && code.cityCd.length > 0) { + const data = tableData(coSttnRes, { code }); + const chData = data.map((item: any) => ({ + ...item, + telno: formatPhoneNumber(item.telno || undefined), + regDt: moment(item.regDt).format("YYYY-MM-DD"), + dmdInfoId: `${item.dmdInfoId.slice(0, 3)}-${item.dmdInfoId.slice(3, 5)}-${item.dmdInfoId.slice(5, 10)}-${item.dmdInfoId.slice(10)}` + })); + // .filter((item: any) => item !== undefined); + setMngTable(chData); + } + } + }, [coSttnRes, code]); + useEffect(() => { + coSttnSearch(String(mngPage), "13", String(0)); + }, [coSttnSearch, mngPage]); + ///////////////////////////////////////////// 수요처 관리 ////////////////////////////////////////////////// + // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { const actTabData = tabData.find((tab) => tab.id === activeTab); - let layerId:string | undefined | null = getSelectedLayers(); + let layerId: string | undefined | null = getSelectedLayers(); if (layerId === null || layerId === undefined) { layerId = seletectedLayerNm || ''; } @@ -453,10 +514,12 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const isRswt = layerId == '중수도시설'; // 온배수시설 const isHtdfl = layerId == '온배수시설'; + // 수요처관리 + const isReuseMng = layerId == '수요처'; if (isPrcsFclt) { if (viewMode == 'list') { return ( - <div style={{overflowY:'auto'}}> + <div style={{ overflowY: 'auto' }}> <div className="flex justify-between items-center mb-4"> <Title title="하수처리시설 현황" /> </div> @@ -474,7 +537,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ ) } else { return ( - <div style={{overflowX:'hidden'}}> + <div style={{ overflowX: 'hidden' }}> <div className="flex justify-between items-center mb-4"> <Title title="하수처리시설 상세정보" /> </div> @@ -528,7 +591,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } else { // 재이용시설 목록 return ( - <div style={{overflowY:'auto'}}> + <div style={{ overflowY: 'auto' }}> <div className="flex justify-between items-center"> <Title title="하수재이용시설 현황" /> {/* <div className="flex gap-2 mt-8"> @@ -600,7 +663,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } else { // 중수도시설 목록 return ( - <div style={{overflowY:'auto'}}> + <div style={{ overflowY: 'auto' }}> <div className="flex justify-between items-center"> <Title title="중수도시설 현황" /> {/* <div className="flex gap-2 mt-8"> @@ -636,7 +699,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } else { // 온배수시설 목록 return ( - <div style={{overflowY:'auto'}}> + <div style={{ overflowY: 'auto' }}> <div className="flex justify-between items-center"> <Title title="온배수시설 현황" /> {/* <div className="flex gap-2 mt-8"> @@ -662,15 +725,60 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ ); } } - + if (isReuseMng) { + if (viewMode == 'detail') { + return ( + <div style={{ overflowX: 'hidden' }}> + <div className="flex justify-between items-center mb-4"> + <Title title="수요처 상세정보" /> + </div> + {/* 높이 조정 */} + <UiTable + tableData={isDmdModal?.data || []} + headlist={coSttHeadList.slice(0, 3)} + pageSize={1} + total={0} + headName={"위치정보"} + cellClick={() => { }} + onPageChange={() => { }} + /> + <UiTable + tableData={isDmdModal?.data || []} + headlist={coSttHeadList.slice(3)} + pageSize={1} + total={0} + headName={"기본정보"} + cellClick={() => { }} + onPageChange={() => { }} + /> + </div> + ) + } else if(viewMode == 'list') { + console.log('수요처 대이터 확인', mngTable, coSttHeadList); + ( <UiTable + headName={[]} + tableData={mngTable || []} + headlist={coSttHeadList} + pageSize={20} + total={coSttnResCount + 10 || 0} + cellClick={(index: number | undefined) => { + coMngCellClick(index); + // setUpdateData(coSttnRes[index as number]); + }} + onPageChange={(page) => { + setMngPage(page); + }} + ></UiTable>) + } + } return null; // 조건에 맞는 콘텐츠가 없을 경우 }; return ( viewMode == 'nothing' ? <></> : - <NewWindowPortal - onClose={memoizedOnClose} - title="시설 상세 정보" + <NewWindowPortal + onClose={memoizedOnClose} + title="시설 상세 정보" width={viewMode == 'list' ? window.screen.availWidth : 1100} height={viewMode == 'list' ? window.screen.availHeight : layerId == '하수처리시설' && viewMode == 'detail' ? 450 : 900} scrollbars='yes' From d389390b0c25db4a9b229a2d76e99ff922d951c6 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Fri, 25 Jul 2025 18:30:14 +0900 Subject: [PATCH 21/27] =?UTF-8?q?=EC=88=98=EC=9A=94=EC=B2=98=20=EC=83=81?= =?UTF-8?q?=EC=84=B8,=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=ED=98=84=ED=99=A9?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 40247c0df..7f7d18f9a 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -754,8 +754,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ </div> ) } else if(viewMode == 'list') { - console.log('수요처 대이터 확인', mngTable, coSttHeadList); - ( <UiTable + return ( <div> + <div className="flex justify-between items-center"> + <Title title="수요처 현황" /> + </div> + <UiTable headName={[]} tableData={mngTable || []} headlist={coSttHeadList} @@ -768,7 +771,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ onPageChange={(page) => { setMngPage(page); }} - ></UiTable>) + ></UiTable></div>) } } return null; // 조건에 맞는 콘텐츠가 없을 경우 From bd999eb0f38c69865fa9c8ca89639d3e4f0f0126 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 25 Jul 2025 18:38:56 +0900 Subject: [PATCH 22/27] =?UTF-8?q?[apps/cs]=20chore:=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/admin/ui/add-admin-dialog.tsx | 5 +- apps/cs/src/pages/apilog/ui/apilog-page.tsx | 26 ++++----- apps/cs/src/pages/groups/ui/group-form.tsx | 4 +- apps/cs/src/pages/groups/ui/groups-dialog.tsx | 10 ++-- .../src/pages/loginlog/ui/loginlog-page.tsx | 26 ++++----- .../pages/privacylog/ui/privacylog-page.tsx | 26 ++++----- apps/cs/src/pages/recent/ui/recent-page.tsx | 35 ++++++------ .../ui/user-statistics-page.tsx | 54 +++++++++---------- apps/cs/src/pages/users/ui/users-page.tsx | 42 +++++++-------- .../src/shared/ui/input-date-range-picker.tsx | 47 ++++++++++++++++ 10 files changed, 149 insertions(+), 126 deletions(-) create mode 100644 apps/cs/src/shared/ui/input-date-range-picker.tsx diff --git a/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx b/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx index 327473932..859af4058 100644 --- a/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx +++ b/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx @@ -47,7 +47,7 @@ function AddAdminDialog() { const [open, setOpen] = useState(false); const [userSearchQuery, setUserSearchQuery] = useState<UserSearchParams>({ - keywordType: "", + keywordType: "userName", keyword: "", }); const [selectedGroupId, setSelectedGroupId] = useState(""); @@ -193,6 +193,7 @@ function AddAdminDialog() { <form onSubmit={handleSearch} className="flex items-center gap-2"> <Select + value={userSearchQuery.keywordType} onValueChange={(value) => setUserSearchQuery({ ...userSearchQuery, keywordType: value }) } @@ -201,8 +202,8 @@ function AddAdminDialog() { <SelectValue placeholder="선택" /> </SelectTrigger> <SelectContent> - <SelectItem value="userId">아이디</SelectItem> <SelectItem value="userName">이름</SelectItem> + <SelectItem value="userId">아이디</SelectItem> </SelectContent> </Select> <Input diff --git a/apps/cs/src/pages/apilog/ui/apilog-page.tsx b/apps/cs/src/pages/apilog/ui/apilog-page.tsx index a81275198..ab98a1931 100644 --- a/apps/cs/src/pages/apilog/ui/apilog-page.tsx +++ b/apps/cs/src/pages/apilog/ui/apilog-page.tsx @@ -7,7 +7,6 @@ import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; import { Button, Input, - InputDatePicker, Label, Select, SelectContent, @@ -15,10 +14,11 @@ import { SelectTrigger, SelectValue, } from "@common/components"; +import { columns } from "@/pages/apilog/model/table-columns"; import { ApiLogApi, type ApiLogParams } from "@/entities/apilog"; import { useDataTable } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; -import { columns } from "@/pages/apilog/model/table-columns"; +import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; type DateRange = { from?: Date | undefined; @@ -133,6 +133,11 @@ function ApiLogPage() { setDateRange(presetDateRange || defaultDateRange); }; + const handleDateRangeChange = (dateRange: DateRange) => { + setDateRange(dateRange); + setPresetDateRange(""); + }; + return ( <div className="flex-1"> <div className="card card-border"> @@ -148,20 +153,9 @@ function ApiLogPage() { <SelectItem value="3M">3개월</SelectItem> </SelectContent> </Select> - <InputDatePicker - value={dateRange.from} - onChange={(date) => { - setDateRange({ ...dateRange, from: date }); - setPresetDateRange(""); - }} - /> - ~ - <InputDatePicker - value={dateRange.to} - onChange={(date) => { - setDateRange({ ...dateRange, to: date }); - setPresetDateRange(""); - }} + <InputDateRangePicker + dateRange={dateRange} + setDateRange={handleDateRangeChange} /> <Label className="ml-4 mr-2 text-label">사용자ID</Label> <Input diff --git a/apps/cs/src/pages/groups/ui/group-form.tsx b/apps/cs/src/pages/groups/ui/group-form.tsx index 6c1d8b67f..16c620388 100644 --- a/apps/cs/src/pages/groups/ui/group-form.tsx +++ b/apps/cs/src/pages/groups/ui/group-form.tsx @@ -161,11 +161,11 @@ function GroupForm({ form }: GroupFormProps) { > <div className="flex items-center space-x-2"> <RadioGroupItem value="Y" id="mngrY" /> - <Label htmlFor="mngrY">Y</Label> + <Label htmlFor="mngrY">예</Label> </div> <div className="flex items-center space-x-2"> <RadioGroupItem value="N" id="mngrN" /> - <Label htmlFor="mngrN">N</Label> + <Label htmlFor="mngrN">아니오</Label> </div> </RadioGroup> </FormControl> diff --git a/apps/cs/src/pages/groups/ui/groups-dialog.tsx b/apps/cs/src/pages/groups/ui/groups-dialog.tsx index 427ba4b1b..9fca4ebdb 100644 --- a/apps/cs/src/pages/groups/ui/groups-dialog.tsx +++ b/apps/cs/src/pages/groups/ui/groups-dialog.tsx @@ -1,6 +1,6 @@ "use client"; -import { memo, useState } from "react"; +import { memo, useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; @@ -43,7 +43,7 @@ const GroupsDialog = memo( const { data: group } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.GROUPS, groupId], queryFn: () => GroupApi.findGroupById(groupId!), - enabled: !!groupId && open, // open 시점 groupId가 있을 때만 상세 조회 API 호출 + enabled: !!groupId && open, // open 시점 groupId가 있을 때만 상세 조회 API 호출 }); const { mutateAsync: createGroup } = useMutationWrapper({ @@ -77,7 +77,7 @@ const GroupsDialog = memo( delYn: group?.delYn ?? "", authrtId: group?.authrtId ?? "", siteId: group?.siteId ?? "", - mngrYn: group?.mngrYn ?? "", + mngrYn: group?.mngrYn ?? "Y", }, }); @@ -91,6 +91,10 @@ const GroupsDialog = memo( if (await confirm(confirmMessage)) callback(data); }; + useEffect(() => { + if (open) form.reset(); + }, [open]); + return ( <Dialog open={open} onOpenChange={setOpen} {...props}> <DialogTrigger asChild>{children}</DialogTrigger> diff --git a/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx b/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx index a9748b28d..7ae7990a1 100644 --- a/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx +++ b/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx @@ -7,7 +7,6 @@ import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; import { Button, Input, - InputDatePicker, Label, Select, SelectContent, @@ -16,10 +15,11 @@ import { SelectValue, LoadingWithImage, } from "@common/components"; +import { columns } from "@/pages/loginlog/model/table-columns"; import { LoginlogApi, type LoginlogParams } from "@/entities/loginlog"; import { useDataTable } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; -import { columns } from "@/pages/loginlog/model/table-columns"; +import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; type DateRange = { from?: Date | undefined; @@ -141,6 +141,11 @@ function LoginlogPage() { setDateRange(presetDateRange || defaultDateRange); }; + const handleDateRangeChange = (dateRange: DateRange) => { + setDateRange(dateRange); + setPresetDateRange(""); + }; + return ( <div className="flex-1"> <div className="card card-border"> @@ -156,20 +161,9 @@ function LoginlogPage() { <SelectItem value="3M">3개월</SelectItem> </SelectContent> </Select> - <InputDatePicker - value={dateRange.from} - onChange={(date) => { - setDateRange({ ...dateRange, from: date }); - setPresetDateRange(""); - }} - /> - ~ - <InputDatePicker - value={dateRange.to} - onChange={(date) => { - setDateRange({ ...dateRange, to: date }); - setPresetDateRange(""); - }} + <InputDateRangePicker + dateRange={dateRange} + setDateRange={handleDateRangeChange} /> <Label className="ml-4 mr-2 text-label">사용자ID</Label> <Input diff --git a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx index 90dc84571..ffce1c92d 100644 --- a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx +++ b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx @@ -7,7 +7,6 @@ import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; import { Button, Input, - InputDatePicker, Label, Select, SelectContent, @@ -15,13 +14,14 @@ import { SelectTrigger, SelectValue, } from "@common/components"; +import { columns } from "@/pages/privacylog/model/table-columns"; import { PrivacyLogPrivacy, type PrivacyLogParams, } from "@/entities/privacylog"; import { useDataTable } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; -import { columns } from "@/pages/privacylog/model/table-columns"; +import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; type DateRange = { from?: Date | undefined; @@ -132,6 +132,11 @@ function PrivacyLogPage() { setDateRange(presetDateRange || defaultDateRange); }; + const handleDateRangeChange = (dateRange: DateRange) => { + setDateRange(dateRange); + setPresetDateRange(""); + }; + return ( <div className="flex-1"> <div className="card card-border"> @@ -147,20 +152,9 @@ function PrivacyLogPage() { <SelectItem value="3M">3개월</SelectItem> </SelectContent> </Select> - <InputDatePicker - value={dateRange.from} - onChange={(date) => { - setDateRange({ ...dateRange, from: date }); - setPresetDateRange(""); - }} - /> - ~ - <InputDatePicker - value={dateRange.to} - onChange={(date) => { - setDateRange({ ...dateRange, to: date }); - setPresetDateRange(""); - }} + <InputDateRangePicker + dateRange={dateRange} + setDateRange={handleDateRangeChange} /> <Label className="ml-4 mr-2 text-label">조회정보</Label> <Input diff --git a/apps/cs/src/pages/recent/ui/recent-page.tsx b/apps/cs/src/pages/recent/ui/recent-page.tsx index 1ad451ae7..a2b0eeb00 100644 --- a/apps/cs/src/pages/recent/ui/recent-page.tsx +++ b/apps/cs/src/pages/recent/ui/recent-page.tsx @@ -13,7 +13,6 @@ import { import { Button, Input, - InputDatePicker, Label, Select, SelectContent, @@ -31,8 +30,9 @@ import { } from "@/entities/post"; import { BoardApi } from "@/entities/board"; import { AuthorityButton } from "@/entities/menu-authority"; -import { useAlertStore, useSelectPrompt, useDataTable } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; +import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; +import { useAlertStore, useSelectPrompt, useDataTable } from "@/shared/lib"; import { columns } from "../model/table-columns"; import { MovePostDialog } from "./move-post-dialog"; @@ -58,7 +58,7 @@ function RecentPage() { }); const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); const [presetDateRange, setPresetDateRange] = useState(""); - const [dateRange, setDateRange] = useState<DateRange | undefined>({ + const [dateRange, setDateRange] = useState<DateRange>({ from: undefined, to: undefined, }); @@ -169,7 +169,7 @@ function RecentPage() { }; const handlePresetDateRange = (value: string) => { - let presetDateRange: DateRange | undefined; + let presetDateRange: DateRange; switch (value) { case "1W": presetDateRange = { @@ -190,12 +190,20 @@ function RecentPage() { }; break; default: - presetDateRange = undefined; + presetDateRange = { + from: undefined, + to: undefined, + }; } setPresetDateRange(value); setDateRange(presetDateRange); }; + const handleDateRangeChange = (dateRange: DateRange) => { + setDateRange(dateRange); + setPresetDateRange(""); + }; + const onSoftDeletePost = async () => { const { resolved, value: delRsn } = await prompt("삭제 사유를 입력해주세요."); @@ -260,20 +268,9 @@ function RecentPage() { <SelectItem value="3M">3개월</SelectItem> </SelectContent> </Select> - <InputDatePicker - value={dateRange?.from} - onChange={(date) => { - setDateRange({ ...dateRange, from: date }); - setPresetDateRange(""); - }} - /> - ~ - <InputDatePicker - value={dateRange?.to} - onChange={(date) => { - setDateRange({ ...dateRange, to: date }); - setPresetDateRange(""); - }} + <InputDateRangePicker + dateRange={dateRange} + setDateRange={handleDateRangeChange} /> <Label className="ml-4 mr-2 text-label">게시판</Label> <Select diff --git a/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx b/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx index 4c45e04e2..9fedb47f4 100644 --- a/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx +++ b/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx @@ -4,19 +4,6 @@ import dayjs from "dayjs"; import { useState } from "react"; import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; -import { - Button, - Input, - InputDatePicker, - Label, - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@common/components"; -import { SiteSelect } from "@/entities/site"; -import { useDataTable } from "@/shared/lib"; import { Chart as ChartJS, CategoryScale, @@ -31,6 +18,19 @@ import { type ChartData, } from "chart.js"; import { Bar, Doughnut } from "react-chartjs-2"; +import { + Button, + Input, + Label, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@common/components"; +import { SiteSelect } from "@/entities/site"; +import { useDataTable } from "@/shared/lib"; +import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; import { UserStatisticsApi } from "../api"; import { chartData } from "../model/chart-data"; import { columns } from "../model/table-columns"; @@ -105,7 +105,7 @@ function UserStatisticsPage() { }); const handlePresetDateRange = (value: string) => { - let presetDateRange: DateRange | undefined; + let presetDateRange: DateRange; switch (value) { case "1W": presetDateRange = { @@ -126,10 +126,15 @@ function UserStatisticsPage() { }; break; default: - presetDateRange = undefined; + presetDateRange = defaultDateRange; } setPresetDateRange(value); - setDateRange(presetDateRange || defaultDateRange); + setDateRange(presetDateRange); + }; + + const handleDateRangeChange = (dateRange: DateRange) => { + setDateRange(dateRange); + setPresetDateRange(""); }; const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { @@ -200,20 +205,9 @@ function UserStatisticsPage() { <SelectItem value="3M">3개월</SelectItem> </SelectContent> </Select> - <InputDatePicker - value={dateRange.from} - onChange={(date) => { - setDateRange({ ...dateRange, from: date }); - setPresetDateRange(""); - }} - /> - ~ - <InputDatePicker - value={dateRange.to} - onChange={(date) => { - setDateRange({ ...dateRange, to: date }); - setPresetDateRange(""); - }} + <InputDateRangePicker + dateRange={dateRange} + setDateRange={handleDateRangeChange} /> <Label className="ml-4 mr-2 text-label">사이트</Label> <SiteSelect enabledAllSite className="w-[16rem]" /> diff --git a/apps/cs/src/pages/users/ui/users-page.tsx b/apps/cs/src/pages/users/ui/users-page.tsx index e119738fa..5362b8b42 100644 --- a/apps/cs/src/pages/users/ui/users-page.tsx +++ b/apps/cs/src/pages/users/ui/users-page.tsx @@ -9,7 +9,6 @@ import { Button, Checkbox, Input, - InputDatePicker, Label, Select, SelectContent, @@ -25,6 +24,7 @@ import { } from "@/entities/user"; import { ENDPOINT } from "@/shared/config"; import { useDataTable } from "@/shared/lib"; +import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; import { columns } from "../model/table-columns"; type DateRange = { @@ -40,7 +40,7 @@ function UsersPage() { pageSize: 10, }); const [presetDateRange, setPresetDateRange] = useState(""); - const [dateRange, setDateRange] = useState<DateRange | undefined>({ + const [dateRange, setDateRange] = useState<DateRange>({ from: undefined, to: undefined, }); @@ -62,7 +62,7 @@ function UsersPage() { }); const { data: userSttsStats } = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.USERS], + queryKey: [ENDPOINT.USER_SERVICE.USERS, "userStatusStatistics"], queryFn: () => UserApi.selectUserSttsStats(), }); @@ -145,7 +145,7 @@ function UsersPage() { }; const handlePresetDateRange = (value: string) => { - let presetDateRange: DateRange | undefined; + let presetDateRange: DateRange; switch (value) { case "1M": presetDateRange = { @@ -166,15 +166,24 @@ function UsersPage() { }; break; default: - presetDateRange = undefined; + presetDateRange = { + from: undefined, + to: undefined, + }; } setPresetDateRange(value); setDateRange(presetDateRange); }; - const getUserSttsStatsCnt = (code: string): number => { - if (!Array.isArray(userSttsStats)) return 0; - return userSttsStats.find((item) => item.sttsCd === code)?.cnt ?? 0; + const handleDateRangeChange = (dateRange: DateRange) => { + setDateRange(dateRange); + setPresetDateRange(""); + }; + + const getUserSttsStatsCnt = (code: string): string => { + if (!Array.isArray(userSttsStats)) return "0"; + const count = userSttsStats.find((item) => item.sttsCd === code)?.cnt ?? 0; + return count.toLocaleString(); }; const handleUserStateCodeChange = (code: string, checked: boolean) => { @@ -292,20 +301,9 @@ function UsersPage() { <SelectItem value="6M">6개월</SelectItem> </SelectContent> </Select> - <InputDatePicker - value={dateRange?.from} - onChange={(date) => { - setDateRange({ ...dateRange, from: date }); - setPresetDateRange(""); - }} - /> - ~ - <InputDatePicker - value={dateRange?.to} - onChange={(date) => { - setDateRange({ ...dateRange, to: date }); - setPresetDateRange(""); - }} + <InputDateRangePicker + dateRange={dateRange} + setDateRange={handleDateRangeChange} /> </div> </div> diff --git a/apps/cs/src/shared/ui/input-date-range-picker.tsx b/apps/cs/src/shared/ui/input-date-range-picker.tsx new file mode 100644 index 000000000..9f574661e --- /dev/null +++ b/apps/cs/src/shared/ui/input-date-range-picker.tsx @@ -0,0 +1,47 @@ +import { InputDatePicker } from "@common/components"; +import { useEffect } from "react"; +import { useAlertStore } from "../lib"; + +type DateRange = { + from?: Date; + to?: Date; +}; + +type InputDateRangePickerProps = { + dateRange: DateRange; + setDateRange: (dateRange: DateRange) => void; +}; + +function InputDateRangePicker({ + dateRange, + setDateRange, +}: InputDateRangePickerProps) { + const alert = useAlertStore((state) => state.setMessage); + + useEffect(() => { + if (dateRange.from && dateRange.to && dateRange.from > dateRange.to) { + alert("시작일보다 종료일이 커야 합니다."); + setDateRange({ ...dateRange, to: dateRange.from }); + } + }, [dateRange]); + + return ( + <> + <InputDatePicker + value={dateRange.from} + onChange={(date) => { + setDateRange({ ...dateRange, from: date }); + }} + /> + ~ + <InputDatePicker + value={dateRange.to} + onChange={(date) => { + setDateRange({ ...dateRange, to: date }); + }} + /> + </> + ); +} + +export { InputDateRangePicker }; From 9a62ef6276a5496a720c4a41a1cadd65ed69609c Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 25 Jul 2025 18:44:30 +0900 Subject: [PATCH 23/27] =?UTF-8?q?[apps/cs]=20chore:=20=EC=88=AB=EC=9E=90?= =?UTF-8?q?=EC=97=90=20toLocaleString()=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/dashboard/ui/dashboard-page.tsx | 60 +++++++++++++------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/apps/cs/src/pages/dashboard/ui/dashboard-page.tsx b/apps/cs/src/pages/dashboard/ui/dashboard-page.tsx index 4d657a5fc..4bae35f7c 100644 --- a/apps/cs/src/pages/dashboard/ui/dashboard-page.tsx +++ b/apps/cs/src/pages/dashboard/ui/dashboard-page.tsx @@ -110,10 +110,16 @@ function DashboardPage() { <div className="absolute left-0 top-0 p-6 tracking-tighter text-white"> <h3 className="text-2xl font-medium">총 회원수</h3> <div className="mt-2 text-6xl font-bold"> - {data?.memberTotCnt ?? "-"} + {data?.memberTotCnt + ? data.memberTotCnt.toLocaleString() + : "-"} </div> <p className="mt-1 text-2xl opacity-80"> - 금일 신규 가입자 {data?.memberTodayCnt ?? "-"}명 + 금일 신규 가입자 + {data?.memberTodayCnt + ? data.memberTodayCnt.toLocaleString() + : "-"} + 명 </p> </div> {/* 차트 영역 */} @@ -131,10 +137,12 @@ function DashboardPage() { <div className="absolute left-0 top-0 p-6 tracking-tighter"> <h3 className="text-2xl font-medium">전체 게시물</h3> <div className="mt-2 text-6xl font-bold"> - {data?.pstTotCnt ?? "-"} + {data?.pstTotCnt ? data.pstTotCnt.toLocaleString() : "-"} </div> <p className="mt-1 text-2xl opacity-80"> - 금일 +{data?.pstTodayCnt ?? "-"} 등록 + 금일 + + {data?.pstTodayCnt ? data.pstTodayCnt.toLocaleString() : "-"}{" "} + 등록 </p> </div> {/* 차트 영역 */} @@ -152,10 +160,16 @@ function DashboardPage() { <div className="absolute left-0 top-0 p-6 tracking-tighter"> <h3 className="text-2xl font-medium">오늘 접속자 수</h3> <div className="mt-2 text-6xl font-bold"> - {data?.accessTodayCnt ?? "-"} + {data?.accessTodayCnt + ? data.accessTodayCnt.toLocaleString() + : "-"} </div> <p className="mt-1 text-2xl opacity-80"> - 전일 대비 +{data?.accessBefDayPer ?? "-"}% + 전일 대비 + + {data?.accessBefDayPer + ? data.accessBefDayPer.toLocaleString() + : "-"} + % </p> </div> {/* 차트 영역 */} @@ -173,7 +187,7 @@ function DashboardPage() { <div className="absolute left-0 top-0 p-6 tracking-tighter"> <h3 className="text-2xl font-medium">API 호출 건수</h3> <div className="mt-2 text-6xl font-bold"> - {data?.apiTodayCnt ?? "-"} + {data?.apiTodayCnt ? data.apiTodayCnt.toLocaleString() : "-"} </div> <p className="mt-1 text-2xl opacity-80">금일 누적</p> </div> @@ -221,7 +235,10 @@ function DashboardPage() { </div> <div className="mt-5"> <div className="text-5xl font-bold"> - {data?.waitMemberCnt}건 + {data?.waitMemberCnt + ? data.waitMemberCnt.toLocaleString() + : "0"} + 건 </div> <div className="mt-2 text-2xl text-gray-500"> 신규 가입 승인 대기 @@ -253,7 +270,9 @@ function DashboardPage() { <span className="text-2xl font-medium">메뉴 승인</span> </div> <div className="mt-5"> - <div className="text-5xl font-bold">3건</div> + <div className="text-5xl font-bold"> + {(3).toLocaleString()}건 + </div> <div className="mt-2 text-2xl text-gray-500"> 매뉴 수정 승인 대기 </div> @@ -283,7 +302,10 @@ function DashboardPage() { </div> <div className="mt-5"> <div className="text-5xl font-bold"> - {data?.waitCntnCnt}건 + {data?.waitCntnCnt + ? data.waitCntnCnt.toLocaleString() + : "0"} + 건 </div> <div className="mt-2 text-2xl text-gray-500"> 컨텐츠 수정 승인 대기 @@ -303,19 +325,19 @@ function DashboardPage() { <div className="space-y-4"> <div className="flex items-center justify-between border-b border-border pb-4"> <span className="font-medium">신규 사용자 가입</span> - <span>1분 전</span> + <span>{(1).toLocaleString()}분 전</span> </div> <div className="flex items-center justify-between border-b border-border pb-4"> <span className="font-medium">메뉴 수정 요청</span> - <span>5분 전</span> + <span>{(5).toLocaleString()}분 전</span> </div> <div className="flex items-center justify-between border-b border-border pb-4"> <span className="font-medium">게시물 신고</span> - <span>10분 전</span> + <span>{(10).toLocaleString()}분 전</span> </div> <div className="flex items-center justify-between"> <span className="font-medium">컨텐츠 승인 요청</span> - <span>15분 전</span> + <span>{(15).toLocaleString()}분 전</span> </div> </div> </div> @@ -328,20 +350,22 @@ function DashboardPage() { <div className="p-4"> <div className="space-y-4"> <div className="flex items-center justify-between border-b border-border pb-4"> - <span className="font-medium">3월 정기 시스템 점검</span> + <span className="font-medium"> + {(3).toLocaleString()}월 정기 시스템 점검 + </span> <span>내일</span> </div> <div className="flex items-center justify-between border-b border-border pb-4"> <span className="font-medium">서버 업데이트 예정</span> - <span>3일 후</span> + <span>{(3).toLocaleString()}일 후</span> </div> <div className="flex items-center justify-between border-b border-border pb-4"> <span className="font-medium">백업 스케줄</span> - <span>5일 후</span> + <span>{(5).toLocaleString()}일 후</span> </div> <div className="flex items-center justify-between"> <span className="font-medium">정기 보안 점검</span> - <span>7일 후</span> + <span>{(7).toLocaleString()}일 후</span> </div> </div> </div> From 4ee840fa82b8b5886fa05505ba6c6f0287a67c7a Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 25 Jul 2025 18:56:54 +0900 Subject: [PATCH 24/27] =?UTF-8?q?chore:=20pnpm-lock=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pnpm-lock.yaml | 10836 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 10836 insertions(+) create mode 100644 pnpm-lock.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..3ebaa2a1e --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,10836 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + +importers: + + .: + dependencies: + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@types/node': + specifier: ^22.13.9 + version: 22.13.9 + '@types/react': + specifier: ^18.3.18 + version: 18.3.18 + '@types/react-dom': + specifier: ^18.3.5 + version: 18.3.5(@types/react@18.3.18) + turbo: + specifier: 2.4.2 + version: 2.4.2 + + apps/common/features: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../../packages/common/assets + '@common/components': + specifier: workspace:* + version: link:../../../packages/common/components + '@common/config': + specifier: workspace:* + version: link:../../../packages/common/config + '@common/network': + specifier: workspace:* + version: link:../../../packages/common/network + '@fontsource-variable/noto-sans-kr': + specifier: ^5.2.5 + version: 5.2.5 + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@minoru/react-dnd-treeview': + specifier: ^3.5.0 + version: 3.5.0(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: ^5.75.5 + version: 5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + '@tinymce/tinymce-react': + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.3.1)(react@18.3.1) + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + next: + specifier: 15.3.0 + version: 15.3.0(react-dom@18.3.1)(react@18.3.1) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@18.3.1)(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + sonner: + specifier: ^2.0.1 + version: 2.0.1(react-dom@18.3.1)(react@18.3.1) + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.13.1 + version: 22.13.9 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + steiger: + specifier: ^0.5.5 + version: 0.5.5(typescript@5.6.3) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/cs: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@common/config': + specifier: workspace:* + version: link:../../packages/common/config + '@fontsource-variable/noto-sans-kr': + specifier: ^5.2.5 + version: 5.2.5 + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@fullcalendar/core': + specifier: ^6.1.17 + version: 6.1.17 + '@fullcalendar/daygrid': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17) + '@fullcalendar/interaction': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17) + '@fullcalendar/react': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17)(react-dom@18.3.1)(react@18.3.1) + '@fullcalendar/timegrid': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17) + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@minoru/react-dnd-treeview': + specifier: 3.5.1-alpha.1 + version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-tooltip': + specifier: ^1.1.8 + version: 1.1.8(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: ^5.75.5 + version: 5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + '@tinymce/tinymce-react': + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.3.1)(react@18.3.1) + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + next: + specifier: 15.3.0 + version: 15.3.0(react-dom@18.3.1)(react@18.3.1) + next-qrcode: + specifier: ^2.5.1 + version: 2.5.1(react@18.3.1) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@18.3.1)(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + sonner: + specifier: ^2.0.1 + version: 2.0.1(react-dom@18.3.1)(react@18.3.1) + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.13.1 + version: 22.13.5 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + steiger: + specifier: ^0.5.5 + version: 0.5.5(typescript@5.6.3) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/dm: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/business_components': + specifier: workspace:* + version: link:../../packages/common/business_components + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + js-sha512: + specifier: ^0.9.0 + version: 0.9.0 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + next: + specifier: 15.1.7 + version: 15.1.7(react-dom@18.3.1)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + react-hot-toast: + specifier: ^2.5.2 + version: 2.5.2(react-dom@18.3.1)(react@18.3.1) + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/fo: + dependencies: + '@common/business_components': + specifier: workspace:* + version: link:../../packages/common/business_components + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@tailwindcss/vite': + specifier: ^4.0.10 + version: 4.1.11(vite@6.2.0) + html2canvas: + specifier: ^1.4.1 + version: 1.4.1 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + next: + specifier: 15.1.7 + version: 15.1.7(react-dom@18.3.1)(react@18.3.1) + select: + specifier: ^1.1.2 + version: 1.1.2 + webpack: + specifier: ^5.98.0 + version: 5.98.0 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + typescript: + specifier: ^5.6.3 + version: 5.6.3 + + apps/sn: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/business_components': + specifier: workspace:* + version: link:../../packages/common/business_components + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@fontsource-variable/noto-sans-kr': + specifier: ^5.2.5 + version: 5.2.5 + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@minoru/react-dnd-treeview': + specifier: 3.5.1-alpha.1 + version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: ^5.75.5 + version: 5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + moment: + specifier: ^2.30.1 + version: 2.30.1 + next: + specifier: 15.1.7 + version: 15.1.7(react-dom@18.3.1)(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@faker-js/faker': + specifier: ^9.5.0 + version: 9.5.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.13.1 + version: 22.13.9 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + steiger: + specifier: ^0.5.5 + version: 0.5.5(typescript@5.6.3) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/wr: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/business_components': + specifier: workspace:* + version: link:../../packages/common/business_components + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + i18next: + specifier: ^25.3.2 + version: 25.3.2(typescript@5.6.3) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + moment: + specifier: ^2.30.1 + version: 2.30.1 + next: + specifier: 15.1.7 + version: 15.1.7(react-dom@18.3.1)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + react-hot-toast: + specifier: ^2.5.2 + version: 2.5.2(react-dom@18.3.1)(react@18.3.1) + react-i18next: + specifier: ^15.6.0 + version: 15.6.1(i18next@25.3.2)(react-dom@18.3.1)(react@18.3.1)(typescript@5.6.3) + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + packages/common/assets: + devDependencies: + '@types/node': + specifier: ^20.11.0 + version: 20.17.19 + tsup: + specifier: ^8.0.1 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ^5.3.3 + version: 5.6.3 + + packages/common/business_components: + dependencies: + '@common/components': + specifier: workspace:* + version: link:../components + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@minoru/react-dnd-treeview': + specifier: 3.5.1-alpha.1 + version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-scroll-area': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-select': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + axios: + specifier: 1.8.1 + version: 1.8.1 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^3.6.0 + version: 3.6.0 + libphonenumber-js: + specifier: ^1.12.9 + version: 1.12.10 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + ol: + specifier: ^7.3.0 + version: 7.5.2 + ol-ext: + specifier: ^4.0.11 + version: 4.0.31(ol@7.5.2) + path: + specifier: ^0.12.7 + version: 0.12.7 + proj4: + specifier: ^2.9.0 + version: 2.15.0 + react-day-picker: + specifier: ^8.10.1 + version: 8.10.1(date-fns@3.6.0)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1) + react-dropzone: + specifier: ^14.3.8 + version: 14.3.8(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + recharts: + specifier: ^2.15.1 + version: 2.15.1(react-dom@18.3.1)(react@18.3.1) + sonner: + specifier: ^2.0.1 + version: 2.0.1(react-dom@18.3.1)(react@18.3.1) + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + xlsx: + specifier: ^0.18.5 + version: 0.18.5 + xlsx-populate: + specifier: ^1.21.0 + version: 1.21.0 + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@eslint/js': + specifier: ^9.17.0 + version: 9.21.0 + '@storybook/addon-essentials': + specifier: ^8.5.3 + version: 8.6.0(@types/react@18.3.18)(storybook@8.6.0) + '@storybook/addon-interactions': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-onboarding': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-themes': + specifier: ^8.5.4 + version: 8.6.0(storybook@8.6.0) + '@storybook/blocks': + specifier: ^8.5.3 + version: 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/manager-api': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@storybook/react': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3) + '@storybook/react-vite': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3)(vite@6.2.0) + '@storybook/test': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/theming': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(vite@6.2.0) + '@xlsx/xlsx-populate': + specifier: ^0.0.8 + version: 0.0.8 + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.5.3) + eslint: + specifier: ^9.17.0 + version: 9.21.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.21.0) + eslint-plugin-react-refresh: + specifier: ^0.4.16 + version: 0.4.19(eslint@9.21.0) + eslint-plugin-storybook: + specifier: ^0.11.2 + version: 0.11.3(eslint@9.21.0)(typescript@5.6.3) + globals: + specifier: ^15.14.0 + version: 15.15.0 + postcss: + specifier: ^8.5.3 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + storybook: + specifier: ^8.5.3 + version: 8.6.0(prettier@3.5.2) + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + tsup: + specifier: 8.3.6 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.18.2 + version: 8.25.0(eslint@9.21.0)(typescript@5.6.3) + vite: + specifier: ^6.0.5 + version: 6.2.0(@types/node@22.13.9) + vite-tsconfig-paths: + specifier: 5.1.4 + version: 5.1.4(typescript@5.6.3)(vite@6.2.0) + + packages/common/components: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../assets + '@common/config': + specifier: workspace:* + version: link:../config + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@minoru/react-dnd-treeview': + specifier: ^3.5.0 + version: 3.5.0(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-accordion': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-checkbox': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collapsible': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dialog': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-popover': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-progress': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-radio-group': + specifier: ^1.2.2 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-scroll-area': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-select': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-separator': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slider': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-tabs': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-tooltip': + specifier: ^1.1.8 + version: 1.1.8(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-visually-hidden': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^3.6.0 + version: 3.6.0 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + embla-carousel-react: + specifier: ^8.6.0 + version: 8.6.0(react@18.3.1) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-day-picker: + specifier: ^9.7.0 + version: 9.7.0(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1) + react-dnd-html5-backend: + specifier: ^16.0.1 + version: 16.0.1 + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + devDependencies: + '@eslint/js': + specifier: ^9.17.0 + version: 9.21.0 + '@faker-js/faker': + specifier: ^9.5.0 + version: 9.5.0 + '@storybook/addon-essentials': + specifier: ^8.5.3 + version: 8.6.0(@types/react@18.3.18)(storybook@8.6.0) + '@storybook/addon-interactions': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-onboarding': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-themes': + specifier: ^8.5.4 + version: 8.6.0(storybook@8.6.0) + '@storybook/blocks': + specifier: ^8.5.3 + version: 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/manager-api': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@storybook/react': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3) + '@storybook/react-vite': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3)(vite@6.2.0) + '@storybook/test': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/theming': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@types/node': + specifier: ^22.13.1 + version: 22.13.5 + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(vite@6.2.0) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.5.3) + eslint: + specifier: ^9.17.0 + version: 9.21.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.21.0) + eslint-plugin-react-refresh: + specifier: ^0.4.16 + version: 0.4.19(eslint@9.21.0) + eslint-plugin-storybook: + specifier: ^0.11.2 + version: 0.11.3(eslint@9.21.0)(typescript@5.6.3) + globals: + specifier: ^15.14.0 + version: 15.15.0 + postcss: + specifier: ^8.5.1 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + storybook: + specifier: ^8.5.3 + version: 8.6.0(prettier@3.5.2) + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + tsup: + specifier: 8.3.6 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.18.2 + version: 8.25.0(eslint@9.21.0)(typescript@5.6.3) + vite: + specifier: ^6.0.5 + version: 6.2.0(@types/node@22.13.5) + vite-tsconfig-paths: + specifier: 5.1.4 + version: 5.1.4(typescript@5.6.3)(vite@6.2.0) + + packages/common/config: + devDependencies: + eslint: + specifier: ^9.8.0 + version: 9.21.0 + tsup: + specifier: ^8.2.3 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ^5.5.3 + version: 5.6.3 + vite: + specifier: ^5.3.5 + version: 5.4.18(@types/node@22.13.9) + + packages/common/network: + dependencies: + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + axios: + specifier: ^1.8.1 + version: 1.8.1 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + devDependencies: + '@types/node': + specifier: ^20.11.19 + version: 20.17.19 + typescript: + specifier: ^5.3.3 + version: 5.6.3 + +packages: + + /@adobe/css-tools@4.4.2: + resolution: {integrity: sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==} + dev: true + + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + /@babel/code-frame@7.26.2: + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + dev: true + + /@babel/compat-data@7.26.8: + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.26.9: + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.26.9: + resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + dev: true + + /@babel/helper-compilation-targets@7.26.5: + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-module-imports@7.25.9: + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9): + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-plugin-utils@7.26.5: + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-string-parser@7.25.9: + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.25.9: + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.25.9: + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.26.9: + resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + dev: true + + /@babel/parser@7.26.9: + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.26.9 + dev: true + + /@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9): + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + dev: true + + /@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.9): + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + dev: true + + /@babel/runtime@7.26.9: + resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + + /@babel/runtime@7.28.2: + resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/template@7.26.9: + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + dev: true + + /@babel/traverse@7.26.9: + resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.26.9: + resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + dev: true + + /@clack/core@0.3.5: + resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + dev: true + + /@clack/prompts@0.8.2: + resolution: {integrity: sha512-6b9Ab2UiZwJYA9iMyboYyW9yJvAO9V753ZhS+DHKEjZRKAxPPOb7MXXu84lsPFG+vZt6FRFniZ8rXi+zCIw4yQ==} + dependencies: + '@clack/core': 0.3.5 + picocolors: 1.1.1 + sisteransi: 1.0.5 + dev: true + + /@date-fns/tz@1.2.0: + resolution: {integrity: sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==} + dev: false + + /@dependents/detective-less@5.0.1: + resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} + engines: {node: '>=18'} + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.1 + dev: true + + /@emnapi/runtime@1.4.3: + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + requiresBuild: true + dependencies: + tslib: 2.8.1 + dev: false + optional: true + + /@esbuild/aix-ppc64@0.21.5: + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/aix-ppc64@0.24.2: + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/aix-ppc64@0.25.0: + resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + optional: true + + /@esbuild/android-arm64@0.21.5: + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.24.2: + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.25.0: + resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/android-arm@0.21.5: + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.24.2: + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.25.0: + resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/android-x64@0.21.5: + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.24.2: + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.25.0: + resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/darwin-arm64@0.21.5: + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.24.2: + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.25.0: + resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@esbuild/darwin-x64@0.21.5: + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.24.2: + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.25.0: + resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@esbuild/freebsd-arm64@0.21.5: + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.24.2: + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.25.0: + resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + optional: true + + /@esbuild/freebsd-x64@0.21.5: + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.24.2: + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.25.0: + resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + optional: true + + /@esbuild/linux-arm64@0.21.5: + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.24.2: + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.25.0: + resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-arm@0.21.5: + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.24.2: + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.25.0: + resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-ia32@0.21.5: + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.24.2: + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.25.0: + resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-loong64@0.21.5: + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.24.2: + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.25.0: + resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-mips64el@0.21.5: + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.24.2: + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.25.0: + resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-ppc64@0.21.5: + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.24.2: + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.25.0: + resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-riscv64@0.21.5: + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.24.2: + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.25.0: + resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-s390x@0.21.5: + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.24.2: + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.25.0: + resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-x64@0.21.5: + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.24.2: + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.25.0: + resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/netbsd-arm64@0.24.2: + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-arm64@0.25.0: + resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + optional: true + + /@esbuild/netbsd-x64@0.21.5: + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.24.2: + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.25.0: + resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + optional: true + + /@esbuild/openbsd-arm64@0.24.2: + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-arm64@0.25.0: + resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + optional: true + + /@esbuild/openbsd-x64@0.21.5: + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.24.2: + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.25.0: + resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + optional: true + + /@esbuild/sunos-x64@0.21.5: + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.24.2: + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.25.0: + resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + requiresBuild: true + optional: true + + /@esbuild/win32-arm64@0.21.5: + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.24.2: + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.25.0: + resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@esbuild/win32-ia32@0.21.5: + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.24.2: + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.25.0: + resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@esbuild/win32-x64@0.21.5: + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.24.2: + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.25.0: + resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /@eslint-community/eslint-utils@4.4.1(eslint@9.21.0): + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 9.21.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.12.1: + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/config-array@0.19.2: + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/core@0.12.0: + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@types/json-schema': 7.0.15 + dev: true + + /@eslint/eslintrc@3.3.0: + resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@9.21.0: + resolution: {integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/object-schema@2.1.6: + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/plugin-kit@0.2.7: + resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/core': 0.12.0 + levn: 0.4.1 + dev: true + + /@faker-js/faker@9.5.0: + resolution: {integrity: sha512-3qbjLv+fzuuCg3umxc9/7YjrEXNaKwHgmig949nfyaTx8eL4FAsvFbu+1JcFUj1YAXofhaDn6JdEUBTYuk0Ssw==} + engines: {node: '>=18.0.0', npm: '>=9.0.0'} + deprecated: Please update to a newer version + dev: true + + /@feature-sliced/filesystem@2.4.0: + resolution: {integrity: sha512-aOFdPACNvkFXYb+gNHId8UCRD5fm7Z9/RV6JgBPlgEvm1QtLS4idg2XeHMDGnHrNRCS4ki+0RauxVZxm+g9pvw==} + dependencies: + typescript: 5.6.3 + dev: true + + /@feature-sliced/steiger-plugin@0.5.4(typescript@5.6.3): + resolution: {integrity: sha512-QzkIQUqNq94fv7aV0GY8wKmlFij9CtSQEIV+/0ed33SZGrv1FjUaySO4eHPlSCcH3Y+fH9nnpTaULtqRwwT7sw==} + dependencies: + '@feature-sliced/filesystem': 2.4.0 + fastest-levenshtein: 1.0.16 + lodash-es: 4.17.21 + pluralize: 8.0.0 + precinct: 12.2.0 + tsconfck: 3.1.5(typescript@5.6.3) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@floating-ui/core@1.6.9: + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + dependencies: + '@floating-ui/utils': 0.2.9 + dev: false + + /@floating-ui/dom@1.6.13: + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + dependencies: + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + dev: false + + /@floating-ui/react-dom@2.1.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@floating-ui/dom': 1.6.13 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@floating-ui/utils@0.2.9: + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + dev: false + + /@fontsource-variable/noto-sans-kr@5.2.5: + resolution: {integrity: sha512-dIJyVPIBRJXtvaFmQ6GKCV93J9Fx3O2Ym5C3gDRcz5zLpEigrnlEfBnsXBUv4aDBHEF/gm/Q07d40dddGxFytg==} + dev: false + + /@frontend-opensource/use-react-hooks@1.1.4: + resolution: {integrity: sha512-otCSyciL5MVCNNYmdDdg2lEL6rbZ3XX1meYQCzapUSC4V6qx2YxMk1kUbhwEM/+vdxhYzBHsVBGD0rZWl5cgrw==} + dependencies: + async-wave: 1.8.6 + fast-deep-equal: 3.1.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@fullcalendar/core@6.1.17: + resolution: {integrity: sha512-0W7lnIrv18ruJ5zeWBeNZXO8qCWlzxDdp9COFEsZnyNjiEhUVnrW/dPbjRKYpL0edGG0/Lhs0ghp1z/5ekt8ZA==} + dependencies: + preact: 10.12.1 + dev: false + + /@fullcalendar/daygrid@6.1.17(@fullcalendar/core@6.1.17): + resolution: {integrity: sha512-K7m+pd7oVJ9fW4h7CLDdDGJbc9szJ1xDU1DZ2ag+7oOo1aCNLv44CehzkkknM6r8EYlOOhgaelxQpKAI4glj7A==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + dependencies: + '@fullcalendar/core': 6.1.17 + dev: false + + /@fullcalendar/interaction@6.1.17(@fullcalendar/core@6.1.17): + resolution: {integrity: sha512-AudvQvgmJP2FU89wpSulUUjeWv24SuyCx8FzH2WIPVaYg+vDGGYarI7K6PcM3TH7B/CyaBjm5Rqw9lXgnwt5YA==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + dependencies: + '@fullcalendar/core': 6.1.17 + dev: false + + /@fullcalendar/react@6.1.17(@fullcalendar/core@6.1.17)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-AA8soHhlfRH5dUeqHnfAtzDiXa2vrgWocJSK/F5qzw/pOxc9MqpuoS/nQBROWtHHg6yQUg3DoGqOOhi7dmylXQ==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@fullcalendar/core': 6.1.17 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@fullcalendar/timegrid@6.1.17(@fullcalendar/core@6.1.17): + resolution: {integrity: sha512-K4PlA3L3lclLOs3IX8cvddeiJI9ZVMD7RA9IqaWwbvac771971foc9tFze9YY+Pqesf6S+vhS2dWtEVlERaGlQ==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + dependencies: + '@fullcalendar/core': 6.1.17 + '@fullcalendar/daygrid': 6.1.17(@fullcalendar/core@6.1.17) + dev: false + + /@hookform/resolvers@4.1.3(react-hook-form@7.54.2): + resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==} + peerDependencies: + react-hook-form: ^7.0.0 + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.54.2(react@18.3.1) + dev: false + + /@humanfs/core@0.19.1: + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + dev: true + + /@humanfs/node@0.16.6: + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/retry@0.3.1: + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + dev: true + + /@humanwhocodes/retry@0.4.2: + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + dev: true + + /@img/sharp-darwin-arm64@0.33.5: + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-darwin-arm64@0.34.1: + resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.33.5: + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.34.1: + resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.0.4: + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.1.0: + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.0.4: + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.1.0: + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.0.4: + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.1.0: + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.0.5: + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.1.0: + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-ppc64@1.1.0: + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.0.4: + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.1.0: + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.0.4: + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.1.0: + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.0.4: + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.1.0: + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.0.4: + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.1.0: + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-linux-arm64@0.33.5: + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linux-arm64@0.34.1: + resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + dev: false + optional: true + + /@img/sharp-linux-arm@0.33.5: + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + dev: false + optional: true + + /@img/sharp-linux-arm@0.34.1: + resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + dev: false + optional: true + + /@img/sharp-linux-s390x@0.33.5: + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + dev: false + optional: true + + /@img/sharp-linux-s390x@0.34.1: + resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + dev: false + optional: true + + /@img/sharp-linux-x64@0.33.5: + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linux-x64@0.34.1: + resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + dev: false + optional: true + + /@img/sharp-linuxmusl-arm64@0.33.5: + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linuxmusl-arm64@0.34.1: + resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + dev: false + optional: true + + /@img/sharp-linuxmusl-x64@0.33.5: + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linuxmusl-x64@0.34.1: + resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + dev: false + optional: true + + /@img/sharp-wasm32@0.33.5: + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 1.4.3 + dev: false + optional: true + + /@img/sharp-wasm32@0.34.1: + resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 1.4.3 + dev: false + optional: true + + /@img/sharp-win32-ia32@0.33.5: + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-ia32@0.34.1: + resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.33.5: + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.34.1: + resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + + /@isaacs/fs-minipass@4.0.1: + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + dependencies: + minipass: 7.1.2 + dev: false + + /@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.6.3)(vite@6.2.0): + resolution: {integrity: sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + glob: 10.4.5 + magic-string: 0.27.0 + react-docgen-typescript: 2.2.2(typescript@5.6.3) + typescript: 5.6.3 + vite: 6.2.0(@types/node@22.13.9) + dev: true + + /@jridgewell/gen-mapping@0.3.8: + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + /@jridgewell/source-map@0.3.6: + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + /@juggle/resize-observer@3.4.0: + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + dev: false + + /@kurkle/color@0.3.4: + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + dev: false + + /@mapbox/jsonlint-lines-primitives@2.0.2: + resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} + engines: {node: '>= 0.6'} + dev: false + + /@mapbox/mapbox-gl-style-spec@13.28.0: + resolution: {integrity: sha512-B8xM7Fp1nh5kejfIl4SWeY0gtIeewbuRencqO3cJDrCHZpaPg7uY+V8abuR+esMeuOjRl5cLhVTP40v+1ywxbg==} + hasBin: true + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/point-geometry': 0.1.0 + '@mapbox/unitbezier': 0.0.0 + csscolorparser: 1.0.3 + json-stringify-pretty-compact: 2.0.0 + minimist: 1.2.8 + rw: 1.3.3 + sort-object: 0.3.2 + dev: false + + /@mapbox/point-geometry@0.1.0: + resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==} + dev: false + + /@mapbox/unitbezier@0.0.0: + resolution: {integrity: sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==} + dev: false + + /@mdx-js/react@3.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.3.18 + react: 18.3.1 + dev: true + + /@minoru/react-dnd-treeview@3.5.0(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-kDHGQ0UK18w6ie5EH68NynATSP9BAzNLmWBXuVSoaGkraWWFdEdAWqQxAZiMorAixFu40MzYkn2N9/Gam6q17w==} + peerDependencies: + react: ^18.3.1 + react-dnd: 15.x || 16.x + react-dom: ^18.3.1 + dependencies: + '@juggle/resize-observer': 3.4.0 + dnd-multi-backend: 8.1.2(dnd-core@16.0.1) + framer-motion: 11.18.2(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dnd: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1) + react-dnd-html5-backend: 16.0.1 + react-dnd-touch-backend: 16.0.1 + react-dom: 18.3.1(react@18.3.1) + react-use-measure: 2.1.7(react-dom@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - dnd-core + dev: false + + /@minoru/react-dnd-treeview@3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-XEKBjhyltG0gzn+ioZRwhlV7+Q/uVZqTMS/tAO3On/rPNuNgqWHROFsyGdHQS/DYoENGOG8JX03chCxExOgEpA==} + peerDependencies: + react: ^18.3.1 + react-dnd: 15.x || 16.x + react-dom: ^18.3.1 + dependencies: + '@juggle/resize-observer': 3.4.0 + dnd-multi-backend: 8.1.2(dnd-core@16.0.1) + framer-motion: 11.18.2(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dnd: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1) + react-dnd-html5-backend: 16.0.1 + react-dnd-touch-backend: 16.0.1 + react-dom: 18.3.1(react@18.3.1) + react-use-measure: 2.1.7(react-dom@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - dnd-core + dev: false + + /@next/env@15.1.7: + resolution: {integrity: sha512-d9jnRrkuOH7Mhi+LHav2XW91HOgTAWHxjMPkXMGBc9B2b7614P7kjt8tAplRvJpbSt4nbO1lugcT/kAaWzjlLQ==} + dev: false + + /@next/env@15.3.0: + resolution: {integrity: sha512-6mDmHX24nWlHOlbwUiAOmMyY7KELimmi+ed8qWcJYjqXeC+G6JzPZ3QosOAfjNwgMIzwhXBiRiCgdh8axTTdTA==} + dev: false + + /@next/eslint-plugin-next@15.1.7: + resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} + dependencies: + fast-glob: 3.3.1 + dev: true + + /@next/swc-darwin-arm64@15.1.7: + resolution: {integrity: sha512-hPFwzPJDpA8FGj7IKV3Yf1web3oz2YsR8du4amKw8d+jAOHfYHYFpMkoF6vgSY4W6vB29RtZEklK9ayinGiCmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-arm64@15.3.0: + resolution: {integrity: sha512-PDQcByT0ZfF2q7QR9d+PNj3wlNN4K6Q8JoHMwFyk252gWo4gKt7BF8Y2+KBgDjTFBETXZ/TkBEUY7NIIY7A/Kw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@15.1.7: + resolution: {integrity: sha512-2qoas+fO3OQKkU0PBUfwTiw/EYpN+kdAx62cePRyY1LqKtP09Vp5UcUntfZYajop5fDFTjSxCHfZVRxzi+9FYQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@15.3.0: + resolution: {integrity: sha512-m+eO21yg80En8HJ5c49AOQpFDq+nP51nu88ZOMCorvw3g//8g1JSUsEiPSiFpJo1KCTQ+jm9H0hwXK49H/RmXg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@15.1.7: + resolution: {integrity: sha512-sKLLwDX709mPdzxMnRIXLIT9zaX2w0GUlkLYQnKGoXeWUhcvpCrK+yevcwCJPdTdxZEUA0mOXGLdPsGkudGdnA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@15.3.0: + resolution: {integrity: sha512-H0Kk04ZNzb6Aq/G6e0un4B3HekPnyy6D+eUBYPJv9Abx8KDYgNMWzKt4Qhj57HXV3sTTjsfc1Trc1SxuhQB+Tg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@15.1.7: + resolution: {integrity: sha512-zblK1OQbQWdC8fxdX4fpsHDw+VSpBPGEUX4PhSE9hkaWPrWoeIJn+baX53vbsbDRaDKd7bBNcXRovY1hEhFd7w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@15.3.0: + resolution: {integrity: sha512-k8GVkdMrh/+J9uIv/GpnHakzgDQhrprJ/FbGQvwWmstaeFG06nnAoZCJV+wO/bb603iKV1BXt4gHG+s2buJqZA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@15.1.7: + resolution: {integrity: sha512-GOzXutxuLvLHFDAPsMP2zDBMl1vfUHHpdNpFGhxu90jEzH6nNIgmtw/s1MDwpTOiM+MT5V8+I1hmVFeAUhkbgQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@15.3.0: + resolution: {integrity: sha512-ZMQ9yzDEts/vkpFLRAqfYO1wSpIJGlQNK9gZ09PgyjBJUmg8F/bb8fw2EXKgEaHbCc4gmqMpDfh+T07qUphp9A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@15.1.7: + resolution: {integrity: sha512-WrZ7jBhR7ATW1z5iEQ0ZJfE2twCNSXbpCSaAunF3BKcVeHFADSI/AW1y5Xt3DzTqPF1FzQlwQTewqetAABhZRQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@15.3.0: + resolution: {integrity: sha512-RFwq5VKYTw9TMr4T3e5HRP6T4RiAzfDJ6XsxH8j/ZeYq2aLsBqCkFzwMI0FmnSsLaUbOb46Uov0VvN3UciHX5A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@15.1.7: + resolution: {integrity: sha512-LDnj1f3OVbou1BqvvXVqouJZKcwq++mV2F+oFHptToZtScIEnhNRJAhJzqAtTE2dB31qDYL45xJwrc+bLeKM2Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@15.3.0: + resolution: {integrity: sha512-a7kUbqa/k09xPjfCl0RSVAvEjAkYBYxUzSVAzk2ptXiNEL+4bDBo9wNC43G/osLA/EOGzG4CuNRFnQyIHfkRgQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@15.1.7: + resolution: {integrity: sha512-dC01f1quuf97viOfW05/K8XYv2iuBgAxJZl7mbCKEjMgdQl5JjAKJ0D2qMKZCgPWDeFbFT0Q0nYWwytEW0DWTQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@15.3.0: + resolution: {integrity: sha512-vHUQS4YVGJPmpjn7r5lEZuMhK5UQBNBRSB+iGDvJjaNk649pTIcRluDWNb9siunyLLiu/LDPHfvxBtNamyuLTw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + /@nolyfill/is-core-module@1.0.39: + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + dev: true + + /@petamoriken/float16@3.9.2: + resolution: {integrity: sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==} + dev: false + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + optional: true + + /@radix-ui/number@1.1.0: + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + dev: false + + /@radix-ui/primitive@1.1.1: + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + dev: false + + /@radix-ui/react-accordion@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collapsible': 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-collapsible@1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-context@1.1.1(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-dialog@1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-direction@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-icons@1.3.2(react@18.3.1): + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^18.3.1 + dependencies: + react: 18.3.1 + dev: false + + /@radix-ui/react-id@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-label@2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-menu@2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/rect': 1.1.0 + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-progress@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-scroll-area@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-select@2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-separator@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-slider@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-nNrLAWLjGESnhqBqcCNW4w2nn7LxudyMzeB6VgdyAnFLC6kfQgnAjSL2v6UkQTnDctJBlxrmxfplWS4iYjdUTw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-slot@1.1.2(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-switch@1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-tabs@1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-tooltip@1.1.8(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-previous@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-rect@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/rect': 1.1.0 + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-size@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/rect@1.1.0: + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + dev: false + + /@react-dnd/asap@5.0.2: + resolution: {integrity: sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==} + dev: false + + /@react-dnd/invariant@4.0.2: + resolution: {integrity: sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==} + dev: false + + /@react-dnd/shallowequal@4.0.2: + resolution: {integrity: sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==} + dev: false + + /@rollup/pluginutils@5.1.4: + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + dev: true + + /@rollup/rollup-android-arm-eabi@4.34.8: + resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-android-arm64@4.34.8: + resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-arm64@4.34.8: + resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-x64@4.34.8: + resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-freebsd-arm64@4.34.8: + resolution: {integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + optional: true + + /@rollup/rollup-freebsd-x64@4.34.8: + resolution: {integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==} + cpu: [x64] + os: [freebsd] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.34.8: + resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.34.8: + resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.34.8: + resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.34.8: + resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-loongarch64-gnu@4.34.8: + resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==} + cpu: [loong64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-powerpc64le-gnu@4.34.8: + resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.34.8: + resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.34.8: + resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.34.8: + resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.34.8: + resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.34.8: + resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.34.8: + resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.34.8: + resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /@rtsao/scc@1.1.0: + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + dev: true + + /@rushstack/eslint-patch@1.10.5: + resolution: {integrity: sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==} + dev: true + + /@sindresorhus/merge-streams@2.3.0: + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + dev: true + + /@standard-schema/utils@0.3.0: + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + dev: false + + /@storybook/addon-actions@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-lI03stcI28wN8trjp7zx0PzN1NRxSpU/551slzEhSM0tghcLxcfLZR/wh4Jp0T68Obj7z//YXPttZ9PBFajs6w==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 8.6.0(prettier@3.5.2) + uuid: 9.0.1 + dev: true + + /@storybook/addon-backgrounds@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-MbMPjuC19jJBXqQext8rENBACLKujDn+MuxIbNYMmn2ljzeYFp87tVxzlCB7XY7rV0zvkHxH8N/zDnPl7pBTcQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-controls@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-oc+mssxmNY+D26jyJ+IZ1u8bmzveCO2wqpUl6vtLM5MruchZAHzHqa2ZIn+H9KOEqcKlYVDF5n6oEuprcnrsdg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + dequal: 2.0.3 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-docs@8.6.0(@types/react@18.3.18)(storybook@8.6.0): + resolution: {integrity: sha512-ytYn5ec2Tp62t9emjXgm4Ds+eG7SiSg/vNeOwM6L1lM2UCV2/XdzntbqlUb/FHehSXIv9eRJDSe5BBzPieUUaw==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@mdx-js/react': 3.1.0(@types/react@18.3.18)(react@18.3.1) + '@storybook/blocks': 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/csf-plugin': 8.6.0(storybook@8.6.0) + '@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@storybook/addon-essentials@8.6.0(@types/react@18.3.18)(storybook@8.6.0): + resolution: {integrity: sha512-T3R9Q1hq6eJKy758gQgYEuAYxcddGZ8eGBLIyIJEgzpwsUnN5mF+rIqx8LoWxpWu/xiKzg17LqCBnJbLGkRZUA==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/addon-actions': 8.6.0(storybook@8.6.0) + '@storybook/addon-backgrounds': 8.6.0(storybook@8.6.0) + '@storybook/addon-controls': 8.6.0(storybook@8.6.0) + '@storybook/addon-docs': 8.6.0(@types/react@18.3.18)(storybook@8.6.0) + '@storybook/addon-highlight': 8.6.0(storybook@8.6.0) + '@storybook/addon-measure': 8.6.0(storybook@8.6.0) + '@storybook/addon-outline': 8.6.0(storybook@8.6.0) + '@storybook/addon-toolbars': 8.6.0(storybook@8.6.0) + '@storybook/addon-viewport': 8.6.0(storybook@8.6.0) + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@storybook/addon-highlight@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-xgSUzNV8ZpNDJ35bLz7wfg/q7/O/C5845wbZsn+PobUOWpOMOKeZwbGkO3Fh4+CWKeFuMhUpFiZSWkNgT+bV0g==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/addon-interactions@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-AgobFrUxmKgGHKeOismuLZdXlndP3ZDquHztiomfMiu01xOqNPxG0+xoCcegvftU7hKE+TlBRzhjCWg/bFz4LQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.0(storybook@8.6.0) + '@storybook/test': 8.6.0(storybook@8.6.0) + polished: 4.3.1 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-measure@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-ogc+VNLyXq8hGfI4Fkmh9i3JbxfiIViiINdBoldD6K0gId3yaqqrSwQ2vWhYIbfUuz+PsMxsoNS7MD4EiRXhPg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.0(prettier@3.5.2) + tiny-invariant: 1.3.3 + dev: true + + /@storybook/addon-onboarding@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-UOOvYQlHKdY31YJwR+ECX7e/BNuhp4alcJmx1fuI7m6tXqTGLtioeMJEreh2jV3FDaaDqL4DL/1UfYXqNRMp+A==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/addon-outline@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-IWxrNNZOk5rtOdnLNyK7gpqi0g0rMGYl5ju37Glbfa7iG2J1VKofG2CbkUpVyVY0uiTXqkKkhOKlc9zELhLQSg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-themes@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-dKUjFgHP9Fd2fxrXcUUjev5X3cGqVvVogzh+nCRA/QlZgf3NzA8J2VPtqtFMX3ex+vaozGsrEKrk+LQTK1B7SA==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-toolbars@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-Mg0V9RrnDt/IQe+zjggGS+4Otkv4YFqyjL/ygwnV6aKGgzL5zFpC+5rf8MeBEvNeol9+THC/XltN/Xf+jbtLEQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/addon-viewport@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-sVDF3gIjGdvfBdCM/jEBu6Nd5GlqITKBtdySiQdNDl5JI4ak77ZM+T+VQmJxB4sIqvCjWzCbQqUC45nymVObug==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + memoizerific: 1.11.3 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/blocks@8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0): + resolution: {integrity: sha512-3PNxlB5Ooj8CIhttbDxeV6kW7ui+2GEdTngtqhnsUHVjzeTKpilsk2lviOeUzqlyq5FDK+rhpZ3L3DJ9pDvioA==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/icons': 1.3.2(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/builder-vite@8.6.0(storybook@8.6.0)(vite@6.2.0): + resolution: {integrity: sha512-Bdc5fXLJbPdQo2eJ3dDNhfhWuQOME2KWvrixnsfo57IOhDa5B81jVcDBQIIgB9K1NQDRGyaWfYCcKZqy16yPlQ==} + peerDependencies: + storybook: ^8.6.0 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + dependencies: + '@storybook/csf-plugin': 8.6.0(storybook@8.6.0) + browser-assert: 1.2.1 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + vite: 6.2.0(@types/node@22.13.9) + dev: true + + /@storybook/components@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-k5MQAuLPt5KOaa5J4QvX/WKucaiFTMJiEX5lsSaY6qON6Sx8PtnLQxVwWF7BIMW/jLpd94BUxrVjVrQKlwoLKQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/core@8.6.0(prettier@3.5.2)(storybook@8.6.0): + resolution: {integrity: sha512-UzVo2sNz8PZuDp++/R9NBtjupSXhvxS8lptYcwtk51b6MvcM4AL/b4V3PGryOVJDru9sMwz+pzaj7Jg8RVFMJA==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + dependencies: + '@storybook/theming': 8.6.0(storybook@8.6.0) + better-opn: 3.0.2 + browser-assert: 1.2.1 + esbuild: 0.25.0 + esbuild-register: 3.6.0(esbuild@0.25.0) + jsdoc-type-pratt-parser: 4.1.0 + prettier: 3.5.2 + process: 0.11.10 + recast: 0.23.10 + semver: 7.7.1 + util: 0.12.5 + ws: 8.18.1 + transitivePeerDependencies: + - bufferutil + - storybook + - supports-color + - utf-8-validate + dev: true + + /@storybook/csf-plugin@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-Cd7LL4XQ8ccUDzJGxVyuzgsYuRYS5LVL4/ZNmAxikz9LtVrVFI/4RgFa5MvlQZc0twreoLtztFskziny8OiJUQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + unplugin: 1.16.1 + dev: true + + /@storybook/csf@0.1.13: + resolution: {integrity: sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==} + dependencies: + type-fest: 2.19.0 + dev: true + + /@storybook/global@5.0.0: + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + dev: true + + /@storybook/icons@1.3.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-t3xcbCKkPvqyef8urBM0j/nP6sKtnlRkVgC+8JTbTAZQjaTmOjes3byEgzs89p4B/K6cJsg9wLW2k3SknLtYJw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: true + + /@storybook/instrumenter@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-eEY/Hfa3Vj5Nv4vHRHlSqjoyW6oAKNK3rKIXfL/eawQwb7rKhzijDLG5YBH44Hh7dEPIqUp0LEdgpyIY7GXezg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.9 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/manager-api@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-ddBibYrO3yQCdtZBqQYqfABjR9eS+llvt2NFDajfyQw+zmuNIZfw4BDGKH1WHE4wm/kXmlFFhPHXaHgAPTRPfQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/preview-api@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-c/sZj4Tb+DtdCndcjoFUneUwl2XUdQckqN4nf1SuIJ/BXRbAexlD04fvPJ4wzmwUNg8EQF7BhTWVNDa1RvJz2w==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/react-dom-shim@8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0): + resolution: {integrity: sha512-5Y+vMHhcx0xnaNsLQMbkmjc3zkDn/fGBNsiLH2e4POvW3ZQvOxjoyxAsEQaKwLtFgsdCFSd2tR89F6ItYrA2JQ==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/react-vite@8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3)(vite@6.2.0): + resolution: {integrity: sha512-uDQyf2u0Zki4qIavOu2jyGIlvmUOsgCpHXY+7KHr542ZIkXI3mGOi5/rwUxgNSHGD3JloYGdlt+4Md+9i5xEbA==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.6.0 + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + '@storybook/test': + optional: true + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.6.3)(vite@6.2.0) + '@rollup/pluginutils': 5.1.4 + '@storybook/builder-vite': 8.6.0(storybook@8.6.0)(vite@6.2.0) + '@storybook/react': 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3) + '@storybook/test': 8.6.0(storybook@8.6.0) + find-up: 5.0.0 + magic-string: 0.30.17 + react: 18.3.1 + react-docgen: 7.1.1 + react-dom: 18.3.1(react@18.3.1) + resolve: 1.22.10 + storybook: 8.6.0(prettier@3.5.2) + tsconfig-paths: 4.2.0 + vite: 6.2.0(@types/node@22.13.9) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + dev: true + + /@storybook/react@8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3): + resolution: {integrity: sha512-go0KhCFcOhxkTdaMCxeuJxmc/5CaiaO76+SBzIoPIMWEh9tZQmKb+vojdKcFZswHjZV3zA1uJFUzyympspRffA==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.6.0 + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + typescript: '>= 4.2.x' + peerDependenciesMeta: + '@storybook/test': + optional: true + typescript: + optional: true + dependencies: + '@storybook/components': 8.6.0(storybook@8.6.0) + '@storybook/global': 5.0.0 + '@storybook/manager-api': 8.6.0(storybook@8.6.0) + '@storybook/preview-api': 8.6.0(storybook@8.6.0) + '@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/test': 8.6.0(storybook@8.6.0) + '@storybook/theming': 8.6.0(storybook@8.6.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + typescript: 5.6.3 + dev: true + + /@storybook/test@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-qiiv4wh4FoxTb1PoiA/noo9HcLDqfTwL0svMoNpTy2Bxm6xajgg5zYmmIT4pKyQkMd9pfKKQKILok31VxAj8vw==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.0(storybook@8.6.0) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/theming@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-te7dl0ZXnEyKS4LW+QHc3MP7nurWhWhmClY7G2WKNW9eHenb9zvXkcAQt6c4OWhrJi01CAYoXmZNJP0jEzxRRQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.15: + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + dependencies: + tslib: 2.8.1 + dev: false + + /@tailwindcss/node@4.1.11: + resolution: {integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==} + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.5.1 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.11 + dev: false + + /@tailwindcss/oxide-android-arm64@4.1.11: + resolution: {integrity: sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-darwin-arm64@4.1.11: + resolution: {integrity: sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-darwin-x64@4.1.11: + resolution: {integrity: sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-freebsd-x64@4.1.11: + resolution: {integrity: sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11: + resolution: {integrity: sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-arm64-gnu@4.1.11: + resolution: {integrity: sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-arm64-musl@4.1.11: + resolution: {integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-x64-gnu@4.1.11: + resolution: {integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-x64-musl@4.1.11: + resolution: {integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-wasm32-wasi@4.1.11: + resolution: {integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + requiresBuild: true + dev: false + optional: true + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + /@tailwindcss/oxide-win32-arm64-msvc@4.1.11: + resolution: {integrity: sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-win32-x64-msvc@4.1.11: + resolution: {integrity: sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide@4.1.11: + resolution: {integrity: sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.11 + '@tailwindcss/oxide-darwin-arm64': 4.1.11 + '@tailwindcss/oxide-darwin-x64': 4.1.11 + '@tailwindcss/oxide-freebsd-x64': 4.1.11 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.11 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.11 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.11 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.11 + '@tailwindcss/oxide-linux-x64-musl': 4.1.11 + '@tailwindcss/oxide-wasm32-wasi': 4.1.11 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.11 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.11 + dev: false + + /@tailwindcss/vite@4.1.11(vite@6.2.0): + resolution: {integrity: sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + dependencies: + '@tailwindcss/node': 4.1.11 + '@tailwindcss/oxide': 4.1.11 + tailwindcss: 4.1.11 + vite: 6.2.0(@types/node@22.13.9) + dev: false + + /@tanstack/query-core@5.67.1: + resolution: {integrity: sha512-AkFmuukVejyqVIjEQoFhLb3q+xHl7JG8G9cANWTMe3s8iKzD9j1VBSYXgCjy6vm6xM8cUCR9zP2yqWxY9pTWOA==} + dev: false + + /@tanstack/query-devtools@5.74.7: + resolution: {integrity: sha512-nSNlfuGdnHf4yB0S+BoNYOE1o3oAH093weAYZolIHfS2stulyA/gWfSk/9H4ZFk5mAAHb5vNqAeJOmbdcGPEQw==} + dev: false + + /@tanstack/react-query-devtools@5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1): + resolution: {integrity: sha512-S31U00nJOQIbxydRH1kOwdLRaLBrda8O5QjzmgkRg60UZzPGdbI6+873Qa0YGUfPeILDbR2ukgWyg7CJQPy4iA==} + peerDependencies: + '@tanstack/react-query': ^5.75.5 + react: ^18.3.1 + dependencies: + '@tanstack/query-devtools': 5.74.7 + '@tanstack/react-query': 5.67.1(react@18.3.1) + react: 18.3.1 + dev: false + + /@tanstack/react-query@5.67.1(react@18.3.1): + resolution: {integrity: sha512-fH5u4JLwB6A+wLFdi8wWBWAYoJV5deYif2OveJ26ktAWjU499uvVFS1wPWnyEyq5LvZX1MZInvv9QRaIZANRaQ==} + peerDependencies: + react: ^18.3.1 + dependencies: + '@tanstack/query-core': 5.67.1 + react: 18.3.1 + dev: false + + /@tanstack/react-table@8.21.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==} + engines: {node: '>=12'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@tanstack/table-core': 8.21.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@tanstack/table-core@8.21.2: + resolution: {integrity: sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==} + engines: {node: '>=12'} + dev: false + + /@testing-library/dom@10.4.0: + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.9 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + dev: true + + /@testing-library/jest-dom@6.5.0: + resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + dependencies: + '@adobe/css-tools': 4.4.2 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + dev: true + + /@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0): + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + dependencies: + '@testing-library/dom': 10.4.0 + dev: true + + /@tinymce/tinymce-react@6.1.0(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-K0MP3yYVKe8+etUwsg6zyRq+q9TGLaVf005WiBHiB8JZEomAwbBPERGunhU9uOqNQ5gJs8yVOPZ68Xcd1UHclA==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + tinymce: ^7.0.0 || ^6.0.0 || ^5.5.1 + peerDependenciesMeta: + tinymce: + optional: true + dependencies: + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@types/aria-query@5.0.4: + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + dev: true + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + dev: true + + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.26.9 + dev: true + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + dev: true + + /@types/babel__traverse@7.20.6: + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + dependencies: + '@babel/types': 7.26.9 + dev: true + + /@types/d3-array@3.2.1: + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + dev: false + + /@types/d3-color@3.1.3: + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + dev: false + + /@types/d3-ease@3.0.2: + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + dev: false + + /@types/d3-interpolate@3.0.4: + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + dependencies: + '@types/d3-color': 3.1.3 + dev: false + + /@types/d3-path@3.1.1: + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + dev: false + + /@types/d3-scale@4.0.9: + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + dependencies: + '@types/d3-time': 3.0.4 + dev: false + + /@types/d3-shape@3.1.7: + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + dependencies: + '@types/d3-path': 3.1.1 + dev: false + + /@types/d3-time@3.0.4: + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + dev: false + + /@types/d3-timer@3.0.2: + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + dev: false + + /@types/doctrine@0.0.9: + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + dev: true + + /@types/eslint-scope@3.7.7: + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.6 + + /@types/eslint@9.6.1: + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + dependencies: + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + + /@types/estree@1.0.6: + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + /@types/js-cookie@3.0.6: + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/mdx@2.0.13: + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + dev: true + + /@types/node@20.17.19: + resolution: {integrity: sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==} + dependencies: + undici-types: 6.19.8 + dev: true + + /@types/node@22.13.5: + resolution: {integrity: sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==} + dependencies: + undici-types: 6.20.0 + + /@types/node@22.13.9: + resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==} + dependencies: + undici-types: 6.20.0 + + /@types/prop-types@15.7.14: + resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + + /@types/react-dom@18.3.5(@types/react@18.3.18): + resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + peerDependencies: + '@types/react': ^18.3.18 + dependencies: + '@types/react': 18.3.18 + + /@types/react@18.3.18: + resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + + /@types/resolve@1.20.6: + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + dev: true + + /@types/uuid@9.0.8: + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + dev: true + + /@types/webpack@5.28.5: + resolution: {integrity: sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw==} + dependencies: + '@types/node': 22.13.9 + tapable: 2.2.1 + webpack: 5.98.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + - webpack-cli + dev: true + + /@typescript-eslint/eslint-plugin@8.25.0(@typescript-eslint/parser@8.25.0)(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/type-utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.25.0 + eslint: 9.21.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.0.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + eslint: 9.21.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@8.25.0: + resolution: {integrity: sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + dev: true + + /@typescript-eslint/type-utils@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + debug: 4.4.0 + eslint: 9.21.0 + ts-api-utils: 2.0.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@8.25.0: + resolution: {integrity: sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@typescript-eslint/typescript-estree@8.25.0(typescript@5.6.3): + resolution: {integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree@8.25.0(typescript@5.7.3): + resolution: {integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.6.3) + eslint: 9.21.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/visitor-keys@8.25.0: + resolution: {integrity: sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@typescript-eslint/types': 8.25.0 + eslint-visitor-keys: 4.2.0 + dev: true + + /@vitejs/plugin-react@4.3.4(vite@6.2.0): + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + dependencies: + '@babel/core': 7.26.9 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 6.2.0(@types/node@22.13.9) + transitivePeerDependencies: + - supports-color + dev: true + + /@vitest/expect@2.0.5: + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.2.0 + tinyrainbow: 1.2.0 + dev: true + + /@vitest/pretty-format@2.0.5: + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + dependencies: + tinyrainbow: 1.2.0 + dev: true + + /@vitest/pretty-format@2.1.9: + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + dependencies: + tinyrainbow: 1.2.0 + dev: true + + /@vitest/spy@2.0.5: + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + dependencies: + tinyspy: 3.0.2 + dev: true + + /@vitest/utils@2.0.5: + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + dev: true + + /@vitest/utils@2.1.9: + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + dev: true + + /@vue/compiler-core@3.5.13: + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + dependencies: + '@babel/parser': 7.26.9 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-dom@3.5.13: + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + dev: true + + /@vue/compiler-sfc@3.5.13: + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + dependencies: + '@babel/parser': 7.26.9 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.3 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-ssr@3.5.13: + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + dev: true + + /@vue/shared@3.5.13: + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + dev: true + + /@webassemblyjs/ast@1.14.1: + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + /@webassemblyjs/floating-point-hex-parser@1.13.2: + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + /@webassemblyjs/helper-api-error@1.13.2: + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + /@webassemblyjs/helper-buffer@1.14.1: + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + /@webassemblyjs/helper-numbers@1.13.2: + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + /@webassemblyjs/helper-wasm-bytecode@1.13.2: + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + /@webassemblyjs/helper-wasm-section@1.14.1: + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + /@webassemblyjs/ieee754@1.13.2: + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + dependencies: + '@xtuc/ieee754': 1.2.0 + + /@webassemblyjs/leb128@1.13.2: + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + dependencies: + '@xtuc/long': 4.2.2 + + /@webassemblyjs/utf8@1.13.2: + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + /@webassemblyjs/wasm-edit@1.14.1: + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + /@webassemblyjs/wasm-gen@1.14.1: + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + /@webassemblyjs/wasm-opt@1.14.1: + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + /@webassemblyjs/wasm-parser@1.14.1: + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + /@webassemblyjs/wast-printer@1.14.1: + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + /@xlsx/xlsx-populate@0.0.8: + resolution: {integrity: sha512-6yu24ePaO3cnAuti77FhVPZvKkzUt6s6x3zJ9wiuBSjR0ImWu7l/SgePelZaf8Oty4SP4rg4vznQVCGQtfzu2A==} + engines: {node: '>=16'} + dev: true + + /@xtuc/ieee754@1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + /@xtuc/long@4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + /acorn-jsx@5.3.2(acorn@8.14.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.14.0 + dev: true + + /acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + /adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + dev: false + + /ajv-formats@2.1.1(ajv@8.17.1): + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.17.1 + + /ajv-keywords@5.1.0(ajv@8.17.1): + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + dependencies: + tslib: 2.8.1 + dev: false + + /aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + dependencies: + dequal: 2.0.3 + dev: true + + /aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + dev: true + + /array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + is-array-buffer: 3.0.5 + dev: true + + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + dev: true + + /array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + dev: true + + /arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + dev: true + + /assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + dev: true + + /ast-module-types@6.0.1: + resolution: {integrity: sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==} + engines: {node: '>=18'} + dev: true + + /ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + dev: true + + /ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.8.1 + dev: true + + /async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + dev: true + + /async-wave@1.8.6: + resolution: {integrity: sha512-wqWvr0Mrc1TrY92hN9MV0Xebxa6kt+T7QtjZ7FEMv+RUBa/Hfpz/UOgz0rB+7uqVK8TuBSXykOyU/k9gogdLkw==} + dependencies: + is-promise: 4.0.0 + lodash.add: 3.7.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + lodash.isfunction: 3.0.9 + lodash.size: 4.2.0 + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /attr-accept@2.2.5: + resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==} + engines: {node: '>=4'} + dev: false + + /autoprefixer@10.4.20(postcss@8.5.3): + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.24.4 + caniuse-lite: 1.0.30001701 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + dev: true + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.1.0 + dev: true + + /axe-core@4.10.2: + resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==} + engines: {node: '>=4'} + dev: true + + /axios@1.8.1: + resolution: {integrity: sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /base64-arraybuffer@1.0.2: + resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} + engines: {node: '>= 0.6.0'} + dev: false + + /better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + dependencies: + open: 8.4.2 + dev: true + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + + /browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + dev: true + + /browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001701 + electron-to-chromium: 1.5.107 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.4) + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + /bundle-require@5.1.0(esbuild@0.24.2): + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + dependencies: + esbuild: 0.24.2 + load-tsconfig: 0.2.5 + dev: true + + /busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + /call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + dev: true + + /call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: false + + /caniuse-lite@1.0.30001701: + resolution: {integrity: sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==} + + /cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + dev: false + + /chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + dev: true + + /chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chart.js@4.4.8: + resolution: {integrity: sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==} + engines: {pnpm: '>=8'} + dependencies: + '@kurkle/color': 0.3.4 + dev: false + + /check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + dev: true + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + /chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + dependencies: + readdirp: 4.1.2 + dev: true + + /chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + dev: false + + /chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + /class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + dependencies: + clsx: 2.1.1 + dev: false + + /client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: false + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: false + + /codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + requiresBuild: true + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + optional: true + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + requiresBuild: true + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: false + optional: true + + /combine-errors@3.0.3: + resolution: {integrity: sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==} + dependencies: + custom-error-instance: 2.1.1 + lodash.uniqby: 4.5.0 + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: false + + /cosmiconfig@9.0.0(typescript@5.6.3): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 5.6.3 + dev: true + + /crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + dev: false + + /cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /css-line-break@2.1.0: + resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==} + dependencies: + utrie: 1.0.2 + dev: false + + /css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true + + /csscolorparser@1.0.3: + resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==} + dev: false + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + /custom-error-instance@2.1.1: + resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} + dev: false + + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + dev: false + + /d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + + /damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + + /data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /date-fns-jalali@4.1.0-0: + resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==} + dev: false + + /date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + dev: false + + /date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + dev: false + + /dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + dev: false + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: false + + /decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + dev: false + + /deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: true + + /define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + requiresBuild: true + dev: false + + /detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + dev: false + + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + + /detective-amd@6.0.1: + resolution: {integrity: sha512-TtyZ3OhwUoEEIhTFoc1C9IyJIud3y+xYkSRjmvCt65+ycQuc3VcBrPRTMWoO/AnuCyOB8T5gky+xf7Igxtjd3g==} + engines: {node: '>=18'} + hasBin: true + dependencies: + ast-module-types: 6.0.1 + escodegen: 2.1.0 + get-amd-module-type: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /detective-cjs@6.0.1: + resolution: {integrity: sha512-tLTQsWvd2WMcmn/60T2inEJNhJoi7a//PQ7DwRKEj1yEeiQs4mrONgsUtEJKnZmrGWBBmE0kJ1vqOG/NAxwaJw==} + engines: {node: '>=18'} + dependencies: + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /detective-es6@5.0.1: + resolution: {integrity: sha512-XusTPuewnSUdoxRSx8OOI6xIA/uld/wMQwYsouvFN2LAg7HgP06NF1lHRV3x6BZxyL2Kkoih4ewcq8hcbGtwew==} + engines: {node: '>=18'} + dependencies: + node-source-walk: 7.0.1 + dev: true + + /detective-postcss@7.0.1(postcss@8.5.3): + resolution: {integrity: sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==} + engines: {node: ^14.0.0 || >=16.0.0} + peerDependencies: + postcss: ^8.4.47 + dependencies: + is-url: 1.2.4 + postcss: 8.5.3 + postcss-values-parser: 6.0.2(postcss@8.5.3) + dev: true + + /detective-sass@6.0.1: + resolution: {integrity: sha512-jSGPO8QDy7K7pztUmGC6aiHkexBQT4GIH+mBAL9ZyBmnUIOFbkfZnO8wPRRJFP/QP83irObgsZHCoDHZ173tRw==} + engines: {node: '>=18'} + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.1 + dev: true + + /detective-scss@5.0.1: + resolution: {integrity: sha512-MAyPYRgS6DCiS6n6AoSBJXLGVOydsr9huwXORUlJ37K3YLyiN0vYHpzs3AdJOgHobBfispokoqrEon9rbmKacg==} + engines: {node: '>=18'} + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.1 + dev: true + + /detective-stylus@5.0.1: + resolution: {integrity: sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==} + engines: {node: '>=18'} + dev: true + + /detective-typescript@14.0.0(typescript@5.7.3): + resolution: {integrity: sha512-pgN43/80MmWVSEi5LUuiVvO/0a9ss5V7fwVfrJ4QzAQRd3cwqU1SfWGXJFcNKUqoD5cS+uIovhw5t/0rSeC5Mw==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 + dependencies: + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /detective-vue2@2.2.0(typescript@5.7.3): + resolution: {integrity: sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 + dependencies: + '@dependents/detective-less': 5.0.1 + '@vue/compiler-sfc': 3.5.13 + detective-es6: 5.0.1 + detective-sass: 6.0.1 + detective-scss: 5.0.1 + detective-stylus: 5.0.1 + detective-typescript: 14.0.0(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + /dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dev: false + + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + /dnd-core@16.0.1: + resolution: {integrity: sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==} + dependencies: + '@react-dnd/asap': 5.0.2 + '@react-dnd/invariant': 4.0.2 + redux: 4.2.1 + dev: false + + /dnd-multi-backend@8.1.2(dnd-core@16.0.1): + resolution: {integrity: sha512-KPDVEsiM+6gNEegqZYTWJQgJxYV4vB91tUrvoKJjaS0wwWqT/jNU0P7xJAwCue/cbasJNvk2dFZH7tC+bjX1Rg==} + peerDependencies: + dnd-core: ^16.0.1 + dependencies: + dnd-core: 16.0.1 + dev: false + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dev: true + + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: true + + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.26.9 + csstype: 3.1.3 + dev: false + + /dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + /earcut@2.2.4: + resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + dev: false + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + /effector@23.3.0: + resolution: {integrity: sha512-ZnQ3POaNARlxT9+kxrK58PO/xmStBdxfPq0rceglENg8Ryxx/yx+1RsV/ziznrFPhLkZYc7NdDA1OKxnMW98/g==} + engines: {node: '>=11.0.0'} + dev: true + + /electron-to-chromium@1.5.107: + resolution: {integrity: sha512-dJr1o6yCntRkXElnhsHh1bAV19bo/hKyFf7tCcWgpXbuFIF0Lakjgqv5LRfSDaNzAII8Fnxg2tqgHkgCvxdbxw==} + + /embla-carousel-react@8.6.0(react@18.3.1): + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^18.3.1 + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 18.3.1 + dev: false + + /embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + dependencies: + embla-carousel: 8.6.0 + dev: false + + /embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + /empathic@1.0.0: + resolution: {integrity: sha512-qtKgI1Mv8rTacvpaTkh28HM2Lbf+IOjXb7rhpt/42kZxRm8TBb/IVlo5iL2ztT19kc/EHAFN0fZ641avlXAgdg==} + engines: {node: '>=16'} + dev: true + + /enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: true + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.18 + dev: true + + /es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + /es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + dev: true + + /es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + + /es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + + /es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + /es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + dev: true + + /es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + dev: true + + /esbuild-register@3.6.0(esbuild@0.25.0): + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.4.0 + esbuild: 0.25.0 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + dev: true + + /esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + dev: true + + /esbuild@0.25.0: + resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.0 + '@esbuild/android-arm': 0.25.0 + '@esbuild/android-arm64': 0.25.0 + '@esbuild/android-x64': 0.25.0 + '@esbuild/darwin-arm64': 0.25.0 + '@esbuild/darwin-x64': 0.25.0 + '@esbuild/freebsd-arm64': 0.25.0 + '@esbuild/freebsd-x64': 0.25.0 + '@esbuild/linux-arm': 0.25.0 + '@esbuild/linux-arm64': 0.25.0 + '@esbuild/linux-ia32': 0.25.0 + '@esbuild/linux-loong64': 0.25.0 + '@esbuild/linux-mips64el': 0.25.0 + '@esbuild/linux-ppc64': 0.25.0 + '@esbuild/linux-riscv64': 0.25.0 + '@esbuild/linux-s390x': 0.25.0 + '@esbuild/linux-x64': 0.25.0 + '@esbuild/netbsd-arm64': 0.25.0 + '@esbuild/netbsd-x64': 0.25.0 + '@esbuild/openbsd-arm64': 0.25.0 + '@esbuild/openbsd-x64': 0.25.0 + '@esbuild/sunos-x64': 0.25.0 + '@esbuild/win32-arm64': 0.25.0 + '@esbuild/win32-ia32': 0.25.0 + '@esbuild/win32-x64': 0.25.0 + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-config-next@15.1.7(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-zXoMnYUIy3XHaAoOhrcYkT9UQWvXqWju2K7NNsmb5wd/7XESDwof61eUdW4QhERr3eJ9Ko/vnXqIrj8kk/drYw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@next/eslint-plugin-next': 15.1.7 + '@rushstack/eslint-patch': 1.10.5 + '@typescript-eslint/eslint-plugin': 8.25.0(@typescript-eslint/parser@8.25.0)(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + eslint: 9.21.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@9.21.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.21.0) + eslint-plugin-react: 7.37.4(eslint@9.21.0) + eslint-plugin-react-hooks: 5.1.0(eslint@9.21.0) + typescript: 5.6.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.21.0): + resolution: {integrity: sha512-A0bu4Ks2QqDWNpeEgTQMPTngaMhuDu4yv6xpftBMAf+1ziXnpx+eSR1WRfoPTe2BAiAjHFZ7kSNx1fvr5g5pmQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.0 + enhanced-resolve: 5.18.1 + eslint: 9.21.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0) + get-tsconfig: 4.10.0 + is-bun-module: 1.3.0 + stable-hash: 0.0.4 + tinyglobby: 0.2.12 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.12.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0): + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + debug: 3.2.7 + eslint: 9.21.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@9.21.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0): + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@rtsao/scc': 1.1.0 + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.21.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jsx-a11y@6.10.2(eslint@9.21.0): + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.2 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.21.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + dev: true + + /eslint-plugin-react-hooks@5.1.0(eslint@9.21.0): + resolution: {integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + dependencies: + eslint: 9.21.0 + dev: true + + /eslint-plugin-react-refresh@0.4.19(eslint@9.21.0): + resolution: {integrity: sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==} + peerDependencies: + eslint: '>=8.40' + dependencies: + eslint: 9.21.0 + dev: true + + /eslint-plugin-react@7.37.4(eslint@9.21.0): + resolution: {integrity: sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.21.0 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + dev: true + + /eslint-plugin-storybook@0.11.3(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-gDBnBZiyk4ZG7OMSJRaHBcuJ8TMCXgMIQ3HB/XvtN0SvSio2ZOIeYD3yGj39g/DbyCe/Bg02j/ip9tWlDEs82A==} + engines: {node: '>= 18'} + peerDependencies: + eslint: '>=8' + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@storybook/csf': 0.1.13 + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + eslint: 9.21.0 + ts-dedent: 2.2.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + /eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /eslint@9.21.0: + resolution: {integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.0 + '@eslint/js': 9.21.0 + '@eslint/plugin-kit': 0.2.7 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.6 + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-equals@5.2.2: + resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} + engines: {node: '>=6.0.0'} + dev: false + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + dev: true + + /fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + /fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + dev: true + + /fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + dependencies: + reusify: 1.1.0 + + /fdir@6.4.3(picomatch@4.0.2): + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + dependencies: + picomatch: 4.0.2 + dev: true + + /file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + dependencies: + flat-cache: 4.0.1 + dev: true + + /file-selector@2.1.2: + resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} + engines: {node: '>= 12'} + dependencies: + tslib: 2.8.1 + dev: false + + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: false + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + dev: true + + /flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + dev: true + + /follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + /form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + dev: false + + /frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + dev: false + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: true + + /framer-motion@11.18.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + motion-dom: 11.18.1 + motion-utils: 11.18.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + /function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /geotiff@2.1.3: + resolution: {integrity: sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==} + engines: {node: '>=10.19'} + dependencies: + '@petamoriken/float16': 3.9.2 + lerc: 3.0.0 + pako: 2.1.0 + parse-headers: 2.0.6 + quick-lru: 6.1.2 + web-worker: 1.5.0 + xml-utils: 1.10.2 + zstddec: 0.1.0 + dev: false + + /get-amd-module-type@6.0.1: + resolution: {integrity: sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==} + engines: {node: '>=18'} + dependencies: + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + + /get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + /get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + dev: true + + /get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + /glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + dev: true + + /globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + dev: true + + /globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + dev: true + + /globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.3 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + dev: true + + /globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + + /gonzales-pe@4.3.0: + resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} + engines: {node: '>=0.6.0'} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /goober@2.1.16(csstype@3.1.3): + resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==} + peerDependencies: + csstype: ^3.0.10 + dependencies: + csstype: 3.1.3 + dev: false + + /gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.1 + dev: true + + /has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + dev: true + + /has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.1.0 + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + + /html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: false + + /html2canvas@1.4.1: + resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==} + engines: {node: '>=8.0.0'} + dependencies: + css-line-break: 2.1.0 + text-segmentation: 1.0.3 + dev: false + + /i18next@25.3.2(typescript@5.6.3): + resolution: {integrity: sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@babel/runtime': 7.28.2 + typescript: 5.6.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + dev: true + + /ignore@7.0.3: + resolution: {integrity: sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==} + engines: {node: '>= 4'} + dev: true + + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + + /immer@10.1.1: + resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} + dev: true + + /import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + dev: true + + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + + /is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + requiresBuild: true + dev: false + optional: true + + /is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + dependencies: + async-function: 1.0.0 + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + dev: true + + /is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + dependencies: + has-bigints: 1.1.0 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + + /is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-bun-module@1.3.0: + resolution: {integrity: sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==} + dependencies: + semver: 7.7.1 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + + /is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + dev: true + + /is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + dev: false + + /is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + dev: true + + /is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + + /is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + dev: true + + /is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.18 + dev: true + + /is-url-superb@4.0.0: + resolution: {integrity: sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==} + engines: {node: '>=10'} + dev: true + + /is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + dev: true + + /is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + dev: true + + /is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + dev: true + + /is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + dev: true + + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: false + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + dev: true + + /jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 22.13.9 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + /jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + /jiti@2.5.1: + resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} + hasBin: true + dev: false + + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + + /js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + dev: false + + /js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + dev: false + + /js-sha512@0.9.0: + resolution: {integrity: sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==} + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + engines: {node: '>=12.0.0'} + dev: true + + /jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stringify-pretty-compact@2.0.0: + resolution: {integrity: sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==} + dev: false + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + dev: true + + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: false + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + dev: true + + /language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + dependencies: + language-subtag-registry: 0.3.23 + dev: true + + /lerc@3.0.0: + resolution: {integrity: sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==} + dev: false + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /libphonenumber-js@1.12.10: + resolution: {integrity: sha512-E91vHJD61jekHHR/RF/E83T/CMoaLXT7cwYA75T4gim4FZjnM6hbJjVIGg7chqlSqRsSvQ3izGmOjHy1SQzcGQ==} + dev: false + + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + dev: false + + /lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + dependencies: + detect-libc: 2.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + dev: false + + /lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: false + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: true + + /lodash._baseiteratee@4.7.0: + resolution: {integrity: sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==} + dependencies: + lodash._stringtopath: 4.8.0 + dev: false + + /lodash._basetostring@4.12.0: + resolution: {integrity: sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw==} + dev: false + + /lodash._baseuniq@4.6.0: + resolution: {integrity: sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==} + dependencies: + lodash._createset: 4.0.3 + lodash._root: 3.0.1 + dev: false + + /lodash._createset@4.0.3: + resolution: {integrity: sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==} + dev: false + + /lodash._root@3.0.1: + resolution: {integrity: sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==} + dev: false + + /lodash._stringtopath@4.8.0: + resolution: {integrity: sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==} + dependencies: + lodash._basetostring: 4.12.0 + dev: false + + /lodash.add@3.7.0: + resolution: {integrity: sha512-/uxUZkB6vYiPoGSXADJJE+Ee4W2vU+bxZOFdvJdx+mDgv+qyAO76sWD84Q4FxsMgTjC1+gVFC9YNhdG243QRDw==} + dev: false + + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + dev: false + + /lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + dev: false + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.size@4.2.0: + resolution: {integrity: sha512-wbu3SF1XC5ijqm0piNxw59yCbuUf2kaShumYBLWUrcCvwh6C8odz6SY/wGVzCWTQTFL/1Ygbvqg2eLtspUVVAQ==} + dev: false + + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: false + + /lodash.uniqby@4.5.0: + resolution: {integrity: sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==} + dependencies: + lodash._baseiteratee: 4.7.0 + lodash._baseuniq: 4.6.0 + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + dev: true + + /lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lucide-react@0.474.0(react@18.3.1): + resolution: {integrity: sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==} + peerDependencies: + react: ^18.3.1 + dependencies: + react: 18.3.1 + dev: false + + /lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + dev: true + + /magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + /map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + dev: true + + /mapbox-to-css-font@2.4.5: + resolution: {integrity: sha512-VJ6nB8emkO9VODI0Fk+TQ/0zKBTqmf/Pkt8Xv0kHstoc0iXRajA00DAid4Kc3K5xeFIOoiZrVxijEzj0GLVO2w==} + dev: false + + /math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + /memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + dependencies: + map-or-similar: 1.5.0 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + /mgrs@1.0.0: + resolution: {integrity: sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==} + dev: false + + /micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + /minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + dependencies: + minipass: 7.1.2 + dev: false + + /mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + dev: false + + /module-definition@6.0.1: + resolution: {integrity: sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==} + engines: {node: '>=18'} + hasBin: true + dependencies: + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + dev: false + + /motion-dom@11.18.1: + resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==} + dependencies: + motion-utils: 11.18.1 + dev: false + + /motion-utils@11.18.1: + resolution: {integrity: sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==} + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + /nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + /next-qrcode@2.5.1(react@18.3.1): + resolution: {integrity: sha512-ibiS1+p+myjurC1obVIgo7UCjFhxm0SNYTkikahQVmnyzlfREOdUCf2f77Vbz6W6q2zfx5Eww2/20vbgkLNdLw==} + engines: {node: '>=8', npm: '>=5'} + peerDependencies: + react: ^18.3.1 + dependencies: + qrcode: 1.5.4 + react: 18.3.1 + dev: false + + /next-themes@0.4.6(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /next@15.1.7(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.3.1 + react-dom: ^18.3.1 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + dependencies: + '@next/env': 15.1.7 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001701 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.1.7 + '@next/swc-darwin-x64': 15.1.7 + '@next/swc-linux-arm64-gnu': 15.1.7 + '@next/swc-linux-arm64-musl': 15.1.7 + '@next/swc-linux-x64-gnu': 15.1.7 + '@next/swc-linux-x64-musl': 15.1.7 + '@next/swc-win32-arm64-msvc': 15.1.7 + '@next/swc-win32-x64-msvc': 15.1.7 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /next@15.3.0(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-k0MgP6BsK8cZ73wRjMazl2y2UcXj49ZXLDEgx6BikWuby/CN+nh81qFFI16edgd7xYpe/jj2OZEIwCoqnzz0bQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.3.1 + react-dom: ^18.3.1 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + dependencies: + '@next/env': 15.3.0 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001701 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.0 + '@next/swc-darwin-x64': 15.3.0 + '@next/swc-linux-arm64-gnu': 15.3.0 + '@next/swc-linux-arm64-musl': 15.3.0 + '@next/swc-linux-x64-gnu': 15.3.0 + '@next/swc-linux-x64-musl': 15.3.0 + '@next/swc-win32-arm64-msvc': 15.3.0 + '@next/swc-win32-x64-msvc': 15.3.0 + sharp: 0.34.1 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + /node-source-walk@7.0.1: + resolution: {integrity: sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==} + engines: {node: '>=18'} + dependencies: + '@babel/parser': 7.26.9 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + /object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + dev: true + + /object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /ol-ext@4.0.31(ol@7.5.2): + resolution: {integrity: sha512-byh26JcXZggkLUY79+c29cxf2ovkkwz5niWJzOIN+dLPDJ+ogSn0y4Wl8fIS9O2JtQff5/cInHRImgZBvl+N1g==} + peerDependencies: + ol: '>= 5.3.0' + dependencies: + ol: 7.5.2 + dev: false + + /ol-mapbox-style@10.7.0: + resolution: {integrity: sha512-S/UdYBuOjrotcR95Iq9AejGYbifKeZE85D9VtH11ryJLQPTZXZSW1J5bIXcr4AlAH6tyjPPHTK34AdkwB32Myw==} + dependencies: + '@mapbox/mapbox-gl-style-spec': 13.28.0 + mapbox-to-css-font: 2.4.5 + ol: 7.5.2 + dev: false + + /ol@7.5.2: + resolution: {integrity: sha512-HJbb3CxXrksM6ct367LsP3N+uh+iBBMdP3DeGGipdV9YAYTP0vTJzqGnoqQ6C2IW4qf8krw9yuyQbc9fjOIaOQ==} + dependencies: + earcut: 2.2.4 + geotiff: 2.1.3 + ol-mapbox-style: 10.7.0 + pbf: 3.2.1 + rbush: 3.0.1 + dev: false + + /open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + dev: true + + /own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: false + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: false + + /package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + + /pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + dev: false + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-headers@2.0.6: + resolution: {integrity: sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==} + dev: false + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.26.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + /path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + /path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + dev: true + + /path@0.12.7: + resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==} + dependencies: + process: 0.11.10 + util: 0.10.4 + dev: false + + /pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + dev: true + + /patronum@2.3.0(effector@23.3.0): + resolution: {integrity: sha512-BfKIOpoymVz6XnkOn8Fi5QZ1a3r/3lXdd8BcdHmYDbIXPTIRnD1EPFBFev/DheWnOge6/ZswEqgNF2ANLGOxLw==} + peerDependencies: + effector: ^23 + dependencies: + effector: 23.3.0 + dev: true + + /pbf@3.2.1: + resolution: {integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==} + hasBin: true + dependencies: + ieee754: 1.2.1 + resolve-protobuf-schema: 2.1.0 + dev: false + + /picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + dev: true + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + + /pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + dev: false + + /polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + dependencies: + '@babel/runtime': 7.26.9 + dev: true + + /possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@15.1.0(postcss@8.5.3): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.10 + + /postcss-js@4.0.1(postcss@8.5.3): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.3 + + /postcss-load-config@4.0.2(postcss@8.5.3): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.1.3 + postcss: 8.5.3 + yaml: 2.7.0 + + /postcss-load-config@6.0.1(postcss@8.5.3): + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + dependencies: + lilconfig: 3.1.3 + postcss: 8.5.3 + dev: true + + /postcss-nested@6.2.0(postcss@8.5.3): + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 6.1.2 + + /postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + /postcss-values-parser@6.0.2(postcss@8.5.3): + resolution: {integrity: sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==} + engines: {node: '>=10'} + peerDependencies: + postcss: ^8.2.9 + dependencies: + color-name: 1.1.4 + is-url-superb: 4.0.0 + postcss: 8.5.3 + quote-unquote: 1.0.0 + dev: true + + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + dev: false + + /postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + /preact@10.12.1: + resolution: {integrity: sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==} + dev: false + + /precinct@12.2.0: + resolution: {integrity: sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==} + engines: {node: '>=18'} + hasBin: true + dependencies: + '@dependents/detective-less': 5.0.1 + commander: 12.1.0 + detective-amd: 6.0.1 + detective-cjs: 6.0.1 + detective-es6: 5.0.1 + detective-postcss: 7.0.1(postcss@8.5.3) + detective-sass: 6.0.1 + detective-scss: 5.0.1 + detective-stylus: 5.0.1 + detective-typescript: 14.0.0(typescript@5.7.3) + detective-vue2: 2.2.0(typescript@5.7.3) + module-definition: 6.0.1 + node-source-walk: 7.0.1 + postcss: 8.5.3 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-plugin-tailwindcss@0.6.11(prettier@3.5.2): + resolution: {integrity: sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + dependencies: + prettier: 3.5.2 + dev: true + + /prettier@3.5.2: + resolution: {integrity: sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /prexit@2.3.0: + resolution: {integrity: sha512-mX+LIbtS0anKtl2PykYabxninwloblUQMRO6CubeSmjxb+kKlATuJoH9UeN8NLE4TgIEFWfBXw7V3GkWbBrSmg==} + engines: {node: '>=12'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: false + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + /proj4@2.15.0: + resolution: {integrity: sha512-LqCNEcPdI03BrCHxPLj29vsd5afsm+0sV1H/O3nTDKrv8/LA01ea1z4QADDMjUqxSXWnrmmQDjqFm1J/uZ5RLw==} + dependencies: + mgrs: 1.0.0 + wkt-parser: 1.4.0 + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + /proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + dev: false + + /protocol-buffers-schema@3.6.0: + resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + dev: false + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + dev: false + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: false + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + /quick-lru@6.1.2: + resolution: {integrity: sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==} + engines: {node: '>=12'} + dev: false + + /quickselect@2.0.0: + resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} + dev: false + + /quote-unquote@1.0.0: + resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + + /rbush@3.0.1: + resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==} + dependencies: + quickselect: 2.0.0 + dev: false + + /react-chartjs-2@5.3.0(chart.js@4.4.8)(react@18.3.1): + resolution: {integrity: sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==} + peerDependencies: + chart.js: ^4.1.1 + react: ^18.3.1 + dependencies: + chart.js: 4.4.8 + react: 18.3.1 + dev: false + + /react-day-picker@8.10.1(date-fns@3.6.0)(react@18.3.1): + resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==} + peerDependencies: + date-fns: ^2.28.0 || ^3.0.0 + react: ^18.3.1 + dependencies: + date-fns: 3.6.0 + react: 18.3.1 + dev: false + + /react-day-picker@9.7.0(react@18.3.1): + resolution: {integrity: sha512-urlK4C9XJZVpQ81tmVgd2O7lZ0VQldZeHzNejbwLWZSkzHH498KnArT0EHNfKBOWwKc935iMLGZdxXPRISzUxQ==} + engines: {node: '>=18'} + peerDependencies: + react: ^18.3.1 + dependencies: + '@date-fns/tz': 1.2.0 + date-fns: 4.1.0 + date-fns-jalali: 4.1.0-0 + react: 18.3.1 + dev: false + + /react-dnd-html5-backend@16.0.1: + resolution: {integrity: sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==} + dependencies: + dnd-core: 16.0.1 + dev: false + + /react-dnd-touch-backend@16.0.1: + resolution: {integrity: sha512-NonoCABzzjyWGZuDxSG77dbgMZ2Wad7eQiCd/ECtsR2/NBLTjGksPUx9UPezZ1nQ/L7iD130Tz3RUshL/ClKLA==} + dependencies: + '@react-dnd/invariant': 4.0.2 + dnd-core: 16.0.1 + dev: false + + /react-dnd@16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + dependencies: + '@react-dnd/invariant': 4.0.2 + '@react-dnd/shallowequal': 4.0.2 + '@types/node': 22.13.5 + '@types/react': 18.3.18 + dnd-core: 16.0.1 + fast-deep-equal: 3.1.3 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + dev: false + + /react-dnd@16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + dependencies: + '@react-dnd/invariant': 4.0.2 + '@react-dnd/shallowequal': 4.0.2 + '@types/node': 22.13.9 + '@types/react': 18.3.18 + dnd-core: 16.0.1 + fast-deep-equal: 3.1.3 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + dev: false + + /react-docgen-typescript@2.2.2(typescript@5.6.3): + resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} + peerDependencies: + typescript: '>= 4.3.x' + dependencies: + typescript: 5.6.3 + dev: true + + /react-docgen@7.1.1: + resolution: {integrity: sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==} + engines: {node: '>=16.14.0'} + dependencies: + '@babel/core': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.10 + strip-indent: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /react-dom@18.3.1(react@18.3.1): + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + /react-dropzone@14.3.8(react@18.3.1): + resolution: {integrity: sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==} + engines: {node: '>= 10.13'} + peerDependencies: + react: ^18.3.1 + dependencies: + attr-accept: 2.2.5 + file-selector: 2.1.2 + prop-types: 15.8.1 + react: 18.3.1 + dev: false + + /react-hook-form@7.54.2(react@18.3.1): + resolution: {integrity: sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.3.1 + dependencies: + react: 18.3.1 + dev: false + + /react-hot-toast@2.5.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==} + engines: {node: '>=10'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + csstype: 3.1.3 + goober: 2.1.16(csstype@3.1.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /react-i18next@15.6.1(i18next@25.3.2)(react-dom@18.3.1)(react@18.3.1)(typescript@5.6.3): + resolution: {integrity: sha512-uGrzSsOUUe2sDBG/+FJq2J1MM+Y4368/QW8OLEKSFvnDflHBbZhSd1u3UkW0Z06rMhZmnB/AQrhCpYfE5/5XNg==} + peerDependencies: + i18next: '>= 23.2.3' + react: ^18.3.1 + react-dom: '*' + react-native: '*' + typescript: ^5 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true + dependencies: + '@babel/runtime': 7.28.2 + html-parse-stringify: 3.0.1 + i18next: 25.3.2(typescript@5.6.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + typescript: 5.6.3 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + dev: false + + /react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + dev: true + + /react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + tslib: 2.8.1 + dev: false + + /react-remove-scroll@2.6.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /react-smooth@4.0.4(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + fast-equals: 5.2.2 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) + dev: false + + /react-style-singleton@2.2.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /react-transition-group@4.4.5(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@babel/runtime': 7.26.9 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /react-use-measure@2.1.7(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + react-dom: + optional: true + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: false + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + + /readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + dev: true + + /recast@0.23.10: + resolution: {integrity: sha512-mbCmRMJUKCJ1h41V0cu2C26ULBURwuoZ34C9rChjcDaeJ/4Kv5al3O2HPwTs2m0wQ1vGhMY+tguhzU1aE8md1A==} + engines: {node: '>= 4'} + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + dev: true + + /recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + dependencies: + decimal.js-light: 2.5.1 + dev: false + + /recharts@2.15.1(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==} + engines: {node: '>=14'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + clsx: 2.1.1 + eventemitter3: 4.0.7 + lodash: 4.17.21 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + react-smooth: 4.0.4(react-dom@18.3.1)(react@18.3.1) + recharts-scale: 0.4.5 + tiny-invariant: 1.3.3 + victory-vendor: 36.9.2 + dev: false + + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + dependencies: + '@babel/runtime': 7.26.9 + dev: false + + /reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + /regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: false + + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve-protobuf-schema@2.1.0: + resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} + dependencies: + protocol-buffers-schema: 3.6.0 + dev: false + + /resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + dev: false + + /reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + /rollup@4.34.8: + resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.34.8 + '@rollup/rollup-android-arm64': 4.34.8 + '@rollup/rollup-darwin-arm64': 4.34.8 + '@rollup/rollup-darwin-x64': 4.34.8 + '@rollup/rollup-freebsd-arm64': 4.34.8 + '@rollup/rollup-freebsd-x64': 4.34.8 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.8 + '@rollup/rollup-linux-arm-musleabihf': 4.34.8 + '@rollup/rollup-linux-arm64-gnu': 4.34.8 + '@rollup/rollup-linux-arm64-musl': 4.34.8 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.8 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.8 + '@rollup/rollup-linux-riscv64-gnu': 4.34.8 + '@rollup/rollup-linux-s390x-gnu': 4.34.8 + '@rollup/rollup-linux-x64-gnu': 4.34.8 + '@rollup/rollup-linux-x64-musl': 4.34.8 + '@rollup/rollup-win32-arm64-msvc': 4.34.8 + '@rollup/rollup-win32-ia32-msvc': 4.34.8 + '@rollup/rollup-win32-x64-msvc': 4.34.8 + fsevents: 2.3.3 + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + + /rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + + /safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + /safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-regex: 1.2.1 + dev: true + + /sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + dev: false + + /scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + dependencies: + loose-envify: 1.4.0 + + /schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + /select@1.1.2: + resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==} + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + dev: true + + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: false + + /sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + dev: false + optional: true + + /sharp@0.34.1: + resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.1 + '@img/sharp-darwin-x64': 0.34.1 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.1 + '@img/sharp-linux-arm64': 0.34.1 + '@img/sharp-linux-s390x': 0.34.1 + '@img/sharp-linux-x64': 0.34.1 + '@img/sharp-linuxmusl-arm64': 0.34.1 + '@img/sharp-linuxmusl-x64': 0.34.1 + '@img/sharp-wasm32': 0.34.1 + '@img/sharp-win32-ia32': 0.34.1 + '@img/sharp-win32-x64': 0.34.1 + dev: false + optional: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: true + + /side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + requiresBuild: true + dependencies: + is-arrayish: 0.3.2 + dev: false + optional: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + dev: true + + /sonner@2.0.1(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /sort-asc@0.1.0: + resolution: {integrity: sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==} + engines: {node: '>=0.10.0'} + dev: false + + /sort-desc@0.1.1: + resolution: {integrity: sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==} + engines: {node: '>=0.10.0'} + dev: false + + /sort-object@0.3.2: + resolution: {integrity: sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==} + engines: {node: '>=0.10.0'} + dependencies: + sort-asc: 0.1.0 + sort-desc: 0.1.1 + dev: false + + /source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + /source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + dependencies: + frac: 1.1.2 + dev: false + + /stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + dev: true + + /steiger@0.5.5(typescript@5.6.3): + resolution: {integrity: sha512-d4eZwqJjfG7dKgwXKBwmZsNWSRqeQrRpEvEr58rhMmNbICcQsJ8cpK9n6nuish3kNjKyYzx6t2TpQYEO26xTFA==} + hasBin: true + dependencies: + '@clack/prompts': 0.8.2 + '@feature-sliced/steiger-plugin': 0.5.4(typescript@5.6.3) + chokidar: 4.0.3 + cosmiconfig: 9.0.0(typescript@5.6.3) + effector: 23.3.0 + empathic: 1.0.0 + fastest-levenshtein: 1.0.16 + globby: 14.1.0 + immer: 10.1.1 + lodash-es: 4.17.21 + micromatch: 4.0.8 + patronum: 2.3.0(effector@23.3.0) + picocolors: 1.1.1 + prexit: 2.3.0 + yargs: 17.7.2 + zod: 3.24.2 + zod-validation-error: 3.4.0(zod@3.24.2) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /storybook@8.6.0(prettier@3.5.2): + resolution: {integrity: sha512-NEHCK2nXogw7WxAkJfMwPnc5Cmh/KqVNrdaFeXBAKhC2Zr1FTZIiCR5nSUT85run44Wkpmo7qvUoKvII9GOWbA==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + dependencies: + '@storybook/core': 8.6.0(prettier@3.5.2)(storybook@8.6.0) + prettier: 3.5.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + /string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + dev: true + + /string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + dev: true + + /string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.1.0 + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /styled-jsx@5.1.6(react@18.3.1): + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: ^18.3.1 + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + client-only: 0.0.1 + react: 18.3.1 + dev: false + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + /tailwind-merge@3.0.2: + resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} + dev: false + + /tailwindcss-animate@1.0.7(tailwindcss@3.4.17): + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + tailwindcss: 3.4.17 + dev: false + + /tailwindcss@3.4.17: + resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-import: 15.1.0(postcss@8.5.3) + postcss-js: 4.0.1(postcss@8.5.3) + postcss-load-config: 4.0.2(postcss@8.5.3) + postcss-nested: 6.2.0(postcss@8.5.3) + postcss-selector-parser: 6.1.2 + resolve: 1.22.10 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + /tailwindcss@4.1.11: + resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==} + dev: false + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + /tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + dev: false + + /terser-webpack-plugin@5.3.13(webpack@5.98.0): + resolution: {integrity: sha512-JG3pBixF6kx2o0Yfz2K6pqh72DpwTI08nooHd06tcj5WyIt5SsSiUYqRT+kemrGUNSuSzVhwfZ28aO8gogajNQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 4.3.0 + serialize-javascript: 6.0.2 + terser: 5.39.0 + webpack: 5.98.0 + + /terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + /text-segmentation@1.0.3: + resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==} + dependencies: + utrie: 1.0.2 + dev: false + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + + /tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + /tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + dev: true + + /tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + dev: true + + /tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.3.1 + dev: true + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /ts-api-utils@2.0.1(typescript@5.6.3): + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + dependencies: + typescript: 5.6.3 + dev: true + + /ts-api-utils@2.0.1(typescript@5.7.3): + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + dependencies: + typescript: 5.7.3 + dev: true + + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + /tsconfck@3.1.5(typescript@5.6.3): + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.6.3 + dev: true + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + /tsup@8.3.6(postcss@8.5.3)(typescript@5.6.3): + resolution: {integrity: sha512-XkVtlDV/58S9Ye0JxUUTcrQk4S+EqlOHKzg6Roa62rdjL1nGWNUstG0xgI4vanHdfIpjP448J8vlN0oK6XOJ5g==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + bundle-require: 5.1.0(esbuild@0.24.2) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.0 + debug: 4.4.0 + esbuild: 0.24.2 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-load-config: 6.0.1(postcss@8.5.3) + resolve-from: 5.0.0 + rollup: 4.34.8 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.12 + tree-kill: 1.2.2 + typescript: 5.6.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + dev: true + + /turbo-darwin-64@2.4.2: + resolution: {integrity: sha512-HFfemyWB60CJtEvVQj9yby5rkkWw9fLAdLtAPGtPQoU3tKh8t/uzCAZKso2aPVbib9vGUuGbPGoGpaRXdVhj5g==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /turbo-darwin-arm64@2.4.2: + resolution: {integrity: sha512-uwSx1dsBSSFeEC0nxyx2O219FEsS/haiESaWwE9JI8mHkQK61s6w6fN2G586krKxyNam4AIxRltleL+O2Em94g==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /turbo-linux-64@2.4.2: + resolution: {integrity: sha512-Fy/uL8z/LAYcPbm7a1LwFnTY9pIi5FAi12iuHsgB7zHjdh4eeIKS2NIg4nroAmTcUTUZ0/cVTo4bDOCUcS3aKw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /turbo-linux-arm64@2.4.2: + resolution: {integrity: sha512-AEA0d8h5W/K6iiXfEgiNwWt0yqRL1NpBs8zQCLdc4/L7WeYeJW3sORWX8zt7xhutF/KW9gTm8ehKpiK6cCIsAA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /turbo-windows-64@2.4.2: + resolution: {integrity: sha512-CybtIZ9wRgnnNFVN9En9G+rxsO+mwU81fvW4RpE8BWyNEkhQ8J28qYf4PaimueMxGHHp/28i/G7Kcdn2GAWG0g==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /turbo-windows-arm64@2.4.2: + resolution: {integrity: sha512-7V0yneVPL8Y3TgrkUIjw7Odmwu1tHnyIiPHFM7eFcA7U+H6hPXyCxge7nC3wOKfjhKCQqUm+Vf/k6kjmLz5G4g==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /turbo@2.4.2: + resolution: {integrity: sha512-Qxi0ioQCxMRUCcHKHZkTnYH8e7XCpNfg9QiJcyfWIc+ZXeaCjzV5rCGlbQlTXMAtI8qgfP8fZADv3CFtPwqdPQ==} + hasBin: true + optionalDependencies: + turbo-darwin-64: 2.4.2 + turbo-darwin-arm64: 2.4.2 + turbo-linux-64: 2.4.2 + turbo-linux-arm64: 2.4.2 + turbo-windows-64: 2.4.2 + turbo-windows-arm64: 2.4.2 + dev: true + + /tus-js-client@4.3.1: + resolution: {integrity: sha512-ZLeYmjrkaU1fUsKbIi8JML52uAocjEZtBx4DKjRrqzrZa0O4MYwT6db+oqePlspV+FxXJAyFBc/L5gwUi2OFsg==} + engines: {node: '>=18'} + dependencies: + buffer-from: 1.1.2 + combine-errors: 3.0.3 + is-stream: 2.0.1 + js-base64: 3.7.7 + lodash.throttle: 4.1.1 + proper-lockfile: 4.1.2 + url-parse: 1.5.10 + dev: false + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + + /typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + dev: true + + /typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + dev: true + + /typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + dev: true + + /typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + dev: true + + /typescript-eslint@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/eslint-plugin': 8.25.0(@typescript-eslint/parser@8.25.0)(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + eslint: 9.21.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + /typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + dev: true + + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + dev: true + + /undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + /unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + dev: true + + /unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + dependencies: + acorn: 8.14.0 + webpack-virtual-modules: 0.6.2 + dev: true + + /update-browserslist-db@1.1.3(browserslist@4.24.4): + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: false + + /use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /use-sidecar@1.1.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + dependencies: + inherits: 2.0.3 + dev: false + + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.18 + dev: true + + /utrie@1.0.2: + resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==} + dependencies: + base64-arraybuffer: 1.0.2 + dev: false + + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: true + + /victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-shape': 3.1.7 + '@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 + dev: false + + /vite-tsconfig-paths@5.1.4(typescript@5.6.3)(vite@6.2.0): + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + dependencies: + debug: 4.4.0 + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.6.3) + vite: 6.2.0(@types/node@22.13.9) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /vite@5.4.18(@types/node@22.13.9): + resolution: {integrity: sha512-1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 22.13.9 + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vite@6.2.0(@types/node@22.13.5): + resolution: {integrity: sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + dependencies: + '@types/node': 22.13.5 + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vite@6.2.0(@types/node@22.13.9): + resolution: {integrity: sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + dependencies: + '@types/node': 22.13.9 + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + fsevents: 2.3.3 + + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: false + + /watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + /web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + dev: false + + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + /webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + dev: true + + /webpack@5.98.0: + resolution: {integrity: sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.0 + browserslist: 4.24.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.1 + es-module-lexer: 1.6.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.13(webpack@5.98.0) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + /whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + dev: true + + /which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.18 + dev: true + + /which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + dev: true + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: false + + /which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + for-each: 0.3.5 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wkt-parser@1.4.0: + resolution: {integrity: sha512-qpwO7Ihds/YYDTi1aADFTI1Sm9YC/tTe3SHD24EeIlZxy7Ik6a1b4HOz7jAi0xdUAw487duqpo8OGu+Tf4nwlQ==} + dev: false + + /wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + dev: false + + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + dev: false + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + /ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + 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 + dev: true + + /xlsx-populate@1.21.0: + resolution: {integrity: sha512-8v2Gm8BehXo6LU7KT802QoXTPkYY1SKk5V8g/UuYZnNB3JzXqud/P99Pxr2yXeKyt+sKlCatmidz6jQNie1hRw==} + dependencies: + cfb: 1.2.2 + jszip: 3.10.1 + lodash: 4.17.21 + sax: 1.4.1 + dev: false + + /xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + dev: false + + /xml-utils@1.10.2: + resolution: {integrity: sha512-RqM+2o1RYs6T8+3DzDSoTRAUfrvaejbVHcp3+thnAtDKo8LskR+HomLajEy5UjTz24rpka7AxVBRR3g2wTUkJA==} + dev: false + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: false + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + dev: false + + /yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: false + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: false + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + 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 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /zod-validation-error@3.4.0(zod@3.24.2): + resolution: {integrity: sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.18.0 + dependencies: + zod: 3.24.2 + dev: true + + /zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + + /zstddec@0.1.0: + resolution: {integrity: sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==} + dev: false + + /zustand@5.0.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': ^18.3.18 + immer: '>=9.0.6' + react: ^18.3.1 + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false From 2aba7bb16e3ddbbbe6637e3a19309ee6a31923ff Mon Sep 17 00:00:00 2001 From: RSONE001 <rsone001@gmail.com> Date: Fri, 25 Jul 2025 22:49:06 +0900 Subject: [PATCH 25/27] =?UTF-8?q?ESlint=20=EB=AC=B8=EB=B2=95=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cs/src/pages/link/model/table-columns.tsx | 30 ++-------------- .../cs/src/pages/link/ui/QuickStartButton.tsx | 36 +++++++++++++++++++ apps/cs/src/pages/link/ui/link-form.tsx | 8 +++-- apps/cs/src/pages/link/ui/link-page.tsx | 4 +-- apps/cs/src/pages/link/ui/modify-page.tsx | 4 +-- apps/cs/src/pages/link/ui/regist-page.tsx | 2 +- .../linkParams/ui/link-params-dialog.tsx | 12 ++++--- .../pages/linkParams/ui/link-params-page.tsx | 4 +-- .../pages/linkStats/ui/link-stats-page.tsx | 4 +-- .../pages/linkTable/ui/link-table-dialog.tsx | 18 +++++----- .../pages/linkTable/ui/link-table-page.tsx | 4 +-- 11 files changed, 73 insertions(+), 53 deletions(-) create mode 100644 apps/cs/src/pages/link/ui/QuickStartButton.tsx diff --git a/apps/cs/src/pages/link/model/table-columns.tsx b/apps/cs/src/pages/link/model/table-columns.tsx index 8ea7e3fb6..5b1710fec 100644 --- a/apps/cs/src/pages/link/model/table-columns.tsx +++ b/apps/cs/src/pages/link/model/table-columns.tsx @@ -1,10 +1,7 @@ import dayjs from "dayjs"; import { createColumnHelper } from "@tanstack/react-table"; import { type Link } from "@/entities/link"; -import { Button } from "@common/components"; -import { useMutation } from "@tanstack/react-query"; -import { LinkApi } from "@/entities/link"; -import { useAlertStore } from "@/shared/lib/use-alert-store"; +import QuickStartButton from "../ui/QuickStartButton"; const columnHelper = createColumnHelper<Link>(); @@ -83,30 +80,7 @@ const columns = [ id: 'quick_start_btn', header: '즉시 실행', cell: (info) => { - const row = info.row.original; - const { setMessage: alert } = useAlertStore((state) => state); - - const { mutateAsync: updateQuickStart } = useMutation({ - mutationFn: (linkSn: string) => LinkApi.linkQuickStart(linkSn), - onSuccess: (resut) => { - if (resut === 'succ') { - alert('즉시 실행 요청이 완료되었습니다.'); - } else { - alert('기존 요청이 실행 대기중입니다.'); - } - }, - onError: () => { - alert('즉시 실행 요청을 실패했습니다.'); - } - }); - - return ( - <Button color="sky" onClick={(e) => { - e.stopPropagation(); - updateQuickStart(row.link_sn); - } - }>즉시 실행</Button> - ) + return <QuickStartButton linkSn={info.row.original.link_sn} /> } }) ]; diff --git a/apps/cs/src/pages/link/ui/QuickStartButton.tsx b/apps/cs/src/pages/link/ui/QuickStartButton.tsx new file mode 100644 index 000000000..a322ee678 --- /dev/null +++ b/apps/cs/src/pages/link/ui/QuickStartButton.tsx @@ -0,0 +1,36 @@ +import { useMutation } from "@tanstack/react-query"; +import { LinkApi } from "@/entities/link"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { Button } from "@common/components"; + +const QuickStartButton: React.FC<{ linkSn: string }> = ({ linkSn }) => { + const { setMessage: alert } = useAlertStore((state) => state); + + const { mutateAsync: updateQuickStart } = useMutation({ + mutationFn: (linkSn: string) => LinkApi.linkQuickStart(linkSn), + onSuccess: (result) => { + if (result === 'succ') { + alert('즉시 실행 요청이 완료되었습니다.'); + } else { + alert('기존 요청이 실행 대기중입니다.'); + } + }, + onError: () => { + alert('즉시 실행 요청을 실패했습니다.'); + }, + }); + + return ( + <Button + color="sky" + onClick={(e) => { + e.stopPropagation(); + updateQuickStart(linkSn); + }} + > + 즉시 실행 + </Button> + ); +}; + +export default QuickStartButton; \ No newline at end of file diff --git a/apps/cs/src/pages/link/ui/link-form.tsx b/apps/cs/src/pages/link/ui/link-form.tsx index a5f09af18..05a3da0f1 100644 --- a/apps/cs/src/pages/link/ui/link-form.tsx +++ b/apps/cs/src/pages/link/ui/link-form.tsx @@ -50,7 +50,11 @@ const LinkForm = ({ form, linkSn, updateLinkInfo, handleInsertLink, deleteLink, await handleConfirm(async () => { if (await confirm(confirmMsg)) { - !!linkSn ? updateLinkInfo?.(data) : handleInsertLink?.(data); + if (linkSn) { + updateLinkInfo?.(data); + } else { + handleInsertLink?.(data); + } } }); }; @@ -578,7 +582,7 @@ const LinkForm = ({ form, linkSn, updateLinkInfo, handleInsertLink, deleteLink, </div> </form> </Form> - <ConfirmDialog open={onConfirm} /> + <ConfirmDialog isOpen={onConfirm} /> </> ) }; diff --git a/apps/cs/src/pages/link/ui/link-page.tsx b/apps/cs/src/pages/link/ui/link-page.tsx index ee5f4d93f..95a9cc043 100644 --- a/apps/cs/src/pages/link/ui/link-page.tsx +++ b/apps/cs/src/pages/link/ui/link-page.tsx @@ -4,8 +4,8 @@ import "@common/assets/styles/grid.css"; import { useState } from "react"; import { useRouter } from "next/navigation"; -import { Button, DataTable, Input, Label, LoadingWithAnimation } from "@common/components"; -import { getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { Button, Input, Label, LoadingWithAnimation } from "@common/components"; +import { getCoreRowModel } from "@tanstack/react-table"; import { LinkApi, type Link, type LinkSearchParam } from "@/entities/link"; import { useQuery } from "@tanstack/react-query"; import { columns } from "../model/table-columns"; diff --git a/apps/cs/src/pages/link/ui/modify-page.tsx b/apps/cs/src/pages/link/ui/modify-page.tsx index a15fecb97..594cb4c49 100644 --- a/apps/cs/src/pages/link/ui/modify-page.tsx +++ b/apps/cs/src/pages/link/ui/modify-page.tsx @@ -58,7 +58,7 @@ function ModifyLinkPage({ linkSn }: { linkSn: string }) { } }); - const fetchUserInfo = async (id: string) => { + const fetchUserInfo = async () => { const userData = await getUserInfo(); return userData.userName; }; @@ -74,7 +74,7 @@ function ModifyLinkPage({ linkSn }: { linkSn: string }) { let newData = { ...linkInfo }; if (linkInfo.mdfr) { - const userName = await fetchUserInfo(linkInfo.mdfr); + const userName = await fetchUserInfo(); newData = { ...linkInfo, mdfr: userName, diff --git a/apps/cs/src/pages/link/ui/regist-page.tsx b/apps/cs/src/pages/link/ui/regist-page.tsx index 6aa26e79e..403aefa24 100644 --- a/apps/cs/src/pages/link/ui/regist-page.tsx +++ b/apps/cs/src/pages/link/ui/regist-page.tsx @@ -41,7 +41,7 @@ function RegistLinkPage() { }); const handleInsertLink = (data: LinkFormData) => { - let insertData = { + const insertData = { ...data, link_clsf_cd: data.link_clsf_cd !== 'none' ? data.link_clsf_cd : null, next_link_excn_dt: dayjs().add(Number(data.link_batch_time), 'minute').format('YYYY-MM-DD HH:mm:ss'), diff --git a/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx b/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx index f3fe466b8..cff72a030 100644 --- a/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx +++ b/apps/cs/src/pages/linkParams/ui/link-params-dialog.tsx @@ -55,12 +55,12 @@ function LinkParamsDialog({ selectedLink, form, insertLinkVrbl, dialogOpen, onOp setOnConfirm(false); }; - function replaceEmptyWithNull<T extends Record<string, any>>(data: T): T { + function replaceEmptyWithNull<T extends Record<string, unknown>>(data: T): T { const result = {} as T; for (const [key, value] of Object.entries(data)) { - result[key as keyof T] = value === '' ? null : value; + (result as Record<string, unknown>)[key] = value === '' ? null : value; } - return result; + return result as T; }; const handleSubmit = async (data: LinkVrblFormData) => { @@ -70,7 +70,11 @@ function LinkParamsDialog({ selectedLink, form, insertLinkVrbl, dialogOpen, onOp const cleanData = replaceEmptyWithNull(data); if (await confirm(confirmMsg)) { - isModifyMode ? updateLinkVrbl(isToday ? { ...cleanData, link_vrbl_vl: checkNowMonth } : cleanData) : insertLinkVrbl(isToday ? { ...cleanData, link_vrbl_vl: checkNowMonth } : cleanData); + if (isModifyMode) { + updateLinkVrbl(isToday ? { ...cleanData, link_vrbl_vl: checkNowMonth } : cleanData); + } else { + insertLinkVrbl(isToday ? { ...cleanData, link_vrbl_vl: checkNowMonth } : cleanData); + } } }); }; diff --git a/apps/cs/src/pages/linkParams/ui/link-params-page.tsx b/apps/cs/src/pages/linkParams/ui/link-params-page.tsx index 82273de25..b3806e712 100644 --- a/apps/cs/src/pages/linkParams/ui/link-params-page.tsx +++ b/apps/cs/src/pages/linkParams/ui/link-params-page.tsx @@ -205,7 +205,7 @@ function LinkParamsPage() { }); }; - const fetchUserInfo = async (id: string) => { + const fetchUserInfo = async () => { const userData = await getUserInfo(); return userData.userName; }; @@ -229,7 +229,7 @@ function LinkParamsPage() { let newData = { ...linkVrblInfo }; if (linkVrblInfo.mdfr) { - const userName = await fetchUserInfo(linkVrblInfo.mdfr); + const userName = await fetchUserInfo(); newData = { ...linkVrblInfo, mdfr: userName, diff --git a/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx b/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx index 547b3766f..f6168ba76 100644 --- a/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx +++ b/apps/cs/src/pages/linkStats/ui/link-stats-page.tsx @@ -279,8 +279,8 @@ function LinkStatsPage() { endDate: dayjs().format('YYYY-MM-DD'), }); setEndDate(dayjs().format('YYYY-MM-DD')); - setStartDate(dayjs().format('YYYY-MM-DD')), - setLinkStatsList(data); + setStartDate(dayjs().format('YYYY-MM-DD')); + setLinkStatsList(data); setLinkSearchParam({ ...linkSearchParam, startDate: dayjs().format('YYYY-MM-DD'), diff --git a/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx b/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx index 9c27a38d9..a566a7d95 100644 --- a/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx +++ b/apps/cs/src/pages/linkTable/ui/link-table-dialog.tsx @@ -58,17 +58,19 @@ function LinkTableDialog({ dialogOpen, onOpenChange, form, tableInfo, insertLink await handleConfirm(async () => { if (await confirm(confirmMsg)) { - !isModifyMode - ? insertLinkTableCol({ - ...data, - link_sn: tableInfo.link_sn, - tbl_sn: tableInfo.tbl_sn, - }) - : updateLinkTableCol({ + if (!isModifyMode) { + insertLinkTableCol({ ...data, link_sn: tableInfo.link_sn, tbl_sn: tableInfo.tbl_sn, }); + } else { + updateLinkTableCol({ + ...data, + link_sn: tableInfo.link_sn, + tbl_sn: tableInfo.tbl_sn, + }); + } } }); }; @@ -492,7 +494,7 @@ function LinkTableDialog({ dialogOpen, onOpenChange, form, tableInfo, insertLink </DialogFooter> </form> </Form> - <ConfirmDialog open={onConfirm} /> + <ConfirmDialog isOpen={onConfirm} /> </DialogContent> </Dialog> ) diff --git a/apps/cs/src/pages/linkTable/ui/link-table-page.tsx b/apps/cs/src/pages/linkTable/ui/link-table-page.tsx index cdb93b931..11f478b71 100644 --- a/apps/cs/src/pages/linkTable/ui/link-table-page.tsx +++ b/apps/cs/src/pages/linkTable/ui/link-table-page.tsx @@ -281,7 +281,7 @@ function LinkTablePage() { let newData = { ...colInfo }; if (colInfo.mdfr) { - const userName = await fetchUserInfo(colInfo.mdfr); + const userName = await fetchUserInfo(); newData = { ...colInfo, mdfr: userName, @@ -294,7 +294,7 @@ function LinkTablePage() { setDialogOpen(true) }; - const fetchUserInfo = async (id: string) => { + const fetchUserInfo = async () => { const userData = await getUserInfo(); return userData.userName; }; From 7661823c8bc4c76a6b8e3a811ba2d87567469698 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Sat, 26 Jul 2025 10:30:00 +0900 Subject: [PATCH 26/27] =?UTF-8?q?=EC=8A=A4=ED=86=A0=EC=96=B4=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EB=94=94=20env=20=ED=94=84=EB=A1=9C=EB=8D=95=EC=85=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/.env.production | 42 ++++++++++++++++++++++++++++--------- apps/wr/app/store/store.tsx | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/apps/wr/.env.production b/apps/wr/.env.production index 0900b009d..64066e879 100644 --- a/apps/wr/.env.production +++ b/apps/wr/.env.production @@ -1,17 +1,39 @@ +# NEXT_PUBLIC_SITE_ID = WR +# NEXT_PUBLIC_PORT = 3000 +# NEXT_PUBLIC_PROXY_HOST = http://wr.hasuon.or.kr +# NEXT_PUBLIC_SERVER_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/api/v1 +# NEXT_PUBLIC_FO_SERVER_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/operation-service/api/v1 +# NEXT_PUBLIC_CS_SERVER_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000 +# NEXT_PUBLIC_CS_TUS_UPLOAD = /attach-service/api/v1/tus/upload +# NEXT_PUBLIC_GEOSERVER_URL = http://172.29.143.87:8080/geoserver +# NEXT_PUBLIC_LX_GEOSERVER_URL = http://172.29.143.87:8080/geoserver_swl +# NEXT_PUBLIC_CLAIM_NAME = Authorization +# NEXT_PUBLIC_AUTH_USER_ID = token-id +# NEXT_PUBLIC_ACCESS_TOKEN = access-token +# NEXT_PUBLIC_REFRESH_TOKEN = refresh-token + +# NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/sewerage-service/api + + + + + + + + NEXT_PUBLIC_SITE_ID = WR -NEXT_PUBLIC_PORT = 3000 -NEXT_PUBLIC_PROXY_HOST = http://wr.hasuon.or.kr -NEXT_PUBLIC_SERVER_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/api/v1 -NEXT_PUBLIC_FO_SERVER_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/operation-service/api/v1 -NEXT_PUBLIC_CS_SERVER_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000 +NEXT_PUBLIC_PORT = 11301 +NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11301 +# NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 +NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 +NEXT_PUBLIC_FO_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_CS_TUS_UPLOAD = /attach-service/api/v1/tus/upload -NEXT_PUBLIC_GEOSERVER_URL = http://172.29.143.87:8080/geoserver -NEXT_PUBLIC_LX_GEOSERVER_URL = http://172.29.143.87:8080/geoserver_swl +NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver +NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver NEXT_PUBLIC_CLAIM_NAME = Authorization NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token -NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/sewerage-service/api - - +NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index 1bb7a03b7..284f300c5 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -195,7 +195,7 @@ export const StoreZus = ( getMiddleRegionCd(set); getUnitWaterShedCd(set); getEnvPartCd(set); - LoginApi.login({userId: "admin1gmail", password: "test1234!"}) + LoginApi.login({userId: "CLEANWATER", password: "gktneh12!@"}) return { ...initState, ...comFcltSearchAction(set), From 87be84f62074dae542de00b1cf316c0a6c20ab52 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Sat, 26 Jul 2025 13:23:11 +0900 Subject: [PATCH 27/27] =?UTF-8?q?=EC=8B=A4=EC=A0=81=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncReg/pbnstPrfmncReg/page.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index c4e62a861..fbab00284 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -125,6 +125,9 @@ export default function PrfmncPrfmncReg() { }; if (prfmncRes[index]?.prfList) { prfmncRes[index].prfList?.forEach((prfItem) => { + const yr = Number(prfItem.ym?.slice(0, 4)); // "YYYY" + + if(yr === Number(searchYear)) { const month = Number(prfItem?.ym?.slice(4)); // "MM" const monthKey = `${month}월`; @@ -155,7 +158,11 @@ export default function PrfmncPrfmncReg() { outSubtotal.total += value; } }); + } }); + + if(inSubtotal.total!==0 && outSubtotal.total!==0) { + inUsageData.push(inSubtotal); outUsageData.push(outSubtotal); const usageTotalObj: { [key: string]: any } = { @@ -174,18 +181,21 @@ export default function PrfmncPrfmncReg() { const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; setpbnstRuseFcltId(prfmncRes[index].pbnstRuseFcltId); setInputData(tableData); + }else{ + setInputData([]); + } } else { setInputData([]); } } }, - [prfmncRes] + [prfmncRes,searchYear] ); useEffect(() => { if (!prfmnc.isInit) { const year = new Date().getFullYear() - prfmncHasuInit(1, "41", String(year)); + prfmncHasuInit(1, '41', String(year)); } }, [prfmnc.isInit, prfmncHasuInit]); useEffect(() => { @@ -305,7 +315,7 @@ export default function PrfmncPrfmncReg() { }} onPageChange={ (page) => { - prfmncHasuInit(page, "41", searchYear); + prfmncHasuInit(page, '41', searchYear); setPageNation(page) }} />