init: initial commit

- ticker / QR ad overlay / break slide graphics (1920×1080) with all
  geometry derived from one shared module (src/shared/obs-geometry.mjs)
- OBS scene-collection generator (scripts/generate-obs-scenes.mjs) and a
  read-only in-dashboard setup verifier, both driven by the same module
- en/sr dashboard i18n selected via bundle config; configschema.json with
  neutral first-run defaults seeded from optional branding config
- install.sh / systemd user service / update.sh for venue deployment
- reference OBS scene collection + profile from a real venue as fixtures
This commit is contained in:
2026-07-15 17:43:05 +02:00
commit 4bb64a8ca3
71 changed files with 18186 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
import type { Strings } from "./en";
/** Serbian (latinica). */
export const sr: Strings = {
common: {
loading: "Učitavanje…",
},
ticker: {
settings: "Podešavanja",
loopBlurbLabel: "Stalna poruka (na svakom prelazu)",
separatorLabel: "Separator",
defaultTtlLabel: "Podraz. trajanje (s)",
speedLabel: "Brzina (px/s)",
newMessage: "Nova poruka",
messagePlaceholder: "Tekst poruke…",
ttlTitle: "Trajanje u sekundama (prazno = podrazumevano)",
permanentTitle: "Poruka bez isteka — uklanja se samo ručno",
permanent: "Stalna",
add: "Dodaj",
activeMessages: "Aktivne poruke",
noMessages: "Nema aktivnih poruka — prikazuje se samo stalna poruka.",
clickToEdit: "Klikni za izmenu teksta",
edit: "Izmeni",
refresh: "Obnovi",
remove: "Ukloni",
},
ads: {
none: "Nema reklama.",
rowTextPlaceholder: "Tekst — traka (široki deo)…",
columnTextPlaceholder: "Tekst — kolona (uski deo)…",
columnImageTitle: "Slika u koloni (dodaj slike kroz Assets dijalog)",
noColumnImage: "Bez slike u koloni",
missingImage: "(nedostaje)",
enabled: "Uključena",
delete: "Obriši",
addAd: "+ Nova reklama",
},
choreo: {
obsSection: "OBS",
connectedScene: "Povezan — scena:",
notConnected: "Nije povezan",
attempt: (n: number) => ` (pokušaj #${n})`,
stateSection: "Stanje",
modeBreak: "Pauza",
modeLive: "Program",
phaseAd: "Reklama",
phaseLive: "Uživo",
nextTransitionIn: "sledeći prelaz za",
showAdNow: "Prikaži reklamu sada",
skipAd: "Preskoči reklamu",
breakOn: "PAUZA: UKLJUČI",
breakOff: "PAUZA: ISKLJUČI",
breakSlideSection: "Najava (slajd pauze)",
headingLabel: "Naslov",
nextActNameLabel: "Sledeći nastup",
nextActFromLabel: "Odakle su",
logoLabel: "Logo benda",
logoAuto: "Automatski (prva slika)",
logoSizeLabel: (px: number) => `Veličina logoa (${px}px)`,
invertLogo: "Invertuj boje logoa (za taman logo na tamnoj pozadini)",
timingSection: "Tajming",
adIntervalLabel: "Interval reklama (min)",
adDurationLabel: "Trajanje reklame (s)",
breakGapLabel: "Pauza: razmak (s)",
breakAdDurationLabel: "Pauza: trajanje reklame (s)",
breakAdsPerBurstLabel: "Pauza: reklama po turi",
},
obsCheck: {
run: "Pokreni provere",
running: "Proveravam…",
allGood: "sve je u redu ✓",
intro:
"Proverava OBS podešavanje u odnosu na ono što grafika očekuje: scene, izvore, transformacije, prelaze.",
fixPrefix: "Rešenje:",
status: {
pass: "ok",
warn: "pažnja",
fail: "greška",
skip: "presk.",
},
},
seed: {
loopBlurb: "Dobro došli ♪",
sampleAdRow: "Zapratite nas na mrežama!",
sampleAdColumn: "Skenirajte QR kod 📱",
breakHeading: "Čekajte, ima još!",
},
};