---
marp: true
theme: ocideck
paginate: true
title: Proefpresentatie
author: Brenno de Winter
organization: Stichting LibreKAT
version: 0.1
date: 30 juni 2026
description: Dit is een korte demonstratie van de mogelijkheden van deze versie van Ocideck met de belangrijkste features in een presentatie
keywords: Ocideck, demonistratie
ocideck_format: 1
---

<!-- _class: title no-logo -->

![bg 100%](images/pasted_1782730259151.png)
<!-- ocideck_title_image_overlay: false -->

# OciDeck: presentaties met inhoud
<!-- ocideck_title_text_color: #111827 -->

---

<!-- _class: split logo-safe -->

<!-- _style: --image-width: 55%; --split-text-scale: 1.55; -->

<div class="split-text" style="font-size: 1.55em">

# Een demonstratie
<!-- ocideck_bullet_marker: dot -->

- Van slides met bullets
- Afbeeldingen
- Video's
- Grafieken en tijdlijnen
- Checklists
- Broncode
- Interactieve vragen
- Tabellen

</div>

<div class="split-image">

![](images/pasted_1782807831131.png)

</div>

---

<!-- _class: split logo-safe -->

<!-- _style: --image-width: 35%; --split-text-scale: 1.55; -->

<div class="split-text" style="font-size: 1.55em">

# Ocideck (pootjes in plaats van bullets)
<!-- ocideck_bullet_marker: paw -->

- Presentaties met structuur
- De informatie staat centraal
- Extra mogelijkheden
  - Grotere teksten over meerdere slides verdelen
  - Video's opknippen in meerdere slides
  - Gebruikersnotities naast de sprekersnotities
  - Checklists aflopen
  - Slidekwaliteit bewaken

</div>

<div class="split-image">

![](images/pasted_1782731654371.png)

</div>

---

<!-- _class: split logo-safe -->

<!-- _style: --image-width: 40%; --split-text-scale: 3.50; -->

<div class="split-text" style="font-size: 3.50em">

# Verkeerde opmaak? Ocideck fixt hem
<!-- ocideck_bullet_marker: dot -->

- Van scan naar verhaal
- Evidence-first compliance
- Levende rapportage
- Traceerbaarheid
- Bestuurlijke taal boven technische ruis

</div>

<div class="split-image">

![](images/pasted_1785138624730.png)

</div>

---

<!-- _class: split logo-safe -->

<!-- _style: --image-width: 40%; --split-text-scale: 3.50; -->

<div class="split-text" style="font-size: 3.50em">

# Dit is een hele volle slide
<!-- ocideck_continue_split: true -->

- Structured slide editors — dedicated editors per slide type: title, bullets, two-column bullets, bullets + image, single/two images, quote, table, section divider, image-only, video, audio, source code, charts, cockpit dashboards, interactive question (quiz) slides, animated timelines, and free-form Markdown.
- Source-code slides — a "code sheet" with per-language syntax highlighting, stored as a fenced code block.
- Background, text colour and monospace font come from the style profile, with an optional syntax-colouring toggle (turn it off for a single-colour, CRT-terminal look).
- The code auto-sizes to fill the panel.
- Charts — bar, horizontal bar, stacked bar, combo (bars + a line on a second axis), line, area, pie, donut, spider/radar, scatter, waterfall, and heatmap (doubles as a likelihood × impact risk matrix) charts rendered natively (preview, presenter, PDF, PPTX) and as self-contained SVG in the HTML export.
- Data is entered in an in-app grid or imported from CSV; the spec is stored as JSON in the Markdown, with optional linking to a CSV kept in a tidy data/ directory.
- Optional min/max draw reference lines (bar/line/area/combo/waterfall) or fix the scale (radar); legend hover highlights a series, and line tooltips pick the dot under the cursor.
- Question slides (interactive quiz) — multiple choice, true/false, multiple-correct, or ordering questions (tap the shuffled options into the right order), with the kind chosen in the editor.
- The answer pool is unlimited; a configurable number of options (default 4) is drawn at random each run.
- Optional answer-time countdown, an on-wrong policy (retry until correct, or reveal-and-continue), and an optional image with a pan-and-zoom detail view.
- Presenting blocks advancing until answered correctly; the audience window is interactive and stays in sync.
- The spec round-trips as a JSON block; answer state is session-only.
- Timeline slides — turn a list of dated events into an animated timeline: a glowing accent spine with nodes and cards that alternate above/below (horizontal) or left/right (vertical), styled from the active profile.
- Layout is automatic (horizontal for short timelines, vertical for longer ones) or forced; animation is draw-in-on-open, step-by-step (one event per click, synced to the audience window), or none.
- Events are an ordinary Markdown list (marker :: title :: description), so the .md stays readable; layout and animation round-trip as _class tokens.
- Live preview — see each slide rendered as you edit, with inline Markdown, footers, and TLP (Traffic Light Protocol) marking.
- Free-Markdown slides render fenced code with syntax highlighting, $…$ / $$…$$ LaTeX math, and Mermaid diagrams.
- Traffic Light Protocol — a deck-wide classification plus an optional per-slide TLP level; slides classified stricter than the level the deck is shown at are automatically withheld, both when presenting and exporting.
- Visual marking (banner, badge, optional diagonal watermark) follows FIRST TLP 2.0 colours and is WYSIWYG through preview, presenter, and PDF/PPTX export.
- Optional classification enforcement (release ceiling, required minimum, mandatory classification, watermark toggle) blocks export fail-closed when policy fails; export metadata embeds TLP in PDF/PPTX/HTML.
- Privacy check & redaction (OciWacht) — OciDeck reads every slide for data that may be privacy-sensitive and reports it in the quality panel, right next to the contrast and readability checks: identification numbers (the Dutch BSN plus national ID numbers across the EU, each validated by its own checksum), IBANs and payment cards, e-mail addresses, phone numbers (E.164 against the assigned ITU calling codes), API keys, tokens, private keys and plain-text passwords, GDPR art.
- 9/10 special categories (health, criminal, religion, trade-union, biometric, genetic notation), bulk personal data in tables, and the structural leaks generic scanners miss — user paths that reveal a name, tokens in URLs, share links with built-in access.
- False positives are the real enemy here (a scanner that cries wolf gets switched off, and then it detects nothing at all), so checksums, context gates, and an allow-list of values that belong to nobody — test IBANs, the official test-BSN range, example.com, the reserved "drama" phone ranges — do the filtering, and a co-occurrence escalator keeps a slide about privacy law quiet while a slide carrying a name, a BSN and a diagnosis speaks up.
- It all runs on this device, and a finding never shows you the value it found.
- What you do with a finding is yours to decide — per slide, or deck-wide: accept (a police briefing contains personal data by definition), accept + warn (the slide gets a personal data badge beside its TLP marking, so whoever receives the deck knows what they are holding), or leave out of display and export.
- That last one means what it says: not a black bar painted over text that is still sitting in the PDF, but data removed at a single projection boundary that the type system enforces, so no render surface can forget it — screen, presenter, audience window, PDF, PPTX, HTML, speaker notes, document metadata.
- Your Markdown keeps the original.
- And because a pentest report has to be verifiable, export gives you two versions from one source: full for the client who must be able to check the finding, redacted for the wider circle — with a salted-commitment redaction manifest so a third party can still prove nothing else was altered.
- The check does not guarantee that everything is found; it reduces the chance that personal data leaks out unintentionally.
- Information-security reporting (MIAUW pentest module) — an optional module, off by default, for authoring MIAUW-conforming penetration-test reports.
- It adds dedicated finding / findings-summary / checklist / scope-matrix / sign-off slide types, a native CVSS 4.0 builder with an offline CWE picker and CVE fields, a finding wizard, and a compliance overview that scores the deck against the MIAUW requirements (EIS).
- Mechanical bookkeeping is automated: auto-numbering of findings, evidence SHA1 + SHA-256 hashing, scope-coverage checks, and a derived management summary.
- A report can be finalised and sealed (SHA-512 over the canonicalised content, detecting any later change) with an optional RFC 3161 trusted timestamp, exported as a MIAUW report template, and bundled into a one-click, AES-256-encrypted audit dossier (report + evidence + hash tables).
- Everything is offline by default; the optional AI helpers below are privacy-gated.
- Optional, privacy-first AI assistance — an entirely optional, off-by-default backend (a local model, or a consented outbound endpoint) that drafts free-text finding fields grounded only on the tester's own facts (it strips any CWE/CVE/CVSS identifier it invents) and suggests image alt-text / tags for accessibility.
- AI-drafted content is marked and blocks sealing until a human reviews it, so provenance is always explicit.
- Fullscreen presenter — keyboard-driven navigation, presenter view, blank screen, auto-advance, and a slide-grid overview.
- Presentation timer / rehearsal mode — the presenter view doubles as a rehearsal clock: a countdown against a target time (set in Settings or live with K), the time spent on the current slide, and an end-of-run summary (total vs.
- target and per-slide times, copyable).
- It measures only — no pacing coaching — and is session-only, never written to disk.
- Dual-screen presenter — when a second display is connected, the beamer shows the slide while the laptop shows the presenter view (current/next slide, notes, timer), kept in sync.
- Annotation layer — draw on slides while presenting (pen, highlighter, eraser, laser pointer).
- Kept as a separate layer that never touches the Marp Markdown, mirrored live to the beamer, and saved in a .ink.json sidecar.
- Live table editing — opt a table into being editable while presenting (off by default) and change it in front of the audience: a subtle pencil toggle, arrow keys moving the cursor inside a cell, Tab between cells, mirrored to the beamer.
- Media handling — drag-and-drop images, an image carousel picker, captions, and descriptions stored as sidecar metadata.
- The library can filter images without tags and clean up md5-identical duplicates (merging their tags/captions and repointing every deck — open or on disk — to the kept file).
- Import / export — round-trips Marp Markdown, imports existing slides, and exports to PDF, PPTX (with speaker notes), and a self-contained offline HTML deck (code highlighting, math, charts, and mermaid diagrams render in the browser).
- Decks are saved as a self-contained package with copied assets.
- Nextcloud (WebDAV) source — browse a folder on your Nextcloud, open .ocideck packages or Marp .md decks from it, and save a deck back (as an .ocideck package or as a flat .md plus assets).
- The app password is stored encrypted in the OS keychain; a private/LAN server is only reachable after explicitly marking it as trusted, and downloads pass through the same safety gate and size limits as every other import.
- Productivity — find & replace, slide finder, undo/redo, skip-slide state, multi-select with bulk copy-to-another-deck / delete / skip, and tabbed multi-deck editing.
- Paste a spreadsheet selection (or CSV / a markdown table) into a table cell to fill the whole grid.
- Markdown mode edits the whole deck as raw Marp text, with an in-editor find bar (Ctrl/Cmd+F, replace via Ctrl/Cmd+H) over the live buffer, plus a structural syntax check (line highlights, optional Apply anyway) before switching back.
- Ctrl/Cmd+O opens, Ctrl/Cmd+S saves.
- Accessibility — WCAG 2.1-oriented: interface text scaling up to 200%, keyboard-operable panel divider and dialogs, screen-reader labels for slides and charts (charts read out their data), and slide-change announcements while presenting.
- Crash recovery — automatic snapshots so work survives an unexpected exit.
- Theming — customizable deck style profiles (deck and source-code colours via presets or custom hex, fonts, logo, footer) and app appearance (including a dark interface), a bundled Marp CSS theme (assets/themes/ocideck.css), and a bundled EB Garamond font (no network fetch).
- Localized — a fully translated interface in 31 languages: Dutch, English, German, French, Italian, Spanish, Portuguese, Polish, Czech, Slovak, Slovenian, Croatian, Bulgarian, Romanian, Hungarian, Greek, Danish, Swedish, Finnish, Estonian, Latvian, Lithuanian, Maltese, Irish, Ukrainian, Indonesian, Frisian, Swiss German, Latin, Papiamento, and Klingon.
- Every interface string is translated in all of them, enforced by tests.

</div>

<div class="split-image">

![](images/pasted_1780132337939.png)

</div>

---

<!-- _class: split logo-safe -->

<!-- _style: --image-width: 40%; --split-text-scale: 1.20; -->

<div class="split-text" style="font-size: 1.20em">

# Zet de inhoud centraal
<!-- ocideck_list_style: richText -->

Veel presentaties beginnen met een leeg vlak. Je sleept een tekstvak. Je schuift een afbeelding. Je kiest een lettertype. Je trekt een lijn recht. Je maakt een tabel net iets kleiner. En voor je het weet ben je vooral bezig met opmaak.

Dat is vreemd, want een presentatie gaat eigenlijk niet over vakjes, lijnen en kleuren. Een presentatie gaat over een verhaal. Over informatie. Over kennis die je wilt delen. Over data die moet kloppen.

OciDeck is gebouwd vanuit dat idee.

OciDeck is een programma om presentaties te maken, maar niet als conventionele presentatiesoftware. In OciDeck staat de inhoud centraal. Je maakt geen losse vormpjes op een canvas. Je kiest wat voor soort slide je nodig hebt: een titel, een lijst, een tabel, een afbeelding, een grafiek, broncode, een tijdlijn, een vraag, een video of een dashboard. Daarna vul je de inhoud in. OciDeck zorgt dat het netjes, consistent en bruikbaar wordt weergegeven.

Dat maakt werken rustiger. Je hoeft minder te schuiven en te prutsen. Je kunt je concentreren op wat je wilt zeggen.

## De data eerst
Conventionele presentatiesoftware slaat vooral de opmaak op. Waar staat het tekstvak? Welke grootte heeft het? Welke kleur heeft de rand? De inhoud zit daar ergens in verstopt.

OciDeck draait dat om. De inhoud is de basis. Een tabel is echt een tabel. Een grafiek komt uit data. Een tijdlijn komt uit gebeurtenissen. Een code-slide bevat echte broncode. Een vraag-slide bevat een echte vraag met antwoorden.

Dat is belangrijk, want inhoud moet te controleren zijn. Je wilt kunnen terugzien wat er staat. Je wilt een presentatie kunnen aanpassen zonder dat alles uit elkaar valt. Je wilt informatie kunnen hergebruiken. En je wilt niet dat je verhaal afhankelijk wordt van handmatig geschuif met objecten.

OciDeck helpt daarbij door presentaties op te slaan als Marp Markdown. Dat is gewone tekst. Leesbaar. Open. Makkelijk te bewaren, te vergelijken en te delen.

## Vrijheid en soevereiniteit
Een belangrijk idee achter OciDeck is digitale soevereiniteit.

Je presentatie moet van jou zijn. Niet opgesloten in één programma. Niet afhankelijk van één leverancier. Niet alleen bruikbaar zolang een bepaald pakket beschikbaar blijft.

Daarom gebruikt OciDeck Marp. Marp is een open manier om presentaties te maken met Markdown. Dat betekent: als je een presentatie in OciDeck maakt, zit je niet vast aan OciDeck. Je kunt de presentatie ook openen of verwerken met andere Marp-tools. De inhoud blijft toegankelijk.

OciDeck zelf is bovendien open source onder de EUPL-licentie. Dat past bij het doel: transparant, controleerbaar en aanpasbaar. Je hoeft niet blind te vertrouwen op een gesloten systeem. Je kunt zien hoe het werkt. Je kunt het gebruiken, bestuderen, delen en verbeteren.

Dat maakt OciDeck interessant voor mensen en organisaties die grip willen houden op hun eigen informatie.

## Wat kun je ermee dat anders lastig is?
OciDeck is niet alleen een andere manier van opslaan. Het geeft je ook mogelijkheden die je in conventionele presentatiesoftware niet zomaar krijgt.

Je kunt bijvoorbeeld slides een TLP-classificatie geven. Daarmee kun je aangeven hoe gevoelig informatie is. OciDeck kan slides die te gevoelig zijn automatisch weglaten bij presenteren of exporteren. Zo kun je met één deck werken voor verschillende doelgroepen, zonder telkens handmatig kopieën te maken.

Je kunt ook export blokkeren als een presentatie niet aan regels voldoet. Bijvoorbeeld als er geen classificatie is ingesteld, of als de presentatie te gevoelig is voor het gekozen doel. Dat maakt OciDeck geschikt voor omgevingen waar zorgvuldigheid belangrijk is.

Daarnaast controleert OciDeck de kwaliteit van slides. Zijn teksten niet te vol? Is het contrast goed genoeg? Mist er media? Zijn grafieken duidelijk genoeg? Dat helpt om betere en toegankelijkere presentaties te maken.

OciDeck heeft ook interactieve mogelijkheden. Je kunt quizvragen maken waarbij de presentatie pas verder gaat na een goed antwoord. Je kunt tabellen live bewerken tijdens het presenteren. Je kunt een video in stukken knippen en over meerdere slides verdelen. Je kunt notities maken voor de spreker, maar ook aparte notities voor deelnemers of cursisten.

Voor technische presentaties is OciDeck extra sterk. Broncode, Markdown, grafieken, Mermaid-diagrammen, LaTeX en offline HTML-export passen natuurlijk in de manier van werken. Je presentatie wordt meer een gestructureerd document dan een verzameling plaatjes.

## Voor wie is OciDeck?
OciDeck is voor mensen die meer willen dan mooie slides.

Voor trainers die interactieve lessen willen geven. Voor onderzoekers die hun data netjes willen presenteren. Voor security-professionals die met gevoelige informatie werken. Voor ontwikkelaars die code en diagrammen willen tonen. Voor organisaties die grip willen houden op hun documenten. Voor iedereen die presentaties ziet als kennisdragers, niet alleen als opgemaakte schermen.

OciDeck maakt presenteren minder afhankelijk van vorm en meer gericht op inhoud.

Je maakt nog steeds mooie slides. Maar je bouwt ze op een stevigere basis.

De kern is simpel:

Met OciDeck maak je presentaties waarin de inhoud de baas is. Je houdt controle over je data. Je blijft vrij door open standaarden. En je krijgt functies die gewone presentatietools niet vanzelf bieden.

Dat maakt OciDeck geen gewone vervanger voor conventionele presentatiesoftware.

Het is een andere manier van denken over presentaties.

</div>

<div class="split-image">

![](images/pasted_1782729465810.png)

</div>

---

<!-- _class: two-bullets logo-safe -->

# Twee kolommen naast elkaar

<div class="ocideck-two-bullets" style="display:grid; grid-template-columns:1fr 1fr; gap:3rem; align-items:start;">
<div>
<h3 style="margin:0 0 .5rem;">De mens</h3>
<ul style="margin:0; padding-left:1.3em;">
<li>Wil rustig thuiswerken</li>
<li>Typt een belangrijke e-mail</li>
<li>Heeft het scherm echt even nodig</li>
<li>Drinkt koffie</li>
</ul>
</div>
<div>
<h3 style="margin:0 0 .5rem;">De kat</h3>
<ul style="margin:0; padding-left:1.3em;">
<li>Wil ook thuiswerken, maar dan op schoot</li>
<li>Gaat languit op het toetsenbord liggen</li>
<li>Zit precies vóór dat scherm</li>
<li>Drinkt uit het koffiekopje</li>
</ul>
</div>
</div>

---

<!-- _class: logo-safe -->

# Een dag uit het leven van een kat
<!-- ocideck_bullet_marker: paw -->

- Ochtend
- De mens wakker maken om 05:00 uur, niet onderhandelbaar
- Ontbijt eisen, eraan ruiken, verontwaardigd afkeuren
- Middag
- Drie uur staren naar een volstrekt lege muur
- De zonnevlek door het hele huis achtervolgen
- Avond
- Zoomies door de gang, op topsnelheid
- Op schoot springen precies wanneer de mens wil opstaan

---

<!-- _class: cockpit logo-safe -->

# Verschillende controls om informatie te geven

```cockpit
{
  "layout": "auto",
  "animateOnEnter": true,
  "animationDurationMs": 30000,
  "meters": [
    {
      "type": "thermometer",
      "label": "Exploitability heat",
      "unit": "/10",
      "min": -5.0,
      "max": 10.0,
      "greenFrom": 1.0,
      "greenTo": 3.0,
      "redFrom": 7.0,
      "value": 6.9
    },
    {
      "type": "speedometer",
      "label": "Overall risk",
      "unit": "%",
      "min": 0.0,
      "max": 100.0,
      "greenFrom": 0.0,
      "greenTo": 40.0,
      "redFrom": 70.0,
      "value": 78.0
    },
    {
      "type": "voltmeter",
      "label": "Evidence confidence",
      "unit": "%",
      "min": 0.0,
      "max": 100.0,
      "greenFrom": 75.0,
      "greenTo": 100.0,
      "redFrom": 50.0,
      "value": 92.0
    },
    {
      "type": "heading",
      "label": "Findings trend",
      "value": 187.0,
      "heading": 90.0,
      "markerLabel": "Koersverschillen"
    },
    {
      "type": "horizon",
      "label": "Gaan we recht?",
      "unit": "%",
      "pitch": 0.0,
      "bank": 15.0
    },
    {
      "type": "altimeter",
      "label": "De druk loopt op",
      "unit": "%",
      "min": 0.0,
      "max": 100.0,
      "greenFrom": 0.0,
      "greenTo": 40.0,
      "redFrom": 70.0,
      "value": 50.0
    }
  ]
}
```

---

<!-- _class: section logo-safe -->

# Grafieken in alle soorten en maten

Van taart tot risicomatrix: de hele doos gaat open

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "pie",
  "title": "Een taartgrafiek",
  "source": "data/Een_taartgrafiek.json",
  "animationDurationMs": 4600
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "bar",
  "title": "Een staafgrafiek",
  "source": "data/Een_staafgrafiek.json",
  "animationDurationMs": 2400
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "line",
  "title": "Een lijngrafiek",
  "source": "data/Een_lijngrafiek.json",
  "animationDurationMs": 3600
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "scatter",
  "title": "En wat spreiding",
  "source": "data/En_wat_spreiding.json",
  "animationDurationMs": 1800
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "stackedBar",
  "title": "Een staaf grafiek",
  "source": "data/Een_staaf_grafiek.json",
  "animateOnEnter": false,
  "animationDurationMs": 8800
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "radar",
  "title": "Spider",
  "source": "data/Spider.json",
  "animationDurationMs": 2800
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "donut",
  "title": "Waar gaat de dag van een kat naartoe?",
  "source": "data/Waar_gaat_de_dag_van_een_kat_naartoe.json",
  "animationDurationMs": 2600
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "area",
  "title": "Spinintensiteit door de dag",
  "source": "data/Spinintensiteit_door_de_dag.json",
  "animationDurationMs": 3000
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "horizontalBar",
  "title": "Favoriete slaapplekken (ranglijst)",
  "source": "data/Favoriete_slaapplekken_ranglijst.json",
  "animationDurationMs": 2400
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "horizontalStackedBar",
  "title": "Hoe elke kat zijn uren verdeelt",
  "source": "data/Hoe_elke_kat_zijn_uren_verdeelt.json",
  "animationDurationMs": 2600
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "combo",
  "title": "Brokjes en gewicht van een groeiende kater",
  "source": "data/Brokjes_en_gewicht_van_een_groeiende_kater.json",
  "animationDurationMs": 2800
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "waterfall",
  "title": "Het energiebudget van een kattendag",
  "source": "data/Het_energiebudget_van_een_kattendag.json",
  "animationDurationMs": 3200
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "bullet",
  "title": "Doel versus werkelijkheid",
  "source": "data/Doel_versus_werkelijkheid.json",
  "maxBound": 24.0,
  "targets": [
    14.0,
    6.0,
    3.0,
    0.0
  ],
  "bands": [
    8.0,
    16.0
  ],
  "animationDurationMs": 2600
}
```

---

<!-- _class: chart logo-safe -->

```chart
{
  "type": "heatmap",
  "title": "Risicomatrix: kans x impact van kattenkwaad",
  "source": "data/Risicomatrix_kans_x_impact_van_kattenkwaad.json",
  "animationDurationMs": 3000
}
```

---

<!-- _class: logo-safe -->

# Checklist
## Nagelsknippen van een kat
<!-- ocideck_list_style: checklist -->
<!-- ocideck_checklist_progress: true -->

- [x] Nagelknipper, styptisch poeder en lekkernijen klaar
- [ ] Kat is ontspannen
- [ ] Knippende mens is ontspannend
- [ ] Kat stevig vast
- [ ] Quick (levend gedeelte) geïdentificeerd (niet aanknippen!)
- [ ] Pootje vast, nagel zichtbaar
- [ ] Knip alleen het witte topje (1-2 mm)
- [ ] Geen bloeding na het knippen
- [ ] Kat belonen met lekkernij

<!-- ocideck_privacy: warn -->

---

<!-- _class: assets logo-safe -->

# De kattenpopulatie in beeld

| Group | Total | AtRisk | New | Unowned |
| --- | --- | --- | --- | --- |
| Huiskatten | 182 | 12 | 7 | 3 |
| Buurtkatten | 47 | 9 | 4 | 22 |
| Boerderijkatten | 24 | 2 | 1 | 6 |
| Ocikatten (zeldzaam) | 5 | 0 | 1 | 0 |

---

<!-- _class: scorecard logo-safe -->

# Sinds de vorige kattentelling

| Label | Value | Previous | Unit | Polarity |
| --- | --- | --- | --- | --- |
| Katten in beeld | 258 | 231 |  | higher-better |
| Ongeknipte nagels | 34 | 61 |  | lower-better |
| Gemiddeld dutjes per dag | 5 | 4 |  | neutral |
| Kapotte vazen | 3 | 7 | stuks | lower-better |

---

<!-- _class: discoveries logo-safe -->

# Wat we niet wisten te hebben

| Discovery | Kind | DaysUnnoticed | Owner |
| --- | --- | --- | --- |
| Zwarte kat in de schuur | Buurtkat | 412 | Buurman |
| Kittens onder het terras | Nest | 60 | Buurvrouw |
| Kater bij de vuilnisbakken | Zwerver | 190 |  |

---

<!-- _class: finding logo-safe -->
<!-- ocideck_finding_id: F-01 -->
<!-- ocideck_finding_role: header -->

# F-01 · Slim kattenluik met ingebakken sleutel

**Scope object:** `https://api.snorflap.example/v3/deur`
**CVSS 4.0:** 9.3 (Critical) · `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N`
**CWE:** [CWE-798 — Use of Hard-coded Credentials](https://cwe.mitre.org/data/definitions/798.html)
**Test:** `WSTG-ATHN-01`
**Retest:** NotResolved — de leverancier onderzoekt het nog

## Description
Het slimme kattenluik "SnorFlap 3000" herkent de eigen kat aan zijn chip, maar de bijbehorende cloud-app draagt een vaste, in de firmware ingebakken sleutel. Wie die sleutel kent, ontgrendelt het luik op afstand: geen kat, geen chip, geen wachtwoord nodig.

## Confirmation (reproduction)
1. Firmware van het luik uitgelezen en er stond gewoon een vaste sleutel in.
2. Een open-verzoek naar de deur-API gestuurd met die sleutel, vanaf een willekeurig netwerk.
3. Het luik klikte open. De buurkat wandelde naar binnen en at de voerbak leeg.

## Possible impact
Elke kat ter wereld — en erger nog, elke mens die de sleutel bemachtigt — kan de voordeur van het dierenrijk openzetten. Verlies van voer (beschikbaarheid), inzicht in wie er thuis is (vertrouwelijkheid) en ongenode gasten op de bank (integriteit).

## Recommendation
Vervang de vaste sleutel door een uniek geheim per apparaat in de beveiligde opslag van het toestel. Laat het luik alleen chips van een witte lijst toe en meld onbekende openpogingen. En zet de voerbak voorlopig gewoon binnen.

---

<!-- _class: logo-safe -->
<!-- ocideck_finding_id: F-01 -->
<!-- ocideck_finding_role: evidence -->

![bg 100%](images/evidence_snorflap_firmware.png)
<!-- ocideck_image_alt: Terminal-screenshot van de firmware-analyse van het SnorFlap-kattenluik; de hardgecodeerde sleutel is geel gemarkeerd en een open-verzoek met die sleutel laat een onbekende kat toe. -->

---

<!-- _class: code logo-safe -->

# Wat broncode

```dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'markdown_view.dart';

/// Localized labels + content for the About / disclaimer / data-sources screen
/// and the first-launch disclaimer gate.
class AboutCopy {
  const AboutCopy({
    required this.openLabel,
    required this.aboutTitle,
    required this.gateTitle,
    required this.gateBody,
    required this.acknowledge,
    required this.readMore,
    required this.markdown,
  });

 
```

---

<!-- _class: section logo-safe -->

# Voor de liefhebbers

Diagrammen en formules horen er ook gewoon in

---

<!-- _class: logo-safe -->

# De grote kat-beslisboom
<!-- ocideck_list_style: richText -->

```mermaid
flowchart TD
    A[Kat ziet iets op de rand van de tafel] --> B{Kijkt de mens?}
    B -->|Ja| C[Eerst even oogcontact maken]
    C --> D[Heel langzaam de poot ernaartoe]
    B -->|Nee| E[Meteen omduwen, geen getuigen]
    D --> F[Voorwerp valt op de grond]
    E --> F
    F --> G{Ging het stuk?}
    G -->|Ja| H[Missie geslaagd, nonchalant weglopen]
    G -->|Nee| I[Zoek een nieuw voorwerp]
    I --> A
```

---

<!-- _class: logo-safe -->

# De kat van Schrödinger
<!-- ocideck_list_style: richText -->

Zolang de doos dicht blijft, is de kat netjes in superpositie:

$$\lvert \text{kat} \rangle = \tfrac{1}{\sqrt{2}}\left( \lvert \text{slaapt} \rangle + \lvert \text{wil eten} \rangle \right)$$

En de kans dat de kat op het drukste moment precies op je toetsenbord ligt:

$$P(\text{toetsenbord}) = 1 - \frac{1}{9^{\,\text{levens}}} \approx 1$$

Inline werkt ook: een kat spint rond $f \approx 25\ \text{Hz}$, precies de frequentie die botten helpt helen.

---

<!-- _class: video logo-safe -->

<iframe class="ocideck-embed" data-src="https://www.youtube.com/watch?v=JZUnLGCXS5s" src="https://www.youtube-nocookie.com/embed/JZUnLGCXS5s?autoplay=0&amp;rel=0&amp;modestbranding=1&amp;playsinline=1&amp;enablejsapi=1" style="width:100%; aspect-ratio:16/9; border:0;" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>

<!--
Video over ocicats
-->

---

<!-- _class: section logo-safe -->

# Nu wat vragen

Omdat interactiviteit zo leuk is

---

<!-- _class: question logo-safe -->

![](images/pasted_1782167168460.png)

```question
{
  "kind": "multipleChoice",
  "prompt": "Wat is geen bier?",
  "optionCount": 4,
  "timeLimitSeconds": 20,
  "onWrong": "retry",
  "answers": [
    {
      "text": "Gemeentepils",
      "correct": true
    },
    {
      "text": "Lord Nelson",
      "correct": true
    },
    {
      "text": "Heineken",
      "correct": true
    },
    {
      "text": "Melk",
      "correct": true
    },
    {
      "text": "Chateau Neuf du Pape",
      "correct": true
    },
    {
      "text": "Amstel",
      "correct": false
    },
    {
      "text": "Grolsch",
      "correct": false
    },
    {
      "text": "Warsteiner",
      "correct": false
    },
    {
      "text": "Bitburger",
      "correct": false
    },
    {
      "text": "Tiger Beer",
      "correct": false
    },
    {
      "text": "Castle Beer",
      "correct": false
    },
    {
      "text": "Hertog Jan",
      "correct": false
    },
    {
      "text": "Affligem",
      "correct": false
    },
    {
      "text": "Bulldog",
      "correct": false
    },
    {
      "text": "Gladjanus",
      "correct": false
    },
    {
      "text": "Bintang",
      "correct": false
    },
    {
      "text": "Asahi",
      "correct": false
    },
    {
      "text": "Peroni",
      "correct": false
    },
    {
      "text": "Moretti",
      "correct": false
    },
    {
      "text": "Castello",
      "correct": false
    }
  ]
}
```

---

<!-- _class: question logo-safe -->

![](images/pasted_1784118365926.png)

```question
{
  "kind": "multipleCorrect",
  "prompt": "Op welke vragen is 42 het antwoord?",
  "optionCount": 4,
  "timeLimitSeconds": 0,
  "onWrong": "retry",
  "answers": [
    {
      "text": "Life",
      "correct": true
    },
    {
      "text": "Universe",
      "correct": true
    },
    {
      "text": "Everything",
      "correct": true
    },
    {
      "text": "Cats",
      "correct": false
    },
    {
      "text": "Health",
      "correct": false
    },
    {
      "text": "Animals",
      "correct": false
    },
    {
      "text": "Anthem",
      "correct": false
    }
  ]
}
```

---

<!-- _class: question logo-safe -->

![](images/pasted_1781245807752.png)

```question
{
  "kind": "trueFalse",
  "prompt": "Een volkslied is altijd in het Engels",
  "optionCount": 4,
  "timeLimitSeconds": 0,
  "onWrong": "retry",
  "statementIsTrue": false,
  "answers": [
    {
      "text": "Het juiste antwoord",
      "correct": true
    },
    {
      "text": "Een fout antwoord",
      "correct": false
    },
    {
      "text": "Nog een fout antwoord",
      "correct": false
    },
    {
      "text": "En nog een fout antwoord",
      "correct": false
    }
  ]
}
```

---

<!-- _class: question logo-safe -->

```question
{
  "kind": "ordering",
  "prompt": "Zet de perfecte kattendag op volgorde",
  "optionCount": 5,
  "timeLimitSeconds": 0,
  "onWrong": "retry",
  "answers": [
    {
      "text": "05:00 — de mens wakker maken",
      "correct": true
    },
    {
      "text": "08:00 — ontbijt eisen en het daarna negeren",
      "correct": true
    },
    {
      "text": "13:00 — een dutje in de zonnevlek",
      "correct": true
    },
    {
      "text": "18:00 — zoomies door het hele huis",
      "correct": true
    },
    {
      "text": "23:00 — op de borst van de mens gaan liggen",
      "correct": true
    }
  ]
}
```

---

<!-- _class: question logo-safe -->

```question
{
  "kind": "openText",
  "prompt": "Hoeveel levens heeft een kat volgens de folklore? Typ je antwoord.",
  "optionCount": 4,
  "timeLimitSeconds": 0,
  "onWrong": "lockAndContinue",
  "similarityThreshold": 0.8,
  "answers": [
    {
      "text": "negen",
      "correct": true
    },
    {
      "text": "9",
      "correct": true
    },
    {
      "text": "nine",
      "correct": true
    }
  ]
}
```

---

<!-- _class: question logo-safe -->

```question
{
  "kind": "imagePair",
  "prompt": "Welke is de échte Ocikat?",
  "optionCount": 2,
  "timeLimitSeconds": 0,
  "onWrong": "retry",
  "answers": [
    {
      "text": "De echte Ocikat",
      "correct": true,
      "image": "images/pasted_1782807831131.png"
    },
    {
      "text": "Delfts blauw bedrog",
      "correct": false,
      "image": "images/pasted_1780132337939.png"
    }
  ]
}
```

---

<!-- _class: table logo-safe table-editable -->

# Dit is een tabel, werk hem eens bij

| Rol | Takenlijst | Verantwoordelijkheden | Bevoegdheden |
| --- | --- | --- | --- |
| Bestuur | Strategie en beleid goedkeuren, toezicht houden op uitvoering, eindbeslissingen nemen. | Algehele beveiliging, privacy (AVG), compliance (NIS2, Wbni, DORA), risicoacceptatie, naleving wet- en regelgeving. | Beslissend (budget, strategie, risicoacceptatie), mandateren, afrekenen op resultaten. |
| CISO | Beveiligingsbeleid en -strategie ontwikkelen, risicoanalyses uitvoeren, incidentresponse leiden, technische beveiligingsmaatregelen implementeren, security awareness-programma’s opzetten. | Bescherming van informatieassets (CIA-triad), effectief risicomanagement, naleving beveiligingsnormen (ISO 27001), incidentbeheer. | Veto-recht op projecten met onacceptabele risico’s, toegang intrekken, beveiligingsteams aansturen, budget voor beveiliging bepalen. |
| FG (DPO) | Privacybeleid ontwikkelen, AVG-naleving monitoren, datalekken beoordelen en melden (AP), privacy-impactassessments (PIA’s) uitvoeren, advies geven over databescherming. | Naleving AVG, bescherming persoonsgegevens, tijdige melding datalekken, toezicht op gegevensverwerking. | Toegang tot alle persoonsgegevensverwerkingen, adviesrecht (niet bindend), meldplicht aan AP, onafhankelijke beoordeling. |
| Compliance Officer | Compliance-strategie ontwikkelen, interne audits uitvoeren, rapportages opstellen voor toezichthouders (AP, AFM, DNB), sectorale regelgeving (NIS2, DORA, Wbni) toepassen. | Naleving van alle toepasselijke wet- en regelgeving, risicobeheer op compliance-gebied, rapportage aan toezichthouders. | Eis tot naleving afdwingen, audits initiëren, compliance-rapportages goedkeuren, sancties voorstellen. |
| CIO | IT-strategie en -beleid ontwikkelen, IT-infrastructuur beheren, systemen en applicaties implementeren, IT-budget beheer. | Beschikbaarheid, betrouwbaarheid en veiligheid van IT-systemen, technische implementatie van beveiligingsmaatregelen. | IT-budget bepalen, IT-teams aansturen, technische keuzes maken (bv. cloud, netwerkarchitectuur), toegang tot systemen regelen. |

<!-- ocideck_privacy: warn -->

---

<!-- _class: timeline logo-safe timeline-vertical -->

# Hoe zijn we hier toch gekomen?

<!-- ocideck_timeline_duration: 9200 -->
<!-- ocideck_timeline_current: 3 -->
- 2019 :: Oprichting :: Het begin van het verhaal.
- 2021 :: Doorbraak :: De eerste grote mijlpaal.
- Nu :: Vandaag :: Waar we nu staan.
- Morgen :: Nieuwe kansen :: En objectgen
- Overmorgengen :: Dat is de dag naar morgen :: Wereldvrede en wereldominantie
- Volgende eeuw :: Star Wars :: Starwars

---

<!-- _class: timeline logo-safe timeline-horizontal timeline-steps -->

# Hoe zijn we hier toch gekomen?

<!-- ocideck_timeline_duration: 6000 -->
<!-- ocideck_timeline_current: 4 -->
- 2019 :: Oprichting :: Het begin van het verhaal.
- 2021 :: Doorbraak :: De eerste grote mijlpaal.
- Nu :: Vandaag :: Waar we nu staan.
- Morgen :: Nieuwe kansen :: En objectgen
- Overmorgengen :: Dat is de dag naar morgen :: Wereldvrede en wereldominantie
- Volgende eeuw :: Star Wars :: Starwars

---

<!-- _class: logo-safe -->

![bg left:50%](images/pasted_1780579562050.png)
![bg right:50%](images/pasted_1781125492632.png)
<!-- ocideck_image_alt: Paniek (zoogdierbrein), Ocicat -->
<!-- ocideck_image_alt2: Menselijk brein, ocicat -->

---

<!-- _class: logo-safe -->

![bg 85%](images/pasted_1782807831131.png)
<!-- ocideck_image_alt: Portret van een Ocikat in close-up tegen een donkere achtergrond -->

# De Ocikat in vol ornaat

---

<!-- _class: video logo-safe -->

<video src="media/IMG_8718.mp4#t=0,21.082" controls autoplay muted loop style="width:100%; max-height:72vh;"></video>

<!--
Brenno achter het stuur en zonder dat hij rijdt
-->

---

<!-- _class: question logo-safe -->

```question
{
  "kind": "multipleChoice",
  "prompt": "Welk scenario ontvouwt zich",
  "optionCount": 4,
  "timeLimitSeconds": 0,
  "onWrong": "retry",
  "answers": [
    {
      "text": "De zelfrijdende auto rijdt door de bus stopt",
      "correct": true
    },
    {
      "text": "De bus drukt door, de zelfrijdende auto remt net op tijd",
      "correct": false
    },
    {
      "text": "De bus drukt door, de zelfrijdende auto remt te laat",
      "correct": false
    },
    {
      "text": "Beide voertuigen rijden door met een grove aanrijding",
      "correct": false
    },
    {
      "text": "De bus rijdt auto klem en de chauffeur wordt agressief",
      "correct": false
    },
    {
      "text": "Beide auto's stoppen en een ambulance komt langs",
      "correct": false
    }
  ]
}
```

---

<!-- _class: video logo-safe -->

<video src="media/IMG_8718.mp4#t=20" controls autoplay muted loop style="width:100%; max-height:72vh;"></video>

<!--
Brenno achter het stuur en zonder dat hij rijdt
-->

---

<!-- _class: split logo-safe -->

<!-- _style: --image-width: 45%; --split-text-scale: 1.85; -->

<div class="split-text" style="font-size: 1.85em">

# Profiel Brenno de Winter

- Geboortedatum: 6 december 1971
- Diagnose: diabetes
- Woonadres: Molendraaier 1337, 2211 PW Noordwijk
- Telefoonnummer: +31653536508
- BSN: 586250359
- Bankrekeningnummer: DE05613696556870613676

</div>

<div class="split-image">

![](images/pasted_1784966899247.png)
<!-- ocideck_image_alt: Brenno de Winter -->

</div>

<!-- ocideck_privacy: redact -->

---

<!-- _class: quote logo-safe -->

![bg opacity:.45](images/pasted_1782736845937.png)

> Liefde en wereldvrede

— Brenno de Winter

<!-- ocideck_privacy: accept -->

