-
+
-
+ Get started by editing{" "}
+
+ src/app/page.tsx ++ . +
+ - + Save and see your changes instantly. + +
dAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJw b z_^v8bbg` SAn{I*4bH$u(RZ6*x UhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=p C^ S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk( $?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU ^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvh CL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c 70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397* _cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111a H}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*I cmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU &68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-= A= yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v #ix45EVrcEhr>!NMhprl $InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~ &^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7< 4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}sc Zlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+ 9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2 `1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M =hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S( O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/ui/src/app/globals.css b/ui/src/app/globals.css new file mode 100644 index 0000000..a2dc41e --- /dev/null +++ b/ui/src/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + background: var(--background); + color: var(--foreground); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/ui/src/app/layout.tsx b/ui/src/app/layout.tsx new file mode 100644 index 0000000..2b7599d --- /dev/null +++ b/ui/src/app/layout.tsx @@ -0,0 +1,35 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; +import React from "react"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/ui/src/app/page.tsx b/ui/src/app/page.tsx new file mode 100644 index 0000000..e68abe6 --- /dev/null +++ b/ui/src/app/page.tsx @@ -0,0 +1,103 @@ +import Image from "next/image"; + +export default function Home() { + return ( + ++ ); +} diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..c133409 --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/webui/package-lock.json b/webui/package-lock.json index 5956179..6be184a 100644 --- a/webui/package-lock.json +++ b/webui/package-lock.json @@ -33,7 +33,10 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "tailwindcss": "^4" + "@types/node": "^24.0.4", + "@types/react": "^19.1.8", + "tailwindcss": "^4", + "typescript": "^5.8.3" } }, "node_modules/@alloc/quick-lru": { @@ -1703,6 +1706,16 @@ "hoist-non-react-statics": "^3.3.0" } }, + "node_modules/@types/node": { + "version": "24.0.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz", + "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -1716,9 +1729,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.7.tgz", - "integrity": "sha512-BnsPLV43ddr05N71gaGzyZ5hzkCmGwhMvYc8zmvI8Ci1bRkkDSzDDVfAXfN2tk748OwI7ediiPX6PfT9p0QGVg==", + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", + "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -3383,6 +3396,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, "node_modules/use-sync-external-store": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", diff --git a/webui/package.json b/webui/package.json index 6159669..66501f5 100644 --- a/webui/package.json +++ b/webui/package.json @@ -34,6 +34,9 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "tailwindcss": "^4" + "@types/node": "^24.0.4", + "@types/react": "^19.1.8", + "tailwindcss": "^4", + "typescript": "^5.8.3" } } -- 2.49.1 From ed69cb345d2899523773928a80cba2c0193efeed Mon Sep 17 00:00:00 2001 From: lumijiez <59575049+lumijiez@users.noreply.github.com> Date: Wed, 25 Jun 2025 15:17:44 +0300 Subject: [PATCH 3/4] Transfer all code to TS --- ui/next.config.ts | 4 +- ui/package-lock.json | 1016 ++++++++++++++++- ui/package.json | 23 +- ui/public/file.svg | 1 - ui/public/globe.svg | 1 - {webui => ui}/public/logo.png | Bin ui/public/next.svg | 1 - ui/public/vercel.svg | 1 - ui/public/window.svg | 1 - ui/src/app/components/ClientLayoutEffect.tsx | 21 + ui/src/app/components/ImprinkAppBar.tsx | 238 ++++ ui/src/app/components/hooks/useRoles.ts | 71 ++ .../app/components/theme/MuiThemeProvider.tsx | 23 + ui/src/app/components/theme/ThemeContext.tsx | 74 ++ .../components/theme/ThemeToggleButton.tsx | 26 + ui/src/app/components/theme/darkTheme.ts | 276 +++++ ui/src/app/components/theme/lightTheme.ts | 276 +++++ ui/src/app/favicon.ico | Bin 25931 -> 1078774 bytes ui/src/app/form/page.tsx | 0 ui/src/app/gallery/page.tsx | 720 ++++++++++++ ui/src/app/globals.css | 26 - ui/src/app/layout.tsx | 60 +- ui/src/app/page.tsx | 544 +++++++-- ui/src/app/token/route.ts | 23 + ui/src/lib/auth0.ts | 8 + ui/src/lib/clientApi.ts | 36 + ui/src/lib/serverApi.ts | 8 + ui/src/middleware.ts | 12 + .../templates}/PaymentForm.js | 0 .../templates}/login.html | 0 .../auth0-templates => ui/templates}/page.js | 0 webui/src/app/favicon.ico | Bin 1078774 -> 0 bytes 32 files changed, 3282 insertions(+), 208 deletions(-) delete mode 100644 ui/public/file.svg delete mode 100644 ui/public/globe.svg rename {webui => ui}/public/logo.png (100%) delete mode 100644 ui/public/next.svg delete mode 100644 ui/public/vercel.svg delete mode 100644 ui/public/window.svg create mode 100644 ui/src/app/components/ClientLayoutEffect.tsx create mode 100644 ui/src/app/components/ImprinkAppBar.tsx create mode 100644 ui/src/app/components/hooks/useRoles.ts create mode 100644 ui/src/app/components/theme/MuiThemeProvider.tsx create mode 100644 ui/src/app/components/theme/ThemeContext.tsx create mode 100644 ui/src/app/components/theme/ThemeToggleButton.tsx create mode 100644 ui/src/app/components/theme/darkTheme.ts create mode 100644 ui/src/app/components/theme/lightTheme.ts create mode 100644 ui/src/app/form/page.tsx create mode 100644 ui/src/app/gallery/page.tsx delete mode 100644 ui/src/app/globals.css create mode 100644 ui/src/app/token/route.ts create mode 100644 ui/src/lib/auth0.ts create mode 100644 ui/src/lib/clientApi.ts create mode 100644 ui/src/lib/serverApi.ts create mode 100644 ui/src/middleware.ts rename {webui/auth0-templates => ui/templates}/PaymentForm.js (100%) rename {webui/auth0-templates => ui/templates}/login.html (100%) rename {webui/auth0-templates => ui/templates}/page.js (100%) delete mode 100644 webui/src/app/favicon.ico diff --git a/ui/next.config.ts b/ui/next.config.ts index e9ffa30..cb651cd 100644 --- a/ui/next.config.ts +++ b/ui/next.config.ts @@ -1,7 +1,5 @@ import type { NextConfig } from "next"; -const nextConfig: NextConfig = { - /* config options here */ -}; +const nextConfig: NextConfig = {}; export default nextConfig; diff --git a/ui/package-lock.json b/ui/package-lock.json index 7225517..e7222cf 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -8,6 +8,15 @@ "name": "ui", "version": "0.1.0", "dependencies": { + "@auth0/nextjs-auth0": "^4.7.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@fontsource/inter": "^5.2.6", + "@mui/icons-material": "^7.1.2", + "@mui/material": "^7.1.2", + "@mui/material-nextjs": "^7.1.1", + "@mui/system": "^7.1.1", + "axios": "^1.10.0", "next": "15.3.4", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -15,7 +24,7 @@ "devDependencies": { "@eslint/eslintrc": "^3", "@tailwindcss/postcss": "^4", - "@types/node": "^20", + "@types/node": "^20.19.1", "@types/react": "^19", "@types/react-dom": "^19", "eslint": "^9", @@ -51,6 +60,172 @@ "node": ">=6.0.0" } }, + "node_modules/@auth0/nextjs-auth0": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@auth0/nextjs-auth0/-/nextjs-auth0-4.7.0.tgz", + "integrity": "sha512-Q9R707LNPeV23NUgNc0QhkVD5g2L+fZTfZzH6q37vHlsEG6QVqwoXsteJlq7Os2689O1RjrHWPKX6kIjx1SP1A==", + "license": "MIT", + "dependencies": { + "@edge-runtime/cookies": "^5.0.1", + "@panva/hkdf": "^1.2.1", + "jose": "^5.9.6", + "oauth4webapi": "^3.1.2", + "swr": "^2.2.5" + }, + "peerDependencies": { + "next": "^14.2.25 || ^15.2.3", + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", + "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@edge-runtime/cookies": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@edge-runtime/cookies/-/cookies-5.0.2.tgz", + "integrity": "sha512-Sd8LcWpZk/SWEeKGE8LT6gMm5MGfX/wm+GPnh1eBEtCpya3vYqn37wYknwAHw92ONoyyREl1hJwxV/Qx2DWNOg==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/@emnapi/core": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", @@ -84,6 +259,152 @@ "tslib": "^2.4.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -238,6 +559,15 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@fontsource/inter": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.6.tgz", + "integrity": "sha512-CZs9S1CrjD0jPwsNy9W6j0BhsmRSQrgwlTNkgQXTsAeDRM42LBRLo3eo9gCzfH4GvV7zpyf78Ozfl773826csw==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -717,7 +1047,6 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -732,7 +1061,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -742,7 +1070,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -752,20 +1079,298 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mui/core-downloads-tracker": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.1.2.tgz", + "integrity": "sha512-0gLO1PvbJwSYe5ji021tGj6HFqrtEPMGKK4L1zWwRbhzrWWUumUJvMvJUsIgWQIYQsgOnhq9k2Fc1BxLGHDsAg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.1.2.tgz", + "integrity": "sha512-slqJByDub7Y1UcokrM17BoMBMvn8n7daXFXVoTv0MEH5k3sHjmsH8ql/Mt3s9vQ20cORDr83UZ448TEGcbrXtw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^7.1.2", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.1.2.tgz", + "integrity": "sha512-Z5PYKkA6Kd8vS04zKxJNpwuvt6IoMwqpbidV7RCrRQQKwczIwcNcS8L6GnN4pzFYfEs+N9v6co27DmG07rcnoA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/core-downloads-tracker": "^7.1.2", + "@mui/system": "^7.1.1", + "@mui/types": "^7.4.3", + "@mui/utils": "^7.1.1", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.1.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^7.1.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material-nextjs": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@mui/material-nextjs/-/material-nextjs-7.1.1.tgz", + "integrity": "sha512-6/tjmViYMI7XIqDTqK+n4t5B07YfVDq72emdBy/o8FLHsV7u477Ro0Aago2MQu8FrBQWDvzvvRkynIb02GjDBQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.4", + "@emotion/server": "^11.11.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "next": "^13.0.0 || ^14.0.0 || ^15.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/cache": { + "optional": true + }, + "@emotion/server": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", + "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", + "license": "MIT" + }, + "node_modules/@mui/private-theming": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.1.1.tgz", + "integrity": "sha512-M8NbLUx+armk2ZuaxBkkMk11ultnWmrPlN0Xe3jUEaBChg/mcxa5HWIWS1EE4DF36WRACaAHVAvyekWlDQf0PQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/utils": "^7.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.1.1.tgz", + "integrity": "sha512-R2wpzmSN127j26HrCPYVQ53vvMcT5DaKLoWkrfwUYq3cYytL6TQrCH8JBH3z79B6g4nMZZVoaXrxO757AlShaw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.1.1.tgz", + "integrity": "sha512-Kj1uhiqnj4Zo7PDjAOghtXJtNABunWvhcRU0O7RQJ7WOxeynoH6wXPcilphV8QTFtkKaip8EiNJRiCD+B3eROA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/private-theming": "^7.1.1", + "@mui/styled-engine": "^7.1.1", + "@mui/types": "^7.4.3", + "@mui/utils": "^7.1.1", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.3.tgz", + "integrity": "sha512-2UCEiK29vtiZTeLdS2d4GndBKacVyxGvReznGXGr+CzW/YhjIX+OHUdCIczZjzcRAgKBGmE9zCIgoV9FleuyRQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.1.tgz", + "integrity": "sha512-BkOt2q7MBYl7pweY2JWwfrlahhp+uGLR8S+EhiyRaofeRYUWL2YKbSGQvN4hgSN1i8poN0PaUiii1kEMrchvzg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/types": "^7.4.3", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", + "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", + "license": "MIT" + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", @@ -971,6 +1576,25 @@ "node": ">=12.4.0" } }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", + "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -1318,11 +1942,22 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.1.8", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -1338,6 +1973,15 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.35.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.0.tgz", @@ -2144,6 +2788,12 @@ "node": ">= 0.4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2170,6 +2820,17 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -2180,6 +2841,21 @@ "node": ">= 0.4" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2245,7 +2921,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2276,7 +2951,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2335,6 +3009,15 @@ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -2380,6 +3063,18 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2387,6 +3082,28 @@ "dev": true, "license": "MIT" }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2406,7 +3123,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -2474,7 +3190,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2531,6 +3246,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -2554,11 +3287,20 @@ "node": ">=0.10.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -2590,6 +3332,21 @@ "node": ">=10.13.0" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, "node_modules/es-abstract": { "version": "1.24.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", @@ -2663,7 +3420,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2673,7 +3429,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2711,7 +3466,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -2724,7 +3478,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2771,7 +3524,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -3293,6 +4045,12 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3331,6 +4089,26 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -3347,11 +4125,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3392,7 +4185,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -3417,7 +4209,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -3505,7 +4296,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3584,7 +4374,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3597,7 +4386,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -3613,7 +4401,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -3622,6 +4409,15 @@ "node": ">= 0.4" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3636,7 +4432,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -3779,7 +4574,6 @@ "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -4124,11 +4918,19 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -4144,6 +4946,18 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -4151,6 +4965,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4477,6 +5297,12 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4504,7 +5330,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -4527,7 +5352,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4557,6 +5381,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4623,7 +5468,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -4749,11 +5593,19 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/oauth4webapi": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.5.3.tgz", + "integrity": "sha512-2bnHosmBLAQpXNBLOvaJMyMkr4Yya5ohE5Q9jqyxiN+aa7GFCzvDN1RRRMrp0NkfqRR2MTaQNkcSUCCjILD9oQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4944,7 +5796,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -4953,6 +5804,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4977,9 +5846,17 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, "license": "MIT" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5052,7 +5929,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -5060,6 +5936,12 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5116,9 +5998,24 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -5167,7 +6064,6 @@ "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.16.0", @@ -5188,7 +6084,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -5513,6 +6408,15 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -5710,6 +6614,12 @@ } } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5727,7 +6637,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5736,6 +6645,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swr": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.3.tgz", + "integrity": "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/tailwindcss": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", @@ -6037,6 +6959,15 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6162,6 +7093,15 @@ "node": ">=18" } }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/ui/package.json b/ui/package.json index d0624a9..bc1a8a5 100644 --- a/ui/package.json +++ b/ui/package.json @@ -9,19 +9,28 @@ "lint": "next lint" }, "dependencies": { + "@auth0/nextjs-auth0": "^4.7.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@fontsource/inter": "^5.2.6", + "@mui/icons-material": "^7.1.2", + "@mui/material": "^7.1.2", + "@mui/material-nextjs": "^7.1.1", + "@mui/system": "^7.1.1", + "axios": "^1.10.0", + "next": "15.3.4", "react": "^19.0.0", - "react-dom": "^19.0.0", - "next": "15.3.4" + "react-dom": "^19.0.0" }, "devDependencies": { - "typescript": "^5", - "@types/node": "^20", + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", + "@types/node": "^20.19.1", "@types/react": "^19", "@types/react-dom": "^19", - "@tailwindcss/postcss": "^4", - "tailwindcss": "^4", "eslint": "^9", "eslint-config-next": "15.3.4", - "@eslint/eslintrc": "^3" + "tailwindcss": "^4", + "typescript": "^5" } } diff --git a/ui/public/file.svg b/ui/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/ui/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/public/globe.svg b/ui/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/ui/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/webui/public/logo.png b/ui/public/logo.png similarity index 100% rename from webui/public/logo.png rename to ui/public/logo.png diff --git a/ui/public/next.svg b/ui/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/ui/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/public/vercel.svg b/ui/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/ui/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/public/window.svg b/ui/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/ui/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/src/app/components/ClientLayoutEffect.tsx b/ui/src/app/components/ClientLayoutEffect.tsx new file mode 100644 index 0000000..d550be7 --- /dev/null +++ b/ui/src/app/components/ClientLayoutEffect.tsx @@ -0,0 +1,21 @@ +'use client'; + +import { useEffect } from 'react'; +import axios, { AxiosResponse } from 'axios'; + +export default function ClientLayoutEffect(): null { + useEffect(() => { + async function fetchData(): Promise+ + ++ +
+ + +- + Get started by editing{" "} +
++ src/app/page.tsx ++ . +- + Save and see your changes instantly. +
+{ + try { + const res: AxiosResponse = await axios.get('/token'); + console.log('Token response:', res.data); + } catch (error) { + console.error('Token fetch error:', error); + } + } + + fetchData().then(() => console.log('Ok')); + }, []); + + return null; +} diff --git a/ui/src/app/components/ImprinkAppBar.tsx b/ui/src/app/components/ImprinkAppBar.tsx new file mode 100644 index 0000000..41b6108 --- /dev/null +++ b/ui/src/app/components/ImprinkAppBar.tsx @@ -0,0 +1,238 @@ +'use client'; + +import { + AppBar, + Avatar, + Box, + Button, + Divider, + IconButton, + Menu, + MenuItem, + Paper, + Toolbar, + Typography, + useMediaQuery, + useTheme as useMuiTheme, +} from '@mui/material'; +import { + Menu as MenuIcon, + Home, + PhotoLibrary, + ShoppingBag, + Store, + Dashboard, + AdminPanelSettings, + Api, + BugReport, +} from '@mui/icons-material'; +import { useUser } from '@auth0/nextjs-auth0'; +import {useState, MouseEvent, JSX} from 'react'; +import ThemeToggleButton from '@/app/components/theme/ThemeToggleButton'; +import useRoles from '@/app/components/hooks/useRoles'; +import { useTheme } from '@/app/components/theme/ThemeContext'; + +interface NavLink { + label: string; + href: string; + icon: JSX.Element; + show: boolean; +} + +export default function ImprinkAppBar() { + const { user, isLoading } = useUser(); + const { isMerchant, isAdmin } = useRoles(); + const [anchorEl, setAnchorEl] = useState (null); + const theme = useMuiTheme(); + const { isDarkMode, toggleTheme } = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('md')); + + const handleMenuOpen = (event: MouseEvent ) => { + setAnchorEl(event.currentTarget); + }; + + const handleMenuClose = () => { + setAnchorEl(null); + }; + + const navigationLinks: NavLink[] = [ + { label: 'Home', href: '/', icon: , show: true }, + { label: 'Gallery', href: '/gallery', icon: , show: true }, + { label: 'Orders', href: '/orders', icon: , show: true }, + { label: 'Merchant', href: '/merchant', icon: , show: isMerchant }, + ]; + + const adminLinks: NavLink[] = [ + { label: 'Dashboard', href: '/dashboard', icon: , show: isMerchant }, + { label: 'Admin', href: '/admin', icon: , show: isAdmin }, + { label: 'Swagger', href: '/swagger', icon: , show: isAdmin }, + { label: 'SEQ', href: '/seq', icon: , show: isAdmin }, + ]; + + const visibleLinks = navigationLinks.filter(link => link.show); + const visibleAdminLinks = adminLinks.filter(link => link.show); + + const renderDesktopNavigation = () => ( + + {visibleLinks.map(link => ( + + ))} + + ); + + const renderAdminBar = () => { + if (!visibleAdminLinks.length || isMobile) return null; + + return ( ++ + ); + }; + + const renderMobileMenu = () => ( + <> ++ ++ Admin Tools + + {visibleAdminLinks.map(link => ( + + ))} ++ + + > + ); + + return ( + <> ++ + + {renderAdminBar()} + > + ); +} \ No newline at end of file diff --git a/ui/src/app/components/hooks/useRoles.ts b/ui/src/app/components/hooks/useRoles.ts new file mode 100644 index 0000000..1f425dd --- /dev/null +++ b/ui/src/app/components/hooks/useRoles.ts @@ -0,0 +1,71 @@ +import { useState, useEffect } from 'react'; +import { useUser } from '@auth0/nextjs-auth0'; +import clientApi from '@/lib/clientApi'; + +interface RoleResponse { + roleName: string; +} + +export const useRoles = () => { + const { user } = useUser(); + const [roles, setRoles] = useState+ {isMobile && renderMobileMenu()} + ++ Imprink + + {!isMobile && ( + <> +{renderDesktopNavigation()} ++ {isLoading ? ( + + + ) : user ? ( +Loading... ++ + ) : ( ++ {user.name} + ++ + + + )} + > + )} +([]); + const [isLoading, setIsLoading] = useState (false); + const [error, setError] = useState (null); + + useEffect(() => { + const fetchUserRoles = async () => { + if (!user) { + setRoles([]); + setError(null); + return; + } + + setIsLoading(true); + setError(null); + + try { + const response = await clientApi.get ('/users/me/roles'); + const userRoles = response.data.map(role => role.roleName.toLowerCase()); + setRoles(userRoles); + } catch (err) { + console.error('Failed to fetch user roles:', err); + setError(err as Error); + setRoles([]); + } finally { + setIsLoading(false); + } + }; + + fetchUserRoles().then(r => console.log(r)); + }, [user]); + + const hasRole = (roleName: string): boolean => { + return roles.includes(roleName.toLowerCase()); + }; + + const hasAnyRole = (roleNames: string[]): boolean => { + return roleNames.some(roleName => hasRole(roleName)); + }; + + const hasAllRoles = (roleNames: string[]): boolean => { + return roleNames.every(roleName => hasRole(roleName)); + }; + + const isMerchant = hasAnyRole(['merchant', 'admin']); + const isAdmin = hasRole('admin'); + const isCustomer = hasRole('customer'); + + return { + roles, + isLoading, + error, + hasRole, + hasAnyRole, + hasAllRoles, + isMerchant, + isAdmin, + isCustomer, + }; +}; + +export default useRoles; diff --git a/ui/src/app/components/theme/MuiThemeProvider.tsx b/ui/src/app/components/theme/MuiThemeProvider.tsx new file mode 100644 index 0000000..95a9f28 --- /dev/null +++ b/ui/src/app/components/theme/MuiThemeProvider.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { ThemeProvider } from '@mui/material/styles'; +import CssBaseline from '@mui/material/CssBaseline'; +import { darkTheme } from './darkTheme'; +import { lightTheme } from './lightTheme'; +import { useTheme } from './ThemeContext'; +import { ReactNode } from 'react'; + +interface MuiThemeProviderProps { + children: ReactNode; +} + +export default function MuiThemeProvider({ children }: MuiThemeProviderProps) { + const { isDarkMode } = useTheme(); + + return ( + + + ); +} diff --git a/ui/src/app/components/theme/ThemeContext.tsx b/ui/src/app/components/theme/ThemeContext.tsx new file mode 100644 index 0000000..ed0aad5 --- /dev/null +++ b/ui/src/app/components/theme/ThemeContext.tsx @@ -0,0 +1,74 @@ +'use client'; + +import React, { + createContext, + useContext, + useState, + useEffect, + ReactNode, +} from 'react'; + +interface ThemeContextType { + isDarkMode: boolean; + toggleTheme: () => void; +} + +const ThemeContext = createContext+ {children} + (undefined); + +interface ThemeContextProviderProps { + children: ReactNode; +} + +export function ThemeContextProvider({ children }: ThemeContextProviderProps) { + const [isDarkMode, setIsDarkMode] = useState(true); + const [isInitialized, setIsInitialized] = useState(false); + + useEffect(() => { + const savedTheme = localStorage.getItem('theme-preference'); + const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + + const shouldBeDark = savedTheme ? savedTheme === 'dark' : systemPrefersDark; + + setIsDarkMode(shouldBeDark); + setIsInitialized(true); + }, []); + + useEffect(() => { + if (!isInitialized) return; + + const savedTheme = localStorage.getItem('theme-preference'); + if (savedTheme) return; + + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + const handleChange = (e: MediaQueryListEvent) => { + setIsDarkMode(e.matches); + }; + + mediaQuery.addEventListener('change', handleChange); + return () => mediaQuery.removeEventListener('change', handleChange); + }, [isInitialized]); + + const toggleTheme = () => { + const newTheme = !isDarkMode; + setIsDarkMode(newTheme); + localStorage.setItem('theme-preference', newTheme ? 'dark' : 'light'); + }; + + if (!isInitialized) { + return null; + } + + return ( + + {children} + + ); +} + +export function useTheme(): ThemeContextType { + const context = useContext(ThemeContext); + if (!context) { + throw new Error('useTheme must be used within a ThemeContextProvider'); + } + return context; +} \ No newline at end of file diff --git a/ui/src/app/components/theme/ThemeToggleButton.tsx b/ui/src/app/components/theme/ThemeToggleButton.tsx new file mode 100644 index 0000000..e40faa3 --- /dev/null +++ b/ui/src/app/components/theme/ThemeToggleButton.tsx @@ -0,0 +1,26 @@ +'use client'; + +import { IconButton } from '@mui/material'; +import { useTheme } from './ThemeContext'; +import {JSX} from "react"; + +export default function ThemeToggleButton(): JSX.Element { + const { isDarkMode, toggleTheme } = useTheme(); + + return ( ++ {isDarkMode ? '🌙' : '☀️'} + + ); +} diff --git a/ui/src/app/components/theme/darkTheme.ts b/ui/src/app/components/theme/darkTheme.ts new file mode 100644 index 0000000..2afcf02 --- /dev/null +++ b/ui/src/app/components/theme/darkTheme.ts @@ -0,0 +1,276 @@ +'use client' + +import { createTheme, ThemeOptions } from '@mui/material/styles'; + +export const darkTheme: ThemeOptions = createTheme({ + palette: { + mode: 'dark', + primary: { + main: '#6366f1', + light: '#818cf8', + dark: '#4f46e5', + contrastText: '#ffffff', + }, + secondary: { + main: '#f59e0b', + light: '#fbbf24', + dark: '#d97706', + contrastText: '#000000', + }, + background: { + default: '#0f0f23', + paper: '#1a1a2e', + }, + text: { + primary: '#f8fafc', + secondary: '#cbd5e1', + }, + error: { + main: '#ef4444', + light: '#f87171', + dark: '#dc2626', + }, + warning: { + main: '#f59e0b', + light: '#fbbf24', + dark: '#d97706', + }, + info: { + main: '#06b6d4', + light: '#22d3ee', + dark: '#0891b2', + }, + success: { + main: '#10b981', + light: '#34d399', + dark: '#059669', + }, + divider: '#334155', + }, + typography: { + fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', + h1: { + fontSize: '2.5rem', + fontWeight: 700, + lineHeight: 1.2, + letterSpacing: '-0.025em', + }, + h2: { + fontSize: '2rem', + fontWeight: 600, + lineHeight: 1.3, + letterSpacing: '-0.025em', + }, + h3: { + fontSize: '1.5rem', + fontWeight: 600, + lineHeight: 1.4, + letterSpacing: '-0.015em', + }, + h4: { + fontSize: '1.25rem', + fontWeight: 600, + lineHeight: 1.4, + }, + h5: { + fontSize: '1.125rem', + fontWeight: 600, + lineHeight: 1.5, + }, + h6: { + fontSize: '1rem', + fontWeight: 600, + lineHeight: 1.5, + }, + body1: { + fontSize: '1rem', + lineHeight: 1.6, + fontWeight: 400, + }, + body2: { + fontSize: '0.875rem', + lineHeight: 1.6, + fontWeight: 400, + }, + button: { + fontSize: '0.875rem', + fontWeight: 500, + textTransform: 'none', + letterSpacing: '0.025em', + }, + }, + shape: { + borderRadius: 12, + }, + shadows: [ + 'none', + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + ], + components: { + MuiCssBaseline: { + styleOverrides: { + body: { + scrollbarWidth: 'thin', + scrollbarColor: '#6366f1 #1a1a2e', + '&::-webkit-scrollbar': { + width: '8px', + }, + '&::-webkit-scrollbar-track': { + background: '#1a1a2e', + }, + '&::-webkit-scrollbar-thumb': { + background: '#6366f1', + borderRadius: '4px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: { + borderRadius: '8px', + padding: '10px 24px', + fontSize: '0.875rem', + fontWeight: 500, + boxShadow: 'none', + '&:hover': { + boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)', + transform: 'translateY(-1px)', + }, + '&:active': { + transform: 'translateY(0)', + }, + }, + contained: { + background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', + '&:hover': { + background: 'linear-gradient(135deg, #5b21b6 0%, #7c3aed 100%)', + }, + }, + outlined: { + borderWidth: '1.5px', + '&:hover': { + borderWidth: '1.5px', + backgroundColor: 'rgba(99, 102, 241, 0.08)', + }, + }, + }, + }, + MuiTextField: { + styleOverrides: { + root: { + '& .MuiOutlinedInput-root': { + borderRadius: '8px', + backgroundColor: 'rgba(255, 255, 255, 0.02)', + '&:hover .MuiOutlinedInput-notchedOutline': { + borderColor: '#6366f1', + }, + '&.Mui-focused .MuiOutlinedInput-notchedOutline': { + borderColor: '#6366f1', + borderWidth: '2px', + }, + }, + }, + }, + }, + MuiCard: { + styleOverrides: { + root: { + background: 'linear-gradient(145deg, #1a1a2e 0%, #16213e 100%)', + border: '1px solid rgba(99, 102, 241, 0.1)', + backdropFilter: 'blur(20px)', + '&:hover': { + border: '1px solid rgba(99, 102, 241, 0.2)', + transform: 'translateY(-2px)', + boxShadow: '0 20px 40px rgba(0, 0, 0, 0.3)', + }, + transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', + }, + }, + }, + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: 'none', + backgroundColor: '#1a1a2e', + border: '1px solid rgba(99, 102, 241, 0.1)', + }, + }, + }, + MuiAppBar: { + styleOverrides: { + root: { + background: 'rgba(26, 26, 46, 0.8)', + backdropFilter: 'blur(20px)', + borderBottom: '1px solid rgba(99, 102, 241, 0.1)', + boxShadow: '0 8px 32px rgba(0, 0, 0, 0.3)', + }, + }, + }, + MuiDrawer: { + styleOverrides: { + paper: { + background: 'linear-gradient(180deg, #1a1a2e 0%, #16213e 100%)', + border: 'none', + borderRight: '1px solid rgba(99, 102, 241, 0.1)', + }, + }, + }, + MuiChip: { + styleOverrides: { + root: { + background: 'rgba(99, 102, 241, 0.1)', + color: '#818cf8', + border: '1px solid rgba(99, 102, 241, 0.2)', + '&:hover': { + background: 'rgba(99, 102, 241, 0.2)', + }, + }, + }, + }, + MuiTab: { + styleOverrides: { + root: { + textTransform: 'none', + fontWeight: 500, + fontSize: '0.875rem', + '&.Mui-selected': { + color: '#6366f1', + }, + }, + }, + }, + MuiTabs: { + styleOverrides: { + indicator: { + background: 'linear-gradient(90deg, #6366f1, #8b5cf6)', + height: '3px', + borderRadius: '3px', + }, + }, + }, + }, +}); \ No newline at end of file diff --git a/ui/src/app/components/theme/lightTheme.ts b/ui/src/app/components/theme/lightTheme.ts new file mode 100644 index 0000000..7b7f812 --- /dev/null +++ b/ui/src/app/components/theme/lightTheme.ts @@ -0,0 +1,276 @@ +'use client' + +import { createTheme, ThemeOptions } from '@mui/material/styles'; + +export const lightTheme : ThemeOptions = createTheme({ + palette: { + mode: 'light', + primary: { + main: '#6366f1', + light: '#818cf8', + dark: '#4f46e5', + contrastText: '#ffffff', + }, + secondary: { + main: '#f59e0b', + light: '#fbbf24', + dark: '#d97706', + contrastText: '#000000', + }, + background: { + default: '#f8fafc', + paper: '#ffffff', + }, + text: { + primary: '#0f172a', + secondary: '#475569', + }, + error: { + main: '#ef4444', + light: '#f87171', + dark: '#dc2626', + }, + warning: { + main: '#f59e0b', + light: '#fbbf24', + dark: '#d97706', + }, + info: { + main: '#06b6d4', + light: '#22d3ee', + dark: '#0891b2', + }, + success: { + main: '#10b981', + light: '#34d399', + dark: '#059669', + }, + divider: '#e2e8f0', + }, + typography: { + fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', + h1: { + fontSize: '2.5rem', + fontWeight: 700, + lineHeight: 1.2, + letterSpacing: '-0.025em', + }, + h2: { + fontSize: '2rem', + fontWeight: 600, + lineHeight: 1.3, + letterSpacing: '-0.025em', + }, + h3: { + fontSize: '1.5rem', + fontWeight: 600, + lineHeight: 1.4, + letterSpacing: '-0.015em', + }, + h4: { + fontSize: '1.25rem', + fontWeight: 600, + lineHeight: 1.4, + }, + h5: { + fontSize: '1.125rem', + fontWeight: 600, + lineHeight: 1.5, + }, + h6: { + fontSize: '1rem', + fontWeight: 600, + lineHeight: 1.5, + }, + body1: { + fontSize: '1rem', + lineHeight: 1.6, + fontWeight: 400, + }, + body2: { + fontSize: '0.875rem', + lineHeight: 1.6, + fontWeight: 400, + }, + button: { + fontSize: '0.875rem', + fontWeight: 500, + textTransform: 'none', + letterSpacing: '0.025em', + }, + }, + shape: { + borderRadius: 12, + }, + shadows: [ + 'none', + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + '0 25px 50px -12px rgba(0, 0, 0, 0.15)', + ], + components: { + MuiCssBaseline: { + styleOverrides: { + body: { + scrollbarWidth: 'thin', + scrollbarColor: '#6366f1 #f1f5f9', + '&::-webkit-scrollbar': { + width: '8px', + }, + '&::-webkit-scrollbar-track': { + background: '#f1f5f9', + }, + '&::-webkit-scrollbar-thumb': { + background: '#6366f1', + borderRadius: '4px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: { + borderRadius: '8px', + padding: '10px 24px', + fontSize: '0.875rem', + fontWeight: 500, + boxShadow: 'none', + '&:hover': { + boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)', + transform: 'translateY(-1px)', + }, + '&:active': { + transform: 'translateY(0)', + }, + }, + contained: { + background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', + '&:hover': { + background: 'linear-gradient(135deg, #5b21b6 0%, #7c3aed 100%)', + }, + }, + outlined: { + borderWidth: '1.5px', + '&:hover': { + borderWidth: '1.5px', + backgroundColor: 'rgba(99, 102, 241, 0.08)', + }, + }, + }, + }, + MuiTextField: { + styleOverrides: { + root: { + '& .MuiOutlinedInput-root': { + borderRadius: '8px', + backgroundColor: 'rgba(241, 245, 249, 0.5)', + '&:hover .MuiOutlinedInput-notchedOutline': { + borderColor: '#6366f1', + }, + '&.Mui-focused .MuiOutlinedInput-notchedOutline': { + borderColor: '#6366f1', + borderWidth: '2px', + }, + }, + }, + }, + }, + MuiCard: { + styleOverrides: { + root: { + background: 'linear-gradient(145deg, #ffffff 0%, #f8fafc 100%)', + border: '1px solid rgba(99, 102, 241, 0.1)', + backdropFilter: 'blur(20px)', + '&:hover': { + border: '1px solid rgba(99, 102, 241, 0.2)', + transform: 'translateY(-2px)', + boxShadow: '0 20px 40px rgba(99, 102, 241, 0.15)', + }, + transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', + }, + }, + }, + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: 'none', + backgroundColor: '#ffffff', + border: '1px solid rgba(99, 102, 241, 0.1)', + }, + }, + }, + MuiAppBar: { + styleOverrides: { + root: { + background: 'rgba(255, 255, 255, 0.8)', + backdropFilter: 'blur(20px)', + borderBottom: '1px solid rgba(99, 102, 241, 0.1)', + boxShadow: '0 8px 32px rgba(99, 102, 241, 0.1)', + color: '#0f172a', + }, + }, + }, + MuiDrawer: { + styleOverrides: { + paper: { + background: 'linear-gradient(180deg, #ffffff 0%, #f8fafc 100%)', + border: 'none', + borderRight: '1px solid rgba(99, 102, 241, 0.1)', + }, + }, + }, + MuiChip: { + styleOverrides: { + root: { + background: 'rgba(99, 102, 241, 0.7)', + border: '1px solid rgba(99, 102, 241, 0.2)', + '&:hover': { + background: 'rgba(99, 102, 241, 0.9)', + }, + }, + }, + }, + MuiTab: { + styleOverrides: { + root: { + textTransform: 'none', + fontWeight: 500, + fontSize: '0.875rem', + '&.Mui-selected': { + color: '#6366f1', + }, + }, + }, + }, + MuiTabs: { + styleOverrides: { + indicator: { + background: 'linear-gradient(90deg, #6366f1, #8b5cf6)', + height: '3px', + borderRadius: '3px', + }, + }, + }, + }, +}); \ No newline at end of file diff --git a/ui/src/app/favicon.ico b/ui/src/app/favicon.ico index 718d6fea4835ec2d246af9800eddb7ffb276240c..b0ae2d4e095a9f6b2fc1d1a6ab303466214a52d5 100644 GIT binary patch literal 1078774 zcmX_{V{j(@*7f6DF(zwr$&**tYTB=e*B-s=BMI`s?of-)sHW z?r;S;aRgW#SP&2p1W5@IB@htsNDvT6Q~=aJZ*t3x=l^-Y*h^?Sfq=lF{pSV+NzcRr zK?VVl6cJQ$&%F4wsC6B4AP6&AZhL|^4i8R_H iAs1=GyeKm-!axoo5;UeM6Z}ra=L8S#nh8VNW#WlYW;F$e; z0)=zp^P23no%p5rCr#e;(Bs-hf#3NDWl!t&d-w5T+4%T+c1e9XVkF?QeuAOn;*PO- zv-^=`Ztg05x1(^|v&!$O<5%$BO=}pk1Je0S^mni__nY=d0x~n&7+{z*6M*9MUFmE* z-5&HC+3h kzK4Txx1p6I9%EYHImi<$e(Gj2W^OmbTH1}61J@(4LIavoVuc7W8hyJ7X zWOr@S%CRTcVe%5X0qb$zacpH$O_P{4;2ET{t#*fiQgF5XIw*!?t>+xVNS(&5<2U{Y zFH?t{2FAWufsX5%Ns7)FIWpcwT<>8(7WCXgAKdqz{>Y?3Zc{3Hqy8qHvZK!|SU!~J z(rVCv00+{J4;{F!_+-`jn9Sze^YR1FE0BQ9U#!@jsz{23mA!cbVkV^Lh}+UROc!1I zHjMDzXuHmR4--WAtrHuZ9uz9q&vp-_mBLSo0$yIF{E?PmOJdf$=W9sxQ;8`FrDWNp zssw$&{I&37$p*69Y&f(91wK6+D+C8HniF@P=3i#cn~XUNkxq`icHh`^CN-;mE&WYO zocAX+BuovKY~uwaF7MV3YZ9%Ylu_S3!B53nlJR~=AdW(?W8{t|G4di `GX@E)6fHlKh=&*w-1}oW4l^NoYe {rP4{~eN`dQdxPUS@+KV0j zVEHYPnCCnAI5XU61bPIl@)JnKdE&Y8HHK9;0qxlb&&72&uXM#6ho+mCx;5sAlxvB| z+Ak}uRSpkNc DXm*C%pX(zElP$;Up+r!)wNsr#ck2C-TPpo;=C72nniEfO zsydm*EDP3Lu&zI~PZ){!e6Y{{TZEn$$M>Vi$LJ_88>WjOo~Q-%065(Vw*~*K`BWo= zGlD-tIsQ5^phsW&zm`=Cje{&nq3@V^ogg%fEA2H%NlrKsA^~M1K!gN7TM{ZVk}T%m zyfvJ-(by~GGW+#lP&!9AQJB3BQ0wN-!I&c!Y2{9nf^17kH2smNu&o>;>Al@)Bj>d% z8B(NyZ}mkY2DHlNhUB;_JIU6eP9?Ish?o Y|#w<5o4n zB*#5zL{8jb|0X>lQ8PT)LK=d!JDptZH56)jji6l%dK!$Gkh>&4c+r@z o;QnCXezrKZ zn}<$H+gk-j{^v7iP#1z%5{dU#rE}g<6d}vcwao`r(Rn;(T2$kV31G5>(JC6VB@;Se zomqs*OB60%#yN$r8ntXM <#i9wHFnb#NbpsP$%XZ!8+H-e zdL~32?p (`hHV|4y*yVk2fZW5{agQ<2ZkJz7 z+RlqN5p xD}5@#cLszqV@qn9u$9Nd~qz!e@DS|V2HO?Pk^@JxfF5GDi8zgAB&7{tyRPWNdC z%yaqARrF{tRiBMKC)7SicaRz08qHtKcYFqs0M*(Tz&FjwbF-5yFblZoSyPoapg}g1 zHoSygzh&83k55T#P4c4C9lXX;aIj_=!GJ+V@!SFP?hu#}WB~6A9{>46TXd6!yxQ_P z9%n`b-s^kx?hkEO3%TjGIF@K{1^JDNz>a^3%XMB!IraYC7!CgSc7>vB^Bh|9?~mQ` ztJk>+ 3{FFo!5fK}M+t(us8sTG}~(urs3@Qtacx zef|OQFw&D^4dx^=Co%H+a)N)D{=rR9I9SL=IkL8>)~_5Y;v}0eKN7zKpX1r8ZN#YA zJ&83Ylg5;?;*(&*&xi>XqvY}} vvYwQ zvR_g0q(}yk5Hdo&1w5LY|4d`oHZ4bV9BV0PT25oGo0|dT=J|G!i!tF;=uBUj-W&Je zF@8# 5;QM~;wK^MK%c(~-aqLmP?ivyIIATYU$@UV-zD6n;j>ET3*x45^fXGG8h2=3&> zG}Vz11pX#&$a(S7eZBDql4U)*V8Rpv NY|2S9cPzP< zIzuCYeD?sFG`6PqK6WQpu0_yoTFBSt@){xzGAYYb1z9*S@!-K*RM(90X_vE86Bbow z6zhd>&g4(oD(O^XnsHZFpAN+LUN*jc0ii+KJmCAhVJyo%d9kxVWLeOs_&gzR`tA$@ zlbO!1*eM(HpK!q|<@PF=A+Bd}+u3Z$B`Ql!tCICRSe?;wYiu}msN)a}zOi1)yFJvE zI!3B}NXd?$b;nE0^uzV+>1V 4L zmAwv=3`E)sMBpsfUutYZXYk|-f3{PIGYW-SgwM%nE$vdq&p~r75QrlaN90mED`Kr0 zlqyQH&=7YMOOnOlGDXtl^Film4+AZX{N?3o1Wovt=q}^A3FaVn$lNo@3K@}uqZE&% zmR8cQea>1+H0T!kVG2x3gV_BgdjVMS%l6;)iVnV-G1{Z7OG*>8n2&B=^6@yRl%vA< z77aSFXajV(2ZIv&&DLZ vErHW8(qf>{8CLr}nBqy(~p;XtttLegcRrvn@;~H@SUm8{}S%#ay6^hE~4qbNf%2 z!;UstxPVaTWD1(y_ -Xj*Xl5PN?B8CY5Ej) zIhS_O*OsXgQl}fAWFztp_^^mRPvExy)v49~58$>WVHM)Gpuc({)$R?Z%-r$OcLlN9 zS0qd2rg$;nyCcIDbmdH$)czU~x*HHRJIsFxW01>)4p7H$3X-@fCx#>+Mui1W+h%t^ z+(moowma-2% qnZvc5R3!SokK)1z>wN?6fK7n$Lm;P8aQYk^ zSh0KP_z}C&BK;}P-pFS_u@+J6i*EmGwx^sC|ImFys+wSVT-fp5jkt>NHNebi8ts?d z);@KKrk+(xl8anTi~rU9I?d{?l1b$n^FW|%_`jX= e)-XD$BaJAyckKoj+yds|s z&-W)cpGPZs- Uj*l&v6|$U4D;+ zjO~X(T;1 LU#Dak2Yo!jT2M=y0*6j(Vksb4|g0{)?(V@64l#1FtLvoPuO&5cZ)-S zO@gYDhG`y(%v9=}#q;r|&mwtUaf{fB9XVl4^Q2kH>)!a=7q|D_{CI(7QRsZn9kc$x zoFZzWJW|@RNg%K}Y|8{Dn1&Om_p2iNJUmfdKwkZ^QGrQ!%}(lRT6YMA@QK>Qz4SUQ z(^G?8vr&&CC%quTJKq?8i9+?Od2hla#>lJLWT_ZV(u9A*nPDS~?&?4O`xj`N%l;7O z3o`a7ye@Wc4QHMV`uq1~-4^JpLsY+D=m|pFjwa}!vUM_mN5GIgsutbWSSBEkQFGt{ z2Thq&>$=nBe%X!pwTaSir-1N#HRpR({QA2q=WEgI%6sp&CX?@bFY 3P$o^?dzt;9U3lOxx~r+3tOQ!*}J{_nGjkkMQGm`?==h zYettJ=<)h=xpDqabGl*~SPfWFRM5h0JJjT-_d~sUe62|vg9B8_9j!$;Y7O-BXiT8n zZzCA>g!e3^58;0WL1}#lx{)1C-E$m|$lp5CA8k4kMeeoH#PrEY#M|MiG=Et%Kv`Ud}K z*dVJyL3E%FazuHJIt*`|?O%vN(5>*Go#>~XaE|+sxa%8plfS)PdLWn2W{d|;F|%7( z^CbV(kx#Ac2U^G}FBZ1wV?<_!cY);va8D ?<9%IlG`y!=Iu>*=#(@i$_bx z50d`fQ2UOYxiWV6M<=Wu!j4{MFv_m%C17PkUBjn8<|1G;3)X r}dTWN{3SxG)xXD`UjmIIcLwiUq*%bAF|y(=k>lQ`Jbz| zKg;BO@2-xsy~^lq@?7UnJ}xq+k&b~?!;RHKjl% Nvm_U{)L%VSMe&=feweE<}grWhz{M(L)7+bGV2fKqd5x@hl9 z4$2YUDBE2P!m#yLYGp{p*?Dlg^Rjo#qjpksQkNT10e4i{eEN;rwM60Ci@8cks~*BG zcM%aQGJk9zF&UX`@2zub(}9z+d6+os6eg{1Ijfl2m#dJ)!hk8e=b9vT;23NNf4= zrRKj^D&?LhKH(`aPq $Hp&O >lbsKGn0kWN4{q7~-M%~m5D~q8GZVb{I z1Q~CUxkxM`F!Zxmp;ju$)44UxQ{_nW&5?yEXZ9kt$40`UB)KNuQqFL9ZHYtwr7yHZ zEq2{1@RJtC8#u`52j?p=`mg3rX>~mmkqC`_b5^83!R1hNNHuc!!6g@?HG%$s1yA34 z)Sk1W%Z;9Ub-tIr?}6?2@6Rg2x21PN@5e~SE$j2$sA+X#TWM&NbEzuk-S8YzHEu4= zuwe5a|EP3iNlNb$%4i9ZX}fLiZ(+X^= gJeZrnFYFF8{1=#IT+J1ok60V2GjxN%d=A&hvEP@3C(FY z2aUXTXyz>+W=f7I0@c Ueo2^$ zWZ?~$w01SkwvS)N^`nI~bFG !l<$+iX$4CIg!iFUd&o-MR?86t{80;q_ z-kT3H?MLv0MC;HKi^>}=Xdo%^Iw~bmuS5^%wV|kj)mK^=W-|8c^Zb3X#(m?%g0FoT zW%BdzIhp%1J)O4PObD>!z|;&$pA031PTnK`vL4 al6+1skC&GjCcp6_sePUtvn2t%lIyQ$K_Yf-jzUjTU#iK05j_FR|v6^ z1(~C#>-%y>w%=`t-!bOam;Cph-($ c XQd>>JKzVSgwxS%OA z(q!>2MtU^G=*%D=_U_p|ArJdE=RoBdkI4g}#ObX(cm9Mr>TaW>&Qk5RTB*T3HH` z(-u w%l{He-lgaBA;4#e=zPpG=( zk4KOo+ |sB xo^MWe-!|rL)7?Lzq49sPPI97H;+Op8fdxSDulZ(k%5>06hq7^6sY^SIJD+lp zgL5kX8-rfzVQIxpt=jpX`Ba(=PjA-JZ7H5Ih2JY;snG|glM^PfezApx<2}LLqUc=_ zSD&)EDasz2joOd2&kQ5R6zbYQ<;Dr-4D>Rl18n70_pHfearuF_chn)6*!UqCvIS7C z;CAzCBUo9F>heQTX+`#nI-p&R2209c*klPgY(*-DlNY#a928m4m4nELH{J PU7qZcA|7tfH9*@fuG>-;;~lo$+?;0m4(t`&aI%;V$mr|19E7YJ?Ul{K&6 z)DrVv`I+RvdC6f1-dRvYv}iZnY4jZumeOEr0g8YDMI2?Tputlj)66&vDC{@sYLt5p zztc#)k4V4w@AsCkv+dViLcf8Pp0_153mIrFi$gIZ9z(xgC?o7QB!QBh_`ir1oDx5H zBt*=2#W?J;Q1p0g%*@Q(zV*KMzh98PM`J%n^}1a9x9N|~+)x%+G#KG;;h#v4JD}jH z4t%uUl80TS>dw22MCyhk6ZrP=AJPZ!Od@)HSko(q=6FU3R^F7v+txsS_a^Aa*3DW_ zkhVtAuD7`J8IusZQ=Gm3V0}?m06ZG N<^Y*dQl=LmkTo;{?RVLvK}EL83h9w=@9 z#hN^Obg#DMjcWQEnFQh44$THTZ(s9zYqr-Qf#}F&?e~Mp>>bltkw@sgYW_)AVDoFT z*wuVEs;g`y&tzpm(n~+@*O4d;j$YBGw?*|fHJ>*FI_wXZ_J~aX+&I(8a6>87_mK ftAty=h zsSz+1lvh?iCd~uFAYS+Nredsq8*9`{M`U@$_sc2gd*b{0d&cjRuzMeq|K<&M2G}*~ z?gP~%=E$(9XS%h&Ecj9j>p-eSCmpF2gu;%(2**x=YMKD9s6AZyBqg$VGCZa2e7R12 zZ_xG5|1JO3!0-F{hF|hs!T)ad9ht#l`?u9~1Rq-IcWsEt$fFnvI!RfhAP*s)6ESs$ zNrpHE2(V-bP}%r(sBxt3ziKQ1s&Rj(v}in@>rn>>b3k`Zj|UocIiynjyDlK#q;<`Z zA>ubXkl_GAE=3PBbPKr|1xA1Fnx_=r27ENw45m{KgX1bbVsIb~b !K63e*#icbW< 9L!2K1$8Ip(RE17=uBH}8j-P%Q2f48U@ZsaXQ;y>)aKLpJ?QG 0iLPF6#niW&Q>rqsQQORlr1G{exGrafE-x)p6+aE )StrRrhtG46oub$7GZ$`fd;pfk{oc8;e!?$*VFps5dI|eR2egm$8^)V zULz8YR^DgF`j7{%zmW|HpBcndy|Nc>;@Fz-++3iN)?P!+lE%RgC=V>uAWlS-Wxh#U z3{9lVC2&O~#MpEg=JX|10!$}?PXr*ERNgcGvSXQ^jK;xErQ@@d?nZ6`+#pr%^ d&u4}6K9P<&o_8$=k%qMuT*OevI-)*YBce=5$AHCuKwvr07+ zKF(y*rYE3a;T}8gR5uhx1WK0)`+*weufxM6mRpIaU6P`Y<2M|=5@t{HF6Q#3*C@n3 z_)<8rMJ_=$&(OyjJ(bHP%GuA1u`DK%tpDrjAa_3!KUsrlaEy$gu3`5{Tx-wou~5u_ zx9cDD;M%Y~K}WDE#7OSeQodnrD6DV}%ErB9p$iR
VbbUwBzl2!?LhBb&NnF5eT^)3YgZ4jtKq&?b}w8HJ@x zRo3iOMvHlyYjn@uOUm`z`S+0CH*2iV<*6ON%_ib`Kx>mCQ7!bso$AYCf0T0opKhHy zwkOv#2;l&Ul<}uUiTAi-Q@@Bnm@m}fp-8A=7NGwR7Nm&9DwF_~XoCOgBep-xbl*zE z=;T`ib`gm(ODN%^qS_SN5yF5t*r|;~C!e_**|1?UT2VB*Kt8Cc48|YmyOS5Mg4~Jz zP~XuAqY7Wuc=8U9p@trrR2Ie3kSWp=pP1oejDtY;!NuW*UVFR;@tc{8+mLQn^%{|W zHotW@X-}vWCd=2=1hqSEgInz?8iTEO}3vgmah^R%qlJ0VZLtG~yNh$Q){8US3ZA zLL1sRp}_W$w$1u4-4>ze(&x}mHY!hsi3>BAd$%P@OR%-)TjotEqqE`t20k20nmR$2 zV (U zy6Bnr-MZdKh}+k(-|_Y5=e5t(X$@m^s)QPM)Qbt8xo~uNo8rFUx_QxZR`8%rClWJJ zWj3f{tuPJ}N|y7UJ5fG3hn7WA5S~Qv$#B(1 )T?OIGVaw-K&n?H-3Wpt`uI%}G z+yj?E5K!SDh-*h7M-Yl9^iX`?^moe~?w<*A6tv&h#N-jXqbG1>PeQtk#n@N$L>dxg z=pJp@n(F~-E&K5uBNETlPpRHB`yjD%Rl>Hn`;WZ-y v0csz@cYV%Cp z>Vv6&tL3c6#*Fu%^I*-JkTyw%^qTFOZj*S{%i$Y 6p)IqLC0G~RY zq0ewIQxr -|} ztr?br?;c7O`^lt)xF|y{O;0MYYbLGJWsJ01&$>Ri?$WHDqK+UUdF_SzmQR>iU6*GH zb9gtALs6V?`Z&g0SB=j_y$?$5v>D1lrZpimJZbq~-;mI>G0%;;)sO7c35Dp9BFR ze4xyWZw NX`vXMOg-CPVj_y_`8!Ek89iLq zgw*Csb =`ZjYc zTK!DO5gDY_@5@9m1#<$#scZoy2^sL|0Ya(S1<5RxQAL455ErWH>aYwADT2W4PNT5Z zJ*q!~M~5r@WRmVby(W*Ejd!C&UbiZxyh*46m*a5he92QRlM`-iK7)lr-G%cIgi sDj!qg!G0~J2Pprb$>GP4y%uPMEU<0NwL$c#X5=v?rfI1$3Q!y<+- zO-DSW*0P&GC%)_^1gE#(p1+s3Kdq3wFIe5O@o} x5_oc1g!k*k?hYl(#QYiVwJ;i=0FSH*4|8n5W?8 z!ksL=_srg`lGwE+(xoHlR+2@d(J`+Jc0$bAGGI=bPTgig;WM`nC9~)T<-ulv-ewVh z-u^X5-jQ?vzaIL|#Q#Lkvu8u+LhKd+y5}c0@ft{hSqWUlglo7N@8zVoD9cmU$AK4x z_O`cL{Xap-GX;=YL90f?P${+vPlLzaU|o4`h`8$DHz|^zUScK~3;0&eY>a2YM!Yq$ zDG7Ar5y*W|Yi!6Z(P*@&y}$}aD74c+mwF9hjYL~)RH1;_4=f2f6FRI k4K8*cdtM@Y9{j$`+&&hr zeO?bSwL?LpgVVd$GpwBn1Va9hu_#-?HF#kD(HB$ro6bClQmJSa`Pax)E7=5Zd;yb( zg>f+%jhkQl^{HLA<9guvtM9qz`)^NdSar_d?k=VQ!-cVZkY$LJ*bpJ6SaSH=K`PRK z(k?BnacpM{KoAPmW36FRe}LqT>koG(!^8+CA}&Kf+JM@OQ2(ZRrjQCP%TUmxW=+8q zLj>jU58iT`AF0y@0GOy0a7Sw!VGT1G@qwt!GwE1y389Th#E?S0@u1%skKo95yM>9< zag F5`pO3+8%RFrrB;74%V7q30INQK#E?p)#b_CfMdkpm5HHm&8? )%=sTALuBL(>E&I`?&!vU!>l zN0mSqkC`OVs?{5i)qgrs{@ z6O)9*Dn)lpaVr?P?>Th5MB9JRMmh zlwBaA8dElQntuM(sjx!y0hOuarW(?*q}S_VM$LO$&gbj3*KS*hJYwiZV>Pta${)ng ze^Q++49kgnc$w%=D|p!GLiCHDAhh@(3?iS4!W5P|cDfP|?vKMFn`5Rug(Wq2V=Fmd z>n-0me$Pl>u^e`tA2!h^&RaZe0!#yDPyw(a2zYIp>ukLXWNW0UNQJ3{g8ExM&!|>6 z9HV_ IyavkA4 zMUp#Ak|QC3Y2hFl;bNh&?{Ah%YvG&d7`|3U<- #^9k_gYQPoKM?)C? zqHB5mtp4k@4eocba{WHqve|m;NNT7RVy+XK6Nx+KuKN433B5_@24h{nW4xS{4~5-O zx3tIUHuw#ucxqS!mBRMS!`dk4z`bhNU3Qp8 8mYx}7#_Ivoc=O6P( zS=D! B=Qb5c#lwBXl{&b)SbOQop_V+7m*PfQ?G#Npr~_s2g6f~Z?$-k>0v6F_-Gb1+ zq?utIG{yt3qsOz6M6tysk4C tWhKq<7#9_|Uthw$VH&*4!`mH({s_R*M*a zXIE279dV&|?VsbC4vjsY&gHvyN4`h=?n1+tJIbtf^{KJQwQ)@65guIhsVZ0rA&EwA z30G5Y-F#{EW(F(#Nb&^zO|=$P?@M1mse?*WOSr%;*5L}{Rl*VLMVR@-6*0p{;@OwU z=*23Y)BLBO9!&ZOTD)k`Kl<%x0AM2cPyN_jeL*ZoD{>lbY3(prn3?c|^hl>5+DRtH zDYfte{bzY`!FQQY2CrFox0!hP*5Vtx+11 Ig|V@JqfSU zfsaipn0pCBomlCv77<{4Hb*KO5lNBC{oPTLas}&wEa>_BY$EeD-vHWP>Nq;!oP&kA zw&;JA3mzS2#KIecHbFXct`4jv$YCT!cwU9pj#Ym1pBYh7U}0rr`5=$@8Gs%fOk~lu z(CW}}ublIGk@L1w<9pKreEx8vY;<;9P0w+qkvd5o@fG_1s~3O*?eN>#TeH&3pgl&! zXojREUQQXL+LGfc*u~ C+M(C2ZV&9x&AF? zBi@q0quQd=v=tSrXLz~9k`|j!vx!IqZ>?lFq9)*8=-JrnMQ&QwMp&?;s(#F8Nk?fE zskHTKZj6eK)1OxAKr*TOdoJRr^9LWq@DlEV`^zF2OI=6TeGF(*ugLFZ%Km4b2mKCB z?|cWE_))|wt#*UWo(VCy@2z_$Ud9V~x8eCa*Y(ejQLh!uYSl~iV#bYIXzJ1O;sKS- zToJ_MgW@0XPpPP+Fb*e$FwMzp!?QHxy2A3_%TSbjs?eGKlW1nEzZJ|5oRh_W6=!wT zoG5moTYMi={;OHQ0)>AKVgt<4PvCyl#6U|*_pCyX0>sp5x z;;%TV4aj7<5NFrrn*U?@igzViAqa{38_?d=_(KCyL^5xOeH4R1U56Q)A_Cb~EW5p= z34`Bw ?YS5%*E4A1UR(CnoQ+MJlbdC-S{EqNJ&h2WxW^<(iWekGw3~8{dd4( MR*FnfT&g*CFfw7vO<@A;ew1K*0zD1xVB2p9hKn-ATd8{^=#OPY5H5B!t%Q z8l~XCHKH^@Culp)E~%1Z=+|nq9N#0C^WBewLUt0axY6}zym=z5=x~iNT$IzTp~7MR zSCCBR=XSg?AFw% jQ z2(~>+ %MDqLjREq^Ok0|EQ3B~ikpjeoLM{Yp)B*y5Opfrtz3mrRZ*GXC6c zSTC8Q!@b|8AjD)Fk2qEa?LhA%gdy1eJ21IL2?H$ha1wZeO7Fdr1a5?kN|bejqS$7! z8_LL(?@HW7$~?KPa!>3e3C1kOxl0p&7O!+%;uxUa&gNdY#mF52WkH1BOg4T4mkkEz zTKBe$fU;I$y9IVc&pi?hg7CM&1WHrYZ&lo0tDn5i4fS~ZivRGC7jKq4cZMZUyX{97 z?I^-~!YA6jLYOD&F{hG55f*3pg6I|F2ED)c`Z bvY!0hj-mm`8*OaZ*EP!LaTvSrUQj`&rjY)cS&%Ik>N+ zD3%oJyW%2U?A$=2qZt|+oLz(Q5$AhN+va>WXSCS$oIPD?caBT>uEOB<6oU3YJYr1x zY!in#;K+HRd#?>kO$u!Wr>c`^20^bpYa+gx5(wy=t%s#&*RO=h%b)y2(d+R2JXk>T zz0&4;Y=iy=QSM0eDWK>C7i7&n5xdn0IUys;1kqByiA 2AghLBs}vY>`esrDyHRnk#(U(FKZag?C~^a= ziGlp#4Q{TcP0Fk+K=*ZgdP14V5Y9T~(a{5VrxJ}>mR^DAWJ~#DEq?1w$XM(VUK(WX zJrzNNz7d4V`%5eWqPQNwkh8=YrIN
z}GjLGz?8fi#p%0)aG6C zblN`j8FkYcwl>ZUZym}4RQn0sIOe<}HGmgIbdej|7kSC!P30)hLXoX`*Xm}~RAn~= zpLbZF;6`=MY+Q1Hzbrk(fQOh_4~ASFN*H1MIlOX+H_t=yzxE;nY=I&dZW!#O8G_`3 z1jd>2TuKl`Np*wOj%ZU4kppFf=*Z~E;86ZH!1|m^Gj_XwdIKLoz3`|Ov`A4-r4>f3 ztu{l+tqWm6R4CnHqk`Yg`PH;mmM)Aa_5c7at7gBsMLU9P?x&eX*M9HIq#WNnTDL8? z>yfV?B<-PL7|Xrm&JCY8R{{$Lv5C`4(ljG*0@+4T5QA-i4{o`aj1;BY@Iab+32;C< zXX@YHMIMNS*16%6ytGyVW$5R *|OttTs+#VucdTi`nNndxK2XcJ_5y=CS6!(gTLGij8TGS#*$S3ey?CUStrc#Kp; zO?*HbJ{&6arNMebDzE)QAL*aVo9BbJC+WEg(SqpZWam4@5@;#JM;4 e>a99 XCsEdGu|Gwpl>1M)51K}rO!5ldm&l}uifdv~-ff3|qfn=%Zxw_MGFTRFQ+Pw$ zXs0M@n``uk8UW!F23vck#!HA4Vq(Q%AcG^2en7Atvh!xsA~%oGOL0lmT75+Wk{SxF z3Z)VM80SJuKgw@0WQvq4Ww3Tv{Yci^ftC=_iLFYt<}$8FLI3`>i0j!=GJem@I2HxL zfV`bRX4b{q(8mfTGIC)=Bm6F8h!hJIqh0h5;>B_x_XOQ{ml9)O&aNFv*z2&kPf#Yy zF-V9sN>xY_Z5jc06B;J2=B#5L3HY~nDkzwguxgDCG*PcY9Rhtc4tc?juibgj1n)rG z!HD_V#^WdgseaBYm?;+8T@{3cbw8e# G|%xy-Im=RyMw^cgU%0wFqhBu(HxF zD-g9*f7aqcE?zY)Br3~WpJpkFLkf~0XXClM43F=7tK93q)idr6yn2x8%JYBqQg(k% z#QL3jg`K1`isCbcriE#bcCEqiN}pY_*_Sqe;|_7Gp~n*+Ui(@W>)j7{? h`7y@~L=Zm(t3j6gl z$R6j!3EaOVfj1g7F2od(g@S_)DEWw8L40sTf;Pz6500I^Vxl0+z(oz`7V%=(Dv@tW z;-X0@RfzQ{{Hl)) 7#l8;# zhJ|}~;nQk1_0)Z2R)8%H1JTa(=W!)nw^TsYy;Wy1>tED}vU?gSpTBGm+vh=;X-a1g zfdD3{B2=!gy0Apftz0=))p%->u8PGQUl>11<9Jzw%dzzoAG`T{DGz+#Jf#^Fvhg?c zi4I|6b+UqAEkx??_WKRbRAE-1n2RW|?1GOS(K?*v)80elX_!{lBN(q;lC>Y;@ o)#H=li$ccOnFG+&|!BgiOtB?RYrOB zMDaqMym&;{MJNKb$J|FqpTH@L_MFKz+qt(sy?^Fy#0zsRnCi-mcD` #+ILFdf0o_BFzZebv6rz7d135;h4oq+fKM{4*Fv@$B$C$nb2|heaN>K{eW 8CtDeFFERDRL<7*V5mQb7uQp9Mljpa=0kXti zVZ}>!pTua0R>pP%)(8 PCG z0BF=OxTF(V4WfWPcUDBLFP)T)$=HVx68F2~^P7czvPRe@lU=*F4>SIIVgARbfAmC2 z_g9lx6(fp?Wn;pu;IjXWPwo)B0)MSa3Uq#QJ;kr+iKZPUPzXJl0o>DTokp855s@mw zN>cFL+x~|S))@vupPjF5A(0x?{NXBr!;{m1Z779x5GnLO21`8H%-1=NEOFzrs3Gra z9wcettdN{mxjzESkHNFxP#U3ZO4yo97az#L24z75o2XMNGuw7gx6Nr;cORYcs|)_J zw&ARh@gfT}b^R0xqRr3;R6ZfDrDM^6=sniTaLMI}%+XFb&5{N)AH>r1r#y=Ew?2wz zh-#1YpxCzibn;DRw-SWwtBswPa@@XbNWy0}mme^#f)?O+wY%RMWxk-JI`$y1#_;nx z3^^M_^bn<#qmk{alGY^q3kMeS%`O1YjHP;c$0OE4oadHHJ3MF=8Ksb-**@F#lr>je zoRp?3gmu(Q!qd5M`(iL1hGdZ()T%BbxK?v4{-uTDEUij10B{rNOW%kL9Rza{@n2oF zxP*UDpthMg(ItW`Vn9-!u@p!B9Vu%58jM6Eo;!|=@O_1I_`NCTbbjqgGv0V|mZ<)A zGePd?o_r9<+MMI;{0+@zvAA8qSsINEhmy=VaZW2@Wj`q5%7kd)ZkX`r?H$jAygtb8 zZF^kky!}p^L)ZG+YX-Xe^)*HBOGn0;V{G|_r+~n;S<|Y)TMT)?9%t)ZDg=s#D8Qe0 zyCxtsF+Z6~QHi!ZWszQD1d2~wP6ZaMI%0w +WUD_ZthT9RJlW7e zEds_R5XpmT55NKCk?nJblk%nd*r72k!_0RrY+7`*1k$a?e&DdmO4rgnh6qG19%qd! z{E7pD^8*_dO0^x9KriZo_`D-{9w@;ce@bZ}#twnHz~6hs2iv1w1{sjRJTUhS^9QD5 zK2er@{n>*+8U|h}F1`;)OXAhM2Q_?7HH6y$54i{v3ST3=ILFSC)5@^iT3+^w@nCxX z=cTa8oIt6Z{gdn=dq{ >SsMK^Fq6C zeE8p=TKq=P c#t^uLldcM%u9?grPXOWDy`zXzEM!I8-6_L&(@}D_7~1&XO0fh^L5*MKSxsgUrbR zUDztdP>3C%cSn}`_!5*kp2GJxu(?jQjd^n_!Nj)1%_fzzF>807D*mb!@sE`3FtqHc z6s>oxOHP3Gx@k;&Q;$* DL1|Ys%wMAqB6WUj4-Xn^%%nD zlqE^Tk}-tqg$9H%iOD2_CuTK%eWU_Z1AJp5J~rW#ZT6XFEpURMaQwf*=PNqU+eQ;{ zde |EAR>G2FjAwG#M!Me7#K#-U$?-# z9jQKX<5-|xG$M)j`^85F-v=$>8+gvwq_Eq $*gSd^U(UDjc7a?z#>$u+Qxcc?S4)oTycKAtC zoJH`4{!k1Pc&SMGM0pDVB5|Dn?TtsCbpd2Ff$+KkgMGY{dv8vRCbGk@vb<5?+h^;t z7@|MZL8wUThmWWBZtiE2gX)2pG=%)K^$i_D0wfXyPpNM>I&xB%B61iQs3A?Jgz+#X z22?Sqr=}l?93b2qDdjpx8I>%_Mk8pgm4E)JlO|8pOCvi7vWZK;>^OvM0LmlhVX-l$ zDKt|7WT!1#qLDw2V1|{K>nSxqbZjqm6?0X(!Q5tKW{3q iI1+^ShBfv>7pfjJKt4-i zSRF;9o8%94ZmW6Vf|*%bs $i*h_NVg+N1>`LWaisENv|0%{+r+09CqFD zZ`3s+Y8o(;R=+?*k_51si{w;ndgSL@w9-{DV#*yv>@956P3Za{!SWuNcsYh31o-t? zn%_*-87oc82qKj;QysZw{~u51;8p4Wz5Q&QY#Wm&yOZsjY;&^R$+ny9nrgC*$u=k3 ze0tXUeZGIgUhjSHeeKtE-E8sQFMq2#Fn$FXKpKFGdR3KO1jO-g6Zly$$V4uota4bw z(oCYX10oXa axe|GQ%v>u08pz6T!^uVe{X4xG*fa23lN56P{IkW|K3e@v zU@fM+NpPe+4e%)b@X9N82Kl_KX(6jToIiy!L>Qepn_u*k*N7%-z?UTXV1k_N7MqT= zwYl+OTT p)hXKWEWm9er6-+48`-2&&_B_TlC` zdM^X~#V0yy!nvg^{`VUAE1nDl(_@Hc+)> CAsjD-y6cM<|E$8mZ|Chz~i6JSJcaJ>oCg5qCydi;gyv zI017uQZLGP9Jl81GfKMFb-EqAjrmcBi>-yH)9m=;a#haIedEYAih%Kr4vWLaVplDa zp91IVnEtVn>vIFaVdIni$#hyHPeiAdB63c%(wsM}R4a2PyYWTU$vxL%uB`97ZDF2J z`%h86@HWS-gm#k2bTAm{PMrd1D^DUtk(A%Yh7iv8Ayh2xg+jlMnwBAspT?s}IKyE9 z|BdnAcen`;uRVx^!9eoi?v#|#n(QU0ydY?`w?LK{9^@a~AFH_IJIy u&)w)Zj|@V(2aRR7Kekprco!gzWDG^*I3c z9T{N4MW9V-Os@Y$xwoLtrLTWHs4GdUCgQhT tvcoj4cYE$@uVd#1UAWwQPzj3-zX^gUIQpva50B8y6MzZxfN&XI zBaxf}4b`pSS}s!f&8hT&m_v4zNI0yC@Hdt&Vj~wVn1v5VH2L?<`@TeK%c5aK42$H=YP8%TSo?zZXb% ziBECpdh0v(-g@tK=yGy<;7fldM*q>K1H=pd!OxC%L#5Q8>v#tPHV6>{c9@$6RyaY* zxUL=~Q(*;ln?QJfnlv2H;YDg0`yzE+3J+9@(jUO5v >eei*J`q)1&*jiMT!rLRmA>r!)J>Iv?|;=r7- zWQ30q4|pz`MM@(^@Br7%y)~RSe3mzg@z7V6v^D&I1xIlp5GO1=5E1RQp4 ~|5&p9jLV&g a9Y2 {NN*E0%C=6*x&Al+F4ndyH+yadd0 z1D%3s81`pRaQg6V6eurrbk7a$g2gG!;}%SFm;xw@G;SA?VWy4EOStHr>v_1c^*lSy ztWU$kt<1r!j~HC-MId$v)pVO-KLd`}1B;Fq{B3=NpVlq7eJSC+joF>(0UO$3awIx& z% S9{6-2liuDY6KIS{5NP9HgziOJSY$EkRF*g9%=C#6|qe= z5&I77KM=V1BI%@!f@}=Kdz<_6>tnGA_%N{KZpH#iS1o~(mh`6(jj$rQgiPk%hX_8( z0y3__qvJwNWR-1MBO9lz8m^b#%M(SEeXD*5KDH3F4_TOb@|!Yq;k2 SuX} z;34__@{c08 `q(w%s%2UAAVaH{F%hHPhr$(X%`i`!P zy0MWw8;)L)1X00~3b=g!Jq{|F@vo`u_}B^WzH4{b>}bl)%bPLs!1nZjm2RU!Q{*x$ z+`0bAGMBbmovIcVmGR{oOmVToL2dYFuW?LMQzK|efy+5EV(Ucz)af^zb2soSuJe%M z(SM&W;>bQBWnk$Jn;TvrtELn}1DdBrNL4@_j>(BxRYv${o}g0%I!3RG^gZ2<3UEoV z_*c3= |eO( E32tI%b_4(BTC#EYGt;6#`w15R>9bgr3H?tNV%wOD0jI_0 zgso2+#mD(@{l|_=u}uFm_beKIKB=#+tURv?K9?(Y-XEmt@Ai8gjVnbU@xb@9%`75u zyBE%)W*@)eVZ9;whJsSK6Ht2m$cgFbOvp=`Dns>o$hQ8#WoX6pTzjO1rA1c_g+HIY zRpk)r3wmy~3ti!p^XjC!1 A(3i=2Gc%QD$2dkpa18b{VHmPI@fi7)RA~jF7(OU{Ckqipy@i zEiA0WOksOc&%jSXyXtU+ZbO{+Q!8RB9>Sk0HNo%)dmzh-NHJ;4kD#=@- fJ>SGW$DHl!o5S>mb}?v-ZK& z$3bFWPKlf)!sPE_tE0PnnO7}wP)#*a#%(*qeNs=$QmiIJJz|y8CK<`OKix$0YCXB2 z+@lU4e+b~tLVXwA^cjTXugu%iW@OeA3Eucyy#EyMqxOF^%nftG#Q3exenuMbU`qka zH%w?qFNTYk^n{ceKx|^>L5h+CDbi3p8YlGe X!w?g^}aDn#NDEr-%*^ z4qQiQNk4}of|Xh^hfklyoml!Fpu1K*5<}Ri73%@ybvYY1TSD0m0UnuZrz-lq_5LBW zv=eUt`YkGUjM?%oGk(YF8Qpb}`t6E4(!t^K>jN;4LR>tmjI+;#Fi&&lscp!9+>c!v zd|%`QmYpUpk-_NUb*oQ(-Jv5znoKt4gUsgec !H@-lxl0F8}f5*v|_9^#ly23m&K6> zCn`V_Hy}dKt~hA%sW;@Wy*n-+?*@Wj{@-q7fG%>0>O%xc9t($8q{03R4j0|9meP=e za3V!@`-n%9Vz%?AuQqj#&y8x{%jPh#@BXS079V8^q~4Z$Up3Ekz98+RJ2hJX965gg z^*`)kD@_txsoQP*UP#!QHJ7klt>cqve_e}`FCh0|C%o%v5tgLm^ARwk*Egp{m;pEf zfu&CTCRO;GXhxMb2*Yw6%yuSpBYM77N;BA5M^O)UlDMM!W$|x-wx_O(im(??9j*5d zgHKYzn|_EOled!pPQ+wZ7#VZ4ES-nz9_z2G+JnHm8z}FkX!D}WOn%&OPy!a>+b2AZ zsi;1AUq{NnsE{HjemTa<678Flpi%j2CibQLAZ2ajF4|AnKP ^*zUq=xx#;K^7aRc=~`1ghOE)jUD$Io7N4wezj5*v3!Q5HHKL5-K=+ z9Mr_nQ3;4LQ-ZxYrykTCG}2tcadtUcKzti5nL|YK>1D)OEO(_BGG657gO5(4Z&U%V zqSxW8&Qi&PX_3bs%>RzJqewY~+~6$~&;-10ufFTvm;xZAJs(zHBFI{VBK*=` y@Aj!Dg~Guu-YYV&6? z{jph#>x^7S@F!y7;97Aw)>q5`%?XxK-U#R#6O7vmcb7hezHc$Ga7+(v&Z(<>tH4i7 zPM8o91cPt6v$rFd75*c}Id0`Ffgoel6TaI-dxCh$$=6FjnmT47cSNG)b2UhzIS3Q- zc|`wWW=B*%y-@#9kz-Bb BSpcKbV%|pVKjM$7h+GG*5NqO9fHGl0t`qf#FdJ3eHx?QB z;0PeU_l$7rFQ^_V#`%|g@0 VAu#l2a>=fd3Q;tq@WS+&3Y+_zyje= z>ZgM^<%VaX!#s;UMLVU uiG-dy+? zAVP1XI!G1pEzJ+v;4~q)!^C(=tIyD8#fn5X8FQDnTn!CYLSfRG8xRNbsf$2Er`dz> zt!0%8`E|{(=e0MK7zb_ 1l>12v8A=K}@Mp#EP@ZuI7$UYsQRjT7R%+pO4yYHW zBJ5c~!BPvk0qF%avo0b0Y*4*sv%Gj|opnZ2 csU67`EwdKSM~@4C6o z*)r_SCjeZ%l+`C^-DF&DWRn86^G+OBL+;74F$*78|6zSCQuxv@T0D@0p5{UyicZlv zDs&lYtn90on6hij;KCr)Jgb4J?x$I$7t`H 3D7u{1WvPhY(?nVks| zY8(zxpmgmuej{mpRCRcn|2mW4oBuG)0kEVQs8^TU;yEZRIg;y|bb!1EkKQ^RP%MY4 z_`GP@wz&W!`?3$*=5zqs&y{I*Y9LNwQK6Uqn=mCs${$Lw!^x4oK;c&W6;=MUoRqYs zqdU!Gd4fkZF4j6`vW`EYQs!m|5TWOuzjq%x+mGtqETS;LpcaFi?67bXQ{-A2W#EP? z-RqII1+RMT9JKsss8{tzMNvrR{$9_F1Sd+ 1g|2nsOdtFnmS ztp3Ft cPY#8KA6aSV6a}Orr?J0sSZ3MUEg _E6_} N@l|pWGeAVbw7_ZWp{r~Am;*WzI>JK9V35Qw-6#6R zZxCFlbn)FYwj+8lU_}oDa{9i10n^4|g}-^V`?giO8|Y=8(nodha-%vH(52 TddYQFAe80UT*-40$~>mX{~vxi6Ob1O5mN|QVr0Ebn1K7dBx05 z?m OHIu zXYNX>)NF$ijgeO?A{TFO{{%mWiM@`Z+=)>vPzJP6yG0sXV2;+$T(Ma9oDQ{m5dor3 z`GZA0F_6tF?OblN%Mub98tD2~X2%0c8sxl4Q%oIO%1E~GtcZxWUM-$ee0~o&A3d7g zA1PZBa_;flhja^JazDSV)%?oKKFUwt79;=xFGC?G@dE6awAG?mpWV6s){%60vy(9y za1x3rj(3E=yHy2A#(zW`kcEYGjI-b_M3*#6b75Sw!i7pmwT|_;VKhkSF~wcbLionE zJ>6K57uEy4BK?*fk{rdxS(uSGPtagqiry3V+tL{NrrmC?ARYfms;ufbXGDZ!@+Tq{ zf@O#a8V~R<@R2nvUEQ7LBt3i63lP^gmygT(9)y(c=`wg4#5ti~?UJ#6_id^wy(uX7 zxG_x;*yQ^x|A-K>eC*#8l^#f{Q@o{Tj3;icT>j)yZdxFX=nM62ji(`K?;&hia 4c@G{K45e;)%IQ^++v==+ZCM9*X0;(GA&Hnj{Mj2f@qK7D3#HOZ=xcv z?8d3}o1(t=i6*97ICyuk%!)zONeve+K4O2Zvk(0wANO02XQ~E5JUrTEP6VFniTkw` zmUe+6E!~-YVA&_Yh!*m?;QHSaZQLHyrAV^%fLj^hDL01&qgWG~-@r1cg|(@e?i%aR zJi0z7SJ(UQTC)3+0(JfK5@W_4V@?m~A{ye23t0iFQ+H4>C0J|i5uk)1+97x2S3mh? zVFDFpeYP#XQ-4|2HyR1g&Xd)O$4_n6V-oUU%t?C89;iRQGb4dU{jHE!JnRIHG{=M& zwnBY<%`12BK#o);dkrX?7@J!{f 3)@TbPVr@C%9-*fDY$7C7^cm|eq0nCK8zum(x<)#s%YjrcIcgf&nEI|p;xRo{y zzY-hfb1Y` SlwlHXaR2Y^>9Ka(oiUiMpnT> DY z58wgL=y o$b9+ByN^uEmDkR-!vtWB(N^p9Kk* z( DCIcSUPBj8)_bp_CyI(f@ScE76Ziar~3p1a0_kEsW?tFPzu`{=Btf?Fp zKcS )DG0vl%{jBeOhZLT3Pk6_P%a8umCYUxpkCMt@_y?8|b=<+d6GWuQpH z0S(i+*-`|lZ{YhmcSM;h;{ncNuys4Ute$w)XH*C~cJLZA(JrJXr@(!sVLC ~|ID5|OG0fgHkc4Y(c zGi)fv$#b4XF;XvqOx#a50CMV`p)XR?$7`#0 =7VoB8(J9;XJ5&EmASZ2kBp+I1lG!5 z;ZsBL{OloGp41|jDdF4De1Uqj$=6OYUH2GOVOO?<**)df^XfI7GHq(%LG9J2vTWE^ z{iTn^hZofepDtNgP8dm3hD42P^k!LZaw$-Scvg&IS;M&<-u8$J213gUiKQ4`X4wI5 zZyNKj=yO|26JHrr4EtbiiQwq1d yERwxB(u4%Wjb6e*&zOqjpLhEgrKe<6aAYP)~HYIYc`7 zqGURR`7~c3X6UO7Em)aMoI4}4S&7@!uQ-91&N#uBWuku;7LD}rcPyhOEDvZ*<5zw~ zR6mX0l@xzd32)0L^LO*AMhDcfs!|k&3gDQl5;kfUx|+=fi-d%G1GLgXNa2{jLDL(L z9g#w=pTX{eSKGsW3}~HR0?X+0XneLVD%Ex{d_mZ-aR{LNbu=&(!{Aodo`L}Jh%2bf z@Bh&1mzgR3;2YIs4b|7q ~i4Iz~sM2e?Ji5(HNGA$%?*X|#z8p4J1 z0e_^%pZZlrf*)zaA1xPjxUKysqQj|c;Z5&lZhzT@23*}o#z=8NzMvV1wqF>fJU^<1 zlRrspbP61@DN>@+d{fci7$;CeIyQZEBWS)@Q6v8~ Q+*1(Q1u3qDY^k(%6^yVf<>r+m{i8j3&7Ja|Kf&FAaNY?!Pt} zgw*#765(R0-Lmhh?{# jHPiTN*Mf@f|Xp3c)RefEhj*XL$5>E4kv z!8P0Y z{ztn{aq)nr&P%BuB;y|ziZo)K_(t5vrGr7V_LwY3^9|8-JrG*S!ilF$4d4Fo5 zC%uxYK)KT6LnXEC^5;5)rvZ2=$K2o^{Ch(iVKjMhY8ze%f%KQy3V~gI`hiX}Z8Tav zanDD{NWpu6yI1c*hSY!ChNOP)q=F=?okANV*?`aGB*%Mb B<4U^ z8{OL!L*~^XVWPJHS@Pg?RSs!CO)$}1!@&BX8UX3pTU-mH;=)YzUF&9nL^su(l;L8H za7*1E&ANJKrw*Ncrt@*ro#wvZPC@2YkrE`9dlGEGGWW3t&X 2u7mF>NQR8S}_E+#Bv-j2q2D;-OF+j zMQ>7$FOFsBaGy=w6LZF0uJD${BE^t{Ib#3SxlH^cA%9hk1glF&a_`Zmjrl5DP;iYR z+4G3;?&KOm@-m0o$WAZa1+VRJV~oLBaE`SWTUfr(Yo-QbilP-Be*Z%xD#gTWMHUCx zCwax~l@fjF)7Y}2$vh#uJ}Q;Gi8IbplMZ?(6nkFF6^V)J;Y>@mCMh=~dSTcaM|y un;1r6Y|JUKixRIj)cIoGgX;8U-*j zR{&x>trQP@ya5rtP6#RDg!q$xQop*J`_slysB)4s(u|hfm6>TU{z%X)DXhIeZhRh2 z`CtF+&H?Gm0+&Wn{$v2E21~)D6GH*I(5M{f$AR`6?AtRWuy{&c-~lwG#3v+2hvjmV zfhx40@#TcFU>YZ$;Qf%!KRHII2Egt8=z~AkL6-4RnR4Xt>cYg-WSqM>;H5ozg6F0H z0lSHmnEKf2A#w6)bq~THRT$7N-$V`K)pG=#fL;ysaf{29ip?ukw=lY}$||C!lL}0J z^o#zDokd%Os~Ma|kKER;^Cjo!3)H#E9LoG6bNtaV&01@9S`fXjrJGWUi_)nHii~_q z;!=GMzKe_?-%p@N0fS)&cG|S{O9YPUf_jJ}EE(6=h0U?N|W}Pb@TrS2&|;}Bn#1^0I^Z1pjY^!u{&4lNT+nbTcL0k z50V#rlyLN!Nr{WEf&w 7)P z^`ymIiYY!nP#i`I{`Yf6II^hZZjZLlJS CX?L_iAo1b!It5LqW^91I}W=$IHPG z-dB-&lI^dKn{Q%(>U-(RDT~4*EnPC=2b=X5U?)-%0o2&*?x|~f4P3)4Unu?YDu(LK z=07r#YMR)9dF0O6G$*QZ)D}Sg)Md{pZ|uM7PGBF%&Xs!63D3-sNak (vs-K=mI zEZe3!bnv6{$m>u-y(g*>xr)?4hUmvM-_f2dfpjmWRvl3ilMu?|psWSL<;+@32vqf- z$M5q6e%~^yE+koMe|#E3BRqHt3%~nK7`dT%KhY23UJ%?c1=-X8XJS)HlqiMpCk}Vy z$>jhMq>qa+4(Ou9qY>VL=h1Y6=2goEVpA8741BMWP(KoeyWW >GnP_RelsZ7e)^9oHgzc=N77`wR97-)CdI>@b;uW3{ajO~7xcu`0 z s{8t>tV&>i4=G$1MGX>#x}Q?!PN1eg!wCh zSZ$b^unHzR5N|;=0Q;=^cbxoCPNXz)%l#*`Ge$rvU?xz?)rn<&XJR&Oj`PG5-%$=f zP9RRsXZ45o_NJoGoCS&Zkxu&YUso#rChGdfZ_Wpp+KM15Cmm$=i36mbX^kr7JMNV6 zF&W@o47S^y6q3WkxDhpJN*V-lxm_(Bt@Om!9b-^&l=(k~90_m4iz;gp^ioA0^f0Ln zlZ na;CIz%43#ZI8|q^G$ONhx_1S_wN}HC zm4UqJ>#gfo*ZbVO*JPk4miCQYa{61opA=rm4z%2LT{;yB(+cp_bWG9RxRBh=WohNL zOut}12*uWMromas4btUiAJ9oZ;2&O+3EsFcl!MH*b5viuwEjm!NHT$&Qe%n>A}DS* zg8Cx Xw8NvjsJOs GW-hK6DGwV3ZV~O zRZ(|EHb1-@ShsT5DQ{&;Z+Qac^za4I@T`%>C)Q}aq+02(z^*_J$Qbze@4i#fR7pF8 zFqbgE3x60XR;G-?$VwRD)4!tVqqDpmmU_T945JuN6^I>TioYq4cjB=-X6%~p`W7ya zju68M_dTJuwP iEzLGL_xDy|HC>aKkk$~AYH08d*SnhXz-Rq@ gh$ z{y-MF>g_eqlSWj?qwWDy%b{yCHx11c4|z-oLR+7mWhq->Hde1ZDqLYbk;dzKlE@ev zQNZdeKKN5XD0Tf4^FQ`}|IR8EdXL-s$l*f$(-rfQE3W>lo1n-hwrsIO+N&itSc<#~ zcA<*}T1QZpczi6iTwYi=X-e1x>>2!MLAD60JJul*qGvgQWyf1WPjYwIaJRV(67x7T z>&XX2jm3z#*1gW+&lmo@`%5r({99Ua{h+dDa65U>DjaP%tVg8|pq6g~1Mvm65L(3? zR*5a>;wrvuud#(BO~OHgL~Ko(D#|0ke_^Z7OjMg5?S7p!I!(w2YVAneRruCOz|o^b zQ|P?fO8{{oIzN_LC!}*D!frc|r^{!BoSi79(2B;G=;{d4?&e#~ol+3a&s}0qSs@Q3 zC&lKH6p5Pryg%WVarMT+hKfgF<4lZ$iaDW|t<4nEj9pqpzM-O&m&2oZ`8CJ-9~ajH zH_!jb{`*SNlXD<*a}&Eb#G^8T!`%UhXF?(2gZiXI?@u{hD#4U8!LfJOEKc1!UIi{+ z|B(1TCGcUxI1saAeBUkRp&RJ^p)N~2>=zT^Nw#PPEOcY>V3pDhk;9J&V?$hls{&h> zmH_`Jr-(-8+b^+Yvmzx>VtdW@-5v&}=z26b@8j-|{~HGC2N>Fh$N}yo`dOu+^|o-o z?~}an+IC9S&jd5UQFg(v-_VrCn+BjklrWZCE72xdbb!*yt{Hdmc$}F}3@#uUlCIc} z?kWG!846OCR7!Q_QPiT3ljc@^47@qET^31=iYn)jsZ_D+567HAdLZk8pBglf1h~{e ztvl~h8Ol K@Ik+uwlR$Ym}onsHFlq-SH? z?W5b^-uORaPXwISLfG+!8k{>j0{qo7hm~fsmqi`+4j}c5jT8?a3!tg5X^htT%3$EP zKjr(9l;_c3t;2;6pHTIVsg~W_RQzSNLM|GcA2K|plm{;uu{O2#VlfTr8=(ibAdlC| zb{;jaY4^qi U&*A0geYSF$o0Fa+`5ap^tvRWEYwW!#t~@$K^{*7 z6{1xHV;fm+1I?kQ3Fe=a+!Pcf&F&ajaS(Xe(j!=s!~l8>K5Qc2>B2ON5wUjJ*AM!! zWhdgC7_jYw$K;3x2Hw8tP9rvQGhcZIFQ3dvMfIWS;jsa^lm;%rd<2?0!7TPh+fOCt zWYmuie(%g)b+8(o6|An*xI7-{nuKG(IaaKyfP*mNk88^&x}_Iv74abdCJ}Rx00%#b zfuZ#{5mn(T4Dz8LiijAh{xr$zJuHT5xG~--T3a_Sm3wCY@i#gI%>@2+u0JH N+HVKpiE%?NJXcM%dsyF^r%`g&Y8@*>KFDnZHL zL#u_>+P;QOMjSI}&6ZXQOHmfiE%g5jA*2$CW}!4XI|kQ7$0h4nK57zyrA4)VSt~F! z%?K1LgpDfuUCX-hH|BXTP2X#y`uFXn|AK%!BamU#i?p!5TTyjSq0e?3V;OP83l4lg zFXAPG8 ~+QuZEV zt}fq)+0k0RqfM?Y!7BF&{6n@K GFP>-ZuTwGLAh$a(H_wN)I-Bfuc+9$E|HZ-kUfmR0Lv@3f_hjElV z*ij=66H0yr(}Zmal_Dz>@91aFOQHDP4`OkN(EPlNa}6CfL0o=Lk-V3c=X}yClk1{| zx>`nn7pcPVw161|$JpX7?pA?(Sb^|H7nvYsij;@qbM+Oi1A!@7 RFw?q@keCJoG05*?Kh zE5lT^T=HHYk}b5*MZ&tD+kYaTxC;Qiqem4`$RUx6_MG?EEwXjaxC4zG9If|h9ul|j z-XWG%J3Zou4I{bxddKsuUYx*#B_AP*i?g$go%WD{(7TJC=8vV|K&q%XqAFhEm{J`! z*6-7EyMX0S)1s-Jv_Ldz4Y2&cS&?eoWe^Pv{jxdHa|X^AYc-huK@WUf_k`X0+<7&4 z&tUd>sRp``pBiR?4zC%WZ*>1b!|4uN+!j}4Jm9rtP@^K;d>;+aCs%FzLH#n8q|E?U zq7>^_ThRlrju(aJ|8S4nw)%GtNf*)gu8p|P^qhtUuw!ZTe4HtF{M BLD-5wlK zH*bbuD$_5P4P% k2)>(5|TaavY9)9D?G%&Tc5{2{TOm3SpTy*6al zU&6FyALyh!r1Nn;b=cA$`1M|iP2JgWHRvKyk`ok1?*jNV*?-Ouf*+MgZ3zdmoh|eU z6*5Av$(Dto3Ns&BtrM^L(jMOm8PZ>^8u)^QB0VZT3QA)R=Q!KzdyKLF%ZFS5fX!d; zzCFhXC)GX1aZdMv(Q@llLye_&uodNwmIC4qiry+TJ6~Lx`5)K0{C9T3SD#nxewY#E z V;{U3XS-} z)A9eXGBDe~(!!z@E m$BzLRqM2?q$iI}+ {yr=$kz9VrQ*$uc^#us#>X5DJj)V|4k4$cH20Hp(o)67azB@Zh z9dEm`a+EI9kET~1s?ZosW~@p{e;=ZN#`*9DFi@lpV900%>L$vHx+aN3loOQvZq_1# z8ept)z~(mfqHe$7h~1AG(CxjcXt41fUpD>7`rCfTB0f Rwb45an)eOF~MQZN_CiU0(uBBiN{HUa1FjYwAVisU>< zlTNy%32Llp!4}8p#=_Xl>CQh;;QoC7%&00}2hWcNG7E62r|iP{M+u$=?Ql~mL$2s^ zO`9yc-ccnhfZ5&znLJZWHCd!fr6vC6 oHPj{akoW z9advf%@SamBOY7NA*?oZefw`bWMgAx!ziZ5(D0(VMhLpHrX>{CbL8GCOxvT|(BwAn zMGbF4o6$QR>;A;Zd%N5CLSzVY@<{q@9g0Qtf0+M1*wYL3q+U`K=P;HyTreazDoNo} zcEM~%u^-Q+?%x&|I#KY5SOqsvwxTM;I^zJ7j7!AlvOXar+E=qkU7Ib7Nm9|VSx-$m z=rZVj{3CR|zt =PRiXm?r78Z; zCB9#u66f5a%4M@ENwuSszcFf%8Y2_+?yw7!&4C9rTt6{Dad}<&ZTp_|K=m|OJ$Qwk z36M@!!`3B@D5ZHA9HI8dGEK|9{_g?)7qUO>OGZZGOL8HblSxiyls$eW>M5?3e{uWY zL!v4Yg%R~Q$rHV^=DaS{a+R2a*}CeGTz4e=|j9PRg|XynoWrw$jE&n`tV|^*YoM ze0-kLZ}&aLCNe#jWr+Z-Ufo2*cWtM`!H#i02y5>*Ms^MG{A22>(gyYQerFWzcreT7 zbnc%m{MfMjB`Xm#-&mi_M4Gr`McCYcLEU<~8O*veT0X(JQN8SHEjKQ$)AbZO)qS9M z>G_yPR@feKgfAb$Dx55wO~_82uM#k@ErJC7fI`(-R^Lo3^J!GDf@u< yt3CTVVA-MMCTVuGAit}?tMDE(#`F{ zS6@w( &54h <7R38I}oS7_Fd=Dqe zLqvF_i@<0HVn0y0Pe9ePA-_fh#hSYUED6OF-s59dzXVEOT~cy7@&f&Mj4=9I0zEp8 z7H1)hEf;4TOuXGgLO5gkK_;v Iu-J+?Xdg5^;om3Ir>QSm;TV6Rc)Gch_) zL%0bmWg3>Nco v0KJYyQ zUxB0eufyR(2yi=xSm9$To{bx7^fj?;($0wPmd+G;*aH4>z~QW(+^C}O+}^I8ms{jM zKRk9mzJJcdef;vjdii=?k)bc+CptQ9!z$n~0JOrc=%liwTy>48oQSicDKta=w18w< zr)aRjy9Fyd1 (*fcDJ!|GLS ;V^x@ws6fb zK0O+RJ{d5ETA*O{XV0bDGE>qwJBlZ!A*>qjA5yqtLjC!v71sJVv|}u{>?$#GG{+2c z;(wC>v@$*=Z^mG>%#GR}z*Cc~OOdLh^FEba1qdRme`1QDy1)J2L}Hz{ocYD^|6p%s z=dK8g>CLBh)yu{gOP!I(+x}sWw_5*E(!jJ4LL27fpiizv2o(5ThUZc2D%63U6F%3u zHti4JEZvzl1Zad9K2=o>y^wmflw;<8JAXCPA}>fFulIqb#4!7BnwKj9kLNqO?uQBC zWRV7h ?~HA56*e)q^U++XGyG!eB8Y&dAtIE7z`}FQ7F$ z5%hqDN|kgl^J5_OT2^eo&xy`sxA{HhyzTGBb-Y-7zUFykVL=vNjLstrQ34>KIZ}n7 z-Lw?dF2A~sA?qt^z^W#HRni<%39Sd=mDgVxIkD3jxNdWKbYThdVX)$08bDs9*=9ne z6Q79@^qN$vV_^_GXh4iv37Jw4trHTfupAS{yN_}Lzc8G+bxbw?if9Z`I;}{C^`o(x z=c+_{w?NQ_#=@4FD#jOY5fMf5cYOasb^^V?G~TH(cg{-fR0#1Ws2TmP%bY2=EIDk+ z8LOS}IZ4vd=`rRjZgjWI__{6h(#Uj{|ERnmo{NEI<5B)$ZB3(!%}w5wt>K^%W~T z|6^Fe>ucD{7S~tKZ?ZHIwx$s )& zYr8{fyB*NJ@5O7tQlZq`9{-9B&DIJ%(18-ZrR5HMq7I^YP#lM{7^ZLn7ekE-p=9H> zZBqF?919bkC4We>fX%i*LW&$Fx&r?zHxoaTB0z7=Bx~+8VY1d1SO3nbTQ3BV^!`h7 zzLAu h~|)|9q+I^te{wr*lK&1>QVIhLv_IN7Pwvj^I@TIAVba zWnhcFh~AV1Ir0ppVUr7QPAJao$~9+6pg0DA+-F#aK=yBROI)DuLWY<5PsZ8hG^;7s z!r}Q lpQ&YfCQ=>H$Qs6q;X7{7ck4Pz z(Rwdk0uo(zhZ n2(qNWJThO j5eu(lTc=u6(1`#5P`JHDq#cCag&t}Pw~ zi;Wb!ERQ&hKI~Uz3p9+XEe!5ePwr#kF#D&?id|Vac&i1!02zzHuj6a CzT=x;D!xx%}r^r(Nxt{Xc(^96@AZh|K)l<+>wThYwWsq=+rlLSvV2dgFdo` zMZVc;FTyz?>54yYfgcT707nse;D9R815%9sf}3k)#1^3Ij0HF5w#oQ`Nb#A@UojCn zpSF8v_`V{~yf^jetjrz!pX+nAAA{~)m#AnnHlVZoEI9z)G%O|#6WTf{b#frFh`4dP zAJ2M%!9WgAinpQ(o<|N4EDm-zSs^nd 5v*)^>boY6X#+! z$+9N3@us1Go55a18b**;s=0_ceQ#R~H1?R@Xc9Y@kfGQpap+qMSNosxEBfU8DlhWe zL{mG1%}xHv`QP$RCPOOb-WITS+Qvua_M;=3v8XEz`ax|3{I_Zzr`Ok>|BtAD?yK~1 zzqsLS?ChOA*-dU|*JRsGwr$&X6DCbIC)=8AyY7DXb$!0q1K5A<*Lj}Dajdo8OHemK zdUCW>vQkEMx#k5x9jd$q#$J^fKh8ku*WJ3doNiDMCF5!)jd>O$YGyZBFjAwfu%~OG z;yD#@`J{UCYo;yIzB~?H?^>P7BeMSTchzD74*X8AK7OsS9laFfN$7tMRwexJJzyzZ zDT~In?MDrhj06Nif;EKeaPJ-rdywQy?P9pydPncludU}$uI_zgw|KagQiD3L1+{dB z^PnT{iMa-ypa(GjS;sv8b4Q@0VProsEwe-m+cHE~8F^q&KYUxHBEdKyBLaWGTqa&N z1lVoW; R3>lKBPVtL->llV!(FR7%F&XFw&GZGFT1FkA0Go5t^LuySaP{UgA z_|$}EIEBuW?%+q&d&R$lOcw SS!nFbSB@|&fhqi5MiXJA`AxV-?KXjz8oacq zo6sU>Y4-JAQ>8lc+q^K*#ow0KD}_6uIAV*3UHU%I*6j0YN9f_Wm$O2{5>&hmX{(0P zV5=gI(32loa-7!6|M$R%7e5`KhxG|mPxX`gn~4;Tt{F!nQ=v(+A K>bWM_WTtHB`tntDkX`>Q0n@AIvv7wR*^7oDFj#6DL=TcV&SxZFFX zWZXoaoKc{RB32zq27Fv>M}CkT9hj&uKjrBG$7>)gB?gCz(rIPhx>P^Jtxfk<)m@z7 zkZQK!@R-#ZTrMJ<@@HYEr&7UTMFX`piWxt{dvci)=K?7%tx8sK3;Grt9_C1;R&j5C z$HGi7e1_6g{`&$VO8dkH#;A%~-J7TwMFa(ltC$9_idI&}N@Y)h@BGABUdw y+iNS`L&baL10L4(Z%6q}3mH_&YB?|wv#M26i(qNJUe<;Gb}77i zOUXko0kfn}+3*gC2F_J75~?UrWbbG`k(0NsSmYZ2_m9K}_0E%prLL!|e!;7rFSJ$V zT8rH+@58L+NmclHRX-$}y=DbNz(S|>Tq~U`{{hiW+6n_$bWa3>^m;%@kA+1rP)Y8q z3aBcPluC0$gjL98uHV5RLs>sj`u~6io8CKj=AWZe?^Ph@7&h`uHfTIF?J>lp<@_~2F9 zSJ0K=fFz+=8o)3d7G*8@!MQ8@5Yw&vj^4nFtx&3(@AKpMW8%c~$DCI6A{+E}<#!ke zhC|W7gE95RT0+98-<919tg#IpTsyA^3&sjI3&9N$%Pvg(@9TCPw{FEZKE7aS`kr{J z1KEGugA?lhZMKp%MB_&Vdr?jIH2r#tL?IRw@vBTSfJkDI-e&*FDu0?|QMP2WrU18C zf1O~MCC;)_^myYU2d;j;%(g8T_bwN0qGj~WV?%~C?TV)Izt@(u6u8YF;8_K*?Yzn> z?`G%?!Mnr)@B_A#4uxVA=6jdJ>DdDD^AY4vuZs-x)P7I-uZ$a54$77GIP5x2-J@xX z#{*|zYQgXcEYx-n(TyE#`(|hbGAb{-k+S{H%20`*aIGrgUG(^ATVgndDE{UTs|kN( zC&9b2@9M!?#zeOYTaR6jzMm7nvucar{}hRkvqkg_y)*Lb1YwB%_JIJfW_b{HwO+MC zp@RE!foeyTN_oS$YP95Jdwoye;m0u&(8Onz8G10Mc$bc`JR)bJUwr{X#Q?BLi(}cY zNDzxp)X&$19&_YsAU!|L>6j$B @XiL{)n z4pS(ZeZJw|(Ec7`8Imptc`Q{suhEB=tUtAglqB3`o6C0w74|XXvu#zA#*5V!$3WRm ze9a1N(@aU*(=C0$Kd3;_kCYyu;rC6PQ`gXCpww%>aEE=|_B<-Y$`4)Kmw0>Putmc( zy{|C0Iu@O-^oHC62~1zBs=Zo^F=Q7z$G6>$|JOg3l8BJq$M`1zj#aL)fESz@+Q)qc z_R0ai(|SVTB3Xn;SFvbZJVo96e6+0VaOv_rX6yAPCJh_UU(Z?1?L3I9g{7_mQi9xC zc3_W#Ac;D5cH8oIon6jfQG=#Kifd=yFz!?{T>q9)5bnP@hO8KvY1^J(F7wk`NzLp6 zonLqKIby%7cE4lY?kkD#BgPZs$KVOcV|9{Ccms; aXuot)8iERA>{O?W0G$jX22rc@$q7-q;xq4 zix=aq>J+|15?W3QMb&)CtL8zebZVMpW+%9a9zxU7GZ76ZDpo@%6UyC%(HuDtO;BvH zd*EME&5X~=HXNgYQzR(ZF{iPmdiKL)qt=tnZ=_V4t@0f8)w`8eqjxqdQ(~w(y+KCn zv{3{MjPYA<8uMI05{gAPF$nB7PC_QfJcWe-iHgA %O9J5QahKU{;v0s}O)FKurUB zjYtiHH%Z%V04(syIPdfAP|r&PRhD8;DC^qZIMJoVMHlkfYOgcGXM6#_*BNNTa1Lbp zGW0wDm9~sqf^~!RMcQkRCo09;b8{}zQ_eb;XY1!ApZNDJqIYNjv>u)&UIm9CQ=}@d z-*(-{FL #EgmX0 zdP(RQ$t4Lk{uXrIeN;ssOQ{x5GhZKkl3+B&UKaUt9S! z&QxI;j;}SlU>p`q%fvtC%a5-s*Qqw