2835f78635
Replace the single signed-± cash_movement with two distinct financial documents — the direction is the event TYPE, not the sign of an amount: cash_in = Mandat Arkëtimi (receipt / pay-IN, +) voucher AR-NNNN cash_out = Mandat Pagese (disbursement / pay-OUT, −) voucher PA-NNNN Each carries a positive magnitude, voucher number, reason, the operator who raised it and the admin who authorized it, and prints an Albanian slip. Authorization changes from admin-only to operator-RAISED / admin-AUTHORIZED: any shift:create holder raises the voucher, but POST /api/cash-voucher only commits when authorizedBy is a real admin (shift:cash) re-entering their password (verified server-side). Keeps the float control while letting the operator do the booth paperwork. Legacy cash_movement events are kept — they still verify and still fold into the drawer (signed-±); the append-only chain is never rewritten. The drawer fold and the Z-report window now sum all three types. Verified against a copy of the live DB with the real signing modules: cash_in 3000 + cash_out 5000 → drawer −2000, hash-chain verifies OK. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
668 lines
26 KiB
TypeScript
668 lines
26 KiB
TypeScript
// Albanian (sq) — the DEFAULT and fallback language. Customer/operator-facing copy.
|
||
// Keys are dot-namespaced by area (common, nav, booth, …). When adding a string,
|
||
// add it here first (the fallback), then mirror the key in en.ts.
|
||
// See wiki/concepts/i18n.md.
|
||
|
||
export const sq = {
|
||
common: {
|
||
loading: "Duke u ngarkuar…",
|
||
logout: "Dil",
|
||
cancel: "Anulo",
|
||
close: "Mbyll",
|
||
save: "Ruaj",
|
||
none: "—",
|
||
themeDark: "errët",
|
||
themeLight: "çelët",
|
||
theme: "Tema",
|
||
today: "Sot",
|
||
yesterday: "Dje",
|
||
// Month names (index 0 = January) — kept in the catalog because the appliance's
|
||
// browser ICU may lack Albanian locale data (Intl falls back to English).
|
||
months: [
|
||
"Janar",
|
||
"Shkurt",
|
||
"Mars",
|
||
"Prill",
|
||
"Maj",
|
||
"Qershor",
|
||
"Korrik",
|
||
"Gusht",
|
||
"Shtator",
|
||
"Tetor",
|
||
"Nëntor",
|
||
"Dhjetor",
|
||
],
|
||
},
|
||
auth: {
|
||
title: "Sistemi i Parkimit",
|
||
username: "Përdoruesi",
|
||
password: "Fjalëkalimi",
|
||
signIn: "Hyr",
|
||
signingIn: "Duke hyrë…",
|
||
},
|
||
nav: {
|
||
booth: "Kabina",
|
||
shift: "Turni",
|
||
setup: "Konfigurimi",
|
||
devices: "Pajisjet",
|
||
tariff: "Tarifa",
|
||
tariffLab: "Lab Tarife",
|
||
subscriptions: "Abonimet",
|
||
site: "Park",
|
||
users: "Përdoruesit",
|
||
roles: "Rolet",
|
||
shifts: "Turnet",
|
||
logs: "Loget",
|
||
},
|
||
status: {
|
||
live: "LIVE",
|
||
connecting: "DUKE U LIDHUR",
|
||
offline: "JASHTË LINJE",
|
||
},
|
||
devices: {
|
||
footerTitle: "Pajisjet",
|
||
none: "Asnjë pajisje e konfiguruar.",
|
||
catAccess: "Rele",
|
||
catReader: "Lexuesi",
|
||
catCamera: "Kamera",
|
||
catPrinter: "Printer",
|
||
catVision: "ANPR",
|
||
// Role/direction suffixes for the chip label (e.g. "Lexuesi hyrje").
|
||
role: {
|
||
entry: "hyrje",
|
||
exit: "dalje",
|
||
both: "hyrje/dalje",
|
||
mixed: "hyrje/dalje",
|
||
lane: "në korsi",
|
||
booth: "në kabinë",
|
||
},
|
||
state: {
|
||
ready: "gati",
|
||
degraded: "i dëmtuar",
|
||
offline: "jashtë linje",
|
||
},
|
||
allOk: "të gjitha gati",
|
||
issuesCount: "{{count}} me probleme",
|
||
issuesTitle: "Problemet e pajisjeve",
|
||
clickForIssues: "Kliko për detajet",
|
||
checkedAt: "kontrolluar {{time}}",
|
||
},
|
||
booth: {
|
||
processTicket: "Proceso biletën",
|
||
scanPlaceholder: "Skano ose shkruaj numrin e biletës…",
|
||
open: "Hap",
|
||
occupancy: "Prania",
|
||
occUnavailable: "zënia e padisponueshme",
|
||
inside: "brenda",
|
||
of: "nga",
|
||
uncapped: "pa kufi",
|
||
free: "Vende të lira",
|
||
lotFull: "● parkimi plot",
|
||
liveFeed: "Aktiviteti live",
|
||
events: "Evente",
|
||
noEventsYet: "Asnjë event ende — hyrjet dhe daljet do të shfaqen këtu.",
|
||
activeSessions: "Sesionet aktive",
|
||
insideCount: "brenda",
|
||
noActiveSessions: "Asnjë sesion aktiv.",
|
||
noMatch: "Asnjë rezultat për filtrin.",
|
||
badgeOverstay: "tej afatit",
|
||
badgeOverstayTitle:
|
||
"Sesion i paguar. Klienti nuk doli brënda afatit kohor. Ka filluar një periudhë e re tarifimi.",
|
||
plateTitle: "Targa e njohur nga kamera (orientuese — nuk është vendim aksesi).",
|
||
// filtra
|
||
filterSearchSessions: "Kërko biletë / abonent / targë…",
|
||
filterSearchFeed: "Kërko event / identitet / targë…",
|
||
filterAll: "Të gjitha",
|
||
fStatusUnpaid: "Papaguar",
|
||
fStatusPaid: "Paguar",
|
||
fStatusExiting: "Duke dalë",
|
||
fStatusOverstay: "Tej afatit",
|
||
fKindTransient: "Kalimtarë",
|
||
fKindSubscription: "Abonentë",
|
||
fDirEntry: "Hyrje",
|
||
fDirExit: "Dalje",
|
||
fSrcBooth: "Kabinë",
|
||
fSrcReader: "Lexues",
|
||
fEvtEntry: "Hyrje",
|
||
fEvtExit: "Dalje",
|
||
fEvtPay: "Pagesë",
|
||
fEvtVoid: "Anulim",
|
||
fEvtAnomaly: "Anomali",
|
||
openPayExit: "Hap pagesën / daljen",
|
||
openBarrier: "Hap barrierën",
|
||
openBarrierTitle: "Hap barrierën manualisht",
|
||
barrierOpened: "barriera u hap",
|
||
openManually: "hape me dorë",
|
||
// session row badges
|
||
badgeExiting: "duke dalë",
|
||
badgePaid: "paguar",
|
||
badgeUnpaid: "papaguar",
|
||
badgeSubscription: "abonim",
|
||
// event types (live feed labels)
|
||
evtEntry: "HYRJE",
|
||
evtExit: "DALJE",
|
||
evtPay: "PAGESË",
|
||
evtVoid: "ANULIM",
|
||
evtOpenCmd: "HAP→",
|
||
evtOpenObserved: "HAP✓",
|
||
evtShiftOpen: "TURN+",
|
||
evtShiftZ: "TURN Z",
|
||
evtCashMovement: "ARKË",
|
||
evtCashIn: "ARKËTIM",
|
||
evtCashOut: "PAGESË",
|
||
evtAnomaly: "ANOMALI",
|
||
// rreshti i detajeve të eventit live + etiketat e klasifikimit (nga payload)
|
||
evtNoReason: "pa arsye të regjistruar",
|
||
badgeEntryRefused: "hyrje e refuzuar",
|
||
badgeExitRefused: "dalje e refuzuar",
|
||
badgeLotFull: "parkimi plot",
|
||
badgeBarrierFailed: "barriera nuk u hap",
|
||
badgeManualOpen: "hapje manuale",
|
||
badgeSubRefused: "abonimi u refuzua",
|
||
badgeSubSale: "shitje abonimi",
|
||
badgeNoTicket: "bileta nuk u printua",
|
||
feedSourceBooth: "kabinë",
|
||
feedSourceReader: "lexues",
|
||
// dritarja e detajeve të eventit
|
||
eventDetail: "Detajet e eventit",
|
||
edType: "Lloji",
|
||
edTime: "Ora",
|
||
edIndex: "Indeksi në regjistër",
|
||
edDirection: "Drejtimi",
|
||
edSource: "Burimi",
|
||
edIdentity: "Identiteti",
|
||
edReason: "Arsyeja",
|
||
edSnapshots: "Fotot",
|
||
edPayload: "Të dhënat e nënshkruara",
|
||
edChain: "Zinxhiri",
|
||
edSignature: "Nënshkrimi",
|
||
edKeyId: "Çelësi",
|
||
edPrevHash: "Hash-i i mëparshëm",
|
||
edNoPayload: "Ky event nuk ka të dhëna shtesë.",
|
||
edCopy: "Kopjo",
|
||
edCopied: "U kopjua",
|
||
edDetails: "Detajet",
|
||
edAuditData: "Të dhënat e auditimit (nënshkrimi & zinxhiri)",
|
||
edAmount: "Shuma",
|
||
edTender: "Mënyra e pagesës",
|
||
edSession: "Sesioni",
|
||
edPlate: "Targa",
|
||
edCategory: "Kategoria",
|
||
edOperator: "Operatori",
|
||
edTariffVersion: "Versioni i tarifës",
|
||
edRawPayload: "Të dhënat e papërpunuara të nënshkruara",
|
||
edOccurrence: "ID e hyrjes",
|
||
subscriber: "Abonent",
|
||
edVia: "Mënyra e hyrjes",
|
||
viaQr: "Kod QR",
|
||
viaCard: "Kartë/çip RFID",
|
||
viaPlate: "Targë",
|
||
},
|
||
// Mesazhet e përkthyera për REASON_CODES e nënshkruara (shih @parking/shared).
|
||
// Çelësat përputhen 1:1 me kodet; {{param}} mbushet nga reasonParams i eventit.
|
||
reason: {
|
||
"entry.refused.full": "Hyrja u refuzua — parkimi plot ({{count}}/{{capacity}})",
|
||
"entry.held.noTicket": "Hyrja u mbajt — bileta nuk u printua: {{detail}}",
|
||
"exit.refused.closed": "Dalja u refuzua — sesioni është mbyllur tashmë",
|
||
"exit.refused.noSession": "Dalja u refuzua — biletë e panjohur",
|
||
"exit.refused.unpaid": "Dalja u refuzua — e papaguar (bëj pagesën në fillim)",
|
||
"exit.refused.graceExpired": "Dalja u refuzua — afati i daljes skadoi (kërkohet pagesë shtesë)",
|
||
"exit.open.noBarrier": "Dalja u regjistrua, por nuk ka barrierë daljeje të konfiguruar — hape me dorë",
|
||
"exit.open.unavailable": "Dalja u regjistrua, por barriera është e padisponueshme — hape me dorë",
|
||
"exit.open.failed": "Dalja u regjistrua, por barriera nuk u hap — hape me dorë",
|
||
"exit.freeGrace": "Periudhë pa pagesë në hyrje (pa tarifë)",
|
||
"exit.manualOpen": "Hapje manuale e barrierës (ndërhyrje njerëzore)",
|
||
"sub.refused.notFound": "Abonimi u refuzua — nuk u gjet",
|
||
"sub.refused.outOfWindow": "Abonimi u refuzua — {{status}}/jashtë afatit",
|
||
"sub.refused.noSession": "Dalje me abonim pa sesion të hapur (tashmë jashtë / nuk ka hyrë kurrë)",
|
||
"sub.refused.atCapacity": "Abonimi u refuzua — në kapacitet ({{inUse}}/{{max}} makina brenda)",
|
||
},
|
||
tariff: {
|
||
title: "Tarifa",
|
||
noRateCard: "Asnjë tarifë e publikuar — arka nuk mund të faturojë derisa të publikoni një.",
|
||
activeSince: "Aktive që nga {{date}} · {{count}} version(e) në histori. Publikimi krijon një version të ri; sesionet e kaluara ruajnë çmimin origjinal.",
|
||
currency: "Monedha",
|
||
freeEntryGrace: "Periudha pa pagesë në hyrje (min)",
|
||
billingIncrement: "Intervali i faturimit (min)",
|
||
dailyCap: "Kufiri ditor (bosh = pa kufi)",
|
||
dailyCapPh: "p.sh. 12.00",
|
||
lostTicketFee: "Tarifa për biletë të humbur",
|
||
exitGrace: "Periudha e kthimit në dalje (min)",
|
||
rateBlocks: "Blloqet tarifore",
|
||
rateBlocksHint: "Çdo brez zgjat një numër orësh dhe faturohet me çmimin e tij; brezat konsumohen me radhë (orët e para, pastaj orët në vijim). Brezi i fundit është \"më pas\" (i hapur) — çmimi i tij zbatohet pas mbarimit të shkallës. Çmimi është për interval faturimi.",
|
||
bandDuration: "Kohëzgjatja e brezit",
|
||
hoursUnit: "orë",
|
||
egHours: "p.sh. 2",
|
||
pricePerIncrement: "Çmimi / interval",
|
||
thereafter: "më pas (i hapur)",
|
||
remove: "Hiq",
|
||
addBlock: "+ Shto bllok",
|
||
publishNewVersion: "Publiko version të ri",
|
||
publishing: "Duke publikuar…",
|
||
publishedOk: "U publikua versioni i ri i tarifës — tani është tarifa aktive.",
|
||
defaultCard: "Tarifa bazë (gjithmonë aktive)",
|
||
defaultCardHint: "Çmimi bazë i zbatuar kur asnjë nivel kohor/sezonal nuk vlen. Kjo e vetme është mjaftueshëm për shumicën e parkimeve.",
|
||
modeLadder: "Shkallë orësh",
|
||
modeFlat: "Çmim fiks",
|
||
modeStepped: "Sipas kohëzgjatjes (deri-në)",
|
||
steppedHint:
|
||
"Vendos çmimin TOTAL për një qëndrim deri në një kohë të caktuar (p.sh. deri 3 orë = 500). Fiton rreshti i parë me kufi ≥ kohëzgjatjes (kufiri përfshihet). Totali i rreshtit të fundit përsëritet si çmim ditor për qëndrime më të gjata.",
|
||
stepUpTo: "Deri në",
|
||
stepTotal: "Çmimi total",
|
||
addStep: "+ Shto rresht",
|
||
steppedTiersConflict:
|
||
"⚠ Nivelet kohore/sezonale NUK zbatohen kur tarifa bazë është 'Sipas kohëzgjatjes (deri-në)' — motori i shpërfill plotësisht. Hiqi nivelet, ose ndrysho tarifën bazë në 'Shkallë orësh' a 'Çmim fiks'. Publikimi bllokohet derisa kjo të rregullohet.",
|
||
tiersAdvanced: "Të avancuara: nivele kohore & sezonale",
|
||
tiersHint: "Opsionale. Shto nivele tarifore që vlejnë vetëm në orë/ditë/data ose kategori të caktuara (p.sh. orë e lirë, tarifë nate, fundjavë, autobus). Pa nivele, publikohet vetëm tarifa bazë.",
|
||
tierName: "Emri",
|
||
tierPriority: "Përparësia",
|
||
tierCategory: "Kategoria",
|
||
tierCategoryPh: "p.sh. autobus",
|
||
tierDays: "Ditët",
|
||
tierHours: "Orët",
|
||
tierDates: "Datat",
|
||
tierOvernight: "(kalon mesnatën)",
|
||
addTier: "+ Shto nivel",
|
||
dow1: "Hën",
|
||
dow2: "Mar",
|
||
dow3: "Mër",
|
||
dow4: "Enj",
|
||
dow5: "Pre",
|
||
dow6: "Sht",
|
||
dow0: "Die",
|
||
},
|
||
setup: {
|
||
title: "Konfigurimi",
|
||
intro:
|
||
"Shto fillimisht kontrolluesit e barrierave — cakto cili rele është hyrje/dalje dhe në cilin terminal është lidhur butoni i hyrjes. Pastaj shto lexues, kamera dhe printera dhe drejto secilin te barriera që shërben.",
|
||
// Category titles + the singular noun used in buttons/modal titles.
|
||
catControllers: "Kontrolluesit (barrierat + butoni i hyrjes)",
|
||
catReaders: "Lexuesit (QR / RFID)",
|
||
catCameras: "Kamerat (foto + targë)",
|
||
catPrinters: "Printerat (bileta / vouchera)",
|
||
nounController: "kontrollues",
|
||
nounReader: "lexues",
|
||
nounCamera: "kamerë",
|
||
nounPrinter: "printer",
|
||
add: "+ Shto {{noun}}",
|
||
addAnother: "+ Shto edhe një {{noun}}",
|
||
addTitle: "Shto {{noun}}",
|
||
editTitle: "Ndrysho {{noun}}",
|
||
needControllerFirst: "Shto fillimisht një kontrollues — {{noun}} drejtohet te një prej releve të tij.",
|
||
failedToLoad: "Ngarkimi i konfigurimit dështoi: {{error}}",
|
||
loadingCatalog: "Duke ngarkuar katalogun e pajisjeve…",
|
||
// Direction labels (relay direction + inherited binding).
|
||
dirEntry: "Hyrje",
|
||
dirExit: "Dalje",
|
||
dirBoth: "Hyrje + dalje",
|
||
inherits: "trashëgon {{direction}}",
|
||
// Warnings panel.
|
||
warnTitle: "⚠ U ruajt, por nevojitet veprim:",
|
||
dismiss: "Mbyll",
|
||
// Assignment row.
|
||
disabled: "(çaktivizuar)",
|
||
edit: "Ndrysho",
|
||
remove: "Hiq",
|
||
removing: "Duke hequr…",
|
||
confirmRemove: "Të hiqet kjo pajisje {{driver}}?",
|
||
noRelaysSet: "asnjë rele e caktuar",
|
||
unbound: "e palidhur",
|
||
// Device form.
|
||
noDrivers: "Asnjë drejtues i regjistruar.",
|
||
chooseDevice: "Zgjidh një pajisje…",
|
||
scan: "Skano për kontrollues",
|
||
scanning: "Duke skanuar…",
|
||
noControllersFound: "Asnjë kontrollues në LAN.",
|
||
use: "Përdor",
|
||
test: "Testo lidhjen",
|
||
testing: "Duke testuar…",
|
||
saveConfigure: "Ruaj & konfiguro",
|
||
saveChanges: "Ruaj ndryshimet",
|
||
saving: "Duke ruajtur…",
|
||
cancel: "Anulo",
|
||
testFailed: "Testi dështoi: {{error}}",
|
||
saveFailed: "Ruajtja dështoi: {{error}}",
|
||
deviceLabel: "Pajisja:",
|
||
preconditionsOk: "● parakushtet OK",
|
||
autoFixedOnSave: "(rregullohet vetë në ruajtje)",
|
||
backendPushIp: "IP-ja e backend-it",
|
||
chooseAddress: "Zgjidh një adresë…",
|
||
onDeviceSubnet: "— në subnetin e pajisjes",
|
||
noNicOnSubnet: "⚠ asnjë NIC në subnetin e pajisjes — pajisja mund të mos arrijë backend-in",
|
||
backendIpHint: "Adresa te e cila kjo pajisje do të dërgojë eventet e hyrjes.",
|
||
// Relay editor.
|
||
relaysTitle: "Relet në këtë kontrollues",
|
||
relaysHint:
|
||
"Çdo rele hap një barrierë. Cakto drejtimin e saj; për hyrje kalimtare, cakto në cilin terminal hyrës është lidhur butoni i hyrjes.",
|
||
relay: "Rele",
|
||
entryButtonTerminal: "Butoni i hyrjes në terminalin",
|
||
presenceInput: "Sensori i pranisë (terminali)",
|
||
presenceInputHint:
|
||
"Terminali hyrës ku është lidhur sensori/laku i pranisë së automjetit. Kur vendoset, lëshohet vetëm NJË biletë për automjet: butoni printon vetëm kur ka makinë, dhe nuk lëshon biletë të dytë derisa laku të lirohet (makina hyri) dhe një makinë e re ta zërë. Mënyra e preferuar.",
|
||
entryCooldown: "Pritje pas biletës (sek)",
|
||
entryCooldownHint:
|
||
"Kur nuk ka sensor pranie: shtypjet e përsëritura të butonit shtypen për kaq sekonda pas një bilete. Zgjidhje rezervë (jo garanci) — një abuzues mund ta presë afatin.",
|
||
addRelay: "+ Shto rele",
|
||
// Camera ANPR opt-in.
|
||
anpr: "Njohja e targave (ANPR)",
|
||
anprHint:
|
||
"Aktivizo që ky aparat të skanojë targat: shërbimi i vizionit lexon targën nga pamja dhe e dërgon si lexim (vetëm këshillues — nuk hap vetë barrierën). Kërkon shërbimin e vizionit aktiv.",
|
||
// Binding picker.
|
||
whichBarrier: "Cilën barrierë shërben kjo pajisje?",
|
||
controller: "Kontrolluesi",
|
||
choose: "Zgjidh…",
|
||
relayLabel: "Rele {{relay}} ({{direction}})",
|
||
noRelaysConfigured: "Ky kontrollues nuk ka rele të konfiguruar.",
|
||
},
|
||
lab: {
|
||
title: "Lab Tarife",
|
||
intro:
|
||
"Testo tarifat në kohë (dritare ditë/natë, kufi ditor, qëndrim tej afatit) në sekonda, pa pritur orë. Çmimi llogaritet me të njëjtën logjikë si kabina; nuk shkruhet asgjë në ledger.",
|
||
loadTicket: "Ngarko nga një biletë reale",
|
||
loadTicketPh: "Numri i biletës / identiteti",
|
||
load: "Ngarko",
|
||
loaded: "U ngarkua sesioni {{id}}",
|
||
tariffVersion: "Versioni i tarifës",
|
||
activeVersion: "Versioni aktiv (i tanishëm)",
|
||
entered: "Hyrja",
|
||
asOf: "Deri më (tani/dalja)",
|
||
now: "Tani",
|
||
category: "Kategoria",
|
||
categoryPh: "p.sh. bus (bosh = makinë)",
|
||
payment: "Pagesa",
|
||
paid: "u pagua",
|
||
graceMin: "afati (min)",
|
||
price: "Llogarit çmimin",
|
||
pricing: "Duke llogaritur…",
|
||
outcome: "Rezultati",
|
||
amountDue: "Shuma për pagesë",
|
||
billedPeriod: "Periudha e faturuar",
|
||
overstay: "tej afatit",
|
||
settled: "i shlyer",
|
||
periodStart: "Fillimi i periudhës",
|
||
graceExpires: "Afati skadon",
|
||
curve: "Kurba sipas kohëzgjatjes",
|
||
curveHint: "Tarifa nga hyrja për disa kohëzgjatje — shih ku rrafshohet kufiri ditor ose ndryshojnë dritaret.",
|
||
},
|
||
subs: {
|
||
title: "Abonimet",
|
||
unnamed: "(pa emër)",
|
||
unbound: "pa kufizim",
|
||
car_one: "{{count}} makinë",
|
||
car_other: "{{count}} makina",
|
||
cred: "kredencial",
|
||
plates: "{{count}} targë(a)",
|
||
noPrice: "pa çmim",
|
||
perMonth: "muaj",
|
||
monthlyPrice: "Çmimi mujor",
|
||
pricePlaceholder: "p.sh. 10000",
|
||
tender: "Paguar me",
|
||
tenderCash: "Para në dorë",
|
||
tenderCard: "Kartë",
|
||
tenderHint: "Regjistrohet si pagesë e nënshkruar (aktiviteti, arka, raporti i turnit).",
|
||
saleRecorded: "Shitja u regjistrua: {{amount}} {{currency}} ({{tender}}).",
|
||
saleNoShift: "⚠ Asnjë turn i hapur — hapni një që arkëtimi të hyjë në një raport turni.",
|
||
edit: "Ndrysho",
|
||
revoke: "Anulo",
|
||
delete: "Fshij",
|
||
noneYet: "Asnjë abonim ende.",
|
||
add: "+ Shto abonim",
|
||
new: "Abonim i ri",
|
||
editTitle: "Ndrysho abonimin",
|
||
holderName: "Emri i mbajtësit",
|
||
contact: "Kontakti",
|
||
carLimit: "Kufiri i makinave",
|
||
limitCarsInAtOnce: "kufizo makinat brenda njëkohësisht",
|
||
validFrom: "Vlen nga",
|
||
validTo: "Vlen deri",
|
||
months: "Muaj",
|
||
monthsHint: "muaj të paguar",
|
||
coverageHint: "deri më {{end}}",
|
||
totalDue: "gjithsej {{total}}",
|
||
validToOverride: "Vlen deri (manual)",
|
||
isoDateOptional: "Datë ISO (opsionale)",
|
||
boundPlates: "Targat e lidhura",
|
||
commaSeparatedOptional: "të ndara me presje (opsionale)",
|
||
credentials: "Kredencialet",
|
||
credentialsCardQr: "Kredencialet (kartë / QR)",
|
||
rfCardTag: "Kartë/Tag RF",
|
||
rfCardTagSoon: "Kartë/Tag RF (së shpejti)",
|
||
rfPlaceholder: "numri i kartës (ose lexo kartën)",
|
||
readCard: "Lexo kartën",
|
||
captureChooseReader: "Zgjidh lexuesin, pastaj afro kartën:",
|
||
captureNoReaders: "Asnjë lexues i konfiguruar.",
|
||
captureWaiting: "Afro kartën te lexuesi…",
|
||
captureTimeout: "Skadoi pa lexuar kartë. Provo sërish.",
|
||
captured: "Karta u lexua: {{value}}",
|
||
qr: "QR",
|
||
qrAutoGen: "kodi QR gjenerohet automatikisht në ruajtje",
|
||
credentialValue: "vlera e kredencialit",
|
||
addCredential: "+ kredencial",
|
||
needCredentialOrPlate: "Një abonim kërkon të paktën një kredencial OSE një targë të lidhur.",
|
||
save: "Ruaj",
|
||
cancel: "Anulo",
|
||
saved: "Abonimi u ruajt.",
|
||
savedPrinted: "Abonimi u ruajt — kodi QR u printua.",
|
||
savedPrintFailed: "Abonimi u ruajt, por printimi dështoi ({{error}}). Përdor \"Printo kodin\".",
|
||
printCode: "Printo kodin",
|
||
printedOn: "Kodi u printua te {{printer}}.",
|
||
confirmRevoke: "Të anulohet abonimi për {{name}}? Do të refuzohet te barriera.",
|
||
confirmDelete: "Të fshihet abonimi për {{name}}? (t e kaluara ruhen.)",
|
||
statusActive: "aktiv",
|
||
statusSuspended: "pezulluar",
|
||
statusRevoked: "anuluar",
|
||
},
|
||
site: {
|
||
occupancy: "Prania:",
|
||
noCapacitySet: "(pa kapacitet të caktuar)",
|
||
free: "lirë",
|
||
full: "PLOT",
|
||
capacityLabel: "Kapaciteti (bosh = pa kufi):",
|
||
capacityPlaceholder: "p.sh. 120",
|
||
printExitDefault: "Printo biletën e daljes si parazgjedhje",
|
||
printExitHint: "(kabina larg daljes → klienti del vetë me biletë)",
|
||
parkDetails: "Të dhënat e parkimit (opsionale — shfaqen në bileta/fatura)",
|
||
save: "Ruaj",
|
||
saved: "U ruajt.",
|
||
fieldParkName: "Emri i parkimit",
|
||
fieldParkNamePh: "p.sh. Acme Parking",
|
||
fieldOperator: "Operatori (emri ligjor)",
|
||
fieldOperatorPh: "kompania operuese",
|
||
fieldNius: "NIUS",
|
||
fieldNiusPh: "p.sh. L01234567A",
|
||
fieldAddress: "Adresa",
|
||
fieldPhone: "Telefoni",
|
||
fieldEmail: "Email",
|
||
},
|
||
users: {
|
||
title: "Përdoruesit",
|
||
add: "+ Shto përdorues",
|
||
new: "Përdorues i ri",
|
||
none: "Asnjë përdorues.",
|
||
username: "Përdoruesi",
|
||
password: "Fjalëkalimi",
|
||
passwordHint: "Të paktën 8 karaktere.",
|
||
newPassword: "fjalëkalim i ri",
|
||
role: "Roli",
|
||
resetPassword: "Rivendos fjalëkalimin",
|
||
edit: "Ndrysho",
|
||
editTitle: "Ndrysho përdoruesin",
|
||
save: "Ruaj",
|
||
delete: "Fshi",
|
||
confirmDelete: "Të fshihet përdoruesi \"{{name}}\"?",
|
||
// Optional profile metadata.
|
||
detailsSection: "Të dhënat (opsionale)",
|
||
fullName: "Emri i plotë",
|
||
phone: "Telefoni",
|
||
email: "Email",
|
||
address: "Adresa",
|
||
},
|
||
roles: {
|
||
title: "Rolet",
|
||
add: "+ Shto rol",
|
||
new: "Rol i ri",
|
||
editTitle: "Ndrysho rolin",
|
||
name: "Emri",
|
||
permissions: "Lejet",
|
||
builtin: "i integruar",
|
||
edit: "Ndrysho",
|
||
delete: "Fshi",
|
||
confirmDelete: "Të fshihet roli \"{{name}}\"?",
|
||
permCount_one: "{{count}} leje",
|
||
permCount_other: "{{count}} leje",
|
||
userCount_one: "{{count}} përdorues",
|
||
userCount_other: "{{count}} përdorues",
|
||
},
|
||
shift: {
|
||
label: "Turni:",
|
||
open: "hapur",
|
||
notStarted: "i panisur",
|
||
since: "që nga",
|
||
startShift: "Fillo turnin",
|
||
starting: "Duke filluar…",
|
||
endShift: "Mbyll turnin",
|
||
ending: "Duke mbyllur…",
|
||
drawer: "Arka:",
|
||
openingFloatInherited: "(bilanci fillestar i trashëguar nga turni i mëparshëm)",
|
||
drawerCashAdmin: "Para në arkë (admin) — shto ose hiq bilancin",
|
||
drawerVoucher: "Mandat arke — operatori e hap, admini e autorizon",
|
||
amount: "shuma",
|
||
reasonPlaceholder: "arsyeja (p.sh. bilanci fillestar)",
|
||
load: "Shto +",
|
||
remove: "Hiq −",
|
||
authName: "përdoruesi i adminit",
|
||
authPassword: "fjalëkalimi i adminit",
|
||
authRequired: "Një admin duhet ta autorizojë: shkruaj përdoruesin dhe fjalëkalimin e tij.",
|
||
mandatArketimi: "Arkëtim (hyrje) +",
|
||
mandatPagese: "Pagesë (dalje) −",
|
||
voucherHint: "Mandat Arkëtimi shton para; Mandat Pagese heq para. Arka lëviz vetëm me autorizimin e një admini.",
|
||
voucherRecorded: "Mandati {{no}} u regjistrua. Arka tani {{amount}}.",
|
||
enterPositive: "Shkruaj një shumë pozitive.",
|
||
drawerNow: "Arka tani {{amount}}.",
|
||
zReport: "RAPORT Z",
|
||
payments: "Pagesa:",
|
||
cash: "Para:",
|
||
card: "Kartë:",
|
||
drawerSection: "— Arka —",
|
||
openingFloat: "Bilanci fillestar:",
|
||
cashTaken: "Para të marra:",
|
||
cashAdded: "Para të shtuara:",
|
||
cashRemoved: "Para të hequra:",
|
||
expectedDrawer: "Gjëndje Arke:",
|
||
printedToReceipt: "Printuar te printeri i kabinës.",
|
||
recordedNoPrinter: "Regjistruar (pa printer për të printuar).",
|
||
// Header shift control + the booth shift gate.
|
||
headerNoShift: "Asnjë turn",
|
||
headerOpen: "Hap turnin",
|
||
headerClose: "Mbyll turnin",
|
||
headerHeldBy: "Turn i hapur nga {{operator}}",
|
||
headerHeldByShort: "Turni: {{operator}}",
|
||
gateTitle: "Hap një turn për të proceduar biletat",
|
||
gateBody:
|
||
"Asnjë turn nuk është i hapur. Hap turnin tënd që pagesat dhe daljet të regjistrohen te ky turn.",
|
||
gateOtherTitle: "Turni i hapur i përket një operatori tjetër",
|
||
gateOtherBody:
|
||
"{{operator}} ka një turn të hapur. Vetëm një turn mund të jetë i hapur njëkohësisht — ai duhet të mbyllë turnin para se ti të hapësh tëndin.",
|
||
openNow: "Hap turnin tani",
|
||
opening: "Duke hapur…",
|
||
},
|
||
shifts: {
|
||
title: "Historiku i turneve",
|
||
myTitle: "Turnet e mia",
|
||
none: "Asnjë turn i mbyllur.",
|
||
operator: "Operatori",
|
||
started: "Filloi",
|
||
ended: "Mbaroi",
|
||
payments: "Pagesa",
|
||
cash: "Para",
|
||
card: "Kartë",
|
||
expectedDrawer: "Gjëndje arke",
|
||
// Filter (admin only).
|
||
filterFrom: "Nga",
|
||
filterTo: "Deri",
|
||
allOperators: "Të gjithë operatorët",
|
||
apply: "Apliko",
|
||
clear: "Pastro",
|
||
// Expanded drawer detail.
|
||
drawerSection: "Arka",
|
||
openingFloat: "Bilanci fillestar",
|
||
cashTaken: "Para të marra",
|
||
cashAdded: "Para të shtuara",
|
||
cashRemoved: "Para të hequra",
|
||
loadFailed: "Ngarkimi i turneve dështoi.",
|
||
},
|
||
logs: {
|
||
title: "Loget e sistemit",
|
||
refresh: "Rifresko",
|
||
level: "Niveli",
|
||
source: "Burimi",
|
||
since: "Që nga",
|
||
apply: "Apliko",
|
||
clear: "Pastro",
|
||
allLevels: "Të gjitha nivelet",
|
||
allSources: "Të gjitha burimet",
|
||
frontend: "Ndërfaqja",
|
||
backend: "Serveri",
|
||
time: "Koha",
|
||
message: "Mesazhi",
|
||
status: "Statusi",
|
||
path: "Rruga",
|
||
empty: "Asnjë regjistër.",
|
||
},
|
||
pay: {
|
||
ticket: "Bileta",
|
||
entry: "Hyrja",
|
||
now: "Tani",
|
||
duration: "Kohëzgjatja",
|
||
statusLabel: "Statusi",
|
||
paid: "PAGUAR",
|
||
unpaid: "PAPAGUAR",
|
||
overstay: "TEJ AFATIT",
|
||
overstayHint: "Sesion i mëparshëm i paguar. Klienti nuk doli brënda afatit kohor. Kërkohet pagesë për periudhën e re. Totali më poshtë është tarifa e periudhës së re.",
|
||
topUp: "Periudha e re për pagesë",
|
||
total: "Totali",
|
||
noTariff: "pa tarifë",
|
||
tender: "Mënyra",
|
||
cash: "Para",
|
||
card: "Kartë",
|
||
printExitVoucher: "Printo biletë dalje",
|
||
selfExitHint: "(klienti del vetë te dalja)",
|
||
payAndOpen: "Paguaj + hap barrierën",
|
||
payAndVoucher: "Paguaj + printo biletën",
|
||
openBarrier: "Hap barrierën",
|
||
printVoucher: "Printo biletën",
|
||
takingPayment: "Duke marrë pagesën…",
|
||
printingVoucher: "Duke printuar biletën…",
|
||
opening: "Duke hapur…",
|
||
noSessionFound: "Nuk u gjet asnjë sesion për këtë biletë.",
|
||
alreadyClosed: "Ky sesion është mbyllur tashmë (doli {{time}}).",
|
||
lookingUp: "Duke kërkuar…",
|
||
paidBarrierOpened: "Paguar — barriera u hap. Automjeti mund të dalë.",
|
||
paidExitRecorded: "Paguar dhe dalja u regjistrua, por barriera nuk u hap: {{reason}}.",
|
||
subscription: "ABONIM",
|
||
plan: "Plani",
|
||
prepaid: "I PARAPAGUAR",
|
||
subAssistHint: "Abonim i parapaguar. Hap barrierën për të ndihmuar daljen (lexues me defekt / kartë e munguar). S'ka pagesë.",
|
||
subBarrierOpened: "Barriera u hap për abonentin (ndërhyrje e regjistruar).",
|
||
voucherPrinted: "Bileta e daljes u printua në {{printer}}. Klienti del vetë te dalja.",
|
||
// payment receipt (transparency slip)
|
||
receiptPrintFailed: "(fatura nuk u printua — provoni \"Riprinto faturën\".)",
|
||
receiptReprinted: "Fatura u riprintua në {{printer}}.",
|
||
reprintReceipt: "Riprinto faturën",
|
||
reprinting: "duke printuar…",
|
||
// snapshots
|
||
noSnapshots: "asnjë foto",
|
||
loadingSnapshots: "duke ngarkuar fotot…",
|
||
snapEntry: "hyrje",
|
||
snapExit: "dalje",
|
||
snapFailed: "kamera e paarritshme",
|
||
plate: "Targa",
|
||
},
|
||
};
|
||
|
||
// The catalog SHAPE (keys + nesting), with string-typed values — so en.ts must
|
||
// supply every key but may differ in value. (Not `typeof sq` with `as const`, which
|
||
// would pin en.ts to the Albanian literals.)
|
||
type Stringify<T> = { [K in keyof T]: T[K] extends object ? Stringify<T[K]> : string };
|
||
export type Catalog = Stringify<typeof sq>;
|