diff --git a/deploy/wpp.env.example b/deploy/wpp.env.example index f1f390c..282a87a 100644 --- a/deploy/wpp.env.example +++ b/deploy/wpp.env.example @@ -14,3 +14,6 @@ ELEVENLABS_API_KEY= # BRAIN_API_KEY= # BRAIN_WORKSPACE= # kun ved Anthropic-brugernøgler (sk-ant-usr…) # BRAIN_EFFORT=low + +# Navn på knappen for arbejdspakken (kategorier med pakken "arbejde") på "nyt spil"-siden +# WORK_PACK_LABEL=Arbejde diff --git a/fupogfakta/admin.py b/fupogfakta/admin.py index 88864b1..c1896f2 100644 --- a/fupogfakta/admin.py +++ b/fupogfakta/admin.py @@ -5,7 +5,7 @@ from .models import Category, Question @admin.register(Category) class CategoryAdmin(admin.ModelAdmin): - list_display = ["name", "active", "question_count"] + list_display = ["name", "packs", "active", "question_count"] list_editable = ["active"] @admin.display(description="spørgsmål") diff --git a/fupogfakta/data/questions_c_nord.json b/fupogfakta/data/questions_c_nord.json new file mode 100644 index 0000000..c8d8fbb --- /dev/null +++ b/fupogfakta/data/questions_c_nord.json @@ -0,0 +1,1939 @@ +[ + { + "category": "Star Wars", + "prompt": "I tv-showet Star Wars Holiday Special fra 1978 hedder Chewbaccas søn _____.", + "answer": "Lumpy", + "alternatives": [ + "lumpawaroo", + "lumpawarrump", + "lumpy" + ], + "decoys": [ + "Chewie junior", + "Bumpy", + "Wookie", + "Rumpy" + ], + "note": "Showet viste Chewbaccas familie på Kashyyyk: faren Itchy, konen Malla og sønnen Lumpy. Det blev så udskældt, at det aldrig er blevet genudsendt.", + "source": "https://en.wikipedia.org/wiki/Star_Wars_Holiday_Special", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "Boba Fett blev vist første gang i en _____ i Star Wars Holiday Special fra 1978.", + "answer": "tegnefilm", + "alternatives": [ + "animationsfilm", + "animeret film", + "tegnefilm", + "tegnefilmen", + "tegnefilmsindslag", + "tegneserie", + "tegnet film" + ], + "decoys": [ + "dukkefilm", + "musikvideo", + "reklamefilm", + "drømmescene" + ], + "note": "Før Imperiet slår igen dukkede han op i et tegnet indslag, lavet af det canadiske studie Nelvana.", + "source": "https://starwars.fandom.com/wiki/Boba_Fett/Legends", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "TIE-jagernes hvinende lyd blev lavet af et _____ blandet med en bil, der kører på våd asfalt.", + "answer": "elefantbrøl", + "alternatives": [ + "brøl fra en elefant", + "elefant", + "elefantbrøl", + "elefantkald", + "elefantlyd", + "elefantskrig", + "elefanttrut" + ], + "decoys": [ + "ulvehyl", + "ørneskrig", + "hvalsang", + "abeskrig" + ], + "note": "Lyddesigneren Ben Burtt blandede en elefants kald med lyden af en bil på våd vej. Han skabte også lyssværdenes summen.", + "source": "https://starwars.fandom.com/wiki/TIE/ln_space_superiority_starfighter", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "Før Imperiet slår igen overvejede holdet at lade Yoda spille af en _____ i kostume.", + "answer": "abe", + "alternatives": [ + "abe", + "aber", + "chimpanse", + "chimpansen", + "en abe" + ], + "decoys": [ + "hund", + "pingvin", + "kat", + "papegøje" + ], + "note": "Man overvejede også stop motion, før Yoda endte som en dukke styret af Frank Oz.", + "source": "https://en.wikipedia.org/wiki/Yoda", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "Navnet R2-D2 opstod, da en lydmand bad om \"Reel 2, _____ 2\".", + "answer": "Dialog", + "alternatives": [ + "dialog", + "dialog track", + "dialogspor", + "dialogue", + "dialogue track" + ], + "decoys": [ + "Disk", + "Drum", + "Deck", + "Door" + ], + "note": "Lydmanden Walter Murch bad om spole 2, dialogspor 2, forkortet R2 D2. George Lucas hørte det og syntes, det var et fantastisk navn.", + "source": "https://en.wikipedia.org/wiki/R2-D2", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "Sproget Huttese, som Jabba the Hutt taler, er bygget over inkaernes sprog _____.", + "answer": "quechua", + "alternatives": [ + "kechua", + "ketchua", + "kichwa", + "quechua", + "quechuan" + ], + "decoys": [ + "aymara", + "nahuatl", + "guarani", + "mapudungun" + ], + "note": "Lyddesigneren Ben Burtt faldt for sprogets sjove gentagelser og musikalitet. Sammen med en lingvist lavede han falske quechua-ord.", + "source": "https://starwars.fandom.com/wiki/Huttese", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Legends-romanen Vector Prime fra 1999 dør Chewbacca, da en hel _____ styrter ned over ham.", + "answer": "måne", + "alternatives": [ + "en måne", + "måne", + "månen" + ], + "decoys": [ + "rumstation", + "stjernedestroyer", + "komet", + "asteroide" + ], + "note": "Han blev på planeten Sernpidal for at redde Han og Leias søn Anakin. Wookieerne var stolte over, at der skulle en hel måne til at fælde ham.", + "source": "https://starwars.fandom.com/wiki/Chewbacca/Legends", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Timothy Zahns Legends-bøger lærer storadmiral Thrawn sine fjender at kende ved at studere deres _____.", + "answer": "kunst", + "alternatives": [ + "art", + "kunst", + "kunsten", + "kunstværk", + "kunstværker", + "malerier" + ], + "decoys": [ + "affald", + "sport", + "madopskrifter", + "gravsteder" + ], + "note": "Thrawn mener, at et folks kunst afslører, hvordan de tænker og kæmper. Han debuterede i bogen Heir to the Empire fra 1991.", + "source": "https://starwars.fandom.com/wiki/Mitth%27raw%27nuruodo/Legends", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Legends-bøgerne var Lukes kone Mara Jade engang Palpatines hemmelige agent med titlen kejserens _____.", + "answer": "hånd", + "alternatives": [ + "emperor's hand", + "hand", + "hånd", + "højre hånd" + ], + "decoys": [ + "skygge", + "dolk", + "øje", + "stemme" + ], + "note": "Som Emperor's Hand udførte hun kejserens ordrer i det skjulte. Senere blev hun Jedimester og gift med Luke Skywalker.", + "source": "https://starwars.fandom.com/wiki/Mara_Jade_Skywalker", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Legends-tegneserien Dark Empire fra 1991 bliver _____ den genopståede kejser Palpatines lærling.", + "answer": "Luke Skywalker", + "alternatives": [ + "lord skywalker", + "luke", + "luke skywalker", + "skywalker" + ], + "decoys": [ + "Han Solo", + "Lando Calrissian", + "prinsesse Leia", + "Boba Fett" + ], + "note": "Palpatine vender tilbage i en klonkrop, og Luke går over til den mørke side for at bekæmpe ham indefra. Leia hjælper ham tilbage til lyset.", + "source": "https://starwars.fandom.com/wiki/Luke_Skywalker/Legends", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Legends-bøgerne bliver Han og Leias søn Jacen Solo til Sith-herren Darth _____.", + "answer": "Caedus", + "alternatives": [ + "caedus", + "cædus", + "kædus" + ], + "decoys": [ + "Corvus", + "Vindex", + "Solus", + "Obscura" + ], + "note": "Det sker i bogserien Legacy of the Force, hvor han til sidst bliver stoppet af sin egen tvillingesøster Jaina.", + "source": "https://starwars.fandom.com/wiki/Jacen_Solo", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Thrawn-bøgerne fra Legends kan et lille træboende _____ kaldet ysalamir blokere for Kraften.", + "answer": "firben", + "alternatives": [ + "firben", + "firbenet", + "krybdyr", + "padde", + "salamander", + "øgle" + ], + "decoys": [ + "egern", + "flagermus", + "insekt", + "snegl" + ], + "note": "Thrawn bruger dem som skjold mod Jedier. Evnen udviklede sig, fordi de blev jaget af rovdyr, der kunne bruge Kraften.", + "source": "https://starwars.fandom.com/wiki/Ysalamir", + "packs": [ + "nørd" + ] + }, + { + "category": "Star Wars", + "prompt": "I Legends-spillet Knights of the Old Republic opdager spilleren, at man selv er Sith-herren Darth _____.", + "answer": "Revan", + "alternatives": [ + "revan" + ], + "decoys": [ + "Malak", + "Bane", + "Nihilus", + "Plagueis" + ], + "note": "Jedirådet havde slettet hans hukommelse og givet ham en ny identitet. Afsløringen kommer midt i spillet fra 2003.", + "source": "https://en.wikipedia.org/wiki/Star_Wars:_Knights_of_the_Old_Republic_(video_game)", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "I J.K. Rowlings tidlige udkast hed Hermione til efternavn _____.", + "answer": "Puckle", + "alternatives": [ + "puckle" + ], + "decoys": [ + "Wimple", + "Huxley", + "Bristow", + "Pennyfeather" + ], + "note": "Rowling syntes ikke, at Puckle passede til hende, og skiftede til Granger.", + "source": "https://harrypotter.fandom.com/wiki/Hermione_Granger", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "J.K. Rowling fandt på quidditch på et hotelværelse i Manchester efter et _____ med sin kæreste.", + "answer": "skænderi", + "alternatives": [ + "diskussion", + "skænderi", + "skænderier", + "skænderiet", + "strid", + "uenighed" + ], + "decoys": [ + "frieri", + "stævnemøde", + "biografbesøg", + "maraton" + ], + "note": "Rowling vidste, at troldmandsverdenen manglede en sport, der kunne samle folk. Det har hun selv fortalt i 2013.", + "source": "https://www.telegraph.co.uk/culture/books/10065868/JK-Rowling-invented-Quidditch-after-a-row-with-her-boyfriend.html", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Hogwarts' latinske motto betyder: Kild aldrig en sovende _____.", + "answer": "drage", + "alternatives": [ + "drage", + "dragen" + ], + "decoys": [ + "trold", + "kæmpe", + "hippogrif", + "troldmand" + ], + "note": "På latin lyder det Draco dormiens nunquam titillandus. Et ret fornuftigt råd.", + "source": "https://harrypotter.fandom.com/wiki/Hogwarts_School_of_Witchcraft_and_Wizardry", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Navnet Dumbledore er et gammelt engelsk ord for en _____.", + "answer": "humlebi", + "alternatives": [ + "bi", + "bumblebee", + "humlebi", + "humlebien" + ], + "decoys": [ + "grævling", + "ugle", + "sommerfugl", + "pindsvin" + ], + "note": "Rowling forestillede sig rektoren gå rundt på slottet og nynne for sig selv, ligesom en humlebi.", + "source": "https://harrypotter.fandom.com/wiki/Albus_Dumbledore", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Hunuglen Hedvig blev i filmene spillet af _____.", + "answer": "hanugler", + "alternatives": [ + "han ugler", + "han-ugler", + "hanner", + "hanugle", + "hanugler", + "sneuglehanner" + ], + "decoys": [ + "udstoppede ugler", + "malede duer", + "computeranimation", + "hvide høge" + ], + "note": "Sneuglehanner er hvidere og mindre end hunnerne og derfor lettere for unge skuespillere at holde.", + "source": "https://www.lauraerickson.com/page/owls-of-harry-potter/", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Tvillingerne Fred og George Weasley har fødselsdag den _____.", + "answer": "1. april", + "alternatives": [ + "1 april", + "1. april", + "1/4", + "aprilsnar", + "første april" + ], + "decoys": [ + "13. juni", + "24. december", + "29. februar", + "31. oktober" + ], + "note": "Passende for to spøgefugle er de født på aprilsnar. Det har Rowling selv fortalt.", + "source": "https://harrypotter.fandom.com/wiki/Fred_Weasley", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Forlaget Bloomsbury sagde ja til Harry Potter, efter at direktørens otteårige _____ var vild med de første kapitler.", + "answer": "datter", + "alternatives": [ + "datter", + "datteren", + "pige" + ], + "decoys": [ + "søn", + "nabo", + "barnebarn", + "nevø" + ], + "note": "Alice Newton kom ned fra sit værelse og sagde til sin far, at bogen var meget bedre end alt andet.", + "source": "https://www.nzherald.co.nz/lifestyle/revealed-the-eight-year-old-girl-who-saved-harry-potter/UTQCYL6RAEUSL4V5JH7MMP3WTE/", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "I den danske oversættelse hedder den unge Voldemort Romeo G. _____ Jr.", + "answer": "Detlev", + "alternatives": [ + "detlev" + ], + "decoys": [ + "Mortensen", + "Valdemar", + "Lodberg", + "Godtfred" + ], + "note": "Navnet er et anagram, for bogstaverne kan byttes om til Jeg er Voldemort. På engelsk hedder han Tom Marvolo Riddle.", + "source": "https://harrypotter.fandom.com/wiki/Tom_Riddle", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Ifølge bogen Quidditch gennem tiderne findes der _____ kendte regelbrud i quidditch.", + "answer": "700", + "alternatives": [ + "700", + "syv hundrede", + "syvhundrede" + ], + "decoys": [ + "42", + "150", + "365", + "1.300" + ], + "note": "Alle sammen blev begået i én og samme VM-finale i 1473 mellem Flandern og Transsylvanien.", + "source": "https://harrypotter.fandom.com/wiki/Quidditch_World_Cup", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "I mange år planlagde J.K. Rowling, at det allersidste ord i Harry Potter-serien skulle være _____.", + "answer": "ar", + "alternatives": [ + "ar", + "arret", + "lynar", + "lynaret", + "scar" + ], + "decoys": [ + "Hogwarts", + "magi", + "farvel", + "Voldemort" + ], + "note": "Til sidst ville hun slutte helt klart og tydeligt. Derfor ender bogen på engelsk med ordene All was well.", + "source": "https://www.abc.net.au/news/2007-07-06/rowling-reveals-tears-shed-over-potter/92208", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "Hermiones patronus er en _____, fordi det er J.K. Rowlings yndlingsdyr.", + "answer": "odder", + "alternatives": [ + "en odder", + "odder", + "odderen" + ], + "decoys": [ + "kat", + "ræv", + "pindsvin", + "egern" + ], + "note": "Rowling har fortalt, at odderen er hendes yndlingsdyr. Derfor fik Hermione den som patronus.", + "source": "https://harrypotter.fandom.com/wiki/Otter", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "I filmen De Vises Sten står der omkring _____ tryllestavsæsker på hylderne i Ollivanders butik.", + "answer": "17.000", + "alternatives": [ + "17 000", + "17.000", + "17000", + "sytten tusind", + "syttentusind" + ], + "decoys": [ + "4.000", + "9.500", + "30.000", + "1.200" + ], + "note": "Ifølge Warner Bros. Studio Tour blev hver eneste æske mærket med sit eget nummer og runer.", + "source": "https://harrypotter.fandom.com/wiki/Ollivanders", + "packs": [ + "nørd" + ] + }, + { + "category": "Harry Potter", + "prompt": "J.K. Rowling har intet mellemnavn. K'et valgte hun efter sin _____ Kathleen.", + "answer": "farmor", + "alternatives": [ + "bedstemor", + "bedstemoren", + "farmor", + "farmoren" + ], + "decoys": [ + "kat", + "moster", + "faster", + "gudmor" + ], + "note": "Forlaget ville have forbogstaver på omslaget, så hun lånte et K fra sin farmor Kathleen Rowling.", + "source": "https://en.wikipedia.org/wiki/J._K._Rowling", + "packs": [ + "nørd" + ] + }, + { + "category": "E-faktura", + "prompt": "Før e-fakturaen blev et krav i 2005, modtog det offentlige Danmark omkring _____ papirregninger om året.", + "answer": "18 millioner", + "alternatives": [ + "18 millioner", + "18 mio", + "18 mio.", + "18.000.000", + "18000000", + "atten millioner" + ], + "decoys": [ + "3 millioner", + "45 millioner", + "120 millioner", + "750.000" + ], + "note": "Det oplyste staten, lige før e-faktura til det offentlige blev obligatorisk den 1. februar 2005. Danmark var et af de første lande i verden med sådan et krav.", + "source": "https://www.budregn.im.dk/media/14278/elektronisk-fakturering.pdf", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Navnet Peppol er en forkortelse for Pan-European Public _____ OnLine.", + "answer": "procurement", + "alternatives": [ + "indkøb", + "offentlige indkøb", + "procurement", + "udbud" + ], + "decoys": [ + "Payment", + "Post", + "Paperwork", + "Partnership" + ], + "note": "Procurement betyder indkøb. Peppol startede i 2008 som et EU-projekt om offentlige indkøb, men bruges i dag også mellem private firmaer over hele verden.", + "source": "https://en.wikipedia.org/wiki/PEPPOL", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Peppol-netværket bygger på den såkaldte _____-hjørnemodel.", + "answer": "fire", + "alternatives": [ + "4", + "fire" + ], + "decoys": [ + "tre", + "fem", + "seks", + "otte" + ], + "note": "De fire hjørner er afsender, afsenderens udbyder, modtagerens udbyder og modtager. Før Peppol skulle begge parter ofte bruge samme udbyder, det kaldes en trehjørnemodel.", + "source": "https://peppol.org/about/", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Foreningen OpenPeppol, der styrer det internationale e-faktura-netværk Peppol, er registreret i _____.", + "answer": "Belgien", + "alternatives": [ + "belgien", + "brussels", + "bruxelles", + "bryssel" + ], + "decoys": [ + "Holland", + "Luxembourg", + "Schweiz", + "Danmark" + ], + "note": "OpenPeppol blev stiftet den 1. september 2012 som en nonprofit-forening efter belgisk lov og har adresse i Bruxelles.", + "source": "https://peppol.org/about/", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Det første land uden for Europa, der i 2018 fik sin egen Peppol-myndighed, var _____.", + "answer": "Singapore", + "alternatives": [ + "singapore" + ], + "decoys": [ + "Canada", + "Japan", + "Australien", + "Sydafrika" + ], + "note": "Singapores myndighed IMDA blev Peppol-myndighed i maj 2018, og landet åbnede sit landsdækkende e-faktura-netværk i 2019. Japan fulgte efter i 2021.", + "source": "https://en.wikipedia.org/wiki/PEPPOL", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Siden 2019 skal stort set alle fakturaer mellem italienske virksomheder sendes gennem _____.", + "answer": "skattevæsenet", + "alternatives": [ + "agenzia delle entrate", + "skat", + "skattemyndigheden", + "skattemyndighederne", + "skattevæsen", + "skattevæsenet", + "skattevæsnet" + ], + "decoys": [ + "nationalbanken", + "postvæsenet", + "handelskammeret", + "politiet" + ], + "note": "Italien var det første EU-land med obligatorisk e-faktura mellem virksomheder. Alle fakturaer passerer skattevæsenets system, der hedder Sistema di Interscambio.", + "source": "https://ec.europa.eu/digital-building-blocks/sites/spaces/einvoicingCFS/pages/718735703/2024+Italy+2024+eInvoicing+Country+Sheet", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Med EU's momsreform ViDA bliver e-faktura obligatorisk ved handel mellem firmaer i forskellige EU-lande fra _____.", + "answer": "2030", + "alternatives": [ + "1. juli 2030", + "2030", + "juli 2030" + ], + "decoys": [ + "2026", + "2027", + "2028", + "2033" + ], + "note": "ViDA står for VAT in the Digital Age og blev vedtaget i marts 2025. Kravet om e-faktura ved handel på tværs af EU-grænser gælder fra 1. juli 2030.", + "source": "https://taxation-customs.ec.europa.eu/taxation/vat/vat-digital-age-vida_en", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "EAN-nummeret, som offentlige institutioner bruger som fakturaadresse, stod oprindeligt for European _____ Number.", + "answer": "Article", + "alternatives": [ + "article", + "artikel", + "vare", + "varenummer" + ], + "decoys": [ + "Address", + "Accounting", + "Authority", + "Access" + ], + "note": "EAN blev skabt til stregkoder på varer i butikkerne. Det samme nummersystem bruges også til at give myndigheder og firmaer en adresse, som fakturaer kan sendes til.", + "source": "https://en.wikipedia.org/wiki/International_Article_Number", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Danske EAN-numre, også dem på fakturaer til kommuner og ministerier, begynder typisk med cifrene _____.", + "answer": "57", + "alternatives": [ + "57", + "570", + "579", + "fem syv" + ], + "decoys": [ + "45", + "20", + "10", + "99" + ], + "note": "Stregkode-organisationen GS1 har givet Danmark, Færøerne og Grønland præfikserne 570 til 579. Et EAN-nummer har i alt 13 cifre.", + "source": "https://en.wikipedia.org/wiki/List_of_GS1_country_codes", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Da Danmark indførte e-faktura i 2005, kaldte staten VANS-netværket for det elektroniske _____.", + "answer": "postvæsen", + "alternatives": [ + "postvæsen", + "postvæsenet", + "postvæsnet" + ], + "decoys": [ + "motorvej", + "rørpost", + "pengeskab", + "bibliotek" + ], + "note": "VANS-udbyderne sendte fakturaerne videre til den rigtige modtager ud fra EAN-nummeret, ligesom et postbud bruger en adresse.", + "source": "https://www.budregn.im.dk/media/14278/elektronisk-fakturering.pdf", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Danmark lovgav i 2003 om e-faktura med den internationale standard UBL, selvom den kun var nået til version _____.", + "answer": "0.7", + "alternatives": [ + "0,7", + "0.7", + "nul komma syv" + ], + "decoys": [ + "0.1", + "0.3", + "0.5", + "0.9" + ], + "note": "Den første officielle UBL 1.0 kom først i 2004. Det danske format OIOXML byggede altså på en meget tidlig udgave af standarden.", + "source": "https://en.wikipedia.org/wiki/Universal_Business_Language", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "E-faktura", + "prompt": "Ordet faktura kommer fra latin og bygger på verbet facere, der betyder at _____.", + "answer": "gøre", + "alternatives": [ + "at gøre", + "gøre", + "lave", + "udføre" + ], + "decoys": [ + "betale", + "skrive", + "tælle", + "skylde" + ], + "note": "Latin factura betyder udførelse. Det samme verbum har også givet os ordet fakta.", + "source": "https://ordnet.dk/ddo/ordbog?query=faktura", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Det første antivirusprogram, der jagede ormen Creeper rundt på det tidlige internet, hed _____.", + "answer": "Reaper", + "alternatives": [ + "høstmanden", + "manden med leen", + "reaper", + "the reaper" + ], + "decoys": [ + "Hunter", + "Catcher", + "Cleaner", + "Terminator" + ], + "note": "Creeper skrev bare I'M THE CREEPER, CATCH ME IF YOU CAN på skærmen. Reaper fulgte efter den på ARPANET og fjernede den igen.", + "source": "https://en.wikipedia.org/wiki/Creeper_and_Reaper", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Robert Morris, der slap Morris-ormen løs i 1988, var søn af en kryptograf, der arbejdede for _____.", + "answer": "NSA", + "alternatives": [ + "national security agency", + "nsa" + ], + "decoys": [ + "CIA", + "FBI", + "NASA", + "IBM" + ], + "note": "Morris-ormen lammede tusindvis af computere på det unge internet. Morris fik tre års prøvetid og 400 timers samfundstjeneste og blev senere professor på MIT.", + "source": "https://en.wikipedia.org/wiki/Morris_worm", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Skaberen af ILOVEYOU-virussen fra år 2000 slap for straf, fordi _____ dengang ikke havde love mod hacking.", + "answer": "Filippinerne", + "alternatives": [ + "de filippinske øer", + "filippinerne", + "philippinerne" + ], + "decoys": [ + "Indonesien", + "Thailand", + "Brasilien", + "Rumænien" + ], + "note": "ILOVEYOU kom som et kærlighedsbrev på e-mail og ramte omkring hver tiende computer på internettet. Kort efter fik Filippinerne en lov mod hacking.", + "source": "https://en.wikipedia.org/wiki/ILOVEYOU", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Den tyske Enigma-maskines store svaghed var, at et bogstav aldrig kunne krypteres til _____.", + "answer": "sig selv", + "alternatives": [ + "det samme bogstav", + "samme bogstav", + "sig selv", + "sig selv igen" + ], + "decoys": [ + "en vokal", + "et tal", + "bogstavet X", + "nabobogstavet" + ], + "note": "Det skyldtes maskinens reflektor. Kodebryderne kunne derfor udelukke alle gæt, hvor et bogstav stod samme sted i klarteksten og den krypterede tekst.", + "source": "https://en.wikipedia.org/wiki/Cryptanalysis_of_the_Enigma", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Under 2. verdenskrig fandt briterne nye kodebrydere blandt folk, der var lynhurtige til at løse _____.", + "answer": "krydsord", + "alternatives": [ + "avisens krydsord", + "kryds og tværs", + "krydsord", + "krydsordsopgaver" + ], + "decoys": [ + "skakopgaver", + "hovedregning", + "kabaler", + "rebusser" + ], + "note": "Avisen The Daily Telegraph holdt en konkurrence i at løse et svært krydsord hurtigt. Nogle af deltagerne blev diskret kontaktet og endte på Bletchley Park.", + "source": "https://en.wikipedia.org/wiki/Bletchley_Park", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Når man tastede de gamle reCAPTCHA-ord, hjalp man i virkeligheden med at digitalisere _____.", + "answer": "bøger", + "alternatives": [ + "avisarkiver", + "aviser", + "bøger", + "bøger og aviser", + "gamle aviser", + "gamle bøger", + "new york times" + ], + "decoys": [ + "frimærker", + "opskrifter", + "nodeark", + "landkort" + ], + "note": "Ordene kom fra skannede tekster, som computeren ikke selv kunne læse. Sådan blev blandt andet hele avisen The New York Times' arkiv digitaliseret.", + "source": "https://en.wikipedia.org/wiki/ReCAPTCHA", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Ordet phishing blev første gang brugt i 1995 om svindlere, der fiskede efter adgangskoder til _____.", + "answer": "AOL", + "alternatives": [ + "america online", + "aol" + ], + "decoys": [ + "Hotmail", + "CompuServe", + "Yahoo", + "MSN" + ], + "note": "AOL var dengang en af USA's største netudbydere. Stavningen med ph er inspireret af phreaking, som var hacking af telefonnettet.", + "source": "https://en.wikipedia.org/wiki/Phishing", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "I 1947 fandt teknikere en møl inde i Harvard Mark II-computeren. Den sad fast i et _____.", + "answer": "relæ", + "alternatives": [ + "relay", + "relæ", + "relæet" + ], + "decoys": [ + "radiorør", + "hulkort", + "tastatur", + "blæser" + ], + "note": "Mølen blev tapet ind i logbogen med teksten First actual case of bug being found. Ordet bug om fejl var dog allerede brugt af Thomas Edison i 1800-tallet.", + "source": "https://www.computerhistory.org/tdih/september/9/", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Pinkoder har fire cifre, fordi hæveautomatens opfinder opdagede, at hans _____ ikke kunne huske flere.", + "answer": "kone", + "alternatives": [ + "hustru", + "kone", + "konen" + ], + "decoys": [ + "mor", + "sekretær", + "bankdirektør", + "datter" + ], + "note": "John Shepherd-Barron ville egentlig have seks cifre. Men da han prøvede det på sin kone Caroline, kunne hun kun huske fire, og det blev verdensstandard.", + "source": "https://en.wikipedia.org/wiki/John_Shepherd-Barron", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Det første kendte tyveri af computer-passwords skete på MIT i 1962. Tyven ville bare have mere _____.", + "answer": "computertid", + "alternatives": [ + "computertid", + "maskintid", + "regnetid", + "tid", + "tid på computeren" + ], + "decoys": [ + "lommepenge", + "papir", + "kaffe", + "diskplads" + ], + "note": "Ph.d.-studerende Allan Scherr havde kun fire timer om ugen på computeren. Han printede hele passwordfilen og tilstod det først næsten 50 år senere.", + "source": "https://www.wired.com/2012/01/computer-password/", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Apple II-virussen Elk Cloner fra 1982 viste med jævne mellemrum et _____ på skærmen.", + "answer": "digt", + "alternatives": [ + "digt", + "et digt", + "rim", + "vers" + ], + "decoys": [ + "dødningehoved", + "billede af en elg", + "smiley", + "bandeord" + ], + "note": "Virussen blev skrevet af den 15-årige skoleelev Rich Skrenta som et drilleri. Den spredte sig fra diskette til diskette, og hver 50. gang viste den sit digt i stedet for programmet.", + "source": "https://en.wikipedia.org/wiki/Elk_Cloner", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "IT-sikkerhed", + "prompt": "Astronomen Clifford Stoll fangede i 1986 en hacker, der solgte til KGB, fordi han undersøgte en regnskabsfejl på _____.", + "answer": "75 cent", + "alternatives": [ + "0,75 dollar", + "75 cent", + "75 cents" + ], + "decoys": [ + "1 cent", + "50 cent", + "3 dollar", + "12 dollar" + ], + "note": "Stoll passede computerne på et laboratorium i Californien. Han lokkede hackeren med falske hemmelige filer, og sporet førte til Hannover i Tyskland.", + "source": "https://en.wikipedia.org/wiki/The_Cuckoo%27s_Egg_(book)", + "packs": [ + "nørd", + "arbejde" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Linus Torvalds valgte en pingvin som Linux-maskot. Han har fortalt, at han engang blev _____ af en pingvin.", + "answer": "bidt", + "alternatives": [ + "bidt", + "bidt i fingeren", + "nappet" + ], + "decoys": [ + "jagtet", + "kysset", + "reddet", + "fodret" + ], + "note": "Det skete i en zoologisk have i Canberra i Australien. Pingvinen Tux blev tegnet i 1996 af Larry Ewing.", + "source": "https://en.wikipedia.org/wiki/Tux_(mascot)", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Ordet emoji har intet med emotion at gøre. På japansk betyder det _____.", + "answer": "billedtegn", + "alternatives": [ + "billedbogstav", + "billede og tegn", + "billede tegn", + "billede-tegn", + "billedskrift", + "billedtegn" + ], + "decoys": [ + "lille ansigt", + "glad stemme", + "hemmelig besked", + "smilende øje" + ], + "note": "E betyder billede og moji betyder tegn. De første 176 emojier blev tegnet i 1999 af Shigetaka Kurita og er i dag en del af samlingen på MoMA i New York.", + "source": "https://en.wikipedia.org/wiki/Emoji", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Navnet Tetris er en blanding af tetra, der betyder fire, og opfinderens yndlingssport _____.", + "answer": "tennis", + "alternatives": [ + "tennis" + ], + "decoys": [ + "skak", + "badminton", + "ishockey", + "volleyball" + ], + "note": "Alexey Pajitnov lavede spillet i Moskva i 1984 på en sovjetisk computer. Alle brikkerne i Tetris består af fire firkanter.", + "source": "https://en.wikipedia.org/wiki/Tetris", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Programmeringssproget Python er opkaldt efter _____.", + "answer": "Monty Python", + "alternatives": [ + "monty python", + "monty python's flying circus", + "monty pythons", + "monty pythons flying circus" + ], + "decoys": [ + "en kæmpeslange", + "en græsk sagnfigur", + "opfinderens hund", + "en raket" + ], + "note": "Guido van Rossum begyndte på sproget i december 1989 og opkaldte det efter den britiske komikergruppes tv-serie Monty Python's Flying Circus.", + "source": "https://en.wikipedia.org/wiki/History_of_Python", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Det allerførste .com-domæne blev registreret i 1985 og hed _____.com.", + "answer": "symbolics", + "alternatives": [ + "symbolics", + "symbolics.com" + ], + "decoys": [ + "computer", + "internet", + "arpa", + "digital" + ], + "note": "Domænet tilhørte computerfirmaet Symbolics. Det er stadig registreret og er dermed verdens ældste .com-domæne.", + "source": "https://en.wikipedia.org/wiki/Symbolics", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Super Mario hed først Jumpman og var i Donkey Kong fra 1981 slet ikke blikkenslager, men _____.", + "answer": "tømrer", + "alternatives": [ + "snedker", + "tømrer", + "tømrerlærling" + ], + "decoys": [ + "murer", + "skorstensfejer", + "elektriker", + "maler" + ], + "note": "Han blev først blikkenslager i spillet Mario Bros., der foregår i kloakrør. Navnet Mario fik han efter udlejeren af Nintendos lager i USA.", + "source": "https://en.wikipedia.org/wiki/Mario", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Den allerførste Apple-computer kostede i 1976 _____ dollar.", + "answer": "666,66", + "alternatives": [ + "666", + "666,66", + "666.66" + ], + "decoys": [ + "499,99", + "777,77", + "1.000", + "350" + ], + "note": "Steve Wozniak kunne godt lide gentagne cifre, og prisen var en tredjedel oveni de 500 dollar, som butikken betalte. Han tænkte slet ikke på dyrets tal fra Bibelen.", + "source": "https://en.wikipedia.org/wiki/Apple_I", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Rasmus Lerdorf, der skabte programmeringssproget PHP, blev født i 1968 i _____.", + "answer": "Grønland", + "alternatives": [ + "godhavn", + "grønland", + "qeqertarsuaq" + ], + "decoys": [ + "Færøerne", + "Island", + "Canada", + "Svalbard" + ], + "note": "Han blev født i byen Qeqertarsuaq. PHP blev skabt i 1993 og driver i dag en stor del af verdens hjemmesider.", + "source": "https://en.wikipedia.org/wiki/Rasmus_Lerdorf", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Minecraft hed i den allerførste udgave fra 2009 _____.", + "answer": "Cave Game", + "alternatives": [ + "cave game", + "cavegame", + "the cave game" + ], + "decoys": [ + "Block World", + "Dig Dig", + "Craft Cave", + "Mine Land" + ], + "note": "Markus Persson, kendt som Notch, lagde den første version ud i maj 2009. Her kunne man kun placere og fjerne blokke af græs og brosten.", + "source": "https://en.wikipedia.org/wiki/History_of_Minecraft", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Den allerførste video på YouTube fra 2005 varer 19 sekunder og handler om _____ i San Diego Zoo.", + "answer": "elefanter", + "alternatives": [ + "elefant", + "elefanter", + "elefanterne", + "elefanternes snabler", + "snabler", + "to elefanter" + ], + "decoys": [ + "giraffer", + "pandaer", + "flamingoer", + "isbjørne" + ], + "note": "Videoen hedder Me at the zoo og er lagt op af medstifteren Jawed Karim. Han siger bare, at elefanterne har virkelig, virkelig lange snabler.", + "source": "https://en.wikipedia.org/wiki/Me_at_the_zoo", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Søgemaskinen Google hed oprindeligt _____.", + "answer": "BackRub", + "alternatives": [ + "back rub", + "backrub" + ], + "decoys": [ + "LinkFinder", + "WebHunter", + "Stanford Search", + "PageFinder" + ], + "note": "Navnet kom af, at søgemaskinen analyserede backlinks, altså links tilbage til en side. Google kommer af tallet googol, et ettal med hundrede nuller.", + "source": "https://en.wikipedia.org/wiki/History_of_Google", + "packs": [ + "nørd" + ] + }, + { + "category": "Computerhistorie", + "prompt": "Ada Lovelace, der ofte kaldes verdens første programmør, var datter af digteren _____.", + "answer": "Lord Byron", + "alternatives": [ + "byron", + "george byron", + "lord byron" + ], + "decoys": [ + "William Wordsworth", + "Percy Shelley", + "John Keats", + "Walter Scott" + ], + "note": "Hendes mor lod hende lære matematik, blandt andet så hun ikke skulle arve faderens poetiske galskab. Ada kaldte selv sin tilgang for poetisk videnskab.", + "source": "https://en.wikipedia.org/wiki/Ada_Lovelace", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Gramfarvning, som deler bakterier i to grupper, er opkaldt efter en læge fra _____.", + "answer": "Danmark", + "alternatives": [ + "danmark", + "dansk", + "dansker", + "københavn" + ], + "decoys": [ + "Tyskland", + "Østrig", + "Holland", + "Skotland" + ], + "note": "Danskeren Hans Christian Gram udviklede farvemetoden i 1884, mens han arbejdede i Berlin. Den bruges stadig hver dag på hospitaler over hele verden.", + "source": "https://www.britannica.com/science/Gram-stain", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "August Krogh hentede insulin til Danmark i 1922, ikke mindst fordi hans _____ havde sukkersyge.", + "answer": "kone", + "alternatives": [ + "hustru", + "hustruen", + "kone", + "konen", + "marie", + "marie krogh" + ], + "decoys": [ + "datter", + "bror", + "mor", + "svigerfar" + ], + "note": "Marie Krogh var selv forsker og havde fået diabetes. Rejsen til Toronto blev begyndelsen på det, der i dag er Novo Nordisk.", + "source": "https://novonordiskfonden.dk/en/who-we-are/history/", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Svampen, der gjorde det muligt at masseproducere penicillin, blev i 1943 fundet på en muggen _____.", + "answer": "melon", + "alternatives": [ + "cantaloupe", + "cantaloupe-melon", + "cantaloupemelon", + "melon", + "netmelon" + ], + "decoys": [ + "appelsin", + "brødskive", + "kartoffel", + "ost" + ], + "note": "En muggen melon fra et marked i den amerikanske by Peoria bar en svampestamme, der lavede langt mere penicillin end Flemings. Dens efterkommere bruges stadig i dag.", + "source": "https://scientificdiscoveries.ars.usda.gov/tellus/stories/articles/enduring-mystery-moldy-mary", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Det allerførste stetoskop fra 1816 var lavet af sammenrullet _____.", + "answer": "papir", + "alternatives": [ + "et stykke papir", + "karton", + "papir", + "papirark" + ], + "decoys": [ + "læder", + "bambus", + "birkebark", + "kobberblik" + ], + "note": "Den franske læge René Laennec var for genert til at lægge øret mod en ung patients bryst, så han rullede et bundt papir sammen. Bagefter byggede han et rør af træ.", + "source": "https://www.pbs.org/newshour/health/a-curious-inspiration-for-the-first-stethoscope", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Koen, der i 1796 leverede smitten til verdens første vaccine, hed _____.", + "answer": "Blossom", + "alternatives": [ + "blossom" + ], + "decoys": [ + "Daisy", + "Buttercup", + "Bella", + "Molly" + ], + "note": "Malkepigen Sarah Nelmes fik kokopper fra koen Blossom, og Edward Jenner brugte smitten til at beskytte en dreng mod kopper. Koens hud hænger stadig på et lægebibliotek i London.", + "source": "https://artuk.org/discover/stories/the-smallpox-vaccine-edward-jenner-and-a-cow-called-blossom", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Opfinderne af insulin solgte deres patent til University of Toronto for _____.", + "answer": "1 dollar", + "alternatives": [ + "$1", + "1 dollar", + "1 dollar hver", + "1$", + "en dollar", + "en dollar hver", + "en dollar stykket", + "én dollar" + ], + "decoys": [ + "1 million dollar", + "100.000 dollar", + "500 dollar", + "50 cent" + ], + "note": "Banting, Best og Collip ville ikke tjene penge på livsvigtig medicin. De solgte derfor patentet for en symbolsk dollar hver i 1923.", + "source": "https://bantinghousenhs.ca/insulin-patent-sold-for-1/", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Navnet malaria kommer fra italiensk og betyder _____.", + "answer": "dårlig luft", + "alternatives": [ + "bad air", + "dårlig luft", + "mala aria", + "ond luft", + "slem luft", + "usund luft" + ], + "decoys": [ + "ondt blod", + "sumpvand", + "myggestik", + "kold feber" + ], + "note": "Man troede længe, at sygdommen kom fra den dårlige luft over sumpe. I dag ved vi, at den spredes af myg.", + "source": "https://www.dictionary.com/browse/malaria", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Wilhelm Röntgen kaldte sine nye stråler for X-stråler, fordi X betød _____.", + "answer": "ukendt", + "alternatives": [ + "den ubekendte", + "det ukendte", + "noget ukendt", + "ubekendt", + "ukendt", + "ukendte" + ], + "decoys": [ + "kryds", + "ti", + "ekstra", + "gennem" + ], + "note": "Röntgen vidste ikke, hvad strålerne var, da han opdagede dem i 1895, så han brugte matematikkens bogstav for det ukendte. På dansk har vi i stedet opkaldt dem efter ham.", + "source": "https://www.nobelprize.org/prizes/physics/1901/rontgen/biographical/", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Under polioepidemien i København i 1952 pumpede ca. 1.500 _____ luft i patienternes lunger med håndkraft.", + "answer": "medicinstuderende", + "alternatives": [ + "lægestuderende", + "medicinerstuderende", + "medicinstuderende", + "studenter", + "studerende" + ], + "decoys": [ + "soldater", + "spejdere", + "brandmænd", + "gymnasieelever" + ], + "note": "Lægen Bjørn Ibsen viste, at man kunne holde lammede patienter i live ved at blæse luft ind med en gummiballon. Det regnes for starten på verdens moderne intensivafdelinger.", + "source": "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC11411485/", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "I 1988 blev den danske anatom Niels Steensen _____ af paven.", + "answer": "saligkåret", + "alternatives": [ + "beatificeret", + "erklæret salig", + "saligforklaret", + "saliggjort", + "saligkåret" + ], + "decoys": [ + "adlet", + "æresdoktor", + "lyst i band", + "udnævnt til kardinal" + ], + "note": "Steno var en berømt anatom og geolog, men blev senere katolsk biskop. Pave Johannes Paul 2. saligkårede ham som den første naturvidenskabsmand nogensinde.", + "source": "https://www.catholicireland.net/gods-scientist-blessed-niels-stensen-1638-86/", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Dronning Victoria gjorde bedøvelse populær, da hun i 1853 fik kloroform under _____.", + "answer": "en fødsel", + "alternatives": [ + "en barnefødsel", + "en fødsel", + "fødsel", + "fødslen", + "fødslen af prins leopold", + "sin fødsel" + ], + "decoys": [ + "en tandudtrækning", + "en blindtarmsoperation", + "sin kroning", + "et benbrud" + ], + "note": "Lægen John Snow gav hende kloroform, da hun fødte sit ottende barn, prins Leopold. Bagefter kaldte dronningen det for velsignet kloroform.", + "source": "https://collection.sciencemuseumgroup.org.uk/objects/co74958/letter-from-queen-victoria-mentioning-chloroform-use-in-childbirth", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Antoni van Leeuwenhoek, den første, der så bakterier i et mikroskop, var af profession _____.", + "answer": "klædehandler", + "alternatives": [ + "kludehandler", + "klædehandler", + "købmand", + "manufakturhandler", + "stofhandler", + "tekstilhandler", + "tøjhandler" + ], + "decoys": [ + "apoteker", + "urmager", + "skomager", + "bager" + ], + "note": "Han ville egentlig bare tjekke kvaliteten af stof og tråd, men slibede så gode linser, at han i 1600-tallet blev den første, der så bakterier.", + "source": "https://www.asbmb.org/asbmb-today/people/050221/the-17th-century-cloth-merchant-who-discovered-the", + "packs": [ + "nørd" + ] + }, + { + "category": "Lægevidenskab", + "prompt": "Sygeplejersken Florence Nightingale blev i 1858 det første kvindelige medlem af et britisk selskab for _____.", + "answer": "statistik", + "alternatives": [ + "statistik", + "statistikere" + ], + "decoys": [ + "kemi", + "astronomi", + "botanik", + "geografi" + ], + "note": "Nightingale brugte tal og sine egne farverige diagrammer til at vise, at flere soldater døde af sygdom end af kamp. Det fik hospitalerne til at forbedre hygiejnen.", + "source": "https://rss.org.uk/news-publication/news-publications/2020/general-news/nightingale-2020-the-bicentenary-our-first-female/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Tolkien skrev Hobbittens første sætning på en blank side, mens han sad og _____.", + "answer": "rettede eksamensopgaver", + "alternatives": [ + "rettede eksamener", + "rettede eksamensbesvarelser", + "rettede eksamensopgaver", + "rettede opgaver", + "rettede prøver", + "rettede stile" + ], + "decoys": [ + "ventede på toget", + "passede sine børn", + "spiste morgenmad", + "sad i kirke" + ], + "note": "Midt i en bunke kedelige eksamensbesvarelser fandt Tolkien en tom side og skrev: I et hul i jorden boede en hobbit. Han vidste først ikke selv, hvad en hobbit var.", + "source": "https://www.tolkienestate.com/writing/john-d-rateliff-the-hobbit/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Som lille dreng i Sydafrika blev J.R.R. Tolkien bidt af en _____.", + "answer": "tarantel", + "alternatives": [ + "bavianedderkop", + "edderkop", + "fugleedderkop", + "tarantel", + "tarantula" + ], + "decoys": [ + "slange", + "skorpion", + "sjakal", + "struds" + ], + "note": "Det skete i haven i Bloemfontein, hvor han blev født. Mange tror, det er derfor, hans bøger er fulde af kæmpeedderkopper, men Tolkien sagde selv, at han ikke var bange for dem.", + "source": "https://tolkiengateway.net/wiki/Spiders", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Aragorns skrig, da han sparker til en orkhjelm i De To Tårne, er ægte. Viggo Mortensen _____.", + "answer": "brækkede to tæer", + "alternatives": [ + "brækkede en tå", + "brækkede to tæer", + "brækkede tæer", + "brækkede tæer på foden", + "brækkede tæerne" + ], + "decoys": [ + "forstuvede anklen", + "trådte på et søm", + "fik en hveps i støvlen", + "slog knæet" + ], + "note": "Han brækkede tæerne ved femte optagelse, så smerten i skriget er ægte. Peter Jackson brugte netop den optagelse i filmen.", + "source": "https://nofilmschool.com/viggo-mortensen-broken-toes-two-towers-scream", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Skuespillerne fra Ringens Brødreskab fik næsten alle tatoveret ordet _____ på elverisk.", + "answer": "ni", + "alternatives": [ + "9", + "ni", + "nine" + ], + "decoys": [ + "ring", + "venner", + "brødre", + "hobbit" + ], + "note": "Tatoveringen fejrer brødreskabets ni medlemmer. Gimlis skuespiller John Rhys-Davies ville ikke selv, så han sendte sin stuntmand i stedet.", + "source": "https://screenrant.com/lord-rings-tattoo-fellowship/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Tolkiens elversprog quenya er især inspireret af _____.", + "answer": "finsk", + "alternatives": [ + "det finske sprog", + "finland", + "finnish", + "finsk" + ], + "decoys": [ + "islandsk", + "ungarsk", + "baskisk", + "gælisk" + ], + "note": "Tolkien forelskede sig i finsk, da han som student læste eposset Kalevala. Det andet store elversprog, sindarin, låner i stedet lyde fra walisisk.", + "source": "https://en.wikipedia.org/wiki/Quenya", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Andy Serkis fandt Gollums stemme ved at efterligne sin _____.", + "answer": "kat", + "alternatives": [ + "kat", + "kat med hårbold", + "katte", + "katten" + ], + "decoys": [ + "papegøje", + "bedstefar", + "hund", + "kaffemaskine" + ], + "note": "Hans kat hostede en hårbold op, og den gurglende lyd blev til Gollums berømte hoste. Serkis har sagt, at han skylder katten hele sin karriere.", + "source": "https://www.looper.com/1335826/lotr-andy-serkis-gollum-voice-inspired-by-cat-furball/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Uruk-haiernes kampråb ved Helms Kløft blev optaget med publikum til en _____-kamp i New Zealand.", + "answer": "cricket", + "alternatives": [ + "cricket", + "cricketkamp", + "kricket" + ], + "decoys": [ + "rugby", + "fodbold", + "basketball", + "netball" + ], + "note": "I 2002 gik Peter Jackson på banen i en pause under en cricketlandskamp i Wellington, og titusinder af tilskuere råbte og brølede på kommando.", + "source": "https://newzealandfilmmap.com/locations/sky-stadium-helms-deep/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "På Tolkiens gravsten i Oxford står der under hans eget navn også navnet _____.", + "answer": "Beren", + "alternatives": [ + "beren" + ], + "decoys": [ + "Bilbo", + "Gandalf", + "Aragorn", + "Frodo" + ], + "note": "Hans kone Edith fik navnet Lúthien på stenen, og Tolkien fik Beren. Det er et elskende par fra hans egne myter, inspireret af Edith, der engang dansede for ham i en skov.", + "source": "https://tolkiengateway.net/wiki/Wolvercote_Cemetery", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Ringbrynjerne i filmene bestod af 12,5 millioner små ringe skåret af _____.", + "answer": "plastikrør", + "alternatives": [ + "plast", + "plastik", + "plastikrør", + "plastrør", + "pvc", + "pvc-rør" + ], + "decoys": [ + "aluminium", + "kobbertråd", + "gummislanger", + "sugerør" + ], + "note": "Wētā Workshop skar kilometervis af plastikrør i skiver og satte ringene sammen i hånden. Bagefter fik de en overflade, så de lignede metal.", + "source": "https://www.facebook.com/WetaWorkshop/photos/throwback-to-the-weta-workshop-chainmaille-department-dedicated-to-middle-earth-/10155250953942303/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Som ung arbejdede Tolkien på den store Oxford-ordbog med ord, der begynder med bogstavet _____.", + "answer": "W", + "alternatives": [ + "w" + ], + "decoys": [ + "Q", + "X", + "Z", + "H" + ], + "note": "I 1919 og 1920 skrev han blandt andet om walrus, wasp og winter. Hans arbejde med ordet walrus, altså hvalros, fik særlig ros af redaktøren.", + "source": "https://blog.oup.com/2009/09/walrus/", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "I Peter Jacksons lille gæsteoptræden i byen Bree står han og spiser en _____.", + "answer": "gulerod", + "alternatives": [ + "gulerod", + "gulerødden", + "gulerødder" + ], + "decoys": [ + "æble", + "kyllingelår", + "pølse", + "pære" + ], + "note": "Instruktøren dukker op i regnen, lige før hobbitterne går ind på kroen i Bree. Han spiller den samme gulerodsmand igen i en af Hobbit-filmene.", + "source": "https://tolkiengateway.net/wiki/Albert_Dreary", + "packs": [ + "nørd" + ] + }, + { + "category": "Ringenes Herre", + "prompt": "Hver jul fra 1920 til 1943 skrev Tolkien breve til sine børn fra _____.", + "answer": "julemanden", + "alternatives": [ + "father christmas", + "julemand", + "julemanden", + "julenissen", + "nissen", + "santa claus" + ], + "decoys": [ + "tandfeen", + "påskeharen", + "Gandalf", + "kongen" + ], + "note": "Brevene var fulde af tegninger, og nogle var skrevet af julemandens klodsede hjælper, en isbjørn. De udkom som bog i 1976.", + "source": "https://www.tolkienestate.com/writing/baillie-tolkien-letters-from-father-christmas/", + "packs": [ + "nørd" + ] + } +] \ No newline at end of file diff --git a/fupogfakta/management/commands/load_questions.py b/fupogfakta/management/commands/load_questions.py index 678e84a..03d581f 100644 --- a/fupogfakta/management/commands/load_questions.py +++ b/fupogfakta/management/commands/load_questions.py @@ -22,6 +22,9 @@ class Command(BaseCommand): for path in paths: for item in json.loads(path.read_text(encoding="utf-8")): cat, _ = Category.objects.get_or_create(name=item["category"].strip()) + if item.get("packs") and cat.packs != item["packs"]: + cat.packs = item["packs"] + cat.save(update_fields=["packs"]) _, was_created = Question.objects.update_or_create( prompt=item["prompt"].strip(), defaults={"category": cat, "answer": item["answer"].strip(), diff --git a/fupogfakta/migrations/0003_category_packs.py b/fupogfakta/migrations/0003_category_packs.py new file mode 100644 index 0000000..128ff59 --- /dev/null +++ b/fupogfakta/migrations/0003_category_packs.py @@ -0,0 +1,14 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [("fupogfakta", "0002_question_times_all_correct")] + + operations = [ + migrations.AddField( + model_name="category", + name="packs", + field=models.JSONField("pakker", blank=True, default=list, + help_text='Fx ["familie"], ["nørd"] eller ["nørd", "arbejde"]. Tom = familie.'), + ), + ] diff --git a/fupogfakta/models.py b/fupogfakta/models.py index 4df8982..374645f 100644 --- a/fupogfakta/models.py +++ b/fupogfakta/models.py @@ -1,9 +1,19 @@ from django.db import models +# Pakker: en kategori kan høre til flere. "arbejde" er aldrig med i "alle" og vælges kun med vilje. +PACKS = ["familie", "nørd", "arbejde"] +PRESETS = {"alle": ["familie", "nørd"], "familie": ["familie"], "nørd": ["nørd"], "arbejde": ["arbejde"]} + + class Category(models.Model): name = models.CharField("navn", max_length=60, unique=True) active = models.BooleanField("aktiv", default=True) + packs = models.JSONField("pakker", default=list, blank=True, + help_text='Fx ["familie"], ["nørd"] eller ["nørd", "arbejde"]. Tom = familie.') + + def in_packs(self, wanted) -> bool: + return bool(set(self.packs or ["familie"]) & set(wanted)) class Meta: verbose_name = "kategori" @@ -53,6 +63,8 @@ def record_question_result(question_id: int, everyone_found_it: bool): times_all_correct=F("times_all_correct") + (1 if everyone_found_it else 0)) -def load_game_questions(): +def load_game_questions(preset: str = "alle"): + wanted = PRESETS.get(preset, PRESETS["alle"]) qs = Question.objects.filter(active=True, category__active=True, times_all_correct__lt=TOO_EASY).select_related("category") + qs = [q for q in qs if q.category.in_packs(wanted)] return [q.as_game_dict() for q in qs if "_____" in q.prompt] diff --git a/fupogfakta/tests/test_packs.py b/fupogfakta/tests/test_packs.py new file mode 100644 index 0000000..dd1ba10 --- /dev/null +++ b/fupogfakta/tests/test_packs.py @@ -0,0 +1,20 @@ +from django.test import TestCase + +from fupogfakta.models import Category, Question, load_game_questions + + +class PackTests(TestCase): + def setUp(self): + for name, packs in [("Dyreriget", []), ("Star Wars", ["nørd"]), ("E-faktura", ["nørd", "arbejde"]), ("Firma", ["arbejde"])]: + cat = Category.objects.create(name=name, packs=packs) + Question.objects.create(category=cat, prompt=f"{name} har _____.", answer="x") + + def cats(self, preset): + return sorted({q["category"] for q in load_game_questions(preset)}) + + def test_presets(self): + self.assertEqual(self.cats("alle"), ["Dyreriget", "E-faktura", "Star Wars"]) # arbejde kun med vilje + self.assertEqual(self.cats("familie"), ["Dyreriget"]) # tom = familie + self.assertEqual(self.cats("nørd"), ["E-faktura", "Star Wars"]) + self.assertEqual(self.cats("arbejde"), ["E-faktura", "Firma"]) + self.assertEqual(self.cats("ukendt"), self.cats("alle")) diff --git a/party/management/commands/tts_warm.py b/party/management/commands/tts_warm.py index 5438300..81f4032 100644 --- a/party/management/commands/tts_warm.py +++ b/party/management/commands/tts_warm.py @@ -2,15 +2,30 @@ import re from django.core.management.base import BaseCommand -from party import tts from fupogfakta.engine import RULES -from party.narrator import LINES, TEASES +from fupogfakta.models import Question +from party import tts +from party.narrator import LINES, TEASES, speakable_prompt + + +def _expand_categories(lines: list[str], categories: list[str]) -> list[str]: + """Replikker, hvis eneste pladsholder er {kategori}, findes i et endeligt antal udgaver: lav dem alle.""" + out = [] + for line in lines: + if set(re.findall(r"\{(\w+)\}", line)) == {"kategori"}: + out += [line.format(kategori=c) for c in categories] + return out class Command(BaseCommand): - help = "Genererer speakerens faste replikker (dem uden pladsholdere) på forhånd, så første spil ikke venter." + help = ("Genererer speakerens replikker på forhånd. Uden --budget: kun de faste replikker (gratis, når de findes). " + "Med --budget N: derefter op til N tegn af spørgsmålenes oplæsning og forklaring (de mindst brugte først, " + "dvs. dem der kommer næste gang) og kategori-replikkerne. Køres om natten, så kvoten fordeles.") - def handle(self, *args, **opts): + def add_arguments(self, parser): + parser.add_argument("--budget", type=int, default=0, help="højst så mange nye tegn ud over de faste replikker") + + def handle(self, *args, budget, **opts): if not tts.enabled(): self.stdout.write("ElevenLabs er ikke sat op (ELEVENLABS_API_KEY/ELEVENLABS_VOICE_ID). Springer over.") return @@ -19,3 +34,29 @@ class Command(BaseCommand): static += [r["say"] for r in RULES] ok = sum(1 for line in static if tts.synth_sync(line)) self.stdout.write(self.style.SUCCESS(f"{ok} af {len(static)} faste replikker ligger i cachen.")) + if budget <= 0: + return + + # Spørgsmålene i den rækkefølge, spillet vælger dem (mindst brugte først), skiftevis med + # kategori-replikkerne, så begge dele bliver dækket over et par nætter. + questions = [] + for q in Question.objects.filter(active=True).select_related("category").order_by("times_used", "id"): + questions += [speakable_prompt(q.prompt)] + ([q.note] if q.note else []) + categories = sorted(set(Question.objects.filter(active=True).values_list("category__name", flat=True))) + per_category = _expand_categories(LINES.get("lie_start", []), categories) + queue = [t for pair in zip(questions, per_category) for t in pair] + queue += questions[len(per_category):] + per_category[len(questions):] + + spent = made = cached = 0 + for text in queue: + if tts.is_cached(text): + cached += 1 + continue + if spent + len(text) > budget: + break + if tts.synth_sync(text): + spent += len(text) + made += 1 + left = sum(1 for t in queue if not tts.is_cached(t)) + self.stdout.write(self.style.SUCCESS( + f"{made} nye replikker ({spent} tegn); {cached} lå allerede i cachen; {left} mangler endnu.")) diff --git a/party/static/party/common.js b/party/static/party/common.js index 2b7218b..cbab667 100644 --- a/party/static/party/common.js +++ b/party/static/party/common.js @@ -462,7 +462,8 @@ } /* ---------- lydeffekter ---------- */ - var CATS = ['dyreriget', 'kroppen', 'mad_og_drikke', 'rummet_og_naturen', 'opfindelser', 'danmark', 'sprog_og_ord', 'sport', 'historie', 'geografi']; + var CATS = ['dyreriget', 'kroppen', 'mad_og_drikke', 'rummet_og_naturen', 'opfindelser', 'danmark', 'sprog_og_ord', 'sport', 'historie', 'geografi', + 'star_wars', 'harry_potter', 'e_faktura', 'it_sikkerhed', 'computerhistorie', 'laegevidenskab', 'ringenes_herre']; var SFX = ['whoosh', 'tick', 'timeup', 'submit', 'join', 'drumroll', 'stamp', 'truth', 'house', 'explode', 'coins', 'like', 'fanfare', 'category', 'whoosh_long', 'swoosh_up', 'pop_in', 'slide', 'boo'].concat(CATS.map(function (c) { return 'cat_' + c; })); var MUSIC = ['music_lobby', 'music_choose', 'music_think', 'music_reveal', 'music_final']; @@ -551,6 +552,23 @@ phase: function (t) { t(523, 0, 0.15); t(784, 0.09, 0.25); } }; var lastAt = {}; + /* Varianter: "stamp", "stamp__2", "stamp__3" … er samme effekt i flere udgaver; der vælges tilfældigt + (aldrig samme to gange i træk), så hyppige lyde ikke bliver monotone. Uden asset-kort: kun grundnavnet. */ + var variantCache = {}, lastVariant = {}; + function variants(name) { + if (variantCache[name]) return variantCache[name]; + var v = [name]; + if (ASSETS.sfx) Object.keys(ASSETS.sfx).sort().forEach(function (k) { if (k.indexOf(name + '__') === 0) v.push(k); }); + return (variantCache[name] = v); + } + function pickVariant(name) { + var ready = variants(name).filter(function (n) { return bufs[n]; }); + if (ready.length < 2) return ready[0] || name; + var pool = ready.filter(function (n) { return n !== lastVariant[name]; }); + var pick = pool[Math.floor(Math.random() * pool.length)]; + lastVariant[name] = pick; + return pick; + } /* WPP.sfx(navn, {volume, rate, delay, fallback, gap}) – afspil en effekt (kan overlappe sig selv). fallback: navn der bruges, hvis filen ikke findes (fx cat_ → category). gap: mindst så mange ms mellem to af samme navn; for tætte kald droppes (mod lyd-spam). @@ -565,7 +583,7 @@ if (at < (lastAt[name] || 0) - 0.005) return 0; lastAt[name] = at + opts.gap / 1000; } - var b = bufs[name]; + var b = bufs[pickVariant(name)]; if (!b) { var f = FALLBACK[name] || FALLBACK[opts.fallback]; if (f) f(function (fr, st, d, ty, v, f2) { sound.tone(fr, (st || 0) + delay, d, ty, v, f2); }); @@ -576,12 +594,14 @@ }; WPP.sfx.names = SFX; WPP.sfx.has = function (name) { return known(name) && !failed[name]; }; + WPP.sfx.variants = variants; /* Hent filerne. Uden liste: alt (kun værten); telefonerne henter kun det, de bruger (boo). */ WPP.sfx.preload = function (list) { if (list) { list.forEach(load); return; } if (WPP.sfx._preloaded) return; WPP.sfx._preloaded = true; - (ASSETS.sfx ? Object.keys(ASSETS.sfx) : SFX.concat(MUSIC)).forEach(load); + /* musikken hentes først, når den skal spilles (afkodet fylder et nummer ~10 MB) */ + (ASSETS.sfx ? Object.keys(ASSETS.sfx) : SFX).forEach(function (n) { if (!/^music_/.test(n)) load(n); }); }; /* Afspil en vilkårlig lydfil (fx serverens TTS) gennem AudioContext; caches pr. URL. opts.at = AudioContext-tid, lyden tidligst må starte (afkodningen kan tage et øjeblik). */ @@ -610,7 +630,7 @@ if (name === music.name) return; music.name = name; music._fade = opts.fade != null ? opts.fade : FADE; - music._gain = opts.gain != null ? opts.gain : (MUSIC_GAIN[name] || 1); + music._gain = opts.gain != null ? opts.gain : (MUSIC_GAIN[String(name).replace(/__\d+$/, '')] || 1); if (name) load(name); music._kick(); }, @@ -662,6 +682,12 @@ track.g.gain.exponentialRampToValueAtTime(0.0001, t + dur); track.src.stop(t + dur + 0.05); } catch (e) { /* allerede stoppet */ } + /* slip det afkodede nummer, når det er tonet ud; næste gang hentes det fra browserens cache */ + var name = track.name; + setTimeout(function () { + if (music.name === name || (music.cur && music.cur.name === name)) return; + delete bufs[name]; delete loading[name]; + }, (dur + 0.5) * 1000); } ['pointerdown', 'keydown', 'touchstart', 'touchend', 'click'].forEach(function (ev) { diff --git a/party/static/party/host.js b/party/static/party/host.js index 4bf9b1b..3e617d8 100644 --- a/party/static/party/host.js +++ b/party/static/party/host.js @@ -582,7 +582,7 @@ sfx(u, 'fanfare', { delay: from ? 0.3 : 0 }); sfx(u, 'swoosh_up', { delay: 0.9, volume: 0.4 }); /* vinderens søjle rejser sig */ confetti(root); - u.finalT = setTimeout(function () { u.finalMusic = true; if (audible(u.ctx)) WPP.music.set('music_final'); }, 3000); + u.finalT = setTimeout(function () { u.finalMusic = true; if (audible(u.ctx)) WPP.music.set(musicFor(u, 'final', state)); }, 3000); } } /* kategorikortet: whoosh når det letter, kategoriens jingle når det lander (finalen: FINALE-skiltet smækker først) */ @@ -598,7 +598,17 @@ if (u.state && pkey(u.state) === key) sparkle(root, root.querySelector('.screen .in-card'), 22); }, (t0 + INTRO_LAND) * 1000); } - function musicFor(u, phase) { return phase === 'final' ? (u.finalMusic ? 'music_final' : null) : (MUSIC[phase] || null); } + /* Tænkemusik pr. kategori (music_think_), ellers den fælles. Findes et nummer i flere udgaver + (music_reveal__2 …), vælges én pr. spørgsmål, så lie → present → guess spiller videre uden skift. */ + function musicFor(u, phase, state) { + var base = phase === 'final' ? (u.finalMusic ? 'music_final' : null) : (MUSIC[phase] || null); + if (!base) return null; + var q = state.question || state.intro || {}; + if (base === 'music_think' && q.slug && WPP.sfx.has('music_think_' + q.slug)) base = 'music_think_' + q.slug; + var v = WPP.sfx.variants(base), r = state.round || {}; + var seed = (r.number || 0) * 7 + (r.question_number || 0) + String(state.code || '').charCodeAt(0); + return v[(seed || 0) % v.length]; + } /* nye noder med data-sfx får deres lyd (bevarede noder har allerede fået den) */ function nodeSfx(root, u, state, quiet) { @@ -791,7 +801,7 @@ u.lastPhase = phase; if (audible(ctx)) { WPP.sfx.preload(); - WPP.music.set(musicFor(u, phase), { fade: phase === 'intro' || phase === 'final' ? STING_FADE : null }); + WPP.music.set(musicFor(u, phase, state), { fade: phase === 'intro' || phase === 'final' ? STING_FADE : null }); } } diff --git a/party/static/party/party.css b/party/static/party/party.css index 6b95262..25b9d42 100644 --- a/party/static/party/party.css +++ b/party/static/party/party.css @@ -897,3 +897,18 @@ button, input { font-family: inherit; } .rl-row .rl-icon { font-size: 1.8rem; } .rl-row b { display: block; } .rl-row span { font-size: .95rem; color: var(--muted); } + +/* ---------- nyt spil: vælg spørgsmålspakke ---------- */ +.new-game { display: flex; flex-direction: column; align-items: center; gap: 20px; } +.packs { display: flex; gap: 8px; margin: 0; padding: 0; border: 0; flex-wrap: wrap; justify-content: center; } +.packs legend { width: 100%; margin-bottom: 8px; color: var(--muted); font-weight: 600; } +.packs label { cursor: pointer; } +.packs input { position: absolute; opacity: 0; pointer-events: none; } +.packs span { display: inline-block; padding: 10px 20px; border-radius: 999px; font-weight: 700; background: var(--card); box-shadow: inset 0 0 0 2px var(--card-b); } +.packs input:checked + span { background: var(--yellow); color: var(--navy); box-shadow: 0 4px 0 var(--yellow-d); } +.packs input:focus-visible + span { outline: 3px solid #fff; outline-offset: 2px; } +.more-packs { width: 100%; margin-top: 6px; } +.more-packs summary { cursor: pointer; color: var(--muted); font-size: .95rem; list-style: none; } +.more-packs summary::-webkit-details-marker { display: none; } +.more-packs[open] summary { margin-bottom: 8px; } +.pack-hint { margin: 8px 0 0; font-size: .9rem; color: var(--muted); } diff --git a/party/static/party/sfx/boo__2.mp3 b/party/static/party/sfx/boo__2.mp3 new file mode 100644 index 0000000..e50d7fb Binary files /dev/null and b/party/static/party/sfx/boo__2.mp3 differ diff --git a/party/static/party/sfx/boo__3.mp3 b/party/static/party/sfx/boo__3.mp3 new file mode 100644 index 0000000..2738dc7 Binary files /dev/null and b/party/static/party/sfx/boo__3.mp3 differ diff --git a/party/static/party/sfx/cat_computerhistorie.mp3 b/party/static/party/sfx/cat_computerhistorie.mp3 new file mode 100644 index 0000000..b7b6972 Binary files /dev/null and b/party/static/party/sfx/cat_computerhistorie.mp3 differ diff --git a/party/static/party/sfx/cat_e_faktura.mp3 b/party/static/party/sfx/cat_e_faktura.mp3 new file mode 100644 index 0000000..3b248b1 Binary files /dev/null and b/party/static/party/sfx/cat_e_faktura.mp3 differ diff --git a/party/static/party/sfx/cat_harry_potter.mp3 b/party/static/party/sfx/cat_harry_potter.mp3 new file mode 100644 index 0000000..f9f3a6d Binary files /dev/null and b/party/static/party/sfx/cat_harry_potter.mp3 differ diff --git a/party/static/party/sfx/cat_it_sikkerhed.mp3 b/party/static/party/sfx/cat_it_sikkerhed.mp3 new file mode 100644 index 0000000..ab8a75f Binary files /dev/null and b/party/static/party/sfx/cat_it_sikkerhed.mp3 differ diff --git a/party/static/party/sfx/cat_laegevidenskab.mp3 b/party/static/party/sfx/cat_laegevidenskab.mp3 new file mode 100644 index 0000000..aedd0c2 Binary files /dev/null and b/party/static/party/sfx/cat_laegevidenskab.mp3 differ diff --git a/party/static/party/sfx/cat_ringenes_herre.mp3 b/party/static/party/sfx/cat_ringenes_herre.mp3 new file mode 100644 index 0000000..032efef Binary files /dev/null and b/party/static/party/sfx/cat_ringenes_herre.mp3 differ diff --git a/party/static/party/sfx/cat_star_wars.mp3 b/party/static/party/sfx/cat_star_wars.mp3 new file mode 100644 index 0000000..29f1900 Binary files /dev/null and b/party/static/party/sfx/cat_star_wars.mp3 differ diff --git a/party/static/party/sfx/coins__2.mp3 b/party/static/party/sfx/coins__2.mp3 new file mode 100644 index 0000000..98ce407 Binary files /dev/null and b/party/static/party/sfx/coins__2.mp3 differ diff --git a/party/static/party/sfx/explode__2.mp3 b/party/static/party/sfx/explode__2.mp3 new file mode 100644 index 0000000..ad26e21 Binary files /dev/null and b/party/static/party/sfx/explode__2.mp3 differ diff --git a/party/static/party/sfx/explode__3.mp3 b/party/static/party/sfx/explode__3.mp3 new file mode 100644 index 0000000..3754097 Binary files /dev/null and b/party/static/party/sfx/explode__3.mp3 differ diff --git a/party/static/party/sfx/house__2.mp3 b/party/static/party/sfx/house__2.mp3 new file mode 100644 index 0000000..09ea22c Binary files /dev/null and b/party/static/party/sfx/house__2.mp3 differ diff --git a/party/static/party/sfx/join__2.mp3 b/party/static/party/sfx/join__2.mp3 new file mode 100644 index 0000000..86e472c Binary files /dev/null and b/party/static/party/sfx/join__2.mp3 differ diff --git a/party/static/party/sfx/join__3.mp3 b/party/static/party/sfx/join__3.mp3 new file mode 100644 index 0000000..312390a Binary files /dev/null and b/party/static/party/sfx/join__3.mp3 differ diff --git a/party/static/party/sfx/like__2.mp3 b/party/static/party/sfx/like__2.mp3 new file mode 100644 index 0000000..b5796ca Binary files /dev/null and b/party/static/party/sfx/like__2.mp3 differ diff --git a/party/static/party/sfx/music_reveal__2.mp3 b/party/static/party/sfx/music_reveal__2.mp3 new file mode 100644 index 0000000..63985d4 Binary files /dev/null and b/party/static/party/sfx/music_reveal__2.mp3 differ diff --git a/party/static/party/sfx/music_think__2.mp3 b/party/static/party/sfx/music_think__2.mp3 new file mode 100644 index 0000000..220dfb0 Binary files /dev/null and b/party/static/party/sfx/music_think__2.mp3 differ diff --git a/party/static/party/sfx/music_think_computerhistorie.mp3 b/party/static/party/sfx/music_think_computerhistorie.mp3 new file mode 100644 index 0000000..ba5db3f Binary files /dev/null and b/party/static/party/sfx/music_think_computerhistorie.mp3 differ diff --git a/party/static/party/sfx/music_think_e_faktura.mp3 b/party/static/party/sfx/music_think_e_faktura.mp3 new file mode 100644 index 0000000..0b7ac65 Binary files /dev/null and b/party/static/party/sfx/music_think_e_faktura.mp3 differ diff --git a/party/static/party/sfx/music_think_harry_potter.mp3 b/party/static/party/sfx/music_think_harry_potter.mp3 new file mode 100644 index 0000000..bc3f229 Binary files /dev/null and b/party/static/party/sfx/music_think_harry_potter.mp3 differ diff --git a/party/static/party/sfx/music_think_it_sikkerhed.mp3 b/party/static/party/sfx/music_think_it_sikkerhed.mp3 new file mode 100644 index 0000000..269ba75 Binary files /dev/null and b/party/static/party/sfx/music_think_it_sikkerhed.mp3 differ diff --git a/party/static/party/sfx/music_think_laegevidenskab.mp3 b/party/static/party/sfx/music_think_laegevidenskab.mp3 new file mode 100644 index 0000000..a2f9f9e Binary files /dev/null and b/party/static/party/sfx/music_think_laegevidenskab.mp3 differ diff --git a/party/static/party/sfx/music_think_ringenes_herre.mp3 b/party/static/party/sfx/music_think_ringenes_herre.mp3 new file mode 100644 index 0000000..5ebe597 Binary files /dev/null and b/party/static/party/sfx/music_think_ringenes_herre.mp3 differ diff --git a/party/static/party/sfx/music_think_star_wars.mp3 b/party/static/party/sfx/music_think_star_wars.mp3 new file mode 100644 index 0000000..4b26024 Binary files /dev/null and b/party/static/party/sfx/music_think_star_wars.mp3 differ diff --git a/party/static/party/sfx/pop_in__2.mp3 b/party/static/party/sfx/pop_in__2.mp3 new file mode 100644 index 0000000..da6c56a Binary files /dev/null and b/party/static/party/sfx/pop_in__2.mp3 differ diff --git a/party/static/party/sfx/pop_in__3.mp3 b/party/static/party/sfx/pop_in__3.mp3 new file mode 100644 index 0000000..2c6f697 Binary files /dev/null and b/party/static/party/sfx/pop_in__3.mp3 differ diff --git a/party/static/party/sfx/stamp__2.mp3 b/party/static/party/sfx/stamp__2.mp3 new file mode 100644 index 0000000..6db7024 Binary files /dev/null and b/party/static/party/sfx/stamp__2.mp3 differ diff --git a/party/static/party/sfx/stamp__3.mp3 b/party/static/party/sfx/stamp__3.mp3 new file mode 100644 index 0000000..85063f0 Binary files /dev/null and b/party/static/party/sfx/stamp__3.mp3 differ diff --git a/party/static/party/sfx/submit__2.mp3 b/party/static/party/sfx/submit__2.mp3 new file mode 100644 index 0000000..32532ec Binary files /dev/null and b/party/static/party/sfx/submit__2.mp3 differ diff --git a/party/static/party/sfx/submit__3.mp3 b/party/static/party/sfx/submit__3.mp3 new file mode 100644 index 0000000..3d9f477 Binary files /dev/null and b/party/static/party/sfx/submit__3.mp3 differ diff --git a/party/static/party/sfx/truth__2.mp3 b/party/static/party/sfx/truth__2.mp3 new file mode 100644 index 0000000..d68d14b Binary files /dev/null and b/party/static/party/sfx/truth__2.mp3 differ diff --git a/party/static/party/sfx/whoosh__2.mp3 b/party/static/party/sfx/whoosh__2.mp3 new file mode 100644 index 0000000..f7ebb13 Binary files /dev/null and b/party/static/party/sfx/whoosh__2.mp3 differ diff --git a/party/static/party/sfx/whoosh__3.mp3 b/party/static/party/sfx/whoosh__3.mp3 new file mode 100644 index 0000000..c9d6f9d Binary files /dev/null and b/party/static/party/sfx/whoosh__3.mp3 differ diff --git a/party/templates/party/host_new.html b/party/templates/party/host_new.html index 0b09c13..019b654 100644 --- a/party/templates/party/host_new.html +++ b/party/templates/party/host_new.html @@ -4,7 +4,18 @@

Weirsøe Party Protocol

Fup og Fakta
-
{% csrf_token %} + {% csrf_token %} +
+ Spørgsmål + + + +
+ Flere valg… + +

Arbejdsspørgsmål: e-faktura, IT-sikkerhed og kategorier med pakken "arbejde".

+
+
{% if username %}

Logget ind som {{ username }}

{% endif %} diff --git a/party/tts.py b/party/tts.py index c879bcb..e6fb0e6 100644 --- a/party/tts.py +++ b/party/tts.py @@ -64,6 +64,10 @@ def _fetch(text: str, path: Path) -> None: tmp.replace(path) +def is_cached(text: str) -> bool: + return bool(text.strip()) and cache_path(_digest(text)).exists() + + def synth_sync(text: str) -> dict | None: """Til management-kommandoer: generér (eller find i cache) synkront.""" if not enabled() or not text.strip(): diff --git a/party/views.py b/party/views.py index 914b7a8..06f31ce 100644 --- a/party/views.py +++ b/party/views.py @@ -32,7 +32,8 @@ def play(request): def host_new_page(request): if not request.host_identity: return _forbidden() - return render(request, "party/host_new.html", {"username": request.host_identity.username}) + return render(request, "party/host_new.html", {"username": request.host_identity.username, + "work_pack_label": settings.WORK_PACK_LABEL}) @require_POST @@ -40,7 +41,7 @@ async def host_new(request): ident = request.host_identity if not ident: return _forbidden() - questions = await sync_to_async(load_game_questions)() + questions = await sync_to_async(load_game_questions)(request.POST.get("pack", "alle")) if not questions: return HttpResponse("Der er ingen spørgsmål i banken. Kør 'manage.py load_questions'.", status=503) room = create_room(questions, ident.username, settings.PUBLIC_URL) diff --git a/partyhub/settings.py b/partyhub/settings.py index 9bea75a..7288ae1 100644 --- a/partyhub/settings.py +++ b/partyhub/settings.py @@ -36,6 +36,9 @@ TTS_STYLE = float(env("TTS_STYLE", "0.7")) # højere = mere udtryk TTS_SIMILARITY = float(env("TTS_SIMILARITY", "0.8")) # Spilhjernen (valgfri, udbyder-agnostisk, se party/brain/providers.py): anthropic | openai | ollama +# Navnet på arbejdspakken på "nyt spil"-siden (pakken "arbejde" er aldrig med i "Alle") +WORK_PACK_LABEL = env("WORK_PACK_LABEL", "Arbejde") + BRAIN_PROVIDER = env("BRAIN_PROVIDER", "") BRAIN_MODEL = env("BRAIN_MODEL", "") BRAIN_API_KEY = env("BRAIN_API_KEY", "")