From d638b4b605e7087a8bd824dd1a91fefaecc6c5aa Mon Sep 17 00:00:00 2001
From: "dana_maria.caruntu" <dana_maria.caruntu@stud.acs.upb.ro>
Date: Wed, 4 Dec 2024 00:14:05 +0200
Subject: [PATCH]  format code and add comments + coding style done

---
 src/consumer.c    |  68 +++++++++++++++++---------------
 src/consumer.h    |  13 +++----
 src/firewall      | Bin 49696 -> 0 bytes
 src/ring_buffer.c |  97 ++++++++++++++++++++++++++++++----------------
 src/ring_buffer.h |  12 +++---
 src/serial        | Bin 48384 -> 0 bytes
 6 files changed, 112 insertions(+), 78 deletions(-)
 delete mode 100755 src/firewall
 delete mode 100755 src/serial

diff --git a/src/consumer.c b/src/consumer.c
index d0363e3..634ec56 100644
--- a/src/consumer.c
+++ b/src/consumer.c
@@ -9,21 +9,17 @@
 #include "packet.h"
 #include "utils.h"
 
-_Atomic unsigned long global_seq_num;
-_Atomic unsigned long write_seq_num;
+// _Atomic type variables to avoid race conditions for multiple threads
+_Atomic unsigned long global_seq_num; // assign a number to each packet processed by any consumer
+_Atomic unsigned long write_seq_num; // assign a number to each packet written to the log file
 
-pthread_mutex_t write_mutex;
-pthread_cond_t write_condition;
-pthread_mutex_t global_seq_num_mutex;
-
-void initialize_thread_resources(void)
-{
-	pthread_mutex_init(&write_mutex, NULL);
-	pthread_cond_init(&write_condition, NULL);
-}
+//mutex and condition variables for thread synchronization
+pthread_mutex_t write_mutex; // protects acces to shared resources during write
+pthread_cond_t write_condition; // used to signal between threads
 
 void cleanup_thread_resources(void)
 {
+	// destroy mutex and condition variables
 	pthread_mutex_destroy(&write_mutex);
 	pthread_cond_destroy(&write_condition);
 }
@@ -31,33 +27,43 @@ void cleanup_thread_resources(void)
 
 void write_to_file(int file_descriptor, unsigned long packet_sequence, char log_entry[], int length)
 {
-	pthread_mutex_lock(&write_mutex);
+	pthread_mutex_lock(&write_mutex); // ensures only one thread writes at a time
+	// wait until it's the thread's turn to write
 	while (packet_sequence != write_seq_num)
 		pthread_cond_wait(&write_condition, &write_mutex);
+
+	// write to log_entry file and increment sequence
 	write(file_descriptor, log_entry, length);
+	// using atomic_fetch-add to make sure incrementing isn't interrupted by other threads
 	atomic_fetch_add(&write_seq_num, 1);
+
+	// signal the waiting threads
 	pthread_cond_broadcast(&write_condition);
 	pthread_mutex_unlock(&write_mutex);
 }
 
-void consumer_thread(so_consumer_ctx_t *ctx)
+void *consumer_thread(void *arg)
 {
-	char packet_buffer[256];
-	char log_entry[256];
+	so_consumer_ctx_t *ctx = (so_consumer_ctx_t *)arg; // for coding style purposes
+	char packet_buffer[256]; // buffer for storing recieved packet data
+	char log_entry[256]; // buffer for storing log entry
 	unsigned long packet_sequence;
 	int file_descriptor = ctx->log_file;
 
 	while (true) {
-		pthread_mutex_lock(&write_mutex);
+		// dequeue packet from ring buffer
+		pthread_mutex_lock(&write_mutex); // get exclusive access for a thread
 		ssize_t received_size = ring_buffer_dequeue(ctx->producer_rb, packet_buffer, 256);
 
 		if (received_size <= 0 && ctx->producer_rb->stop) {
-			pthread_mutex_unlock(&write_mutex);
+			pthread_mutex_unlock(&write_mutex); // release mutex before exiting
 			break;
 		}
-		packet_sequence = atomic_fetch_add(&global_seq_num, 1);
+		// increment the global sequence number and release the mutex
+		packet_sequence = atomic_fetch_add(&global_seq_num, 1); // makes sure incrementing isn't interrupted by other threads
 		pthread_mutex_unlock(&write_mutex);
 
+		// process packet and write to log file
 		struct so_packet_t *packet = (struct so_packet_t *)packet_buffer;
 		int action_result = process_packet(packet);
 		unsigned long hash_value = packet_hash(packet);
@@ -68,13 +74,14 @@ void consumer_thread(so_consumer_ctx_t *ctx)
 		write_to_file(file_descriptor, packet_sequence, log_entry, length);
 	}
 	cleanup_thread_resources();
+	return NULL;
 }
 
-
-void *consumer_thread_wrapper(void *arg)
+void initialize_consumer_context(so_consumer_ctx_t *ctx, int file_descriptor, struct so_ring_buffer_t *rb)
 {
-	consumer_thread((so_consumer_ctx_t *)arg);
-	return NULL;
+	ctx->producer_rb = rb;
+	ctx->log_file = file_descriptor;
+	ctx->log_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
 }
 
 
@@ -84,21 +91,20 @@ int create_consumers(pthread_t *tids,
 					const char *out_filename)
 {
 	int file_descriptor = open(out_filename, O_RDWR | O_CREAT | O_APPEND, 0666);
-	
+
 	DIE(file_descriptor < 0, "Error opening output file");
 
 	for (int i = 0; i < num_consumers; i++) {
-		so_consumer_ctx_t *ctx = malloc(sizeof(so_consumer_ctx_t));
-		if(!ctx){
+		so_consumer_ctx_t *ctx = malloc(sizeof(so_consumer_ctx_t));// allocate memory for consumer context
+
+		if (!ctx)
 			DIE(1, "malloc failed");
-		}
 
-		ctx->producer_rb = rb;
-		ctx->log_file = file_descriptor;
-		ctx->log_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
+		initialize_consumer_context(ctx, file_descriptor, rb);
 
-		pthread_create(&tids[i], NULL, consumer_thread_wrapper, ctx);
+		// create consumer threads
+		pthread_create(&tids[i], NULL, consumer_thread, ctx);
 	}
 
 	return num_consumers;
-}
\ No newline at end of file
+}
diff --git a/src/consumer.h b/src/consumer.h
index 5654068..f11eadb 100644
--- a/src/consumer.h
+++ b/src/consumer.h
@@ -3,19 +3,18 @@
 #ifndef __SO_CONSUMER_H__
 #define __SO_CONSUMER_H__
 
-#include "ring_buffer.h"
-#include "packet.h"	
 #include <stdio.h>
+#include "ring_buffer.h"
+#include "packet.h"
 
 typedef struct so_consumer_ctx_t {
 	struct so_ring_buffer_t *producer_rb;
 
     /* TODO: add synchronization primitives for timestamp ordering */
-	pthread_mutex_t log_mutex;
-	int log_file;
-    pthread_cond_t seq_cond;
-    unsigned long next_seq_to_log;
-	
+	pthread_mutex_t log_mutex; // mutex for synchronization writing to the log file
+	int log_file; // file descriptor for the log file
+    pthread_cond_t seq_cond; // condition variable for signaling when the sequence number is reached(maintaing log orde)
+    unsigned long next_seq_to_log;// next sequence number to be written to the log file
 } so_consumer_ctx_t;
 
 int create_consumers(pthread_t *tids,
diff --git a/src/firewall b/src/firewall
deleted file mode 100755
index 3837e4800c35b40ee0a28c121b57ddd6a796c79c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 49696
zcmeHwd3+qjm4Eg0^c<QQ&FHW#`5Yg@a%>$wu>oTlTV`y00d`_@jbv$bfUZa*AArFi
z98iQ<E4w7lhH(9IcoVZB31kTb5T~6iAtt{Z&O-8Yb}=glvum7?coRUs?|W6%)6<fY
z-F$w(|7d^IRqxfi>eZ{GtEStxR<B><F$|$EQ(P<viWf>ul`44f36()oC6<Z^?&paT
z;REbtoGh=B2}<R4+>@OK6y8Kid_|NQC7mqMLZ{k7N{Mf*>rk#N(W!_@nD{KpD%hQV
zd4{CZsV=wmRmpO@VhY}pBk?+Q@{w<zSTD<;xW<*LddIXwlwIU5;ybSRjw?Q$o>7j_
zsb(ji(BD!e*PT|Pj4qwJ`I;1;J6$c=gic8ZU00q=*Z(#8HY>haN}xMkt?H*!t?zR1
zkzfA1mu}`Ol)karA))H6Q>9*1v^4KnvZ$h^zO1FWt$TOb?xjo0mMkjoYA;{FCXiim
z{83C@x^b&OyA2Xfi4&fE64vsljJgz+6aBu||LygnuFrk9x%D?220pdqmopYrT}(7&
zH}Mb+T|`eYp)bnM!XMGFKaAU`$V0di{JoZXwRPFqKHY7oEbICip!_V11eTA1zk3Y)
zg)m?=IX?nEE=6YDpB+O^-5B`wW619w1HW?&Ie{_g?;nGnd^lRYzBC5@Q)9^g!x;2$
zgFcQj_eI0&XnKprkZ+EGuNwn@=@{~9co|La>to>mbqxIQ7<ia7s{D7y!2f;>{B>j0
z>yN<4!Q;M~ff%h`3&xN$Z4CU!#*i}}_!(}cfb$?HPfQg1YGk1vXGKT4sWVkupR8+d
zt54Ray3(EPdqgr>x4Smk(A-wr(tKk|5P?nD+MQ1APPVky-5_wQZAmw`rd);HZCu=1
z+k#Z=>TFJDD6VgBZgY`mv|@0pOLnDeJJZS5TF^Cgbf@cVYBsT}xe-<g*qLr`$u8Q_
z*<M>;SKE~q4V|f!XlQ8Z?rO@Apcb&By(85ob~bc$Hn*i4NK6A)psUTs)TcT-MQf_H
zu49kQEGymI)|@655VUu~Nl4q;$rZKf=Jrgj*v?(GpiS+@Ez83!B1v_uyCGTEbVIVC
zwz);XjpQk+J`Lqd#HH)kUa~5=pnU!!JDbTZ#8|Hh7G}^3$`^~|+ASN<ik+#(=B{+A
zbIXQRE$wZoEwwvZQn0tNwY^QbHz`R+C8UwvgAv|?(cFu>7qbar=pVs^_h6LQkffC*
zR7RZop8?)}#Gan_{%+v2m>zuMa|&13+#I3V>R|<U7B>fJ#c)``k1@R|o=|Z2L@M`)
z7XZ_x*DrQFkCXU8wLa1KS1Kg_s0%-+)|1Cvc&}QJ1ZpIomZRY+7k<GiNtbZpmn!^b
z7ye>}-{!)vQurDdKB4eUF8oG?Kb{nP(cEjwEZ<K!@Vw4cWkU{po`e3313%4yKj*;H
zoUX5ZH8MxCX^zs@iR)y}k3=;UBZeG!=lbD{1Mk&Bke+kkd0nB)lszP${`3`a;B}i(
zS<Hb)0NGcO1Fx3MTo!lWLpHS#r4D@9fv<Gn5zzLv)PYxz09;n(z(;LrArcO}?lV-p
z*@1V?AKM)G0*9O$2VR9Zmo_=@s;e-*!-1zcL|?ld_z4<`be{uX<iOwMz!y942ORi`
z4*Wp}ev$+KpaVbIfj{KHPjTQMb>OEu@J~4KaR+|TfuHWcA9diJ^XM@Lex`%|qwN15
z5BxSd^^b|3(}6^v^@~mD7W)U&p5bGOo)-fzu)^WRU)w0e+2N9}BZ*EEMBhXuXHWfl
zczE~#!!+=mJ@uLm(|~jK)N?jW1LfIM-?U*Gc+Q@B$cAZ9J9}!thG_sgd+IhDrh(_|
zsZZK44LD~{)!Hx(G-pp;Zo@RdoISPDhG}3qduqN7(|~gJ)N~uBf#mF|JR7C~<m@TK
zhH2n9d+OZ}b$w~TK>cl)26oinhH2nH{cV^A4AkF-X`n#;ZI}iK)Zd0_U_kwCm<9yY
z--c-*K>cl)1_0FGhN<JD{x(b<9`(0j>gcGy4O0h4{cV^!HtMfowEhn_Q0uQ2-2Q;S
zjO__0{6!ahuM6&X!TVkCUKiZ$f?Hj1$^~ERg15Th4KBFa1uu8Oi(PP;3odcNQ(W*k
z7aVcHmJ9yivTT38=YrpH!6#ktFJ16YUGNWG@JlZEX&3ys6Q2Lh+TPc$OZ5J0qUX&s
zo3~WYADsXFME~;tgRmMN_qU+@T|;?v+8qcQ3?Ti>i&3{kzm-qPvUBNi7+Q9Mh=!Kn
z@QLWOeMI+yN<n{$3i}uTD<yM2O!S^fJog_f63?A86UNJl*FH=aLO`_=5Ewquz;UPf
zY5du@oXi*9bGIgXmd~JUqW5GvoakGA9)O``9}Eu<)uS`NY~2gkxE8#&e&Rp13x$-~
z3cf_|-l0Tq_lZPb^-$u%>JvN1BX=UvTYZKxb2)$R?HEIZJyLy+Dg+o5ThCqlf<w|d
zVDYy(F4II&qW4&0&e1FysjYYGac~cT?nJ^k26dA4!s_Fl7@Mn)C+0|ugSF>$6^uO&
zV?n?5C{syQ5S55YRgeUsEcj@m_h*UTBSZP9E!U@aE0k=ddVxV|>8pw*jOT!X$d?nn
zKN@=feGpS6(0bFUeu=&f#BofLff3GrmBjuSln1__sr{cfFEFNgT^M%8HZNeC$4ajq
zp)~GjKs4Ktp&O|Nz0bpDcv?0aY~DZEy>4jJpN5C~1Zds@&D!4Q*7sY#E2Utxd~+y>
zo_lg7wQRrjAz^!8ewHRG+NlvkKgF2+EX{jEpC<Vvyl*S?aZ?W^j#TktjqyjSXuhHV
zAv`ZODSu?&F+$_wlAgiRXBdDvjS$&e{eI8h_eFZ$&_Dc9Sy^RUd9$>#hRu5JN%S<b
za@z<iD{L#@L{*iZ&9<HuKxXu;)OwBsExoZs>Nz)?s{h=Ro28yJ3_87W1T&iS#?7{#
zp?$WVpF?s+&oBN<)u+SO^C3y>w+<*hTcn=5M(9b}dJ4hIEs+&*m3HG(f9lzLLUgYm
zYS#LMt?xThUtH<CTIwrO`e=C~TlqgRb0>}rqQeZIx(cfr-BKLynMy_PI1UzWuBxFw
zo>SEu0D*MlHB#L-&y#N4A=Ui@gD*duQMb>bjy4KeUH|4%sdi|e>cB^#LA!H@)1+Hb
zQ)NY3TM@FYc$f6`TXU5a*GnsAj<Dj7Sia~=r?eG_%30L3%c_s>%qN|F9KQPpqj!9q
z#uEo7J=tl~+b~2+o50d&q}y<UY2?W9F%nF@LylfZF$(o<z{tjZ{1|G$Ls;)6s{3v(
z0{QWTp*l5#Ly4Zj&D1VA4)3f{-e~xPYLgF8DBC0?y)gw3(-hh_OK*&0(Ag%ZvAA>A
zXVNI*{aXC}w)odbP`~xeEGd4U6#pFto#OkY_~U;$j355Js>3o{$$yf#ervl@a;H>s
z`3NPYq(p^rtt*T}nfhdf@j|Wc2dJEM*}YQTZ}413F1tsn`&R~?b^0#GIIZri4j?;>
zsg-yhGN579Fn$6Bs^K1aPgQ!gZN+D#74^!B&q^z<8DYgjhZQZ_ioU9%(L(qtcL>jx
z@d#>66ce-BAI9<EaB7Tb{u3N3xz$|IR~2wXvxkc@A@^PaGzC4B%tbW!x}ur7`;noG
z-~jC;9nA-Sr<_s&TV&IGnX2D!ZJHsQ=Bv^vmon&VnyGk{an@$TDB_oC@yAdo#hX(6
zndwse*QNL&2A$%c#gh}nXGe3K2j!l<LxR?1RAV*$9{a7TN29ICl8WwBioPus-KrF2
zrr(c4k(_Ws;MG#$uWKOFS;6lC*8W>Jbe-1t9_lEo_A>dX-x{YhJ}EUuMreE!4~bIa
z=fSH~@PM-&a7M+S&Z<g%##XUUs`yr1dXJ_>X#5(3&RO&}Tg4Jvg^YsVXVv1MR#9QA
zsFo@=DHYF46_<`sG1XS_zacVvxt3`sER7av9sdkE>8YU9@%A)XjiXY>zcJ{n#*<;~
zsdn%>8{>hjYP|NY@>G+pVj&saZ{4L-{7|acH$ufHY!zXpLawF^VxSOHbHOc8k!hM5
zt?&=1oUBud+PUAFpcMXZsSwWx7~!0CdMl*s^ab!r6|!k2WvTe!jH=V$*(yFJRXjG8
zWIp%g&!vjP3_4Zx*eaIVDh5kw3^<gf;_tPJ`L>FBvbW#5T&Z|ns#rThMch{LQ;2l7
z{%xl#;k!id)5m%B{rE8?^@%=j2^N4rSD%|dnCRP2*k^zM=7?M%wUTN3-vqwrX}XJO
z?{g?0dhb7#AMOT$boJUe8!2P*xhJvIA)8kaHp|sFVfRLMv`X+MZhLx&<ia{Eh40s5
z7u#ZkQtTPkg0yu4u|p$TaF#9h7jR&r?_Ls{=<h#6N#A~1Z(eU4rV&LJ^l{amB<)y?
zpeeox0}{RanYTw;7Tv#%XAdRf$k0DvnSKBva;`oxS2{3l4b1{$W{#Im?6)q)u{*W!
zPMD-|*DKt^;5guT-0Qbus$}Rt$UtkQ0)OEm>^WW8yZ1Cd!(tWOyJ5)Pkp0%n7fHRj
z(ED~VWIfJ^myvs071fcFKI;w!>CqN{%c@Uw|CqX0-7%Wc`l_LYyfPcKXA(Wu$3bjB
z##fb$;dj{3Z3;XAvJs960hw`3;<nQ@9<uG}LwIU;8{W5{uzgjPz5Bn13^aXkp{z(X
zwTmpK=>@Haa@}s^;rlUFCVKZDCAOZYDG|3`lHt&+*>pLC9#TRp$=;!x5FpuBNAGwK
zQFiKW+~~MWoJmBVv#w;O{l}zTDJ9|^_P~C!2HKBPf>>kd$k0jDw0HktHu4&-{{9mV
zEG-}qbHMaGP1Htr5LQl~BE;K%WTqgK=<BC)gf%nvKTTo1w)gvMvER`99Ed)cOpbc~
z846|Db-#6*y6%hM>g%U_qW@mm7apfN^s$HGxGw`Z^%+PTss)3irFu@sFtKAl0Gk7#
zy8t9CIE$nPBv15qKZXs8Ly6uE4~}Tj>Ia|v4orIH5-&HTG;IRB)?58z&)yfs9z6fP
zt;UinpygO{G1UeG9#`tQC%4H?zm`Ggm|Ee}W67H^{z&y82*s(N;Pz|>ZbR1ri_z^U
z9u<!Y%z77VRX;_6R5d(_RlP+ChVN^^2F<@>(5dQ0EKcOGwTFcEL1-V<IY!yOtuOX&
zu4JU%4bVFQdZ*w>RUD$RZmyysSM*g6CJrY03twVnU-c7-{);>;fSYqCyv@yt;-M#C
zbx-x60iFx1AB)}{$9U9N{TTGq5LC!xIEJ8yev{RHv~_f(`izAwf+N*Kq~`6*pa2We
z>T^e`Pcxzn2yDllu;l9WjC|xe7yXV%M4uUy8&&A|)#r?!>eI$;druF8?Uo<(R1X<g
z@6EsE8^rGz!?3q@r22gmL~7UU?F|$@nTqyXH=U2l7gAM+`oyy5ca?H3rpUt5AK2?4
zGOqywKlj16^T-NNU0D78&0ps*a_Gg7h(J6(GWzf+ipT4I+SGe3(Le4I?3_P?=LR(O
zk)cn*UoWq=PSA?tc;D`&lqC8(;tW<@lx6jMOTg0?CbL0PRhj7DdSYeof33x4X8+>%
zus;uhGPe6pQFPEVFi~PhP;<zK-FZ-&LB0Ge9c2tnU>+qImi-gp>>&xw`}|N=^Y)ys
zL6r}UtnwjM<ws?en_%2CRjSIjKrpKOC{_88tTM>C%7^+~RrX}63>vQTqjr@&&MF^-
zW!xDcR8?7W$SN<BwNofn<yp)_^pK1yzX*6lm4Ec_Syk?{zC$))rxIQr_cgZ9`T`|b
zV9-E4{A1^Y+GpMAAiqhHw<vN@XOs8teZQ~z{j5e8i>cAQ9!H?jfY{r82JS;@&1RYC
zLA_QXvJT}^TCWvxq0ik_{eJX2)$iYB{Q<%q3~0-vkUZGC^?OIE-yrKw-H%&e^&2!9
zW0W_zJ3e>9q^{a;eNWj&&#&oGsW2;y`z%vosOt6RjY+ge5)J-YqH93ZSN%Q6;V^%@
zpr`r`i~(;<i{3-aqbKk;?C_JCJbJr-*SGa|(p$9nxR~Z4w6+h_S@TF7^&g@o&B%Bj
zLWq=7HD^3aZW+4jEs_DJ_mks~3|)1SqYvDdltL58d7rj&L^Rz7LWfehB<_9sG!M0p
zpFq+p7mdCBv|3!>yT1cwuJ7&NjpUBObUZqzdS7(Th6B+#TOW+hx%ScMoYY`+PV2Gg
zobD6RIeX7IY~P;%57yL2_6ualZe#<QY%G&4%4BI^SG1*>Y-J|9RA=>qc0X}r$wAg9
zdiV3pz^m8Z{Y2ZhpK8~;|03jv9>cmd`W@?*h1kkGW1vEHeO4=gWlVJQR`jWj3t(tJ
z+pIQmwt-((A`Z)r?Ds-aB~_=tItGPQB`|EJq<25n%4R<@bS*aaj_m&(Bv7SJ9m1`T
z!4V<dzd45JI7ZrWIMOp1fUt8^r9MuuU#N_%Q5cMI0b3LAHhlx3^*=LI%1-n_wW{%v
z;UD*~fkw~MWcIXM%f>L6``}Wt7vlqhGrE5U>OQm&JDrF-Zhhy|f$!h4La*m^yqCt2
z6L(>SEl;1$?b~}=q;mnG;K<O{H?eT1-4urI1iRyDPCrQuE`oj#7l9b=`zC|b&Hk2~
z<H%4ond9h{{Z_wX+5fNECAXc9VF2xY`h9YG@8h&kbVM^h9v<OXqn7MpGV|62sHt31
z#_%MOkFZGeM?!e;lN-BoKD-H<<hp4kY5`YMj6NfVOg4QcI&<&-Fi<^D)1B6XpZ~R5
z4_1OfF4E5AlWdE3uCYkNSVZ7i!e%{NPD6-GWj}#hZC=kH<_qy8O|{Z>@Y(O6L<Vfn
z)7%+v3Cc|TmU2|4x&pC!uZ-u&LDoahj<QOJz$>-1K}(+u`-9H}$SR25gW^Q5?3q1J
zbN9y5^Mw<tR#$;X)~ZX^Y8H!s?#UIhR+C56YAu>k>idvHE2sAi!t3Y+_j0FyoNeus
zT4BUC+O*nVNP%F}2V|@hz3Sa>;IS$*F1<a!Pj=|cdQAyLr|ir4?k-r-!<2?(xR70N
zGtL!l{g3@0^|*lHIBS*qClq}D1^%4@|1QP;B?@Z)(e;rBKJvgv9{9)uA9>&-4}9c-
zk38^^2R`z^M;`dd1Any#=nXTvHl$kHJNLx-{WyNhE>17ZrRqgV*9GyCE`ith8k0M^
z8yZrb<#l2Wm&McVaeB|LncrTF^SgW6kWnex+SAEYYe#xdoL=1nBVOiH*O>GT-7PH+
z^0jR{p{+h%Uz@Itci<gIynW{|hu(+GG9)9HUKEVCx5dc_mr&S{p_4B@GMU@f43T{E
z(xE9+<kaI9FovFy=7^Q)G%>^L<Yo2dX1um7-rbgQd3~IkB`%xAQ3XxzXpxM4x^VQy
z7@cmUf!X$TrQ19HyT;jXkNyQ0XVbYX;I~UvXm)hA*LT-(Tz24X&r~{|?(A;EyP}BR
z%`30GQmnpW(`LkRyrgpel9t`^l9uiqQBALw#z_o$u)RBtH(=uph<F|Fh|sR?R+cK?
zuhku5%M~kERg2Ztmu$UMtlhX~lla8SD>jPiE3Vjdg;=w4%gXhlBymB>h6_rrWSwP;
zp}6aUlKKncqGWqnNo!e2ecYxHTf1r-Qy_?6)Z7LW%E*L^;}=PTG}PAJTBhykx?q0U
z!UY%SID2H0-*#2*XlU+C?Lt3BH^r638o#=v{#pcWS315Ug{~V<H&KEvgiaN|ngm~)
zqh6AY>(^=1!kA=UScUCB{EAh)|Ifq2Y2@Gk;qdT%NW-rV4?jlmkA{b@L3;Ao@bD{0
zD_$EOK8^HBq+tv(_aL2zwCu;&GDrF_(iWr-{A76eZln!AA09r8bkV<nAL$#fgCFU?
z{1W^)FkFXip?OI6B3+O4D@a?A)?wT1Zln?HnjJ=3iS!kuKg8bPX{0N$_Zi07@^_KW
zLwXpS{OgfEfQ`i#q^}~q8|eo~4<ns{Bc)f6UWW8E(j7>{INH4#={%(ChQN<>H_{fQ
z?;yP!X%o(14<kK<^cAEhke){RN2Fn#LKjkF;4*H!LKwSa#-y-6Z~*=xJdUl!LHO}J
zB3SLG^GE*11NLIYz8_%I6Mhi6u{F6x>!P7ufqi1d#0x&QaMlc>BmQgfx9yeTVP+&G
zF2bkrw;6c-tq{VKuDkJ<hxS@Wi0a(fr#!17KF>;6B+Cy2eId$cIm@r+V&;DZ_!TI>
z&{^J@DL)PTRVaVJS?>9)EkBHU{{rRRS>-Ku`8<@DBaS{mYTIZ2&L9G^e?9Oa#Lp4(
zi?-i<#-qzyQ2s5%)vH<MFWKdHqr3+3b|_2!1GfCbzz-cC9{w<^{5`w;72sb+oOWcD
zH`?W=fgk_I@G#C!GWK21)nog^uxk#=@s2^Jye3mV59JF`{<O2)^B5Cw{ZalSlz%Nt
z|3kL^7L;%Q)$s64C;wF$`FErI8kB!Ai~sLz{=+E$1^O4okL_R24YvMQP+o?9w>zu6
z-7Y_k^8G0PZC3ej?D8=B<u>dQk5xVo<#W-GvB#d#-;l9?J<2cmGvzHPUyJe*C;v4W
z{<~4W5#?j~|1iowf$|AX{*4*_R}??JW@r27@=W<@lqbOds<Yhl5))ASg)y%D9_8iE
z@>GU@9?HEKzsBkx>ruWP<u}34wtlnIj_($fKZbFx$|-+WM*iI>{|U;MI?HAAaeN*|
z`Dv7oRliqI{uavjWa;l<{Uq|E>mv{RfA_#RsX>2lVvr_0T>5(wG_=u0-^8FREED?!
z8TcJEUk4Y+lwP5wOMmAAzwhEp&#BxOfYINzpngo3E`RUC;dX)_Mc=0jQ$Jr#ewktk
zz}InAPKS+j6;dC<g<t0KRisi?Jq2aHHF5MhiBfE0NM%&@?Qb;j*agx-C0LmuN|j<d
zjHK(J@(;a2O_$a`Rf0m(;fRsz2XaQ?0GQ#Uig7qo&YWiye6uRYn@LQs>#4;5KTGuY
z(cA(nRRhWQ?yw$GaE(ekRJu>42UPl?N*`6}ph}Oa^n^;!s1zUl;VY)nxJoNkTBXv>
zDy>mzhf4RU^ngkqROzEC9aQNtm7Y-P8I|gf9mQ}u{MTH88k-A0tsZ`Nn!1492bh1M
zVN*CV`g<(;`z!i;EBgB?`g<xHS4pNzSFO4rUb=NhcU!tUK7W4sqVmeJ`P~f8zh%LK
z^2$YX6k5y!hm39+ghACO-n09%!wzI6{rLzuN&n$=S<cI}Y*L0K{n}hj-!@Yc^<a7%
z?UMAL$4DXNze~?UxK7Jt#9h)K!AK(Me_1L?zM;ng7l)+xVAUe&@2-#pAvI*U$i+g`
z)Di|07rl$pDfmq!U!!@-`ge3)&ubGd0EI8$|0X<J?6vUl2grIIWk`NTi4mZmAp1Q2
zO6c`@{of(T@Lk79>k!x{2CO$hX+A$G0my$hNi=*Z5ad$cdJBc#mV%p*F9=wZ&7;T|
z|Ak^}YJNTP!uTpgThkcuikyH|d<s}^D{j`LQqKPeWLR<QOGFNHX-R4g(``D7i&9l%
zzJ;+_pfm0yqQx^QFAQ20`<5^e5dQapvgkb$-}xrxqw64~)IUD(bz*!1cKD0@D^Vbf
z2XXTk$H+pjQR4+LkxK%`79yL>C1HcUaOaP6NzAyH$YumP!Bc2VCSWE5<Bewsm{m9j
z)I}ot1!%4GT^FF?-na)vzMA4QU=qfC<mFlh0>%p{_U(ufRm`C9^3^d=WYD<mt7jA9
z#y!N7VqliBnxr)_S*ZxugKiesBh=1@$ngf^)d0P7z!I1d;QYhj2+WkV4pWP5)eNSv
z3Xl)XGD$`*;UQtpok*pGxef{Qqy+0)5?y9C5C>7_lm=G4L>x3U1*#`6h6^P3ngHWj
z|D|CH9>My53TifZwy<^)Q^Gt*f+_=-<wCd=v|$o8nH01!z<3t4Y1$@R&{R;fpbBCA
zip<(<{u+W<$pyM>n((hcev<!h!Iu*c&TIh0a)Tv-k5QiF2G5fQTJ(j#;B2!R1<_Tw
z9nT5HK16C15PLX4!6%Gwf+{Bxq$Pd82$J!+48#gs@Ex=$;fo6EYCA-XvT@@rsL09B
zr<#`<9T1mOkVn>UHt6Xpr;vet1}*V(#s$d2M-49l<9#b3;Fz$;mYfM@Cz4#U$7gsx
zi)6CjOEC~B@vVi5(6c~^(1qYMLf7N&3H=lpGxQGb-q1hdZi#}JkrQkMwebO9BgBRa
zV<}<6vP!~w02MSMCJ7CY!$T==m@GK}gokdzPxi+s8+a3%Lf1-yZ`uTb{e;dpneQl}
z=_dT-gcxO~d=a<sTu<aA74AWq2z(9MP^}d8KA~Ax;7OPhS|vplV6i1d1<oVtR!Ln!
zXzHMzAL1qg^w=MoC|TBISnfetXq#l&VY4(MC;Wd)mJu@WE24@>=DRerhjPMCuhdSZ
zo)zx!L>{C<a*UYP4YiTQzUMW@Qw0Zc8Rz06@FK`^|Cf<VG4u;fCZ-d2v?Ov87&!t}
z0ui3<$t9N<m_9rdL}Eq*Zn<+AJDspp?4dZ9<>Stw#xIFDu()_P1F3P}RiHIzf$XI@
zl=Td33*L+L2OL?RffnJXcp5hwHF|WLS_tx933DIR+>g$4a{rUfop&R+?+6|Q^{3S`
zns;KD`>f`^qe5|;)Q|4CkZm8>Y|bU-1l7+okYKy|GLi%E=r)%8f?BBZ9uP}j?^m_j
zmL+*xmgH?&l9L(9dm(wbMeX+Tc-(OD?h{huzJprw@=|4UKK10~i=~yD*~+!HtnuSe
zg~gXEG5iqEV&2zc7B7@y5?uAgD`eHHxay17lTdTuiCcqBFzI~me$+yLfY7B8>ZP86
z8ZrJ`pql$FwIbq;Hr7!SP)?XT->GBnDvpW)sblWuEFEQ8I?8Pw6E;KH3?kj7^jwHM
zUB-Rig`WJ5_AW8wJn4jOrU%QB84Dz|nH@A^rGyf}E`-u7rKU+tpbkHU%C1y`XR%lk
zJftfyWeH_H15Lu813PAZAN4n)VRC?8-thh<o5QY)PSd84=c4nJDeSpCyH+9>y^5Ai
zt6)SvFPr`j-Gnapg7H?UbS|4rxok4!(x^bLp8QvX)0E4f!Y!QV1(YdQPAH+3lj-4=
zlPQ;4<Lm|0&0z2oms~WxQLrER@w8}q85zB3YDC^%G!ftxK`fg7opNf?#Cf%7dYH&z
ztaH&s;&Sw&X$C5+7fqD67fl3U(ey{4^rDIKIeO9b55%YzO$ij(izYToFPf;tUNljO
zy=bBmd(lKa!(KEIU@w|xLrsy$(Tk>hI8ZN|{sVLf6SNE#O$6ABCZe(zO$6ABCNjZZ
zG!bAgnux4aga|hS*??R$1+jqH1W+$v7Q!68fML8^z)<6f5Vc-XGiMesBrk{s3@v2z
z0*2hD7ch)h3z$Qok%B14R#cz?c|ESzF*l%ub^Ws@nI?i*ywGN=Uc5X-d9`?9<MiT%
zcyjdO<qqmeYVk5aRTz8m63#4M!Xp<iRBL<j@(lp?;)MWv@j@2bix-N3%;M!7icGm~
znc(+wsFe7AK#j}m79X!$e7tV)@w&yw>lU9}w?t@u%b5~<0}LLz2|v{>cM;|oZ<i7K
zEHEAn1s+oB>7g5q2_j0<NY2C{mCvAZ7LX|~qPaYTxqPu^77?1u!;5{N&=?P`fuvx{
z#YFClNFtca$)#<YOcVp6x%@_8{A5S;$H?VA&Wp=05Sc9~CMLcFgc0_+2O{G>3xn3A
z&K)Q$A!E&fqkAW>1kMOACVq2ZaPO29_EwBsKarXPC-&xb-6*0tR7Z2*_};vRdOR<Y
z0p`F@_KK+#wH#=8vR@BI8WG7YQ+Y&u6pp3K{YbnK6hZlb=qFbO<xuFSeiM`fo_`JH
z<w)tjg7R_%^wY*wP!5Cs>ye+P#?PHh&yS$~+mVk4a_>Q6z6l#V&rc$h_bWsr$Jji|
z`{`!V6Rr8$1XALC1h=Aqcd~gJ86G#iQ}f9bIc|EVG2o@PFOGoEqH)tZsg(0HZhGU^
zQ6h)wG;aE-z@#Tm?{t<K<H6Hf7~6mX9z3nZGbt|zPiqMS0pTqnMtb73&NnF^<H6H6
zKJXJ_q`}iy<flr@!P8e9BQw1`c={%Ci5xtAlet6=p1wGj$idS$BS;>UgQssM19I^6
z%__VCYKlaR2T$v|z;aZ92T!Y}xEMup@U&_fkb|eSBSutm@U-d}kb|dH&nC#h(@HTQ
z2T!Yk$uM}5^&7w*rgp$bi9htgdy^&+6!rS!H=@X*r%(Tk0Ox6Z^3RkW2z>=qpVrK#
zFzM;jKg-;XB#-crFz0(nrG&W-3G<``lb$~PWhPZOk0_^m5dTa4OZ~sK*)9lho)uph
zz8xwBD>lK(R-aGvGsIjx^@k*e@X=ELs+CBsJW%_qC)4-Gr4efajAv<=I;35$rOg&5
zJ;eGGW+4fx^k4RAThN9{6a`Yy#sK44(57jB4;pC}<=CtWn&oLv#!o2oSGf5%bA{Rb
z=QZ6lQAmvtt~7>$@;&4S;9G`fFnrr__xQd+LxS&J+=Z_frG{@8@*ZD4Q3{jxYXWZ+
z+>3lr4#xfv8mY(#{!3mtGREJ7I{3>VAz{J<B++=z%q>W{COIX6Z$Ys|HOV<oy2PZ%
z=A7B)Lf~RN^MpdNGXQwz355d>ku08hLXqG<Auk`BL%9sZ#?j0ZiZW0%j^>_Fi~;%R
z9Lmopf6Lh?RFL--0CM&T6*3@apU}7fSt)0q(0CtpyJNy6dqNY;8WgeTB9Yv2sG{$6
zcuV-+AP))i7?McLq-V}p1O>53Ve!X7W%vL@#zohFRv23d7|(#$I1Sp!gcyZ>K$yf7
zDKe*nXU5l%$K&(F;yys*n(8}6WKxKv34@;8B9r}85R(D$1!Oq@{!^I57@1<yGiV;+
zV|1X<k((3y69D7)P?#H<M0sHxz&$sY{Sq)vfG;=76|OXXPGqq{a?(;`8wBL$6_All
z!b?6dNoH<=Nxxt4=7Di0dnH=pTLs|1H5KR6V{drEb_flc57r>TmH#S`5rsTd!#I(D
z0ve-v)Ota4P$TJaI~F4YgQloelrKYjo}#Q$$buVTYxoCYYRT77?)e$rsJ5PybUQ%2
zUK)>bsn{EZ$Xsey?{9FMMKjBP5glbjfS#*kc&;WW2EiT*L{UQXe+={gOhWNceICvK
z(Z#-Mjq$tyLN4Rnc=;@!hxwlZ`x;HgznKw*B@uG5mqZoN{Gb0gSAhCrMi69d0;1qX
zgA2b-g(QrPQd$bukxQpVsr8;C0=fzBSAi{fgNou2iew65SyXT%91xlmq>+IhKs|h;
z`pUX`sZa85N*KE-WMEMMWpoo>YNTAs@{Ug!J3d6Pj0or^ywqU1lnuNMt$`bj80o1e
z0;2TLFJGh{-kHJE8%x+n1Q*k73T|>|CXAgK;`tn*Sv~I}g|Ul7=zk<ME9G6JFm{m$
z{ZfXS>J-L44xxWdXjbqRa>9F*;(?I7j}yi|4pI5>#LB8XloQ_1f{MHN<rWohIS)5n
z{4)up#(htKEb@KS^z!KxT;{-`TO+5Cxgv+?&4Dl7Ist36E2mL^GzSje8d;9ami!mE
z@W8D(-vRB%xlft{kKH=)v{FDz7P=-ii>pFX(xbOdJf}*J$wD!yF1=e^J)Uf!?EzrD
z0`iKVK&!6vQ|;#~j+u(XxbGbhPpIu|6zfX3$?-Hjc@CK7-Z@Ls@J~pPHST*H2ZIwx
z#oRek#lf3$N+G(;PbFAT-jovnSgygnIeDmD1rK)Sz~D_>xk^>J!#9<NAvLEPx)y~f
zCSdYSId6hv`Gl8P-qD+K?m_9rJdK+JkKUBi18_wiMYcI`>?Uk<3Q?uN<2U8}0pKNy
z_%R$U@Dxa*c%&Q_UK%1N-v_Gr50nG=_cL6%X;|S#$ougk@~>y$nh04RKcBRD1~x~i
zYVi%++XfO5(iOi>Qf?DdmY}fsAtiJUIOsC&n?fUdfnFjnlxX0^#}G%fo^FDe7_X=Q
z&5)(;Bco}c$n$&GqSO<~r6hX}QcG%@ig@2RKyymWQ&{{rAmxe3GcHPOaw77KXFyIw
zo(VCc!bGGN<HTEZ6;SzdHu6j?{yv}}%|@O{q0b^OcsBA(_P>gJOyoR>Bt%=E^cN;^
zn3Ci=Jn#XG3K$cjv`{u4LK7QB(v)DTtzH<#(i9Oo39c!iVRrm?74Lv=qDfpqGggB_
zToD?(W=A$7n<{0D*ew(Ivmd0n9XF)K>?M@NW|$X`Hgm$CXQ0K}tvKibgD!8gm>c>G
z7dBzgraG#<njFGLXbAO3sWQ4b(!_?#xUZB33ex3YEOjM3mxDaWuEfTh=Pg*D6Cg5d
zO<9&wO<twT^J^4`mGW)YcvZYYmXc+;VQJYlKt;)`*y5AX(nEgXXrbSa(d9lc^n=1n
z4?Wq(c-|jFf>}Cg16U>v1~9}Rlhc43{qaK{dIoiYBCq%YP@xqdqKpXr2RabtyrC5k
z@-T9N&`RJa7t^PIQv$9-!K~B3sadCpUK6sdgT+Tk=&g`seSQ+>zeo88CsN+?K5pT&
zxT#~qC?Tf(5f&Wx%@6zyoNIg+VtfnzgD5~O5wIjk90B7i1f0)6%;<$w-%<vOj2Nou
zTgE`#xE#`a7cfw2{F;CZ8K^X_BmoyOu+;c50m~VvGP;PYih+djD-ykufz8I}2)KlS
zZAK0OtH&RLoi)aJBw$V9BLJF=0Rj?ib%*hFlD3wCwDAFztP4@U+HL%bfDQRy2e8jr
zK+-lwzXjlSV=<L%3VaLFdW`R)Q~55BJ`dn7!yswfBmV-j1I9Z<cJ+i;P;$_iO#-ed
z{uzJ=jdKKC%jO(177)*M!H2=~s6oTHFPT#g;0fc~R8qsX4H`6x`gR0fhkzG__d^u<
z{lx(TW8i-h+1%XNIHaEcg>ny}bEvt<DivEEdiaX{1~z$UJ3dCATJyYy9235+2@8bx
z7myQJRJ0QO9%|<BA8?!gD(C|Pxs>-lgM2V2|1D5NBdGt3bgNjJ;}1MZ1I!K-<^<Vl
zL<nT%<S^hh%Ah<a#6ZA!gvi1SgpFJxi!cx~;soR}P-yHTvM2*Z#t*0@#=vAFNkAS0
zabpva6^1ErON|=RGcNiptf>@HI`HzC2I@hG!m3cwJglbj=wYQeMD-SV4XtS$Ix$0$
z@g_##&?E-p27YNRLX&feqty5|<c6kjOH~>{s1HqL^-GPvCtw-_7YPq(^!gCzp}0vq
z;@&|jo)M#CIS=j5jN6WzNjKq{kGr>t2xi8vN8Zzp+qheCGx_!~i1e{xVUaQAag^jW
zv<YKsWI3{etum&uRRK1{h_fLv;r%JBH>R7P0^Q6a)0i2EV3?E)vzS2`++-!W*MUTF
zpC`GEKGfEj9UvnLjkN@nhKV10zGTA`WI42OQoCNvF`ol2Xzr^ebK!pSb(JQu#H<hr
zm{(W{RM4!dVImPJMZLp!6_9&dP-4<ec#6RrA<u``b9miJMRddbOGPG%0&j%}fq0mT
zC?>`DF9F+X5b`-fz7M4NBFIewg@=aO@m~hbbxiZ?ESd=-vK>X?dOicDXGil7pf{->
zN+BWOgonHprs5KM)G+Sx<&^=A>n1V*7Y<!eYEeAglRpTAIq=3_i$dz25^@O^O?xd0
zoqH-|>G8cmioSbR%F?5IC-_r4#ot6IEX;v3dvo`Z4Y=NsiSRdz2e|6yz?*w>|3;NQ
zq)Y2|hzFx&gE=s?7f27aRsL>xfB${+BoXc6(`DRO=tpZn-Ts*ri<q-53i17A6mwW`
z<-VdgW-vWQoV2(T>vAfr5#qcDQ4eFEHHgwSMXAhz>?=riLx<Qmo|=c|VRFj8sYLA=
zs24>AaCkQ}KR6dST(8Om%+D}$o9K>HjMGY*E$jXmS%!7!tt_m2@gReTZ_WL-67iT4
z0Wa-jFL?&mV`b5UYIS@{(M(h{#(k%t#`-;#6;qhgscOMzVC4<%igbcaS_mpudPC75
zkWBh{;8JT8=^UGMJ<vh)(9~4wRaA5GYN}LvwMG=(1{F0CYVhfbxx{9^S?j5pq4g9W
zHH5hO?8hWcg-u#a(fIKfM&R?C;n{V^ltI6>>FFtpT6^7jJpAC%$B&ni#AN|0Fb5vI
zRZa!u5AN72M1B+U=j#<tMp8K{K$6Zcm2s0`K}!RKN8E_nH21KKs1U1wq=oiLr1BR~
z^aw|n`?pgUf?|}Vllpm6@t<AbOdPquF%K5ELJKc&%+F7vyg7iITF(?v-cPqj@W<Ag
zBE;((@BF|b*vRV}??QhA%H{gTyCirw5%c=Sdp-kledArqfLz~rmoXsMH{J^vkn0=o
zg$&5`jrSr3<od?DoB_GM@m4V)*Eimk49NA3_Ywx=`o_C@JZ+-X@cPEPrtk^?a(&}X
zu+?&X<6X;uT;F)tg=i%$*Eik``IiHb>l^RJ=r#ayedFB}_ynZM^^N!PXd?i*zVU94
z>;sux-*~T{@JW=&^^NzMVj2hK`o?=Ln<LjZ-s^%1@W}Oz*SWs&*061IedFB`*arb>
zePj8Hsbwb7`o^o)H)aCmCZW0I$SQ6*Aghq)^^Ms=Ia=SCJCS3;1DdcvnAEg+gqTcg
zn#e#d<<$@Cu!^2+(yEA0Cwx=$S3;FMo$yU#z$?N5U-4Ox@acqaQYq)@bix<6XoabN
z3g@MR3Ey-U7djvKn15lc41JalCj5(MQeGZR_?Iw%$3P1>?+=0ZpU?RaA4~+s2Oc9v
zI+zF)sepVCRDt3cStt)C0u#AJ9!vx#bBR2d2*kNW9!vyg1e4&A2NQvr49J6tz^uXr
z&`=~ov{<b4Ul*8y5sVKe{58e&<3NnfAn?~RAP*+|J7Pp74<`I|49J5Ce?6NZ4<`I6
z2IRqnzk$h01^;rU4D8&B_#YPOU?Mna(gjcz_6Flup@_GygEInO1dg|_gEOTEymSx|
zoMkQpQ2|kgOM|Np5=S0LgVmEShOLr&O@Q&V`5nA8+=^lu7l(jg)w6|n7cnKw8%R)P
z@Umaqf;LPd=Sx8w1B_=uo2Gq*T*3kNt`<}wymST-+-yDu6qnJeiIq$f=0Pyz5h9Gu
z`K3tp=KKewPHoP!eO|RWKLJGe5fvW0usMGWfZm*^kx1yxd760b&3OX;+;7^jF;5k@
zH|EKBdt;sedt;s~v^VBy96TnxYGZyiicGrk>NPww_6{M=;x^TTM)dHFdc9t~PV;*y
zR>LK}i%`xhM3HkLJZR)xkGm&_507)+K~=pu^6)smGKAv%JhB#B*7YO}v*s58=HeG<
zDbm9#a?3y%dp%4h?jtP4l!tP{B!YZ8w2cP8Kt;5T;h`oFxwN^TH_jriK`P=KL7tZg
zWFnJ9ndJE31yGVZ&67(K-y#BXv^=iPy`9RwnMY0M!?MDYPg+8hBYDE4*2<%jd|En&
z7thy4tc8g<H%<g!1Zh4tsfi__$;1pmqM#(Q1sIcL=I(`{P;rp*X(D5r$s{q8Hpg?Z
zIew?j9;CHz<T`_0^d&;yOHL;<p>jX+F>Ke8tf#1uZo(wL=hHGLT=6r)(yCcHJV@Ij
zG3?P2$63wcp&YCOTabSIheIVM$b|?gGDtu0i(wm?_)2W_tX^v9IouLcX~Q2Ezqy3e
zxbH`xi(U<iIl07U4xHW_Z6R<HIh4-PBQ*f$7Emjh0|##54c~b_Nxbit$R|-cZ=3}0
zxMh52otQUOLhtX5Y(`;Ogqq$Qxa*dZ84F0c5SPhBjBgfeLz4I$R@4*dFlp8d{R&HF
zF*$*@Xr|88@475i?8bfP?STTL(5II>Rdz{~R&a%d+*1awiPAE$FrGj$?RH)UuJHxj
z7}ycUxs)(-F9=;2S{7PcuoPt;OROz`%@*OO8?wMtgwErn#Go?X!HD3TB|@Q#LuM`p
zr>F=`50H>Rxv`>{#aqilvy0ajTvSY>OmLA~cFqJN6k;o;2Z<t73W~|FCTtjM3kVaL
z4zntN$vuzlixwDWuHp$10nX@2Wu8(gEhn9MM!vtQ=w{Z8urvc%wJIpknpsLADhYxd
zRC{_*I%J$v;&k8aVyD3I<uF4EoF2(8n&2pkW(>KJ4JpbqN^%QA=Cn!ENL&n01jWjO
zXswCxAgVg)Jha(luW@lGgvODLL{*)V?N;g3soBUojbe$PX5-PsvlTLq_7v00g=!rx
zq1M5kOE$S~vYBqQbi$4F6PGbVC=(KYA$D|YJ0eFnchD6XIqr53=?DprY`RFc)zTrk
zHZm(Hqc+<128R`SDh~mh9X9zR+pi$geuXkd$H`_KpB-WoMmA`Xt(#4<+pc)D7Mf@i
zv!TvtoW$X+Iy3dz$=r(_h$-Cl9EhppzCYK9+1=c0_iZbCIPlqRh%X~R;8<Nh6B9Wj
zMuALI>ek0hsk;|?0M#g0cJrt!EMo4k$dgTwpQU6)F^MS1cAyUNLbS_te`vbb+118z
zP&tOj@e~hOJGtVaD7%e|m5R|vp@|`bS`8h1L|jdFGP(yF{A`vxEK7A3VuBbMkJB>o
z7?*)KeS&MuoWWkRG9$}O8gXWgGibP?=r6Hdl^vMp*?7mGGJCXWEe#o4X}e?OAd%HF
z)GlTwHoPMoV`-md0*xbcx`&2plS9rO13`D=<;b8ICC;2~=b1{6Z{!91YS`7>QM((&
zMmj!kWCzc8JK8Z=jN%$wI%Z+2nK!!=;#YpIUg4a5N4PGadsA>kJ#zHm8RFhN-FqR?
z(lQ_{`<ZJ5)qN#bw?<TYG=}HjT$(=e+%C^|%z~~7QujkwILisL(C$!jMKF$nk{Sau
zuIvPX3$10-!<kjZ1nQZ3Bz1Q@DHP+WcARsz#)Lbv6(^C;$@!BrVMY3<$i6f+)4Qf+
z2$u08BA#h3%(5KkY6Mw<`4@967y{0<%S=?((F<oeS*T}Zy5Wc+-_;Ydmpiln(%^0f
znmfWc9F)=7i#r`LnW(bIf~@&8M^6YLw|l~_u{*-ml`W<Qd0S-GTpS${_nEkp;fiRp
zmozj$${D{v2B})xQLXH?9mUM}5j|#tbD$0B85YqsGE9nPI84lh0|$;AQV~4Prj)He
z#g1$amZ>_hr;Qvo;@R933e)WxvbSXgXN)%TW|nN(WA`juf^x2|9}oDtW4q!?)4*Lf
z;o-s(0dWV7>W1;B+z2Ij{1W&>hJM$8PgCHp4S%!|`fdCT;?HAD^F;Z#w1W1n#0U5@
zJ_ari-Ao_lCev*J-B!|VGu`OhLgISdylJ}a#m(xW96j`TEdxI-)~|(_QNyy{vkD)u
zCiht5Znp}XtZ_Y7@D9u9nQuj&vWjoF3U0TI#`#t-u-vlVvO*77!5+)FY`!%)&~268
zZUt|*#ywzp0uNgFvB1Q%Rd~DQxyTBgw5)ZOx!tP7eVvt?w#>9;JhEaW7k;G`Pg@h2
z%Q(5hib7B1O)IC{vcM!fUSqoz_N*&>%F27n%72QCiXOMDz)o4%XoXM+xO*%(=vh}_
z8QbS)Xu7Q&lIy7|u%b@`U1^yQ5W?4B<@g92e#Y_zzHfOOf2+_TMh73aN}jaJ2-jeh
zP;$SOW5NN}{g!!|mGfK6^Ndv(XtMGHKeNI;RtQ-uP+^&k4l!h_0~KV+<WIW_f310u
z$H|Q|q<Isw%_|~s9X8~U+)nL6#y(^fz{0%$nX!f3_||VN){wReNTl6T+!&s;6}?0H
zl?v@9LbXSS4K&dT3o^O9+ltC2MY~A)2*Dw0^)W@LD6q>(q{l@6`e*b7>VEsE^NiO0
zuvd}ke%W1*Uv}bKrt8tWoqwV0QLi(p*LkVenTO~`UC-pMr(akw!$#mq%YO=e=jT*S
z-%-o-dDe}SdCH+LoUrD2X69R-Us}dV&jeK9hmb?n`TU=)4vi!<qGVNP+@s*dHX?2`
zei&3I4-Fy)4I%~&A_fg223PSZ<ajtS?BT>b0-QKTH?AGmGgC!+G2T&6{bMh)z_2_$
z=+#DG`3mGtqAFE^1D5Bc6*y^`6;^TJHuzwDpmBhT0?mPKmT$;1-?J8+v?kq;p7;YR
zPENUBcD?&$<TY5{%T8JzGdGUTZH+U#0*LFtW!8kZes1~Sw5B#9u(w;W0QU#q0SLhF
zT|Hi}3{|hsv%JuX62fc?oV5&d+_v48=eJhyDTrGfxZf&*@W2m9FNOv5e?%bSdh&M5
z`nlyLbhlNA#6#^w-OBTbl~2h7)&xe+E9B_)9JS6P7-t|e4dy^M44RQAEn~T7JR0;(
zc#|5G4ira?Pja`M3e10_Jm0t_IGptFvWl(PQ&wm{8JSZ-qYnmLG6)W)&W|4~lP7=-
zN{EI)vzt9@ejNX?6>7B3nv2A9k9081Y(rl+3(Bo9B=022(<-d_fd&g6i4enORwX43
z)-p;0DJ!(znnWT#Y1i~FxYOf7%__0AN%f>-?@{aNqk0bFPfvvv;Gh8JX)rPekij>O
z+id_n^fEEWGM_bhy8wDA3N3nh!rMbP3RHuBK4V$)Fz@L@RC9@O)~bBV^51SPLt~ps
zYvNm$*=hL^LFR4NjKC{AZ6Ty?w<3?wJ^X#T8$H&?0?lWwWz2dBv2J&>{_~iu69dgw
zpvUsbmNB-;@fZ_hpun2AV$7mBE365RfT-K5m`?+D2*4xOv=y8gu%;vPeam>jx@d(J
zrV%o26>YZyi0bj%tz1uQfi+vUiE8AWFClQyUfZn_hy#NGn-<LvTx8{(w0yT)F-*Ak
zTd~Wm+$XIFRsv61mj#+VSLa)iz;w&>+-($F!K*BP+VWjwO(8++tQaK?memvJ@swfy
zMEAYlif*?GJrxBOoaFBbJY@x`$bY|upXPWym`aH!Z7o4!9$?7y%*wY+Gv@%s%tS=V
zwbYh~nS*HNv17&=FN2`8W2TT#xcQbDzv)!cq)7P-gE)_H985IKSr37O*Hjjde>Cb@
zG^ShJ3H6?`S!iHRz09)iz@%>(Pg`ag{70i6kAFRs!x*<BaM+6cyJh{OWe#{s;gp9k
z)(nt8d<U#4Jl5nN#@MyavYM=7!XF^YSy-<S<s(dazqO7hiSS`-x~F8E<vEN6$41K|
z$47K~nmkPmv^4&h@5&yTwmh#}!MDi4H25Twsm{)}_9Q+9%OA28$s~O&7D?m$WP4|G
zW3sFH#uR}vBfstmSby-6KZw~@+mdW)?n(=dr7zYd?QfEb)>La<#~yIu%bDG&C5vo2
z{^n{jP4YVNJBBQF{!C{wS=WxQ--xcJ_RchYeN)u6ckE#slj-&(ebH5Pr8`lH_D+XY
zWDLY=c~T7vymaH%_^SEmtIy`d%UaXjZK>srskT&Sa~;6i&bp@MyO%C0Te2u#*4S9T
zBVM+tGG5kD+qI{yuBo%Vt-ZUeth;Sjb6b5`x^_oPstbi(X?#kx44+m_r|Qz}on^47
zy{*wMsB5Y1YSP8{j4ul68XU0bO0|x#mOjoauIy-OPG5-@=tAY%QoGZlGgVukq<6`)
z>n1<33!)ofm}nvGd?Sw~lU>w^>}GC&g$uI2hf3e06}vi{)2WeyYt!jYFgiYHoK&C0
z73()$nv@@QP3>;xCQLW6b<*2iqPva04xFlw*EQ94GC6+%wk@@b^`O$V9cb2+t14Q4
zCdN3Lx*WB#CClnHCOcCNT|$4WSTv^a(c;cjD%pik+-AhHn2hw6_FZsIZMwa+xh}b@
zxjrRBE!F7=v4+m}RvBb)B6S2Ahgtf&WEiUNJ+qhFy1P=HnI<B|%8~YWgk3KEWOu5Y
zy4fzSN%E5R_7*_sg9xooa&A*|V-x#Oel<5qJ@y7h$WQEcQKYB}Q_Jvoc6E$!&C^UR
zKfOzJ=@R((ExJhuDR4G$s!dyyLO-I<PG`xXPc|cBStj$!!J!d@K$obkzaAgVrS_E{
ztWGA|ccE(uZV5O$Nk4aQX>Wx2jaf=nZ{O9G`Xp-G)zRDr`_P5}@CoZimksi>(<qap
zPWKL^O>*Soj~zn_S`(^dSj$g4r<+?-aA#|W&>ulg;sq34H`PG$qsU1J=uWjEc*rjK
z$?l{I@6J?Ldv|9Y{D<!jC+QQ!ZMCh4GX9!!vI$*X)S(}sH^Bn_Dsq=HgDjG6*}Nrj
zMfJ+n$qie#RBuaio2*Jyueyv~Bdz7ZQZ%--@4(<n^})x9MK<5c)hjn|S^M$o<i^b+
z-CVELXkye7R(7F*={wKT2A715o37Y^Z!pUWAxYx(21GD<iXx9(RlBF9y|x~GLe@oj
z!6oO4>Q!5>xKf!yUCdRUsUg|gnW{@Q?@ZOpE=3-b6N9L&qpzH!H+OZnD1&K~=Pyme
zIOXCr0=Fea<4|2^a|gy-mzR>#f&3wB3N>bj_Z;nkHfu~b*=?U@zo**LoqJq{udZIR
za_jmnx^>mZ!|Pg7wQb!UBO{`#tphzN-5_YJ=2nCG6zZ_v_8{IHf{%6F$yjlzwf*VB
zZ&|ycdNsMw7N&x7S7&WU2lcb|q;evffIjDqQN2^(9gQS9Eq$+k7r9-=Z?dztt&uud
zdqV>ZYDw)(A=1(`6kxhpy9w<;b4?l(D@O3<Hj!>kHi1<nc@(7IEH-u!a~Gnk4#IaJ
z&?G0yk~?a<Qp9p&dmF~hbUpPJO~u_R35A%RsEHsU`N{5P$dMhY-Ny1TXB$JKN4H#{
zG_=%`nHYAPTkz#~M35W|h?dk7X|k@n6Mk>$Zf)ZV)wS2B>UO3DdMsvck!)|N*Y>wG
z!%A4&is6n#U?Fe=JO|946lO14A3+WJInOMJP*Nh=ccwZU;M62u8^d1;3n%cZxfG5A
zdvjMkx&u{mJx1&`QhHbI&XjZz6*xVgsW>$UL$&qwN&J8}$u(XeU}C*A6-^@LHbN{}
zT3<_xtj4zPx-54{d)Ohcjyy`U6tZj9uCEpi4K3Xmvs8^~nnhKh(rzoR63vg&@jH3h
zqy5&ILhDg&xb`rju{Dj5phZ~&`wJ*c7P8CQB7xi`jRozJMamqGHx3(8$x_Maoeio}
zfvZ(=b=1}`MooE~LRGqH!mVFGQHGVESfyf->qtR~uF7H?>~OVPktYzUay18Irun2D
z+K<U}ZKK^~ugCwSzyaT0C*%l@85grF#&6XfX)s1e)H$a(LhMuo(#ss%a8w$TeJgda
zil+9~R7HJlTWv*Gdj<YagH%O&VMQ&LZ;frO=qqKIZ&9~Y3%+$Pzgu6?h2PLPChzh(
zQPJJiS<%wGqoT2{t^zCB<dQ{Yi0<y)WeALl`SUB9+v-}n5kgF;fRThdn$ul>fuw6s
zHpO3Ke|NgMrK<uBK#f<QYAA0Kqb$jQm7Xo@!dfzgrT3nWR2Q)DUUywuj`#r8plX-u
zB_@iTPO=GELOq;?3~XSK2$A9EBBXk)0MFuolYo)HHPp4GTafBe7-cAsb`uLvxXyAi
zw7$7LQ-)^xpSQK`EAp3a=|9_m73>K%u9GTt5s#K-&21NJ&(RQo0@;(0Q4USFDkKse
zYtU#rqe&FtahM*>>GHnn`L^kO&HN|cN@dijH#{y2uXq<<QOUmW!(yC;c*Wf~DWNOQ
zcl_`G>1gy*f%o8*yUm4)P$hAN-{-<FRCxW}V?{33B4db&;;tHrA^Ygsia$e)x4&P^
zNZfA5AL+#}^|G$J02x5)?;-2LuOc&={f`4ra@=3^dQsuspAh?r!n;3V_LjoCKcDtT
z;78Mot%_0cu`%%U2^0fg<%!imATB!mqpM;Jdir=J`Ey^bq$^VGdA^cURU`50hlQdV
zc=ChZl>4nL7F!kG{q96Rwg`#d{jNowqIbWWK}TRj?|$Q^8~D-uGgiFq1HB;%#pZR&
zKu0o~oO_slf^dIl`E$TiRL@%N5P<C0n7&Bp?^Wy4LE!V?&j)KHM)o%Re+Izkqh9VG
zKmLUAnmd!8RP+zcl(;#nh`w@|pCPkz^hwpx@bkyOZv;MWb7wO2d-OPc)u|?fqa6Lr
znCy4It<<gX?$?^{P<Z!u4C%9AquKeCmapnd{hzL%k3oM*(Ys$aqBo{uu)m{*+3nkh
zW5}6o%J!<Nm87MLV?OZto;;zypRNU+Pk3l>e>d_nB}XVZy1!h_^qM=9?i>Sua18t-
zjE@QTyZ=uC&+%3-Wo!Fi8bi*{$H3$NqaL+g0*Hsv+G`T<<Y!TnsT1W&fhT(g6<*u(
z4(6HB<SYVxoETl#sxkC_oaB3oMW7~|p>7O%`o(x2X|9s=0Qow=^fBT7&G8)y|MGZA
z_kkhPPmf{$y^7xbCD4CRczx7EFAmZ5xWc>NeS4nqlE!&IF$Ufk!=A!1@Us~o8}SXu
zMGCJQL4QTH8hCuLO&qOvS|h}CWq(}F*XOBX`se`ByZarzCP4kg{mb;L72f><BfZ8t
zTAX}p4Ez_Aoau9=AtlP5!@yG<9;%TDJq|xPhMd>Oz@HuiZ(v@ddfhoo%BT5&F8aI>
z;q{L-^z<`@@sh@QF9)9D+3mLrfR8%~Ri1uAPx9Sw&t5Zz{PY<3UL{ALf>bH_pBaPx
zo50T)#h$;Rc<_X&@w2X1lzjJ_qyM7t?r*uA9Yb#(enLw1b$_g82JqCr`)Z_G-M-?=
zy3X|c@^(CG*6wKLXFwpj()geKuo%X(W~vcS1SxEpVRH%l?YvE2-=0*vcJ<hs>Ppsj
z@5X~dYe!28|HoQ+C1j04fo+erW;{c8*6zX11?@vMbYfRAS>N5-O3(BTi2whxEK=vA
zO`Uu9+r1+@^86%&$!vGq3;jChLymf|sT*S_Nj{aVckLwM$tP>;hd1x+od9)kLEEfq
zKgjX8kxZ_+V&#VFWc9|?$)rfG-oA0=hPA8U4xHj7s}rg;vHA*;ymbAhOIEH=Zd$YE
z%IYo2Eh{fsU!8RA3!=fW6GNNIRhO<`d&#Qgg7O9Bi^Z6mdG?-97CG%X@2Hde^4K$J
zZnH}lE`nv*$7yyMDN3&0vH`o6I%u|RSVbYTg}0*MI^J}_K96hL*3r0#47oFJ?;U0x
zv)RfPmM{3T`_{Z4WK)xAq@MQRcqd9EQ@qoYrG<9=Z5C3Hy)&)$Tse%LkJ|QWk=%pA
z1GCxz#~wc&nqg=0hGYZ&gG^ht`*2Vl*x2P{uHI(NLP`yKyEwBi(}4deur7;|_L;H}
zSv8es3wAlxm7=vhTZTL*m0^%|%7Fbh>>;Z7NYe8(ws&l490$pI+G($CtH&OsJQ}sj
z=Ocz_?+d#HZAseH%5o+jk~jmRo{lMSaHMv|`S8JROFAIRsu{7{ny6m7RG!$$u4ogG
zsq(lt3njM;vrrw*^B1Rie6lEaVv{>?5+M(>c&keXygd+TTjYMYEgzi<F66C58>b^S
zYu{8hzkT+hHsUDYbPU@3RCPKgvJoUu?=of~^#+eV^>CiD(Wz$^aWaW6t;Z_r>tptG
zRNnSIZ6?}cWNrC0+s4_ob+)H$v8)CqIvkhpuBA@M|H<qK5t(gvSH-YpEzb{hD@ggY
zL763F#K9H<71n0ai1MyIt=J<*irDA0N#}4jlIrXb<v0dSm18@y9D^N>Ez)}&DB7Z`
zFKez>sFjzj#X)<cU~&%d^7=h(P$4+QCOem4Bc6{coj?+0ovD^uB2>8!oGX=cH!4TA
zys;f1WoV1KJWU7e<unt6x}C?s@>G+Wd+EbpHY8=pNmz2|JXF=<KpDo-&nU_f^`acJ
zKkeQEm)g-y=LB@_0=xv9+Zx(+zIMkB`W=KS;WG)9hX<W#bR`?^Y-^-l?5?aO(_aNl
z0v9bk@p#LZ-oMf5WQEs>TBd4H%tQ`LDVu+(DT{QfpJO$Hz0OjIB}kq8O^RQqYI&^L
zv4@j=(SDwjU+*XCG@ea9g8vgJ|2_WiEnR>8|C8xdKYwC*$(P&yT3|!?)BMMk{W?9M
zV6u^Xr}_21S~GA&qWPPM5SLDAU&eX4{r^c6(*G@{$@KpxrqlI`S=+Dabb1TQ>HjLz
zu>SwbbXueM-S#WA=tqXyMDy$aKTW6l|4-BU-Sz*R;=e=*93*Gr(&>;AO#I|CH~&Mx
zkx#UI`#C~APf&b2FL(Uhhe9WRT=D7Du9y;{A5(PtRX4wS_>8Mm(`g$ttkXwb{FRDN
zr)OLZuK9HOT^GN8uGZ-;+BkPynopyiMaEfwy<er%h$d92+kY=9e%=0}N)f7bmWx5R
zpP~{!M27The!Wks)77r}yTpmtUHnbeQnF6zlf%x-t^Xtn@jf>9L88<9`A?{h<Mx;4
z*Xg_9!IySye*OO+9{q3f(~lG>cGWOp?;jsm{JQ<suwci(w(INQB^POay`Ow^Bapb3
zy8Nf@)+zrM9CVsr)DRc0%`)kbiG7dTIhhGVKFQMj`)VY<L-8kE{*TLI`<@4WGO^Oe
z$c*Nn>%!~m=yamucae!NDE)Cws0du3m@@|dQ<qDIwdL88-Td<WBb$aG?>^jcEeOk0
z-`)JH#?ZgyZpm>UJ{{q_-29sqzuSL5=FgSlV`pkS)iN}{POln+zvf}daaeauB|!7(
zl+IgpUhAMV{ACHzd#%pPO-ry#1(TO5{-dh?vw)q6KOMJv{tN=AV~-it?aVi1X0h%#
X3h&mR2mEOKCI2KDZgerYK=FS8Z$N~@

diff --git a/src/ring_buffer.c b/src/ring_buffer.c
index 106932d..afebef1 100644
--- a/src/ring_buffer.c
+++ b/src/ring_buffer.c
@@ -2,11 +2,11 @@
 
 #include <stdlib.h>
 #include <pthread.h>
-#include <string.h>
 #include <stdio.h>
 #include "ring_buffer.h"
 #include "utils.h"
 
+// struct to store the sizes of the two parts of the buffer when splitting
 typedef struct {
 	size_t first_part;
 	size_t second_part;
@@ -15,11 +15,12 @@ typedef struct {
 SplitSizes split_space(size_t size, size_t space_at_end)
 {
 	SplitSizes sizes;
-
+	// split the space into two parts if the size is bigger than the space at the end
 	if (size > space_at_end) {
 		sizes.first_part = space_at_end;
 		sizes.second_part = size - space_at_end;
 	} else {
+		// otherwise it's all in the first part
 		sizes.first_part = size;
 		sizes.second_part = 0;
 	}
@@ -28,147 +29,171 @@ SplitSizes split_space(size_t size, size_t space_at_end)
 
 static size_t get_free_space(const so_ring_buffer_t *ring)
 {
+	// calculate the free space in the ring buffer by subtracting the length from the capacity
 	return ring->cap - ring->len;
 }
 
 static size_t adjust_position(size_t pos, size_t offset, size_t cap)
 {
+	// adjust the position by adding the offset
 	size_t new_pos = pos + offset;
-
+	// if the new position is greater than the capacity, wrap around
 	if (new_pos >= cap)
 		new_pos -= cap;
 	return new_pos;
 }
 
-static void copy_data_to_ring(so_ring_buffer_t *ring, const void *data, size_t size)
+static void copy_to_ring(so_ring_buffer_t *ring, const void *data, size_t size)
 {
+	// calculate the space at the end of the buffer
 	size_t space_at_end = ring->cap - ring->write_pos;
+	// split the space into two parts
 	SplitSizes sizes = split_space(size, space_at_end);
 
+	// copy the data to the buffer
 	memcpy(ring->data + ring->write_pos, data, sizes.first_part);
+	// if there is a second part, copy it to the beginning of the buffer
 	if (sizes.second_part > 0)
 		memcpy(ring->data, (const char *)data + sizes.first_part, sizes.second_part);
 }
 
-static void copy_data_from_ring(so_ring_buffer_t *ring, void *data, size_t size)
+static void copy_from_ring(so_ring_buffer_t *ring, void *data, size_t size)
 {
+	// calculate the space at the end of the buffer
 	size_t space_at_end = ring->cap - ring->read_pos;
+	// split the space into two parts
 	SplitSizes sizes = split_space(size, space_at_end);
 
+	// copy the data from the buffer , no need to check for second part
 	memcpy(data, ring->data + ring->read_pos, sizes.first_part);
 }
 
 int ring_buffer_init(so_ring_buffer_t *ring, size_t cap)
 {
-	ring->data = malloc(cap);
+	ring->data = malloc(cap); // allocate memory for the ring buffer
 	if (ring->data == NULL)
-		DIE(1, "Memory allocation failed");
+		DIE(1, "malloc failed");
 
+	// initialize the ring buffer
 	ring->cap = cap;
 	ring->len = 0;
 	ring->read_pos = 0;
 	ring->write_pos = 0;
 	ring->stop = 0;
 
+	// initialize the synchronization primitives for synchronization
 	int result = pthread_mutex_init(&ring->mutex, NULL);
 
 	if (result != 0)
-		DIE(1, "Failed to initialize mutex");
+		DIE(1, "pthread_mutex_init failed");
 
 	result = pthread_cond_init(&ring->not_empty, NULL);
 	if (result != 0)
-		DIE(1, "Failed to initialize not_empty condition");
+		DIE(1, "failed to initialize not_empty");
 
 	result = pthread_cond_init(&ring->not_full, NULL);
 	if (result != 0)
-		DIE(1, "Failed to initialize not_full condition");
+		DIE(1, "failed to initialize not_full");
 	return 0;
 }
 
 ssize_t ring_buffer_enqueue(so_ring_buffer_t *ring, void *data, size_t size)
 {
 	if (data == NULL) {
-		ERR(1, "Invalid data pointer");
+		ERR(1, "invalid data pointer");
 		return -1;
 	}
 
+	// lock to ensure exclusive access to the ring buffer
 	int result = pthread_mutex_lock(&ring->mutex);
 
 	if (result != 0) {
-		ERR(result != 0, "Failed to lock mutex");
+		ERR(result != 0, "pthread_mutex_lock failed");
 		return -1;
 	}
 
+	// wait until there is enough space in the buffer
 	while (get_free_space(ring) < size && !ring->stop) {
 		result = pthread_cond_wait(&ring->not_full, &ring->mutex);
 		if (result != 0) {
 			pthread_mutex_unlock(&ring->mutex);
-			ERR(result != 0, "Failed to wait on not_full condition");
+			ERR(result != 0, "failed to wait on not_full condition");
 			return -1;
 		}
 	}
 
+	// if the buffer is stopped and there is no space, return
 	if (ring->stop) {
 		pthread_mutex_unlock(&ring->mutex);
 		return -1;
 	}
 
+	// copy the data to the buffer
+	copy_to_ring(ring, data, size);
 
-	copy_data_to_ring(ring, data, size);
-
+	// update the write position and length
 	ring->write_pos = adjust_position(ring->write_pos, size, ring->cap);
 	ring->len += size;
 
+	// signal that the buffer is not empty
 	result = pthread_cond_signal(&ring->not_empty);
 	if (result != 0)
-		ERR(result != 0, "Failed to signal not_empty condition");
+		ERR(result != 0, "failed to signal not_empty condition");
 
+	// unlock the mutex and allow other threads to access the buffer
 	result = pthread_mutex_unlock(&ring->mutex);
 	if (result != 0)
-		ERR(result != 0, "Failed to unlock mutex");
+		ERR(result != 0, "pthread_mutex_unlock failed");
 	return size;
 }
 
 ssize_t ring_buffer_dequeue(so_ring_buffer_t *ring, void *data, size_t size)
 {
 	if (data == NULL) {
-		ERR(1, "Invalid data pointer");
+		ERR(1, "invalid data");
 		return -1;
 	}
 
+	// lock mutex to ensure exclusive access to the ring buffer
 	int result = pthread_mutex_lock(&ring->mutex);
 
 	if (result != 0) {
-		ERR(result != 0, "Failed to lock mutex");
+		ERR(result != 0, "pthread_mutex_lock failed");
 		return -1;
 	}
 
+	// wait until there is enough data in the buffer
 	while (ring->len < size && !ring->stop) {
 		result = pthread_cond_wait(&ring->not_empty, &ring->mutex);
 		if (result != 0) {
 			pthread_mutex_unlock(&ring->mutex);
-			ERR(result != 0, "Failed to wait on not_empty condition");
+			ERR(result != 0, "failed to wait on not_empty condition");
 			return -1;
 		}
 	}
 
+	// if the buffer is stopped and there is no data, return
 	if (ring->stop && ring->len == 0) {
 		pthread_mutex_unlock(&ring->mutex);
 		return 0;
 	}
 
-	copy_data_from_ring(ring, data, size);
+	// copy the data from the buffer
+	copy_from_ring(ring, data, size);
 
+	// update the read position and length
 	ring->read_pos = adjust_position(ring->read_pos, size, ring->cap);
 	ring->len -= size;
 
+	// signal that the buffer is not full
 	result = pthread_cond_signal(&ring->not_full);
 	if (result != 0)
-		ERR(result != 0, "Failed to signal not_full condition");
+		ERR(result != 0, "failed to signal not_full condition");
 
+	// unlock the mutex and allow other threads to access the buffer
 	result = pthread_mutex_unlock(&ring->mutex);
 	if (result != 0)
-		ERR(result != 0, "Failed to unlock mutex");
+		ERR(result != 0, "pthread_mutex_unlock failed");
 
 	return size;
 }
@@ -176,45 +201,51 @@ ssize_t ring_buffer_dequeue(so_ring_buffer_t *ring, void *data, size_t size)
 void ring_buffer_destroy(so_ring_buffer_t *ring)
 {
 	if (ring == NULL || ring->data == NULL)
-		DIE(1, "Attempting to destroy an uninitialized ring buffer");
+		DIE(1, "invalid ring buffer");
 
+	// free the data allocated for the ring buffer
 	free(ring->data);
 
+	// destroy the synchronization primitives and condition variables
 	int result = pthread_mutex_destroy(&ring->mutex);
 
 	if (result != 0)
-		DIE(1, "Failed to destroy mutex");
+		DIE(1, "failed to destroy mutex");
 
 	result = pthread_cond_destroy(&ring->not_empty);
 	if (result != 0)
-		DIE(1, "Failed to destroy not_empty condition");
+		DIE(1, "failed to destroy not_empty");
 
 	result = pthread_cond_destroy(&ring->not_full);
 	if (result != 0)
-		DIE(1, "Failed to destroy not_full condition");
+		DIE(1, "failed to destroy not_full");
 }
 
 void ring_buffer_stop(so_ring_buffer_t *ring)
 {
 	if (ring == NULL)
-		DIE(1, "Attempting to stop an uninitialized ring buffer");
+		DIE(1, "invalid ring buffer");
 
+	// lock the motex to modify the stop flag
 	int result = pthread_mutex_lock(&ring->mutex);
 
 	if (result != 0)
-		DIE(1, "Failed to lock mutex");
+		DIE(1, "pthread_mutex_lock failed");
 
+	// set the stop flag to 1 to indicate that the buffer is stopped
 	ring->stop = 1;
 
+	// wake up all threads waiting on the condition variables and consumers
 	result = pthread_cond_broadcast(&ring->not_empty);
 	if (result != 0)
-		DIE(1, "Failed to broadcast not_empty condition");
+		DIE(1, "failed to broadcast not_empty condition");
 
 	result = pthread_cond_broadcast(&ring->not_full);
 	if (result != 0)
-		DIE(1, "Failed to broadcast not_full condition");
+		DIE(1, "failed to broadcast not_full condition");
 
+	// unlock the mutex to allow other threads to access the buffer
 	result = pthread_mutex_unlock(&ring->mutex);
 	if (result != 0)
-		DIE(1, "Failed to unlock mutex");
-}
\ No newline at end of file
+		DIE(1, "pthread_mutex_unlock failed");
+}
diff --git a/src/ring_buffer.h b/src/ring_buffer.h
index 4f8aac3..1fa880d 100644
--- a/src/ring_buffer.h
+++ b/src/ring_buffer.h
@@ -6,7 +6,6 @@
 #include <sys/types.h>
 #include <string.h>
 #include <pthread.h>
-#include <semaphore.h>
 
 typedef struct so_ring_buffer_t {
 	char *data;
@@ -15,11 +14,10 @@ typedef struct so_ring_buffer_t {
 	size_t len;
 	size_t cap;
 	/* TODO: Add syncronization primitives */
-	pthread_mutex_t mutex;
-	pthread_cond_t not_empty;
-	pthread_cond_t not_full;
-	sem_t semaphore;
-	int stop;
+	pthread_mutex_t mutex; // mutex for synchronization access to the buffer
+	pthread_cond_t not_empty; // condition variable for signaling when the buffer is not empty
+	pthread_cond_t not_full;// condition variable for signaling when the buffer is not full
+	int stop; // flag to signal that the buffer is stopped
 } so_ring_buffer_t;
 
 int     ring_buffer_init(so_ring_buffer_t *rb, size_t cap);
@@ -28,4 +26,4 @@ ssize_t ring_buffer_dequeue(so_ring_buffer_t *rb, void *data, size_t size);
 void    ring_buffer_destroy(so_ring_buffer_t *rb);
 void    ring_buffer_stop(so_ring_buffer_t *rb);
 
-#endif /* __SO_RINGBUFFER_H__ */
\ No newline at end of file
+#endif /* __SO_RINGBUFFER_H__ */
diff --git a/src/serial b/src/serial
deleted file mode 100755
index b24d42de3c45cf68a28f90244647f218752aba10..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 48384
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
IJfQJ^0UKMC&Hw-a

-- 
GitLab