diff --git a/lectures/asciidoc/ci.adoc b/lectures/asciidoc/ci.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..b6026c4ae63b65423e16462467d1540152f2a66a
--- /dev/null
+++ b/lectures/asciidoc/ci.adoc
@@ -0,0 +1,231 @@
+= Kontinuerlig integrasjon
+
+link:slides/ci.html[Lysark]
+
+== Smidig utfordring
+
+Smidig utvikling baserer seg på å levere nyttig funksjonalitet ofte, slik at en 1) kan lære mer om hva som er riktig funksjonalitet og 2) får mest mulig verdi fra det som er utviklet. Dette krever at en itererer raskt og leverer nye versjoner ofte, uten at en samtidig ofrer kvalitet. En kan jo ikke sette nye funksjoner i produksjon flere ganger i uka eller om dagen, hvis en ikke er sikker på at det (fortsatt) virker som det skal. 
+
+Dette betyr at både det å sikre kvaliteten underveis og sette nye versjoner i produksjon må koste så lite som mulig. Kvalitetssikring handler mye om testing, men også om måter å sikre at koden har visse kvaliteter som gjør den grei å videreutvikle.
+
+=== Testpyramiden
+
+Testing (ved kjøring av kode) foregår gjerne på flere nivåer. _Enhetstesting_ tester mindre kodeenheter som klasser og metoder isolert fra faktisk bruk i et stor program. Målet er ofte å sjekke korrekthet ved all mulig bruk. _Integrasjonstester_ tester flere moduler og sub-systemer sammen, mer basert på hvordan de er ment å samhandle (bruke hverandre). En tester mer ut fra faktisk bruk, enn all mulig bruk, slik at mengden tester (_mulighetsrommet_) begrenses. _Systemtester_ sjekker at totalsystemet virker som forventet slik det skal kjøre i virkeligheten. En tar gjerne utgangspunkt i _bruksscenarier_ som er identifiser ved design av systemet, slik at bruken blir realistisk. Samtidig skal en jo også sjekke at systemet virker ved unormal og gal bruk, siden det også er realistisk. Noen tester er såkalte _ende til ende_-tester, hvor en simulerer konkret brukerinteraksjon gjennom et UI og ser at alt går rett for seg, f.eks. at databaser oppdateres som de skal og at responsen i UI-et er riktig.
+
+En snakker gjerne om dette som en https://martinfowler.com/articles/practical-test-pyramid.html[testpyramide], fordi mengden tester fra lavere til høyere nivå gjerne går ned fordi det blir uoverkommelig å teste alle mulighetene. Uansett ønsker en å vite at koden som helhet er godt gjennomtestet, altså har høy _testdekningsgrad_ (test coverage). Uavhengig av antall tester er måten en rigger dem på forskjellig. Uten støtte fra testrammeverk og automatisering, vil _kontinuerlig_ testing være ressurskrevende å gjennomføre i praksis.
+
+=== Kodekvalitet
+
+Ved siden av at koden virker, så ønsker en også at kvaliteter som sikrer at den er grei å jobbe med over tid, f.eks. at den er lett å få oversikt over, lese og forstå og modifisere for ulike formål. Dette er kvaliteter som kan sikres ved gjennomlesning, men det er også tidkrevende, og i det er mye å hente om en kan automatisere (deler av) det også, f.eks. sjekke av visse standarder for formatering og koding er fulgt.
+
+== Byggeverktøy og automatisering
+
+Byggeverktøy hjelper en å automatisere mange av de aktivitetene som er nødvendige for å sjekke og sikre kvalitet, og som en uten automatisering ikke ville orket å gjennomføre. Mye er allerede automatisert av moderne IDE-er, f.eks. så kompileres gjerne koden kontinuerig så syntaktiske feil kan angis med røde krøllstreker og koden kan kjøres ved et knappetrykk i stedet for å skrive inn komplekse kommandlinjer i terminalen. Men ut over dette, så bruker en gjerne egne byggeverktøy, bl.a. fordi en ønsker et oppsett som er uavhengig av den enkelte IDE. IDE-en samspiller i stedet med byggeverktøyet, slik at en får det beste av begge verdener. Konfigurasjon gjøres med byggeverktøyet, men IDE-en har gjerne egne editorer for å forenkle jobben og utføre byggekommandoer. 
+
+== Konfigurasjon av byggeverktøy
+
+Konfigurasjon av byggeverktøy er komplekst fordi det er så mange variasjonsmuligheter når en skal kompilere, kjøre enhetstester og bygge hele systemer for alle mulige plattformer (språk og rammeverk). Tilnærmingen er likevel nokså lik, selv om detaljene varierer. F.eks. så bygger alle på informasjon om
+
+* hvordan kode og ressurser er strukturert i mapper
+* hvilke eksterne og interne moduler (kodebibliotek) en er avhengig av (og til hvilket formål)
+* hvilke byggeoppgaver som en ønsker utført (og i hvilke rekkefølge).
+
+For å minimere mengden konfigurasjon så følger en gjerne visse konvensjoner, såkalt https://en.wikipedia.org/wiki/Convention_over_configuration[_convention over configuration_]. For å gjøre det lettere å komme igang finnes ofte _prosjektmaler_ og egne kommandoer for å instansiere disse, altså generere et startoppsett med visse elementer fylt inn spesifikt for anledningen.
+
+Byggeverktøy er avhengig av høy grad av fleksibilitet og utvidbarhet, siden feltet er i rivende utvikling og en er nødt til støtte integrasjon av nye rammeverk og verktøy. Dette gjøres gjerne vha. såkalte _tillegg_ (plug-ins), og mange av standardfunksjonene som kompilering og pakking av filer er ofte realisert som tillegg. Disse krever ytterligere konfigurasjon ut over den generelle informasjonen nevnt over.
+
+== Maven
+
+Det mest modne og utbredte byggeverktøyet for Java-plattformen er https://maven.apache.org[Apache maven], med Googles https://gradle.org[gradle] som en konkurrent i sterk vekst (se https://www.jetbrains.com/lp/devecosystem-2020/java/). Disse har litt ulik terminologi og logikk, men forskjellene er mindre enn en skulle tro ut fra hvor sterke preferanser mange har. Den tydeligste forskjellen er knyttet til at konfigurasjon av gradle tillater bruke av et fullt programmeringsspråk (groovy og i senere tid kotlin), med de fordeler og ulemper det medfører. Her tar vi uansett utgangspunkt i maven, selv om det samme kan gjøres (og nokså likt) med gradle.
+
+=== Standard mappestruktur for kode og ressurser
+
+Med mindre noe annet er konfigurert, krever maven sine standardinnstillinger fire mapper for java (hvis mappen trengs, da):
+
+** *src/main/java* inneholder "produktiv" java-kode
+** *src/main/resources* inneholder _ressurser_, f.eks. *fxml*- og *png*-filer
+** *src/test/java* inneholder testkode
+** *src/test/resources* inneholder ressurser spesifikke for testene, f.eks. datafiler
+
+image::../images/javafx-template-structure.png[width=300]
+
+=== Maven-konfigurasjon med pom.xml
+
+Fila *pom.xml* brukes for å konfigurere bygging med maven og en mappe med en slik fil forteller at mappa inneholder et prosjekt satt opp for å bli bygget med maven. Dersom man står i en slik mappe så kan `mvn`-kommandoen bruke for å utføre ulike byggeoppgaver.
+
+Pom-fila (kortform for *pom.xml*-fila) inneholder ulike xml-blokker med diverse informasjon som styrer byggeoppgavene, f.eks:
+
+** nødvendige biblioteker for kompilering, kjøring og testing
+** versjon og konfigurasjon av maven-tillegg som trengs i bygget
+** konfigurasjon av kompilering (java-versjon) og kjøring (hovedklasse)
+
+Eksemplene under finner du i https://gitlab.stud.idi.ntnu.no/it1901/javafx-template/-/tree/main/javafx-template[javafx-template]-prosjektet på gitlab. I første omgang tar vi utgangspunkt i én-modul-prosjektet *javafx-template*.
+
+==== Avhengigheter
+
+Såkalte _avhengigheter_, f.eks. kode-biblioteker som vårt prosjekt trenger, er angitt i `<dependencies>`-blokka med `<dependency>`-elementer, f.eks. så sier xml-snutten under at koden vår trenger _modulen_ med `artifactId` lik `javafx-controls`, `groupId` lik `org.openjfx` og version lik `16` for å kompilere og kjøre. `groupId`, artifactId og `version` er såkalt _GAV_-koordinater som unikt/globalt identifiserer moduler i maven-økosystemet. Med GAV-koordinatene kan maven spørre et maven-kodelager (repository) lokalt eller på nettet (f.eks. https://mvnrepository.com/repos/central[Maven central]) om den tilsvarende *jar*-fila med den faktiske koden for modulen. Denne kan maven så automatisk laste ned så den kan brukes ved kompilering og kjøring.
+
+[,xml]
+----
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-controls</artifactId>
+            <version>16</version>
+        </dependency>
+----
+
+En kan angi hva slags sammenheng en trenger en avhengighet i med `<scope>`-elementet, f.eks. trenger vi *jupiter*-api-et til testing:
+
+[,xml]
+----
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>5.7.2</version>
+            <scope>test</scope>
+        </dependency>
+----
+
+`<scope>`-elementet kan ha ulike verdier for å angi spesifikk bruk av avhengigheter:
+
+* *compile* (standardverdien) - kompilering (og kjøring) av vanlig kode
+* *test* - kompilering (og kjøring) av testkode
+* *runtime* - trengs ved kjøring, men ikke kompilering
+* *provided* - trengs ved kompilering, men ikke ved kjøring (er implisitt med)
+
+Avhengigheten til *jupiter* krever flere moduler, og siden alle skal ha samme versjon, så kunne vi definert det som en konstant i `<properties>`-blokka og så referert til denne i stedet:
+
+[,xml]
+----
+    <properties>
+        <jupiterVersion>5.7.2</jupiterVersion>
+    </properties>
+    ...
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${jupiterVersion}</version>
+            <scope>test</scope>
+        </dependency>
+----
+
+Her deklareres konstanten *jupiterVersion* med verdien *5.7.2* og i `<version>`-elementet vil referansen `${jupiterVersion}` bli byttet ut med denne verdien. Slike konstanter og referanser kan brukes mange steder for å gjøre pom-koden ryddigere og enklere å endre.
+
+==== Maven-tillegg
+
+Maven-tillegg aktiveres og konfigureres i `<plugins>`-blokka med `<plugin>`-elementer:
+
+[,xml]
+----
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <release>16</release>
+                </configuration>
+            </plugin>
+
+----
+
+Her aktiveres og konfigureres kompilatoren slik at den bruke Java 16 til kompilering og kjøring (den er automatisk aktivert for java-prosjekter, men vi må konfigurere den for en spesifikk java-versjon). Dette plukkes opp av IDE-en, slik at editoren støtter full Java 16-syntaks, inkluder https://www.baeldung.com/java-text-blocks[_tekstblokker_] (java 15) og https://docs.oracle.com/en/java/javase/16/language/records.html[_verdiobjekter_ (records)].
+
+Maven-tillegg identifiseres med samme slags GAV-koordinater som moduler generelt, og en kan tenke på slike tillegg som spesielle moduler som implementerer nye typer byggeoppgaver. Tillegg-modulene lastes ned automatisk når kjøring av `mvn`-kommandoen (se under) krever det. Hvilke koordinater og konfigurasjonselementer en må bruke, må en nesten finne fra eksempler og søk på nettet. *javafx-template*-prosjektet konfigurerer tre tillegg,  *maven-compiler-plugin* for kompilering, *maven-surefire-plugin* for kjøring av tester og *javafx-maven-plugin* for kjøring av javafx-apper. Sistnevnte konfigereres bl.a. med hvilken klasse som er prosjektets app-klasse i `mainClass`-elementet.
+
+=== `mvn`-kommandoen
+
+Med tilleggene over aktivert, så kan en bruke `mvn`-kommandoen for å utføre byggeoppgavene de implementerer:
+
+- `mvn compile` kompilerer koden (som er endret siden sist)
+- `mvn test` kjører alle testene (klassen som identifiseres som testklasser)
+- `mvn javafx:run` kjører javafx-appen
+
+Argumentet til `mvn` er enten en spesifikk byggeoppgave eller en såkalt _fase_, som er maven sitt hovedkonsept for å organisere og sekvensiere byggeoppgaver. Hvert type prosjekt/modul, f.eks. java-prosjekt, har et sett faser med tilhørende oppgaver. F.eks. så utføres byggeoppgaven *compile:compile* (*compile*-oppgaven til kompilator-tillegget) som en del av fasen *compile*. Når en skriver `mvn compile` så betyr det altså implisitt å kjøre kompilatoren. Faser har en implisitt innbyrdes rekkefølge, så hvis en kjører én fase, så kjøres automatisk fasene tidligere i rekken. F.eks. så kjøres fasene *compile* og *test-compile* automatisk før *test*-fasen når en kjører `mvn test`. Se http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html[maven sin side om dette] for detaljene.
+
+Merk at en kan oppgi flere (uavhengige) byggeoppgaver og/eller faser etter hverandre, f.eks. så kjører en ofte tester før en kjører programmet med `mvn test javafx:run`.
+
+`<configuration>`-elementene inni `<plugin>`-deklarasjonen av tilleggene angir diverse verdier som tilleggene bruker når deres byggeoppgaver kjøres, om disse kjøres direkte eller som en del av en fase. Noen ganger er det nyttig å kjøre byggeoppgaver med spesifikke alternative verdier, f.eks. kan en ønske å kjøre én bestemt test(klasse) og ikke alle sammen på en gang, eller kjøre en alternativ app-klasse i stedet for den som er angitt i pom-en. Dette lar seg ofte gjøre ved å angi "-Dkonstant=verdi" som kommandolinjeargument, hvor *konstant* og *verdi* er spesifikk for tillegget og anledningen. (Anførselstegnet brukes for å unngå at spesielle tegn i konstantnavnet og verdien tolkes som noe annen en vanlige tegn.) F.eks. kjører man testklassenn *pack.TestClass* med `mvn test "-Dtest=pack.TestClass"` og app-klassen *pack.AppClass* med `mvn javafx:run "-DmainClass=pack.AppClass"`. Som regel er konstantnavnet det samme som det tilsvarende konfigurasjonselementen.
+
+=== Resultater fra byggingen
+
+Hensikten med hver byggeoppgave er ofte å generere filer, ofte kalt _artifakter_, som er _avledet_ fra filer i prosjektet eller byggeoppgaver kjørt tidligere. F.eks. så er er resulatet fra kompilering *class*-filer og kjøring av tester gir testrapporter. De fleste slike byggeresultater (litt avhengig av konfigureringen) havner i *target*-mappa, f.eks. havner *class*-filene i *target/classes*-mappa (sammen med ressurser fra *process-resources*-fasen). Disse klassene (og ressursene) plukkes opp av *jar:jar*-oppgaven i *package*-fasen og pakkes i en *jar*-fil som også havner i *target*. Til slutt kan *deploy*-fasen brukes til å laste *jar*-filen opp på en server, så den kan lastes ned av andre og evt. settes i produksjon.
+
+En nyttig fase som ofte inkluderes først (eller alene) i en `mvn`-kommando er *clean*. Den fjerner hele *target*-mappa, slik at byggingen starter med "blanke ark". Dette kan gjøre det enklere å finne feil i oppsettet, fordi en da inngår å kjøre byggeoppgaver på "gamle" byggeresultater.
+
+== Modularisering
+
+En ønsker ofte å dele opp et prosjekt i flere _moduler_, slik at hver del er relativt isolert fra og uavhengig av hverandre. Dette gjør delene mer gjenbrukbare og kan gjøre det ryddigere og enklere å koordinere gruppen av utviklere som utviklere prosjektet som helhet. F.eks. kan en ha separate moduler for kjernekoden, brukergrensesnittet og web-tjenesten. Med klare skiller mellom modulene, så sauses de ikke så lett sammen og utviklerne går mindre i beina på hverandre.
+
+Det kan fortsatt være avhengigheter mellom modulene, men disse er eksplisitte, på samme måte som moduler har avhengigheter til biblioteksmoduler skrevet av andre og gjort tilgjengelig på sentrale tjenere. Internt i en virksomhet kan modulene i et prosjekt fungere som bibliotelsmoduler i et annet. Modularisering er et viktig virkemiddel for å begrense kompleksiteten til store systemer.
+
+=== Flér-modul-prosjekter i maven
+
+Maven støtter oppdeling av et stort prosjekt i flere moduler. Hver av modulene blir på en måte selvstendige prosjekter under et felles hovedprosjekt. En flérmodul-variant av *javafx-template*-prosjektet finner du i https://gitlab.stud.idi.ntnu.no/it1901/javafx-template/-/tree/main/modules-template[modules-template]-mappa. Denne mappa utgjør hovedmodulen, med moduler for kjernekode og ui i hver sine undermapper, henholdsvis *core* og *ui*. Merk at en kan ha flere nivåer enn dette, altså undermoduler med moduler under der igjen, men her forholder vi oss til bare to nivåer. For et større eksempel, se https://gitlab.stud.idi.ntnu.no/it1901/todo-list[todo-list].
+
+En hovedmodul angir undermodulene i pom-fila si,  i `<module>`-elementer i `<modules>`-blokka:
+
+[,xml]
+----
+    <modules>
+        <module>core</module>
+        <module>ui</module>
+    </modules>
+----
+
+Undermodulene referere tilbake til hovedmodulen ved å angi GAV-koordinatene i `<parent>`-elementet:
+
+[,xml]
+----
+    <parent>
+        <groupId>it1901</groupId>
+        <artifactId>modules-template</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+----
+
+Undermodulene deklarerer egne *artifactId*-verdier, mens *groupId* og *version* arves fra hovedmodulen. Dermed får hoved- og undermoduler egne GAV-koordinater hvor *groupId*- og *version*-elementene er felles. Disse kan brukes for å angi avhengigheter mellom undermodulene, f.eks. fra ui-modulen til kjernemodulen.
+
+Hovedprosjektet blir mer nyttig ved at pom-fila kan inneholde konstanter, avhengigheter og konfigurasjon av tillegg som er felles for undermodulene og gjøre det lettere å sikre at de bruker de samme konstantverdiene, avhengighetene og tilleggene.
+
+Felles avhengigheter deklareres inni `<dependencyManagement>`-blokka og tillegg inni `<pluginManagement>`-blokka. I undermoduler angir man dem som vanlig, men kan utelate detaljer der deklarasjonene i hovedmodulen duger. I ui-modulen aktiveres f.eks. *maven-compiler-plugin*- og *maven-surefire-plugin*-tilleggene med versjonene og konfigurasjonene angitt i hovedmodulen, og i tillegg deklareres *javafx-maven-plugin*-tillegget, som _ikke_ er nevnt i hovedmodulen:
+
+[,xml]
+----
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+        		<artifactId>maven-surefire-plugin</artifactId>
+	        </plugin>
+            <plugin>
+                <groupId>org.openjfx</groupId>
+                <artifactId>javafx-maven-plugin</artifactId>
+                <version>0.0.6</version>
+                <configuration>
+                    <mainClass>app.App</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+----
+
+=== mvn-kommandoer i flér-modul-prosjekter
+
+`mvn`-kommandoer med faser som argument, f.eks. *clean*, *compile* og *test*, kan utføres i mappa for hovedprosjektet. Fasene blir da utført i underprosjektene i en rekkefølge utledet fra innbyrdes avhengigheter. Hvis f.eks. *ui*-modulen avhenger av *core*-modulen, så vil kommandoen `mvn compile` utført i hovedmodulen gjøre at *compile*-fasen først utføres i *core*-modulen og deretter i *ui*-modulen, siden det ligger i kortene at sistnevnte er avhengig av byggeresultatene fra førstnevnte.
+
+Det er litt verre med kjøring av spesifikke byggeoppgaver, f.eks. *javafx:run*. Det går bare hvis tilsvarende maven-tillegg er aktivert for hovedmodulen og alle undermodulene. Ofte må man angi *-pl*-opsjonen etterfulgt av undermodulen for å begrense kjøringen til den relevante modulen. F.eks. kan man kjøre `mvn -pl ui javafx:run` i mappa for hovedmodulen i stedet for kjøre `cd ui` etterfulgt av `mvn javafx:run`.
+
+== IDE-støtte for maven
+
+De fleste IDE-er gjenkjenner mapper med *pom.xml*-fil som prosjekter konfigurert med maven og kan rette seg litt etter konfigurasjonen, f.eks. for å sikre at (implisitt) kompilering og smarte editorfunksjoner bruker riktig Java-versjon og gi tilgang til pakker og klasser i biblioteker som er deklarert som avhengigheter.
+
+Noen IDE-er går enda lenger og tilbyr editorer for å redigere pom-filer og paneler og dialoger for å utføre utføre byggeoppgaver tilsvarende `mvn`-kommandoer.
+
+== Bygging i gitlab
+
+Gitlab har støtte for å kjøre de samme byggeoppgavene som en kan kjøre lokalt. Ut over å være en ekstra kvalitetssikring, så hjelper det å gjøre oppsettet av prosjektet uavhengig av oppsettet på den enkelt utvikler sin maskin. Det er lett å komme i skade for å gjøre kjøring av byggeoppgaver avhenger av lokalt oppsett, så dette sikrer et _reproduserbart_ bygg.
+
+En fil ved navn *.gitlab-ci.yml* brukes for å angi det felles byggeoppsettet, og når ulike byggeoppgaver skal utføres. F.eks. kan en be om at alle testene kjøres hver gang ny kode innlemmes i hovedgreina til prosjektet.
diff --git a/lectures/asciidoc/images/javafx-template-structure.png b/lectures/asciidoc/images/javafx-template-structure.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2363bd6f2af461d49650c92a4b406e2056104f6
Binary files /dev/null and b/lectures/asciidoc/images/javafx-template-structure.png differ
diff --git a/lectures/asciidoc/index.adoc b/lectures/asciidoc/index.adoc
index ed8db42564ccc0635d8e34bf3fa297d8cdfcf01a..be7c6a8a2754104005b475d7c8fc68c0cfc7c924 100644
--- a/lectures/asciidoc/index.adoc
+++ b/lectures/asciidoc/index.adoc
@@ -6,9 +6,11 @@
 
 link:slides/01-course-intro.html[Lysarkene] gir en oversikt over organiseringen av emnet
 
+link:slides/02-git-plus-plus.html[Lysarkene] gir en oversikt over git, gitlab og gitpod
+
 include::{sourcedir}/gitpod.adoc[leveloffset=+2]
 
-link:slides/02-git-plus-plus.html[Lysarkene] gir en oversikt over git, gitlab og gitpod
+include::{sourcedir}/ci.adoc[leveloffset=+2]
 
 == 2020
 
diff --git a/lectures/build.gradle b/lectures/build.gradle
index e72541051596e8daffd3e73764cace96e94611b4..ff1436ed05aa60b5ecee6b26e05a3bd0b82a12c3 100644
--- a/lectures/build.gradle
+++ b/lectures/build.gradle
@@ -43,7 +43,7 @@ asciidoctorj {
        diagram.version '1.5.16' 
     }
     // useIntermediateWorkDir = true
-    attributes toc: 'left', toclevels: 4,
+    attributes toc: 'left', toclevels: 3,
     	'source-highlighter': 'highlightjs'
 
     /*	
diff --git a/lectures/revealjs/ci.adoc b/lectures/revealjs/ci.adoc
index 75e999ee7f0df8bc9850c672b5a400aa1c59a7bf..4ddd60b095897bce17c52b1136ea93f8c8346fee 100644
--- a/lectures/revealjs/ci.adoc
+++ b/lectures/revealjs/ci.adoc
@@ -7,15 +7,6 @@
 
 include::{includedir}header.adoc[]
 
-== Kontinuerlig integrasjon (CI)
-
-Automatisering av alt som fremmer kvalitet, men som tar tid, f.eks.
-
-* kompilering og bygging av jar-filer (generelt avledete artifakter)
-* kjøring av enhets- og integrasjonstester
-* analyser av ulike typer kvalitet (formatering, kodingsstandarder, vanlige feil, ...)
-* bygging av kjørbart system og kjøring av systemtester
-
 == Smidig utfordring
 
 [.smaller-60]
@@ -30,6 +21,15 @@ Automatisering av alt som fremmer kvalitet, men som tar tid, f.eks.
 ** koden innen teamet - integrasjonstesting
 ** hele systemet - systemtesting (og evt. deployment)
 
+== Kontinuerlig integrasjon (CI)
+
+Automatisering av alt som fremmer kvalitet, men som tar tid, f.eks.
+
+* kompilering og bygging av jar-filer (generelt avledete artifakter)
+* kjøring av enhets- og integrasjonstester
+* analyser av ulike typer kvalitet (formatering, kodingsstandarder, vanlige feil, ...)
+* bygging av kjørbart system og kjøring av systemtester
+
 == Smidig løsning
 
 [.smaller-80]
@@ -54,86 +54,56 @@ Automatisering av alt som fremmer kvalitet, men som tar tid, f.eks.
 == Byggeverktøy forts.
 
 [.smaller-60]
-* to hovedalternativer: *gradle* og *maven*
+* to hovedalternativer for Java er *gradle* og *maven*, andre språk har tilsvarende, f.eks. *yarn* for Javascript og *sbt* for Scala.
 ** litt ulik terminologi og logikk, men forskjellene er tildels overfladiske
 ** begge kan mye det samme, så valget er i stor grad pragmatisk (!)
 ** masse materiale å lære fra, uansett valg
 * *maven*
-** mer modent og strukturert, men også mer krevende og tungvint 
+** mer modent og strukturert, men oppfattes som noe mer krevende og tungvint
+** sekvensierer byggetrinn basert på overordnede _faser_
 * *gradle*
 ** konfigurerbare byggetrinn sekvensieres basert på avhengigheter 
-** konfig.filene (*settings.gradle* og *build.gradle*) er forståelige
 
-== Enkelt prosjektoppsett
+== Maven og pom.xml
 
 [.smaller-60]
-Enkle prosjekter består av én modul og mappe
+* *pom.xml* konfigurerer bygg
+** nødvendige biblioteker for kompilering, kjøring og testing
+** versjon og konfigurasjon av maven-tillegg som trengs i bygget
+** konfigurasjon av kompilering (java-versjon) og kjøring (hovedklasse)
+* standardinnstillingene krever fire mapper for java
+** *src/main/java* inneholder "produktiv" java-kode
+** *src/main/resources* inneholder _ressurser_, f.eks. *fxml*- og *png*-filer
+** *src/test/java* inneholder testkode
+** *src/test/resources* inneholder ressurser spesifikke for testene, f.eks. datafiler
 
-[.smaller-60]
-* *settings.gradle* og *build.gradle* konfigurerer bygg
-* *gradlew*/*gradlew.bat* og *gradle*-mappe må inkluderes
+== https://gitlab.stud.idi.ntnu.no/it1901/javafx-template/-/tree/main/javafx-template[javafx-template]
 
-[.smaller-60]
-Eksempel:
+Eksempel på én-modul-prosjekt i (i https://gitlab.stud.idi.ntnu.no/it1901/javafx-template[javafx-template-kodelageret])
 
 [.smaller-60]
-* desktop-app med javafx og fxml
-* ikke noe behov for gjenbruk av kjernelogikk i andre prosjekter
-
-== simpleexample
-
-[.smaller]
 [.left-60]
-* eksempel på én-modul-prosjekt
-** javafx+fxml-app
-** standard mapper for java
-** gradle-filer
+* avhengigheter til biblioteker for javafx og jupiter (testing)
+* velger spesifikke versjon av en del maven-tillegg
+* Java 16 for kompilering (og kjøring)
+* app.App er hovedklassen for kjøring med maven-tillegget for javafx
 
 [.right]
-image::../images/simpleexample-structure.png[width=300]
-
-== simpleexample forts.
-
-[.smaller]
-* standard innhold i *build.gradle*
-** plugins - tillegg som passer til typen prosjekt, f.eks. 
-** repositories - hvor finnes tillegg og bibliotek (jar-filer)
-** dependencies - hvilke bibliotek brukes og til hva/når
-* tillegg-spesifikk konfigurasjon, f.eks.
-** oppstartsklasse for java
-** javafx-versjon og -moduler som brukes
-
-== simpleexample forts.
-
-* build.gradle *plugins*
-** application - java-app med main-metode, som kan pakkes som kjørbar jar
-** org.openjfx.javafxplugin - javafx-app
-
-[source]
-----
-plugins {
-	id 'application'
-	id 'org.openjfx.javafxplugin' version '0.0.8'
-}
-----
+image::../images/javafx-template-structure.png[width=300]
 
-== Modulært prosjektoppsett
+== https://gitlab.stud.idi.ntnu.no/it1901/javafx-template/-/tree/main/modules-template[modules-template]
 
-[.smaller-60]
-_Flermodul_-prosjekter har delmoduler i undermapper
-
-[.smaller-60]
-* *settings.gradle* i hovedmappa navngir hovedprosjektet og delmodulene
-* *gradlew*/*gradlew.bat* og *gradle*-mappe må inkluderes i hovedmappa
-* delmodulene (i undermappene) trenger (bare) egen *build.gradle*-fil
-
-[.smaller-60]
-Eksempel:
+Eksempel på fler-modul-prosjekt
 
 [.smaller-60]
-* klient-tjener-app
-* (noe) felles kjernelogikk i klient og tjener
-* kan ha flere klienter, f.eks. desktop og mobil (og web)
+[.left-60]
+* to undermapper, *core* og *ui*, med hver sin *pom.xml*
+** core har kode (og tester) for domeneklasser
+** ui har GUI-kode med avhengigheter til JavaFX
+** modulspesifikk konfigurasjon er i respektive *pom.xml*-filer
+* *pom.xml* på toppnivå innholder
+** avhengigheter som er felles for (under)modulene
+** konfigurasjon av tillegg som brukes i (under)modulene
 
 == Modularitet
 
@@ -142,20 +112,21 @@ Eksempel:
 ** moduler er relativt selvstendige enheter
 ** eksplisitte avhengigheter mellom moduler
 ** gjenbrukes på tvers av prosjekter
-* tilsvarer i java et sett pakker
+* i Java tilsvarer en modul et sett pakker
 ** skiller mellom API og interne pakker 
 ** distribueres som jar-fil (zip-fil med meta-data)
 
-== multiexample
+== https://gitlab.stud.idi.ntnu.no/it1901/todo-list/-/tree/master/todolist[todo-list]
 
-[.smaller]
+[.smaller-60]
 [.left-60]
 * eksempel på fler-modul-prosjekt
 ** core - kjernelogikk
-** fx - javafx+fxml-app
-** jaxrs - REST API
-** jersey - web-server-app
-** webreact - web-klient
+** fxutil - hjelpekode for fxui
+** fxui - javafx+fxml-app
+** rest - REST API og server
+** integrationtests - integrasjonstester
+** springboot/restserver - alternativ server
 
 == Avhengigheter
 
@@ -174,45 +145,30 @@ image::../images/maven-central.png[width=300, link="https://mvnrepository.com"]
 
 [.smaller-60]
 * avhengigheter er _eksplisitte_
-** deklareres i *build.gradle* i *dependencies*-seksjonen
-** krever (fullt) navn og versjon (major.minor.micro)
+** deklareres i *pom.xml* i *dependencies*-seksjonen
+** krever navn (groupId og artifactId) og versjon (major.minor.micro)
 ** bibliotek må finnes i deklarerte *repositories*
-* _formålet_ angir når avhengigheten brukes
+* *scope* angir anledningen avhengigheten brukes i
 ** *compile* - kompilering (og kjøring) av vanlig kode
 ** *test* - kompilering (og kjøring) av testkode
-** *implementation* - kjøring (men ikke komp.) av vanlig kode
-** *testImplementation* - kjøring (men ikke komp.) av testkode
-
-== IDE-støtte
-
-* importere gradle-konfigurerte prosjekter
-* basere egen konfigurasjon på gradle sin
-** kildekodemapper
-** avhengigheter
-* utføre gradle-oppgaver, f.eks. kjøre tester
+** *runtime* - trengs ved kjøring, men ikke kompilering
+** *provided* - trengs ved kompilering, men ikke ved kjøring (er implisitt med)
 
-== Eclipse-støtte
+== VSCode-støtte
 
 [.smaller-60]
-[.left-60]
-* *New > Project... > Gradle Project*: opprette nytt java-prosjekt, ferdig oppsatt med fornuftig gradle-konfigurasjon
-* *Import... > Existing Gradle Project*
-* *> Gradle > Refresh Gradle Project*: oppdaterer Eclipse sin prosjektkonfigurasjon fra gradle-konfigurasjonen
+* gjenkjenner automatisk mapper med *pom.xml* som maven-prosjekter
+* konfigurerer editorstøtten og innebygget kompilering deretter
 ** kildekodemapper
 ** avhengigheter
-* paneler
-** *Gradle Tasks*
-** *Gradle Executions*
-
-[.right]
-image::../images/gradle-views.png[width=300]
+* ved større endringer av *pom.xml* og/eller mappestrukturen kan en be VSCode oppdatere sin forståelse av oppsettet
+* har tillegg for å utføre bygge-oppgaver, f.eks. kjøre tester, men like greit å bruke terminalen
 
 == CI @ gitlab
 
-* gitlab kan konfigureres til å bygge, når endrer `push`es til et repo
+* gitlab kan konfigureres til å bygge, når endringer overføres til et kodelager
 * *.gitlab-ci.yml* inneholder byggeinstruksjoner
-* hele repoet sjekkes først ut
+* hele kodelageret klones over i en virtuell maskin
 * så utføres byggeinstruksjoner iht. innstillinger
 
-
-include::{includedir}footer.adoc[]
\ No newline at end of file
+include::{includedir}footer.adoc[]
diff --git a/lectures/revealjs/images/javafx-template-structure.png b/lectures/revealjs/images/javafx-template-structure.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2363bd6f2af461d49650c92a4b406e2056104f6
Binary files /dev/null and b/lectures/revealjs/images/javafx-template-structure.png differ
diff --git a/lectures/revealjs/images/simpleexample-structure.png b/lectures/revealjs/images/simpleexample-structure.png
deleted file mode 100644
index fdf2532cb6abcd865a7dbfc14d2adbeca52e6e4b..0000000000000000000000000000000000000000
Binary files a/lectures/revealjs/images/simpleexample-structure.png and /dev/null differ