Bron: docs/functioneel-ontwerp.md op GitHub
Functioneel ontwerp – Commons Mineventory¶
Naam: Commons Mineventory (besluit Olaf 5-11-2026; mine + inventory: een inventaris van wat er in een afbeelding staat, gedolven met AI; tot en met 0.30.1 heette de app Commons Cutter, besluit 3-11-2026). Tagline: Detect objects in a Commons image. Find, cut out and describe them with AI. Tool, repo en map heten sinds 0.31.1 commons-mineventory; het Python-package heet nog cutter/ (backlog 12f). Status: concept v0.9, 5 november 2026 (v0.9: hoofdstuk 17, het dashboard met collecties uit categorieën, per gebruiker, en 8.6, starttegoed en eigen Meta-sleutel, beide als voorstel; v0.8: bijgewerkt tot app-versie 0.30.1: Begrippen, kolommen in werkvolgorde (10.4), bulk onder de objecten (7.4), paginaoverzicht per deel (7.6); de stand van zaken staat in docs/overdracht.md; v0.7: voorstel 9.7, beeldt af en caption voor de hele afbeelding; v0.6: bijgewerkt tot app-versie 0.24.2; zie CHANGELOG.md voor alles wat sinds 0.9.0 gebouwd is; v0.5: bijgewerkt naar wat er in fase 1 is gebouwd, app-versie 0.9.0: bewerkbare AI-teksten, AI-merkjes, proefweergave zoals op Commons, extra SDC, regio op het origineel als voorbeeld; v0.2: antwoorden van Olaf op de belangrijkste vragen verwerkt, en de regio's uit de gestructureerde gegevens uitgewerkt in 7.5; v0.3: frontend met Vite, zie 10.2; v0.4: tweede ronde antwoorden en de naam Commons Cutter). Opdrachtgever en eigenaar: Olaf Janssen (KB, Wikimedia-coördinator). Bouw: Claude Code, op basis van dit document.
Dit FO beschrijft een variant van de Delpher Uitsnijder (versie 0.18.13, lokaal in D:\KB-OPEN\github-repos\delpher-uitsnijder) voor afbeeldingen op Wikimedia Commons. Waar dit document "de Delpher Uitsnijder" zegt, gaat het om die app: haar FO, docs/api.md, docs/commons-beschrijving.md, docs/beeld-taalmodel.md en docs/meta-sam-api.md. Die documenten blijven de bron voor alles wat ongewijzigd wordt overgenomen. Dit FO beschrijft vooral wat anders is.
Punten met [Vraag] wachten op een keuze van Olaf; ze staan ook in hoofdstuk 15. Wat Olaf heeft besloten, staat bij het onderwerp en in de tabel in hoofdstuk 15.
Begrippen¶
Object en uitsnede. Een object is wat er op de afbeelding gevonden is: een kader (soms met de vorm, het masker), een naam, een status en eventueel een beschrijving en een Commons-concept. Het is alleen gegevens, en het wordt bewaard tot de pagina een jaar niet geopend is. Een uitsnede is het beeldbestand dat je van een object maakt met Selectie opslaan: een JPG van het kader en een PNG van de vorm, in de volledige resolutie van het origineel. Uitsneden worden 30 dagen na het laatste gebruik verwijderd (tenzij ze op Commons staan); het object blijft dan, en opnieuw opslaan maakt de uitsnede opnieuw. Elke uitsnede hoort bij een object; een object heeft pas een uitsnede als je het opslaat. De miniaturen in de lijsten zijn geen uitsneden: die maakt de app telkens even voor het tonen. In de interface staat dit ook bij Gevonden objecten (uitsneden), de bewaartermijnen, de prullenbak en de lijst Bekeken (sinds 0.29.0).
1. Doel¶
Een experimentele webapp waarmee je een bestand op Wikimedia Commons opent, er objecten in detecteert (met box en masker), ze uitsnijdt als transparante PNG of als JPG, ze laat beschrijven, en de uitsneden na controle weer op Commons publiceert, met een nette koppeling naar het origineel.
Voorbeelden:
- Uit een album amicorum de losse wapenschilden, portretten en tekeningen halen, zoals uit Album amicorum van Jacob van Bronckhorst van Batenburg (8077131573).jpg (2000 × 1429 px, publiek domein).
- Uit een prent, kaart of krantenpagina op Commons de losse figuren, vignetten, logo's of illustraties uitsnijden.
- De figuren die op Commons al als regio zijn vastgelegd, los uitsnijden. Op Book of Hours of Philip of Burgundy - KW76F - folio 283r - Heaven - All Saints - Jean Le Tavernier.jpg staan 13 heiligen met een eigen rechthoek in beeldt af (zie 7.5). Elke heilige wordt een eigen bestand.
- Een gescande boekpagina (PDF, DjVu of TIFF met meerdere pagina's) doorzoeken op illustraties.
- Alle uitsneden van een bestand in één keer voorbereiden voor upload, met beschrijving, licentie, categorieën en beeldt af (depicts).
2. Verhouding tot CropTool¶
CropTool (croptool2.toolforge.org, broncode wpmed/croptool2, PHP, GPL-2.0, OAuth 1.0a, ondersteund door Wiki Project Med) is het gangbare gereedschap om op Commons een bestand bij te snijden. De Commons Mineventory is daar een verdieping op, geen vervanging.
| CropTool | Commons Mineventory | |
|---|---|---|
| Selectie | Eén rechthoek, met de hand getrokken; randdetectie | Veel objecten tegelijk, gevonden met AI (zoekterm, AI-suggesties per afbeelding, Aanwijzen), met maskers; handmatige rechthoek als terugvaloptie |
| Vorm van de uitsnede | Rechthoek | Rechthoek (JPG) of de vorm van het object (transparante PNG) |
| Bewerkingen | Rechtzetten, draaien, spiegelen, helderheid/contrast, verliesloos JPEG (jpegtran) | Geen beeldbewerking in fase 1. Wel: rand eromheen instelbaar, keuze PNG of JPG |
| Bestandstypen | JPEG, PNG, TIFF, SVG, WebP, GIF; één pagina uit PDF/DjVu | JPEG, PNG, TIFF, WebP; pagina's uit PDF/DjVu/TIFF (zie 5.4). Geen SVG en geen geanimeerde GIF |
| Resultaat | Origineel overschrijven, of één nieuw bestand | Altijd nieuwe bestanden, nooit het origineel overschrijven; meerdere uitsneden per keer |
| Beschrijving | Neemt de beschrijving van het origineel over | Nieuwe beschrijving per uitsnede: wat het model ziet (als voorstel), plus de gegevens van het origineel |
| Koppeling | {{Extracted from}} op de nieuwe pagina, {{Image extracted}} op het origineel |
Hetzelfde (zie 9.3) |
| Gestructureerde gegevens (SDC) | Niet bekend | Caption, beeldt af (P180), licentie en auteursrechtstatus overgenomen |
| Kosten | Gratis | SAM en Muse Spark kosten geld (zie 6.4) |
Bewuste keuzes:
- Geen eigen beeldbewerking. Wie wil rechtzetten of de helderheid aanpassen, gebruikt CropTool, eventueel op de nieuwe uitsnede.
- Geen "origineel overschrijven". Dat is CropTools terrein, en een uitsnede van een object is een ander werk dan het origineel.
- Na de upload een link "Openen in CropTool" bij elke uitsnede die op Commons staat (backlog 14a). CropTool neemt geen vooringevuld kader over (getest in 0.17.0); het detectiepaneel heeft nu Bijsnijden in CropTool voor het hele bestand (0.18.0).
3. Uitgangspunten¶
- Experiment. Geen officiële dienst van de KB of de Wikimedia Foundation. Dat staat in de footer.
- Detectie en beschrijving rechtstreeks via de Meta Model API (SAM 3.1 en Muse Spark), zoals in de Delpher Uitsnijder. Eén API-sleutel van de KB, op de server (besluit Olaf, 3-11-2026).
- Inloggen met het Commons-account van de gebruiker via OAuth 2.0. Uploads gebeuren op naam van die gebruiker.
- Uploaden alleen na een klik van de gebruiker, na een overzicht en een bevestiging. Nooit vanzelf.
- Geen live aanroepen naar de Meta Model API zonder expliciete opdracht van Olaf. Tests draaien op fixtures.
- Hosting: lokaal tijdens de bouw, daarna op Wikimedia Toolforge.
- RESTful: alles via
/api/v1; de UI is een client van dezelfde API. Een GET kost nooit geld en verandert niets. - Taal: de interface is meteen tweetalig, Nederlands en Engels (besluit Olaf, 3-11-2026). De documentatie is Nederlands; code, identifiers en commentaar zijn Engels. De API-velden blijven Nederlands, zoals in de Delpher Uitsnijder.
- Alle teksten in vertaalbestanden (
frontend/i18n/nl.jsonenen.json), gedeeld door de Jinja-templates en de Vue-componenten. Geen tekst hard in de code. - De taal volgt, in deze volgorde:
?uselang=in de URL (zoals op Commons), de keuze van de gebruiker (taalkeuze in de header, onthouden in de sessie), de taal van de browser, en anders Engels. - Foutmeldingen van de API blijven Nederlands (
{"fout": …}), met daarnaast een vaste code ("code": "not_found") die de UI vertaalt. - Andere talen kunnen later via translatewiki.net of een vertaalbestand erbij.
- Volledige resolutie: uitsneden en uploads altijd op de oorspronkelijke resolutie van het Commons-bestand, nooit op de verkleinde versie die naar het model gaat.
4. Wat hergebruikt wordt en wat vervalt¶
4.1 Overnemen (kopiëren en aanpassen, geen gedeelde bibliotheek)¶
| Delpher Uitsnijder | In de Commons Mineventory |
|---|---|
uitsnijder/detectie/basis.py, dummy.py, meta_sam.py, maskers.py |
Ongewijzigd: de detectorinterface, DummyDetector, MetaSamDetector (met meta-sam-parser), maskers lui decoderen en cachen |
uitsnijder/detectie/dienst.py |
De kern blijft: zoektermen, cache per afbeelding+term+model, samenvoegen van dubbelingen (IoU), selectie, prullenbak, opslaan, uitsnede-JPG. De Delpher-delen (zones, ALTO, bijschriften, koppeling aan artikelen) gaan eruit |
uitsnijder/prompts.py |
EN/MIN-syntax, de vertaaltabel en de lijst voor Alles detecteren (zie 7.4) |
uitsnijder/beschrijving.py |
"Wat staat hierop?" en het paginaoverzicht, met reasoning.effort en de modelkeuze. De context is anders: geen ALTO, wel de Commons-beschrijving, caption en categorieën (zie 6.2) |
uitsnijder/verbruik.py, /verbruik |
Ongewijzigd, plus de Commons-gebruiker per aanroep (zie 8.3) |
uitsnijder/cache.py, config.py, changelog.py, markdown_lite.py |
Ongewijzigd, met andere sleutels en variabelen |
uitsnijder/export.py |
Zip en JSON blijven; de IIIF-export wordt een backlog-item |
uitsnijder/api.py, openapi.py |
Zelfde opbouw en conventies ({"fout": …}, X-Robots-Tag, 201 bij aanmaken, oude paden markeren), andere resources (hoofdstuk 11) |
static/js/viewer.js, app.js, lightbox.js, objecten.js, verbruik.js |
De viewer (zoom, pan, overlays, klik/Ctrl-klik, Aanwijzen) wordt een gewone JS-module, gebundeld door Vite. De rest (panelen, vergroter, objectenpagina, verbruik) wordt opnieuw opgebouwd als Vue-componenten met Codex, met dezelfde logica (hoofdstuk 10) |
docs/commons-beschrijving.md |
Basis voor de uploadstap: keuzemenu, rechtenlabels, controle vooraf, proefweergave, maxlag, één upload tegelijk |
| Tests met fixtures | Dezelfde aanpak; de opgenomen SAM- en Muse-antwoorden kunnen mee |
4.2 Vervalt¶
- De Delpher-adapter (
delpher.py): metadata, DIDL, OCR per artikel,imageheader, de imageviewer van de KB, de resolver. - ALTO en alles wat ervan afhangt: koppen, illustratieblokken, bijschriften uit de OCR (
bijschrift.py), "tekst eromheen" als controle van de OCR. - De krantenhiërarchie (
hierarchie.py): aflevering › pagina › artikel, de koppelregel object → artikel,config/delpher_collectiesets.jsonen de typedetectie krant/tijdschrift/boek. - De Delpher-stijl (
delpher-theme.css, het Delpher-logo) en de Firefox-extensie (die kan later terugkomen als "Openen in de Commons Mineventory", zie de backlog). - De rechtenregel op verschijningsjaar (
rechten.py,RECHTEN_GRENSJAAR). Op Commons is de licentie al vastgesteld; zie 5.3. - Het bot-wachtwoord uit
docs/commons-beschrijving.md. In plaats daarvan OAuth (hoofdstuk 8).
4.3 Nieuw¶
- Een Commons-adapter (
commons.py): bestand opzoeken, imageinfo, wikitekst, SDC, pagina's van PDF/DjVu/TIFF. - OAuth 2.0 en een sessie per gebruiker.
- Upload naar Commons met wikitekst en SDC.
- Gratis regio's uit Commons zelf (de opvolger van "Uit Delpher", zie 7.5).
- Een daglimiet per gebruiker naast de algemene daglimiet.
5. De bron: Wikimedia Commons¶
5.1 Invoer¶
De gebruiker plakt in het invoerveld een van:
- een bestandspagina:
https://commons.wikimedia.org/wiki/File:Album_amicorum_….jpg(ookBestand:en andere taalvarianten,?uselang=…,/w/index.php?title=File:…, en#-fragmenten); - een directe bestandslink op
upload.wikimedia.org(ook een thumbnail-URL: de app leidt de bestandsnaam af); - een titel met of zonder
File:, met spaties of underscores; - een M-id (
M28830642) of eencurid.
Eén verzoek normaliseert dit naar de canonieke titel en de page-id. Een redirect (hernoemd bestand) wordt gevolgd en gemeld. Bestaat het bestand niet, of staat het niet op Commons maar op een andere wiki, dan meldt de app dat met een voorbeeld-URL.
Een categorie als invoer (alle bestanden in Category:… als lijst om door te bladeren, net als een aflevering in Delpher) komt in fase 2 (besluit Olaf, 3-11-2026). Sinds 5-11-2026 uitgewerkt als dashboard met collecties, vóór de bewerker: zie hoofdstuk 17. Besluit Olaf (5-11-2026): dat wordt nu gebouwd, vóór OAuth.
5.2 Gegevens ophalen (MediaWiki Action API)¶
Alles via https://commons.wikimedia.org/w/api.php, met een eigen User-Agent, maxlag=5, caching en hooguit ongeveer één verzoek per seconde.
| Wat | Aanroep |
|---|---|
| Titel, page-id, redirect | action=query&titles=…&redirects=1&prop=info |
| Afmetingen, MIME, SHA-1, origineel | prop=imageinfo&iiprop=url|size|mime|sha1|extmetadata|bitdepth |
| Verkleinde versie voor de viewer en het model | iiurlwidth=… (thumbnail-URL). Commons beperkt thumbnails tot vaste stapgroottes; de app vraagt de dichtstbijzijnde stap aan in plaats van een willekeurige breedte. Bij de bouw verifiëren welke stappen er nu zijn |
| Licentie en maker (leesbaar) | extmetadata: LicenseShortName, License, UsageTerms, Artist, Credit, ImageDescription, DateTimeOriginal, Attribution, AttributionRequired, Restrictions |
| Wikitekst | prop=revisions&rvprop=content|ids&rvslots=main (voor de sjablonen: licentie, {{Information}}/{{Artwork}}, {{Personality rights}}, {{Trademarked}}, {{Delete}}, {{Flickrreview}}, {{ImageNote}}) |
| Gestructureerde gegevens | action=wbgetentities&ids=M<pageid>: captions, P180 beeldt af (met kwalificatoren), P6216 auteursrechtstatus, P275 licentie, P170 maker, P571 datum, P195 collectie, P7482 bron |
| Categorieën | prop=categories&clshow=!hidden (zichtbaar) en apart de verborgen |
| Meerpaginabestanden | iiprop=…|metadata en pagecount; per pagina een thumbnail met iiurlparam=page<n>-<breedte>px |
| Bestaat de uitsnede al? | list=allimages&aisha1=<sha1> (zie 9.5) |
Voor het origineel in volledige resolutie haalt de server het bestand één keer op van upload.wikimedia.org en cachet het. Uitsnijden gebeurt altijd op dat origineel.
5.3 Licentie, maker en rechten¶
Op Commons staat elk bestand al onder een vrije licentie of in het publieke domein. De app hoeft dus niet zelf te raden of iets vrij is, zoals bij Delpher. Wel:
- De uitsnede erft de licentie van het origineel. Een uitsnede is een afgeleid werk; bij CC BY-SA moet de uitsnede ook onder CC BY-SA, met naamsvermelding. De app neemt de licentiesjablonen uit de wikitekst van het origineel letterlijk over (zie 9.3) en de licentie- en statusverklaringen uit de SDC.
- Maker en naamsvermelding komen uit het origineel (
|author=of{{Creator:…}},Artist,Attribution). De uitsnede vermeldt het origineel als bron. - Waarschuwen, niet blokkeren, net als in de Delpher Uitsnijder. Rechtenlabels per uitsnede, aangepast aan Commons:
| Label | Wanneer |
|---|---|
| Merk | Het origineel heeft {{Trademarked}}, of "Wat staat hierop?" zegt soort = logo/advertentie, of noemt een bedrijf. Standaard uit; mee na bevestiging met een reden |
| Persoonlijkheidsrechten | {{Personality rights}} op het origineel en de uitsnede toont een persoon |
| Origineel ter discussie | {{Delete}}, {{Copyvio}}, {{No permission since}} of een openstaande licentiecontrole ({{Flickrreview}} zonder bevestiging, {{LicenseReview}}). Uploaden uitgeschakeld, zoals CropTool dat ook doet bij Flickr-bestanden die nog wachten |
| Alleen in de VS vrij | {{PD-US-only}}-achtige sjablonen. Ter info: dat mag op Commons niet, dus de app meldt het |
| Naamsvermelding verplicht | CC BY / CC BY-SA en dergelijke: de app zet de maker en de licentie verplicht in de nieuwe pagina |
| In orde | Publiek domein of een vrije licentie, zonder de signalen hierboven |
5.4 Bestandstypen en resolutie¶
- JPEG, PNG, WebP, TIFF: direct. TIFF wordt intern naar RGB omgezet; de uitsnede wordt PNG of JPG.
- PDF en DjVu: per pagina, als de gerenderde pagina van Commons (
page<n>-<breedte>px) op de grootste beschikbare breedte. Dat is niet de "echte" scan, maar meestal de beste die Commons levert, en het volstaat (besluit Olaf, 3-11-2026). De app rendert PDF's niet zelf. - Meerpagina-TIFF: per pagina, uit het origineel.
- SVG, GIF, video en audio: niet ondersteund; de app meldt dat.
- Grote bestanden: Commons heeft scans van honderden megapixels. Pillow beschermt tegen "decompression bombs"; op Toolforge is het werkgeheugen per webservice beperkt. Voorstel: tot 100 megapixel gewoon verwerken; daarboven alleen detecteren op de verkleinde versie en uitsnijden in tegels uit het origineel, of weigeren met een melding. Niet beantwoord in ronde 2; de app gaat uit van het voorstel (100 megapixel), bij de bouw te meten op Toolforge.
Gebouwd in 0.21.0 (besluit Olaf, 4-11-2026): boven
MAX_MEGAPIXELSleest de app het origineel met libvips (pyvips[binary],cutter/tegels.py) stuk voor stuk. Detecteren en de viewer gebruiken de verkleinde versie van Commons, zoals bij elk bestand; voor een uitsnede, het voorbeeld en de vraag aan Muse Spark wordt alleen het nodige stuk gedecodeerd, in volledige resolutie. JPEG, PNG en (meerpagina-)TIFF; 16-bits, grijs en CMYK worden 8-bits sRGB. Gemeten: een uitsnede van 2000 × 1500 uit een JPEG van 150 megapixel piekt op ongeveer 100 MB geheugen (Pillow zou het hele beeld decoderen, ongeveer 450 MB). Zonder pyvips weigert de app zulke bestanden, zoals voorheen.
5.5 Hiërarchie¶
Veel platter dan bij Delpher:
- Bestand (titel, M-id, licentie, maker, datum, categorieën).
- Pagina (alleen bij PDF/DjVu/TIFF; bij een gewone afbeelding is er één pagina).
- Object: de detectie, met box, masker, label, score, herkomst, beschrijving en het Commons-concept.
Opslag: uitvoer/<M-id>/objecten.json per bestand en per pagina, zoals in de Delpher Uitsnijder. De M-id is stabiel, ook als het bestand wordt hernoemd.
6. Detectie en beschrijving¶
6.1 Detectie (SAM 3.1)¶
Ongewijzigd ten opzichte van de Delpher Uitsnijder (docs/meta-sam-api.md):
POST https://api.meta.ai/v1/responsesmetmodel: sam-3.1, één Engelse noun phrase per aanroep, of een punt- of boxprompt (Aanwijzen).- De server stuurt een verkleinde versie (standaard 1920 px breed) als base64-data-URL. Besloten (3-11-2026): data-URL, zoals in de Delpher Uitsnijder. Dan haalt Meta niets zelf op bij Wikimedia, en bepaalt de app de resolutie.
- Antwoord via
meta-sam-parser; maskers lui decoderen en cachen. - Cache per SHA-1 van het bestand + pagina + term + model. Een nieuwe versie van het bestand (andere SHA-1) geeft dus een nieuwe detectie.
6.2 Beschrijving (Muse Spark)¶
"Wat staat hierop?" per object en "Wat staat op deze pagina?" per bestand, zoals in docs/beeld-taalmodel.md, met dezelfde JSON-velden (soort, onderwerp, bedrijf_of_naam, tekst_in_beeld, tekst_rond_beeld, beschrijving, zekerheid). Verschillen:
- Context voor het model: de beschrijving en de caption van het origineel (als platte tekst, ingekort), de zichtbare categorieën en de bestaande beeldt af-items, uitdrukkelijk als hulp en niet als waarheid. In plaats van de ALTO-tekst. Daarnaast (sinds 0.13–0.16): het bijschrift van de uitsnede, de aanwijzing van de gebruiker (AI-bijsturing) en de tekst die het paginaoverzicht in en onder de hele afbeelding las.
- Lengte (wens Olaf, 6-11-2026, sinds 0.33.2): in de AI-modifiers van Wat staat hierop? staat dezelfde schuif als bij de beschrijving van de hele afbeelding (7.6): Kort, Normaal (een of twee zinnen, zoals voorheen), Commons-caption (hooguit 250 tekens, op de server afgekapt als het toch langer is) en Uitgebreid (een alinea). Hij bepaalt
beschrijvingenbeschrijving_envan de volgende vraag; het onderwerp en de andere velden blijven zoals ze zijn. De schuif begint op de lengte van het laatste antwoord, de samenvatting naast de knop noemt een andere lengte dan Normaal, en het antwoord bewaartbeschrijvingsniveau. Elke lengte is een eigen antwoord in de cache; Normaal houdt de oude sleutel. API:beschrijvingsniveaubijPOST …/beschrijving. - Aanwijzing uit de detectie (wens Olaf, 8-11-2026, sinds 0.33.8;
detection_clueincutter/beschrijving.py): de vraag krijgt één zin mee over wat de app al weet van het object, als aanwijzing, niet als waarheid. Voorrang: een eigen naam (potlood), dan het label van een regio uit Commons, dan de zoekterm van SAM met de zekerheid (found this object when searching for "table" (certainty 75%). It is probably (part of) what "table" describes … Check what you see); onder 50% (CLUE_SURE) zegt de zin dat de detectie onzeker was. Een eigen naam gaat altijd mee, bij elk soort object: gevonden, getekend, aangeklikt of een groep (bij een groep als naam van het geheel, naast de groepszin met de leden, die hun eigen namen al gebruikt; wens Olaf, 8-11-2026). Zonder eigen naam geen zin bij een groep (die noemt zijn leden al), een getekend kader of een klik; nooit bij een eigen prompt. Sinds 0.40.3 (wens Olaf, 13-11-2026) noemt de zin ook de woorden onder Ook gevonden als (het gezochte Engelse woord met de hoogste zekerheid, niet de eigen term, geen klik of rechthoek; een weggehaald woord niet): The image detector also found it when searching for "sailor hat" (certainty 81%)., ook achter een eigen naam of een regio uit Commons, niet bij een groep. Onder AI-bijsturing zegt een regel welke woorden meegaan. De zin staat in de zichtbare prompt, hoort bij de cachesleutel (objecten zonder aanwijzing houden hun antwoord uit de cache) en het antwoord bewaartdetectie_aanwijzing. Waarom: zeker met 0% ruimte ziet de AI alleen het object, zonder de context waarin SAM het vond. Risico: de AI neemt een fout van SAM over; daarom de zekerheid en check what you see. Of het helpt, toetst Olaf met een kleine vergelijking (betaald): vergelijking-detectie-aanwijzing.md, backlog 12i. - Eigen prompt (wens Olaf, 8-11-2026, sinds 0.33.8; sinds 0.40.2 binnen AI-bijsturing, als dichtgeklapt Prompt aanpassen onder aanwijzing, lengte en ruimte, wens Olaf 13-11-2026: de prompt is de zwaarste vorm van bijsturen): Prompt aanpassen, ook bij een groep, toont welke prompt de volgende vraag gebruikt, die van de app of je eigen, met Tonen de hele tekst. Met het potlood pas je hem aan (Prompt bewaren, Annuleren, Begin opnieuw met de prompt van de app); Terug naar de prompt van de app draait het terug; Eerdere prompts (n) houdt je vorige eigen prompts (hooguit 20) om opnieuw te gebruiken of te verwijderen. Bij een groep staat daaronder, als Deel van de prompt van de app voor deze groep, de groepszin met de schakelaar Alleen deze objecten en de eerdere beschrijvingen van de leden (eerst was dat een aparte rij AI-prompt naast een Volledige AI-prompt; dat was verwarrend). Een eigen prompt geldt per object, vervangt de prompt van de app helemaal (ook dat groepsdeel, dat dan grijs wordt), en de aanwijzing komt er nog bij; het is een vaste tekst, dus een latere wijziging van titel of bijschrift zit er niet in. Elke eigen prompt is een eigen antwoord in de cache, en het antwoord bewaart
prompt_eigen. Ook Beschrijven in de bulkacties gebruikt hem. Waar dit in het tabblad komt: zie het herontwerp in ontwerp-wat-is-dit.md (subtabblad AI-prompt en bijsturing). API:GET,PUTenDELETE …/beschrijving/prompt,DELETE …/beschrijving/prompt/geschiedenis/{versie}. - Nieuw veld
wikidata_suggesties: hooguit drie zoektermen voor beeldt af (bijv. "coat of arms", "Jacob van Bronckhorst van Batenburg"). De app zoekt die gratis op metwbsearchentities; de gebruiker kiest het item. Het model verzint zelf geen Q-nummers. - Taal: beschrijving en caption in het Nederlands én het Engels (in één aanroep). Niet beantwoord in ronde 2; dit is het voorstel, en het past bij de tweetalige interface. Het paginaoverzicht geeft sinds app-versie 0.9.0 ook soort en samenvatting in beide talen (
paginasoort_en,samenvatting_en);soortenzekerheidkomen uit een vaste Nederlandse lijst en de interface vertaalt ze. - Met de hand aanpassen (gebouwd, 0.6.0; sinds 0.22.1 met een potloodje per veld): onderwerp en beschrijving (nl en en), naam, tekst in en rond het beeld, met Ongedaan maken na het opslaan; ook in de lightbox naast het grote beeld (0.22.0). De eerste keer dat een veld verandert, bewaart de app de AI-tekst in
ai_origineel, zodat Terug naar de AI-tekst altijd kan;bewerktzegt of er nog iets afwijkt. - Herkenbaar als AI (gebouwd, 0.8.0): bij soort, onderwerp, beschrijving, het paginaoverzicht en Bron: AI-beelddetectie staat een AI-merkje. Een klik opent een venster dat uitlegt wat het model deed (met een link naar het model en, bij de detectie, de score van het object), wat er mis kan gaan en wat de gebruiker moet controleren. De waarschuwing dat een taalmodel zich kan vergissen staat in het blok Model, kosten en kwaliteit.
6.3 Contributor of Standard¶
De regel uit de Delpher Uitsnijder ("Contributor alleen als alles klopt") wordt:
- P6216 van het origineel is publiek domein (
Q19652) én de licentie is een PD-sjabloon (geen CC). Bij CC-licenties zou Meta het werk mogen gebruiken om te trainen zonder de voorwaarden (naamsvermelding, gelijk delen) na te komen; dat doen we niet. - Geen labels Merk, Persoonlijkheidsrechten of Origineel ter discussie.
BEELDMODEL_CONTRIBUTOR=aan(standaardaan, zie onder).
Anders: Standard.
Besloten door Olaf (3-11-2026): Contributor aan voor publiek domein, ook voor bestanden van anderen. BEELDMODEL_CONTRIBUTOR staat daarom standaard op aan. Voorwaarden 1 en 2 blijven gelden: bij twijfel gaat het naar Standard. Per aanroep wordt vastgelegd welk model is gebruikt en waarom, zoals in de Delpher Uitsnijder. De reden staat er als Nederlandse tekst (voor logs en verbruik) en als code (reden_code: publiek_domein, contributor_uit, rechtenlabel, niet_vrij, standaard_gekozen) die de interface in gewone woorden toont, met een link naar Meta's uitleg van de Contributor-modus.
6.4 Kosten en limieten¶
Op basis van de metingen in de Delpher Uitsnijder:
| Actie | Aanroepen | Kosten (ongeveer) |
|---|---|---|
| Eén zoekterm | 1 SAM | $0,0025 |
| Aanwijzen (puntprompt), ook met een AI-hint | 1 SAM | $0,0025 (met een hint die al gezocht is: gratis) |
| Tekenen met een AI-hint | 1 SAM | $0,0025 (zonder hint gratis) |
| Alles detecteren | 8 SAM | $0,02 |
Wat staat hierop? (low) |
1 Muse | $0,005 (Standard), $0,0003 (Contributor) |
Wat staat op deze pagina? (low) |
1 Muse | $0,007 |
| AI-suggesties en dan Alle objecten lokaliseren | 1 Muse + n SAM | ±$0,03 |
| Een typische sessie: één bestand, Alles detecteren, tien beschrijvingen | 8 SAM + 10 Muse | ±$0,07 |
Limieten:
- Daglimiet per gebruiker (
DAGLIMIET_PER_GEBRUIKER, 100 aanroepen, besloten 3-11-2026) en een algemene daglimiet van 500 aanroepen (DAGLIMIET_AANROEPEN=500) plus een dagbudget van $2 (DAGBUDGET_USD=2), beide besloten door Olaf op 3-11-2026. Boven een limiet: 429 met de resterende tijd. - In live-modus vraagt de app vóór elke betaalde actie om bevestiging, met het bedrag (zoals nu).
- Meta: 3000 verzoeken per minuut voor SAM; Contributor heeft lagere limieten.
Wie betaalde aanroepen mag doen: zie 8.3 (een toegangslijst). De limieten zijn aan te passen in het beheerpaneel (8.4). Op Toolforge komt daar een starttegoed van ongeveer $0,25 per ingelogde gebruiker bij, en daarna een eigen Meta-sleutel (8.6, voorstel).
7. Detectiemodi¶
Alle modi uit de Delpher Uitsnijder blijven, op één gedeelde selectie per pagina.
7.1 Zoeken met een zoekterm¶
Zoekwoorden aanpassen voor het lokaliseren (wens Olaf, 13-11-2026; LocateDialog.vue): elke zoekopdracht met woorden (zoeken, de AI-suggesties, de beeldt af-items) gaat via één venster: wat er gezocht wordt, bewaarde antwoorden of SAM opnieuw, en de kosten. Daaronder, dichtgeklapt, AI-bijsturing met Zoekwoorden voor SAM: per term het Engelse woord, aan te passen. SAM kent geen prompt of denkniveau, alleen het beeld en een kort woord; dat woord is dus zijn opdracht. Wat een aangepast woord vindt, telt onder de oorspronkelijke term (de knop houdt zijn aantal, een beeldt af-item blijft gekoppeld); het bedrag rekent mee, want een nieuw woord is een nieuwe vraag.
EN/MIN-syntax, Nederlandse termen via de vertaaltabel naar Engels, één SAM-aanroep per begrip.
7.2 Snel zoeken¶
Uit de interface gehaald (4-11-2026, besluit Olaf): op Commons staan duizenden soorten objecten, dus een vaste lijst klopt voor veel afbeeldingen niet. De AI-suggesties per afbeelding (7.6) vervangen dit. Sinds 0.21.0 is ook de API-modus categorie weg.
Vaste groepen, aangepast aan wat er op Commons staat: wapens en heraldiek, portretten, figuren en personen, dieren, planten en bloemen, gebouwen, kaarten, schepen, initialen en vignetten, logo's en beeldmerken, handschrift en tekstblokken, foto's in een album. Elke groep is een vooringevulde prompt.
7.3 Aanwijzen¶
Klikken op een plek zonder bekend object: een puntprompt aan SAM (één betaalde aanroep), resultaat als kandidaat. Een handmatige rechthoek (gratis) heeft een eigen blok, Rechthoek tekenen; Shift-slepen doet hetzelfde zonder die modus.
AI-hint (wens Olaf, 12-11-2026, sinds 0.40.0). Bij Aanwijzen en bij Tekenen staat een veld AI-hint (optioneel), elk met een eigen woord, bijv. auto. SAM neemt per aanroep óf een woord óf een punt of rechthoek, nooit allebei (zie meta-sam-api.md in de Delpher Uitsnijder); de hint gaat daarom als woordzoektocht, waarvan de app alleen het passende deel houdt:
- Aanwijzen met een hint: één zoektocht naar het woord in de hele afbeelding (het bewaarde antwoord als het woord al gezocht was: gratis). Alleen de kleinste vondst waarvan de vorm onder de klik ligt, komt op de pagina, als kandidaat; de andere vondsten niet. Ligt er niets onder de klik, dan meldt het paneel Geen ‘auto’ gevonden op deze plek en komt er niets bij. Er volgt geen tweede aanroep zonder hint.
- Tekenen met een hint: alleen de rechthoek met 10% ruimte per kant gaat naar SAM, in een hogere resolutie dan de hele afbeelding (een klein object is zo groter in beeld), met de vraag naar het woord. De vondst die het meest van de rechthoek bedekt, wordt het object, met zijn vorm en aangevinkt. Vindt SAM niets, dan blijft de rechthoek bewaard zoals zonder hint, met het woord als zoekterm. Tekenen met een hint kost één aanroep (met bevestiging en bedrag); zonder hint en met Shift-slepen (ook als het veld gevuld is) blijft het gratis.
- Het object krijgt het woord als zoekterm (in plaats van klik of rechthoek), zodat het meetelt bij de vinkjes en bij het zoeken.
7.4 Bulk-operaties¶
Vier tabbladen (wens Olaf, 6-11-2026, sinds 0.33.3). Onder de lijst in Gevonden objecten (uitsneden), onder 27 objecten, 27 geselecteerd en boven Selectie opslaan, staan de bulkacties in vier omkaderde tabbladen (CdxTabs). Zo staan ze niet meer door elkaar.
27 objecten, 27 geselecteerd
┌ Beschrijven (26) │ Ontdubbelen │ Groeperen (27) │ Prullenbak (27) ┐
│ [ Geselecteerde beschrijven (26) $0,17 ] Alle beschrijven (26) │
│ Wat de knop doet; alle = alle zichtbare objecten zonder beschrijving│
└─────────────────────────────────────────────────────────────────────┘
[ Selectie opslaan (27) ] [ Downloaden (zip) ] [ Naar Commons… ]
| Tabblad | Selectie | Alle (zichtbaar) | Per soort |
|---|---|---|---|
| Beschrijven (n) | Geselecteerde beschrijven: alleen die zonder beschrijving, betaald | Alle beschrijven: alle zichtbare zonder beschrijving, betaald | alle bord (5) met bedrag: de zichtbare van die soort zonder beschrijving, betaald (sinds 0.33.8) |
| Ontdubbelen | Geselecteerde ontdubbelen: alleen dubbelingen onder de geselecteerde | Alle ontdubbelen: onder alle zichtbare | nee |
| Groeperen (n) | Geselecteerde groeperen (twee of meer) | Alle groeperen: alle zichtbare als één groep | alle hoed (17) |
| Prullenbak (n) | Geselecteerde naar de prullenbak (rood) | Alle naar de prullenbak | alle hoed (17) |
Besluiten van Olaf (6-11-2026, vragenformulier):
- Alle betekent alle zichtbare objecten (boven de minimale zekerheid en passend bij het zoekveld), naast de selectie en, bij beschrijven, groeperen en de prullenbak, per soort.
- Ontdubbelen heet voortaan zo, niet meer Dubbelingen samenvoegen: samenvoegen en groeperen klinken voor een gebruiker hetzelfde. Ontdubbelen maakt van objecten die hetzelfde tonen één object (de rest staat erin onder ook); groeperen maakt van verschillende objecten samen één. Beide knoppen: de selectie en alle zichtbare (API: {"objecten": [ids]} bij POST …/samenvoegingen).
- Beschrijven beschrijft alleen objecten zonder beschrijving, zoals voorheen. Eerst zonder per soort; op 7-11-2026 wilde Olaf het toch, zoals bij groeperen en de prullenbak: per zoekterm de zichtbare objecten zonder beschrijving (geen groepen), met het bedrag bij elke link en de gewone bevestiging met miniaturen.
- Het tabblad Beschrijven staat steeds open bij het openen van een bestand of pagina.
Het venster van Beschrijven (sinds 0.33.8, wens Olaf 8-11-2026). Voordat de AI meer objecten beschrijft, maakt het venster de instellingen expliciet die anders stilzwijgend golden, net als bij Wat is dit? in de vergroter. Ze staan in de uitklapper Instellingen voor de AI, standaard dicht (de tabel erboven toont ze al per object); een klik op één object in de tabel klapt hem open:
- Aanwijzing voor de AI (optioneel): gaat mee met elk object; wordt geen bijschrift en gaat niet naar Commons.
- Lengte: dezelfde schuif als bij Wat is dit?, van een paar woorden via een Commons-caption (hooguit 250 tekens, nooit meer) tot een alinea, met ernaast de schakelaar Commons-caption met het Commons-merkje. Begint op Commons-caption (wens Olaf).
- Ruimte rond de uitsnede: begint hier op 0%, zodat de AI alleen het object zelf ziet en andere dingen in het beeld de beschrijving niet kleuren (in de vergroter is het 25%).
- Prompt voor de AI (uitklapper, dicht): de prompt zoals hij naar het model gaat, voor het gekozen object, en die volgt de instellingen. Alleen te lezen; de app maakt hem zelf, of het is de eigen prompt van dat object (6.2). Per object verschillen de titel, een eigen bijschrift en bij een groep de leden. Via GET …/objecten/{id}/beschrijving/prompt (gratis).
- Wat de AI ziet: naast de instellingen het voorbeeld met het rode kader, zoals bij Wat is dit?, voor het gekozen object; het volgt de schuif Ruimte rond de uitsnede. Klik op een object in de lijst, of gebruik de pijltjes, om een ander object te zien. Het venster zegt zelf voor welke objecten de instellingen gelden, zonder naar Wat is dit? te verwijzen (wens Olaf: het venster legt zichzelf uit).
De objecten staan in een tabel met per object zijn AI-parameters: Lengte, Ruimte, Aanwijzing en Prompt (van de app of een eigen prompt); ze veranderen meteen mee met de instellingen (wens Olaf). Elk object heeft zijn eigen instellingen (wens Olaf): bovenaan de tabel staat Alle objecten (n), standaard gekozen; dan gaat een wijziging naar alle objecten. Klik je op één object, dan gelden de instellingen alleen voor dat object, en zie je zijn voorbeeld en prompt. Een zin boven de instellingen zegt steeds voor wie je ze aanpast. Naast Alle objecten zet Standaardwaarden herstellen (voor alle objecten) elk object terug op Commons-caption, 0% ruimte en geen aanwijzing. Daaronder Niet tevreden met de AI-beschrijvingen?: na het beschrijven pas je elke beschrijving per object aan in de vergroter (het oog in de objectenlijst, tabblad Wat staat hierop?): bewerken, opnieuw vragen met andere instellingen of een eigen prompt, een eerdere versie terugzetten (wens Olaf). Dan het bedrag; pas na Beschrijven (n) gaat er iets naar het model, met deze instellingen voor elk object. Het venster verschijnt ook in de proefmodus (dan gratis), omdat de instellingen er ook dan toe doen. Elke keer dat het opent, staan de instellingen weer op de beginwaarden. - Het getal in de tabnaam: bij Beschrijven hoeveel geselecteerde objecten nog een beschrijving krijgen, bij Groeperen en Prullenbak hoeveel er geselecteerd zijn. Ontdubbelen heeft geen getal. - Elke betaalde of verwijderende actie vraagt eerst om bevestiging, met de objecten in het venster; de prullenbak geeft één melding met Ongedaan maken voor allemaal. Bij regio's uit Commons zegt het venster dat er op Commons niets verandert. De uitkomst (bijv. 3 dubbelingen samengevoegd) staat als melding onder de tabbladen.
Sinds 0.30.0 (besluit Olaf, 5-11-2026) staan Selectie beschrijven (sinds 0.31.0 Geselecteerde objecten beschrijven) en Dubbelingen samenvoegen niet meer in de kolom Beschrijven en vinden, maar onderaan Gevonden objecten (uitsneden), boven Selectie opslaan: ze werken op wat je gevonden en aangevinkt hebt. Het blok Bulk-operaties is daarmee vervallen.
Geselecteerde objecten beschrijven (alleen de geselecteerde objecten zonder beschrijving) en Dubbelingen samenvoegen. Elke betaalde stap met bevestiging en kosten. Een knop is uitgeschakeld als er niets te doen is: geen aangevinkte objecten zonder beschrijving, of minder dan twee objecten. Onder de knoppen staat in een grijze regel wat Geselecteerde objecten beschrijven zal doen: hoeveel geselecteerde objecten nog geen beschrijving hebben, welke worden overgeslagen, en als ze allemaal al beschreven zijn dat opnieuw beschrijven per object in de vergroter gaat.
Sinds 0.28.0 uit de interface (besluit Olaf, 4-11-2026): Alles detecteren (SAM met een vaste lijst soorten beeld, zoals illustratie, portret en wapen) en Slim detecteren (eerst het paginaoverzicht, dan SAM met de voorgestelde termen). Alle objecten lokaliseren bij de AI-suggesties doet hetzelfde met termen die bij deze afbeelding passen. In de API blijft modus: "alles" bestaan.
Groeperen (wens Olaf, 5-11-2026, zoals in PowerPoint; gebouwd in 0.32.4, backlog 12g). Bij veel kleine objecten van één soort, zoals 15 waterdruppels en 9 bladeren op een stilleven, wil je niet 24 losse uitsneden, maar bijvoorbeeld groep waterdruppels en groep bladeren.
- Groeperen (n) onder de objecten in Gevonden objecten (uitsneden), naast Dubbelingen samenvoegen: maakt van de geselecteerde objecten (twee of meer) één object. Uitgeschakeld bij minder dan twee.
- Groepeer alle … per zoekterm, met één klik (besluit Olaf): onder de zoektermen staat Groeperen: alle waterdruppels (15) · alle bladeren (9) voor elke zoekterm met twee of meer losse objecten.
- Het groepsobject: het kader is het kleinste kader om alle leden heen; het masker is de vereniging van hun maskers (wat in minstens één masker valt). De naam is groep: + de soort + het aantal (groep: waterdruppel (15), Engels group: water drop (15)); een bijschrift geeft hem een eigen naam. Bron en zekerheid: die van de leden (de laagste zekerheid), met het merkje groep (15).
- Bevestigen (wens Olaf): groeperen en opheffen vragen eerst om bevestiging in een venster met de objecten, elk met een kleine uitsnede. Bij groeperen een veld voor een eigen naam (niet verplicht); de voorgestelde naam staat er in het grijs in. Geen aparte melding achteraf.
- De leden blijven bewaard in de groep, niet in de prullenbak. Groep opheffen (in de lijst) zet ze terug zoals ze waren, en verwijdert het groepsobject. Een beschrijving of bijschrift van de groep gaat dan verloren, na een bevestiging.
- Beschrijven (Wat staat hierop?, sinds 0.32.4–0.32.6): de vraag aan de AI krijgt een AI-prompt mee met de objecten van de groep. Zonder ruimte rond de uitsnede: beschrijf alleen deze objecten; negeer de rest; met ruimte: beschrijf alleen deze objecten als onderwerp, en gebruik de omgeving alleen als context (bijvoorbeeld een onderschrift). De eerdere beschrijvingen van de objecten gaan mee als context, gemarkeerd als eerdere AI-antwoorden die fout kunnen zijn. De rij AI-prompt toont wat meegaat; de schakelaar Alleen deze objecten zet het uit (API:
alleen_groep). - Naar Commons (besluit Olaf): een groep mag als één uitsnede naar Commons, zoals elk ander object: het kader in volledige resolutie, met het masker als transparante PNG. De beschrijving door de AI gaat over de groep als geheel.
- Anders dan Dubbelingen samenvoegen: samenvoegen maakt van objecten die vrijwel op dezelfde plek liggen één object en gooit de rest weg; groeperen houdt verschillende objecten bij elkaar en is terug te draaien.
- Gratis: alles gebeurt op de server, zonder aanroep van een model.
- API: POST
…/pagina/{n}/groepenmet{"objecten": [ids]}of{"zoekterm": "water drop"}geeft 201 met het groepsobject; DELETE…/pagina/{n}/groepen/{id}heft de groep op.
7.5 Uit Commons (gratis, zonder SAM)¶
De opvolger van "Uit Delpher": regio's die op Commons al bestaan. Eis van Olaf (3-11-2026): de app moet de regio's uit de gestructureerde gegevens (de gele rechthoeken op de bestandspagina) vinden en elke regio als aparte afbeelding kunnen uitsnijden en uploaden.
Regio's in de gestructureerde gegevens (belangrijkste bron)
- Op Commons kun je bij beeldt af (P180) met de kwalificator P2677 relatieve positie in afbeelding aangeven waar het item staat. Commons zelf tekent die niet (nagekeken 6-11-2026): er is geen standaard-gadget voor. Wie het gebruikersscript van Lucas Werkmeister heeft aangezet (User:Lucas_Werkmeister/wd-image-positions.js, bij de tool Wikidata Image Positions), ziet ze bij het aanwijzen van het beeld als rechthoeken met alleen het label van het item; kwalificatoren zoals aantal (P1114) toont die tool niet. De notities ({{ImageNote}}) worden wel standaard getekend, door de gadget ImageAnnotator, met hun volledige tekst. In deze app tekent de viewer de regio's geel met hun naam (7.5).
- De waarde is
pct:x,y,b,h: linksboven en de afmetingen, in procenten van de breedte en hoogte van de afbeelding. Volgens IIIF bestaat ook de vorm in pixels (x,y,b,hzonderpct:); de app leest beide. - Voorbeeld, het bestand met Alle Heiligen (M83565772), gelezen op 3-11-2026: 13 verklaringen P180 met P2677, bijvoorbeeld Catharina van Alexandrië (Q179718) op
pct:35.5814,68.7074,21.0853,24.2104en Johannes de Doper (Q40662) oppct:45.1206,35.0335,9.75884,16.4123. - De app leest ze met
wbgetentities(zie 5.2), rekent ze om naar pixels van het origineel en maakt per regio een object: - bron
commons, soortregio; - label = het Wikidata-label in het Nederlands, of in het Engels als dat er niet is; de Q-id staat erbij;
- box = de regio, masker = een rechthoek;
- herkomst: de M-id, het id van de verklaring en de waarde van P2677, zodat de koppeling met het origineel controleerbaar blijft.
- Regio's overlappen vaak, zoals de heiligen in het voorbeeld. Dat geeft niets: elke regio is een eigen object. Ze worden niet samengevoegd met de IoU-regel.
- Optioneel een masker met SAM: per regio één boxprompt aan SAM (
<|box;…|>, ziedocs/meta-sam-api.mdvan de Delpher Uitsnijder) geeft de vorm van de figuur, voor een transparante PNG. Dat kost één SAM-aanroep per regio, met bevestiging. Standaard blijft het een rechthoek (JPG). - Knoppen in het blok Uit Commons: "Regio's uit Commons (n)" laadt ze allemaal, gratis. In de lijst en op de pagina tonen ze in het geel, zoals op Commons, met de naam erbij.
Uploaden van een regio
- Elke regio wordt een eigen bestand, met
{{Extracted from|File:<origineel>}}naar het bronbestand (9.3), ook bij een gemaskerde PNG. - Beeldt af van de uitsnede is meteen het item van de regio (Q179718), zonder P2677, want de uitsnede toont alleen dat item. Een caption en een bestandsnaam worden voorgesteld uit het label: "Catherine of Alexandria – extracted from Book of Hours of Philip of Burgundy - KW76F - folio 283r - Heaven - All Saints - Jean Le Tavernier.jpg".
- Het origineel krijgt
{{Image extracted}}(9.3). Aan de verklaring P180 op het origineel verandert niets.
Andere bronnen
- Bestandsnotities (
{{ImageNote}}van de ImageAnnotator-gadget) in de wikitekst: rechthoek plus tekst. De tekst wordt het bijschrift. - Bestaande uitsneden:
{{Image extracted}}op het origineel noemt bestanden die al zijn uitgesneden. Die worden getoond als "staat al op Commons" (zonder positie, tenzij die af te leiden is). Een regio waarvan het item al op een bestaande uitsnede als beeldt af staat, krijgt het label "al uitgesneden".
Alles wat het bestand op Commons al heeft (sinds 0.33.0, backlog 26; naar aanleiding van een vraag van Olaf over File:Atlas de Wit 1698-pl017-Leiden-St Pancraskerk.jpg, met een Nederlandse caption, veel P180 en twee regio's). Het staat in Uit Commons, niet bij de AI-suggesties: het is door mensen ingevoerd en gratis te lezen. Het blok staat bovenaan Beschrijven en vinden en is open als het bestand zulke gegevens heeft, met de andere blokken dicht; zonder gegevens zijn de AI-suggesties open. Het geldt alleen voor pagina 1, net als de regio's. Bovenaan staat dat de app alleen aanvult, met een link naar de gegevens op Commons.
- Captions op Commons: alleen lezen, in alle talen die het bestand heeft, met een link naar de bestandspagina.
- Regio's: zoals nu (gratis objecten).
- Beeldt af zonder positie: één chip per item (een item dat ook een regio heeft, staat er niet bij), met het Wikidata-label; de Q-id staat in de tooltip. Een klik zoekt het item met SAM op de afbeelding (betaald, zoals een zoekterm, met bedrag en bevestiging), met het Engelse label als zoekwoord. Dit blok is alleen lezen (wens Olaf, 11-11-2026): het potloodje voor een eigen zoekwoord is weg. Vindt SAM het item niet (een naam of "Pieterskerk" vindt SAM slecht), zoek dan onder Zoeken met een ander woord en hernoem het gevonden object naar het item; dan wordt het eraan gekoppeld. De uitleg eindigt met Nieuw item toevoegen? en drie links: de AI-suggesties, Zoeken en Aanwijzen of tekenen. Woorden en tekens die een zoekopdracht splitsen (komma, and, en, min, not) worden eruit gehaald. Aanvinken en Alle items detecteren zoals bij de zoektermen; het aantal gevonden objecten staat op de chip.
- Wat zo gevonden wordt, krijgt meteen dat item (wikidata, met het label in label_item) en dus als beeldt af in het Commons-concept (9.1), zonder gok van de AI. De API: items bij POST …/detecties (docs/api.md). In het venster van 9.7 kan de positie daarna aan die bestaande verklaring worden toegevoegd (besluit 3 daar): zo helpt de app van gewone beeldt af regio's te maken.
- Context voor de AI: de bestaande captions en de labels van de P180-items gaan mee als context bij Beschrijf deze afbeelding (ook bij opnieuw vragen van een deel), met de opdracht alleen te beschrijven wat te zien is. De cache-sleutel verandert daar niet door. Een nieuwe beschrijving van de hele afbeelding is sinds 0.38.1 standaard een Commons-caption (zo rijk mogelijk, hooguit 250 tekens; wens Olaf), zodat hij zo naar de gestructureerde gegevens kan; een andere lengte kies je daarna met de schuif. De AI-zoektermen staan sinds 0.38.1 in twee blokken (wens Olaf): eerst Staat al op Commons, de termen voor een item dat het bestand al als beeldt af heeft (zelfde label, nl of en), als knoppen die niets doen, groen met het aantal objecten dat aan dat item gekoppeld is; die lokaliseer je onder Van Commons > Beeldt af. Daaronder Nieuw, nog niet op Commons: de termen die de AI toevoegt, met vinkje en Alle objecten lokaliseren. Sinds 0.39.1 (wens Olaf, 12-11-2026) tonen de knoppen bij Staat al op Commons de naam van het item op Commons (stairs, niet het AI-woord staircase; dat staat in de tooltip), één knop per item. De potloodjes bij de AI-zoektermen zijn weg: een term is wat de AI zei, en het getal telt de objecten van dat woord. Een eigen woord gaf veel complexiteit (een knop sky die eigenlijk driveway was en beide telde; eigen woorden alleen in één browser). Klopt een gevonden object niet, dan haal je het rechts weg; iets anders zoek je met Zoeken of Aanwijzen of tekenen (een regel met links onder de termen). De eigen woorden die de browser nog had, worden vergeten.
- Het blok Uit Commons verschijnt ook bij een bestand zonder regio's, als het een caption of P180 heeft.
- Opnieuw lezen van Commons: de app bewaart wat hij van Commons leest een dag. Een link in het blok leest het bestand opnieuw (gratis, alleen lezen), bijvoorbeeld na het toevoegen van een caption of beeldt af op Commons.
- Prullenbak bij een regio (wens Olaf, 6-11-2026): de prullenbak verandert nooit iets op Commons; het object gaat alleen uit de app. Het bevestigingsvenster zegt dat, met een link naar de gegevens op Commons: een regio weghalen of aanpassen doe je daar zelf (zoals besluit 2 in 9.7). Heeft het object een vorm van SAM bij een rechthoek (een regio of een getekende rechthoek), dan kies je in het venster: Alleen de vorm van SAM (standaard; het object houdt zijn eigen rechthoek, bij een regio die van Commons; gratis) of Het hele object naar de prullenbak. Een regio in de prullenbak komt niet terug met Regio's uit Commons; je zet hem terug uit de prullenbak.
- Kaders in het beeld: na Vorm met SAM krijgt een regio het (strakkere) kader van SAM; de oorspronkelijke regio van Commons blijft bewaard (box_regio), maar wordt niet apart getekend. De schakelaar Kaders verbergt ook de gele kaders van regio's en hun naam (tenzij Namen aan staat).
7.6 Paginaoverzicht¶
"Wat staat op deze pagina?" met zoektermen als chips in het blok AI-suggesties voor deze afbeelding, met per term hoeveel objecten op de afbeelding staan (en in de prullenbak), en een knop Alle objecten lokaliseren (sinds 0.29.0 alleen voor de aangevinkte termen).
Sinds 0.29.0 (besluit Olaf, 5-11-2026): de eerste vraag is één aanroep voor beschrijving én zoektermen (het goedkoopst: het beeld gaat één keer mee). Daarna kan elk deel apart opnieuw (Beschrijving opnieuw, Zoektermen opnieuw: één aanroep met een vraag voor alleen dat deel, het andere deel blijft) of apart verwijderd worden (gratis). Twee aparte aanroepen vanaf het begin zouden ongeveer anderhalf keer zo veel kosten.
Detailniveau (wens Olaf, 5-11-2026, sinds 0.32.3; sinds 0.40.6 niet meer in het paneel maar in het venster waar je de kosten bevestigt: bij Wat staat op deze pagina?, Zoektermen laten maken en Zoektermen opnieuw laten maken, de eerste keer op Normaal): een schuif bepaalt hoeveel soorten objecten de AI als zoekterm voorstelt: Alleen het hoofdonderwerp (1), Hoofdzaken (ongeveer 3), Normaal (tot 12, zoals voorheen) of Veel details (tot 20, ook kleine dingen zoals insecten, knopen en ornamenten). SAM zelf kent geen aantal: het vindt alle exemplaren van een zoekterm. De schuif bepaalt dus waarnaar gezocht wordt. Elk niveau heeft een eigen antwoord in de cache; Normaal houdt de antwoorden van vóór de schuif. Meer zoektermen betekent meer SAM-aanroepen als je ze allemaal laat zoeken; de knop toont het bedrag.
Vier lengtes tegelijk (wens Olaf, 11-11-2026, sinds 0.39.0): de beschrijving van de hele afbeelding komt in één aanroep in alle vier de lengtes (Kort, Normaal, Commons-caption van hooguit 250 tekens, Uitgebreid), in het Nederlands en het Engels. Het beeld gaat één keer mee, dus het kost maar iets meer dan één lengte (alleen de extra uitvoer). De schuif Lengte (en de schakelaar Commons-caption, die blijft voor de zichtbaarheid) wisselt gratis en meteen tussen de lengtes; de gekozen lengte is de beschrijving (samenvatting) die elders gebruikt wordt. Naar Commons gebruikt altijd de lengte Commons-caption als die er is. Met de hand aanpassen geldt voor de lengte die je ziet: elke lengte houdt zijn eigen tekst en zijn eigen AI-origineel (Terug naar de AI-tekst), ook als je heen en weer schuift. Eerdere beschrijvingen bewaart de vier lengtes samen als één versie (besluit Olaf): terugzetten brengt alle vier terug, en de carrousel toont de lengte waar de schuif op staat. Een beschrijving van vóór 0.39.0 heeft alleen zijn eigen lengte; op een andere stand zegt de app dat en wijst naar Beschrijving opnieuw. API: beschrijvingen (per lengte nl, en en eventueel ai_origineel) in het overzicht, {"beschrijvingsniveau": …} bij PATCH …/inventaris. Elke taal staat in een vak met een vaste hoogte dat scrolt als de tekst langer is, zodat de pagina niet van hoogte verandert als je schuift (wens Olaf, 12-11-2026). Laat de AI een lengte leeg, dan werken de andere drie en zegt de app op die stand dat de AI hem niet gaf. Een antwoord dat geen JSON is, of zonder enige beschrijving, wordt niet bewaard: een melding vraagt het opnieuw te proberen (sinds 0.39.1).
Eigen prompt voor de beschrijving en de zoektermen van de afbeelding (wens Olaf, 13-11-2026, sinds 0.40.2; PageDescribeDialog.vue): de eerste beschrijving en de eerste zoektermen maakt de AI altijd met de prompt van de app. Zoektermen opnieuw laten maken werkt net als hieronder voor de beschrijving, met een eigen prompt en eigen eerdere prompts per deel; de prompt van de app volgt daar het detailniveau, een eigen prompt niet (het detailniveau bepaalt dan alleen hoeveel termen de app hooguit houdt). Beschrijving opnieuw laten maken opent daarna een eigen venster, zodat de kolom rustig blijft: bovenaan wat er gebeurt en wat het kost, met de knop Beschrijving maken. Daaronder, dichtgeklapt, Prompt aanpassen: geen hoofdfunctie maar een verfijning. Daarin staat de prompt die meegaat (die van de app of je eigen) in een tekstvak, met Prompt bewaren, Wijziging ongedaan maken, Terug naar de prompt van de app en Eerdere prompts (n) om te gebruiken of te verwijderen (hooguit 20). Alleen een bewaarde prompt gaat mee: is de tekst aangepast maar niet bewaard, dan staat Beschrijving maken uit, met een gele uitleg. De eigen prompt hoort bij de afbeelding (de pagina), geldt alleen voor de beschrijving (niet voor de zoektermen) en blijft gelden tot je teruggaat naar die van de app; Opnieuw beginnen haalt hem weg. Het antwoordformaat blijft dat van de app, dus de velden komen altijd terug; Alles wat de uitkomst stuurt staat in één dichtgeklapte AI-bijsturing (wens Olaf, 13-11-2026), met onderaan, zelf ook dichtgeklapt, Prompt aanpassen; de kop vat samen wat er gekozen is (aanwijzing, denkniveau, eigen prompt of die van de app). Daarin: een Aanwijzing voor de AI (een korte extra opdracht voor deze ene vraag, achter de prompt, ook achter een eigen prompt; niet bewaard als prompt) en het denkniveau (Laag, Middel, Hoog; standaard de instelling van de app, BEELDMODEL_REDENEREN, sinds 0.40.2 Middel (besluit Olaf, 13-11-2026)), met per niveau de prijs; het bedrag op de knop volgt de keuze. De kop zegt wat er gekozen is. Andere hefbomen (model, resolutie van het beeld, de context uit Commons) zijn bewust niet instelbaar. Dat deel krijgt delen.{deel}.prompt_eigen: true. API: GET, PUT en DELETE …/inventaris/{deel}/prompt, DELETE …/inventaris/{deel}/prompt/geschiedenis/{versie}.
Minimale zekerheid (sinds 0.32.3): een schuif boven de objecten in Gevonden objecten (uitsneden) (0 tot 95%) verbergt objecten van de AI-beelddetectie met een lagere zekerheid, ook wat al gevonden is, zonder nieuwe aanroep. Objecten zonder zekerheid (met de hand, uit Commons) blijven altijd zichtbaar. Wat verborgen is, is niet geselecteerd en gaat dus niet mee bij opslaan of beschrijven. De schuif bepaalt zo hoeveel je overhoudt. Onthouden in de browser.
Zoeken in de objecten (sinds 0.33.8, wens Olaf): een smal zoekveld op de regel van Objecten, naast Alle · Geen · Omkeren, filtert de lijst op wat je typt: elk woord moet voorkomen in de naam (ook een eigen naam), de zoekterm, het Wikidata-item, het eigen bijschrift of de beschrijving, ongeacht hoofdletters. Gaf je een object een eigen naam, dan zoekt het veld niet meer in de zoekterm van de AI en de vertaling ervan (wens Olaf, 12-11-2026: car vond anders de suitcase die als cardboard box gevonden was); dat geldt ook op de pagina Objecten en voor q bij de export. Het beeld toont dan ook alleen de passende objecten, en Alle · Geen · Omkeren en alle in de bulkacties gaan alleen over die. Anders dan de schuif haalt het zoeken geen vinkjes weg: de selectie buiten de zoekopdracht blijft staan. Zoeken kan in het Nederlands en het Engels: de zoektermen zijn Engels, de namen ook Nederlands, en de AI-beschrijving staat er in beide talen. Een (i) naast het veld legt dit uit. Het veld is leeg bij een andere afbeelding of pagina; gratis.
7.7 AI-aangevulde versie¶
Idee en opdracht van Olaf (5-11-2026, backlog 19b; gebouwd in 0.32.4). Waar op het origineel iets voor een object stond (de jongen op de rug van de kat), heeft de uitsnede gaten. Een extra knop in de vergroter, Afbeelding aanvullen met AI (met het bedrag), laat Muse Image (muse-image-1.0, /v1/images/edits, $0,01 per beeld) die gaten invullen.
- Wat er gebeurt: de transparante uitsnede gaat op wit mee (hooguit 1536 pixels), met de vraag alleen de witte delen van het onderwerp in te vullen, in dezelfde stijl, techniek en kleuren, zonder iets te veranderen of toe te voegen. Zoeken op internet en code zijn uitgezet (
tool_enablement). Het onderwerp komt uit de beschrijving, het bijschrift of de zoekterm. - Verzonnen, geen bron. Het model weet niet wat er achter het andere voorwerp zat. De versie staat daarom apart, onder de uitsnede, met een AI-merkje en een waarschuwing, en gaat nooit als uitsnede naar Commons. Het Commons-concept en de upload gebruiken altijd de echte uitsnede.
- Lagere resolutie: Muse Image maakt het beeld in zijn eigen resolutie, en tekent het hele beeld opnieuw; ook buiten de gaten kan het iets veranderen.
- Kosten: in live-modus eerst een bevestiging met het bedrag; toegangslijst, daglimieten en verbruikslog gelden zoals bij de andere modellen. Gecachet per verstuurd beeld en vraag: nog eens vragen kost niets, opnieuw wel. In de proefmodus een nagebootste versie (de uitsnede op wit met AI-aangevuld (dummy)).
- Bewaren: het beeld staat in
cache/aanvullingenen gaat na 30 dagen zonder gebruik weg, zoals uitsneden (12.1); het object onthoudtaangevuld(model, onderwerp, afmetingen, kosten). Weghalen haalt het van het object. - Downloaden als PNG met (AI-augmented) in de bestandsnaam, of bekijken in een nieuw tabblad.
- Doorzichtig en zoombaar (sinds 0.32.6): het wit dat met de rand verbonden is, wordt doorzichtig (op een schaakbord, zoals de uitsnede); wit binnen het onderwerp en binnen de vorm van de uitsnede blijft. Uitsnede en aangevulde versie zijn in de vergroter te zoomen en te verschuiven zoals in de hoofdviewer. Bron en Resolutie staan eronder in dezelfde stijl als bij de uitsnede.
- Eigen tabblad AI-aangevuld in de vergroter, na Uitsnede, alleen als er een aangevulde versie is (sinds 0.32.5). Een schakelaar Toon wat de AI invulde legt een magenta laag over de plekken waar de uitsnede geen vorm had en de AI iets tekende; bij benadering.
Eigen prompt en eerdere versies (wens Olaf, 6-11-2026, sinds 0.33.5):
- Bij de AI-prompt in het tabblad AI-aangevuld staat een potloodje. Het opent de prompt in een tekstvak, om hem aan te passen voor de volgende Afbeelding opnieuw aanvullen met AI (betaald, met bevestiging); Terug naar de prompt van de app zet de standaardprompt terug. Een aangepaste prompt staat in de notitie als prompt_eigen en heet in de interface eigen prompt. Elke prompt is een eigen antwoord in de cache.
- Eerdere versies: een nieuwe versie, of Weghalen, zet de vorige in de lijst Eerdere versies (hooguit 20 per object, aangevuld_geschiedenis), als carrousel zoals bij de beschrijvingen: per versie een klein beeld, de prompt en de tijd, met Deze gebruiken (gratis, uit de cache) en het prullenbakje. Is het beeld van een versie niet meer bewaard (bewaartermijn), dan zegt de app dat. Het tabblad AI-aangevuld blijft er zolang er een eerdere versie is.
- Zo werkt opnieuw vragen: elke keer gaan de oorspronkelijke uitsnede en alleen de prompt van dat moment naar het model; de vorige prompt en het vorige resultaat gaan niet mee, en het model onthoudt niets. Een aangepaste prompt vervangt de oude dus helemaal. Verder bouwen op een eerdere versie is een idee voor later (backlog 19d).
- API: prompt bij POST …/aanvulling, standaard_prompt bij GET, PUT …/aanvulling met {"sleutel"}, DELETE …/aanvulling/geschiedenis/{sleutel} en aangevuld.png?sleutel=.
7.8 3D-model van een uitsnede (nice-to-have)¶
Idee van Olaf (6-11-2026). Nice-to-have, nog niet gepland en nog niet gebouwd (backlog 19c). Van een uitgesneden object, bijvoorbeeld een luit op een stilleven, een 3D-model laten maken dat je in de vergroter kunt draaien en waarop je kunt inzoomen.
Welk model. De Meta Model API kent geen 3D (nagekeken 6-11-2026). Meta heeft wel SAM 3D Objects, een apart onderzoeksmodel dat van één beeld met het masker van een object een 3D-model met textuur maakt, ook als het object deels bedekt is. Zelf draaien vraagt een GPU (niet op Toolforge). Het is te huur via Runware, een aanbieder met één API voor veel modellen:
| Model (Runware) | Prijs per model (6-11-2026) | Kort |
|---|---|---|
SAM 3D Objects (meta:sam@3d, voorstel) |
$0,005 tot $0,009 | Beeld + masker + prompt → GLB met textuur |
| TRELLIS.2 (Microsoft, open) | $0,0077 | Beeld → 3D; tweede keuze, zonder masker |
| Hunyuan 3D 3.1 Rapid / Pro | $0,225 | Pro met meerdere aanzichten en PBR-materialen |
| Tripo 3D v3.1 | $0,30 | Nauwkeurige vorm en textuur |
| Rodin Gen-2 | $0,40 | Nette mesh, lokaal bewerken |
| Meshy-6 | $0,80 | Productieklare mesh, low-poly |
SAM 3D Objects past het best: het vraagt precies wat de app al heeft (het originele beeld, het masker van het object en een prompt, bijv. de naam of de beschrijving) en geeft een GLB terug, voor ongeveer een halve cent. Runware vermeldt Zero Data Retention; bij de bouw nagaan wat dat precies inhoudt.
Zoals Afbeelding aanvullen met AI (7.7):
- Een knop 3D-model maken in de vergroter, met het bedrag; eerst een bevestiging die zegt wat er gebeurt.
- Een eigen tabblad 3D (als er een model is), met een 3D-weergave om te draaien en te zoomen (<model-viewer> of three.js via npm, geen CDN), het AI-merkje, de prompt, en een waarschuwing: de achterkant, de diepte en de zijkanten zijn verzonnen; geen bron, nooit als uitsnede naar Commons.
- Downloaden als GLB; weghalen (het bestand blijft de bewaartermijn lang in de cache, 12.1).
- Gecachet per beeld, masker, prompt en model: nog eens vragen kost niets, opnieuw wel.
- In de proefmodus een nagebootst 3D-model (bijv. een vlak met de uitsnede als textuur), zodat alles zonder kosten te testen is.
- Later ook op het canvas (18), als laag die je draait.
Een tweede aanbieder naast Meta. Dat vraagt:
- een eigen sleutel RUNWARE_API_KEY, alleen als omgevingsvariabele (.env.example bijwerken);
- een regel in de privacyverklaring (NL en EN) dat het beeld en het masker naar Runware gaan voor dit model;
- verbruik en kosten in het verbruikslog, met de aanbieder erbij, en binnen de daglimieten en het dagbudget (6.4); bij het starttegoed (8.6) telt het als één aanroep;
- bij de bouw: de licentie van SAM 3D (eigen licentie van Meta) en de voorwaarden van Runware nalezen, en of het resultaat gebruikt mag worden zoals hier bedoeld.
API (voorstel), zoals 7.7: GET, POST en DELETE …/objecten/{id}/model3d en GET …/objecten/{id}/model3d.glb.
8. Inloggen en rechten (OAuth)¶
8.1 Patroon¶
Overgenomen uit de IIIF Manifest Upload Workbench (src/api/oauth.js, docs/oauth-registration.md): OAuth 2.0 van Wikimedia via Meta-Wiki.
- Autoriseren:
https://meta.wikimedia.org/w/rest.php/oauth2/authorize - Token:
https://meta.wikimedia.org/w/rest.php/oauth2/access_token - Profiel:
https://meta.wikimedia.org/w/rest.php/oauth2/resource/profile - Authorization code met PKCE (
S256) en eenstatetegen CSRF; refresh-token voor langere sessies. - Uploaden in twee stappen: eerst naar de upload stash (
action=upload&stash=1), dan publiceren metfilekey. Waarschuwingen (exists,duplicate,badfilename) komen zo vóór het publiceren boven, en worden aan de gebruiker getoond, niet stil genegeerd. - Daarna SDC met
wbeditentityopM<pageid>. - Dubbelingen vooraf zoeken op SHA-1 (
list=allimages&aisha1=). - Bestandsnamen begrenzen op 255 bytes (niet tekens), en verboden tekens eruit (
# < > [ ] { } | / \ :en stuurtekens).
Verschil met de workbench: die draait helemaal in de browser (een "public client"). Hier staan de uitsneden en de Meta-sleutel op de server, en moet de server weten wie er betaalde aanroepen doet. Voorstel:
- Server-side OAuth 2.0 in Flask, als confidential client (authorization code + PKCE). De token staat alleen op de server, in een server-side sessie, nooit in de browser.
- De server uploadt met de token van de gebruiker (
Authorization: Bearer …). - Besloten door Olaf (3-11-2026): server-side.
8.2 Registratie van de consumer¶
- Ontwikkeling: een owner-only consumer op Meta-Wiki. Die is direct goedgekeurd, maar werkt alleen voor Olafs account en kent geen autorisatieflow; de app gebruikt dan de access-token uit
COMMONS_OWNER_TOKEN(zoalsVITE_OWNER_ACCESS_TOKENin de workbench, OI-09 daar). - Toolforge: een publieke consumer met callback
https://<toolnaam>.toolforge.org/oauth/callback. Die moet door een beheerder worden goedgekeurd (dagen tot twee weken). - Grants (minimaal): Basic rights, Upload new files (
uploadfile), Edit existing pages (editpage, nodig voor SDC en voor{{Image extracted}}op het origineel), Create, edit, and move pages (createeditmovepage, voor de nieuwe bestandspagina). Niet: overschrijven (uploadeditmovefile), want de app overschrijft nooit. Bij de bouw verifiëren welke set strikt nodig is. OAUTH_CLIENT_IDenOAUTH_CLIENT_SECRETalleen als omgevingsvariabele (op Toolforge:toolforge envvars). Nooit in de repo.
8.3 Wie mag wat¶
| Actie | Zonder login | Ingelogd |
|---|---|---|
| Bestand openen, bekijken, gratis regio's (7.5), bestaande detecties en beschrijvingen bekijken | ja | ja |
| Betaalde aanroepen (SAM, Muse) | nee | ja, binnen de daglimieten (6.4) |
| Uitsneden downloaden (zip) | ja | ja |
| Uploaden naar Commons | nee | ja, op eigen naam |
Besloten door Olaf (3-11-2026): betaalde aanroepen alleen voor een toegangslijst (TOEGESTANE_GEBRUIKERS, Commons-gebruikersnamen, komma-gescheiden), met een daglimiet van 100 aanroepen per gebruiker (DAGLIMIET_PER_GEBRUIKER=100). Ingelogde gebruikers die niet op de lijst staan, zien de knoppen met kosten grijs, met de uitleg waarom. Uploaden mag iedere ingelogde gebruiker, want dat kost niets. Olaf beheert de lijst (besluit 3-11-2026), in het beheerpaneel van de tool (8.4). In het begin staat alleen Olaf erop; anderen voegt hij toe in het paneel. Een beheerder staat altijd op de toegangslijst. Toegang vraag je aan met de knop Toegang aanvragen bij de grijze knoppen; de aanvraag komt in het beheerpaneel.
Wens van Olaf (5-11-2026), uitgewerkt in 8.6: op Toolforge krijgt ook wie niet op de toegangslijst staat een starttegoed van ongeveer $0,25 voor betaalde aanroepen, en voert daarna een eigen sleutel voor de Meta Model API in (bring your own key).
In het verbruikslog staat per aanroep de Commons-gebruikersnaam, leesbaar (besluit Olaf, 3-11-2026). /verbruik is alleen zichtbaar voor gebruikers op de toegangslijst en voor beheerders, en de privacyverklaring (12.3) noemt het.
8.4 Beheerders en het beheerpaneel¶
Eis van Olaf (3-11-2026): Olaf is nu de enige beheerder, maar wil andere beheerders kunnen toevoegen via hun Wikimedia-account, en de instellingen van de tool in een beheerpaneel kunnen invoeren.
Twee soorten beheer, die los van elkaar staan:
| Beheerder in de app | Beheerder (maintainer) op Toolforge | |
|---|---|---|
| Wat je kunt | Het beheerpaneel: toegang, limieten, instellingen | De server: deployen, logs, omgevingsvariabelen, de API-sleutel |
| Account | Wikimedia-account (SUL), ingelogd via OAuth | Wikimedia developer-account (LDAP), met SSH-sleutel |
| Toevoegen | In het beheerpaneel, op Commons-gebruikersnaam | Op toolsadmin.wikimedia.org, door een bestaande maintainer. Het beheerpaneel kan dat niet |
| Nu | Olaf | Olaf |
Beheerpaneel op /beheer, met Codex, alleen voor ingelogde beheerders:
- Beheerders: toevoegen en verwijderen op Commons-gebruikersnaam. De app controleert of het account bestaat (
list=users). De eerste beheerder komt uit de omgevingsvariabeleBEHEERDERS_START(OlafJanssen); die blijft altijd beheerder en is niet uit het paneel te verwijderen, zodat niemand zichzelf of anderen buitensluit. - Toegangslijst: wie betaalde aanroepen mag doen, met per gebruiker optioneel een eigen daglimiet. Toevoegen, verwijderen, tijdelijk blokkeren.
- Aanvragen: aanvragen voor toegang, met naam, datum en een korte reden van de aanvrager; goedkeuren of afwijzen.
- Limieten en kosten: daglimiet per gebruiker, algemene daglimiet, dagbudget in dollars.
- Noodknoppen: betaalde aanroepen pauzeren (alle SAM- en Muse-aanroepen uit, voor iedereen) en uploaden naar Commons pauzeren.
- Modellen: Contributor aan of uit; redeneerinspanning (
lowenzovoort). - Bewaartermijnen: originelen, uitsneden, cache (12.1).
- Overzicht: verbruik vandaag en deze maand, per gebruiker; ruimte op schijf.
- Logboek van alle wijzigingen in het paneel: wie, wat, wanneer, oude en nieuwe waarde.
Wat niet in het paneel kan: geheimen. MODEL_API_KEY, OAUTH_CLIENT_SECRET en FLASK_SECRET_KEY blijven omgevingsvariabelen op Toolforge (toolforge envvars), en zijn ook voor beheerders niet te zien of te wijzigen in de app.
Opslag: de instellingen, lijsten, aanvragen en het logboek staan in een kleine database: lokaal SQLite, op Toolforge ToolsDB (MariaDB), achter één opslaglaag in de code. SQLite op de gedeelde NFS-schijf van Toolforge is af te raden vanwege de bestandsvergrendeling; bij de bouw verifiëren. De omgevingsvariabelen uit 6.4 en 12.1 (DAGLIMIET_*, DAGBUDGET_USD, BEWAAR_*, BEELDMODEL_CONTRIBUTOR) zijn alleen nog de beginwaarden; zodra een beheerder iets in het paneel wijzigt, geldt de waarde uit de database.
Beveiliging: elke wijziging is een POST, PATCH of DELETE met een CSRF-token; alleen voor beheerders (anders 403); het paneel en de API eronder staan niet in de sitemap en hebben noindex.
8.5 Werk per gebruiker¶
Besluit Olaf (5-11-2026): op Toolforge werkt elke ingelogde gebruiker aan zijn eigen beelden. Twee mensen die dezelfde afbeelding openen, zien elk hun eigen objecten, bijschriften en prullenbak, en overschrijven elkaars werk niet. Tot en met fase 1 is er één gedeelde uitvoermap per afbeelding (uitvoer/<mid>/), zonder gebruiker; dat werkt alleen zolang er één gebruiker is (backlog 12c). Gebouwd wordt dit samen met OAuth (8.1, backlog 13a).
Wat per gebruiker is en wat gedeeld blijft:
| Wat | Waar | Waarom |
|---|---|---|
| Objecten, maskers, bijschriften en hun versies, de prullenbak, opgeslagen uitsneden, Commons-concepten, gegevens van uploads | Per gebruiker: uitvoer/gebruikers/<id>/<mid>/… |
Dit is iemands eigen werk |
| Collecties op het dashboard, met keuzes, voorscan-samenvattingen en de status in de werkset (17) | Per gebruiker: uitvoer/gebruikers/<id>/collecties/ |
Elke gebruiker heeft een eigen dashboard (besluit Olaf, 5-11-2026) |
| Originelen, Commons-antwoorden, paginabeelden, Wikidata | Gedeeld: cache/ |
Openbare gegevens; delen spaart schijfruimte en verzoeken aan Commons |
| Antwoorden van SAM en Muse Spark in de cache | Gedeeld: cache/ |
Dezelfde vraag over hetzelfde beeld kost dan maar één keer geld. Een antwoord uit de cache kost niets en telt dus niet mee voor de daglimiet. Wat iemand ermee doet (bewaren, aanpassen, weggooien) staat in zijn eigen map |
| Verbruik en daglimieten | Centraal, met de gebruikersnaam per aanroep (8.3); later in de database van het beheerpaneel (8.4) | Limieten tellen per gebruiker en voor de hele tool |
| Bekeken en Opzij gezet, kolombreedtes | In de browser (localStorage), zoals nu |
Hoort bij het apparaat, niet bij de server |
Voorstellen (gelden tot Olaf anders zegt):
- Mapnaam: de vaste centrale gebruikers-id uit het OAuth-profiel (
sub), niet de gebruikersnaam. Die verandert niet als iemand zijn account hernoemt, en bevat geen tekens die in een padnaam lastig zijn. De leesbare naam staat in een klein bestand in de map, voor het beheerpaneel. Onderuitvoer/gebruikers/, zodat een gebruikersmap nooit kan botsen metuitvoer/verbruikof een M-id. - REST-API: de paden blijven gelijk. De server haalt de gebruiker uit de sessie; een verzoek kan nooit een gebruiker of map meegeven, dus niemand komt via de app bij het werk van een ander. Ook een beheerder niet, op het overzicht in het beheerpaneel na.
- Zonder inloggen (8.3: bekijken, gratis regio's, zip): het werk hoort bij de browsersessie, in
uitvoer/sessies/<sessie-id>/, en verdwijnt na 1 dag. Wie daarna inlogt, neemt het mee naar zijn eigen map. - Lokaal, zonder OAuth (fase 1, Olafs eigen server): alles valt onder één vaste gebruiker
lokaal. De bestaande mappenuitvoer/M…verhuizen eenmalig naaruitvoer/gebruikers/lokaal/, met een commando dat eerst telt en pas met--echtverplaatst, zoalsopruimen. Wie lokaal met de owner-only consumer inlogt (8.2), werkt in zijn eigen map; het werk vanlokaalkan hij overnemen. - Slot: één slot per gebruikersmap in plaats van één voor de hele uitvoer (
cutter/slot.py), zodat gebruikers elkaar niet laten wachten. De opruimtaak neemt per map het slot van die map. - Bewaartermijnen (12.1) gelden per gebruikersmap, met dezelfde termijnen. Het beheerpaneel (8.4) toont bij Overzicht de ruimte per gebruiker, en een beheerder kan de map van een gebruiker legen (met bevestiging, in het logboek).
- Privacy: de privacyverklaring (12.3) zegt dat het werk per gebruiker op de server staat, hoe lang, en dat beheerders alleen de omvang zien.
- Samenwerken aan één afbeelding (werk van een ander inzien of overnemen) valt hier buiten; dat is een later idee.
8.6 Starttegoed en een eigen Meta-sleutel (bring your own key)¶
Wens van Olaf (5-11-2026). Nog niet gebouwd. Zijn besluiten (5-11-2026) staan in 8.6.6.
8.6.1 Het idee¶
- Op Toolforge krijgt elke ingelogde gebruiker een starttegoed van 100 aanroepen, met SAM of Muse Spark. Dat kost de KB $0,25 (alleen SAM, $0,0025 per stuk) tot ongeveer $0,70 (alleen Muse Spark) per gebruiker (6.4). Dit tegoed betaalt de KB, met de sleutel van de KB (3).
- Met een eigen sleutel voor de Meta Model API betaalt de gebruiker zijn aanroepen zelf, bij Meta. Heeft hij er een, dan gaat die altijd voor, en blijft het tegoed bewaard (8.6.3).
- De sleutel is alleen op de server te gebruiken. Hij komt nooit terug naar de browser, niet in de API, niet in logs en niet in een export. Ook beheerders kunnen hem niet zien (8.6.4).
- Lokaal (fase 1, Olafs eigen server) verandert er niets: de sleutel uit
.envgeldt zonder tegoed.
Dit is iets anders dan de eigen API-sleutel per gebruiker voor scripts (11, fase 4). Die geeft toegang tot de API van de Commons Mineventory zelf. Deze sleutel is voor de API van Meta.
8.6.2 Het tegoed¶
- Eenmalig, bij de eerste keer inloggen, niet elke dag of maand (besluit Olaf).
- In aanroepen, niet in dollars (besluit Olaf): 100 aanroepen, of het nu SAM is ($0,0025) of Muse Spark ($0,005 tot $0,007, 6.4). Dat is eenvoudig uit te leggen. Wie alleen Muse Spark gebruikt, kost de KB wel bijna drie keer zoveel; het dagbudget (hieronder) blijft de rem. De interface toont "Tegoed: 72 van 100 aanroepen".
- De cache is gratis. Een antwoord dat al in de cache staat (ook van een ander, 8.5), kost niets en gaat niet van het tegoed af.
- Vooraf geboekt. Net als het dagbudget nu (12c, 0.26.0) reserveert de app het bedrag vóór de aanroep en verrekent daarna. Zo kan het tegoed nooit onder nul, ook niet bij een voorscan van honderden bestanden (17.5).
- De bestaande limieten (6.4) blijven gelden voor alles wat de KB betaalt: het dagbudget van $2 en 500 aanroepen voor de hele tool, en 100 aanroepen per gebruiker per dag. Met 100 aanroepen per gebruiker kunnen per dag dus drie tot vijf nieuwe gebruikers hun tegoed opmaken voordat de tool aan haar grens zit (vijf bij alleen SAM, door de 500 aanroepen; ongeveer drie bij alleen Muse Spark, door de $2). Daarna meldt de app dat het gratis tegoed voor vandaag op is, en dat het met een eigen sleutel wel kan.
- In het beheerpaneel (8.4): de hoogte van het starttegoed, en per gebruiker het tegoed bekijken, extra tegoed geven of het tegoed op nul zetten. Elke wijziging staat in het logboek.
- De toegangslijst (8.3) blijft voor wie zonder tegoedgrens op kosten van de KB mag werken, zoals Olaf en collega's. Voor hen geldt alleen de daglimiet. Iedere andere ingelogde gebruiker heeft het starttegoed en daarna een eigen sleutel. De knop Toegang aanvragen blijft (besluit Olaf).
8.6.3 Een eigen sleutel invoeren¶
- Op een pagina Mijn account (
/account, via het menu bij de gebruikersnaam, 10.4): een wachtwoordveld Eigen sleutel voor de Meta Model API, met een korte uitleg en een link naar Meta om een sleutel te maken. - Opslaan controleert de sleutel. Lukt dat, dan wordt hij versleuteld bewaard (8.6.4) en wordt het veld leeggemaakt. Daarna toont de pagina alleen nog "Eigen sleutel ingesteld: eindigt op …a1b2, gecontroleerd op 5-11-2026", met Vervangen en Verwijderen (destructief, met bevestiging).
- Bij de bouw nagaan of Meta een gratis manier heeft om een sleutel te controleren, bijvoorbeeld een lijst van modellen (16). Zo niet, dan controleert de app de sleutel bij de eerste echte aanroep en meldt het als die niet werkt.
- Onthouden of alleen deze sessie: standaard onthoudt de app de sleutel versleuteld. Wie dat niet wil, kiest Alleen voor deze sessie; dan staat hij alleen in de server-side sessie en verdwijnt hij bij uitloggen (besluit Olaf).
- Een eigen daglimiet in dollars, optioneel, als rem op je eigen kosten (bijv. $1 per dag).
- Wanneer de app welke sleutel gebruikt: 1. Staat de gebruiker op de toegangslijst: de sleutel van de KB. 2. Anders, met een eigen sleutel: altijd die sleutel, ook als er nog tegoed is; het tegoed blijft dan bewaard (besluit Olaf). 3. Anders, zolang er tegoed is: de sleutel van de KB, één aanroep van het tegoed af. 4. Anders: de knoppen met kosten zijn uitgeschakeld (niet verborgen, 10.4), met de uitleg "Je tegoed is op. Voer je eigen sleutel in om verder te gaan." en een link naar Mijn account.
- Welke sleutel betaalt staat bij de bevestiging vóór elke betaalde actie: "Kost 8 aanroepen, van je tegoed (72 van 100 over)" of "Kost ongeveer $0,02, op je eigen sleutel".
- Contributor of Standard (6.3): dezelfde regels, ook met een eigen sleutel. Op Mijn account kan de gebruiker Contributor voor zijn eigen sleutel uitzetten, want het gaat dan om zijn eigen afspraak met Meta.
- Verbruik: elke aanroep in het verbruikslog krijgt
betaald_door:kb(toegangslijst of tegoed) ofeigen_sleutel, nooit de sleutel zelf. Aanroepen met een eigen sleutel tellen niet mee voor het dagbudget van de KB. Mijn account toont je eigen verbruik per dag.
8.6.4 De sleutel beschermen¶
De sleutel is van de gebruiker en kost hem geld. Hij mag dus nooit uitlekken:
- Alleen schrijven. De API kan een sleutel opslaan, vervangen en verwijderen, maar nooit teruggeven. Een GET geeft alleen of er een sleutel is, de laatste vier tekens, wanneer hij gecontroleerd is, en of hij werkte.
- Versleuteld bewaard, in de database van het beheerpaneel (8.4; ToolsDB op Toolforge), per vaste gebruikers-id uit OAuth (8.5). De versleuteling gebruikt een geheim dat alleen een omgevingsvariabele is (
SLEUTEL_VERSLEUTELING, op Toolforge mettoolforge envvars), net alsMODEL_API_KEY. Zonder dat geheim is de database waardeloos. De sleutel staat nooit in een bestand op de gedeelde schijf. - Alleen op de server ontsleuteld, vlak voor een aanroep naar Meta, en alleen in de kop
Authorizationvan die aanroep. Nooit in een cookie, de sessie in de browser, een URL, een foutmelding, een log, het verbruikslog, een export of de cache. - Logs schoonhouden: de code logt nooit de koppen van een verzoek aan Meta. Een filter in de logging vervangt alles wat op een sleutel lijkt door
***. Een test controleert dat een sleutel niet in de antwoorden, de logs of de bestanden inuitvoer/terechtkomt. - Ook beheerders zien hem niet. Het beheerpaneel toont alleen of een gebruiker een eigen sleutel heeft. Een beheerder kan hem wel verwijderen, bijvoorbeeld bij misbruik; dat staat in het logboek en de gebruiker ziet het op Mijn account.
- Opgeruimd: een sleutel die een jaar niet gebruikt is, verwijdert de opruimtaak (12.1). Verwijderen is echt weg, ook uit de database.
- CSRF-token bij elk opslaan en verwijderen, alleen voor de ingelogde gebruiker zelf, alleen over HTTPS (Toolforge).
- Privacyverklaring (12.3): de app bewaart de sleutel versleuteld en gebruikt hem alleen voor de aanroepen van de gebruiker. Antwoorden die met een eigen sleutel zijn betaald, komen in de gedeelde cache (8.5) en kunnen dus anderen gratis helpen (besluit Olaf).
8.6.5 API (voorstel)¶
| Methode | Pad | Wat |
|---|---|---|
| GET | /api/v1/account |
Ingelogd: tegoed (aanroepen over, van het starttegoed), toegangslijst ja/nee, eigen sleutel (alleen of hij er is, de laatste vier tekens, gecontroleerd), eigen daglimiet, verbruik vandaag |
| PUT | /api/v1/account/meta-sleutel |
Een eigen sleutel opslaan of vervangen ({"sleutel": "…", "onthouden": true}). Controleert hem. 200 met dezelfde samenvatting als de GET, zonder de sleutel |
| DELETE | /api/v1/account/meta-sleutel |
De eigen sleutel verwijderen |
| PATCH | /api/v1/account |
Eigen daglimiet; Contributor uit voor de eigen sleutel |
| PATCH | /api/v1/beheer/toegang/{gebruiker} |
Uitgebreid: tegoed bijboeken of op nul zetten; een eigen sleutel verwijderen (alleen beheerders) |
/api/v1/status noemt het tegoed of eigen sleutel, zodat de header het kan tonen. Een fout van Meta door een verkeerde of lege sleutel geeft een eigen code (own_key_invalid, credit_exhausted), met een vertaling in nl.json en en.json.
8.6.6 Besluiten van Olaf (5-11-2026)¶
- Eenmalig: het starttegoed krijg je één keer, bij de eerste keer inloggen.
- In aanroepen: 100 aanroepen, of het nu SAM of Muse Spark is (niet in dollars, zoals voorgesteld).
- Een eigen sleutel gaat altijd voor: wie een eigen sleutel heeft, betaalt daarmee, en het tegoed blijft bewaard (niet eerst het tegoed, zoals voorgesteld).
- Onthouden: de sleutel standaard versleuteld onthouden, met de keuze Alleen voor deze sessie.
- Toegangslijst: blijft, voor wie onbeperkt op kosten van de KB mag werken.
- Gedeelde cache: antwoorden die met een eigen sleutel zijn betaald, komen in de gedeelde cache.
9. Publiceren op Commons¶
9.1 Werkwijze¶
Gebaseerd op docs/commons-beschrijving.md van de Delpher Uitsnijder:
- Concept per object (veld
commons): bestandsnaam, beschrijving, caption (nl/en), datum, maker, bron, licentie, categorieën, beeldt af, rechtenlabel, en de keuze PNG of JPG. Gratis samengesteld, bewerkbaar in de vergroter: op de weergave zelf (potloodjes, [bewerken]), op de tabbladen Bestandsinformatie en Gestructureerde gegevens, zoals op Commons (0.23–0.24). - Keuzemenu: alle opgeslagen uitsneden van het bestand, met miniatuur, concept, rechtenlabel en een vinkje. Standaard aangevinkt: alleen In orde en Naamsvermelding verplicht.
- Controle vooraf (gratis, alleen lezen): bestaat de naam al, bestaat dezelfde afbeelding al (SHA-1), bestaan de categorieën.
- Proefweergave: de volledige wikitekst en de SDC-verklaringen per uitsnede, elk met een schakelaar Weergave / Broncode (gebouwd, 0.7.0):
- Weergave van de wikitekst: Commons maakt de HTML (
action=parse, alleen lezen, gecachet; een POST omdat de tekst lang kan zijn). De server laat alleen veilige tags staan, zonder afbeeldingen, stijlen of scripts, zodat de browser niets van Wikimedia laadt (12.3). Inklapbare blokken (zoals een instelling) staan net als op Commons dicht; het Wikidata-logo en het potloodje tekent de app zelf. Alleen opgevraagd als de proefweergave open is. - Weergave van de SDC: zoals het tabblad Gestructureerde gegevens op Commons, met captions, beeldt af bovenaan, elke eigenschap met waarden en kwalificaties, en labels van Wikidata. - Een blok Regio op het origineel toont wat het origineel voor deze uitsnede zou krijgen (9.4). - Uploaden (n), alleen na het bevestigingsvinkje: "Ik heb de beschrijving, de licentie en de rechten gecontroleerd. De bestanden worden op mijn naam geüpload." Eén tegelijk, met voortgang en een knop Stoppen.
- Na de upload: de Commons-URL bij het object; optioneel
{{Image extracted}}op het origineel (9.3); een link "Openen in CropTool".
De Upload Stash (Commons:UploadStash) is alleen de controlestap vlak vóór het publiceren (stap 5, zie ook 8.1): de app zet een uitsnede in de stash van de gebruiker, toont de waarschuwingen van Commons, en publiceert daarna met de wikitekst en de SDC. De stash vervangt de opslag op Toolforge (12.1) niet:
- een bestand in de stash verdwijnt na 48 uur als het niet is gepubliceerd;
- de stash vraagt een login met uploadrechten, terwijl bekijken, uitsnijden en downloaden ook zonder login moeten werken;
- terugdownloaden uit de stash kan alleen voor bestanden onder 1 MiB;
- de stash bewaart alleen het bestand, geen beschrijving, licentie of SDC.
Besloten door Olaf (3-11-2026): geen knop om uitsneden in de stash klaar te zetten voor een ander gereedschap, zoals de Upload Workbench. Publiceren gebeurt altijd vanuit de Commons Mineventory.
9.2 Bestandsnaam¶
Besloten door Olaf (3-11-2026): onderwerp voorop, in het Engels.
<Subject> – extracted from <titel origineel zonder extensie>.<png|jpg>, ingekort tot 240 bytes (de titel van het origineel wordt zo nodig ingekort, het onderwerp niet). Bijvoorbeeld:
Coat of arms – extracted from Album amicorum van Jacob van Bronckhorst van Batenburg (8077131573).jpg
Catherine of Alexandria – extracted from Book of Hours of Philip of Burgundy - KW76F - folio 283r - Heaven - All Saints - Jean Le Tavernier.jpg
- Het onderwerp is het Engelse label van het Wikidata-item (bij een regio, 7.5), anders het Engelse
onderwerpuit "Wat staat hierop?" (een nieuw veld naast het Nederlandse), anders het Engelse SAM-label. De gebruiker past het aan. - De titel van het origineel blijft zoals hij is, ook als die Nederlands is.
- Bij een botsing (zelfde naam) volgt een volgnummer: "Coat of arms (2) – extracted from …".
9.3 Wikitekst¶
=={{int:filedesc}}==
{{Information
|description={{nl|1=<beschrijving>}}{{en|1=<optioneel>}}
|date=<datum van het origineel, letterlijk overgenomen>
|source={{Extracted from|File:<origineel>}}
|author=<auteur van het origineel, letterlijk overgenomen>
|permission=<letterlijk overgenomen, als aanwezig>
|other versions=
}}
=={{int:license-header}}==
<licentiesjablonen van het origineel, letterlijk overgenomen>
[[Category:<door de gebruiker gekozen categorieën>]]
[[Category:Uploaded with Commons Mineventory]]
{{Extracted from|File:…}}op de nieuwe pagina, net als CropTool.{{Extracted from|File:…}}is verplicht op elke uitsnede, JPG en gemaskerde PNG, zodat altijd te zien is wat het bronbestand is (eis van Olaf, 3-11-2026). De app laat het niet weghalen.{{Image extracted|<nieuw bestand>}}op het origineel: een bewerking van de pagina van iemand anders. CropTool doet dit ook. Besloten door Olaf (3-11-2026): standaard aan, per upload uit te zetten. Eén bewerking voor alle uitsneden van een sessie; een bestaand sjabloon wordt aangevuld, niet gedupliceerd. De bewerkingssamenvatting noemt de nieuwe bestanden.- Gebruikt het origineel
{{Artwork}},{{Photograph}}of{{Book}}, dan neemt de app dat sjabloon over met de velden die op de uitsnede ook kloppen (maker, datum, instelling, inventarisnummer) en een nieuwedescription/title. Welke velden: vastgelegd in docs/artwork-velden.md (0.20.0), ook voor{{Map}}; de tekst in en rond het beeld als{{Inscription}}(0.22.0). - Licentie: alle sjablonen uit de licentiesectie van het origineel, letterlijk. Bij
{{Flickrreview}}of{{LicenseReview}}met een bevestiging: de bevestiging komt niet mee (CropTool doet dat ook niet), maar wel een verwijzing naar het origineel. - Categorieën: de zichtbare categorieën van het origineel als voorstel (aan te vinken), plus wat de gebruiker toevoegt. Onderhoudscategorieën en
{{Assessments}},{{QI}},{{FP}}en dergelijke komen nooit mee. - Volgcategorie
Category:Uploaded with Commons Mineventory(verborgen), en een projectpaginaCommons:Commons Mineventory. Olaf maakt beide aan (besluit 3-11-2026), vóór de eerste echte upload. - Uploadsamenvatting: "Uitsnede uit [[File:…]] met de [[Commons:Commons Mineventory|Commons Mineventory]]; beschrijving deels opgesteld met een taalmodel en gecontroleerd door de uploader."
9.4 Gestructureerde gegevens (SDC)¶
Na de upload, in één wbeditentity op M<pageid>:
| Verklaring | Waarde |
|---|---|
Caption (labels) |
nl, en optioneel en; hooguit 250 tekens |
| P180 beeldt af | Door de gebruiker gekozen Wikidata-items (6.2), eventueel met P1354 getoond met |
| P6216 auteursrechtstatus, P275 licentie | Overgenomen van het origineel |
| P170 maker, P571 datum van creatie | Overgenomen van het origineel, als aanwezig |
| P195 collectie | Overgenomen van het origineel, als aanwezig, zonder de kwalificator P2868 subject heeft rol (bijv. collection highlight): die gaat over het origineel |
| P31 is een | Q1250322 digitale afbeelding |
| P1163 mediatype | image/jpeg of image/png, naar het gekozen formaat |
| P4092 checksum | SHA-1 van het uitgesneden bestand, met P459 bepalingsmethode = SHA-1 |
| P3575 gegevensgrootte, P2048 hoogte, P2049 breedte | Van het uitgesneden bestand zoals het geüpload wordt (byte, pixel) |
| Relatie met het origineel | Te onderzoeken. Kandidaten: P7482 bron van het bestand met een kwalificator die naar het origineel wijst, of alleen de wikitekst ({{Extracted from}}). Kijken wat de gemeenschap gebruikt |
Regio op het origineel: per beeldt af-item van de uitsnede een P180 met P2677 relatieve positie in afbeelding (pct:x,y,w,h van de uitsnede in het hele beeld) op het origineel, zodat de regio's ook daar vindbaar zijn, zoals bij het Book of Hours. Gewenst door Olaf (4-11-2026): de regio's horen op het origineel, niet op de uitsnede. Gebouwd als voorbeeld in de proefweergave (0.7.0; regio's die het origineel al heeft worden herkend; niet bij bestanden met meer pagina's). Het echte schrijven is een bewerking van het origineel en komt met de upload (fase 2) of later (fase 4).
9.5 PNG of JPG¶
- JPG (rechthoek, volledige resolutie, kwaliteit 95) is de standaard: de gangbare vorm op Commons voor uitsneden van scans en foto's.
- PNG met transparantie (de vorm van het object) als keuze per object, bijvoorbeeld voor een wapen of een figuur. Waarschuwing als de PNG groter is dan 20 MB.
- Optioneel beide, als twee bestanden die naar elkaar verwijzen (
|other versions=). - Een masker dat (bijna) rechthoekig is, wordt altijd JPG.
9.6 Testen¶
- Eerst alleen met nagebootste antwoorden van de API (fixtures).
- Daarna echte uploads op een testwiki:
test-commons.wikimedia.orgof de bètacluster (commons.wikimedia.beta.wmcloud.org). Bij de bouw nagaan welke van de twee OAuth en SDC ondersteunt. COMMONS_UPLOAD=uit(standaard): alles werkt behalve de uploadknop; dan kun je de wikitekst kopiëren of een zip downloaden met bestanden en wikitekst.
9.7 Beeldt af en caption voor de hele afbeelding¶
Voorstel 4-11-2026; besluiten van Olaf 6-11-2026 (onderaan deze paragraaf). Sinds 0.33.5 gebouwd: het venster en het concept (gratis, alleen lezen; GET en PUT …/origineel, cutter/origineel.py, OriginalData.vue). Het opslaan op Commons volgt in fase 2; de knop Op Commons opslaan… staat er al, uitgeschakeld. Nog niet gebouwd: de kleine weergave van de hele afbeelding met de kaders in de kop van het venster, en een knop om de beschrijving in de stand Commons-caption opnieuw te vragen vanuit het venster (nu een uitleg).
Kort gezegd: de AI-caption en de zoektermen (als kandidaten voor beeldt af, P180) worden verzoend met de captions en P180-verklaringen die het bestand op Commons al heeft. De app haalt die bestaande gegevens op (alleen lezen) en zet ze naast de voorstellen; de gebruiker vult aan.
Doel. Wat de AI op de hele afbeelding vond, ook vastleggen in de gestructureerde gegevens van het origineel: - de herkende dingen (boy, girl, vintage car, …) als beeldt af (P180); - de samenvatting van het paginaoverzicht (7.6) als caption.
Er gaat alleen iets naar Commons wat de gebruiker heeft gecontroleerd en aangevinkt, en pas na een bevestiging. Het is een bewerking van het origineel, de bestandspagina van iemand anders. Het opslaan komt daarom in fase 2, na OAuth, en eerst op de testwiki (9.6). Het samenstellen en bekijken kan eerder: dat is gratis en verandert niets op Commons.
Waar. In een eigen venster (een brede CdxDialog), niet in het uitklapblok AI-suggesties voor deze afbeelding: dat wordt anders te vol.
- In dat blok komt onder de zoektermen één knop: Toevoegen aan de gegevens van deze afbeelding…. Die knop is blauw maar niet gevuld; Alle objecten lokaliseren blijft de hoofdactie.
- De knop verschijnt zodra er een paginaoverzicht is, of minstens één object met een gekozen beeldt af-item.
- Bij een bestand met meer pagina's (PDF, TIFF, DjVu) is de knop uitgeschakeld, met uitleg: de gestructureerde gegevens horen bij het hele bestand, niet bij één pagina (besluit 6).
Indeling.
┌ Gegevens van deze afbeelding ─────────────────────────────── ✕ ┐
│ [mini-afbeelding ] 003-KW XKZ 0214-…-page3.jpg ↗ │
│ [met de kaders ] [ Beeldt af (P180) ] [ Captions ] │
│ │
│ Al op Commons: … (alleen lezen)│
│ Voorstellen │
│ ☑ boy (Q3010) – young male human 1 object ▣ door jou │
│ ☐ girl (Q3031) – young female human 1 object ▣ AI ✎ │
│ ☐ automobile (Q1420) 1 object ▣ AI ✎ │
│ ▸ Zoektermen zonder gevonden object (door, lawn) │
│ + Ander item toevoegen [zoeken op Wikidata…] │
├─────────────────────────────────────────────────────────────────┤
│ 3 × beeldt af toevoegen · 1 caption toevoegen │
│ [Annuleren] [Op Commons opslaan…] │
└─────────────────────────────────────────────────────────────────┘
- In de kop staan de naam van het bestand (met link naar Commons) en een kleine weergave van de hele afbeelding met de kaders. Wijs je een regel in het venster aan, dan lichten de kaders van die objecten op, net als bij de lijst links.
- Er zijn twee tabbladen: Beeldt af (P180) en Captions.
- Onderaan staat wat er gaat veranderen, met Annuleren en de hoofdknop Op Commons opslaan…. Tot fase 2 heet die knop Concept bewaren.
- Vóór het opslaan volgt een bevestiging met precies de wijzigingen en de bewerkingssamenvatting.
Tabblad Beeldt af (P180).
- Al op Commons (grijs, alleen lezen): de P180-items die het origineel al heeft, met hun label. Heeft een item een positie (P2677), dan staat er een merkje bij. Hier verandert niets aan: de app vult alleen aan. - Erboven staat uitleg (klein en grijs): Deze app vervangt Commons niet. Wil je een bestaande verklaring aanpassen of verwijderen, doe dat dan op Commons zelf, met een link naar de bestandspagina (tabblad Structured data).
- Voorstellen: één regel per Wikidata-item. Elke regel heeft: - een vinkje; - het item: label, Q-id, korte beschrijving en een link naar Wikidata; - de objecten op de afbeelding die erbij horen: het aantal en de kleur van hun kader; - de bron.
Er zijn drie bronnen:
- Door jou gekozen bij een uitsnede: de beeldt af-items uit het Commons-concept van de objecten (9.1). Die heb je al gecontroleerd, dus ze staan aangevinkt.
- AI-zoekterm: de chips uit het paginaoverzicht. De app zoekt elke term gratis op Wikidata op (wbsearchentities, in het Engels) en stelt het beste resultaat voor. Met het potloodje kies je een ander item, via dezelfde zoeker met autosuggestie als bij de uitsnede. Deze regels krijgen een AI-merkje en staan niet aangevinkt: je vinkt pas aan na controle.
- AI-suggestie bij een uitsnede: de wikidata_suggesties van "Wat staat hierop?" die je nog niet koos. Ook met AI-merkje, niet aangevinkt.
Waar die bronnen samenkomen: - Hetzelfde item uit meer bronnen wordt één regel. - Een item dat het origineel al heeft, staat alleen bij Al op Commons. - Heeft die bestaande verklaring geen positie en vond de app wel een object, dan staat bij die regel een keuze: Overslaan (standaard) of Positie toevoegen aan deze verklaring. Dat laatste wijzigt de verklaring van een ander; de app zegt dat erbij en toont het in de bevestiging. Het is de enige wijziging aan iets wat al op Commons staat (besluit 3). - Objecten in de prullenbak of met de status uitgesloten tellen niet mee. - Zoektermen waarbij geen object is gevonden (in het voorbeeld door en lawn), staan ingeklapt onderaan. Ze komen alleen mee als je ze openklapt en aanvinkt. 3. Ander item toevoegen: een zoekveld met autosuggestie, voor wat de AI niet vond.
Positie (P2677). Per regel kies je met positie, standaard aan:
- Met positie wordt elk object een eigen verklaring: P180 met P2677 pct:x,y,b,h, uit het kader van het object in het hele beeld. Zo werkt ook het Book of Hours (7.5). Commons tekent die regio's op de bestandspagina, en de app leest ze de volgende keer gratis terug als objecten (7.5).
- Zonder positie wordt het één verklaring zonder kwalificator.
Standaard met positie (besluit 1).
Tabblad Captions. Per taal een kaart: Nederlands, Engels en de taal van de interface (nu altijd een van die twee; komt er een taal bij, dan ook die). De AI geeft alleen Nederlands en Engels; voor een andere taal is er alleen Zelf schrijven. Elke kaart heeft drie delen:
- Nu op Commons: de bestaande caption, of "nog geen caption".
- AI-voorstel: de samenvatting van het paginaoverzicht (samenvatting en samenvatting_en) in de stand Commons-caption (7.6, hooguit 250 tekens), met een AI-merkje.
- Zonder de paginasoort ervoor ("prentenboekpagina —"), want dat is geen beschrijving.
- Is de huidige beschrijving in een andere stand (kort, normaal, uitgebreid), dan zegt het venster dat en biedt het aan de beschrijving opnieuw te vragen in de stand Commons-caption (betaald, met het bedrag en een bevestiging). Een eerdere versie in die stand (carrousel) wordt gratis gebruikt (besluit 4).
- De keuze:
- Zonder bestaande caption: Toevoegen, aangevinkt. Het AI-voorstel staat in een tekstvak dat je kunt aanpassen, met Ongedaan maken en een teller tot 250 tekens.
- Met een bestaande caption: Zelf schrijven (standaard), Bestaande houden of Vervangen door het AI-voorstel. Bij Zelf schrijven begint het tekstvak met beide: de bestaande caption en daaronder het AI-voorstel, zodat je ze samenvoegt; met een teller tot 250 tekens en Ongedaan maken. Bij vervangen staan de oude en de nieuwe tekst onder elkaar. Opgeslagen wordt alleen wat in het tekstvak staat als het verschilt van de bestaande caption (besluit 5).
Captions in andere talen staan eronder, alleen lezen; die blijven zoals ze zijn.
Is er nog geen paginaoverzicht, dan legt het venster uit dat het voorstel uit AI-suggesties voor deze afbeelding komt (betaald, met bevestiging). Zelf een caption schrijven kan altijd.
Opslaan op Commons (fase 2).
- Eén bewerking: wbeditentity op M<pageid>, met alleen de nieuwe verklaringen en de gekozen captions. De app stuurt baserevid mee: de versie die het venster las. Is het origineel intussen gewijzigd, dan leest de app het opnieuw en toont het venster de nieuwe stand. Zo gaat er nooit iets over de wijziging van een ander heen.
- Alleen toevoegen. Bestaande verklaringen, kwalificatoren en captions in andere talen blijven zoals ze zijn. Een caption verandert alleen bij de keuze Vervangen of Zelf schrijven; de oude tekst blijft in de geschiedenis van de pagina staan.
- Bewerkingssamenvatting (in het Engels), bijvoorbeeld: Added depicts (3) and caption (nl) with Commons Mineventory; AI suggestions checked by the user.
- Daarna leest de app het origineel opnieuw; de cache van dit bestand vervalt. Objecten met een positie staan voortaan ook als regio van Commons (7.5).
- Rechten: de grant Edit existing pages (8.2). Die is al nodig voor {{Image extracted}}.
- Kosten: geen. Er is geen AI-aanroep, alleen leesverzoeken aan Wikidata en één bewerking op Commons.
Bewaren. Wat je in het venster kiest, bewaart de app per pagina in uitvoer/<mid>/pagina_<n>/origineel.json, net als het Commons-concept per object. Zo kun je later verder. Na het opslaan op Commons staat daar wanneer en door wie.
API (voorstel).
| Methode | Pad | Wat |
|---|---|---|
| GET | /bestand/{mid}/pagina/{n}/origineel |
De voorstellen, de stand op Commons en de bewaarde keuzes. Gratis; de Wikidata-zoekopdrachten voor de zoektermen zijn leesverzoeken en worden gecachet |
| PUT | /bestand/{mid}/pagina/{n}/origineel |
De keuzes bewaren (concept). Gratis |
| POST | /bestand/{mid}/pagina/{n}/origineel/opslaan |
Naar Commons (fase 2): ingelogd, na bevestiging, met baserevid |
Verhouding tot 9.4: geen botsingen (vraag Olaf, 6-11-2026). Er zijn twee bestanden en twee wegen:
| Weg | Bestand | Wat |
|---|---|---|
| Commons-concept van een uitsnede (9.1, 9.4) | de uitsnede (een nieuw bestand) | beeldt af zonder positie: de uitsnede toont alleen dat item |
| idem, bij de upload (9.4, Regio op het origineel) | het origineel | beeldt af met positie (P2677) van de uitsnede |
| dit venster (9.7) | het origineel | beeldt af met of zonder positie, en captions |
Goblet zonder positie op de uitsnede en goblet met positie op het origineel botsen dus niet: dat zijn verschillende bestanden, en beide kloppen. Botsen kan alleen op het origineel, waar de upload (9.4) en dit venster allebei schrijven. Daarvoor gelden deze regels, in één stuk code (cutter/origineel.py) dat beide wegen gebruiken:
- Eén lijst geplande wijzigingen per origineel. De regio's die bij een upload mee zouden gaan en de keuzes in dit venster komen in hetzelfde concept (
origineel.json). Het venster toont wat al met een uitsnede mee gaat (gaat mee met de upload van …), en het Commons-concept van een uitsnede toont wat in het venster al gekozen is. - Ontdubbelen vóór het schrijven. Vlak voor een bewerking leest de app het origineel opnieuw (met
baserevid) en vergelijkt per item en positie (_same_region, 1% marge, zoals nu in 9.4). Wat er al staat, of wat in dezelfde bewerking al zit, gaat niet nog eens mee. - Met positie gaat voor zonder positie. Komt hetzelfde item met positie (een object, of de uitsnede bij de upload) en zonder positie (een regel in het venster zonder met plek), dan gaat alleen de verklaring met positie mee: die zonder positie zegt niets extra's. Staat het item al zonder positie op Commons, dan geldt besluit 3: de gebruiker kiest of de positie aan die bestaande verklaring wordt toegevoegd; anders wordt er geen tweede verklaring zonder positie gemaakt.
- Eén verklaring per object. Een object dat zowel als uitsnede geüpload wordt als in het venster staat, krijgt één verklaring P180 met P2677 op het origineel, niet twee.
- De bewerkingssamenvatting noemt wat er werkelijk ging, na het ontdubbelen.
Fase 4 punt 15 (regio's terugschrijven, ook los van een upload) valt hiermee samen. Het schrijven zelf is fase 2; de regels 1 tot en met 4 kunnen al in het concept en in het venster zichtbaar worden (backlog 15e).
Niet in dit venster. De gelezen tekst in en onder het beeld. Op het origineel zou dat wikitekst zijn ({{Inscription}}), geen SDC, en dat is een andere bewerking.
Besluiten Olaf (6-11-2026), via een vragenformulier: 1. Positie: standaard één verklaring per object, met P2677. 2. Bestaande P180: alleen aanvullen. Bestaande verklaringen vervangen of verwijderen kan niet in de app; het venster legt uit dat de app geen vervanging is voor alles wat op Commons kan, en dat je dat op Commons zelf doet (link naar de bestandspagina). 3. Item al aanwezig zonder positie: de gebruiker kiest per regel, Overslaan (standaard) of Positie toevoegen aan deze verklaring. 4. Bron van de caption: de stand Commons-caption (7.6); is die er niet, dan biedt het venster aan erom te vragen (betaald, met bevestiging). 5. Bestaande caption: standaard Zelf schrijven, met een tekstvak dat begint met de bestaande caption en het AI-voorstel samen. 6. Bestanden met meer pagina's: het venster is uit (knop uitgeschakeld, met uitleg). 7. Talen: Nederlands, Engels en de taal van de interface. 8. AI-herkomst: alleen in de bewerkingssamenvatting, niet in de gegevens zelf. Bij de bouw nagaan of Commons hier inmiddels een afspraak over heeft (16). 9. Wanneer: het samenstellen en het concept nu bouwen, vóór OAuth (gratis, alleen lezen); het opslaan op Commons in fase 2, eerst op de testwiki.
9.8 Notitie op het origineel ({{ImageNote}})¶
Voorstel (6-11-2026, op vraag van Olaf). Nog niet gebouwd (backlog 15d); punten met [Vraag] wachten op Olaf.
Doel. Een object met zijn uitgebreidere beschrijving zichtbaar maken op de bestandspagina van het origineel, als een rechthoek met tekst die verschijnt als je het beeld aanwijst. Niet alleen het label van een Wikidata-item.
Waarom een notitie en geen kwalificator (nagekeken 6-11-2026; besluit Olaf: de notitie is beter, omdat die niet van een gebruikersscript afhangt):
- Commons tekent regio's uit de gestructureerde gegevens (P180 met P2677) zelf niet. Alleen het gebruikersscript van de tool Wikidata Image Positions doet dat, op verzoek van de gebruiker, en dan met alleen het label van het item; kwalificatoren zoals media legend (P2096) of aantal (P1114) toont het niet (7.5).
- Notities ({{ImageNote}}) worden voor iedereen getekend door de gadget ImageAnnotator, ook zonder inloggen (nagekeken op de Atlas de Wit-pagina): gele rechthoeken als je het beeld aanwijst, en de tekst van de notitie in een venstertje als je een rechthoek aanwijst.
- Een notitie is wikitekst, geen gestructureerde gegevens. Voor machines blijft beeldt af (P180, met P2677) de plek (9.4, 9.7); de notitie is voor mensen.
De notitie (zoals ImageAnnotator die zelf schrijft):
{{ImageNote|id=3|x=461|y=667|w=56|h=46|dimx=887|dimy=741|style=2}}
{{LangSwitch|nl=Een klein hondje snuffelt aan de grond bij een groep mannen in zwarte mantels.|en=A small dog sniffs at the ground near a group of men in black cloaks.}}
{{ImageNoteEnd|id=3}}
- Kader: het kader van het object in het hele beeld;
dimxendimyzijn de afmetingen waarop de getallen slaan (de app gebruikt de volledige resolutie van het origineel; ImageAnnotator rekent zelf om). - id: één hoger dan de hoogste bestaande notitie op de pagina.
- Plaats: onderaan de bestandspagina, zoals de gadget het doet.
- Tekst: kort, over wat in het kader staat, neutraal (Commons:Image annotations). In meer talen met
{{LangSwitch}}, zodat de lezer zijn eigen taal ziet; dat raadt Commons aan boven{{en}}/{{nl}}naast elkaar. - Afspraken van Commons: notities zijn voor details in het beeld, niet voor een beschrijving van het hele beeld; ze moeten kort zijn. Bewerken via de gadget kan alleen voor autoconfirmed gebruikers; de app vraagt dat ook (via OAuth bekend).
In de app.
- Waar [Vraag]: in het tabblad Commons-concept van een object (een vinkje Ook als notitie op het origineel), in het venster van 9.7 (per regel), of beide.
- De tekst begint met de beschrijving uit Wat staat hierop? in de gekozen talen, met de hand aan te passen, met een teller; AI-tekst alleen na controle door de gebruiker (zoals 9.7).
- Al een notitie op die plek: de app leest notities al (7.5). Staat er al een notitie met (bijna) hetzelfde kader, dan stelt de app geen nieuwe voor, maar toont hij de bestaande (alleen lezen); aanpassen doe je op Commons zelf.
- Opslaan (fase 2): één bewerking van de wikitekst van het origineel (action=edit met baserevid, zoals 9.7), alleen toevoegen, met bevestiging die precies de toe te voegen tekst toont, eerst op de testwiki. Bewerkingssamenvatting bijv. Added 1 image note with Commons Mineventory; text checked by the user.
- Daarna leest de app het origineel opnieuw; de notitie staat dan ook in Uit Commons (7.5). Een object en zijn eigen notitie worden niet twee keer getoond.
[Vraag] voor Olaf: zie het vragenformulier van 6-11-2026 (tekst, talen, samen met beeldt af of los, waar in de app, lengte).
10. Interface met Codex¶
10.1 Welke Codex¶
Het verzoek noemde Codex v0.4.1. Dat is een oude versie (2022), nog zonder de CSS-only-componenten. De app gebruikt 2.6.0 (package.json). Besloten door Olaf (3-11-2026): Codex 2.x met Vue 3, gebouwd met Vite. Dit wijkt bewust af van de Delpher Uitsnijder, die geen build-stap heeft. Waarom 2.x: de huidige versie sluit aan bij wat Commons zelf gebruikt (Vector 2022), heeft CSS-only-componenten en levert de designtokens als CSS-variabelen.
10.2 Frontend-opbouw met Vite¶
Wat waar draait:
| Onderdeel | Techniek | Waar |
|---|---|---|
| Server: Commons-adapter, detectie, beschrijving, OAuth, upload, REST-API, de HTML-pagina's (Jinja) | Python, Flask | Op Toolforge |
| Panelen, lijsten, dialogen, Lookup, het uploadoverzicht | Vue 3-componenten (.vue) met Codex |
In de browser, gebouwd door Vite |
| Viewer: canvas, zoom, pan, overlays, maskers, klik/Ctrl-klik, Aanwijzen, Shift-slepen | Gewone JavaScript-module, zonder Vue | In de browser, gebundeld door Vite |
| Vite en npm | Node.js (lokaal: v24.12) | Alleen bij het ontwikkelen en bouwen, niet op Toolforge |
Afspraken:
- Codex via npm:
@wikimedia/codex,@wikimedia/codex-iconsen@wikimedia/codex-design-tokens, met vaste versies inpackage-lock.json. De Vue-versie volgt wat Codex vraagt. - De viewer blijft gewone JS. Overgenomen uit de Delpher Uitsnijder (
viewer.jsen de interactie uitapp.js), omgezet naar een ES-module. Niet herschrijven in Vue: tekenen gebeurt tientallen keren per seconde, en de reactiviteit van Vue maakt dat trager. Bovendien blijft de code dan uitwisselbaar met de Delpher Uitsnijder. Een dunne Vue-component zet de viewer op de pagina. Viewer en Vue praten via een kleine, gedocumenteerde interface: functies (zoomToBox,setObjects,setSelection) en events (object-click,point,rectangle). - Flask blijft de pagina's maken. Elke pagina (
/,/objecten,/commons,/verbruik) is een Jinja-template met een of meer plekken waar een Vue-app wordt gemount. Geen single-page-app en geen router in de browser; elke toestand houdt een eigen URL, zoals nu. - Koppeling Flask–Vite: in ontwikkeling laadt de template de bestanden van de Vite-devserver (direct herladen bij elke wijziging); in productie leest Flask
static/dist/.vite/manifest.jsonen zet de juiste bestandsnamen (met hash) in de template. Een kleine helper inweb.py. - Commando's:
npm run dev(naastflask --app app run --debug),npm run build(schrijft naarstatic/dist/),npm test(Vitest, voor de JS-logica van viewer en componenten). - Geen externe CDN's: alles zit in de gebouwde bundel en wordt door Flask uitgeleverd. Niets wordt in de browser van unpkg of jsDelivr geladen; dat lekt het IP-adres van gebruikers naar derden, en dat staat Toolforge niet toe zonder toestemming (zie 12.3).
static/dist/staat niet in git. Het wordt gebouwd: lokaal voor het ontwikkelen, en voor Toolforge in de deploy (zie 12.1).- Taal: componentnamen en code in het Engels. De teksten van de interface staan in
frontend/i18n/nl.jsonenen.json(zie 3); de Vue-componenten gebruiken ze via een kleine vertaalfunctie (ofvue-i18n), en Flask levert dezelfde bestanden aan de Jinja-templates.
10.3 Look en feel¶
- Zo dicht mogelijk bij Commons in Vector 2022: witte achtergrond,
--color-progressive(#36c) voor acties, de lettertypen van de systeeminterface, rustige randen. - Geen Commons-logo als eigen merk: het Commons-logo is een merk van de Wikimedia Foundation. Wel de naam "Commons Mineventory", een eigen eenvoudig icoon (sinds de nieuwe naam: een afbeelding met gevonden objecten in stippelkaders en een lijst ernaast, de inventaris) en de zin "werkt met Wikimedia Commons". Besloten (3-11-2026): een eigen icoon.
- Kleuren alleen via Codex-tokens; eigen toevoegingen (maskerkleuren, selectie) in
static/css/app.cssals variabelen.
10.4 Indeling¶
Zoals in de Delpher Uitsnijder, met Commons-inhoud:
- Header: icoon, "Commons Mineventory", label experiment, rechts de taalkeuze (NL/EN) en Inloggen of de gebruikersnaam met een menu (Mijn uploads, Uitloggen).
-
Invoerbalk: Commons-URL of titel, knop Openen. Daaronder: titel, miniatuur, licentie (als Codex-chip), maker, datum, link naar de bestandspagina, en een uitklapbare Metadata (beschrijving, categorieën, SDC). Sinds 0.29.0 van links naar rechts in de volgorde van het werk, zoals in de Delpher Uitsnijder (besluit Olaf, 4-11-2026): beeld, objecten zoeken, wat je vond.
-
Links: de viewer met zoom en pan, overlays voor boxen en maskers, Aanwijzen met een groene rand.
- Elke kleur betekent één ding (wens Olaf, 8-11-2026): het kader toont de status (kleurenlegenda), de vulling van het masker de soort, en de rand van het masker niets: 2 schermpixels wit met een dunne donkere rand erbuiten (een SVG-filter), zodat de vorm op elk beeld leesbaar is, bij elke zoom even dik.
- Een kleur per soort (wens Olaf, 8-11-2026;
frontend/class-colors.js): staan er objecten van twee of meer soorten op de afbeelding (een eigen naam van het potlood, anders de zoekterm: plate, wine glass), dan krijgt elke soort een eigen kleur voor zijn maskers, en heeft elk object in de lijst Objecten een stip in die kleur. Het kader houdt de kleur van de status (blauw, rood, oranje…). Kleuren op alfabet, uit een vast palet van acht dat afwijkt van de statuskleuren; ze tellen over alle objecten van de pagina, zodat ze niet verspringen met de schuif Minimale zekerheid of het zoekveld. Een groep heeft de soort van zijn leden (groep: wolk (13) hoort bij cloud); een groep van gemengde soorten heeft geen eigen soort en dus de kleur van zijn kader, maar telt bij Alleen deze maskers tonen mee onder elk van de soorten van zijn leden (en blijft zichtbaar als er één aan staat). De detectie kent alleen de zoekterm: een pop die bij person gevonden is, hoort bij person. Geef je hem een eigen naam, dan krijgt hij de kleur van die naam en telt hij bij de vinkjes alleen onder die naam, doll: de naam vervangt de zoekterm (wens Olaf, 12-11-2026; eerder telde hij onder beide, sinds 9-11-2026, maar dan bleef bijvoorbeeld cardboard box als vinkje staan bij een object dat je suitcase noemde). Sindsdien heeft elk object precies één vinkje: woorden waarmee het vóór het samenvoegen ook gevonden werd (Ook gevonden als), tellen bij de maskers niet meer mee (wens Olaf, 12-11-2026: een suitcase2 die ook als suitcase gevonden was, gaf anders twee vinkjes). Bij de zoektermen tellen ze wel mee. Een regio uit Commons heeft zijn naam als soort (dog), ook als hij nog geen masker heeft; dan is er met Kaders uit niets van te zien. Geen soort (en dus de statuskleur) voor een getekend kader en een klik zonder eigen naam. Met één soort blijft alles zoals het was. - Vinkjes in de kleurenlegenda (wens Olaf, 8-11-2026): een vinkje per status van het kader (geselecteerd, gevonden, Commons-regio, zelf getekend, uitgesloten;
frameKeyinclass-colors.js), in de kleur van het kader, met aantallen en Alle · Geen · Omkeren. Uitgevinkt vervaagt die objecten. Samen met Alleen tonen: goed zichtbaar is een object waarvan soort én status aan staan. Nieuw en dikker zijn geen status en blijven uitleg. - Geen schakelaar meer (besluit Olaf, 8-11-2026): een masker toont altijd de soort, een kader altijd de status. Alleen met één soort op de afbeelding krijgen de maskers de kleur van hun kader. (0.33.9 had een schakelaar Kleur maskers: per soort / per status; die herhaalde wat de kaders al lieten zien.)
- Alleen deze maskers tonen (wens Olaf): in de Kleurenlegenda, zolang Maskers aan staat, een regel met elke soort als vinkje in de kleur van die soort (gevuld als het aan staat, de rand als het uit staat), met het aantal objecten erachter en Alle · Geen · Omkeren. Aangevinkt is zichtbaar (in het begin alle soorten, ook een die later gevonden wordt); een uitgevinkte soort verbergt haar maskers en die objecten vervagen. Gratis, alleen weergave. Zolang het zoekveld boven de objectenlijst tekst bevat, staat wat je typte vooraan als vinkje met het aantal treffers (doll (2), ook als het woord alleen in de AI-beschrijving staat); staat het aan, dan zijn al die objecten te zien, ook als andere soorten uit staan. Heet een soort net zo, dan zijn ze één vinkje (wens Olaf, 9-11-2026).
- Kleurenlegenda (wens Olaf): onder de werkbalk van de viewer, standaard open, zolang Kaders of Maskers iets te tonen heeft. Twee regels recht onder elkaar, Alleen deze kaders tonen en Alleen deze maskers tonen, met dezelfde labelkolom; een afgebroken regel begint onder het eerste vinkje. De (i) staat in de kop en legt alle kleuren uit; een klik erop klapt de legenda ook open. De filters blijven gelden als je Maskers, Kaders of Namen aan- of uitzet.
- Midden: Beschrijven en vinden, het detectiepaneel in uitklapbare blokken (Codex Accordion), sinds 0.32.12 in deze volgorde (wens Olaf: wat al op Commons staat gaat voor nieuwe AI-suggesties): Uit Commons (alleen als er iets is), AI-suggesties voor deze afbeelding, Zoeken, Aanwijzen of tekenen, Bijsnijden in CropTool (0.18.0).
- Rechts: Gevonden objecten (uitsneden): laatst bezocht › pagina's (bij PDF/DjVu/TIFF, als miniaturen) › de objecten met vinkjes, en onderaan (blijft in beeld) de knoppen Geselecteerde objecten beschrijven, Dubbelingen samenvoegen, Selectie opslaan, Downloaden (zip) en Naar Commons….
- Elke kolom heeft een kop met één regel uitleg en een (i)-venster (0.28.0).
- Vergroter: de uitsnede, "Wat staat hierop?", het bijschrift en het Commons-concept (tab).
- Gebouwd in fase 1 (stand 0.9.0): de randen tussen de drie kolommen zijn versleepbaar (ook met de pijltjestoetsen; breedte per browser onthouden); de objectenlijst toont een miniatuur per object, en een regel licht op als de muis erboven of boven die uitsnede in het beeld staat; alle knoppen zijn Codex-blauw (progressive), verwijderen blijft rood; in het Commons-concept zitten de invulacties per veld in een klein menu (⋯) met Ongedaan maken direct erna; de namen die de app zelf geeft (klik, rechthoek, regio) en soort en zekerheid volgen de taal van de interface.
- Exporteren (wens Olaf, 9-11-2026;
ExportLinks.vue,GET …/export): Changelog, Verbruik en Objecten (beide tabbladen) hebben links JSON · CSV · Excel boven de facetten. Ze downloaden wat de facetten en het zoekveld nu tonen, in vaste kolommen; zonder keuze alles (bij Verbruik het hele log, ook boven de 500 regels). Gratis. In CSV krijgt tekst die als een formule begint een apostrof ervoor, in Excel is elke tekst een tekstcel, zodat een titel of AI-tekst in een spreadsheet niets kan uitvoeren. - Sorteerbare kolommen en lijstweergave (wens Olaf, 9-11-2026;
SortableTable.vue): een klik op een kolomkop sorteert oplopend, nog een klik aflopend; lege waarden staan altijd onderaan en tot je klikt blijft de volgorde van de pagina staan. Verbruik is een sorteerbare tabel. Changelog heeft een keuze Per versie (de standaard) of Tabel met versie, datum, reeks, soort en wijziging. Objecten heeft op beide tabbladen een keuze Kaarten of Lijst met dezelfde knoppen per object; ‹ › in de vergroter volgen de volgorde van de lijst. De browser onthoudt de keuze. - Naar Commons (wens Olaf, 10-11-2026): de knop voor beeldt af en bijschriften van de hele afbeelding (9.7) staat in een eigen uitklapblok Naar Commons, het laatste onder Beschrijven en vinden, en niet meer onder AI-suggesties voor deze afbeelding. Waarom: het venster gaat over al het werk aan de afbeelding (items uit Commons met een plaats, gevonden objecten, AI-zoektermen, het bijschrift), ook zonder AI. De kolom loopt zo in de volgorde van het werk: Van Commons … Naar Commons.
- Hulpmiddelen voor het hele bestand in de bestandskop (wens Olaf, 10-11-2026): achter het M-id en Q-id staan kleine links, elk in een nieuw tabblad en zonder iets te veranderen: Bijsnijden in CropTool (alleen bij afbeeldingen van één pagina; was een uitklapblok onder Beschrijven en vinden, maar CropTool neemt niets over uit de app: geen kader, masker of tekst), Waar gebruikt (Special:GlobalUsage op Commons) en Geschiedenis van de bestandspagina. De uitleg staat in de tooltip.
- Logo's bij het werk (wens Olaf, 10-11-2026): onder Metadata → Werk op Wikidata staat bij Collectie en Locatie het logo van die instelling, als het item er een heeft (P154), bijvoorbeeld van de KB. De server haalt het logo op (Wikidata en een kleine PNG van Commons, alleen lezen, gecachet) en geeft het via
GET /api/v1/wikidata/{q}/logo, zodat de browser niets van Wikimedia laadt. Bij een bestand dat al gelezen was, verschijnt het logo na Opnieuw lezen van Commons. In de bestandskop staat naast de bestandsnaam het M-id (naar de gestructureerde gegevens op Commons) en het Q-id van het werk met een klein Wikidata-logo, allebei te klikken. - Meldingen bij de knop (wens Olaf, 10-11-2026): de uitkomst van een actie staat onder de knop of link die erom vroeg, niet bovenaan de pagina: Opnieuw lezen van Commons onder die link, het weghalen van de beschrijving of de zoektermen in dat deel van AI-suggesties (of bovenaan die sectie als dat deel weg is), Selectie opslaan in Opslaan en exporteren, het masker van SAM in de vergroter, het weghalen van een vorm boven de objectenlijst (zoals de prullenbak). Ook een fout van zo'n actie. Alleen wat over het hele bestand gaat (een doorverwezen bestandsnaam), staat bovenaan.
- De keuze in het adres (wens Olaf, 10-11-2026: RESTful): op Objecten (beide tabbladen), Changelog en Verbruik staat wat je kiest in het adres, met dezelfde namen als de export:
tab=prullenbak,bron,mid,opgeslagen=1,aangevuld=1,qop Objecten;soort,reeks,datum,qop Changelog;soort,datum,bestand,model,gebruiker,qop Verbruik (lijsten komma-gescheiden). Bij het openen komt de keuze terug, dus elke weergave is als bladwijzer te bewaren en te delen. Ook in het adres (wens Olaf, 10-11-2026): de gesorteerde kolom (sorteer=kosten,sorteer=-kostenaflopend), de weergave (weergave=lijstop Objecten,weergave=tabelop Changelog; een adres wint van de voorkeur van de browser) en een open vergroter op Objecten (object=M…/1/obj-…&vergroten=1|aangevuld). Op de afbeeldingspagina: het zoekveld boven de objectenlijst (q), Minimale zekerheid in procenten (zekerheid=57) en Alleen deze maskers/kaders tonen (maskers=boy,child,kaders=geselecteerd; alleen zolang er iets uitgevinkt is,-is Geen). Het adres verandert zonder nieuwe stap in de geschiedenis van de browser; open of dichte uitklapblokken en kolombreedtes zijn indeling, geen weergave, en staan er niet in. - Zoeken op
/objecten(wens Olaf, 9-11-2026): op beide tabbladen staat boven de facetten een zoekveld, zoals op/changelog. Het zoekt in de naam, zoekterm, het bestand, de licentie, het bijschrift en de beschrijving (Nederlands en Engels); elk woord moet voorkomen. Het werkt samen met de facetten, en de knoppen voor alles wat zichtbaar is, de vergroter en de export volgen het. - Een afbeelding opnieuw beginnen (wens Olaf, 10-11-2026): naast het prullenbakje van elke afbeelding bij Bekeken staat ↻, alleen te gebruiken als er voor die afbeelding iets bewaard is (objecten, prullenbak, AI-suggesties of een concept; de app vraagt dat aan
GET …/werk). Na een bevestiging die zegt wat er weggaat (aantallen objecten, prullenbak, opgeslagen uitsneden, en of er AI-suggesties en een concept voor Commons zijn) gaat alles weg wat voor die afbeelding bewaard is, op alle pagina's (DELETE …/bestand/{mid}/werk), en vergeet de browser de gezochte woorden en uitgevinkte termen ervan. De bevestiging laat kiezen: Eerdere AI-antwoorden houden (dezelfde vraag opnieuw is gratis, uit de cache) of De AI opnieuw vragen: dan tellen de antwoorden die al in de cache stonden niet meer voor deze afbeelding (een merkteken met het tijdstip,ai_opnieuw_vanaf.json), en zijn het volgende paginaoverzicht en elke Wat staat hierop? nieuwe, betaalde antwoorden; wat daarna gevraagd wordt, telt weer gewoon. De zoektermen voor de beelddetectie (SAM) blijven uit de cache komen: SAM geeft voor hetzelfde woord hetzelfde resultaat. Op Commons verandert niets. De AI-suggesties horen bij de afbeelding, niet bij de objecten; dat staat nu ook onder AI-suggesties voor deze afbeelding en in de (i). - Een verkeerd woord weghalen (wens Olaf, 10-11-2026): onder elk object in de lijst en in de vergroter staat Ook gevonden als: boy × child ×, de woorden waarmee het object ook gevonden is voordat vondsten samengingen. Met × haal je een woord weg waar de beelddetectie ernaast zat (de pop gevonden als boy). Een woord dat ook in de naam, de eigen zoekterm (car bij vintage car), het onderwerp van de beschrijving (Nederlands of Engels) of het bijschrift staat, als heel woord (ook meervoud), klopt en heeft geen × (boy bij Boy in white sailor suit with box, wens Olaf); het object telt dan niet meer onder dat woord bij de zoektermen (bij de maskers tellen deze woorden sinds 12-11-2026 sowieso niet mee). De vondst blijft bewaard (
ook_weg), zodat een nieuwe zoekopdracht met dat woord haar niet opnieuw samenvoegt. Met Ongedaan maken, in de lijst en in de vergroter; in de lijst in kleine letters en met vanaf het derde woord +n meer (wens Olaf). Gratis. Nog niet voor de leden van een groep. - Zoektermen tellen samengevoegde vondsten mee (wens Olaf, 10-11-2026): een zoekterm-knop bij AI-suggesties telt de objecten die met dat woord gevonden zijn, ook als ze daarna in een ander object zijn opgegaan (ook: girl in child) of in een groep zitten. Alleen deze maskers tonen doet hetzelfde: zo'n object staat ook onder elk woord waarmee het gevonden is (girl (1)); het masker houdt de kleur van zijn eigen soort. De regel Op de afbeelding: n objecten gevonden met m van de k zoektermen telt elk object één keer.
- Ontdubbelen in groepen (wens Olaf, 10-11-2026): een groep als geheel wordt nooit samengevoegd (zijn kader omvat alle leden), maar een lid wel. Een nieuwe vondst of een object dat hetzelfde toont als een lid van een groep, gaat in dat lid op: het lid houdt zijn naam en vorm, de ander staat eronder als ook. Bij samenvoegen blijft het item waarvoor een van beide gelokaliseerd is (
wikidata) bewaard, ook buiten groepen. Ontdubbelen zegt welke objecten in welke zijn opgegaan (koffer → kartonnen doos). - Bewaard antwoord of SAM opnieuw (wens Olaf, 10-11-2026): zoek je naar woorden waar SAM op deze afbeelding al naar zocht, dan vraagt de app eerst wat je wilt: Bewaarde antwoorden gebruiken (gratis voor die woorden, meteen klaar) of SAM opnieuw vragen (alle woorden opnieuw, betaald, met het bedrag op de knop). De keuze zegt erbij dat meestal hetzelfde terugkomt: SAM geeft voor dezelfde afbeelding, hetzelfde woord en hetzelfde model hetzelfde antwoord; een ander zoekwoord geeft wel iets anders. Het nieuwe antwoord vervangt het bewaarde. API:
"vers": truebijPOST …/detecties; de raming geeftin_cacheen met?vers=1de kosten van opnieuw vragen. Zonder bewaarde woorden blijft het de gewone kostenbevestiging. - Beeldt af, zonder regio: eerste en volgende ronde (wens Olaf, 10-11-2026): de knop doet hetzelfde als altijd (alle aangevinkte items), maar heet na de eerste ronde Alle items opnieuw lokaliseren (n) (of Gekozen items opnieuw …). Een volgende ronde is het zodra een item een gekoppeld object op de afbeelding heeft (door dat item te lokaliseren; dan is zijn knop groen, zoals al zo was). Het bedrag komt van de raming (
GET …/detecties/raming): een woord dat al gezocht is, komt uit de cache en is gratis. - Changelog in het Engels (wens Olaf, 10-11-2026): de wijzigingen zelf blijven Nederlands, zoals alle documentatie. De soorten wijziging (Toegevoegd → Added, Gewijzigd → Changed, Opgelost → Fixed, …), de inleiding en de facetten volgen de taal van de interface, en in het Engels zegt een regel bovenaan dat de wijzigingen in het Nederlands staan. In de API en de export blijft de soort de waarde uit
CHANGELOG.md. - Lijstpagina's met facetten (wens Olaf, 9-11-2026;
ListFacets.vue):/changelogen/verbruikhebben links een zoekveld en facetten, in de stijl van/objecten, met dezelfde versleepbare rand. Binnen een facet is één gekozen waarde genoeg, tussen facetten moet alles kloppen, en elk gezocht woord moet voorkomen. Heeft een facet meer dan zes waarden, dan staan de zevende en verder in een uitklapblok, dat zegt hoeveel erin aangevinkt is. De waarden staan op aantal, hoogste eerst; datums en versiereeksen op nieuwste eerst. Changelog: soort wijziging, versiereeks en datum; Flask maakt de hele pagina en de filter verbergt alleen wat niet past, dus de pagina is ook zonder JavaScript leesbaar. Verbruik: soort, datum, bestand met miniatuur, model (met een (i) die de vier modellen uitlegt en een korte omschrijving per model) en gebruiker, over de laatste 500 aanroepen die de API meegeeft; de tegels bovenaan blijven de totalen. - Pagina's:
/objecten(alle uitsneden; de rand tussen de facetten en de objecten is versleepbaar, en het facet Bestand toont per bestand een miniatuur die de afbeelding groot toont, te zoomen, verslepen en scrollen (ZoomImage), met de omtrek van het masker van elk object van dat bestand (zonder vorm het kader) uit het tabblad (Objecten of Prullenbak), met links naar Mineventory en Commons; het tabblad Prullenbak heeft dezelfde facetten (ObjectFacets.vue,facets.js), met terugzetten en definitief verwijderen van wat de filters tonen; met de facetten Bron, AI-aangevuld (wens Olaf, 8-11-2026: objecten met een AI-aangevulde versie, 7.7), Bestand en Alleen opgeslagen uitsneden; elke kaart heeft naast de prullenbak een oog dat de vergroter op deze pagina opent, met ‹ › door de getoonde objecten, en met het facet AI-aangevuld aan meteen op het tabblad met de AI-aangevulde versie; Ctrl-klik opent het object op zijn bestand via/?mid=…&pagina=…&object=…&vergroten=1|aangevuld; de prullenbak vraagt bevestiging, met de miniatuur; een object uit het tabblad Prullenbak is in de vergroter alleen te bekijken: alleen het tabblad Uitsnede, zonder bijschrift, keuze PNG/JPG en knoppen; een kaart met een opgeslagen uitsnede heeft Bestand openen en Downloaden, en alleen als de app op je eigen computer draait (debugmodus, zelfde machine) ook Tonen in map, want op Toolforge ziet niemand de schijf),/commons(het keuzemenu),/verbruik,/docs,/changelog. - Footer: "Dit is een experiment. Het is geen officiële dienst van de KB, nationale bibliotheek, of van de Wikimedia Foundation. Aan deze toepassing kunnen geen rechten worden ontleend." Plus links naar de documentatie, de API, de broncode, de privacyverklaring en de changelog.
- Meldingen als Codex Message, met één betekenis per kleur (besluit Olaf, 12-11-2026): error (rood) alleen als er iets misging (een mislukte aanroep, geen verbinding, de limiet bereikt, kopiëren mislukt); warning (geel) voor alles om op te letten of ongedaan te maken (naar de prullenbak, niets gevonden, samengevoegd, al beschreven, geen dubbelingen, hernoemd en gekoppeld); success (groen) als het lukte; notice (grijs) alleen voor vaste uitleg in een venster of formulier, niet als melding na een actie. Sinds 0.40.3 (wens Olaf, 13-11-2026): elke actie die iets verandert krijgt een melding, bij de knop die erom vroeg, met ↶ Ongedaan maken waar een gratis aanroep het terugdraait (hernoemen, groeperen en opheffen, terugzetten uit de prullenbak, een beschrijving of aangevulde versie wissen of een andere versie gebruiken, een eigen prompt, Bekeken, een getekende rechthoek, een vorm, het concept terugzetten); na een betaalde vraag Vorige versie terugzetten. Niet terug te draaien: definitief verwijderen, prullenbak legen, Opnieuw beginnen, ontdubbelen, uitsneden opslaan, uploaden. Elk venster is versleepbaar (sinds 0.40.5, wens Olaf, 13-11-2026): aan de titelbalk verplaatsen, aan de randen groter of kleiner, dubbelklik op de titelbalk zet het terug in het midden (
movableDialogsinmovable.js, één keer per pagina); de vergroter en Gestructureerde gegevens onthouden hun plek, de andere vensters openen steeds in het midden. Meldingen verdwijnen nooit vanzelf: je klikt ze weg met het kruisje; per plek staat er één, een nieuwe vervangt de vorige. Alle meldingen van de vier bulkacties staan op één vaste plek boven hun tabbladen, zodat ze altijd in beeld zijn, en zien er hetzelfde uit. Code:frontend/undo.js(useUndoMessage,versionBack,promptBack),UndoMessage.vue, en in CutterAppnotify(…, {where, actions})metundoAction. - Fouten en herstel (wens Olaf, 13-11-2026, sinds 0.40.6): de app blijft bruikbaar als er iets misgaat, en zegt wat er misging. Elke fout van de server is JSON met een code (zie api.md); de frontend toont die als één rode melding, ook bij een HTML- of leeg antwoord of geen verbinding (
api.js, met een vangnet voor onverwachte fouten insafety.js). Een gratis leesverzoek (GET) wacht niet eindeloos en wordt bij een netwerkfout nog eens geprobeerd; een betaald of wijzigend verzoek nooit. Een antwoord dat binnenkomt nadat je naar een ander bestand of een andere pagina ging, komt niet op de verkeerde plek (newestOnly). Dubbelklikken op een betaalde knop doet één aanroep; de bezig-balk loopt pas na de bevestiging, bij de knop die erom vroeg. Bestanden worden atomisch geschreven (cutter/opslag.py): nooit half. Een beschadigdobjecten.jsonmaakt de pagina leeg maar niet onbruikbaar; de app bewaart een kopieobjecten.json.kapot-…en zegt het met een gele melding boven de objecten (één keer per kopie; een beheerder zet het terug). Een beschadigd cachebestand wordt opnieuw gevraagd. Items zonder Nederlands of Engels label krijgen een leesbare naam (meertalig of een andere taal met een taalmerkje); zonder Engels label vraagt de app eerst een Engels zoekwoord voor SAM. - Uitleg die de werkelijkheid volgt (wens Olaf, 13-11-2026, sinds 0.40.6): bovenaan AI-suggesties voor deze afbeelding staat vóór de eerste vraag wat de AI zal maken; daarna, in de verleden tijd, wat er nu is: de beschrijving in hoeveel lengtes (of geen), wel of geen tekst uit de afbeelding, het aantal zoektermen (of geen) en of daarmee al objecten gevonden zijn. De woorden beschrijving, tekst en zoektermen zijn links: een klik klapt dat deel open en schuift ernaartoe (sinds 0.40.7). Bij Naar Commons zegt het paneel kort wat de knop doet; de lijst van wat terug kan staat in het venster zelf.
10.5 Mobiel¶
Panelen als tabbladen (Objecten, Beeld, Detectie; gebouwd in 0.19.0, Beeld eerst). Bekijken en selecteren wel; uploaden bij voorkeur op een groot scherm.
11. REST-API¶
Versieprefix /api/v1, OpenAPI op /api/v1/openapi.json, documentatie op /docs. Zelfde conventies als in de Delpher Uitsnijder: JSON-fouten {"fout": …}, X-Robots-Tag: noindex, een GET kost nooit geld. {mid} is de M-id (M28830642).
| Methode | Pad | Functie |
|---|---|---|
| GET | / met url, titel of mid, en pagina |
De UI; met parameters opent het bestand meteen |
| GET | /api/v1/bestand?url=…|titel=…|mid=… |
Normaliseren; titel, M-id, afmetingen, MIME, SHA-1, licentie, maker, categorieën, SDC-samenvatting, paginalijst, rechtenlabels |
| GET | /api/v1/bestand/{mid}/pagina/{n} |
Pagina: afmetingen, objecten, regio's uit Commons |
| GET | /api/v1/bestand/{mid}/pagina/{n}/afbeelding?w= |
Verkleinde afbeelding (gecachet) |
| POST | /api/v1/bestand/{mid}/pagina/{n}/detecties |
Detectie (prompt, modus: prompt, alles, commons; of punt). 201 |
| GET | /api/v1/bestand/{mid}/pagina/{n}/detecties/raming |
Kostenraming; voert niets uit |
| GET, POST | /api/v1/bestand/{mid}/pagina/{n}/inventaris |
Paginaoverzicht |
| PATCH | /api/v1/bestand/{mid}/pagina/{n}/objecten |
Selectie of status wijzigen |
| GET, PATCH, DELETE | /api/v1/bestand/{mid}/pagina/{n}/object/{oid} |
Eén object; DELETE = prullenbak |
| GET | …/object/{oid}/uitsnede.png en …/uitsnede.jpg |
De uitsnede in volledige resolutie |
| GET, POST, DELETE | …/object/{oid}/beschrijving |
Wat staat hierop? |
| GET, PATCH | …/object/{oid}/commons |
Het Commons-concept (gratis) |
| GET, POST | /api/v1/bestand/{mid}/pagina/{n}/uitsneden |
Uitsneden opslaan |
| GET | /api/v1/bestand/{mid}/commons |
Het keuzemenu |
| POST | /api/v1/bestand/{mid}/commons/controle |
Controle vooraf (alleen lezen op Commons) |
| POST | /api/v1/bestand/{mid}/commons/uploads |
Uploaden van de gekozen objecten; vereist een login, {"bevestigd": true} en COMMONS_UPLOAD=aan. 202 met een taak-id |
| GET | /api/v1/uploads/{taak} |
Voortgang van een upload; DELETE stopt hem |
| GET | /api/v1/bestand/{mid}/export?formaat=zip|json |
Exporteren, inclusief wikitekst per uitsnede |
| GET, DELETE | /api/v1/prullenbak |
Prullenbak |
| GET | /api/v1/objecten |
Alle opgeslagen objecten, met filters |
| GET | /api/v1/status |
Versie, modus, ingelogde gebruiker, budgetten |
| GET | /api/v1/verbruik |
Verbruikslog |
| GET, PATCH | /api/v1/beheer/instellingen |
Limieten, noodknoppen, modellen, bewaartermijnen (alleen beheerders) |
| GET, POST, DELETE | /api/v1/beheer/beheerders[/{gebruiker}] |
Beheerders (alleen beheerders) |
| GET, POST, PATCH, DELETE | /api/v1/beheer/toegang[/{gebruiker}] |
Toegangslijst, met eigen daglimiet of blokkade (alleen beheerders) |
| GET, PATCH | /api/v1/beheer/aanvragen[/{id}] |
Aanvragen bekijken, goedkeuren of afwijzen (alleen beheerders) |
| POST | /api/v1/toegang/aanvragen |
Toegang aanvragen (iedere ingelogde gebruiker; één openstaande aanvraag per gebruiker) |
| GET | /api/v1/beheer/logboek |
Logboek van wijzigingen (alleen beheerders) |
| GET | /beheer |
Het beheerpaneel (UI) |
| GET | /oauth/login, /oauth/callback, POST /oauth/logout |
Inloggen (geen deel van /api/v1) |
| GET, PATCH | /api/v1/account |
Eigen tegoed, verbruik en instellingen (8.6.5) |
| PUT, DELETE | /api/v1/account/meta-sleutel |
Eigen Meta-sleutel opslaan of verwijderen; nooit terug te lezen (8.6.4) |
| GET | /account |
Mijn account (UI) |
API-gebruik zonder browser: met de sessiecookie na het inloggen. Een eigen API-sleutel per gebruiker voor scripts komt later, in fase 4 (besluit 3-11-2026).
12. Toolforge¶
12.1 Opzet¶
- Een tool-account op Toolforge:
commons-mineventory(URLhttps://commons-mineventory.toolforge.org/). De naam moet Engels zijn; de repo heet hetzelfde (besluit Olaf, 3-11-2026; naam gewijzigd 5-11-2026, eerstcommons-cutter). Op 5-11-2026 nagekeken:KBNLwikimedia/commons-mineventorybestaat nog niet op GitHub; of de naam vrij is op Toolforge (toolsadmin) en Toolhub, wordt nagekeken bij de deploy (backlog 12f). Olaf is de enige maintainer; andere maintainers voegt hij toe op toolsadmin. Beheerders in de app staan los daarvan (8.4). - Opslag van
uitvoer/op de Build Service (uitgezocht 8-11-2026, nog te regelen bij de deploy): een Build Service-container ziet de gedeelde schijf van de tool alleen met--mount=all, en$HOMEwijst dan niet naar de datamap (gebruik$TOOL_DATA_DIR). De documentatie van Toolforge waarschuwt voor NFS in dit soort containers. Gebruikers kunnen die schijf niet doorbladeren;tools-staticis openbaar en dus niet geschikt voor uitsneden per gebruiker. - Build Service met een
Procfile(web: gunicorn --workers 2 --bind 0.0.0.0:$PORT wsgi:app) enrequirements.txt; deployen mettoolforge build start <git-url>entoolforge webservice buildservice restart. Alternatief: de klassiekewebservice python3.11met een venv. Voorstel: Build Service. - De frontend bouwen (Vite, zie 10.2). Op Toolforge draait alleen Python; Node.js is alleen nodig om
static/dist/te maken. Twee routes, bij de bouw kiezen: 1. In de Build Service zelf: als die naast Python ook een Node-stap kan draaien (npm ci && npm run build). Het eenvoudigst, als het kan. 2. In een GitHub Action (terugvaloptie): bij elke push naarmainbouwt de Action de frontend en zet het resultaat in een aparte branch (bijv.deploy), die de Build Service ophaalt.static/dist/komt dan nooit inmain. - Configuratie met
toolforge envvars create …(MODEL_API_KEY,OAUTH_CLIENT_ID,OAUTH_CLIENT_SECRET,FLASK_SECRET_KEY, en voor de eigen sleutels van gebruikersSLEUTEL_VERSLEUTELING, 8.6.4). Nooit in de repo. - Opslag: cache en uitvoer op de gedeelde schijf van de tool (
/data/project/commons-mineventory/). Die schijf is gedeeld en niet bedoeld voor veel of blijvende opslag, dus een dagelijkse opruimtaak (toolforge jobs) ruimt op. Bewaartermijnen, besloten door Olaf (3-11-2026); ze tellen vanaf het laatste gebruik, niet vanaf het aanmaken:
| Wat | Termijn | Waarom |
|---|---|---|
| Originelen (de gedownloade scans) | 7 dagen | Staan altijd op Commons en zijn gratis opnieuw op te halen |
| Uitsneden en maskers die nog niet zijn geüpload | 30 dagen | Tijd om te controleren, te uploaden of als zip te downloaden. De app toont bij elke uitsnede wanneer die verloopt |
| Uitsneden die op Commons staan | Het bestand gaat weg na de upload; de gegevens (Commons-URL, datum, gebruiker) blijven | Het bestand op Commons is de blijvende kopie |
| Detecties en beschrijvingen (de antwoorden van SAM en Muse Spark, klein) | 1 jaar | Opnieuw vragen kost geld; met de cache kost het nog eens openen van een bestand niets |
Instelbaar met BEWAAR_ORIGINELEN_DAGEN=7, BEWAAR_UITSNEDEN_DAGEN=30 en BEWAAR_CACHE_DAGEN=365. De opruimtaak en de app (ook met meerdere workers) schrijven de objecten van een pagina onder één gedeeld slot, een slot op het bestand uitvoer/.slot dat ook tussen processen werkt (cutter/slot.py). Zo overschrijft de opruimtaak nooit een wijziging die iemand op hetzelfde moment in de app maakt. Hoeveel ruimte een tool mag gebruiken, bij de bouw nagaan; dat kan de termijnen nog veranderen.
Gebouwd in 0.18.0 (cutter/opruimen.py): het commando flask --app app opruimen telt wat weg zou gaan; met --echt wordt het verwijderd. Op Toolforge draait het dagelijks als toolforge jobs-taak met --echt. Het laatste gebruik is de toegangstijd van een bestand, die de app bij elk lezen zet (de wijzigingstijd blijft staan, want de Commons-cache gebruikt die voor de versheid). Precies:
- 7 dagen: cache/originelen en cache/commons (API-antwoorden en paginabeelden; allebei gratis opnieuw op te halen).
- 30 dagen: opgeslagen uitsneden en maskers (uitvoer/<mid>/pagina_<n>/jpg, png, maskers; vanaf fase 2 per gebruiker onder uitvoer/gebruikers/<id>/, zie 8.5); het object vergeet dan dat het opgeslagen was, en opnieuw opslaan maakt ze weer aan. Ook voorbeelden en maskerafbeeldingen in de cache. Objecten die op Commons staan, houden hun gegevens.
- 1 jaar: de antwoorden van SAM en Muse Spark in de cache, en een hele pagina (objecten en beschrijvingen) die zo lang niet geopend is.
- Nooit: het verbruikslog (uitvoer/verbruik).
- Sessies: server-side, in Redis van Toolforge of in bestanden; tokens versleuteld.
- Lange taken (Alles beschrijven, uploads van tientallen bestanden): pagina voor pagina vanuit de browser, zoals nu, of als toolforge jobs-taak. Voorstel: vanuit de browser, met de knop Stoppen.
- Werkgeheugen: een webservice heeft standaard een beperkt geheugen; grote scans (5.4) kunnen dat overschrijden. Bij de bouw meten en zo nodig meer aanvragen.
- Broncode: openbaar, met een open-sourcelicentie (verplicht op Toolforge). Licentie: MIT (besloten door Olaf, 3-11-2026). Let op: Codex (GPL-2.0-or-later), Vue (MIT) en meta-sam-parser (SAM License) houden hun eigen licentie; dat staat in de README, en Vite zet de licentieteksten bij de gebouwde bundel. De code komt op GitHub onder KBNLwikimedia/commons-mineventory (besluit 3-11-2026, naam 5-11-2026).
12.2 Lokaal ontwikkelen¶
Twee terminals:
flask --app app run --debug, metDETECTIE_MODUS=dummy,COMMONS_UPLOAD=uitenCOMMONS_OWNER_TOKENvoor uploads naar een testwiki;npm run devvoor de frontend (Vite, met direct herladen). Eenmalig vooraf:npm install.
Tests: pytest voor Python en npm test (Vitest) voor de frontend.
12.3 Regels van Toolforge en privacy¶
- Volgens de gebruiksvoorwaarden van Toolforge mag een tool geen persoonsgegevens (zoals IP-adressen) naar derden lekken zonder dat de gebruiker dat weet. Daarom: geen externe CDN's, lettertypen of scripts (alles zit in de gebouwde bundel en komt van de tool zelf), en een privacyverklaring op
/privacy. - Proefweergave van de wikitekst: de server laat Commons de wikitekst renderen (
action=parse) en geeft de browser alleen opgeschoonde HTML zonder afbeeldingen, stijlen of scripts; de browser laadt dus niets van Wikimedia (9.1). - Meta Model API: de server stuurt beelden van Commons (openbaar) en de context (beschrijving, categorieën) naar Meta, nooit gegevens van de gebruiker. De privacyverklaring zegt dat. Of een commerciële, betaalde API van Meta acceptabel is voor een Toolforge-tool, zoeken we uit vóór de deploy (besluit Olaf, 3-11-2026: "zien we te zijner tijd").
- Verbruikslog met gebruikersnamen: zie 8.3.
13. Fasering¶
Fase 0 (nu): dit FO, de repo, de open vragen.
Fase 1: lokaal, zonder kosten
- Skelet overnemen uit de Delpher Uitsnijder: detectie (
DummyDetector), prompts, cache, verbruik, API-conventies, tests. - Commons-adapter: invoer normaliseren, imageinfo, wikitekst, SDC, licentie- en rechtenlabels, meerpaginabestanden, caching.
- Frontend-opzet met Vite, Vue 3 en Codex 2.x; de viewer uit de Delpher Uitsnijder als JS-module; de koppeling Flask–Vite (10.2); de vertaalbestanden voor Nederlands en Engels (3). Daarna de UI, meteen tweetalig.
- Uit Commons: de regio's uit de gestructureerde gegevens (P180 met P2677) als objecten, en de bestandsnotities.
- Opslaan, zip,
/objecten. - Commons-concept per object, keuzemenu, controle vooraf en proefweergave, zonder upload.
6a. Het dashboard met collecties uit categorieën (17), zonder voorscan door AI, lokaal onder de gebruiker
lokaal(besluit Olaf 5-11-2026: nu bouwen, vóór OAuth).
Fase 2: OAuth, upload naar een testwiki, categorieën
- OAuth 2.0 server-side, met een owner-only consumer. Daarmee het werk per gebruiker gescheiden (8.5).
- Upload via de stash, SDC,
{{Image extracted}}op het origineel; alles eerst op de testwiki (welke, blijkt bij de bouw). - Beheerpaneel (8.4): beheerders, toegangslijst, aanvragen, limieten (100 per gebruiker; 500 aanroepen en $2 per dag in totaal), noodknoppen, logboek; opslag in SQLite (lokaal) en ToolsDB (Toolforge). Daarna het starttegoed en de eigen Meta-sleutel (8.6), want die hebben OAuth en de database nodig.
- Een categorie als invoer: bladeren door de bestanden van
Category:…(5.1). Vervallen: wordt het dashboard (17), al in fase 1 (6a).
Fase 3: live
- Detectie en beschrijving live (
DETECTIE_MODUS=live), alleen na een opdracht van Olaf. Kalibratie op Commons-materiaal (albums, prenten, kaarten). - Deploy naar Toolforge als
commons-mineventory, publieke consumer aanvragen, privacyverklaring. Olaf maakt de projectpaginaCommons:Commons Mineventoryen de volgcategorie aan. - De eerste echte uploads op Commons, door Olaf zelf.
Fase 4: verdieping
- Batch over meerdere bestanden (een hele categorie in één keer).
- Regio's terugschrijven naar het origineel (P180 met P2677); het voorbeeld staat al in de proefweergave (9.4). Valt samen met het venster Beeldt af en caption voor de hele afbeelding (9.7), dat al in fase 2 kan, na de upload.
- Een link vanuit Commons: gadget of een item in het menu Hulpmiddelen ("Openen in de Commons Mineventory"), zoals CropTool.
- IIIF-annotaties exporteren.
- Eigen API-sleutel per gebruiker voor scripts.
- Meer talen in de interface.
- Nice-to-have: een canvas om uitsneden te combineren tot nieuwe werken (18), niet voor Commons.
- Nice-to-have: een 3D-model van een uitsnede via SAM 3D Objects op Runware (7.8), niet voor Commons.
14. Repo-structuur (doel)¶
commons-mineventory/
app.py wsgi.py Procfile requirements.txt .env.example .gitignore
cutter/ (beheer.py, opslag.py, commons.py, regios.py, oauth.py, upload.py, wikitekst.py, sdc.py, rechten.py, weergave.py,
detectie/{basis,dummy,meta_sam,maskers,dienst}.py, beschrijving.py,
prompts.py, verbruik.py, cache.py, export.py, api.py, openapi.py, web.py)
templates/ (Jinja-pagina's met mountpunten voor Vue)
frontend/ (main-*.js per pagina, components/*.vue, viewer/*.js, api.js, styles/)
static/dist/ (gebouwd door Vite; niet in git)
package.json package-lock.json vite.config.js
docs/ (functioneel-ontwerp.md, api.md, oauth-registratie.md, deploy-toolforge.md, privacy.md)
tests/ (met fixtures voor Commons, SAM en Muse)
README.md CLAUDE.md CHANGELOG.md BACKLOG.md LICENSE
15. Open vragen voor Olaf¶
Besloten (3-11-2026)¶
| Onderwerp | Besluit | Waar |
|---|---|---|
| Naam | Commons Mineventory (5-11-2026; eerder Commons Cutter); tool, repo en map heten commons-mineventory (lokaal D:\KB-OPEN\github-repos\commons-mineventory, op GitHub KBNLwikimedia/commons-mineventory); het Python-package heet nog cutter/. Backlog 12f |
12.1 |
| Kosten | Eén API-sleutel van de KB voor de Meta-aanroepen | 3, 6.4 |
| Codex | 2.x met Vue 3 | 10.1 |
| Build-stap | Vite (Node.js alleen bij het ontwikkelen en bouwen); de viewer blijft een gewone JS-module; op Toolforge draait alleen Python | 10.2, 12.1 |
| Wie mag betalen | Een toegangslijst, beheerd in het beheerpaneel; in het begin alleen Olaf; toegang aanvragen in de app | 8.3, 8.4 |
| Beheer | Olaf is de enige beheerder; andere beheerders voegt hij toe op Wikimedia-account in een beheerpaneel in de tool, waar ook de toegangslijst, limieten en instellingen staan. Maintainers op Toolforge gaan via toolsadmin | 8.4 |
| Betaalde Meta-API op Toolforge | Later uitzoeken, vóór de deploy | 12.3 |
| Daglimieten | 100 aanroepen per gebruiker; in totaal 500 aanroepen en $2 per dag | 6.4 |
| OAuth | Server-side, als confidential client | 8.1 |
{{Image extracted}} |
Standaard aan op het origineel, per upload uit te zetten | 9.3 |
{{Extracted from}} |
Verplicht op elke uitsnede | 9.3 |
| Bestandsnaam | Onderwerp voorop, in het Engels | 9.2 |
| Licentie van de code | MIT | 12.1 |
| Regio's uit de gestructureerde gegevens | De app vindt ze en snijdt elke regio als apart bestand uit | 7.5 |
| Interface | Meteen tweetalig, Nederlands en Engels | 3 |
| Categorie als invoer | Fase 2 | 5.1, 13 |
| PDF en DjVu | De gerenderde pagina van Commons volstaat | 5.4 |
| Contributor-model | Aan voor publiek domein, ook bij bestanden van anderen | 6.3 |
| Volgcategorie en projectpagina | Beide; Olaf maakt ze aan | 9.3 |
| Verbruikslog | Gebruikersnamen leesbaar, alleen zichtbaar voor de toegangslijst en beheerders | 8.3 |
| Logo | Eigen icoon | 10.3 |
| Testwiki | Wat bij de bouw blijkt te werken | 9.6 |
| Beeld naar SAM | Als data-URL | 6.1 |
| API-sleutel per gebruiker | Later, fase 4 | 11, 13 |
| Bewaartermijnen op Toolforge | Originelen 7 dagen, niet-geüploade uitsneden 30 dagen, detecties en beschrijvingen 1 jaar; telt vanaf het laatste gebruik | 12.1 |
| Upload Stash | Alleen als controlestap vlak vóór het publiceren; geen overdracht aan de Upload Workbench of andere tools | 9.1 |
| Dashboard met collecties | Nu bouwen, vóór OAuth; de bewerker naar /bewerken; voorlopig geen voorscan door AI (5-11-2026) |
17, 17.10 |
| Starttegoed | Eenmalig 100 aanroepen; een eigen Meta-sleutel gaat altijd voor; de toegangslijst blijft (5-11-2026) | 8.6, 8.6.6 |
| Werk per gebruiker | Elke ingelogde gebruiker werkt in een eigen uitvoermap; cache en AI-antwoorden blijven gedeeld (5-11-2026) | 8.5 |
Aangenomen (niet beantwoord, voorstel geldt tot Olaf anders zegt)¶
- Grote bestanden: boven 100 megapixel stuk voor stuk met libvips (5.4; besluit Olaf 4-11-2026, gebouwd in 0.21.0).
- Beschrijving en caption in het Nederlands én het Engels (6.2).
Nog open¶
Geen vragen die de bouw van fase 1 en 2 tegenhouden. Later:
- Is een commerciële, betaalde API van Meta acceptabel voor een Toolforge-tool? Vóór de deploy in fase 3 uitzoeken (besluit Olaf: "zien we te zijner tijd"). (12.3)
16. Te verifiëren bij de bouw¶
-
Of ToolsDB de juiste plek is voor de gegevens van het beheerpaneel, en hoe de tool erbij kan (8.4).
-
De thumbnailstappen die Commons nu toestaat (5.2).
- De minimale set OAuth-grants (8.2).
- Of de testwiki OAuth 2.0 en SDC ondersteunt (9.6).
- Welke SDC-eigenschap de relatie uitsnede → origineel vastlegt (9.4).
- Of Commons afspraken heeft over beeldt af en captions die met AI zijn gevonden, en hoe ander gereedschap dat P2677 schrijft (zoals Wikidata Image Positions) dat vastlegt (9.7).
- Of Commons-bots P1163, P4092, P3575, P2048 en P2049 na een upload zelf toevoegen, zodat de app ze niet dubbel zet (9.4).
- Of de Toolforge Build Service een Node-stap (
npm ci && npm run build) vóór de Python-build kan draaien, of dat de frontend in een GitHub Action wordt gebouwd (12.1). - Welke Vue-versie Codex 2.x vraagt, en of Codex-componenten die zich in een Jinja-pagina mounten goed samengaan met de CSS van Flask-pagina's (10.2).
- Geheugen en time-outs van een Build Service-webservice op Toolforge (12.1).
- Of Commons regels heeft voor beschrijvingen die deels met een taalmodel zijn gemaakt.
- Of de Meta Model API een gratis manier heeft om een sleutel te controleren, en wat Meta toestaat bij het gebruik van sleutels van anderen in een tool (8.6.3).
- De goedkoopste verzoeken om per bestand van een collectie te zien welke uitsneden er met de Commons Mineventory of ander gereedschap op Commons staan (17.4, Al bewerkt).
- Hoeveel miniaturen
prop=imageinfo&iiurlwidth=per verzoek levert bijgenerator=categorymembers(17.3), en of miniaturen vanupload.wikimedia.orgsneller dan één per seconde mogen (17.3).
17. Dashboard: collecties uit categorieën¶
Op verzoek van Olaf (5-11-2026). Nog niet gebouwd. Zijn besluiten (5-11-2026) staan in 17.10. Het belangrijkste: nu bouwen, vóór OAuth, en voorlopig geen voorscan door AI; je kiest met de hand (17.5).
17.1 Doel¶
Vóór het werk per afbeelding (de bewerker, 10.4) komt een dashboard. Daar stel je collecties samen: sets afbeeldingen die je daarna één voor één in de bewerker detecteert, uitsnijdt en beschrijft.
- Je opent een categorie van Commons. De app toont alle afbeeldingen erin als miniaturen.
- Per afbeelding geef je met een vinkje aan of er iets in staat dat de moeite van het uitsnijden waard is: illustraties, wapens, portretten, foto's in een album.
- Je kiest met de hand. Een voorscan met SAM, die per afbeelding laat zien of er objecten in staan, is ontworpen maar uitgesteld (17.5).
- Met één knop wordt de selectie een werkset. Die loop je in de bewerker één voor één door, met Vorige en Volgende en een status per afbeelding (17.6).
Dit vervangt "Een categorie als invoer" (5.1, backlog 15a) en is de eerste stap naar "Batch over meerdere bestanden" (13, fase 4 punt 14).
17.2 Begrippen¶
- Collectie: een benoemde set Commons-bestanden met een bron (nu: één categorie), en per bestand een keuze en een status. Een collectie is alleen gegevens; de afbeeldingen blijven op Commons.
- Keuze per bestand: wel (aangevinkt: hier staan objecten in), niet (bewust uitgevinkt) of nog niet bekeken.
- Voorscan: een detectie met SAM op de hele afbeelding, met een of enkele zoektermen die voor de hele collectie gelden. De uitkomst is een voorstel voor de keuze.
- Werkset: de bestanden van een collectie met keuze wel, in de volgorde van de collectie. Er is geen apart object "werkset": het is een weergave van de collectie.
- Status per bestand in de werkset: te doen, bezig (in de bewerker geopend), klaar of overgeslagen.
17.3 Een categorie openen¶
- Invoer:
Category:Album amicorum van Jacob van Bronckhorst van Batenburg,Categorie:…, een URL van de categoriepagina, of alleen de naam. Normaliseren zoals bij een bestand (5.1). Een redirect ({{Category redirect}}) wordt gevolgd en gemeld. - Eerst een voorproefje (gratis, één verzoek,
prop=categoryinfo): het aantal bestanden en het aantal subcategorieën. Daarna maak je de collectie aan, met de naam van de categorie als voorgestelde naam. - Bestanden ophalen:
generator=categorymembers&gcmtype=file&prop=imageinfo&iiprop=url|size|mime|sha1&iiurlwidth=<stap>, per blok (gcmcontinue), met een eigen User-Agent,maxlag=5, caching en ongeveer één verzoek per seconde (5.2). De M-id isM+ de page-id; daar is geen extra verzoek voor nodig. - Subcategorieën: standaard alleen de categorie zelf. Onder de miniaturen staan de subcategorieën als chips met hun aantal bestanden; met een klik voeg je er een aan de collectie toe (één niveau diep; besluit Olaf).
- Grootte: hooguit 1000 bestanden per collectie. Bij een grotere categorie meldt de app dat, en neemt de eerste 1000 in de volgorde van Commons (
cmsort=sortkey; besluit Olaf). - Bestandstypen (5.4): SVG, GIF, video en audio staan er grijs en zonder vinkje in, met de reden. PDF, DjVu en meerpagina-TIFF zijn één tegel met het aantal pagina's erop; een latere voorscan alleen op pagina 1 (besluit Olaf).
- Bijwerken: Opnieuw ophalen zoekt nieuwe en verdwenen bestanden in de categorie. Nieuwe bestanden komen erbij als nog niet bekeken. Een verdwenen bestand blijft in de collectie staan, met een merkje. Gemaakt werk gaat nooit verloren.
Miniaturen en privacy. De browser laadt niets van Wikimedia (12.3). De server haalt elke miniatuur op in een vaste stapgrootte van Commons (5.2, bijv. 250 px; de stappen nog verifiëren, 16), cachet die 7 dagen (zoals cache/commons, 12.1) en levert hem aan de browser. De miniaturen laden pas als ze in beeld komen (lazy).
Snelheid. Bij één verzoek per seconde duren 500 miniaturen ruim 8 minuten. Miniaturen in standaardmaten komen uit de cache van upload.wikimedia.org en kosten Commons weinig. Daarvoor 4 tegelijk (ongeveer 4 per seconde; besluit Olaf), en de API-verzoeken naar api.php op één per seconde houden. Bij de bouw nagaan wat de richtlijnen van Wikimedia hierover zeggen (16).
17.4 Het dashboard¶
Startpagina met de collecties als kaarten:
┌ Commons Mineventory ─────────────────────────────── NL/EN Inloggen ┐
│ Collecties │
│ [ Category:… of URL ] [Categorie openen] │
│ Of open één bestand: [ File:… of URL ] [Openen] │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ ▦▦▦▦ (4 mini's) │ │ ▦▦▦▦ │ │ ▦▦▦▦ │ │
│ │ Album amicorum … │ │ Book of Hours … │ │ Prenten 1650 … │ │
│ │ 212 bestanden │ │ 48 bestanden │ │ 530 bestanden │ │
│ │ 37 gekozen │ │ 12 gekozen │ │ nog niet bekeken │ │
│ │ ███░░░ 9/37 klaar│ │ ██████ 12/12 │ │ │ │
│ │ 2 dagen geleden │ │ gisteren │ │ vandaag │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
- Per kaart: vier miniaturen, de naam, de bron (categorie, met link naar Commons), het aantal bestanden, het aantal gekozen, de voortgang van de werkset (klaar van het totaal) en wanneer de collectie het laatst is geopend.
- In een menu (⋯) per kaart: Hernoemen, Opnieuw ophalen en Verwijderen (destructief, met bevestiging). Verwijderen haalt alleen de collectie weg; objecten en uitsneden in de bewerker blijven.
- Eén bestand openen kan vanaf het dashboard nog steeds, zonder collectie (zoals nu).
Collectiepagina (/collecties/<id>): het raster met miniaturen.
┌ Album amicorum van Jacob van Bronckhorst van Batenburg ──────── ⋯ ┐
│ Category:Album amicorum … ↗ · 212 bestanden · 37 gekozen · 9 klaar │
│ │
│ Toon: (Alle) (Gekozen) (Niet gekozen) (Nog niet bekeken) │
│ (Voorscan: objecten) (Voorscan: niets) Grootte: ──●── │
│ [Alles kiezen] [Niets kiezen] │
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │☑ ▢▢ │ │☐ │ │☑ ▢ │ │◻ │ │☑ ▢▢▢ │ │◻ PDF │ │
│ │ 3 AI │ │ 0 AI │ │ 1 AI │ │ │ │ 3 │ │ 12p │ │
│ │klaar │ │ │ │bezig │ │ │ │ │ │ │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │
│ │
├ Voorscan met SAM ──────────────────────────────────────────────────┤
│ Zoektermen: [illustration ×] [coat of arms ×] [+ term] │
│ 175 bestanden nog niet gescand × 2 termen = 350 aanroepen │
│ [Voorscan (175) – ongeveer $0,88] │
├────────────────────────────────────────────────────────────────────┤
│ 37 gekozen · 28 te doen [Werkset openen (37) ▶] │
└────────────────────────────────────────────────────────────────────┘
- Tegel: de miniatuur, een vinkje linksboven, de bestandsnaam (ingekort; in volle lengte bij aanwijzen), en na een voorscan de gevonden kaders als dunne rechthoeken op de miniatuur, met het aantal en een AI-merkje. Onderaan de status in de werkset.
- Kiezen: klik op het vinkje; klik op de tegel opent een grotere weergave (de lightbox, met Vorige/Volgende en de toetsen ← →, spatie = vinkje aan/uit). Shift-klik kiest een reeks. Een tegel zonder keuze heeft een open vinkje (◻), een bewust uitgevinkte een leeg vinkje (☐).
- Filters als chips met hun aantal, zoals de facetten op
/objecten. Een schuif voor de grootte van de miniaturen, onthouden in de browser. - Voorscan: het deel Voorscan met SAM in de schets en de filters Voorscan: … komen pas als de voorscan terugkomt (17.5). In de eerste bouw zijn ze er niet.
- Hoofdactie (de enige gevulde knop): Werkset openen (n). Uitgeschakeld als er niets gekozen is.
- Wat er al met een bestand gebeurd is, staat ook op de tegel; zie hieronder.
Al bewerkt met de Commons Mineventory (wens Olaf, 5-11-2026). Op het dashboard en in het raster zie je welke afbeeldingen al bewerkt zijn, zodat je geen werk dubbel doet en geen uitsneden dubbel uploadt. Er zijn twee bronnen, allebei gratis:
- Door jou, in de app (uit je eigen map, 8.5; geen verzoek aan Commons). Per bestand het verste dat je kwam: - geopend: wel in de bewerker geweest, maar geen objecten; - objecten (n): gevonden, maar nog niet opgeslagen; - uitsneden (n): opgeslagen als JPG of PNG; - geüpload (n): met de app naar Commons gebracht.
- Op Commons, door wie dan ook (leesverzoeken, per blok van 50 bestanden, gecachet voor 1 dag):
- Uitsneden met de Commons Mineventory (n): bestanden in de volgcategorie
Category:Uploaded with Commons Mineventory(9.3) met{{Extracted from}}naar dit origineel. Dat geldt ook voor uploads door anderen en vanaf een andere server. - Uitgesneden met ander gereedschap (n):{{Image extracted}}op het origineel noemt bestanden die niet uit de Mineventory komen, bijvoorbeeld van CropTool (7.5). Ook dat is werk dat je niet dubbel wilt doen. - Regio's op Commons (n): het origineel heeft al P180 met P2677 (7.5). Die regio's kun je gratis gebruiken, en ze kunnen ook met het venster uit 9.7 zijn gezet.
Welke verzoeken het goedkoopst zijn, bepaal ik bij de bouw (16). Bijvoorbeeld prop=linkshere op de bestanden van de collectie, beperkt tot bestandspagina's, en dan prop=categories&clcategories= voor de volgcategorie. Of eenmalig de hele volgcategorie lezen en die per origineel indelen.
Daarnaast houdt de app een centraal register bij van wat ze zelf op Commons heeft gezet: uploads, {{Image extracted}} en regio's op het origineel, met datum en gebruikersnaam. Dat is openbare informatie (het staat op Commons), dus het register is gedeeld en niet per gebruiker (8.5). Zo weet de app het meteen, ook voordat de cache van Commons verloopt.
Hoe je het ziet: - Op de tegel een merkje in de hoek: blauw voor door jou bewerkt, groen met het aantal voor op Commons met de Mineventory, grijs voor ander gereedschap. Bij aanwijzen staat er wat en wanneer, met links naar de uitsneden op Commons. - Filters: Nog niet bewerkt, Door jou bewerkt, Al op Commons. - Op de kaart van de collectie: "212 bestanden · 18 al op Commons · 9 door jou bewerkt". - Bij de voorscan (later, 17.5): bestanden die al uitsneden op Commons hebben, slaat de voorscan standaard over. Dat spaart geld. Met een vinkje Ook bestanden die al bewerkt zijn scan je ze toch. - Bij het kiezen: een bestand dat al op Commons is uitgesneden, wordt nooit vanzelf aangevinkt, ook niet door de voorscan. Kies je het zelf, dan blijft het merkje staan. - In de bewerker: open je zo'n bestand, dan staat onder de titel een melding: "Van dit bestand staan al 3 uitsneden op Commons, gemaakt met de Commons Mineventory", met de links. Bij Naar Commons (9.1) waarschuwt de controle vooraf al voor dezelfde afbeelding (SHA-1, 9.5). Dit komt er dus bij, eerder in het werk. - Waarschuwen, niet blokkeren (zoals bij de rechten, 5.3): je kunt een bewerkt bestand altijd openen en opnieuw bewerken, bijvoorbeeld om een object toe te voegen dat de vorige keer ontbrak (besluit Olaf).
Werk van andere gebruikers dat nog niet op Commons staat blijft onzichtbaar. Iedereen werkt in een eigen map (8.5), en wat iemand nog niet gepubliceerd heeft, is van hem (besluit Olaf).
17.5 Voorscan met SAM¶
Uitgesteld (besluit Olaf, 5-11-2026): voorlopig geen voorscan door AI. Bij een grotere categorie van bijvoorbeeld 2000 bestanden kost die al snel $5; Olaf kiest dan liever met de hand. Wat hieronder staat, is het ontwerp voor later (backlog 19a). Komt de voorscan terug, dan zijn twee vragen nog open: SAM of ook Muse Spark, en automatisch aanvinken of alleen tonen.
- Wat: per bestand één SAM-aanroep per zoekterm (6.1, een gewone zoekterm uit 7.1), op dezelfde verkleinde versie als in de bewerker (1920 px). De zoektermen gelden voor de hele collectie en worden bij de collectie bewaard. Voorstel voor de eerste term:
illustration. De gebruiker past ze aan, zoals in Zoeken (EN/MIN-syntax en de vertaaltabel werken ook hier). - Hergebruik: de voorscan is dezelfde detectie als Zoeken in de bewerker en gebruikt dezelfde cache (per SHA-1 + pagina + term + model). Open je het bestand later in de bewerker, dan staan de gevonden objecten er al, als kandidaat (niet geselecteerd), en zoeken op dezelfde term kost niets meer.
- Keuze voorstellen: vindt de voorscan minstens één object met een score boven de drempel (voorstel: 0,5), dan wordt het vinkje gezet, met een AI-merkje (voorgesteld door AI). Vindt hij niets, dan blijft het bestand nog niet bekeken, met niets gevonden. Een keuze die de gebruiker zelf maakte, verandert de voorscan nooit. Open: automatisch aanvinken, of alleen tonen?
- Kosten en bevestiging: de knop draagt het bedrag (bestanden zonder voorscan × termen × $0,0025). Vóór de start volgt een bevestiging met het aantal aanroepen en het bedrag (6.4). Een voorscan van een term die al in de cache staat, kost niets en telt niet mee.
- Uitvoeren: vanuit de browser, bestand voor bestand, met voortgang en een knop Stoppen (12.1, Lange taken). Bij een limiet (429) stopt de voorscan netjes, met de melding hoeveel er nog te doen is. Wat klaar is, blijft bewaard.
- Limieten (6.4): een categorie van 300 bestanden met één term is 300 aanroepen. Dat is meer dan de 100 per gebruiker per dag en het grootste deel van de 500 voor de hele tool. Voorstel: de voorscan houdt zich aan dezelfde limieten en loopt dus soms over meer dagen (Verder met de voorscan), en de beheerder kan de limieten in het beheerpaneel (8.4) verhogen. Op Toolforge geldt daarnaast het starttegoed (8.6): een voorscan van een grote categorie past daar meestal niet in, en vraagt dus een eigen sleutel. De bevestiging zegt vooraf hoeveel van het tegoed gaat en wat op de eigen sleutel komt.
- Alternatief: AI-suggesties per bestand (het paginaoverzicht, 7.6) als voorscan, met Muse Spark. Dat kost ongeveer $0,007 per bestand, bijna drie keer een SAM-term, maar geeft ook een beschrijving en zoektermen die passen bij dat bestand, en die staan in de bewerker meteen klaar. Open: eerst alleen SAM, of ook het paginaoverzicht?
- Fase 1-regel: gebouwd en getest met de
DummyDetectoren fixtures. Live alleen op Olafs eigen server, door Olaf zelf.
17.6 De werkset in de bewerker¶
- Werkset openen opent de bewerker op het eerste bestand dat nog te doen is:
/bewerken?collectie=<id>&mid=M…. - Onder de invoerbalk staat dan een werksetbalk:
◀ Vorige │ Album amicorum … · 10 van 37 · 9 klaar │ ✓ Klaar ⤼ Overslaan │ Volgende ▶ │ Naar de collectie
- Vorige en Volgende lopen door de werkset (ook met Alt+← en Alt+→; de pijltjes zonder Alt blijven van de viewer en de vergroter).
- Status: een bestand wordt bezig zodra je het opent. Klaar en Overslaan zet je zelf, en gaan meteen naar het volgende bestand dat nog te doen is. Geen automatische klaar, want de app weet niet wanneer je klaar bent (besluit Olaf).
- De kolom Bekeken toont boven de gewone lijst de werkset, met de status per bestand, zodat je er ook rechtstreeks naartoe springt.
- Al het andere in de bewerker werkt zoals nu. De werkset verandert niets aan de objecten, uitsneden of het Commons-concept per bestand.
- Later (tweede iteratie, niet in de eerste bouw): acties over de hele werkset vanaf de collectiepagina, zoals AI-suggesties voor alle gekozen bestanden, Selectie opslaan voor alle bestanden of één keuzemenu voor de upload van de hele werkset (9.1).
17.7 Bewaren¶
- Per gebruiker (besluit Olaf, 5-11-2026): op Toolforge heeft elke ingelogde gebruiker een eigen dashboard met eigen collecties. Die staan in de eigen map van de gebruiker (8.5):
uitvoer/gebruikers/<id>/collecties/<collectie-id>.json, met<id>de vaste gebruikers-id uit OAuth. Twee gebruikers die dezelfde categorie openen, hebben elk een eigen collectie, met eigen vinkjes en een eigen status. Wat gedeeld blijft (8.5): de miniaturen en de Commons-gegevens in de cache, en de antwoorden van SAM. Een voorscan die een ander al deed, kost dus niets, maar de keuzes die daaruit volgen staan bij jezelf. - De API kent geen gebruiker in het pad. De server haalt de gebruiker uit de sessie, en een collectie van een ander geeft 404, ook als je het id kent.
- Zonder inloggen werkt het dashboard voor de browsersessie en verdwijnt het na 1 dag (8.5). Lokaal, zonder OAuth, valt alles onder de gebruiker
lokaal. - Tot OAuth er is (backlog 13 en 13a), bouwen we het al zo: alle opslag gaat via één functie die de map van de huidige gebruiker geeft (nu altijd
lokaal). Dan hoeft er bij OAuth niets te verhuizen of te veranderen. - Een collectie bevat: naam, bron, zoektermen voor de voorscan, aangemaakt, laatst geopend, en per bestand de M-id, titel, SHA-1, afmetingen, MIME, aantal pagina's, keuze (met door wie: gebruiker of AI), de samenvatting van de voorscan (per term het aantal objecten en de hoogste score) en de status.
- De kaders op de miniaturen komen uit de detectiecache, niet uit de collectie; de collectie blijft dus klein.
- Het id is kort en willekeurig (bijv.
c-7f3a9b), niet de naam van de categorie: twee collecties uit dezelfde categorie mogen. - Bewaartermijn (12.1): een collectie die een jaar niet geopend is, ruimt
opruimenop, net als een pagina. - Schrijven onder het slot (
cutter/slot.py) en atomisch, zoals de objecten.
17.8 Pagina's en REST-API (voorstel)¶
Pagina's:
| Pad | Wat |
|---|---|
/ |
Het dashboard (de collecties). Met ?url=, ?titel= of ?mid= stuurt het door naar /bewerken?…, zodat bestaande links blijven werken (besluit Olaf) |
/bewerken |
De bewerker zoals nu (10.4); met ?collectie= de werksetbalk |
/collecties/<id> |
Het raster van één collectie |
API onder /api/v1, volgens de afspraken (zelfstandige naamwoorden, meervoud, een GET kost niets):
| Methode | Pad | Wat |
|---|---|---|
| GET | /categorie?titel=… |
Normaliseren en voorproefje: titel, aantal bestanden en subcategorieën, de subcategorieën. Gratis |
| GET, POST | /collecties |
Alle collecties; een nieuwe aanmaken ({"bron": {"categorie": "…"}, "naam": "…"}). 201 |
| GET, PATCH, DELETE | /collecties/{id} |
Eén collectie; naam en zoektermen wijzigen; verwijderen |
| POST | /collecties/{id}/verversingen |
Opnieuw ophalen uit Commons (gratis; maakt een nieuwe stand, vandaar POST). 201 |
| GET, PATCH | /collecties/{id}/bestanden |
De bestanden, met filters (keuze, status, voorscan, bewerkt: nee, door_jou, op_commons); per bestand ook wat er al mee gedaan is (17.4, Al bewerkt); keuze en status van een of meer bestanden wijzigen |
| GET | /bestand/{mid}/bewerkingen |
Wat er met dit bestand al gebeurd is: door jou in de app, en op Commons (met de Mineventory, met ander gereedschap, regio's). Gratis, gecachet |
| GET | /bestand/{mid}/miniatuur?w= |
De miniatuur, via de server en gecachet (17.3) |
| GET | /collecties/{id}/voorscans/raming |
Later (17.5): kostenraming voor de voorscan; voert niets uit |
| POST | /collecties/{id}/bestanden/{mid}/voorscans |
Later (17.5): de voorscan van één bestand (SAM, betaald, binnen de limieten). 201. De browser roept dit bestand voor bestand aan, met Stoppen |
docs/api.md en cutter/openapi.py worden bijgewerkt bij de bouw.
17.9 Eerste bouw¶
Klein en zonder kosten, in deze volgorde, elk met tests:
- Commons: categorie normaliseren, voorproefje, bestanden ophalen per blok, miniaturen via de server (fixtures voor de tests).
- Collecties: opslag in de map van de huidige gebruiker (nu
lokaal, 17.7), de API uit 17.8 zonder voorscan,opruimen. Een test controleert dat twee gebruikers elkaars collecties niet zien. - Dashboard en collectiepagina (Vue en Codex, tweetalig): kaarten, raster, vinkjes, filters, lightbox, Werkset openen, en de merkjes Al bewerkt (eerst door jou, daarna op Commons; het centrale register komt met de upload, 14).
- Bewerker naar
/bewerken, met de werksetbalk en de werkset in Bekeken. - Voorscan: uitgesteld (17.5, besluit Olaf). De eerste bouw kost dus niets.
Daarna itereren op aanwijzing van Olaf. De voorscan (17.5) en acties over de hele werkset (17.6, Later) komen in een volgende ronde.
17.10 Besluiten van Olaf (5-11-2026)¶
- Startpagina: het dashboard op
/, de bewerker naar/bewerken; oude links (/?url=…,/?mid=…) sturen door. - Voorscan: voorlopig geen voorscan door AI: "bij grotere categorieën van bv. 2000 beelden kost dat al snel 5 USD, dan doe ik het liever handmatig". De vragen SAM of ook Muse Spark, en automatisch aanvinken of alleen tonen, komen terug als de voorscan terugkomt (17.5, backlog 19a). Daarmee vervalt ook de vraag naar de limieten voor de voorscan.
- Subcategorieën: standaard alleen de categorie zelf, subcategorieën (één niveau) met een klik erbij; hooguit 1000 bestanden per collectie.
- Meerpaginabestanden: één tegel per bestand (een latere voorscan alleen op pagina 1).
- Miniaturen: 4 tegelijk van
upload.wikimedia.org;api.phpblijft op één verzoek per seconde. - Status klaar: alleen met de hand.
- Fasering: nu bouwen, vóór OAuth, lokaal onder de gebruiker
lokaal(13, fase 1 punt 6a). Backlog 15a wordt daarmee het eerstvolgende punt. - Al bewerkt: alleen waarschuwen, met een merkje en een melding; nooit tegenhouden.
- Werk van anderen in de app: onzichtbaar tot het op Commons staat.
18. Canvas: een speelveld voor uitsneden (nice-to-have)¶
Idee van Olaf (6-11-2026). Nice-to-have, nog niet gepland en nog niet gebouwd (backlog 25). Olafs antwoorden op het vragenformulier staan in 18.12.
18.1 Doel¶
Uit één boek, vriendenboek, atlas, tijdschrift of handschrift (één Commons-categorie) ontstaan veel losse transparante uitsneden, al dan niet aangevuld met AI (7.7). Het canvas is een speelveld om daarmee te spelen: objecten erop slepen, verschuiven, schalen, draaien, combineren en groeperen tot nieuwe samengestelde werken, ook met uitsneden uit andere werken en met transparante beelden van anderen op Commons.
Zo'n werk heeft geen documentaire of encyclopedische waarde. Het gaat daarom nooit naar Commons: je bewaart het om verder te werken, en je exporteert het als beeld, met de bronnen en licenties erbij.
18.2 Bronnen¶
Links op het scherm staan de objecten die je kunt gebruiken, als miniaturen om naar het canvas te slepen:
- Al je eigen uitsneden, uit alle bestanden, te filteren per collectie of categorie (17), per bestand en op naam. Van elke uitsnede het origineel en, als die er is, de AI-aangevulde versie (7.7). Alleen objecten met een vorm (transparante PNG) of een rechthoek.
- Wikimedia Commons:
- standaard de categorie Category:Transparent background (wens Olaf), met subcategorieën op aanvraag;
- zelf categorieën toevoegen (bijv. de categorie van een ander boek of van uploads met de Commons Mineventory); de app onthoudt ze per gebruiker;
- zoeken op Commons, beperkt tot bestanden die transparantie kunnen hebben (PNG, WebP, SVG, GIF). Alles via de server (privacy, 12.3), met de gewone regels voor Commons: eigen User-Agent, caching, ongeveer één verzoek per seconde.
- Eigen afbeelding uploaden vanaf je computer (PNG, WebP of SVG met transparantie, ook JPG). Zo'n bestand blijft privé, in je eigen map (8.5), en gaat niet naar Commons.
- Openverse (beelden met een vrije licentie, open API) als dienst buiten Commons, als die er later bij komt; niet in de eerste versie (zie 18.12, vraag 1 en 2).
18.3 Het scherm¶
Een eigen pagina /canvas, te openen vanaf het dashboard (17) en vanaf een collectie; elk canvas heeft een eigen adres (/canvas/<id>).
┌ Commons Mineventory · Canvas: "Vriendenboek-collage" ────────── Opslaan Exporteren ▾ ┐
│ ┌ Objecten ──────────────┐ ┌──────────────────────────────────┐ ┌ Lagen ───────────┐ │
│ │ Bron: [Mijn uitsneden ▾]│ │ │ │ 👁 🔒 tekst │ │
│ │ 🔍 zoeken │ │ 🐈 (AI) 🌸 │ │ 👁 🔒 groep: 🍋×3 │ │
│ │ ┌──┐┌──┐┌──┐┌──┐ │ │ 👦📦 ← geselecteerd │ │ 👁 🔒 jongen ● │ │
│ │ │🐈││👦││🌸││🍋│ │ │ 🍋🍋🍋 │ │ 👁 🔒 kat (AI) │ │
│ │ └──┘└──┘└──┘└──┘ │ │ 🦅 │ │ 👁 🔒 achtergrond │ │
│ │ ── Commons ── │ │ │ ├ Eigenschappen ───┤ │
│ │ Transparent background │ └──────────────────────────────────┘ │ (●) origineel │ │
│ │ + categorie toevoegen │ A4 staand · 100% · raster aan │ ( ) AI-aangevuld │ │
│ │ ── Eigen bestand ── │ │ schaal, draai, │ │
│ │ [ Uploaden ] │ │ dekking, bron ↗ │ │
│ └────────────────────────┘ └──────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────────┘
- Links: de bronnen (18.2). Slepen naar het canvas plaatst het object op ware grootte, of passend als het groter is dan het canvas.
- Midden: het canvas, met zoom en verschuiven zoals in de viewer (muiswiel, slepen met de spatiebalk), een raster en uitlijnhulp.
- Rechts boven: het lagenpaneel, zoals in Photoshop (wens Olaf): elk object is een eigen laag, de bovenste ligt vooraan. Per laag: zichtbaar (oog), vergrendeld (slot), naam, en slepen om de volgorde te veranderen. Een groep is een laag die je openklapt.
- Rechts onder: de eigenschappen van de geselecteerde laag (18.5).
- Tweetalig en in Codex-stijl, zoals de rest van de app.
18.4 Bewerkingen¶
| Bewerking | Hoe |
|---|---|
| Verplaatsen, schalen, draaien | Slepen; hoekgrepen (Shift houdt de verhouding); draaigreep; of getallen in de eigenschappen |
| Spiegelen | Horizontaal of verticaal, knop of toets |
| Voor en achter | In het lagenpaneel slepen, of Naar voren, Naar achteren, Helemaal voor, Helemaal achter |
| Kopiëren en plakken | Ctrl+C en Ctrl+V dupliceren de laag (ook een groep), iets verschoven |
| Groeperen | Ctrl+G groepeert de geselecteerde lagen, Ctrl+Shift+G heft de groep op; een groep verplaats, schaal en draai je als geheel |
| Ongedaan maken | Ctrl+Z en Ctrl+Y (of Ctrl+Shift+Z), voor elke bewerking |
| Doorzichtigheid | Per laag, 0 tot 100% |
| Achtergrond | Doorzichtig, een kleur, of een afbeelding (uit dezelfde bronnen) als onderste laag |
| Tekst | Een tekstlaag met lettertype (alleen meegeleverde lettertypen, geen externe), grootte, kleur |
| Uitlijnhulp | Een raster en hulplijnen die opspringen bij randen en middens van andere lagen |
| Verwijderen | Del of Backspace; ongedaan te maken |
Meer selecteren met Shift-klik of een rechthoek trekken. Met de pijltjes schuif je een laag een pixel, met Shift tien.
18.5 Origineel of AI-aangevuld¶
- Elke laag die uit een eigen uitsnede komt, heeft in de eigenschappen een schakelaar origineel / AI-aangevuld (wens Olaf). Standaard het origineel; AI-aangevuld kan alleen als die versie er is (7.7).
- Een AI-aangevulde laag heeft in het lagenpaneel het AI-merkje, zodat altijd te zien is wat verzonnen is.
- Vanuit de eigenschappen kun je een uitsnede zonder aangevulde versie meteen laten aanvullen (Afbeelding aanvullen met AI, met het bedrag en een bevestiging, zoals in de vergroter).
18.6 Bewaren¶
- Meerdere canvassen per gebruiker op de server (besluit Olaf), in de eigen map (8.5):
uitvoer/gebruikers/<id>/canvassen/<canvas-id>.json, met een lijst op het dashboard (naam, miniatuur, laatst bewerkt). - Een canvas bewaart verwijzingen, geen kopieën: per laag de bron (eigen uitsnede met M-id, pagina en object-id; een Commons-bestand; een eigen upload), de versie (origineel of AI-aangevuld), positie, schaal, draaiing, spiegeling, dekking, zichtbaarheid en volgorde. Eigen uploads staan in
uitvoer/gebruikers/<id>/canvas-bestanden/. - Automatisch opslaan na elke bewerking (na een korte pauze), plus Opslaan als om een kopie te maken.
- Verdwijnt een bron (uitsnede in de prullenbak, verlopen bewaartermijn, verwijderd van Commons), dan blijft de laag staan met een merkje en de laatst bekende miniatuur, en kun je hem vervangen.
- Bewaartermijn: een canvas dat een jaar niet geopend is, ruimt
opruimenop (12.1). De uitsneden die een canvas gebruikt, tellen als gebruikt, zodat ze niet verlopen zolang het canvas leeft.
18.7 Exporteren¶
- PNG (ook met doorzichtige achtergrond), JPG, PDF (bijvoorbeeld om te printen), SVG (met een eigen groep per laag) en een projectbestand (JSON met de verwijzingen, om te delen of later weer te openen).
- Resolutie: in het formaat van het canvas (18.8), met de lagen in de beste beschikbare resolutie: uitsneden in volledige resolutie van het origineel, AI-aangevulde versies in hun eigen (lagere) resolutie.
- Bronvermelding (besluit Olaf): bij elke export automatisch een lijst met de gebruikte bronnen en hun licenties, als bijlage (een tekstbestand naast het beeld, of een pagina in de PDF) en onder het beeld (een smalle strook, uit te zetten). Per bron: titel, maker, licentie en link naar Commons; bij een AI-aangevulde versie aangevuld met AI (Muse Image); bij een eigen upload eigen bestand. Een waarschuwing als een licentie gelijk delen vraagt (CC BY-SA), of als een bron geen vrije licentie heeft.
- Niet naar Commons: er is geen uploadknop. Delen gaat via de export of het projectbestand (besluit Olaf).
- De export wordt op de server gemaakt (de originelen staan daar), als downloadbestand.
18.8 Formaat¶
Een gekozen formaat bij het aanmaken, later te wijzigen (besluit Olaf): A4 en A3 (staand of liggend), vierkant, 16:9, of een eigen maat in pixels. Voor A4 en A3 een resolutie in dpi (standaard 300) voor het printen.
18.9 AI op het canvas (betaalde extra)¶
Besluit Olaf: mag, als betaalde extra met Muse Image (7.7), met het bedrag op de knop en eerst een bevestiging. Voorbeelden, uit te werken bij de bouw:
- een achtergrond laten maken bij een omschrijving (bijv. a 17th-century landscape), als onderste laag;
- het geheel in één stijl laten samenvloeien (licht, schaduw, kleur), als nieuwe laag of nieuw canvas, met het origineel bewaard.
Wat de AI maakt, krijgt het AI-merkje en staat in de bronvermelding als gemaakt met AI.
18.10 Techniek (bij de bouw kiezen)¶
- Een canvasbibliotheek via npm (bijv. Konva of Fabric.js), meegebouwd door Vite; geen CDN (12.3). De viewer uit de Delpher Uitsnijder blijft zoals hij is; het canvas is een eigen onderdeel.
- Beelden van Commons komen via de server (een proxy met cache), net als de miniaturen in 17.3, zodat de browser niets van Wikimedia laadt en het canvas geen CORS-problemen heeft bij de export.
- Grote originelen: op het canvas een verkleinde versie (bijv. hooguit 2000 px), bij de export de volledige resolutie.
18.11 Pagina's en REST-API (voorstel)¶
| Methode | Pad | Wat |
|---|---|---|
| GET | /canvas, /canvas/<id> |
Pagina's: de lijst en één canvas |
| GET, POST | /api/v1/canvassen |
Je canvassen; een nieuw aanmaken (naam, formaat). 201 |
| GET, PUT, DELETE | /api/v1/canvassen/{id} |
Eén canvas (lagen en instellingen); bewaren; verwijderen |
| GET | /api/v1/canvas-bronnen?soort=uitsneden\|commons\|eigen&zoek=…&categorie=… |
Wat links staat: eigen uitsneden, Commons (categorieën en zoeken), eigen uploads. Gratis |
| POST | /api/v1/canvas-bestanden |
Een eigen afbeelding uploaden (privé). 201 |
| POST | /api/v1/canvassen/{id}/exports |
Een export maken ({"formaat": "png" \| "jpg" \| "pdf" \| "svg" \| "json"}), met de bronvermelding. 201 met een downloadlink |
18.12 Antwoorden van Olaf (6-11-2026)¶
- Bronnen: al je eigen uitsneden uit alle bestanden; zoeken op Wikimedia Commons; een eigen afbeelding uploaden. Andere zoekdiensten koos Olaf hier niet.
- Buiten Commons: als het er komt, dan Openverse (alleen vrije licenties, open API). Omdat Olaf bij vraag 1 geen andere zoekdiensten koos: niet in de eerste versie.
- Bronvermelding: automatisch, als bijlage en onder het beeld.
- Bewerkingen: alles uit 18.4: verplaatsen, schalen, draaien, spiegelen, voor en achter, kopiëren en plakken, groeperen, ongedaan maken, doorzichtigheid, achtergrond, tekst, uitlijnhulp en raster.
- Standaardversie: het origineel, AI-aangevuld met de schakelaar.
- Bewaren: meerdere canvassen per gebruiker op de server.
- Export: PNG (ook doorzichtig), JPG, PDF, SVG en een projectbestand.
- Formaat: een gekozen formaat.
- Plek: een eigen pagina
/canvas, vanaf het dashboard en een collectie. - AI: ja, als betaalde extra met Muse Image, met bedrag en bevestiging.
- Delen: alleen via export of projectbestand.
- Extra (opmerking Olaf): Category:Transparent background als vaste bron; zelf andere Commons-categorieën toevoegen; werken in lagen zoals in Photoshop, met een eigen laag per object (PNG en andere formaten met transparantie).
Nog open (later, bij het oppakken): de naam van de functie (Canvas, Speelveld, Collage?), welke AI-extra's eerst (18.9), en of een canvas ook objecten uit de collecties van andere gebruikers mag gebruiken zodra die op Commons staan.
Afhankelijk van: werk per gebruiker (8.5) voor het bewaren, het dashboard (17) als ingang, de AI-aangevulde versie (7.7).