From a2d5a1b0977cf7af11191df636b2192e79379a61 Mon Sep 17 00:00:00 2001
From: SofianeLasri <alasri250@gmail.com>
Date: Mon, 12 Jun 2023 19:08:43 +0200
Subject: [PATCH] =?UTF-8?q?Avancement=20sur=20la=20home,=20cr=C3=A9ation?=
 =?UTF-8?q?=20de=20la=20template=20de=20base,=20ajout=20d'un=20champ=20ima?=
 =?UTF-8?q?ge=20sur=20le=20mod=C3=A8le=20des=20v=C3=A9hicules,=20cr=C3=A9a?=
 =?UTF-8?q?tion=20des=20autres=20urls=20et=20d'un=20helper=20twig=20pour?=
 =?UTF-8?q?=20les=20liens=20actifs.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                                     |   8 +
 WSR/admin.py                                  |   1 -
 ...ce_circuit_alter_race_location_and_more.py |  26 +++
 ...cle_image_alter_driver_vehicle_and_more.py |  54 +++++
 WSR/models.py                                 |  26 +--
 WSR/static/images/codemastersracing.png       | Bin 0 -> 13747 bytes
 WSR/static/scss/components.scss               |   1 +
 WSR/templates/base.html                       |  74 +++++++
 WSR/templates/home.html                       | 194 +++++++++++-------
 WSR/templatetags/__init__.py                  |   0
 WSR/templatetags/is_active.py                 |  11 +
 WSR/views.py                                  |  15 ++
 WSR_website/urls.py                           |   8 +-
 13 files changed, 329 insertions(+), 89 deletions(-)
 create mode 100644 README.md
 create mode 100644 WSR/migrations/0015_alter_race_circuit_alter_race_location_and_more.py
 create mode 100644 WSR/migrations/0016_vehicle_image_alter_driver_vehicle_and_more.py
 create mode 100644 WSR/static/images/codemastersracing.png
 create mode 100644 WSR/templates/base.html
 create mode 100644 WSR/templatetags/__init__.py
 create mode 100644 WSR/templatetags/is_active.py

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c8d5080
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# WSR Website
+## Python & paquet à installer
+Il est nécessaire d'avoir python > 3.10, ainsi que les paquets suivants :
+
+- Django
+- Pillow
+- django-compressor
+- django-libsass
\ No newline at end of file
diff --git a/WSR/admin.py b/WSR/admin.py
index 2a28291..f4d8e90 100644
--- a/WSR/admin.py
+++ b/WSR/admin.py
@@ -8,5 +8,4 @@ admin.site.register(Race)
 admin.site.register(Result)
 admin.site.register(Vehicle)
 admin.site.register(Driver)
-admin.site.register(Participation)
 admin.site.register(Season)
\ No newline at end of file
diff --git a/WSR/migrations/0015_alter_race_circuit_alter_race_location_and_more.py b/WSR/migrations/0015_alter_race_circuit_alter_race_location_and_more.py
new file mode 100644
index 0000000..bf08aa2
--- /dev/null
+++ b/WSR/migrations/0015_alter_race_circuit_alter_race_location_and_more.py
@@ -0,0 +1,26 @@
+# Generated by Django 4.2.2 on 2023-06-12 13:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('WSR', '0014_alter_race_circuit'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='race',
+            name='circuit',
+            field=models.CharField(choices=[('Pacfic Way', 'Pacific Way'), ('Marina City', 'Marina City'), ('Boucle Art Deco', 'Art Deco'), ('Ocean Drive', 'Ocean Drive'), ('Lake Shore Point', 'Lake Shore Point'), ('Le Trocadéro', 'Trocadero'), ('Boucle de la fontaine', 'Fontaine'), ('Route de la corniche', 'Corniche'), ('Baie de colombe', 'Colombe Bay'), ('Champs Elysées', 'Champs Elysees'), ('Villefranche-sur-mer', 'Villefranche'), ('Liveroutes', 'Liveroutes'), ('La turbie', 'Turbie'), ('Ap Lei Chau', 'Ap Lei Chau'), ('Route des Toriis', 'Torris'), ('Pok Fu Lam', 'Pok Fu Lam'), ('Col Sakura', 'Sakura'), ('Boucle du quai Orra', 'Orra Loop'), ('Voie Hattan', 'Hattan Way'), ('Belvédère de Nakheel', 'Nakheel'), ('Circuit GP', 'Circuit Gp')], max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='race',
+            name='location',
+            field=models.CharField(choices=[('Californie', 'Califoria'), ('Chicago', 'Chicago'), ('Miami', 'Miami'), ('Paris', 'Paris'), ('Barcelone', 'Barcelona'), ("Côte d'Azur", 'Cot'), ('Hong Kong', 'Hong Kong'), ('Okutama', 'Okutama'), ('Dubaï', 'Dubai'), ('Yas Marina', 'Yas Marina')], max_length=100),
+        ),
+        migrations.DeleteModel(
+            name='Participation',
+        ),
+    ]
diff --git a/WSR/migrations/0016_vehicle_image_alter_driver_vehicle_and_more.py b/WSR/migrations/0016_vehicle_image_alter_driver_vehicle_and_more.py
new file mode 100644
index 0000000..94cf6c6
--- /dev/null
+++ b/WSR/migrations/0016_vehicle_image_alter_driver_vehicle_and_more.py
@@ -0,0 +1,54 @@
+# Generated by Django 4.2.2 on 2023-06-12 17:04
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('WSR', '0015_alter_race_circuit_alter_race_location_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='vehicle',
+            name='image',
+            field=models.ImageField(blank=True, default='', upload_to='vehicles', verbose_name="Image d'illustration"),
+        ),
+        migrations.AlterField(
+            model_name='driver',
+            name='vehicle',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='WSR.vehicle', verbose_name='Véhicule'),
+        ),
+        migrations.AlterField(
+            model_name='race',
+            name='finishing_position',
+            field=models.PositiveIntegerField(verbose_name="Position d'arrivée"),
+        ),
+        migrations.AlterField(
+            model_name='race',
+            name='image',
+            field=models.ImageField(upload_to='race_images', verbose_name="Image d'illustration"),
+        ),
+        migrations.AlterField(
+            model_name='result',
+            name='finishing_position',
+            field=models.PositiveIntegerField(verbose_name="Position d'arrivée"),
+        ),
+        migrations.AlterField(
+            model_name='result',
+            name='starting_position',
+            field=models.PositiveIntegerField(verbose_name='Position de départ'),
+        ),
+        migrations.AlterField(
+            model_name='vehicle',
+            name='fabrication_year',
+            field=models.PositiveIntegerField(verbose_name='Année de fabrication'),
+        ),
+        migrations.AlterField(
+            model_name='vehicle',
+            name='model',
+            field=models.CharField(max_length=100, verbose_name='Modèle'),
+        ),
+    ]
diff --git a/WSR/models.py b/WSR/models.py
index e00f820..31b450a 100644
--- a/WSR/models.py
+++ b/WSR/models.py
@@ -12,7 +12,7 @@ class Season(models.Model):
 
 class Driver(models.Model):
     name = models.CharField(max_length=100)
-    vehicle = models.ForeignKey('Vehicle', on_delete=models.CASCADE, verbose_name="Vehicle")
+    vehicle = models.ForeignKey('Vehicle', on_delete=models.CASCADE, verbose_name="Véhicule")
 
     def __str__(self):
         return self.name
@@ -20,8 +20,9 @@ class Driver(models.Model):
 
 class Vehicle(models.Model):
     brand = models.CharField(max_length=100)
-    model = models.CharField(max_length=100, verbose_name="Model")
-    fabrication_year = models.PositiveIntegerField(verbose_name="Fabrication Year")
+    model = models.CharField(max_length=100, verbose_name="Modèle")
+    fabrication_year = models.PositiveIntegerField(verbose_name="Année de fabrication")
+    image = models.ImageField(upload_to='vehicles', default="", blank=True, verbose_name="Image d'illustration")
 
     def __str__(self):
         return f"{self.brand} {self.model}"
@@ -54,6 +55,7 @@ class Race(models.Model):
         HONG_KONG= "Hong Kong"
         OKUTAMA = "Okutama"
         DUBAI = "Dubaï"
+        YAS_MARINA = "Yas Marina"
 
     class Circuits(models.TextChoices):
         PACIFIC_WAY = "Pacfic Way"
@@ -76,12 +78,13 @@ class Race(models.Model):
         ORRA_LOOP = "Boucle du quai Orra"
         HATTAN_WAY = "Voie Hattan"
         NAKHEEL = "Belvédère de Nakheel"
+        CIRCUIT_GP = "Circuit GP"
 
     location = models.CharField(max_length=100, choices=Locations.choices)
     circuit = models.CharField(max_length=100, choices=Circuits.choices)
-    finishing_position = models.PositiveIntegerField(verbose_name="Finishing Position")
+    finishing_position = models.PositiveIntegerField(verbose_name="Position d'arrivée")
     season = models.ForeignKey(Season, on_delete=models.CASCADE)
-    image = models.ImageField(upload_to='race_images', verbose_name="Illustration Image")
+    image = models.ImageField(upload_to='race_images', verbose_name="Image d'illustration")
     type = models.CharField(max_length=100, choices=RaceType.choices, default=RaceType.SINGLE_RACE)
     participation_type = models.CharField(
         max_length=100,
@@ -107,19 +110,10 @@ class Article(models.Model):
 class Result(models.Model):
     driver = models.ForeignKey(Driver, on_delete=models.CASCADE)
     race = models.ForeignKey(Race, on_delete=models.CASCADE)
-    finishing_position = models.PositiveIntegerField(verbose_name="Finishing Position")
-    starting_position = models.PositiveIntegerField(verbose_name="Starting Position")
+    finishing_position = models.PositiveIntegerField(verbose_name="Position d'arrivée")
+    starting_position = models.PositiveIntegerField(verbose_name="Position de départ")
     score = models.IntegerField()
 
     def __str__(self):
         return f"{self.driver} - {self.race}"
 
-
-class Participation(models.Model):
-    season = models.ForeignKey(Season, on_delete=models.CASCADE)
-    race = models.ForeignKey(Race, on_delete=models.CASCADE)
-    drivers = models.ManyToManyField(Driver)
-
-    def __str__(self):
-        return f"{self.season} - {self.race}"
-
diff --git a/WSR/static/images/codemastersracing.png b/WSR/static/images/codemastersracing.png
new file mode 100644
index 0000000000000000000000000000000000000000..cc16d3549bd09af8afd0162f77c99873b25abd4a
GIT binary patch
literal 13747
zcmeAS@N?(olHy`uVBq!ia0y~yU}a!nU{vQ|W?*1Act<XRfq_A?#5JNMI6tkVJh3R1
z!7(L2DOJHUH!(dmC^a#qvhZZ84Fd!7^URQlk_cZPtK|G#y+n{2y^7od1`x2ZuP8`N
z&Q2{+NJ>r5%(GQ`zk9!uLS~AsQn;zFfp39xYDT6<RZ(him0w75Rd%vvijuvZf=z{0
zMQ%ZEYDuC(MQ%=Bu~mhw64+d;ykaYmu)dN4SV>8?trEmh5xxNm&iO^D3Z{Any2%D+
z1`1||dWOa(=H}))3PuKo2Koj@`i4fjhUQkrMpgy}3Q(YAr(jc*l4cd;;s&*=C?(BS
zDWjyMz)D}gyu4hm+*mKaC|%#s($W%ShLMqOQA(O_ab;dfVufyAu`<jAm(=3qqRfJl
z%=|nBkco*&`K2YcN=i^;D{>2bec=Y@6+;6mIX_pwBC$Z<P|rX=Hy7kDu!oCFf>IIA
zz^b}9q_QAYKPa_0zqBYhH7GSr8ObXA7QqyzB*WDelosWH{h5-ipPG}Jo0?ZrtZ%4i
z2zF6{udkJVQD%B(USf_*esU>D*3-pSskAgR#mdyh$iTwV$i&jv$<4*d(9qJ*#L>dk
z(!j;o(A2=f*#cx4$N*%G6}bg^DVZr&hDIi4&MvOz<_0DPhK8<&mWIxTu9k+zZYD-%
z7KUbKFuk66#U+V($*CYqL3%S0dd=|awQ?>>O)SYT3dzsUfh85soSf3)k|L0>f^)D5
zDE`2aW95=slv$RV;#QQOs{oDwt4u8RT9_FbTbjBU8Jidxn^_ndIvH77xLFz*8e5t;
zo4Q$ADna$8AO#f2%^?30)T?i&V3U$;RgzhflL}3ljyWYzR!$};Em`Fx=B3*zRp_Rq
zrX`l<lqlIb`^E<)CTHfQ#|ODP+3153Urwf-0)z$8u8(9WSOHRMg{cg3aRV{I84Hxj
z>=Y2WH#INCR;ftI-p=IH+fxh-49NjLA+8Jz42wmLNJ1-B?AIIlY;la(6_9!$uIN~9
z{psqSi(NCX&s=(U`KCwP_P;oK=H2C+UmiXE`Qg+5|NouO2Hj*}U=Sz?@(X4VP%v-^
zNGNFNpTB<p`TOscrJA}J7!0m^x;TbZ+<F^(vuTb6&lw-H$<_}I63#sR|Nm6&iK`{j
z6Iyay7FV6g^S^vdZ>36P)ptG9xcmERe$Uht;d0IT^W)pgzq^?~{`<^d%gNRH$U*4O
zmm;3uduu|z1#5`7KYqSk`NjLmT=A_=ij4Osb3g3&s^@BT>Jt7j&FtIv*y%9~15P-4
zvHe+cdToG)%ftOCt@^M2X^L=VYFPvt{n+dFUxcgGqQ>`7eg3WsT&<55DMkGBUl`DF
z#Qdp!tJ6Zg1)t_SE!-is&*j;E{#{47TAj4&vi^lH3|PU|SM)plHAr`Y%iFFGq1VF~
z25=lR=Vj0m>015B-Gy-tqeH8cqVz|O51aMYIW63w!MN|$Es&(p1M%4CR;R*1rV#dk
zg#j_s7)+T~1Ze1aH_T!R(+~+)by&+7q9O9=V{otnSL>ryKbE<IT(;`Rnp_4^uA`wJ
z18*y6fGnw%VO_($IzZ#d<K<cjtxkoZE>b-!djmwdT5I;aG_?SU>~T>%(7$T~SF4lg
z2B(DqE13Mcl&*)b4$$ZeJiu<=bW(b8e%QhQnI#SNGQSr4tknl`mNwj%fAuf2^uGuf
zE6aNS<qf{!FS0{5L>Ox7cZIDeyYQvmX(5B6pK{CNsD;xGulTb(K%+0@K>Jpwt#w*o
zmuiW0acezTRA2Yc_?X1gidLr$Om-^-eT*yrzxjFpRQ3DnyF0jAV_0iEw684se$T%4
z@BGjAeutT_b5aarl)uEab=JBA^*5jF{jSw0$`yLR{Dk%Uz1#i&AJTfiSHASImdL7x
z_jl~y&->rHk||81Mf<^%-h@xr;#>X~t>=nZIAgKNu?t=GkIx+TxyyC6=U(;ucJ4i|
zX1Oyyf5x|^^!PtfW(UuTU%7vNW^8=kF8)H^=Ks;7_rgPs)}8pHFZRM;Z2KGL$SR?=
ze-Co)efsVC$M+g}j&lkNGNTv%EBpUPRqsIQz3Te{<{_!M_xbBMYx7?hy*63*pY#3S
z3)a!C@vbi)N>rs!-&Xs0qeR;4a_%E5HJAV9FITAkD$eJ)bz5x2^L^W|GEd$%k7N55
zz1cr@bGm<UU$!s)mehY8x7^+P<}=Ngs}|2H4ClM|JAVFwbcQ;cMkc*>?vMBNS$#gJ
zbS-Poy|gj*&+Dnp@4qhO+r#(A@NLt-!wz<9e;%&iX#FF9^RoqU3m$%bzw!3^tc+);
zt%Eo>L`6;a{c}@|?d(o(X`S`k&2Kz;SLR|^ng3bm^cjba-s6D><_85e{oQOdy`%f8
z$;$iyHoG&Nrk^JGUOha2fz0K9A9sj+xg4ecyN%`FXUnetd)Ol^tc9j+U-IexmK}Nt
z^KU)eZ<=A=qx`nx-tSHCfA7ox#8}U*)W_s^gX?Sm@A9eK2W(v#pGTb6Uhw8r;eWg3
zvX_sWpI+Hu?wQm3-|CIK+4<#jKfIdi%=rDwbZfzV-!2{zv(0svc%S>M*1jVCx$w8P
z5E<4v8$`1nuRmJP>dN@M;^>XMUq%Xd=9ar#FX2C1>-H&AcfmW3j{jzMQa?IaXBF%8
zP7p2d{I>G{o+(|)>3^;kX0Vmqdp`4f<h82VTN8@KLK)SwTdR^y^)4~&SG>cl_Tm0v
zHq|PL@=rxd^DdQbSDv~4M_=EWdg0BdBm9qS4+;F4uk!oKUAxt0_YYUP|EqZaTj%q=
zTNiJyIh6IFSo=ZRE~)>2yZ&8oIX~h1cfSAc?T&icEi2c{_x^9nJnLB4kNmk-p9@<H
z5(J$M_$~Hd-tyqP$J~jV)%n*?Nmz8+n(52E@0Dp2SR~vT)w5cwvQ1}oe~547jCxyq
zFYRHbQE?<2>z@ZqpR^J@6n$p=uW9|hJA9G2>Rh*FbJ@7oH!QDNp1bCIZqF}yM!v{r
zwQrZ(I9E3miWJNWTXEGzbA1&X>z##mPO9r~Z}zc^H(t8=@p+!#br<hn&Jy%|zuSv@
z$?F|YuILo2WmfX^GaZxm+&(Gv(5z!==Z{Cf?>_T;&F6RJ4g!t;{cdxWika--`TzG*
zZ2*^r{C8o6yT!8w6MX+0*UeXcd9C*NTBjMRM%mjpebv~cYS?-6dy~%1<?G6{9?Wjl
z&^UAd&X2RX&uYUe^0`#R|JbZ$GE?3o_OLVHk?4lI{+7o+3nUzOX%POoWtz06P>N8d
ztCe-c2l)rrzx_AR6;PPj@=qgU&yRU!(WbjowU^b~*F<<<D!q68T3Tf8YsN^0k589y
zRm5E@TgX|Ud+Yw*>!Hs1xwZ8xuSg_k-TuZM7g)dFaP3;T^%ehidEbh-uD^t{DC3LH
z>E6s+g`EuA2_C$Hd}}@bm<#>L-zoCzU9?-e^Yo0<r}!@XIs0Ux<ELrw{CEsh!=#d>
z#8nPdKa;;@Rq)i(eCzC{(=+(*?KV37sp`-(cKbP-MPHryyIbi0-yki~n~ZZ_ecigM
z=~Lc5$Gc_67VvBDlbXfDdvX(NktE0K_A}4)(lw%2+`h|v=h#oJ?`+ew3op$1v}@sv
z3!xJuHCAugY1-tLuEwJ_yZOv1oo#pi-+r*7y?=4T;_XgbAO83jD)OP_=aDmvch-pJ
zH|s_9pAx@w(MR-~s6x2eZv)0>^J=2bE?aQ;!+oQbcTOJK#$r>%{x9;am*vMx@ox^c
z@mJ21>IpSg+%_lhMFc}-)w_$==6+v2{YJ3XgA;25-e*14H)RxF->{bb^aAT=T<@bi
zILidpIOnV{aBuj_wEKbI>oetZ9L{e(RL?x&|D8LZIrs0EiJN)%Pj~Oys&xg<4_|P)
zP6^$tIQw$Lch|(X_v7R2vU2vQm$<R!{4M?Yemd)#3-cSKUKmMm7DYUYD&Ue@!Zgoz
zH@CH!Y~tU45zTy$ZmbJ^Va8DZ>igpFv-d<^W}Yn|b?)Hnrdx5J-<*7w+`rJ=N@m)*
zp2ZD|w>j1BFvwkZq+T?N@%oCbMT*lGI>bvwYXnG5aI)f`e3p;Z=KQ=X4EgWo{jWMu
zxqtP{cke@2-;XholX`KmexuvHuE+_GXMc<kKGh^T@65hxL3hUEIjy&RX1uw3nbDpn
z#i24b_(bZ42=)TSMR7^7bF}^(_2JsFf3@sM#Xrwyz0Eiv`~R=k#a!t{oz>yuABs0E
zUQ%|%CE}OB#juiZce^#XERwXZ9Ivyy{>c81#TlWk5uq1SB_;|Uuq=FP694cYbMTDI
z)gkqNtM3=yh?>j(Z+7jHw$JzH^v=@VmBjhlBq3?$+U}!U4jqp)6}}=gZQkYmGnm$?
z`6&L|td(%ZK%jloI!D%+g`%gNrgEJM-;r)5p2l^hw~_sR;j`Oi0{^r(+C9E+7k9Z$
z&h-1y^Vk0AZQH|s<)!R_JlS1ScE)^IDd=Bv`*gy#guR=uneCbED)!-P2$#hL{o}FS
z|2eoSoLcX`;r(<$O#Wj0tqY<bnp&LWrFF#)=RB=aJfr+S_d54;Z&j|p$BdHnZhy(`
zjM>Mvror%g`@}<cTa(w#Fk2COIP&wivSnc_`rqAu`h(w|Z?fX%8OhlU&$l>z5e-YK
zy|K^pu-CVgsNOTB{kL<EWImfM#Jc;TwNk$Hx7qodS*`zP%)gcAYRzQ7e%J0B!ND9C
zs_i59F@G(Z7q((y-@EW#44?W10|F=Ud0WZIy!!T=%duY9VZ8<G9h;EfyS7$zRX^EZ
zv^wsFZk*`7E|rA!(fQNrdmjW`<eNY1PIKat-}7^x+x0Q^UE;dhbE>|jaE3LPThlkm
zV+(^nJZY?L?QM78o_i|1De0=0qEEwrv)8S6i@NeoPj=gGJcFxCexKy5!#}S)`Ih#T
z@88o^qBgxue0*Pa%Kd+MJkjj8K95)i-`Z`W1?{yzq{XC9E>{&0IXzu}TkDVf)p0l0
zPSwa!y=)yPmvL}m^tv@dTU`bAiE0O%sdO>*UEol&P-ClSR5_k<VV*PN;m-{bQcl_r
zWY#vY%dyIwo9DCeNATXG_0po*XR|uPwhK-^yj@1SLS)0zdi||?Z{DeP{VzK2LA?y?
znfqK<tJwZ&|8Gff51%`g;o@ThORqN<uTS~3fywQ@X~c>I7xuZILW?ix><H1*Fux{R
zu(!_3{PjuMyTZ3W9Of?AAn?3$(r$rSPj#6e`S0YKu~+ofp(zeB|3!_ZjpuEylCtL$
ze!thSAVap!_r-2Dy+0p>Z$@&k9TnqBJoIP!`gaF-|IMzhC_Q$dLAKy0+m59Ne_nB6
zwYi(WMCf-|B-c^@g$=VawOhD4z3%>>_^^jp<ilYH3B8%-8N01>!WTGnnDCoBIrQ&a
zVb+wCe8Q0P^ZhDo=gliGZPWfCEhG5lfRD%?QLRhM-+BHKx2U}_bB2uL0S&Gnt>KLN
zy<NvY#`lKsJ2lF+cb<vgVm|kJc9F=&JAKpqBcAQO`MytY+9Ah{0g7js{-51*qwH?y
zOs4M=$8wkJ<g>{!`7CPSp2aM2r)#OSuyBG1>zUhJrI{WkeS24R6kd74C83;B$YpWk
zF#r07yJdfPOQxo#cr9I{{UAZ{jL`qJnh9GvqEBAE`(@AUL>B>twW6z*Z+B7+y?E#C
zfm7QK%G<dp9teNAHbDGtl1#a7?%B<T3tYKx%58Xg$ne*^H4ViL>lr%juQY7xmR%bl
z-m+3Z>_`4K3FmG4J^r?bSl29-*eLp{FHu3~34dC2TUqD*rQ4m>s)_xJzBfxf+2M=D
z8JXuM?D~}pgT>9>7$rq7Joo#@bI0Rp{@Pbq<4<1K{$p<a{`1!}A442^4<4A&dxNX=
zxWR-aEGH(i{?mwNeEwr$)5HD73dw>&fs49lYEQWy%JyBnYNyyQ|76h(ywO_Q!d7_C
zb1k1QwBzCaq>HSIAMW?;<F07bGT6p$E@D0F<JnuY*Or~%ly}Fs;m+Tr#TpOtbB@<0
z?BckwaPdZ`MtQbNi}tKb=$w5}>zq~1{naj74~iDPD|3JR=;)>ilIwlHe#(muJ0PNI
z(H8S{-}~Z6=OezIebAerw9Se4`yXTTyX{%mdhQu=%~&g%Wo!8He$}N9K95~KJT?gA
zyfgEePWa=d3&w^MqZdAV?6hLh^7+@EZkjOl&EuTyx@JuaO<7JfZ?RLzSdciO`^Bdv
ztlC>er@U?!N@$oIwR`_E(|t_OvRZe=#CPtwQ1!k2*tJ{l=J0gLw|7onpU8c;S?L{j
z$b*c1hng4ZX!P+aX<R$>BY&f))<#7y(UL<_7X51`@U0bn)p2{0#A>l;H<|nvF12rF
z`X@K{e?d!V>!Wk6i>;>|Ke%wNT(jYY(iyt$A-6v1<$34Ku9N?l5&7tWw%`)3WoFZ&
z76wT>-CR%{b%@vJ{Mv?zZ?CGigmT}O-|^a7|7pUGGg^_1n?K%<W%QAa`99e|p-$%6
zn;7%%w?~STUzJ6ykexTzJX-g=iutl_cehMQDd*@7FF$Sf-@$I}>YI}}MRFqp4*dST
zaEd|Hd0%5D?o6E<Yi}ENu!P!6Y_sS4W_NnkT${VWzRMfz-JjX3d_J%2x!rA*U92Hb
zorK4R_9F)R26u~m#qv7&q(fKj?<*2ao3Sze@Rn&Sw8H96F)?seXa<%YuTQhCbKkSr
z=)dsa^@$3`C5=iiw$9MmD5{m=n%lA0YS!PGxd%4Bzx$Uzzj^i)<#I_^#?4!tbazhL
zRz6W>yUV8KGgi0Avo+-xeW}>hyZkVdiQ1;9B}=O#SKpj0H7S?dylG|mpDjiAyNxy|
zAGyu-^_f7@D|YcW=l!ln&SFZ-Y~59~bcI^Mu}Pnb)V14Yeh_N)YREn2*pR%>-mC0;
z`i1FX|M%Ydx*&par5VRIr@iwVI)lu=t`om{Xp``nwE_PxiofzZcc|rCZCf(Gop<N~
z?LX~buH1UsTvD&`)SN>_BcW*ZBAeU0o!|cvuDboD^1}8d^RM;3Il19%{lTh-A6ODr
z?8*Et@ZeT??}IzG|5jT&gmKQ9qL|AwZKlWjR;>r3|B9>o{wIHX5~grkzwIT5*n%a6
zetZ2DSvNJAa`y&_6o~(l%{v{z_EL38!^J=5+cggJ*;nVDR=V`RWWH3W{f?A+jk{YS
zlD^ruY;$`0*naa&+nuQg94-DoRk>dOW%qaSsk`r#^)c3;QvZ~xYnGJ$RPF!M#{C7;
zQ<$f&__k0wQCR!`(VSMPb9ZvWRCI67|E2J+dvU|}?M`RiCmr8^cF94lrAbL;s~;~^
z+gNfmA-?_ZANRc3cGIlu&#~}z<?bqKta|vA^T34zJ)BFEIJGx_N}dtD@L%=j8P=BF
z-_+&%AMUr{swmgKGFAJj$G>QAhW5x!0=^9|3TIq-((L-<iNRm*?@G68-mfowut{M1
z)|+y#TRs1jhtKi+lc~pE&$^vyokQf(sUDAas9iDBl?vVxw~Xo8<NenAQyFqZFJ5i1
zoVs`-d$z%f6-R=mI-Pvz@-6MI_u)C$-fo((_R<fBy#@TbUXlNtWna2}W&3yOVQ<0&
zJJVNw=equ`6wEK(6f<3Hk;a4dAAj)AUQ+Oy^TC6C)88;%5-FILI@7Ub=I;W_fO|<Z
z(u<znn#i86&*K~<y{;iYwd%qRyKTlLM}*e4mL-~Akd(eHl%ng{-}-&!?Fpf`z0R$@
zHJ|C1K<wG_bnP~#x`~JD#r|bhcWFFu2tKgiEaEYP%8lJsH<_N4-gfrbQ0}|)oa_SS
zd$+aDUvt&?w1w%EQ(NiAj~BS6o~r*mzwmeL)Y}D9f1e9uy%2Ti)#nd(r90mU9#-m2
z&S)>Ye5|ja_o0n{pvZ@NVJrI9e%N@=hoOB_(c+kY+TV7sI5y)J+eHcH+c7&0kD2_i
z-}GT`|B7qRuSJ{uJ7>!I_wiq*wg12W-XCzs*6NY(8e5-Cp9kevj?HNL!uono%!BD)
z-Z!`X6Wqjn<`LUk@og?G%&LKm*4qvpzm%`u;LPNkr>jsWv&?B>#1Zz&-UOKsX-o%V
zXBA`?v!|R|ELyPkci6%Q2mCA72FSiW_qa@>(7HIlas6kRH4VjgcW|+?@9W5Jz2%f8
znebvE=Y#zM_0mUHF@<T&i(tI|;q?NGaG@!7a_{ujJP)tnida|?#~M>@#+1V$|F%_F
zAyJ~kX`#oehH{gpn_2~?PwZJg&stL5@S|`BSF6%Wrh6B;N;e;nk7Es15<am1L8~yt
zl^&}aUak$;p6}c|S-70l;J~q)Qwx|vSl0yDtYvD8*~%_<@V@u~hSzRY4_RJ>Flviz
z68%tb_>(`1@zTV1{MX}t#O~mn%NedA(mmk{m*|ZwP7#LUC09<K75<_WAFldm-X^C)
zts2oQT%xzK_#T~|D0E<R-xj0W2L+BLYKe5I?m3y+%Jsf|@7V^?wS{H=?=2?>F;3r=
zFUlphrz7xy<)YvZV$9Q)uzc`Zou|1X6k<EKC*$)KelK71%<x~rQsA1MIa6pZXjpC=
zliF6NvlAyPEo1t#eF5i#BBA#T&wfWQ)Dr1h!8PL&m#Mq|smQ|DRzXY^|2T}eeX}m+
zW{Gfx9@vto&=PsGo9D)*W5yO$mk(~?+HtXVb%4!Orepn!qtXt{n#Pdlas4gG@2eWh
zw>hbPywAjZFIKHht%29%K!u7FTalhm?tFGry^x82wu?u9t1PW~Za?MZb<wMZHu1Ci
zM1^?*S4nXFFqQnzD!E~aYQyu&<dx=U+iJNi*5A5kFZ+w_N8f9`pPPM`B=jfSD3$c^
z-6&d-(e4~)<81oIU2ttc`JOxMb-T5fvH1(gmG#W^ZmT`)z-RG)<pYN7pni9o8%`q3
zwO5O+QexG2@7-`T&}`~rzsI3XOzXa{IV8(`Pkl0PYjgF&Kikt~((>H@ADOXj&eWi;
z$xIU5@&(e`8@X@Gd^;yu)OcTYi_==m+%=0;8?xU#Si&r7u+m}oyg!qZYa>@B*Ztq2
zXsV)}5FzyO0DE%B<>LVd=3oAF{|{?q6jOzqxk&ZJX=@s~@7deGnlZblqwJw<(%oZ!
zJbph-`6TbY(2a-nkFw$aN_!FRKkQRCecrL~j@IsJD;mz0F#d}^eP_D6?PcYuk&|vm
z$nV;;*5a^JnA0N>1OJ@EQzNIPhVGxJ5b5OqQHr0TP$uo|`bNHK5ACmcN_y557yQc7
zoD?UM87avWdR+U#q-@sZ{~Vt-3LltuWY$YZ8MY$Pf6;xhGH&v`C&hI=XFi_sLUCTR
zNOAcFrhk<j{}az#TP1A8`EHB5bbDlM+y80Tp6w9TIP_lNt(jcj;X~;sWqx`%iGE-=
z{1ZM|&gs(@&r23(igxia`f0x|lViPe;?tHepVJ!eW98R1?Dw#o9pIlCXQ8q4;ylH@
z-w(!fEL|hu;9KOz9rVmX&#mxQlX6J?2Bto#S#0hcciK))W4>hJQ?2@sTm3`-=inl*
zt0xpzUaM%G%Kyz<a>=d!Wa)!X3~Pl8w34@NUlwD;7<4RAZ2F`94@8eWW(vJ~$l9en
zkEP<H+l_mVcCdZ_c_C~?;7|TLXO2#|q}JYG!nb+97~{7^UZt5_7UG#lXZ1`v-^tz=
zarL)z^g_3-Sr<ay#k5AB{Npawp1DWpL89k^hItHE9+wy$mIw>uYI(fv+D0ymSKezq
zb?$UNv%h5Fvz(<OX34y39LvOxnRK&MWN^8xV*1x+ea?ONapSrJTO15}w{G*gWir)>
z?{kvi0R=|6bY?9tyQ)(jTQ9Q<JXm;a>f>EmEUbUDoMxA5_#L#q+WPzOJ?BFwXUaM*
ziB>)E_+7w;txmbALJt;xUCOi1orm?0;o?Gm?E{<-DkYU>oSt>_&6$wa%S#d!77INn
zbZzK+G9ldQ{vy#*%hts)x@}DV^colraz3c!mMEybyZ8C~OH<AT97~)Q{&;`G=lU3N
zMrY0EvzMrC>Y3B}Rp<JHzR&}L_q8HUepA_g@uKayzg!ZMKQr{*8^ZdSmTh&)U8=UJ
zXGZJSc}oR-cv$~%u71(Cg?IB0iM543PHZ8pKGnaEbDFLTTQRd|_nk!|2JU;^cvyQf
zTVDm`?%ulT(bf~(hYEcSoLY?dHt&-8Z~N)E!t+1{zMmRjb^8|SEice`z|X$jsrRy%
zV2;!?P63Tvy}NOJ_noI2@f?Zm`|oC1>Y#j5QG9iSwI^$sOm9M++&wPSHhx~Q#h<Gy
z63(w;K0a@TqZFG_Y#)QH;#&dEEnzEIZ#<KeiOF@@o5r-y=BUAh>eB%e<}B{KV$pbC
z^Zu{2lqZjyxNe*f%<{j?Wx8imd)stNuk%V85BP7SC)96GbxShJ;BMKOBlo-Wllvvj
z2k(mhsCzK-tF-SC{4J&`8c`V2+`X`2|AP5R)e$ofM@ShsO3bR+TdMxc=(JIBu&40W
zsdb(K2Yx>N@!qhhEJilKx#$G<%KVL!LlTZ&<WOs4`sZnJV>OS(R#(~N*k_5N8#d%H
z2XeRzTw)10mU!*D@_`^fS%H<JS^D2}%_fN$w69ilWXv~saO25}>-SSd{Q2%NE#%^o
zaX)e3fukf_(`CQCAqqtdkLS%cP<|b}U4=C!KjgLXey1as#J+s^bYicvMHfS=#sgC}
znXD(Jf);-*CRy$*mCk><F52`#50}Ku-|g-D*|c}@=fw59n6qkKQJcPCy}xgf^uqj&
zt2Os8Xu0&-LFeqttcAv6${G*EUp?eAOi16xYGle7bNNx*-$S0ebyswT@_9(MbFK|8
za8;Atsk~FuVWFAn%XLPJOnKhuetS~>B4ZhAnZepSjKYE<AEJ*PZ3zDTx^|J*Qr@?(
zWm^4r9i4PY?cD1{8V?jdUGzNFpnTM~k#nnw`OcMV1K1}$@2*(WnH1$Pai!yjhPQ7n
zBq~T>RjubS%1ZO_w)XyTF0#(@cA@i?U=h2Oi!>joS+ncBJZ@q6$33T&tEzjqSAgu%
zEhSB2(^}RSf!bz~Kl`WrvU(Dc%N})bwQYA*gLin^mdr2-8!w3oMts6flEI}y|C(8w
zi=A#M-jr}~*mCyby+`}JJ$MgpaoBUybIX<r>rJ9r9r1PUt7AL+H$P(eP~#q|!4*|z
zrhRC#f`cTR(XlewBZ3L;fd^JjQ;5^PV%M0dsF85<)}yB<!d4`5nOqC2bbDg|L2X6G
zuAR4v-oBopr;sY6wuIrx+_wJ??(5W6?AE->&tMUy{8o3?mt{-U|IT<Gc3}NW^E2my
z#8|@5ZZdq@mVWa6ui#^e+bVYJN%k#hP;^@B`;|FkZ9sI>eeaFyEG`GRTz?uKe88mJ
z{|3tzF^+CggM;>G>y~};;M!r$|KD*@W#6XupqmUy+E)yBF>`F1VtLPUVs4DG#sm2^
z{2gzm=X=yo6ES~duGxO~=klJzQ$+qf;$lir&S(gEI^h-jmW?7G-rY5O<a@fH?6H(1
z<Noy8147rCc=z<mYI<cS?9>%L{Uh*LVvx$?ouVI{P52izOm=<cJ}IN*qiId2xvuI_
zDcjvl|IYlZxe<3UAY4uT=88yGAJ!XB&dd|dl;ChRvYW{?P320)+5koS>ims`-R8Qv
zO#8oF;<7kywy|ZGk?G2U4b79>q}Bg<OSVVOz2~vGo-b9x!)W0%52IyX2TWKl8y)-Z
zt-rS6;-Bk+D|qhh;XgM^%}<dhRVK}SLQj+9M@ufZmlF;(=Xz|(6rLe=_|aLeL++Zr
z2`?UM-!hxWF@I*OvhTEc4BUtMnp*asThgFu=YCj2HmG8Q32V#|`yAzNb8XJ`N>K|p
zeUz^delq3NPsY5w#{vqeGHJcrU+YX<cWal1E~B#MgA}s^6H|QVHe{;p$(+ejc}=B8
z{1R8`(>;qB_?jgSz04Qft;@&gCdGD0ZrQp!6EB};^SY%NDq^y{(9QkQ*^SMsrz)KP
z#VKmAkg=j&{Xpk|nYXv^o-M%w%4D4NhV3g~J4Y|M9JNrbyXjKY!e>2?+6^rqvs7LS
z68XSAo5`$YZ~n*M0$zc}m-oJG{c6ZD!H943!P{Tw-YWmV-h7G6^rq#~txmoR8aS6u
z637oLt94{y{d25rf`-<q2bGMk{(X^fzwDy9Zh^)F#eWxXzTV~?aA4&#28WDgRxXUf
zdfeBVY_bixerR7_EV@KP=*D!zh~*m{V`b!$?l3R!IjmFjXYpqJ+@pQ77Boy2eSIvu
zb(i@ywg)%l{tMo8Z7>uun7(ugr)JZ>cY;rtOT}|USREwUl0KHzepi;`@zM_Q>`jo-
z?AsWgC9vzu^Eq;zS_yprnuQZOjsI<ao++4fawhX)9_G&bF2U3Oscv)fE%j4eH%IYe
z+S~_MpT6j4;S*1Go#Mj!=WT#$YlP69XU9Vh+<6y%4jex(AIs0(o7jDW>&C=$nKBom
z7A^}o&~mz|q2I(X_sPG*N7pyR^FOucVdR^^lF<4|EN6~ZKo?V<u*}?oc`r14L|Esn
z5#(7bn#IKGvqOjDr-vh_=_FrSG5aOkoK&Mb=eh9CHry~XeRE~RDUW%sDy(OoF9~D%
z@&2Nd!1{Tvj7JogZ*{us&Bo9-_k;XP&xLM98^pWMKWb|{u>E8n(;9(U+uUo93M}X7
zGU7ANRh|*Z#2B|(^wqm8VW*-tkr`{0XIYut;|@LG%*C`P)QxYR=iPM;8v`$KZ%I_}
zRA=lgVDP`swN>%rvp6G#Gb<Ofs<n44^J@T&TV&M=G36}$z1(H(ue1NpTJugd;!(-e
zzT(HkIH|31$*y%?IdZ1Q)S0`>eLan5b#*NBYhrqq(Yh<Wm+jT}H5U%7;rwD2%QI1i
z`;>)`Q}g!Zd(!e=OuF3pt+SjMg{yidX6)?Dc*Uae;Cp8or?c#Xzv7k?l8xom8a%ly
zGL>hzG5zlqVXgTWwxarE!-P2tFB&D!sM!8gY*oW|OQ99{vlOaVxP=~=vau^$^RdC@
zbBAPA1RlJMUieJq)}7T2oF^rN5;pZ@yi(Cf=yNmptrtACWd72dX`bDQjQ27XrWDRF
z{oXV;fN}nQ(X6gSg_b8gnO=p`7q4&z9MD-C@I6-Tz|2E=(VV<1M7n#!q8ugJm{xc{
ztM(G)sz^AI=f)h^%PrX+S#aT#1XzpA+JN$FK@aY%+bw<kYgJi}^-5`9hRMegm*ui3
zFXGsscwy6ruoare5|3rJ-YSyMi#x3w!uURCd5h1ByRmV#2@cKOQ{9CREGeAfnf`E^
z(2w^YpL+xykbN1MA<Mo<J>6r=8>LxRCUz%64p_@_uCde)mn^vUv21p9ZqJify|Y~R
zeOa<LK=sSPs-D1@#iFm`SbaRsg)G@?>S|IN@n_0SuB{$>4Oa7XtZvYJJXh<K#hERe
z3tTl4F0Kv8%(8JkZ|hWaEU;#a)uNTokGs!=t=PSoCF6QUE2H$B#Rf+-^mbMXJ@NLx
z#o^Y*bdGb2&K}WK6AEXvgss>leb5CQR&Vc3JsAG=ykvpa;r|Pd+WeYv+`{I>^m$tZ
zdpKC{1ZG55XopBXHdsEVahj`Xli;cb$sU(|(-~i1u+NXa*}*i!gwHrvJA`v?fdBf2
z&b0yEKhn=Vv=`bcc&6_3+4T*TQU|~MS<bMwsd{p1WTN<=L(D7&nKEgYB6k=`AMD6#
z^$LE>d-Q78yg4U5`%Vae<HBZbK)Z9#;lnKF>W;`wp276v`a{QkUzYSH%wb`wITp6U
zxrR&q%*xf8#{)u?XK--MSSp%T7SL3a%vRWc>wf5*!_AAYZdn`Ps_~%9;q;`ag?ve(
z1>M&(O^?o0oxN*$-~kyH4=u-a28s_#&u{H6u9%>2`%*<A^neW44n@reds!7*tfZr~
zuNW>`DZHS;zEkl)=Msn4v9EK#*ZutlcE{#|g<KUX{0?7Q<~!%?6Jl+9c1l%(&1pxb
z)2xdss|0=2Hj8Rap0??XbmDA{MO+D&EY2+HO-T64J9%mM)}~LzdKbA&k6QS2|Mzh1
zWOUegzo>rdO)k^Nl50G^9Gqs6Y!SgQS)|}n*op<e+VakOF1<2g&RWqdUoM$t677)-
z?1i?AzN$O@SFKorLzpp0TCnB3VZsLY7{))ZKRl2*y=8KP!qM5kA6=UwCFFV7p(88i
zn8g{!|AOMiK4%hk#xK!IkaM4D)w6=@My3O6g5>q33wjQ(`B-MVj_IEGDs^6AtC>vi
zj%Yn-b7t($VmZ9N;s4`Xnl?L&ULDhuleu8${&u0=wTF&vwv)Cw^`750MM@~?^HhzF
z>mdJ}Ve&m4Jm-Pk?5EGd55(`-*7Yz_`O~>|>8p~PB&2uW|9U6vfa>pU&pwAf{(fii
zl?ij!h`v%OlkjN&-?6y0GcjSqoj+VZ)NjWnuHsy59QZff>T7A=k~b2esZ$DPc&alB
z=Knk%cHnt_Yn1AO0;eexP53T<nriJCazOsaH?Q-D8+LEW$XsK3z_{Al)S`_+P4fX`
z{`JLfx^8W%4*T*!0dZa_MJDas!Ujp!2X&`)BN#u&&hWhYY;CVjL$TAN_&H4XEae-5
zoQ393i~Rn@<@ZfakqwUn4irvyZP$Jve(da_vQ#VI&hQ*YA1Ss;TLgXnyk50LYLa7L
zuga=IMXnu>U`n?i+0EJ}vRN*VwO~&5*C~ZFl55_IoMCh|x+SvxLC)F$?{x<hw?CT0
z!7Y6?^xpag`%^isr{?L;63Y2t_N{VJ&*7Fgf%`s$|4EANVw!e^>*}O=t|trxrUxxq
zw(-vTNumYED$>>Ln5FhvT#pnj_>&YnNrWXwX?7Pw=GuVPp2IqlYXq0S-+aHQe)`%5
z$zx3_$p?ObGiRo<1jFrjK7GMU6jm0f2|*IYM1g)?r6?{oP!`>9{9a;T_T}I^76~Pc
zK2q(Gsu%n?L%CnNv9JA`@h6t4UQCf|$I<$hJsSkrCmbx=to<PTo$TS8amHzS7W){~
zc$qzKafv><_a=JwtVd!#8|QajcexO?kSp|n-XkZ&h`c)1KND+De_5VzfCcQHmk-M?
za!ycU)z)uk=v-u2SE`!2E%i)mYs)?fo$WQOb5f6%u(9Plo_;6bSfW}k3-hkW`?T3S
zCN&8}`Ca8aHc`yugu#Ti4I7+ItfsAOxbJ?$WR0<!lHmf+fFSR{1F>6lz3Kv2MlU=R
z)vuz(ykw~_C}=dey+5%ftUUjB+U$77`o4|XYbx0Gh#p8@vu{>Q;f&1ag@<<Sd0V(m
zBS;|3%StuTAqiaKRZrThyhJWL;?d-TMW3}F$OnGwoqVo=ljXzvM1?<GGy2yzZtPmP
ztWMRFtL#AS#j79lxi8+@v`pji%Ma}ARa(E<_HEd?Qr6_j(S)7%=Q}daZ(t1ONVsG$
z!ET+iTj5rv<||yLd@?5$m-8}vE^K&zCamtukLQ26ezZSvGf+=Dpu#i*(iHGxVl*qt
z*tujzN9N13$G^65Y}W1HR?ai+_vQy-E7Fq=h=2q2Z0V=NvASZcXZj{SnP5GO$<Kgi
ziBQ^m2|mN!O#dbvb=IE7=sT&1%RS(L=Wm7XfCF=7qVhcXDqU~=<UE$>cj?XDy3@5v
ztY_*DNJxGNWAOi|rY&?VaoO8u9Vf=?MHxF4ET3$-6Vy~V!*9mk<PCSygATm$KKK0R
zmcSP(5e|lz=JOOjc=W76csFbN#ZL}JC!)7qnt6lkhU}kZl6_LUnd(kIS~QQvC_xI8
zft+6N5!vYSwBf*y#4UFwgso6<-7l>1AP{WsAFdzSDNJX)DtTsjFa(1gkfS1ypxQo-
zyUW>5ZgE5Oo~1hcb(e)iKX^}z?Pt8q@gRb0#zy`k<%a)imRs%=T0U`VYn*b(se$LJ
z*z({5LXsc8HGCDUFL%GNI&-%}BqPg<CpMwJMJKp}@-z=xoC&<~It^U(L^Cm+`Q#|X
ze2?qFjJs@_j|~=Ydp*^&Vd|Xar!@I2H;QI870&40Fvs5c&9CksVJp-V4oou^-9DAU
zJ+8d#=DKh-#=a%49-@n8ahN#ovpKZ3L0%`d{>|#Nj@bGM_qjrCm}hx>+_Hi1kv!Wa
z8*xUqJ57tvWgdMxK|SDr=+PiK?*^V}zn^nPEz~nyAbhC7m{G<U)Xtx|O>`9plg?3r
z2QHsne<zC=JUE$^$Z{fK=lN9)H(Ss0vE|e%F)h(Zh<d)%Sond)^OYG~Gp=!&9yOQ{
zBf)4Ckypn0M{~Cnv(&SIGe&HCt}2(sSrtq6Om%Kp;%0CpYz61B#IhwvP97Ec&_9Lc
zMAe<DsBcR0%3P-;lX#gE&)$-W=ZF;ue&|^fILp~@kBv|~qkQ&z2_5s@Om*{@vZgCO
zb4Y43OY?eIxLNUQ)+INCfa%72qYKXXPMD@WZMp*^^RHQLTh2~2ceKch*{J>C{LP~h
z7v9|Nn)=o%TJZ!=`qxWlO^reC7#lx2&s+6iRhs95hU`U4Z9eE3G(WZ5&2(;)&gx~#
zk_PhMpDbH-fBrlvgP9NKO}J5+$$zVvbAy2JEE$iR8A;k#_Hyk|jye@~Yqnh&WBrLs
zi)|(`I!_e-kYf0JZ~3)doGEADNQ!)Tc>S^UrbFHjx{qbI&PtFt;c`tPN!Fo`^^fXq
zG3K^b<_U~zzdPsloczS6l*sYe;IdiM&RW01#zO6b&WguA3Gpy9YCH&=as2$moEpn;
z?JGx%?c|O$c(X7k9XRy+-k)u$cgy0rPZ><u(wm^<lKSz)(IaZs>mue&D4d~c!%^bX
z#@WCA{DOwfJ>R2bni!|Y`g1UEyC;6E`nKP`Q_Fn|y(QacZV}Z|yHMJo=cU(_*_&|6
zS)^d&;h<^lPaGqT>Ft}lPIQ$9TTJ!m29dunexIqBpL*{0n%gDsI361W@8CPMs3CNg
z2j^Mw-s@bZ2Q7SNcP2SZJHfl1sqQ47^SKvg49*p=-`CD|+q-?{$9?j9^^ITK?q~A5
z!{OGz5f{5aX(d;gO1q7NvF5Ltyu0@;@>$;$nWw)|`@!}%4hC`EvlUM74z1gKvSB}G
z!I$Kzxx%1M?jtt?CW#A-LND8YE^=v~bIq<XnsI&9sXf-p|7|BSrQN@)cmIEGG>^qk
zJ>z@Q_D>_9ZR05TBzK#^rcnDz^o-_L$=k(NcwCd1aE&8v!OV>;j}6RqmU>G5kmWtE
zSF6Oz^Xa6-^&KrMR`P;YOdk8a=Cj^ypQeDeMwJ=L+ujJ@P}UIG;NUv@*})r83%MlQ
zcm5Pro0>aQ=kn9iGS)vI6PTX76}X{q?QXf@TjpHG-tXrs=8N8w-ko}s^RdBamUV}3
zUBCYF_R_;*CvLF3^E&x-g1SMn>iO^|q0+U9?#IiEC&x0@pXXy=t^V#%TmoZx-ZjY!
zmG>nlr!LJjKWx!bIHUEho80%(Da*ELGKzoMY3O^!o%7>6HK%VJA7ZOT7bgDcQo47@
z?AV5P;d!ioW_dciw0PfYa<qA>^H0;&y4yY-{Jqg|nWXtsBUeUkk*?I5YAe=1({*n(
zUVgsr|Bbnu4rMRj7?-?lf6%VG2Dwu}b5co?^5^e!q=nX~hQ({o`^~je)c5}PzspJ%
z^DqZ$h-g>XR%&0-ZZzU?Ss0-6`1i}`g>f8UeUDag{n)vHD`H^)YfYrdss>T6n_NG-
z*JYaUK-tUJW$Fa9HEM`-wQ&7t*2|1xz4OvaLu6IM`c)0tvFxo*tC;EnS=VqyEVSUh
zXCJJ6McsWhSH!}Eqy5jbT7TV<08KQl`SB-ZZNPlVDTxZ8Mcp4hYa}dxy&#|?^uYa6
z-^W@HyskTf?6;K&J;2qP!@4H)!p8@oDWXlH8_EuKu^%!JXm#4i^sV~9{Sx0~$M!}I
zkv%_tF6tFHx3r;DqQmK6oBy3Z-~FzKh;DEy3}p}CG?2;ynN$E~TD{-9eHR}Wt8m?(
zU?v;h5|D=O|5F(Jmq9eQo_~+vw7fU`;lG|~HB*>|Ujv6^!rOLvek;D<g%6(W{~q|m
ze|Ms56CZP+hQvp)_WxU?ePmu32(&(8`LkTgViD6dknalqReztqZXIY2&7khzcRi&N
zjY%MmUfrJlllAZ8wkq;im&h!0I@q#a|NSGU*-o3CLH@D%^!@Sf7Z-vg(q35jv^KHc
zkGsD&n9XJ>*wCYPe=4e{v;EJM2@u`jq}ct>Zm)NnxNP4McG>oo0dJ0e-(K$d@mJ(t
z2Q`r9r1_t}|NOiA%a8Y$%~c)QKrU?Rnt$JJ|6aAnd;T+CXlc6j!Z%5ffq{X+)78&q
Iol`;+0JOsY8~^|S

literal 0
HcmV?d00001

diff --git a/WSR/static/scss/components.scss b/WSR/static/scss/components.scss
index ec14160..436f638 100644
--- a/WSR/static/scss/components.scss
+++ b/WSR/static/scss/components.scss
@@ -166,6 +166,7 @@
     flex-direction: column;
     padding: 32px 24px;
     background-color: $white;
+    width: 1076px;
 
     .news-cards {
       display: grid;
diff --git a/WSR/templates/base.html b/WSR/templates/base.html
new file mode 100644
index 0000000..5fd8278
--- /dev/null
+++ b/WSR/templates/base.html
@@ -0,0 +1,74 @@
+{% load static %}
+{% load compress %}
+{% load is_active %}
+
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+    <meta charset="UTF-8">
+    <title>World Series Racing</title>
+    {% compress css %}
+        <link type="text/x-scss" href="{% static 'scss/app.scss' %}" rel="stylesheet" media="screen">
+    {% endcompress %}
+</head>
+<body>
+<header class="container">
+    <a class="logo" href="/">
+        <img src="{% static 'images/WSR.png' %}" alt="Logo WSR">
+    </a>
+    <nav class="navbar">
+        <a class="link {% is_active request 'home' %}" href="{% url 'home' %}">Page d’accueil</a>
+        <a class="link {% is_active request 'races_types' %}" href="{% url 'races_types' %}">Épreuves</a>
+        <a class="link {% is_active request 'vehicles' %}" href="{% url 'vehicles' %}">Nos Véhicules</a>
+        <a class="link {% is_active request 'seasons' %}" href="{% url 'seasons' %}">Anciennes saisons</a>
+    </nav>
+</header>
+
+{% block content %}{% endblock %}
+
+<footer class="container">
+    <div class="row">
+        <div class="col">
+            <div class="logo">
+                <img src="{% static 'images/WSR.png' %}" alt="Logo WSR">
+            </div>
+        </div>
+        <div class="col">
+            <p>Copyright 2023 - World Series Racing ou “WSR” est une marque déposée par Codemasters. <br>Ceci est un
+                projet
+                à titre scolaire.</p>
+        </div>
+        <div class="col">
+            <a href="https://www.codemasters.com/" target="_blank">
+                <img src="{% static 'images/codemastersracing.png' %}" alt="Logo Codemasters" width="128">
+            </a>
+        </div>
+        <div class="col">
+            <p>Juin 2023 - Sofiane LASRI-TRIENPONT<br><a href="/admin">Connexion à l'administration</a></p>
+        </div>
+    </div>
+</footer>
+<script type="text/javascript">
+    // Si le footer n'est pas tout en bas de la page car il y a peu de contenu
+    // On le place tout en bas de la page
+    function footerPosition() {
+        const footer = document.querySelector("footer");
+        const windowHeight = window.innerHeight;
+        const bodyHeight = document.body.offsetHeight;
+
+        if (bodyHeight < windowHeight) {
+            footer.style.position = 'absolute';
+            footer.style.bottom = '0';
+        } else {
+            footer.style.position = 'relative';
+            footer.style.bottom = '0';
+        }
+    }
+
+    footerPosition();
+
+    window.addEventListener('resize', footerPosition);
+</script>
+{% block javascripts %}{% endblock %}
+</body>
+</html>
\ No newline at end of file
diff --git a/WSR/templates/home.html b/WSR/templates/home.html
index 606086c..3fab97a 100644
--- a/WSR/templates/home.html
+++ b/WSR/templates/home.html
@@ -1,40 +1,13 @@
+{% extends 'base.html' %}
 {% load static %}
-{% load compress %}
-
-<!DOCTYPE html>
-<html lang="fr">
-<head>
-    <meta charset="UTF-8">
-    <title>World Series Racing</title>
-    {% compress css %}
-        <link type="text/x-scss" href="{% static 'scss/app.scss' %}" rel="stylesheet" media="screen">
-    {% endcompress %}
-</head>
-<body>
-<header class="container">
-    <a class="logo" href="/">
-        <img src="{% static 'images/WSR.png' %}" alt="Logo WSR">
-    </a>
-    <nav class="navbar">
-        <a class="link active" href="/">Page d’accueil</a>
-        <a class="link" href="#">Épreuves</a>
-        <a class="link" href="#">nos Véhicules</a>
-        <a class="link" href="#">Anciennes saisons</a>
-    </nav>
-</header>
 
+{% block content %}
 <div class="container vitrine">
     <div class="main-frame eurostile">
         <div>
-            {% if race.participation_type == 'invitation' %}
-                <div class="mid">{{ last_race_details.season_name }}</div>
-                <div class="large">{{ last_race_details.race.type_string }} {{ last_race_details.race.name }}</div>
-                <div class="mid">{{ last_race_details.race.location }}, {{ last_race_details.race.circuit }}</div>
-            {% else %}
-                <div class="mid">{{ last_race_details.season_name }}</div>
-                <div class="large">{{ last_race_details.race.location }}</div>
-                <div class="mid">{{ last_race_details.race.circuit }}</div>
-            {% endif %}
+            <div class="mid">{{ last_race_details.season_name }}</div>
+            <div class="large">{{ last_race_details.race.location }}</div>
+            <div class="mid">{{ last_race_details.race.circuit }}</div>
         </div>
         <div class="detail">
             {% for stat in last_race_details.results %}
@@ -84,51 +57,132 @@
     <div class="d-flex">
         <div class="menu flex-grow-1">
             <h4 class="eurostile title">Menu</h4>
-            <a class="link active" href="#">Actualité WSR</a>
-            <a class="link" href="#">Résultats des courses</a>
-            <a class="link" href="#">Participations</a>
+            <a class="link active" href="#" id="news" data-type="changePageContent">Actualité WSR</a>
+            <a class="link" href="#" id="racesResults" data-type="changePageContent">Résultats des courses</a>
+            <a class="link" href="#" id="calendar" data-type="changePageContent">Calendrier</a>
         </div>
-        <div class="content">
-            <h4 class="eurostile title">Actualité WSR</h4>
+        <div class="content" id="pageContent">
+            <div id="newsContainer">
+                <h4 class="eurostile title">Actualité WSR</h4>
 
-            <div class="news-cards">
-                {% for article in six_last_articles %}
-                    <div class="news-card">
-                        <div class="header">
-                            <div class="logo">
-                                <img src="{% static 'images/WSR.png' %}" alt="Logo WSR">
+                <div class="news-cards">
+                    {% for article in six_last_articles %}
+                        <div class="news-card">
+                            <div class="header">
+                                <div class="logo">
+                                    <img src="{% static 'images/WSR.png' %}" alt="Logo WSR">
+                                </div>
+                            </div>
+                            <div class="mt-3">
+                                <div class="eurostile">{{ article.title }}</div>
+                                <div class="desc">{{ article.summary }}</div>
                             </div>
                         </div>
-                        <div class="mt-3">
-                            <div class="eurostile">{{ article.title }}</div>
-                            <div class="desc">{{ article.summary }}</div>
-                        </div>
-                    </div>
+                    {% endfor %}
+                </div>
+                <div class="d-flex justify-content-end">
+                    <a class="btn" href="#">Voir tout</a>
+                </div>
+            </div>
+            <div id="racesResultsContainer" style="display: none;">
+                <h4 class="eurostile title">Résultat des courses</h4>
+                {% for race in three_last_races_results %}
+                    <h5>Saison {{ race.race.season_id }} - {{ race.race.location }}, {{ race.race.circuit }}</h5>
+                    <table class="table">
+                        <thead>
+                        <tr>
+                            <th scope="col">Position de départ</th>
+                            <th scope="col">Position d'arrivée</th>
+                            <th scope="col">Score</th>
+                            <th scope="col">Pilote</th>
+                            <th scope="col">Véhicule</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        {% for result in race.results %}
+                            <tr>
+                                <th>{{ result.starting_position }}</th>
+                                <th scope="row">{{ result.finishing_position }}</th>
+                                <td>{{ result.score }}</td>
+                                <td>{{ result.driver_name }}</td>
+                                <td>{{ result.vehicle_brand }} {{ result.vehicle_model }}</td>
+                            </tr>
+                        {% endfor %}
+                        </tbody>
+                    </table>
                 {% endfor %}
+                <div class="d-flex justify-content-end">
+                    <a class="btn" href="#">Voir tout</a>
+                </div>
             </div>
-            <div class="d-flex justify-content-end">
-                <a class="btn" href="#">Voir tout</a>
+            <div id="calendarContainer" style="display: none;">
+                <h4 class="eurostile title">Calendrier des courses</h4>
+                <p>Nous sommes désolés, mais cet onglet n'est pas encore opérationnel.</p>
             </div>
         </div>
     </div>
 </div>
-<footer class="container">
-    <div class="row">
-        <div class="col">
-            <div class="logo">
-                <img src="{% static 'images/WSR.png' %}" alt="Logo WSR">
-            </div>
-        </div>
-        <div class="col">
-            <p>Copyright 2023 - World Series Racing ou “WSR” est une marque déposée par Codemasters. <br>Ceci est un
-                projet
-                à titre scolaire.</p>
-        </div>
-        <div class="col"></div>
-        <div class="col">
-            <p>Juin 2023 - Sofiane LASRI-TRIENPONT<br><a href="/admin">Connexion à l'administration</a></p>
-        </div>
-    </div>
-</footer>
-</body>
-</html>
\ No newline at end of file
+{% endblock %}
+{% block javascripts %}
+<script type="text/javascript">
+    const links = document.querySelectorAll("[data-type='changePageContent']");
+    const containers = {};
+
+    function hideAllContainers() {
+        for (var container in containers) {
+            containers[container].style.display = 'none';
+        }
+    }
+
+    function showContainer(container) {
+        hideAllContainers();
+        container.style.display = 'block';
+    }
+
+    function setActiveLink(link) {
+        for (var i = 0; i < links.length; i++) {
+            links[i].classList.remove('active');
+        }
+        link.classList.add('active');
+    }
+
+    function getUrlParameter(name) {
+        name = name.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
+        const regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
+        const results = regex.exec(location.search);
+        return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
+    }
+
+    links.forEach(function (link) {
+        link.addEventListener('click', function (event) {
+            event.preventDefault();
+            setActiveLink(link);
+
+            var linkId = link.getAttribute('id');
+            var containerId = linkId + 'Container';
+            var container = document.getElementById(containerId);
+            if (container) {
+                showContainer(container);
+                history.replaceState(null, null, '?content=' + linkId);
+            }
+        });
+    });
+
+    links.forEach(function (link) {
+        const linkId = link.getAttribute('id');
+        const containerId = linkId + 'Container';
+        const container = document.getElementById(containerId);
+        if (container) {
+            containers[containerId] = container;
+        }
+    });
+
+    const contentParam = getUrlParameter('content');
+    if (contentParam !== '') {
+        const targetLink = document.getElementById(contentParam);
+        if (targetLink) {
+            targetLink.click();
+        }
+    }
+</script>
+{% endblock %}
\ No newline at end of file
diff --git a/WSR/templatetags/__init__.py b/WSR/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/WSR/templatetags/is_active.py b/WSR/templatetags/is_active.py
new file mode 100644
index 0000000..819ee40
--- /dev/null
+++ b/WSR/templatetags/is_active.py
@@ -0,0 +1,11 @@
+from django import template
+from django.urls import reverse
+
+register = template.Library()
+
+
+@register.simple_tag
+def is_active(request, url_name):
+    if request.path == reverse(url_name):
+        return 'active'
+    return ''
diff --git a/WSR/views.py b/WSR/views.py
index 2c65714..978f344 100644
--- a/WSR/views.py
+++ b/WSR/views.py
@@ -86,3 +86,18 @@ def home(request):
             "three_last_races_results": three_last_races_results
         }
     )
+
+
+def view_article(request, id):
+    article = Article.objects.get(id)
+    return None
+
+
+def races_types(request):
+    return None
+
+def vehicles(request):
+    return None
+
+def seasons(request):
+    return None
\ No newline at end of file
diff --git a/WSR_website/urls.py b/WSR_website/urls.py
index 78237f0..4779a32 100644
--- a/WSR_website/urls.py
+++ b/WSR_website/urls.py
@@ -23,7 +23,11 @@ from WSR import views
 
 urlpatterns = [
     path('admin/', admin.site.urls),
-    path('', views.home)
+    path('', views.home, name="home"),
+    path('article/<int:id>', views.view_article, name="article"),
+    path('races-types', views.races_types, name="races_types"),
+    path('vehicles', views.vehicles, name="vehicles"),
+    path('seasons', views.seasons, name="seasons")
 ]
 
-urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
\ No newline at end of file
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
-- 
GitLab