From 73a0fba45eac03193c8137e9a8fc0c86aa5b2d0a Mon Sep 17 00:00:00 2001 From: Jack Merrill Date: Tue, 8 Apr 2025 13:22:04 -0400 Subject: [PATCH] Implement WebGPU detection and integrate Kokoro TTS worker; update TypeScript config and add accordion component --- app/dashboard/documents/[id]/page.tsx | 243 ++++++++++---------- app/dashboard/page.tsx | 146 +++++++----- bun.lockb | Bin 157196 -> 195241 bytes components/KokoroReader.tsx | 175 ++++++++++++++ components/nav-actions.tsx | 318 +++++++++++++------------- components/ui/accordion.tsx | 66 ++++++ lib/utils.ts | 21 +- next.config.ts | 28 ++- package.json | 6 +- public/workers/kokoro-worker.js | 49 ++++ tsconfig.json | 62 ++--- 11 files changed, 741 insertions(+), 373 deletions(-) create mode 100644 components/KokoroReader.tsx create mode 100644 components/ui/accordion.tsx create mode 100644 public/workers/kokoro-worker.js diff --git a/app/dashboard/documents/[id]/page.tsx b/app/dashboard/documents/[id]/page.tsx index 362a26b..1884fd7 100644 --- a/app/dashboard/documents/[id]/page.tsx +++ b/app/dashboard/documents/[id]/page.tsx @@ -1,117 +1,126 @@ -import { AppSidebar } from "@/components/app-sidebar"; -import { NavActions } from "@/components/nav-actions"; -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbList, - BreadcrumbPage, -} from "@/components/ui/breadcrumb"; -import { Separator } from "@/components/ui/separator"; -import { - SidebarInset, - SidebarProvider, - SidebarTrigger, -} from "@/components/ui/sidebar"; -import { createClient } from "@/utils/supabase/server"; -import { redirect } from "next/navigation"; -import { remark } from "remark"; -import remarkHtml from "remark-html"; - -export default async function DocumentPage({ - params, -}: { - params: { id: string }; -}) { - const supabase = await createClient(); - - const { - data: { user }, - } = await supabase.auth.getUser(); - - if (!user) { - return redirect("/login"); - } - - // Fetch the document details based on the ID from params - const { data: document, error } = await supabase - .from("documents") - .select("*") - .eq("id", params.id) - .single(); - - if (error || !document) { - console.error("Error fetching document:", error); - } - - // If the document doesn't exist, redirect to the documents page or handle it accordingly - if (!document) { - return redirect("/dashboard"); - } - const { data: documents, error: documentsError } = await supabase - .from("documents") - .select("id, file_name, created_at, owner") - .eq("owner", user.id) - .order("created_at", { ascending: false }); - - if (documentsError) { - console.error("Error fetching documents:", error); - return
Error loading documents.
; - } - - const pages = (document.ocr_data as any).pages.map( - (page: any) => page.markdown - ); - - const processedContent = await remark() - .use(remarkHtml) - .process(pages.join(" ")); - - return ( - - { - return { - name: d.file_name, - url: `/dashboard/documents/${d.id}`, - emoji: "📄", - }; - })} - /> - -
-
- - - - - - - {document.file_name || "Document Details"} - - - - -
-
- -
-
-
-
-
- ); -} +import { AppSidebar } from "@/components/app-sidebar"; +import KokoroReader from "@/components/KokoroReader"; +import { NavActions } from "@/components/nav-actions"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbList, + BreadcrumbPage, +} from "@/components/ui/breadcrumb"; +import { Button } from "@/components/ui/button"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Separator } from "@/components/ui/separator"; +import { + SidebarInset, + SidebarProvider, + SidebarTrigger, +} from "@/components/ui/sidebar"; +import { createClient } from "@/utils/supabase/server"; +import { Speech } from "lucide-react"; +import { redirect } from "next/navigation"; +import { remark } from "remark"; +import remarkHtml from "remark-html"; + +export default async function DocumentPage({ + params, +}: { + params: { id: string }; +}) { + const supabase = await createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return redirect("/login"); + } + + // Fetch the document details based on the ID from params + const { data: document, error } = await supabase + .from("documents") + .select("*") + .eq("id", params.id) + .single(); + + if (error || !document) { + console.error("Error fetching document:", error); + } + + // If the document doesn't exist, redirect to the documents page or handle it accordingly + if (!document) { + return redirect("/dashboard"); + } + const { data: documents, error: documentsError } = await supabase + .from("documents") + .select("id, file_name, created_at, owner") + .eq("owner", user.id) + .order("created_at", { ascending: false }); + + if (documentsError) { + console.error("Error fetching documents:", error); + return
Error loading documents.
; + } + + const pages = (document.ocr_data as any).pages.map( + (page: any) => page.markdown + ); + + const processedContent = await remark() + .use(remarkHtml) + .process(pages.join(" ")); + + return ( + + { + return { + name: d.file_name, + url: `/dashboard/documents/${d.id}`, + emoji: "📄", + }; + })} + /> + +
+
+ + + + + + + {document.file_name || "Document Details"} + + + + +
+
+ +
+
+
+
+
+ ); +} diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index 6f6cb89..330b40a 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -1,61 +1,85 @@ -import { AppSidebar } from "@/components/app-sidebar"; -import { NavActions } from "@/components/nav-actions"; -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbList, - BreadcrumbPage, -} from "@/components/ui/breadcrumb"; -import { Separator } from "@/components/ui/separator"; -import { - SidebarInset, - SidebarProvider, - SidebarTrigger, -} from "@/components/ui/sidebar"; -import { createClient } from "@/utils/supabase/server"; -import { redirect } from "next/navigation"; - -export default async function Page() { - const supabase = await createClient(); - - const { - data: { user }, - } = await supabase.auth.getUser(); - - if (!user) { - return redirect("/login"); - } - - return ( - - - -
-
- - - - - - - Project Management & Task Tracking - - - - -
-
- -
-
-
-
-
-
- - - ); -} +import { AppSidebar } from "@/components/app-sidebar"; +import { NavActions } from "@/components/nav-actions"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbList, + BreadcrumbPage, +} from "@/components/ui/breadcrumb"; +import { Separator } from "@/components/ui/separator"; +import { + SidebarInset, + SidebarProvider, + SidebarTrigger, +} from "@/components/ui/sidebar"; +import { createClient } from "@/utils/supabase/server"; +import { redirect } from "next/navigation"; + +export default async function Page() { + const supabase = await createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return redirect("/login"); + } + + const { data: documents, error } = await supabase + .from("documents") + .select("*") + .eq("owner", user.id) + .order("created_at", { ascending: false }); + + if (error) { + console.error("Failed to fetch documents:", error); + // Optionally handle the error, e.g., show a message to the user + return ( +
+

Failed to load documents.

+
+ ); + } + + return ( + + { + return { + name: d.file_name, + url: `/dashboard/documents/${d.id}`, + emoji: "📄", + }; + })} + /> + +
+
+ + + + + + + Select a document... + + + + +
+
+ +
+
+
+
+
+
+ + + ); +} diff --git a/bun.lockb b/bun.lockb index e6603c539bd2d67c51f9eacbe675527c98f016a6..c9a33ab49e7ddb64ad295c2cd822fd12fe50cbea 100755 GIT binary patch delta 51867 zcmeFa30RF^`!>AqUC~YAu2*h zqL4B3n9Sbu+V`E`{ypFGJm3HOzwiHekMB61`{-Qfx~?@{>srIT?%f_1T$bci*IR61 zIzKXd`I>ddOxEb!dSN#5-do2{1=|lc*yOx?`pAX_ibtcR-^3!iDl>dqjjFiIDTTj+ zX%XXBjP3o ziA1Rx#U13fQ0hWCEj~Cl0LuJ2B2gpA(RD>4DR?B<0K5;10fneAa z!2o|S859r@5f>f{BLst@1H=5HLqwv54S2(zfhpe>SlI$R1iftyE(bRf$wi565V3}0 z4l)>lqrqf|FPM7Z4JJ1yqat#jHxkL!E*Lf^8l#nF;9_)-8q^fzXOOAhV_@po zIxu;*0F|^Li*`~3ycA3suz-S|JtHATYD4Q4orfv-uxEq)ZFalGyU zerj5o@l&z{GI{n8WEx=2PJFpBu%7h2h~K4Uw`G!&5$F|h$LF(Nw) zz5#PEcexn2yw;a4yFb!b>>}p2uv>90H!IsSm2ppDjx>c1&p z7t)JedAG;JqnEhcdQg7M&=T~Brt)woX?zlT^0I#~er92Epc5idF!W^k2rxC^1*V?n zqCDv>dh-Td=)-R%GC0-&SA)FsOLxJdv(@a%>X}d~HM1(vrDL7U+ z7;PX^4`clz{rqt^D)Qz%Q#u!%uS8;qX7X_!ATc;OV3J3MwE|0~f($&|ZPf z$MX4_2wXmf@5yg4<@5LDJ#!jNJ>LbU4!l4*^?U*9A^j*ALI(Ac3q9H4$6J~KrZJld z)&u|W=UqP?6OgvKSCGl|rC_RXB6cY9;2Fqda16@PB(~)E^hRKs8~5Nf>Uqcnz8!Bc z%>}tVB4o)AxSx7Z2_^#yz~qq-94p9$dmvN3m0+qU9Zc&z5lll9ALt+H7Z4&Efi*|^ zfnYN1-6Y;{2gqb_Y+!T@?dwg#l%9|$$`PUMFcwUfYlEqvUqD23I4b`f${QvJlL5{V zyn!ZQ>hW1*B6f-78`yw+WZ+B4RG)1W&%c8CRdWZjHuQdzCZl$_NHhi3kgLaoso(^^ zm{{|;=-~E{sV7&33QmF>LC!`4RPp3kzGp#xG3FCO{U%O=OcmRpr_=!xFm)^}I4sb7 zyuYY9WF5%A;1L>+0i1C3Rgo5Xi zco+KzPqd))Nih-OT`*cSVp^yGi$U4oa4-!;?UsFW7OxKjlLx2zg<-I8n1)QN=ZL`3 zfiV%GlLJMMQeZK;q%4K6_!5{hVoY&6#5m36do)u>j|`pwCyPYego@UH$$(6OgJaAm zhDP{{uB7tyr9n>y51hx>lPJh{A(Mgr@@T(+K=g1>8lN#6Oa{CFQ-;Yxf$?CH!vdox z2HJ>3wGHl{FKpEd_?}+|(_Au0=jY4@A)O{Q=C3F^FfNArfZKgY@OZyy_D-TH_gcs| zS_;-hVVq9Kj}MNH^b4OF=7$H1n7DvwznDOg?qYt0L^CK=*Qxcd|M+m=Yu29k z$s>PnX~VfLZJ6lVdCV@i$FGhxJJb4S@$BCRSAREX5`L?Gx9~ykenO}7SLw?y7EgR<^P|tYY&^s%d9DdO(o4C>4Sc>I&Qb|naP%2zjDSpb)6!A-(u+QMIkGF z+kZQEW5wZmrHiaT+>?zJpSbx}^ZxQ~UA2B~yYuVolv(c|wOcLySFWDze6zX7wfsJ{ zuI`|dcww|z+8k4v|2(_;8e`%g`@5M$XQ)+dgF#2fEC{w*)#Ata0&(|fe~qzD2HWHJ zuWj5~%<`LVW!d^`jZ%+qzHSg-+^JcUcDhMz24C*>Iaa&gRF=_Zzk0pqyTtaK!n-Bs z%+3TzSb>2vm&7DeXD*MqOP$4TYAj7E<1$$RR5zHUnX|-39nZK}-s-HlrJW=bQa4Cy ztXOKt6|sV5&SFl3X*HKgTs1@@TV;}NGdoF~AaP8$xt%0Oki=9>QUS>dImL`}>eNwg zYl#w;fhzB?c`ckJ_3Mg6{gjP*8`*0@7|FK@3!Xs2eVq!UVkb?JXvm+cG9V3vR99(h zB_uCMI!xEyUK6`qUkDn?q;HU@k~+*AZ4P1uEuAHq*eCn{$?*`9BP2D-q0th1;#gMH zO0F>oIFR8PP7Iu=&knEIIkyHVRx&{xT zH>TLksW>l9g~a!U+*AaK9I9+i!r_KTc5|v_H~$NR$4Qv(V%1Q;xpIOi2BiPICvzWyE?R zmzr`E8a5V*Tp=mjmjpu+MhL_E8d7*|eHx>hh(z6)PBRCIV^h4Cqtw$lW(qHAi|4s77sgve7Kd}3myQwqx zgv~Q`7V9==g{Cse5Ipj9{$uQ1NDh$nltXw)NK;DOFILdeS?u0|X_?8ewA{^{xle4K znX^V#OOeQj6?Jk{S4Ps!9My5M9Lmzo95k{K8?21I{1cP4#(`L=TZGsEW$Yeeo)ifa=bb|TRjWg4wE2&4XFeEOG! zW#HN#Bg=}+9W<69HiV^HIb-pV?A!tKL>XK3Cw3pP{z{#>No{O8V*Ql5i+^HzrnNd> z#ClVz`WZ2g#i*N55EZct1a}H@`dFc|WsN7gqi9@?Ht!^@Lb$8~`O(yAtJ!YV?2Fx4D3`kTTW+vQm)`4kt zmr44-c|)MY`o~ypgv1+%0^)KGjAqx# zn3khV@)AmZ*l0)Y3Ug`L&>ogYtTQV_mc3B&Su)J*#A+_g!$~F?4-HKNOfEY+aghrv zgwoKJzu&?#shv2`m3hcy8VV?}`%4`pcM+q3SKh_N`aPJIvrL@QgL#0|da^WUnMP4h z7(h20alKwl%S9%M?8V=6Fj?S_Q;_&^fw#pUda*(mnMMycw933p9mHvF%)?ctQ3yp( zszk#D&U04Ap7+7VsEm2^#m1+MZTS;Z$D|ph)cGPdQ5m~{7+<1;2Ue+4HwQ5vib*OE z8;ZVQq{HpiJw>7s$_(=n<12cKm=o#5&i$B{n@nRNreHABadXh9K`cNS8`-}$b`mkP zhSZh=l&v9_@F!M|7;J{F8zu)DKr9n6G>X`3#9)=1gLsHHE9@f^&-P|oePxo{-u#?~ zzwPWa>JK7cq&qlBybz?E@wVPI(HV*;HY#5~+(lDUKVi6>?>MT-WrLMU5e z*3tO!$Ei?AG@bZ0as-kUB+Lg4ebo?F=phsL9m=$@a8uwY8a1@n*G_U2l6kEp{xy_& z^plC*hp{ve8^#JjH-|ATFPTK!hcBlbd$EfTOM|imD`ygl^Sg)d2%OPsCGp7-%%i_d z;*5i%f2~ro4$?5CgpFHL0}1XDPC5CiXjqmu7osB zDbcF=0g2x(QBI>T?y4Tl%ho}%gks8E#kO`5H`vM7KxNq9q)JHG6ogJS$2}X<6*d<8 z*>k?kV~|W-?90+X4ac#F=$3aqs7`Y4Er_4^bQz#C2 zLRmGGudlq@CJvEkBLR0kWu+ac(j~@{hGG0Y3i(9TSd-dYv&KB6;OyY#Ajw0F_b2WK zI%?tkQAUj1jahMP{$AGyS~|39LR(*X2TU9((T1`w*@cV0SK^*8E(>QKkur^u5%4kd za(0mHK#V+!6%F5i79`xghS_NhjYOA~Czut8kq_%AcjV8I$R_2UE^&_HB|NX#*+~*0 zxgZVC5m--81qo>#?X{ytB1yBj z#pZyRE%X=HC?sl|mlg?W*o3j!T!MtdGY*!zQ)(AFo(gov zKq6m~E&MdVi0hb5Z-jr&^`YVsbmwATMBNZPK`g_-;}^D>|v^8d)IGeg+$|7LVNw93{0w;K8;2$SY- z+H7cP`jZVxXDo4+X#b;*j=?%6Gll)8HYcOi1LauN;_S=>i8_=HtZ0OTj-H&~t!atZ zWxD)PTQU(^2NaSpT`xPydPpvi_`!boN75Z(r(>MRFNHcNudO`D!V*acw79JZ>*^vT zS`5mKMWUa?PaT{+WOf>!knCwnY0N^*MR^#%f|!hN50h6rna__YgZq#NBpYSTvQrX^oUgp3UMnO}tXl#!ka&Hf^T#_&y&onu*GFC&`0krK~6e`(`zy zUXbe0F+$QU1^-Nk)BtPEPRvqR;V79zJVzv&0HtzCYXm`ZBoB%=&S7bzWs>Jm(2BrT zf*Lx`t-YzyW)up^v9_pWDQ2fIH*jLheE z@+wFkN{L)-vq+_kWYQlA+poA_5%UPd)LG2Z0%elPi~qQIgq_9?NS&CDql3nG#AM2i z$}NM>f#LGC)0hqkdOQ^!MU32zK|qV&AyNByl)yvB&?PKwqD)e-r1mC{k&zfOepw3@ zK~g?BNRCnrMd5lEJ4u~P-aq_4J^~Uo!q1fzkZ8xp4G&GehQu!nnt!dbY9)Hq@Xlgd zlVsxkS(wCXqjZfDt@^6F*^o{x04Q`p9Kkz z-(Bn^zN_(an6f=xjP5o_loOtSo%Po6+az*gVU2>sPa)bDHbLsg+lf(n4~eW+KFVnL zuSHH))Y3t67%}Q8Hd-vyYDhF&_y-=lb^L7Mr3gqPmGx2W1wtA>h}?RyU<>sk#08$_|gi9TF4NG}P#0Ye$GMxr-R1(z%P+lYk>;*;_L>%A%(Dm<_ z^1)TgOO@+E(}(|uqcWmwz+K4r?^uF7g8;hm4F$+BAAlMfF7OC2UBr}cGzqv=naYh- z{=-ulp=9L^S6PuS;#A={fUa=>$$kJ`s!R=x2h@QefaDN>42=ayKLw!jQvte&NuDN0 zKm~9vP%37E$+AR%u0((;mNIURMe+eMHma{kqx^uGH8N_fT`ecp#U+*b|&aE?U|ZNQ^!I>P5KEr{uz^h zCkpArlz$SKR3QjxTa6?^U~){fApaZYmk4E`3gW@Eeu3ZTx-70}sgQ5 z-vOqJn6^#%2}H=E(?W(^Fm3RKg1$)5Uj@?;-4yhtV7iD&Uk;{@JOq;=j|F}z=wE^B zL;np-?fv8#{-@k@fhj=^OezgQPmH{xI$&z39+>jg7i2xK9_035{E18u&^oddxGR`E z)}0asrt(foJ=%8_5{N0I8<-mG4W)?zJRt+fS4-K5#)cy)L;XoQ4+N6|gTU0#Frflfru5-L`e-m^@fGr^GF3bddSX8zotR{QK^9p4Hw9$~ z5HgMzG7?k669k!<99keJdFg>+()lfYE}EHG_MX+pY^Y5h@zbm<7Fz(Ro+krLNGW178LLOL-u zpb%tYiY`Y$^{o)}s!aNo&@0zJMW}++LPlcButwmuf}WW2truisGGr^5RNE0yxg8`3 zOwrwftjd&c53PSn+mC=02ZW5o6g@1+|2s^R`8et!!%qtJ5mWRGt$%7bSIBTq$nejY zCQrVQuTaSMUty~M67myY7RuGK(*OTApH$_2U=>}&sZO{ltJ5)o9#82arpfW2$JGBkrvB$KRrT?dRtL$n zQ2z6n8c&B{T*Uu*O#RPeD$Rv|_qa;WR{!!bb$`<0#+~G?ueEypbAx)k!-LMPv%dxp zc<5hMuXym+$ocQ*_2~S2Rx|a0QKR-=SY!P1=%Q&0V-oxBTd_|Rnmspoz`IAkqwRBr-?1)KB-A_b}+tfY}aHGHpkV^@&e9$>wQF+MR!Ytml+9ZPLzu>0|8I zCB#ZPW#g6kR~wG@vEQ9srjP{;ITffmW&Ea_-)}PWlLqp-`;PZDHQmq3 z!DqMC9dft(sl@cx2O1CjD4mwQ;C|k-v^n?RN_N}4S$Z#bQDys}?WQ-yOIO+&^2l4GYy*pIa0c_euKW z=<%~!-LxVPu~*wB1fBEAii^uW;`DftlvTjGE*~1M3U6mT;D^POiT*hq#?`Do>}LB# zq?Wi*H*?G0`y0)=rVNrSTHa;Tw{x8i`PkZPmh9b|8mkv(H_5i=Z^wz(Rjf<-n|0^E zoJ{Q{7x(u%X3@*@!uPmy`?~+oo2t3{_?jRXlHN6y;8fPmV@%>DfQM#`ky#_8l zJ#z7ub00cv_%>7Lfu9CTKV=|)walw}#U<^qevz*qhb6Rq_Ua5kjn-5D!zR15CzQAQUE%!h$v}&U`$Gn+ST|SIx@Aq8N{R}-`&-@W z;ceBt<^U2a38;4y_9_Ojs zN^_^q>+NDDJFPEYRJv+a;~%#^OFlg-IU03Lw=s+DQJptRCwbfW^Ou?%ZT{$y{$Q=i zIpdnu&3=u!F|Gam8};4}8MAzE`hxI5ZVv{~{~BtCcAlzvi>kErbS*6W_ndaRlBB0N zv~Tjju)Xh0Ci`VsPcoRf-+Qv*nmydbOsVZr%S$^7HLJZd2Am2UZx-LY@l=hc(e*9X zvDc>!{EjSb{Vw_Ca`_!KxSnxFW(-or;nicQ0Ej~_}ko2=c z)BAJ}&S9L(+;T(Br4N0kbeq*+RO_uoEv_rk1=?$goJQ&xmI+KZR|w$uBaXLZ}VtaA(VzP@fQeYD1Jx}JLSa=u#q zjYHb^+Uqc*{l_&53l;0qRjt#x^($lOld+c);vXkCeagRJ*ekZI^*a5d2cCR8?B#oF zSkvwwCiZ=oE6of$QX>8s)23qW%~#=rZceVc(6_(tl>=o`=9Oz8Upl;G>~h7_W1(qX zj^F$|QZhF+vVYK;(cS6~v3cV6&EQbpZsVIf8h)usSo*^&$wN`xE~I7aQD_xhhRUc5#>-#p` z+%kMYy+ihcixNcO?Z|57YySHc-DWBQRlKq5r*InxcjZf8Xv^!e;$d$ey zZ`Q1e+a8iWx4m`1Ch>y?XX>tu^0;bP(s9FwX%?L}w}>)sC-d4dW{8jW@Y1=zFQ7CXzb3q%d>w~*Ga zt9Pe$m&`R@KHQjx#lPpZ-8y}t!ASS8hHU3q19tG1C&w69>cfK0>Buv7J9Kb*5YsCE z)#Obz3r5<7jA;0%YG7rPnPm-gR!-J^tZTRLLfnTZZK5J3zPVL@*@SN&4h=eyF!0!0 zj|JwjCadWmjNDfAmUd~8(!J`rL2}b~3XT1K?TXUVI!|9a+d872jb-mQ z!`X$8D}KmJssdXq@*TS`)ath0y7wl-XSdWElru}$bC*yt-VG*N`lnj#tCKDBA4Hb+ zX^>)}b!vdoQx}(tid@srMs5?r%pN|B8*%UMProihr+bWCWHW8z-uny7s{-79$GrWx z*;m%6>G{VYH*n0WH5hLI^Y~M>x_>*{{XIJSC7wzOdC|c8qxqHY^NlaNxmm{j%DPdCy=TkgykZ<#iUn#xKb8{@HQ(zSjLR5`QUTYQxV=}#R$upX|WGi!IFy6 zlXCQ=*ps`@tgoXd73j%zPp*B&7~ z?;-Vlpu>iicyiC#x)LAu1(F69@Jr@>%ZF{P)M0_8p4@A;7t4A0Lmk%SwkP+N`Q7$m znvc*ANbi|$8F~dNuFRAB$Z{bCJ=S6E?s#(5Eb5LAGkBuIN+8uRqq{yVA5zL)Pwp!# zhBW1=4(n3x$$e)@mcyhm4C8X3U^yr?anB&-zd&8Lhb94!! z8pnFvAI7R6Zo2O&*5KF&h}kdDsRy3ox*S{oU>NKB61}SQ6iYZZsB#$l0`VZkdK?o! z9LBc3LN6bBigh@)5909G=;k9&aRZL|KN`j~-=Lombvf4P@i2A-V%%d-u^z|HLJWF~ zo<8vuH{n?HlVQx@9l8oppJT>Php~K!DNjAcQjT4RIORP$`^;0^oMXw)uv$N$w-60E zW>bZ=3Nfq7lWWB)tI*w#I{kXh?(%d}`Kk47wbk9H^cr+DcKfA(8As>6&$xE)kmBj2 zA-})7zwQ?OxbaJ)&z;(d&+PuTrF}~F-Pq-=jl-8}>{|IiW$!d%-JWAse9~d7o_l(= zK}zkVK1O@-;-s-|1CPs(XUz8TvVQxp?X&(b9bJMA&yU#i{LzY_GlGT+o>A&!*M~w z7v~c9rL_)gwfuX`_qjuSe_oig;9YX~df6JS-p!wVecY<%v4d0^I@Gqn?%RV!BWirc zS*V{MH+peOMdLmfOIdogfxQ3ZJom%(C1)O_uQr|6%Tuy1er0yds^JN&e#(oEZ5J91 zP@GH8d+YKdMr~;1!!F0J&)8RQ|MuJ)d#9h-6LRKr=ME~?QM~q2U+PxfBI{lLMbq64 zzWVhZedo%#U5kxd7#{rTJNwq&n>z;wE%D5Ker$oX$f-%f*wY_3dj%hlV`B~M=dd@C zZ@VSr&u31b4dkbK2W;wlx9U-&*SCj$yI#*bJZaA2;#WWC|J>L}{5$jPfX(mL>iHJ8 zh#Ee(U*_bk4lbG-^8MpI4LWTqA8hjN5 zfAyEMvP-)sY>}iEdtVr#TWpuJbH6m=yt+=4Iztx^dw6tY(a$v(`Z^wVhz{$zZ4`SA z>yGH&EI(O(<*bcgwBqB%iXD?I^KK@uv!3O)dWqlkL46vP4Yq#p`1iM}>C=v-v}^gc z*Mzw<)8Z;SroZT+t?%vpf!>Hydp|T&wQi7ov(3+!X6-jxY|weYp|&wg^}S`?_4}qB zKR;*e&gL;{U*nxCuYC=WK7U@Y&9OT0*dayM@|<}uhn{HKEx<-UYRVh7s>VRB_vD(S zMWe9I>$RFkyy!pcY+YGItEBzg-@>5r5zAiyg#AB3~cMckjI=AbGiC zlN6_mD-3KLg9{Q=tgC(d9gVJfv#jyiS1t8Jt_|w@+2Zqr1~c9B9`^6lNm8BH_L%m@ zJJZ*N|NND`;j`{ZinSC$!`j+}@y5*C$?v)ekf4%r|L6l0xbXKjs)VqIjzLTZa zF{qVRgHspImzHvS6T0pw$}NeqGar>AshjE_x^lANj3|e!_QSL{Snpm|KYzJ=WmEIX zrfvc4)zcfcRH+y5`%^hylq?w>`1HZH5&hrZU0rtc@Q$Qi@t?0u_ZaZl;CipNQF-&! z11%eQjs0kMrLo45?Bhp1e0`AS5!ZK+R@31FULSsGWX*nlF;F;3I8V-6F;Bu_OaH2) zcujI=MVTh#pl><~H!Ykcx~TTYee=Qd@1niBA4)1s2~57U;jx?EOfSP_qVUaQhnL3J zS^0d^6aPJ0IrZ&K-@zAo-dhhs!8>R*CQ%g-TdNTe4)A?>7KRGWx^~tXX#+f5u z^`2kSc20+5GYb_tmTr0zM$WrpZaeU^-S~#VF$)k*>vyjqzzH7#v!lwX1R~(=2_hFrf<%s13_;GWKUiD zUdrnCj6XNPu5#A%BhUQ9vW|RD9y=-A|7-FXb`sV}e^1J}GQ(qW;&1(!G^3CAGo~0^ zZ|XN8q*4BmnD?i5FP>*{TIGBLMJt9veof6WOTFmCeR_HRn=s90C~ zu1lH@>f_p;Zd>d!xZ~Fo_13Y0w^j^H%G15|=}^I)1-GU?-)_8Z)V}o_3`Y-_I-49d zFgHtIqW5^E`@JvQhuWSv+u!)-nvJ_z*bltE@P#{ayPHQFy&Yf0Uvy4Ih3W2hwDu4F zHgtjOFViO)W`my2n07we{AZO%??&2lw(n3JI$>dJGGWTu{VOWZ=`FscVjaELv-VOS z^RvTlv*nLjyvaBz58P2f8`@jMQDKD>DuB`{{vxd`RH9KS=NU%LXWtA zH;!1gM6(quf_3s~i$Bk{`RtT9TmN*ck{&gq>t(O)AsO&M`+1>lojOmOTRH6U?C9iV zc%{#{@}H6ZvhUJhZR6HDTXzmCvg2%LRH|6#tZLmTL#>Oe)}8NvwlsgdRo~YB-o`UG zEju_TBYFP3^{1Cw-+0#3NUL=E1F3FkR@WEPJ?5@nyT8-!d99wdT-7ZsuFcqf16jf^ z1NpOOSKs~CZhY;OTKgUin&sYECT;wFe~w1xmCV)0o_L;$XkuMx)@9D_I@>g28l4E! z{?g;Zvxh0_y3dcCvAG{(R;PuEb*`$`z4^ZGW7gEDYgIFT>|L{_!;UYxOKt^Se;akH zLDNIFCW@*uoprLAdNZYw^KUE~(|gsmi8eFV?Cd$`)`fxRI|OuWHLD{t|7{?*$x^oq z*gCnS^MwzK6(?5?99!Ho!?^ikBM>Ct5>*3koL?WL|~DjD#pOGn#V(RYFq6I&;=IdEW8cwpbk#KP(~9_&~^ zyQ;cx%X>7EW<7Dp$?Ci=GOr(ZL)${9d(!ENP3#(d?dQZQU|sO>-&>zqIDNJA*1O-J z+p@uf3YWif%y2%iGU;u{eQTSZFrGP2J~?G&Y<=mryv6T&hBVGGe7V2X=0%s*f6gCt z;q`qL>uTTWOctv9Rov9Im@vHUwmvV?2UJ|I@GuzUkvOr;bJm69v+g`xp0|0N|B0v} zRZ_J@uk>R>_UT9aOcxpCl?U+>SFx^- zs_*tx+aDcU;Xms2@RgD0bkAM;zCLBJzutil+<|WHp*=NQP4J$7CHYuGsY9KHE)N%V zIFlMW;Gk}o!0yQh2bymgJjLLY!ij@<6|Jf}zglun7IeHwd-|GySH691t~3~1RFc!| zX>k`jZr`E{BXZWI5AJ$V;`6OeyJ?PF+wW{V{=Uwk?xVKm7(CUVsbU_zExh(pzi1R$ z*sSVDhKYRLy6HjtZGN;4hFs>ro;@VP z%P-d0NcE5U*NiZ_t9VW3Ez_2jeQg*j{@C+itaZ9(PFbn#Gj`yY+4aE*SNGrzHj3me z%U|z#I6q9}zmMDDBX4D>efwGG=jL%Y+oxpoXio~NpLx630#eJdyS$eFfOr}*5c z4V7Ncr)j;KFgHtc+{G__CydPs>7Dl|bD-4zl~Jb!C$dC$kC-fvGd^1<>a*ssj>pWV zMkrQ^Vcz|+XQnl`u3q-K*~Gc*%Fi`rxt}6GZg79-=dt%?i*18uY!%1a6in*xb*tC3 z)+^_paXr3j>fr^Z)yvint@c|}%<*rP=3kEXQZ=vR#6ru--W>B#VtekZuiU2)_?zgZ0f9DVF}*?Zv-X` z_^wu3lhn`tlVMelOYhWGyf;AAylpw>O4~GkQRcjG@`Ck+t(&)H<9{0*>?=xm=d|+N zOucW9@-7zlT(2%=`;0eqX)~+Q*2a;&(`}yZh?I}B=(hV;g0A8xnYZKinN90I9GHV2_aE6lGxE7&HDf`Dn!C44%PNU; zn_cpEJ5|i{RyD8fp1?1gWBV*mdNXdz(fc0?5**Y0A|GEenKUSFQ+@T=5#tt>j2XRd zm$YH=j#T3|)5Kjy9ZR@%uw7)UOLbRfwB0Z`O0iQN=9S-U+RTP=?YrcSo$zYfr_>rn zgZmlv=UiGk=0tdvO!u;#LRkm~&rVWZ+c%{;vD>R@}=WHwG`b^FyjPBj%HS zaO9*6*FEYX&mQk+562Bw{Myk|F-8OCb*+4%kv^dAyB~S|cl^5Tn)tw2^y^}`#B28> zlA0{3*CBs*hP%j6a%<+yrL#}{bkMBc7T96!{o69Bd2E_RbjR_Wig`m-&3kaX|CN?A zJbwlHChM6=&zJ=^I#O)8sbuIU$vA19A3GLb3_3hFx>FtLqi(%-_x;_sWYg{w@h4sf zYI|Bt`Tjbxa}TD_sRQ$LzZiic5TwAe8QgM>~C9lR@Tw`an_*UQ(T#ngNb)S2TD!si@r7*4;7x>c{9w zjq)2sbbJ~Vlsm&==&QA*J|&%-sF*iG)x6aYdev8NwZf-G?=?R{+nQbUdAYvDu9;&c zS^Kpo&Z<7ESUAJpt!hYHY2K2!h?-N5C(NEFc+IW9&|>1zW0#UfBt{%ngw=(4jR!Q- z8h^Csmc@Q~@rmhQ9g?SiEN|!1;CTCEtpAcpYZRN+Qo7FhAzA+3yPoS69m~UhZve2wuBgY0mESjwe`&51=%QK*Lb;X(XOX|eA_I1@*;dIxQ z?i97&^HnuZJgI%()T{58-j`~IFYg(VXkNoDd~x86V&%ORmLZ4QUuiwW#Bt{88tIdD z#@4Mz>9oA*lKS)dOe+&^NZ&rOE)|(e6bTZTx5()G+0weH+dI`S9?+}Rde`zmo!`?| zxZ2gU|HM|z8>ZVk>#5t?@-8uRRvYCFar|8BJt*Okb_c5m9S6?XzqV(Im5O#)tbciM)OaW_B4ti4>P&Dk?q?~Xa!z0lor?diqOJvVROBwc=doP9yvbIt2q zH+KFV89AIY^V5BuoM1RnVXg)9&P8ahYbS1>y{f^d3#Zygo;f>uadD$|S$W6zyG~px zdFa=8<()f&tdV7$yR~?7 zQtmAW*Mld1-|pGr?e3B|pDQ^sw-a^xL#M6J`GQj5OJZxZ@@(gSrf^ zJG*(PyU1TrLFP4?F?r)w&G_nl{^=Wh>mOdy|M%Cf4#)R&PVEuZR&rh6`bmyeql$Uu z&&?i;QgbHtbcE&6A0BjnnRIi{(Et#@};ki>|%YH{SnXU$4C0n~if#jb5iThpBlSn4(M%Q!#Pje6o2j4opu_nUfKDtuq@ttsQ!;h zC5i?0IH~;U>ZScE)Z(nOdi2jq&uw$uw{OzAH*qfFYtmEtpnKT)4%w%ZH`mN> zzq@8m&Aa$vTjlF(K5p2R+;5uOj|HmEo2Y8tqWBVvdN($#IzDMec0QZql{~8X%V(?V zSn9bST^`(`#OBnRhNhcc<~OrS{uI30Fnnl_u1QPgNKY|q`@nu1>&$BXkWG||px+(Gkz@Sl4_V!^!|J)N7iZMWFZ-x(w&TJIy}s*}cZ)_*=C-mJc&W^%@di_q+D0 zsE%HGVIpZln^i}DEy&OvIs24bz`^Qu{hyf*b36F$L{r5o9hjFlEoW@9&Wz#Xj_!_1 zTl-_i`##AY9d8A1-Z)_L$bolP+$nOqe?F|~uV!0*-Z=kR`{J9H_618ljm^f7G90|B z!N-oO8%vm~dB6HCD9vq^HbXz~Xw|3DnbJzXkNc9}#SYZq)@K!$g?eTb`1N1@bBMIm z!%4l_j4{J{4!IHTvLn@C{?Wih(dbo8$`oGpVcu!u&km;ZE=<_&kZ)~svi)q6P=}j! z&bHVx^W~8*xi`4*l||o9&Uv0(_gLYkzUSg^HBRk(^I_=o!WV8HACoh+o2$OI5}|6| z*np+e5AQQfs;)d+G31-gtjdM0rrq{^o3^F3YM%_0rFOv<SAKlkLKnClB4#gPUaUc-Ok$;Ghu5Q7>*9Qx9ei(~6v z`X~%^A!@wxq4D<4HZi3cH0W!!5Y#gs-617CY`)7f5#CVCK?yz%4`nBN;8#cdMv zAj+BUTOTfw1tUyixd@Y)^qmhki$x)v%?c2vFr)WA+#EI);apaXFqN5p@ZsjMB!p?K z4B>oc{n3Y8z~&)LXO##SvTmPzxJ4`j;bQh2VFq)p_TiSWWe6F2k1&(DfA-Xfp8Cdj&N_5E9b-Q%UXtTf7W}12Ndf#&_TslqC*OAG3c-&hvWY5NI8BXiE%3oyMN%_PUt!gf)6f)tr0Ut>gl3#v%=sVw*@AQCG|pP! z6R?Mot&f<>>V$>Rj|t#YF!(A9J%y_|$8_iuxA-_g;%I!Ug|bF`UA2L_aqW)>1%w7G zfA@jjEm`|RLcH!DI?b$_)uWPHwZ8&1&_&U*HTOn*px5F0MqCfEMlXEHKtnPnLj2!z zlcTZ^wLfptY!doLE*Pv-*Z!Kx;ZS_T>R;;G-!74b;{!?mjmFU}ZK}Uv?GInLB=cYM zuefHyozY0eyR7Q{L$y|vq^?Np#GMekEm6qKxurTc@V*8uc)0?s^uZ&JYE`&cVK9wW zq7pJ$>3YRt(*1-^n=0PT9o}QZ4RrtSx$J*%LjM2OAbnA5`WQN{h7~+(ImSc>SST9J z;H>4pe)AWl%aKeuj7Y#$E7M{)M**%xArHNe_7-%cPJ)h@-hh8w$Tv&KN1qRrB2L$A zK}T;p74vVzm5WjYC4C6=BMOtAKH@=T=pDMBgbL>hI{KL1edwq$`ZXp>##B>&%$oA2 z3Hj*5=~N%(pD*ZK1P4Suf&!P8qhi_&?vT7a;vE1Jz!bp0wv_Msq%SDQ1hN47wB-@t zC~yp*&!?XS$T9Sx_0s@-h@C#rz6aO~>;v`#2Y^GsVPFHW5!eE(0A`8tIfgliqyh_o zg}@@f3orlao*F7{vgucV&25=K70d4`efimC@a2F^CDu8>yec%C51dIm)feFAwzzpaF zm;*MboBm5|3v>ax0`z|}`Z(!%AdfyHOussL5ugvDo&rt-^a0fqKv%#Hum|WP;1+-- za30>t113|t53O;R_35}*{2)1)l}?f~>jE8I6lCjk01 zi6vkK*Z`e@Jm>?#bR&5UyaC<;tAMq@I$%9O3xFnkJV37;O$DX_(}5X40zfZSW0B!! zU=X2I6baD(Zv6m%U@YJZj01WD^m2P&Kp!vwXl3aE^?_$_brtX&cmccwUIDLxH^5uq z9q=Cb0DJ^K0oC+5n$L*T0AGNwz&GGK@B^>}tN?4k2Ivgf0$qS4AQ=b-`~ZI-0Pq6( z0|NmW;0(9`u0T(q7vKi;2J&hA3jq4O@mb&!l=RVl8=x~lKQ>BV1)u}e2lRj@KvO^; zkOFl8O+W%@0kprU0USVE2z^b&J>UUQ3CMu10PP?0)o|Y$fc6;LQ|1A*kI=rc07wTG z0*ipf06hi=0rc+$YoIyM0x$$x0efdSq^J(xI@NCQoZJpjr3 z0m?`^!eM|0{~&M-I0{gOwUyD#)&Y(K6epYm&H}l>DS*cG3~(BF2vh>aXkU~EP~tV< zDsTlT0%!)(Mp6hA0Qta0-~vE*uL|HgKxIRKa^Nm-2Pgw>1Es(%pai%H+yEW`_W|;v zyw;6xA-n;e0Iz}Pz+*vv3a$d40k43Uzzcx#(p(S@V82PO#e2kQ21?+*Z(y34fpvh|{?P56#;#gv zzfo;V)QV~m%1+t%7Inx|e+>CEqMBX)nI-=)q5jtTU*0rSZCRLmN+W69_*M;RzEP`` ztU5X9UdU%rj>*651Z~RH5k9Y+_7G^4`w8t66c0rZ2+$oY0H71n2w*he4OjrQaSa6D z1JkM36Yv1&PWJ#hcW_^TPE&4xJwVIZ1Wb3tb^!9qm6@#|xB`@kPOhc^HEsz|W99(e zH9G-x=cH3Em7xM*@^aGUXcuP?>Q6>HPp-U@Sl$90O4L5V;VcjFf>A zDd8U*Qmu^gjR$C02-MSwzyy`}B*dww!9WlY0z?4eKo}4WTms~U2nvAN0Nu2vg4Y1c zfJHzYunE{E3gGv53B>$0-J!%zy@HWAg_d>hY>#j>;tv|IlvBJ zJFo}X4eSJVksI~`RA@i=AaDpc3LF8>11EvAz;PfKI0l>nNKd*G0-pw-0>V+(MKG16 za_0oT0L}xlk$ww&4H$d{!BwCqlqKNnK(W9#!8d?%;4W|nC<97?+W__E9&jHJeWU9rMqIxLe7ixP;6hwNt+KBYVi0{5UTNZ!w}@NwXn9Z!d9iYj|>AQBZC&2Sko@C zlUYijzb4nk!Vc9y1>pRXSo_P4DB2k<*z@PY21u#>?ME>hx3ID3jDb;@FXE(K=*T5S zhT0#C6pNuyUUcR$K+5jdRSs{$NA6S>wYIRv(MjQlqTCO~bWn>%@Q)$#IW>K>z@Ujq zL*zrxExOV!r`WTIGw9L_IrNcZ@5j5dc0a8O7ivO|QAnZI>%%}l)hr$!ooTg7> z4OK)`0_cE1i1c18AVs7+Pyvx5qBKEJo(KwJ12O!*XXf6$n`9T2_x|`jKkswz%qeru znKS2{nYm%Vy)Z_WFgbA%F;U3Ep8&xS0L3c-LH(IfK2i*sKUijRz7!)jl37B&)KiX< z*)+5btw2FjUjD@4{4Z9O|BNUSVD@NT7nz+Tin3)`;Q}d04k*Lw&y|7<4a$h0HqA&0 zNI81#`CUXo6BUIWD(gR2ijgL;QS+o=RybGcEzM*<&V_r3ET-2@ao84Dm2^A zH6&737dVNmYNzg7SrXi0p= zvX1kCJev*1L+@YK0`@8)yrnQ2+W*^x6(1h?kH+XDc3?hC{#*s&K+k1K4P#=ajL;Aq ztmbPNNl53hQbZ*-;x$;UYbADU2^1N@HWF4Q`;>H;$S%Jo#VV@ck|XkU$nZ60jC}O% z#*YWiUX;24L(mL(jH2MFRKgBu)m#RS^O<`I9&4FtvG&->>MccU0_!CV#~+Fr6?ui6 zK|-)tReWg*tGfWp;T0^m0El$(*tKQ0$c|q@q-d;S$fS6Kbd6;#kTg1Fe*1x_I_Oq6 z(+}NxdQeT!3D?jKXE(uEaYlN-)b=h{+ae>BDQHW&oqZ4bK0% z_}}wGHM1+4_Gg<(;q&Y^F;Y4enS(O zv8wF**m?;45DA4=`ombt6lPm=?zXS$Rysi4TGy1XLwYi#^txQG~2|7M_wEu*e> zytH@GwyGMFo$O69$J`B0uxN6FYwT$}9wM7?mjwT^Rm8FifzblfrlR#U0sDcqYH}&~_OA05-Qs264-EyhEWMM~^V>TuNfr4^Da_i6K1F4~9 zrRaF1={Qt+>;Vws*8zb7-JDx%j&>V;G+aa2uRy;1lu^DgZRESmPk$g5>x zr`Xttc*;CWfe=3%2$aMpe=0Y5cB(v4Lnu@rPmhs$^t*FDK!d!)ZW8a0fq?a%XJ6Is zy(#0rU#cNoWMQkYynkj-;9;oTKrD~7yGC4JJ|%s$h8Na=*;k=hX$1^2*N@2;UaQ{Y z-N!YIX91xl^Wn0hejH^ zB*Y=MZ#9It3cPy2>%8rc3nz9jb!vEJ!dZvaaJFznKOp6e=>JU6jsClOYZ(3^3a#Eh zcQL#qgn5XxiaP%FUCBDHL4rSxwM34;v)r32%6`0hD`H4=1WH?~5c6RWIjRNQuto~f zN3{@Z=S1?l<4^s(^c#-I)ATm>6(Lq^$?mN|>VMkEBGyXHrGK$OYo##R7{Mm2MctH$ z8k%aK7N?gxPGr3`M4?BS*ea530fGC&NU@BYVQ?xa?aGh412Z-P|6vCV2(4fB=ifOG z6sp)A08$GO^(WK;fnyTQH9!IYQGbaYMI$Okq6x(RsjgOjJl^e)rQd)I*Uxi~G|?vm zy3fB_ee{(Fi|z_`{gR2-R8(vfBKyZ7fUtt8yJYhR)2*a z5Y+tSR4V|X@{@k2-c3JL4^Rxnq?owPigfBv*>iSL5v{P}0fcl_e^XwT_MnHv_9+~n zBlu#mt&J?TYm2fqF(RrZL?`>Kb}K(=&j+Hwp=+an)E~W9Ah1zS1yUs|XT|;*GtX&| zA%N5byQ@F9nmJ?4&9NFJTY)^d^X;sezjVIIA+&|kO#-AAcH4Q4nmzgT*qqbl6e57; z0Q4Bx=|7q^KI&eB_W_|w7p7aTK>m}I>TEXmr;6G@+W?_B60~_|K(96%Yy~DIkZ(olTqXxOiEd5n zh3P{(otTG#U}|!@(vzpUqpVM21z$S^`jI~sRwUoK3 zwV2KBdxx>{fi2*;*ePK)u{8&TM6xaTw8o^FJsF3@&_XDkzYYSIR^&-MX&p?AiKw^# zu`&%nL&*=;zucPTt;22!;~rawkmhp@^YvGndzm(Zdq5jzSdaDJP-$-uI(Yv0@uI6- zD~!_$pV+Xz>k&AVQTmqDAwXILT1xEa+X|lBl8z5tI5s4YuVo&+)emrH+KaBATz>W> zMA2ex-3lJtp= zA`mQTdVj?Cp&9pOi6)k$RHYMAHD!G_Nd~!PJC?IasxNo##O7?0n#)5vvE5Li^0`hT zQ1B_r_iaKzMYTelU%~DK!-ELy7Tbtdf)S~fy zIGeIx*F^wQ3tWE~a3wHcL5%|%B$-X#iuCCQLVY0Q@0hpy6KD4dWj&-zyRoP(P-+h_ zC=tiEi4W@hpE=7ljB|icv^)0Q>5bEu{qnK~x!a9RB3gZSvG@3{XSu#NrOdq=Mms%{q?OtIHWND_=$-lqHO$3G5Xk^Vi8VyFW31|(&-rPrmbi}3GJ0)%8&;ES<-L684*DhLJY@a zJ=t-Lm9QBYlnOsC-(q@|yiXfx7#{%=0*JfpGvUAI&pe?)zV69F-vaHQz@U0>$s}E; zq00(0HH@HMq6pd)nR?*#%xs+oiR;Czpf&UZ1{r_Si+iqKeed^i8b(epRtOCFlYVUH zTUu!Fo!)t9sP-&t^EP;fJ}c^D>!*9(?R#>{5pw=GURlLG%k02Ncv8Vg+-(V26HDOp^*M=)jL+>sUAJ}!r>vx`7GN5S{Xb7-o>+afA-VcSgg#I&BsY&8;$KMx_9X@Nuyi zd-gzf>k!l^7|1q29m&P&?Lcj{bs)Qhrs2bZ!iHzo*1Ph4-1>XmLfnQI@Ga(U5dJ)n zMQp>fYBIaE1J6duY}3bhc1&gysDDHFXl!z1hNx*yz3wQdZN$wHBTTk)n zOQ3DZe;q;cO{_Xa40R4Sm{^B>Xg@TP{B8gCgbY8f@{gC@-V}CeKg2te!tU+I*;skG3x8napj;k9d@oRUsAkvoPWKRQCD-9OH}bifT98bO7hGzB=_8 zX(GpjErC*jJ6f!zr48krL@4& zV&x&x=v2SB{@$9d$7mheC#kha6i0#yvt0`TZI`Yf#+{VLekph`~>X4y) znTUOWDEDpZAI!Y)bi>N!BFByhkSb@2P4aL&DO0}DDxq@Gy0b-`CXvog9DvYyNV{S3 z?$3U#$Z!2n%e#>j+yK#j_Sb?vU1xXsKAlJSXzX@%`GC-oQo)_YogQyDVX+2T3kdDd zobSx7GAQVAS%av5pY!E!ucqxRym}juqzG_}@_BsY#$g~p2NV%j-GBSTQ=?wN{R2N; zK*$TnMlS#Zjr{SQAD@YHH3I}2oJ0tB8Z>mW)1lD%aq#cfUpNillwAd+Djp``_&?c2>AK6YS{z9aNw6 z6UjBH$KfAh7KPBMAMWKNqN8<1prM`Q6SJ0`j|sa=Q-sq}qS0pwb5E($drzyc_R`%m z(csjgDIk?W6DiGO!;Z8wK{|c{7L%xp0fKxWk|1#|Ml;<9-4wu{=0fMe%hSE!e+=cA^ zE7;WmyKzxFZbgRWV3(~PqWkpNBpRq{wwRF5tGCLj75Ma1potM@pn-tY0=L%#@;bU> zhi>YM<566-(B~R1fJoPA58f^KBPdXOOu|>R8xWfMt2cIr?5+PNeJi3I&>l?+U3Y7mvx?$ASqK)mBg4wmb+EID3;082 ze;84I2Z_^tZx_mZR@nY}$IJKWVnaFAiyI{%Vdo-;H5nFm4G_iB?*l@%`RKd24Y^w` z-T;Kohut{cH)W2-D#YiWedbs1aJ~mkT#~qu`BY(ds?k#!m)Mn2%0O_^vw&0uyT&sQ ztiOJ^D;1#1K#d*3eS<&BuXJJhmi2(Z;mLhVj)OCZBzFX#Q~yNiCa24o>#%faaD39V zH~U=Y?D)BM8U`X){BmaFqIQF4Rsw_$KjBql0il39SpVU+vGGMjLp#fu(jri(NfJc< zk6toeLf0b|ziZs1_u-=oI}9`$5DHIS52U7k(&P@EiYweknw-XTt0`mN`H?%TC7(MC z2pxlhCfky2Hm0TM4jf!@`_Dt}m2k!Ah zj}|t<%^IZ6MCA;3#kHoZHx;eb zAf@xaDuNL-6o)3fRPgdM_v_&tLV>s+;wJu0_b68It&p2Co`1Rh59Hsd|Hx4>KKFb7 zp6XwON15@GR={78t8?@me4!fV=sbVrwNeI^J*zFqAa$8E7d+_qluE-Q8tV-T;I$ z73_cuyMmKA&r0dSPSP`bDl2~q7cl7We+qYtmvM_r33%m;h2hP6FQfWV$#IjWvt@*N zWIDTb3i5q9T}1n-Tg;y}Z`Ef9$%iqp1G+MuHT(>`>%PE}Ka+YIj?EO9m6u#TJFUW% zSYT3V1IOt5BHIfL`P_@FI_#J5%q)S~_Rij|hXdkqbpwy&mHkUjbq4{V z8xruiK8px*r zi4Y~B?&xeb0vK}8%k25jr8f+v=W`NG3C8I43X3`eOw3-7GZ^E{D{K&KQ@c_M_S{0*JWe?8ayHVX77WV}VTyu_?wCnv+$M=1y=_Cw7 zSMMkTznH@oe*qP*0E6PtGcSI=DKxo9Wnj>>!hE;pu;X7y%`3Oc7X^_*!3Zz&l9Vo?UHFWzjb@PO(Q zUuS#HVvZ^?VVr_>bHA?>cyc;0sN#c`bpRn9){HB%#TM#2mgR;eC6+N(^&E6Ks9^kl zZ~Vyp$@5pr(kApg4w}=9bpVF@XSB(4(*_;bUr?j4oQ!`^MbuXE0>w8@-Dvo{Er2$K z*uay8>H$L26XUXB#g_`h-qPgq`brdp>AdjkbFfogvoKfRHuj{JOGmXWcUR zCKMX++F`&FR)npbyk!Xsx`_20Q^0y&gqU3l1V#H*-`$T1&7pFhyc&MryMW~ZBf$>_ z#QYYtH8Gl_$BrLbeqp3t6pTaW`K^E*qfuHEGWjb+;Vy+@{++v$UiyA##fzH6{R&y% zukdZ+24IjMMAoR7QZN5)+78i@ha7fgRqc7kazHLRH3tx7sYkHvOHypZivN-k+VBTI z%2WIk9+n)Z%Vf1iIL+Ck%?|eAC8-&^33T^_DZ;O&CB+|=##S$KnJm^ZmYlTigHJa8 zp~coF9RMdAvZB~d)-6xhN(O6^OwFey;m+JthskNyZ98bMvZz;}W7(?$|J;D_D+aEw zAG{H5^5e;m52*g2cAWm=4s-;d<6x`d&$b`k`poZ&+%@m9otLF14QzIEj&V$Cq;eu* zv}D_D4wo_8>@pdxHd7k3xpY|?T5XKYk!5zMU2VUXVk?r=AB~K{!)YIB z%Q0tLo@XQa$aVE<%j^IftwDU)sCc=7+aDXCdvi77Y99_?a^Or$PNvD0lQY(lo8zL5 zXb#FI@J8@6rkO|Mq$DOjDmE&?n3|fNl%AH>3jZ*(7xox)P>LTkX8K0byNe^IK&TQu zq{u@CBZ2J>o6DAxo1W>!2HJ&}bXX}P*OF#*jkBAbsSbTs4CqL_jySrT6-m-c1%3 zFE_65rI&{}Y~p!m?r!+--kYT&7Lb%T&M4H2k)jJQls97xt64#A7~+MK!Yu$4@xq7E zdk@2n1~`8jqnR{J4i7GdKxQTcdU6@+c=4x60gxW0V0KI(VDu;r!(5*FoMyKpbtKl7*@%#z zYBq|M;xuO4(sHe4qt!gt?C>5w!)i-0x@<-VR_$0j?TL+?4JS0Fm|Zx#H<}#|o5QKt z1nD8i?BGY0T$>!T&1iCt%Sjcd{EdyO+IDL$vf3CE+?vdwb~|mkj#M+ZRiom4PA{7Y zEGK3phEIC1hYumCJdL;)Vfz}(VJs5AbQS8+131MMgY(3(tN8*6wnYpX2!@5OlUCFS82BFlyNTMgDtf-`JYz{&PDkc zBu-Ph*+>=^(PS^3mF0aS$m(?Z7}7~5-5iW8{RVKdMm zO>>_yI$aJFr0mVsa@{7Sy2(sFkn^uejo7_9a+L-ip1|}q6w+XHccdNl0taa7D-Xdu z?Sz-mMn%%}Gsd!Z!{u;28AGufki1&R*HQiCaFP2USx9;QcMtKr!fNZamPt-+WgBA> z>7!gS6sqtHGg-rI%2t-1)0k?r+L)=2YzQmXMP+&M4r3A@zm|IA0|e!jNxw)<3|`Cu z@*WG4lZApk!4+`NI~+5CN4-!j3KKmQ?K~uN&y5vo*5Tc0RBtP9$kp*+e@zMtD;Cm$ zQLIg_%F)_BG%bMap>P)c6cRPhL*%*Q1=B2eCweC%0(+%K?$~@9%ua_nH5X2bNfPeL zq&t#9?`cv^qBT5{2YU!PTw&q?`=v*y=9)J$JBwvb&ZSrnjG4fsTT+9@rLr!NOQ&KM zRZeb9HG)@~=SiJsU2-9>7MRnm9FG>oNk*Ejb|hw#-6E26i84U}b5<1TsDAZAiKXJg zVm6x-wiH=Ds(Mi?kYbRtwXmKIDYEzOlmiuIE30lDrdWjc~sO&z+x^h!_ z8A`lsds>7`wJA2KoMU1Mj*8$wQ{GDP6#Z;+U)iAV!1?;35o@4*3GTj3hoO9RYf6_C zvE=k<3_LTY5tozzRUh!_Zu_sMKPNXk1;-L7JL?WBJ~fH}0)duY@eXf`6({7|6oh`G z-9{zqNb^`;5AwwKR0&i0!R1-eFHF_qDdDTH2C<^RA`<_HOd5GP$?hAXF=#N>xj^wd7$X zLMx2;6(_GmdCeh87MCdn8zxZ*S<=VxVk*%;9HRIKvVGqvwNb;rtc}#2%46b=6nw=C z;-T2WJf_}h0;In3B&()xzH0?g$>zL?k^qd!-sWsurp0NrTAbY4!CITbj#rE28{|d} z#APTT;srSwn*ictwWLJye}|kGs5QuF@j&BGlrJxIl(%m0)JZ;9b$i=Ba<%f?rwov5 vm)|~WsQgDcQIK6plk-`(;j+G4hrd311!p)c-%gi4n5EraL?W}B<;DL811}Gm delta 28092 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 + + const [inputText, setInputText] = useState( + "Life is like a box of chocolates. You never know what you're gonna get." + ); + const [selectedSpeaker, setSelectedSpeaker] = useState("af_heart"); + + const [voices, setVoices] = useState([]); + const [status, setStatus] = useState<"ready" | "running" | null>(null); + const [error, setError] = useState(null); + const [loadingMessage, setLoadingMessage] = useState("Loading..."); + + const [results, setResults] = useState<{ text: string; src: string }[]>([]); + + // We use the `useEffect` hook to setup the worker as soon as the `App` component is mounted. + useEffect(() => { + // Create the worker if it does not yet exist. + console.log("Initializing worker..."); + worker.current ??= new Worker("/workers/kokoro-worker.js", { + type: "module", + }); + + console.log("Worker initialized"); + + // Create a callback function for messages from the worker thread. + const onMessageReceived = (e: any) => { + switch (e.data.status) { + case "device": + setLoadingMessage(`Loading model (device="${e.data.device}")`); + break; + case "ready": + setStatus("ready"); + setVoices(e.data.voices); + break; + case "error": + setError(e.data.data); + break; + case "complete": + const { audio, text } = e.data; + // Generation complete: re-enable the "Generate" button + setResults((prev) => [{ text, src: audio }, ...prev]); + setStatus("ready"); + break; + } + }; + + console.log("onmessagereceived"); + + const onErrorReceived = (e: any) => { + console.error("Worker error:", e); + setError(e.message); + }; + + console.log("Attaching event listeners to worker"); + + // Attach the callback function as an event listener. + worker.current.addEventListener("message", onMessageReceived); + worker.current.addEventListener("error", onErrorReceived); + + console.log(worker.current); + // Define a cleanup function for when the component is unmounted. + return () => { + worker.current!.removeEventListener("message", onMessageReceived); + worker.current!.removeEventListener("error", onErrorReceived); + }; + }, []); + + const handleSubmit = (e: any) => { + e.preventDefault(); + setStatus("running"); + + worker.current!.postMessage({ + type: "generate", + text: inputText.trim(), + voice: selectedSpeaker, + }); + }; + + return ( +
+
+
+ +
+ + + + + Settings + + + + + + + +
+ {/*
+
+