Meeskond "Tact": Difference between revisions

From ICO wiki
Jump to navigationJump to search
Jlehtsal (talk | contribs)
Misokk (talk | contribs)
 
(28 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== Teema ==
== Teema ==
Sai valitud näidisteema - kontaktiraamatu teenuse loomine. Antud triviaalne projekt on ainult õppe-eesmärgiga. Kontaktiraamatu teenusesse saab teha igaüks konto ning kasutada CRUD (Create-Read-Update-Delete) meetodeid kontaktide haldamise jaoks. Igal kontaktil on järgmised väljad: ees- ja perenimi, telefon (töö, kodu ja mobiil), email (töö ja kodu), aadress (riik, maakond, asula, tänav, maja nr), Windows Live Messenger, Facebook, Orkut, Skype, Twitteri ja profiilipilt (URLi näol).
Klientrakendus võimaldab importida konktakte Facebookist (hiljem ka Twitterist ning Googlest).
Aja olemasolu korral lisame klientrakendusse HTML5 funktsionaalsust.


==Meeskond==
==Meeskond==
Line 13: Line 17:


[http://gitref.org/ Git-i 101]
[http://gitref.org/ Git-i 101]
== Klientrakendus ==
Klientrakenduse ning teenuse saab alla laadida siit - https://github.com/msokk/Tact/zipball/master
Klientrakenduse API default aadress on localhost:58663 ehk arendusserveri konf.
Klientrakenduse ja teenuse vahelise suhtlemise jaoks implementeerisime teenuses JSONP koos CORSi toega.
Suhtlus toimub jQuery AJAX objekti kaudu.
Kasutatud HTML5 ja CSS3 Tehnoloogiad:
* localStorage - võimaldab brauserisse salvestada võti-väärtus stiilis andmeid (kasutusel andmete cachimisel)
* Session History Management - Uus võimalus Javascriptis navigeerimist teha, ajaloo pinusse saab lisada ka JSON objekte, aadressiribale võib ükskõik millise teksti panna (Kasutusel on brauseritevaheline ühtlustav ja polyfill raamistik - https://github.com/balupton/history.js)
* Gradiendid - koostöös box-shadowi ja border-radiusega on võimalik CSSiga luua piltideta, skaleeruvaid nuppe
* box-shadow
* border-radius
Klientrakendust on võimalik installida ka Chrome Web Appina (extensions management alt vali Load unpacked extension ja vali tactclient kaust)
Esialgne disaini kavand :  http://byte.net.ee/kool/Kursus_2/Poolaasta_2/Vorgurakendused_2/Tact/Design/Login/
== Teenuse kirjeldus ==
'''Meetodid (kantsulud näitavad vabatahtlikke parameetreid):
'''
*''EemaldaKontakt( int id )'' - Kontakti kustutamine, vajab kontakti ID-d.
*''KuvaKasutaja()'' - Kuvab kasutaja andmeid (va parool).
*''KuvaKontakt( [int kontaktID, {kõik kontakti parameetrid}] )'' - Parameetrite puudumisel kuvab kõik kasutaja kontaktid, võimaldab teha otsingut läbi erinevate parameetrite osalise lisamise näol. Nt eesnimi = "Ma" - otsib kõiki kontakte, kelle eesnimi algab "Ma".
*''LisaKontakt( {kõik kontakti parameetrid} )'' - Meetod kontakti loomiseks. Kasutaja saab lisada kontaktile: ees- ja perenime, telefoni (töö, kodu ja mobiil), emaili (töö ja kodu), aadressi (riik, maakond, asula, tänav, maja nr), Windows Live Messengeri, Facebooki, Orkuti, Skype, Twitteri ja pildi URLi kontaktist.
*''LogiSisse( string kasutajanimi, string parool, string apiKey )'' - Meetod kasutajale sisse logimiseks. Sisselogimisel luuakse küpsisepõhine sessioon, paroolid on andmebaasis räsi kujul, kontrollitakse apiKey valiidsust ning võimalikku apiKey-ga seotud päringu algataja domeeni (saab piirata päringud veebiteenusele teatud domeeni peale).
*''LogiValja()'' - Meetod kasutaja välja logimiseks. Väljalogimisel sessioon hävitatakse.
*''LooKasutaja( string eesnimi, string perenimi, string kasutajanimi, string parool[, string fbID] )'' - Meetod kasutaja loomiseks. Kasutaja käest küsitakse eesnime, perenime, kasutajanime, parooli ja Facebooki ID-d.
*''MuudaKasutaja( {kõik kasutaja parameetrid} )'' - Meetod kasutaja andmete muutmiseks.
*''MuudaKontakt( {kõik kontakti parameetrid} )'' - Meetod kontakti muutmiseks.
'''Turvalisus''': Kõik meetodid peale kasutaja loomise nõuavad autenditud sessiooni. Produktsioonis oleval süsteemil peavad kõik päringud käima üle SSL ühenduse. Paroolid säilitatakse süsteemis SHA-256 räside näol
==Meeskonna lõpparuanne==
Võrgurakendused 2 aine raames valmis meie meeskonnal kontaktihaldustarkvara. Esmalt mõtlesime välja andmemudeli ja panime XMLis kirja millises formaadis hakkab meie teenus rakendusega suhtlema. Tõsi küll, see formaat muutus veidi töö käigus - eriti just andmete ''wrapperis'' ning tähtede tõusutundlikuses. Antud muudatused olid tingitud ASP.NET veebiteenuste ''automagic''-ust.
Tegime ASP.NETis valmis veebiteenuse ja seejärel rakenduse enda. Kasutasime HTML5 ja CSS3 tehnoloogiaid et rakendust interaktiivsemaks muuta. Päringud toimuvad läbi AJAXi, seega ei toimu iga nupuvajutuse järel lehe uuesti laadimist. Veel peaks ära märkima, et rakendus on seotud Facebookiga. Seega on võimalik viimasest kontakte mugavalt rakendusega sünkroniseerida.
'''Mida oleks võinud (paremini) teha?'''
* API Haldus
* API Logimine
* Rohkem integratsioone - Twitter, Google, jne.
'''Punktijaotus'''
* Martin Lensment - 18p
* Mihkel Sokk - 24p
* Jaak Lehtsalu - 18p


==XML Failid==
==XML Failid==
Line 310: Line 379:
=== 18. Veebruar ===
=== 18. Veebruar ===
Projekti draft areneb
Projekti draft areneb
=== 04. Aprill ===
Githubi repo ülesseadmine, esialgse veebiteenuse loomine (Hello World)


=== 15. Aprill ===
=== 15. Aprill ===
Kõikide liikmete arvutite tööks valmisseadmine, tööplaanide paberile üles kirjutamine (meetodid ja värgid, kuidas miski toimib)
Kõikide liikmete arvutite tööks valmisseadmine (Giti ja Visual Studio masinatesse installeerimine), tööplaanide paberile üles kirjutamine (meetodid ja värgid, kuidas miski toimib), andmebaasimudeli loomine (nii paberil kui ka spetsiaalsel tarkvaral).


=== 16. Aprill ===
=== 16. Aprill ===
Paduprogemine kakao ja puljongi saatel. Esimesed suuremad probleemid (Seoses Visual Studio ja vajaminema programmeerimiskeelega). Üheks suuremaks probleemiks oli ka autentimine. Peavalu valmistas ka sobiva XMLi saamine.
Paduprogemine kakao ja puljongi saatel. Esimesed suuremad probleemid (Seoses Visual Studio ja vajamineva programmeerimiskeelega). Üheks suuremaks probleemiks oli ka autentimine. Peavalu valmistas ka sobiva XMLi saamine.
Muidu päev algas andmebaasi ülesseadmisest. Hiljem tulid meetodid ja programm ise. Nii umbes 23 paiku õhtul sai süsteemi ikka mingit moodi jooksma. Toimib kasutajate lisamine (vajab veel täiendamist), kasutaja muutmine, kontakti lisamine, sisselogimine, väljalogimine.
Muidu päev algas andmebaasi ülesseadmisest. Hiljem tulid meetodid ja programm ise. Nii umbes 23 paiku õhtul sai süsteemi ikka mingit moodi jooksma. Toimib kasutajate lisamine (vajab veel täiendamist), kasutaja muutmine, kontakti lisamine, sisselogimine, väljalogimine.


=== 17. Aprill ===
=== 17. Aprill ===
Lisatud kontaktide otsimine, kasutaja kuvamine ja teiste pisivigade kõrvaldamine.
Viimane päev enne tähtaega. Teenus peaaegu valmis.
Kasutajate lisamine täiustatud (väljade valideerimine), "kontaktide kuvamise" ja "muuda kontakti" päringud korda tehtud.
Host name põhine piirang olemas, kontaktide otsimine korras.
 
=== 5. Mai ===
Wiki täiendatud
 
 
 
 
[[Category: Võrgurakendused II: hajussüsteemide ehitamine]]
[[Category: Võrgurakendused II: hajussüsteemide ehitamine]]

Latest revision as of 12:44, 6 June 2011

Teema

Sai valitud näidisteema - kontaktiraamatu teenuse loomine. Antud triviaalne projekt on ainult õppe-eesmärgiga. Kontaktiraamatu teenusesse saab teha igaüks konto ning kasutada CRUD (Create-Read-Update-Delete) meetodeid kontaktide haldamise jaoks. Igal kontaktil on järgmised väljad: ees- ja perenimi, telefon (töö, kodu ja mobiil), email (töö ja kodu), aadress (riik, maakond, asula, tänav, maja nr), Windows Live Messenger, Facebook, Orkut, Skype, Twitteri ja profiilipilt (URLi näol).

Klientrakendus võimaldab importida konktakte Facebookist (hiljem ka Twitterist ning Googlest). Aja olemasolu korral lisame klientrakendusse HTML5 funktsionaalsust.

Meeskond

  • Mihkel Sokk
  • Jaak Lehtsalu
  • Martin Lensment

Keskkonna Setup

  1. Installi Visual Studio ASP.NET toega
  2. Loo GitHubi konto - https://github.com
  3. Hangi Git - http://help.github.com/win-set-up-git/
  4. Klooni repo aadressilt - https://github.com/msokk/Tact

Git-i 101

Klientrakendus

Klientrakenduse ning teenuse saab alla laadida siit - https://github.com/msokk/Tact/zipball/master

Klientrakenduse API default aadress on localhost:58663 ehk arendusserveri konf.

Klientrakenduse ja teenuse vahelise suhtlemise jaoks implementeerisime teenuses JSONP koos CORSi toega. Suhtlus toimub jQuery AJAX objekti kaudu.

Kasutatud HTML5 ja CSS3 Tehnoloogiad:

  • localStorage - võimaldab brauserisse salvestada võti-väärtus stiilis andmeid (kasutusel andmete cachimisel)
  • Session History Management - Uus võimalus Javascriptis navigeerimist teha, ajaloo pinusse saab lisada ka JSON objekte, aadressiribale võib ükskõik millise teksti panna (Kasutusel on brauseritevaheline ühtlustav ja polyfill raamistik - https://github.com/balupton/history.js)
  • Gradiendid - koostöös box-shadowi ja border-radiusega on võimalik CSSiga luua piltideta, skaleeruvaid nuppe
  • box-shadow
  • border-radius

Klientrakendust on võimalik installida ka Chrome Web Appina (extensions management alt vali Load unpacked extension ja vali tactclient kaust)

Esialgne disaini kavand : http://byte.net.ee/kool/Kursus_2/Poolaasta_2/Vorgurakendused_2/Tact/Design/Login/

Teenuse kirjeldus

Meetodid (kantsulud näitavad vabatahtlikke parameetreid):

  • EemaldaKontakt( int id ) - Kontakti kustutamine, vajab kontakti ID-d.
  • KuvaKasutaja() - Kuvab kasutaja andmeid (va parool).
  • KuvaKontakt( [int kontaktID, {kõik kontakti parameetrid}] ) - Parameetrite puudumisel kuvab kõik kasutaja kontaktid, võimaldab teha otsingut läbi erinevate parameetrite osalise lisamise näol. Nt eesnimi = "Ma" - otsib kõiki kontakte, kelle eesnimi algab "Ma".
  • LisaKontakt( {kõik kontakti parameetrid} ) - Meetod kontakti loomiseks. Kasutaja saab lisada kontaktile: ees- ja perenime, telefoni (töö, kodu ja mobiil), emaili (töö ja kodu), aadressi (riik, maakond, asula, tänav, maja nr), Windows Live Messengeri, Facebooki, Orkuti, Skype, Twitteri ja pildi URLi kontaktist.
  • LogiSisse( string kasutajanimi, string parool, string apiKey ) - Meetod kasutajale sisse logimiseks. Sisselogimisel luuakse küpsisepõhine sessioon, paroolid on andmebaasis räsi kujul, kontrollitakse apiKey valiidsust ning võimalikku apiKey-ga seotud päringu algataja domeeni (saab piirata päringud veebiteenusele teatud domeeni peale).
  • LogiValja() - Meetod kasutaja välja logimiseks. Väljalogimisel sessioon hävitatakse.
  • LooKasutaja( string eesnimi, string perenimi, string kasutajanimi, string parool[, string fbID] ) - Meetod kasutaja loomiseks. Kasutaja käest küsitakse eesnime, perenime, kasutajanime, parooli ja Facebooki ID-d.
  • MuudaKasutaja( {kõik kasutaja parameetrid} ) - Meetod kasutaja andmete muutmiseks.
  • MuudaKontakt( {kõik kontakti parameetrid} ) - Meetod kontakti muutmiseks.


Turvalisus: Kõik meetodid peale kasutaja loomise nõuavad autenditud sessiooni. Produktsioonis oleval süsteemil peavad kõik päringud käima üle SSL ühenduse. Paroolid säilitatakse süsteemis SHA-256 räside näol

Meeskonna lõpparuanne

Võrgurakendused 2 aine raames valmis meie meeskonnal kontaktihaldustarkvara. Esmalt mõtlesime välja andmemudeli ja panime XMLis kirja millises formaadis hakkab meie teenus rakendusega suhtlema. Tõsi küll, see formaat muutus veidi töö käigus - eriti just andmete wrapperis ning tähtede tõusutundlikuses. Antud muudatused olid tingitud ASP.NET veebiteenuste automagic-ust.

Tegime ASP.NETis valmis veebiteenuse ja seejärel rakenduse enda. Kasutasime HTML5 ja CSS3 tehnoloogiaid et rakendust interaktiivsemaks muuta. Päringud toimuvad läbi AJAXi, seega ei toimu iga nupuvajutuse järel lehe uuesti laadimist. Veel peaks ära märkima, et rakendus on seotud Facebookiga. Seega on võimalik viimasest kontakte mugavalt rakendusega sünkroniseerida.

Mida oleks võinud (paremini) teha?

  • API Haldus
  • API Logimine
  • Rohkem integratsioone - Twitter, Google, jne.


Punktijaotus

  • Martin Lensment - 18p
  • Mihkel Sokk - 24p
  • Jaak Lehtsalu - 18p

XML Failid

XML

<?xml version="1.0" encoding="utf-8"?>
<kontaktid>
  <kontakt>
    <nimi>
      <eesnimi>Jaan</eesnimi>
      <perenimi>Igamees</perenimi>
    </nimi>
    <epost tyyp="too">jaantoo@gmail.com</epost>
    <epost tyyp="kodu">jaankodu@gmail.com</epost>
    <telefon tyyp="mobiil" peamine="true">5500000</telefon>
    <telefon tyyp="tavaline">5000000</telefon>
    <aadress>
      <nr>4c</nr>
      <tanav>Raja</tanav>
      <asula>Tallinn</asula>
      <maakond>Harjumaa</maakond>
      <riik>Eesti</riik>
      <indeks>67890</indeks>
    </aadress>
    <sotsiaalne>
      <wlm>jaan@hotmail.com</wlm>
      <facebook>http://facebook.com/37289</facebook>
      <orkut>http://orkut.com/3289783</orkut>
      <skype>jIgamees</skype>
      <twitter>http://twitter.com/jIgamees</twitter>
    </sotsiaalne>
    <pilt>http://profile.ak.fbcdn.net/hprofile-ak-snc4/41629_100000310305025_2955_q.jpg</pilt>
  </kontakt>
  <kontakt>
    <nimi>
      <eesnimi>Oskar</eesnimi>
      <perenimi>Okas</perenimi>
    </nimi>
    <epost tyyp="too">oskartoos@gmail.com</epost>
    <epost tyyp="kodu">oskarkody@gmail.com</epost>
    <telefon tyyp="mobiil" peamine="true">53456545</telefon>
    <telefon tyyp="tavaline">52433000</telefon>
    <aadress>
      <nr>34-2</nr>
      <tanav>Tihase</tanav>
      <asula>Tallinn</asula>
      <maakond>Harjumaa</maakond>
      <riik>Eesti</riik>
      <indeks>34563</indeks>
    </aadress>
    <sotsiaalne>
      <wlm>oskar@hotmail.com</wlm>
      <facebook>http://facebook.com/3242324</facebook>
      <orkut>http://orkut.com/455445</orkut>
      <skype>oOkas</skype>
      <twitter>http://twitter.com/ookas</twitter>
    </sotsiaalne>
    <pilt>http://profile.ak.fbcdn.net/hprofile-ak-snc4/41629_100000310305025_2955_q.jpg</pilt>
  </kontakt>
</kontaktid>

XML Schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="kontaktid">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="kontakt">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="nimi">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="eesnimi" type="xs:string" />
                    <xs:element name="perenimi" type="xs:string" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element maxOccurs="unbounded" name="epost">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="tyyp" type="xs:string" use="required" />
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element maxOccurs="unbounded" name="telefon">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:unsignedInt">
                      <xs:attribute name="tyyp" type="xs:string" use="required" />
                      <xs:attribute name="peamine" type="xs:boolean" use="optional" />
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="aadress">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="nr" type="xs:string" />
                    <xs:element name="tanav" type="xs:string" />
                    <xs:element name="asula" type="xs:string" />
                    <xs:element name="maakond" type="xs:string" />
                    <xs:element name="riik" type="xs:string" />
                    <xs:element name="indeks" type="xs:unsignedInt" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="sotsiaalne">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="wlm" type="xs:string" />
                    <xs:element name="facebook" type="xs:string" />
                    <xs:element name="orkut" type="xs:string" />
                    <xs:element name="skype" type="xs:string" />
                    <xs:element name="twitter" type="xs:string" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="pilt" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <head>
        <style>
          body{
            font-family: Arial, Verdana;
          }

          h1{
            color: #19212b;
          }

          table{
            font-size: 12px;
            border-collapse: collapse;
          }

          .mainTable{
            border: 1px solid grey;
          }

          .mainTable th{
            padding: 3px;
            border: 1px solid grey;
            background: #ccdaed;
          }

          .mainTable td{
            border: 1px solid grey;
            text-align: center;
            padding: 3px;
          }

          .socialTable{
            border: 0;
          }

          .socialTable td{
            border: 0;
            text-align: left;
            padding: 2px;
          }
        </style>
      </head>
      <body>
        <h1>Kontaktid</h1>
        <table class="mainTable">
          <tr>
            <th>Profiilipilt</th>
            <th>Eesnimi</th>
            <th>Perekonnanimi</th>
            <th>E-Post (töine)</th>
            <th>E-Post (kodune)</th>
            <th>Mobiil</th>
            <th>Lauatelefon</th>
            <th>Aadress</th>
            <th>Sotsiaalvõrgustikud</th>
          </tr>
          <xsl:for-each select="kontaktid/kontakt">
            <tr>
              <td>
                <img>
                  <xsl:attribute name="src">
                    <xsl:value-of select="pilt" />
                  </xsl:attribute>
                </img>
              </td>
              <td>
                <xsl:value-of select="nimi/eesnimi"/>
              </td>
              <td>
                <xsl:value-of select="nimi/perenimi"/>
              </td>
              <td>
                <xsl:value-of select="epost[@tyyp='too']"/>
              </td>
              <td>
                <xsl:value-of select="epost[@tyyp='kodu']"/>
              </td>
              <td>
                <xsl:value-of select="telefon[@tyyp='mobiil']"/>
              </td>
              <td>
                <xsl:value-of select="telefon[@tyyp='tavaline']"/>
              </td>
              <td>
                <xsl:value-of select="aadress/tanav"/>
                <xsl:text> </xsl:text>
                <xsl:value-of select="aadress/nr"/>,
                <xsl:value-of select="aadress/asula"/>,
                <xsl:value-of select="aadress/maakond"/>,
                <xsl:value-of select="aadress/riik"/>
              </td>
              <td>
                <table class="socialTable">
                  <tr>
                    <td>Messenger: </td>
                    <td>
                      <xsl:value-of select="sotsiaalne/wlm"/>
                    </td>
                  </tr>
                  <tr>
                    <td>Facebook: </td>
                    <td>
                      <xsl:value-of select="sotsiaalne/facebook"/>
                    </td>
                  </tr>
                  <tr>
                    <td>Orkut: </td>
                    <td>
                      <xsl:value-of select="sotsiaalne/orkut"/>
                    </td>
                  </tr>
                  <tr>
                    <td>Skype: </td>
                    <td>
                      <xsl:value-of select="sotsiaalne/skype"/>
                    </td>
                  </tr>
                  <tr>
                    <td>Twitter: </td>
                    <td>
                      <xsl:value-of select="sotsiaalne/twitter"/>
                    </td>
                  </tr>
                </table>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>


XSLT tulemus

Materjalid

http://facebooksdk.codeplex.com/

http://code.google.com/p/google-gdata/

http://linqtotwitter.codeplex.com/

http://code.google.com/p/sqlite-net/

http://msdn.microsoft.com/en-us/library/7hs6sw69.aspx

Logi

22. Veebruar

Algne XML, Schema ja XSLT leht valmis

18. Veebruar

Projekti draft areneb

04. Aprill

Githubi repo ülesseadmine, esialgse veebiteenuse loomine (Hello World)

15. Aprill

Kõikide liikmete arvutite tööks valmisseadmine (Giti ja Visual Studio masinatesse installeerimine), tööplaanide paberile üles kirjutamine (meetodid ja värgid, kuidas miski toimib), andmebaasimudeli loomine (nii paberil kui ka spetsiaalsel tarkvaral).

16. Aprill

Paduprogemine kakao ja puljongi saatel. Esimesed suuremad probleemid (Seoses Visual Studio ja vajamineva programmeerimiskeelega). Üheks suuremaks probleemiks oli ka autentimine. Peavalu valmistas ka sobiva XMLi saamine. Muidu päev algas andmebaasi ülesseadmisest. Hiljem tulid meetodid ja programm ise. Nii umbes 23 paiku õhtul sai süsteemi ikka mingit moodi jooksma. Toimib kasutajate lisamine (vajab veel täiendamist), kasutaja muutmine, kontakti lisamine, sisselogimine, väljalogimine.

17. Aprill

Viimane päev enne tähtaega. Teenus peaaegu valmis. Kasutajate lisamine täiustatud (väljade valideerimine), "kontaktide kuvamise" ja "muuda kontakti" päringud korda tehtud. Host name põhine piirang olemas, kontaktide otsimine korras.

5. Mai

Wiki täiendatud