306d136a08
Add a per-relay "Test" control on each saved controller in /setup so an admin can prove barrier wiring without a vehicle. POST /api/setup/test-relay pulses a barrier relay — but because a physical open with no matching signed command is the fraud signal, the route SIGNS a barrier_open_command (reason setup.relayTest, source manual, attributed to the acting admin) BEFORE it fires. Reconciliation then reads the open as explained, not an anomaly, and there's an audit trail. - Admin-only (site:update), CSRF-guarded; fires only against a SAVED controller (real id → clean attribution; also stops a redirected/unsaved config from opening an arbitrary host's barrier). Sign-before-fire; a pulse failure is reported, not a 500. radarAlert relays (lamps) are excluded from the UI. - New reason code setup.relayTest in @parking/shared (+ EN template); sq/en keys. - EventLog constructed before setupRoutes so the route can sign. - Integration test (stub controller, no hardware): RBAC 403, CSRF 403, signed barrier_open_command on success, 400 unknown relay w/ no ledger row, 404 unknown controller, 400 bad relay value. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
1025 lines
44 KiB
TypeScript
1025 lines
44 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",
|
||
fontSmaller: "Zvogëlo tekstin",
|
||
fontLarger: "Rrit tekstin",
|
||
fontSize: "Madhësia e tekstit",
|
||
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ë…",
|
||
},
|
||
update: {
|
||
available: "Përditësim i disponueshëm",
|
||
prompt: "Versioni {{version}} është i disponueshëm. Ta instaloj tani dhe ta rinis?",
|
||
},
|
||
nav: {
|
||
booth: "Kabina",
|
||
shift: "Turni",
|
||
setup: "Konfigurimi",
|
||
devices: "Pajisjet",
|
||
tariff: "Tarifa",
|
||
tariffLab: "Lab Tarife",
|
||
subscriptions: "Abonimet",
|
||
plans: "Planet",
|
||
site: "Park",
|
||
users: "Përdoruesit",
|
||
roles: "Rolet",
|
||
shifts: "Turnet",
|
||
drawer: "Arka",
|
||
reports: "Raportet",
|
||
recycleBin: "Koshi",
|
||
logs: "Loget",
|
||
backup: "Kopje rezervë",
|
||
profile: "Profili",
|
||
},
|
||
drawer: {
|
||
recordTitle: "Regjistro një lëvizje arke",
|
||
amount: "shuma",
|
||
reasonPlaceholder: "arsyeja (p.sh. pagesë furnitori, depozitë banke)",
|
||
recordHint: "Regjistrohet menjëherë në arkë. Një admin e shqyrton më pas.",
|
||
mandatArketimi: "Arkëtim (hyrje) +",
|
||
mandatPagese: "Pagesë (dalje) −",
|
||
enterPositive: "Fut një shumë pozitive.",
|
||
recorded: "{{no}} u regjistrua. Arka tani {{amount}}.",
|
||
myTitle: "Lëvizjet e mia të arkës",
|
||
allTitle: "Lëvizjet e arkës",
|
||
pendingCount: "{{count}} në pritje",
|
||
filterAll: "Të gjitha",
|
||
empty: "Asnjë lëvizje arke ende.",
|
||
colWhen: "Kur",
|
||
colType: "Lloji",
|
||
colAmount: "Shuma",
|
||
colReason: "Arsyeja",
|
||
colOperator: "Operatori",
|
||
colStatus: "Statusi",
|
||
status: {
|
||
pending: "në pritje",
|
||
authorized: "autorizuar",
|
||
denied: "refuzuar",
|
||
},
|
||
authorize: "Autorizo",
|
||
deny: "Refuzo",
|
||
denyNotePlaceholder: "arsyeja e refuzimit (opsionale)",
|
||
},
|
||
profile: {
|
||
title: "Profili im",
|
||
accountSection: "Llogaria",
|
||
fullName: "Emri i plotë",
|
||
fullNamePh: "Emri dhe mbiemri",
|
||
email: "Email",
|
||
emailPh: "ti@shembull.com",
|
||
username: "Përdoruesi",
|
||
role: "Roli",
|
||
saveProfile: "Ruaj profilin",
|
||
profileSaved: "Profili u ruajt.",
|
||
passwordSection: "Ndrysho fjalëkalimin",
|
||
currentPassword: "Fjalëkalimi aktual",
|
||
newPassword: "Fjalëkalimi i ri",
|
||
confirmPassword: "Konfirmo fjalëkalimin",
|
||
changePassword: "Ndrysho fjalëkalimin",
|
||
passwordChanged: "Fjalëkalimi u ndryshua.",
|
||
passwordsDontMatch: "Fjalëkalimet nuk përputhen.",
|
||
passwordTooShort: "Fjalëkalimi duhet të jetë të paktën {{min}} karaktere.",
|
||
},
|
||
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…",
|
||
laneEntry: "Hyrje",
|
||
laneExit: "Dalje",
|
||
openTicket: "Lexo",
|
||
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.",
|
||
// Kokat e kolonave të tabelës së sesioneve aktive.
|
||
colWho: "Biletë / abonent",
|
||
colPlate: "Targa",
|
||
colEntry: "Hyrja",
|
||
colElapsed: "Koha brenda",
|
||
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 ANPR",
|
||
// filtra
|
||
filterSearchSessions: "Kërko biletë / abonent / targë…",
|
||
filterSearchFeed: "Kërko event / identitet / targë…",
|
||
filterAll: "Të gjitha",
|
||
fKindTransient: "Kalimtarë",
|
||
fKindSubscription: "Abonentë",
|
||
fSrcBooth: "Kabinë",
|
||
fSrcReader: "Lexues",
|
||
fEvtEntry: "Hyrje",
|
||
fEvtExit: "Dalje",
|
||
fEvtPay: "Pagesë",
|
||
fEvtVoid: "Anulim",
|
||
fEvtAnomaly: "Anomali",
|
||
openPayExit: "Hap pagesën / daljen",
|
||
openReopenBarrier: "Hap — paguar, pret barrierën",
|
||
issueEntry: "Lësho biletë",
|
||
issueEntryTitle: "Lësho një biletë hyrjeje & hap barrierën (butoni fizik i prishur)",
|
||
issueEntryConfirm: "Një automjet është te hyrja. Të lëshohet një biletë hyrjeje dhe të hapet barriera?",
|
||
issueEntryOk: "Bileta e hyrjes {{ticket}} u lëshua.",
|
||
exitedGrace: "doli · në afat",
|
||
exitedGraceLeft: "doli · {{time}}",
|
||
exitedGraceTitle: "Paguar dhe dalur — barriera nuk u konfirmua; po pret afatin kohor.",
|
||
openBarrier: "Hap barrierën",
|
||
openBarrierTitle: "Hap barrierën manualisht",
|
||
barrierOpened: "barriera u hap",
|
||
openManually: "hape manualisht",
|
||
// 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Ë",
|
||
evtCashReview: "SHQYRTIM",
|
||
decision: { authorize: "autorizuar", deny: "refuzuar" },
|
||
evtAnomaly: "ANOMALI",
|
||
evtRefused: "REFUZUAR",
|
||
// 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",
|
||
badgeWindowCharge: "jashtë orarit — detyrim",
|
||
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",
|
||
edDecision: "Vendimi i shqyrtimit",
|
||
edReviewedBy: "Shqyrtuar nga",
|
||
edReviewNote: "Shënim",
|
||
edReviewRef: "Ref. lëvizjes",
|
||
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}}",
|
||
"entry.operatorIssued": "Biletë hyrjeje e lëshuar nga operatori {{operator}} (butoni fizik i prishur)",
|
||
"entry.issue.noPresence": "Hyrja nga operatori u refuzua — asnjë automjet te hyrja",
|
||
"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 manualisht",
|
||
"exit.open.unavailable": "Dalja u regjistrua, por barriera është e padisponueshme — hape manualisht",
|
||
"exit.open.failed": "Dalja u regjistrua, por barriera nuk u hap — hape manualisht",
|
||
"exit.freeGrace": "Periudhë pa pagesë në hyrje (pa tarifë)",
|
||
"exit.manualOpen": "Hapje manuale e barrierës (ndërhyrje njerëzore)",
|
||
"exit.plateSwapSuspected": "Mundësi ndërrimi biletash — targa {{plate}} është tashmë brenda me biletën {{otherIdentity}}",
|
||
"exit.plateSwapOverride": "Operatori {{operator}} lëshoi një dalje me dyshim ndërrimi biletash (targa {{plate}}, edhe e hapur me {{otherIdentity}})",
|
||
"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)",
|
||
"sub.refused.unpaidWindow": "Dalja u refuzua — detyrim jashtë orarit i papaguar ({{amount}} {{currency}}); paguaje në kabinë",
|
||
"void.ticketCancelled": "Bileta u anulua — {{reason}}",
|
||
},
|
||
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 kontrollerat e barrierave — Pastaj shto lexues (QR/RF), kamera, printera.",
|
||
// Category titles + the singular noun used in buttons/modal titles.
|
||
catControllers: "Kontrollerat (barrierat + butoni i hyrjes)",
|
||
catReaders: "Lexuesit (QR / RFID)",
|
||
catCameras: "Kamerat (foto + targë)",
|
||
catPrinters: "Printerat (bileta / vouchera)",
|
||
nounController: "kontroller",
|
||
nounReader: "lexues",
|
||
nounCamera: "kamerë",
|
||
nounPrinter: "printer",
|
||
add: "+ Shto {{noun}}",
|
||
addAnother: "+ Shto {{noun}}",
|
||
addTitle: "Shto {{noun}}",
|
||
editTitle: "Ndrysho {{noun}}",
|
||
needControllerFirst: "Shto fillimisht një kontroller — {{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 kontroller",
|
||
scanning: "Duke skanuar…",
|
||
noControllersFound: "Asnjë kontroller 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ë kontroller",
|
||
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.",
|
||
outputsTitle: "Daljet — relet (barrierat + drita)",
|
||
outputsHint:
|
||
"Relet janë DALJE: secila hap një barrierë (ose ndez dritën e butonit). Cakto numrin e relesë dhe drejtimin. Terminalet hyrëse (butoni, sensori) janë te seksioni Hyrjet më poshtë.",
|
||
pulseOpenMs: "Kohëzgjatja e hapjes (ms)",
|
||
pulseOpenHint: "Sa kohë mbahet rele e barrierës e hapur (jog). Vlen për të gjitha relet e barrierave.",
|
||
inputsTitle: "Hyrjet — terminalet (buton, sensor)",
|
||
inputsHint:
|
||
"Hyrjet janë TERMINALE që hosti i LEXON: butoni i hyrjes dhe sensori i pranisë/radari. Secila i përket një barriere hyrëse — e gateron ose e nis atë rele.",
|
||
inputsIdleHigh: "Hyrjet në pushim HIGH",
|
||
inputsIdleHighHint: "Kjo pllakë i mban hyrjet HIGH në pushim (statusi 1111); një shtypje e ul në LOW.",
|
||
relay: "Rele",
|
||
// Generic input rows: terminal + role + the relay it serves.
|
||
inputTerminal: "Terminali",
|
||
inputServesRelay: "I shërben reles",
|
||
roleButton: "Butoni i hyrjes",
|
||
rolePresenceLoop: "Prania (lak induktiv)",
|
||
rolePresenceRadar: "Prania (radar)",
|
||
roleAlertTrigger: "Trigger alarmi",
|
||
addInput: "+ Shto hyrje",
|
||
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.",
|
||
activeLow: "Aktiv-ulët",
|
||
activeLowHint:
|
||
"Shëno nëse sensori i pranisë (p.sh. radari) qëndron HIGH në pushim dhe shkon LOW kur detekton — e kundërta e butonit. Kjo përmbys leximin e atij terminali që 'prania' të lexohet saktë.",
|
||
eventRadarAlert: "Alarm radar (dritë)",
|
||
triggerInput: "Trigger input",
|
||
triggerInputHint:
|
||
"Terminali i hyrjes (radari) që nis pulsimin e kësaj rele. Pulson kur Trigger input është aktiv por kamera s'konfirmon makinë; ndizet fiks kur kamera konfirmon; përndryshe fiket.",
|
||
lockLane: "Bllokimi nga",
|
||
lockLaneHint:
|
||
"Cila kamerë e ndez dritën fiks: hyrja apo dalja. Një radar i daljes duhet të bllokohet nga kamera e DALJES.",
|
||
lockLaneEntry: "Kamera e hyrjes",
|
||
lockLaneExit: "Kamera e daljes",
|
||
blinkOnMs: "Pulsim ndezur (ms)",
|
||
blinkOffMs: "Pulsim fikur (ms)",
|
||
addRelay: "+ Shto rele",
|
||
// Camera ANPR opt-in.
|
||
anpr: "Njohja e targave (ANPR)",
|
||
anprHint:
|
||
"Lexo targat në këtë aparat: shërbimi i vizionit lexon targën nga çdo pamje dhe e regjistron (hyrje dhe dalje). Kërkon shërbimin e vizionit aktiv.",
|
||
anprAuto: "Hapje/mbyllje automatike me targën e abonentit",
|
||
anprAutoHint:
|
||
"Lejo që KY aparat të hapë vetë barrierën kur njeh targën e një abonenti. ÇAKTIVIZOJE te aparati i daljes në një korsi të përbashkët hyrje/dalje, që një makinë që HYN të mos DALË automatikisht nga targa e pasme (njohja vazhdon — fiket vetëm hapja automatike).",
|
||
testAnpr: "Testo ANPR",
|
||
anprTesting: "Duke testuar ANPR…",
|
||
testAnprHint:
|
||
"Merr një pamje të drejtpërdrejtë nga kjo kamerë dhe përpiqet të lexojë një targë, duke raportuar rezultatin dhe kohën e nevojshme. Vendos një targë para kamerës më parë.",
|
||
anprOk: "✓ Targa u lexua {{plate}} — {{confidence}}% besueshmëri, {{ms}} ms",
|
||
anprLowConfidence: "(besueshmëri e ulët — vetëm këshillues)",
|
||
anprTookMs: "{{ms}} ms",
|
||
"anprFail.vision-disabled": "Shërbimi i vizionit është çaktivizuar — aktivizoje (VISION_ENABLED) për ta testuar ANPR.",
|
||
"anprFail.snapshot-failed": "Nuk u mor dot pamje nga kamera (jashtë linje ose e paarritshme).",
|
||
"anprFail.no-plate": "Nuk u gjet asnjë targë në pamje.",
|
||
// Printer test slip — pushes a real slip so the admin can confirm it physically prints.
|
||
testPrint: "Printo provë",
|
||
printTesting: "Duke printuar…",
|
||
testPrintHint:
|
||
"Dërgon një fletë prove te printeri tani. ‘I lidhur’ vetëm hap lidhjen — kjo konfirmon se printeri vërtet nxjerr letër.",
|
||
printOk: "✓ Fleta e provës u dërgua ({{ms}} ms). Kontrollo printerin.",
|
||
"printFail.print-failed": "Printeri nuk pranoi punën (pa letër, kapaku hapur, ose lidhja ra).",
|
||
// Provë e releut — hap fizikisht barrierën (hapja regjistrohet në ledger).
|
||
testRelay: "Provo R{{relay}}",
|
||
relayTesting: "Duke hapur…",
|
||
testRelayTitle: "Puls releu {{relay}} — hap barrierën",
|
||
confirmRelayTest: "Ky veprim hap fizikisht barrierën dhe regjistrohet në ledger si provë.",
|
||
relayTestOk: "✓ R{{relay}} u pulsua — barriera u hap",
|
||
relayTestFailed: "✗ R{{relay}} dështoi: {{detail}}",
|
||
// Reveal/hide toggle for a secret field (e.g. the device web password).
|
||
revealSecret: "Shfaq fjalëkalimin",
|
||
hideSecret: "Fshih fjalëkalimin",
|
||
// Alarm Server push settings — generated for the camera's Event → Alarm Server form.
|
||
alarmUrlTitle: "Cilësimet e Alarm Server (vendosi te kamera)",
|
||
alarmUrlHint:
|
||
"Vendosi këto te kamera: Configuration → Event → … → Alarm Settings (ose Notify Surveillance Center). Kamera do të dërgojë çdo ngjarje këtu — pa polling.",
|
||
alarmUrlCopy: "Kopjo të gjitha",
|
||
alarmUrlCopied: "U kopjua ✓",
|
||
alarmUrlSaveFirst:
|
||
"Ruaje kamerën më parë — adresa gjenerohet pasi pajisja të marrë një ID. Hape sërish për editim që ta shohësh.",
|
||
alarmUrlTestFirst:
|
||
"Kliko “Testo lidhjen” më parë — kështu përcaktohet IP-ja e këtij hosti në rrjetin e kamerës (që kamera ta thërrasë).",
|
||
alarmFieldHost: "Destination IP / Host",
|
||
alarmFieldUrl: "URL",
|
||
alarmFieldProtocol: "Protokolli",
|
||
alarmFieldPort: "Porta",
|
||
// Binding picker.
|
||
whichBarrier: "Cilën barrierë shërben kjo pajisje?",
|
||
controller: "Kontrolleri",
|
||
choose: "Zgjidh…",
|
||
relayLabel: "Rele {{relay}} ({{direction}})",
|
||
noRelaysConfigured: "Ky kontroller 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",
|
||
perDay: "ditë",
|
||
perWeek: "javë",
|
||
perMonth: "muaj",
|
||
plan: "Plani",
|
||
quantity: "Makina",
|
||
quantityHint: "makina të mbuluara nga ky abonim (çmimi ×N)",
|
||
count: "Sa",
|
||
planNone: "— pa pagesë / falas —",
|
||
planNoneAvail: "Asnjë plan i përcaktuar — admini duhet të krijojë një të parin.",
|
||
version: "Versioni",
|
||
versionCurrent: "aktual",
|
||
versionHint: "Zhvendos këtë abonent në një version tjetër të të njëjtit plan. Çmimi mbetet siç u faturua; ndryshon vetëm orari i lejuar nga këtu e tutje.",
|
||
versionOnlyOne: "vetëm një version i këtij plani",
|
||
everyDay: "çdo ditë",
|
||
allDay: "24/7 (pa orar)",
|
||
quoting: "duke llogaritur…",
|
||
quotePrompt: "zgjidh datën e mbarimit",
|
||
quoteLine: "{{periods}} × {{unit}} · {{amount}} {{currency}}",
|
||
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",
|
||
validToEnd: "Vlen deri (mbarimi)",
|
||
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",
|
||
},
|
||
plans: {
|
||
title: "Planet e abonimit",
|
||
intro: "Planet i përcakton admini; operatori vetëm shet prej tyre — çmimi merret automatikisht, nuk shkruhet. Ndryshimi i një plani publikon një version të ri; shitjet e mëparshme ruajnë çmimin e tyre.",
|
||
add: "+ Shto plan",
|
||
noneYet: "Asnjë plan ende. Shto një që kabina të shesë abonime.",
|
||
colName: "Emri",
|
||
colPrice: "Çmimi",
|
||
colHours: "Orari",
|
||
colUsedBy: "Përdorur nga",
|
||
colEffective: "Vlen nga",
|
||
allHours: "24/7",
|
||
usedByCount: "{{active}} aktive / {{total}}",
|
||
usedByNone: "asnjë",
|
||
usedByTitle: "Shfaq abonimet në këtë plan",
|
||
subscribers: "Abonentët",
|
||
inForce: "në fuqi",
|
||
retired: "i tërhequr",
|
||
versionCount: "{{count}} versione",
|
||
newVersion: "Version i ri",
|
||
retire: "Tërhiq",
|
||
reactivate: "Riaktivizo",
|
||
delete: "Fshij",
|
||
deleteTitle: "Fshij këtë plan përgjithmonë (vetëm kur asnjë abonim nuk e përdor)",
|
||
reactivated: "“{{name}}” është përsëri i shitshëm.",
|
||
confirmDelete: "Të fshihet plani “{{name}}” përgjithmonë? Kjo s'mund të kthehet.",
|
||
deleted: "Plani “{{name}}” u fshi.",
|
||
deleteInUse: "S'mund të fshihet — abonime ende e përdorin këtë plan. Tërhiqe në vend të kësaj.",
|
||
newTitle: "Plan i ri",
|
||
newVersionTitle: "Publiko version të ri",
|
||
newVersionHint: "Kjo publikon një version TË RI të planit — shitjet ekzistuese ruajnë çmimin origjinal.",
|
||
period: "Periudha",
|
||
pricePer: "Çmimi për periudhë",
|
||
namePlaceholder: "p.sh. Mujor standard, ose Mujor natën, ose Hotel ditor",
|
||
needName: "Emri i planit është i detyrueshëm.",
|
||
needPrice: "Shkruaj një çmim më të madh se zero.",
|
||
saved: "Plani u ruajt.",
|
||
confirmRetire: "Të tërhiqet plani “{{name}}”? Nuk do të jetë më i shitshëm (historiku ruhet).",
|
||
needWindow: "Shkruaj orare të vlefshme (HH:MM).",
|
||
needDays: "Zgjidh të paktën një ditë për intervalin.",
|
||
restrictTimes: "Kufizo oraret e parkimit (tarifë kalimtare jashtë intervalit)",
|
||
days: "Ditët",
|
||
window: "Intervali",
|
||
enterAfter: "hyrje pas",
|
||
exitBefore: "· dalje para",
|
||
grace: "Tolerancë",
|
||
graceHint: "minuta tolerancë rreth kufijve të intervalit",
|
||
timeframesHint: "Një skanim jashtë intervalit të lejuar tarifohet me tarifën normale kalimtare për minutat jashtë intervalit (hyrja e hershme shtyhet në dalje; dalja e vonuar bllokohet derisa paguhet).",
|
||
},
|
||
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: "(klienti skanon biletën në dalje)",
|
||
reserveSubs: "Rezervo vendet e abonentëve",
|
||
reserveSubsHint: "Mban një vend për makinat e çdo abonenti aktiv edhe kur nuk janë të parkuar — kalimtarët e shohin 'plot' më shpejt. Joaktiv: numërohen vetëm makinat brenda (mbingarkesa menaxhohet me parkim manual).",
|
||
anprEntry: "Hapje automatike për targat e abonentëve (ANPR)",
|
||
anprEntryHint: "Kur është aktiv, targa e një abonenti e lexuar nga kamera e korsisë hap barrierën përmes portës normale të abonimit. Joaktiv: abonentët duhet të përdorin kartën/QR-në. Fotot e targave regjistrohen gjithsesi.",
|
||
parkDetails: "Të dhënat e parkimit (opsionale — shfaqen në bileta/fatura)",
|
||
save: "Ruaj",
|
||
saved: "U ruajt.",
|
||
fieldParkName: "Emri i parkimit",
|
||
fieldParkNamePh: "p.sh. Parking Aeroport",
|
||
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…",
|
||
endConfirm: "",
|
||
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: "MBYLLJA E TURNIT",
|
||
viewTakings: "Arkëtimet deri tani",
|
||
xReport: "ARKËTIMET DERI TANI",
|
||
asOf: "deri më",
|
||
xReportHint: "Vetëm për shikim — asgjë nuk regjistrohet. Këto shifra nënshkruhen kur mbyllet turni.",
|
||
payments: "Pagesa:",
|
||
cash: "Para:",
|
||
card: "Kartë:",
|
||
srcTickets: "Bileta:",
|
||
srcSubscriptions: "Abonime:",
|
||
srcSubWindow: "jashtë orarit",
|
||
drawerSection: "— Arka —",
|
||
openingFloat: "Arka fillestare:",
|
||
cashTaken: "Xhiro ditore:",
|
||
cashAdded: "Arkëtime:",
|
||
cashRemoved: "Pagesa:",
|
||
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ë",
|
||
srcTickets: "Bileta",
|
||
srcSubscriptions: "Abonime",
|
||
srcSubWindow: "jashtë orarit",
|
||
expectedDrawer: "Gjëndje arke",
|
||
// Filter (admin only).
|
||
filterFrom: "Nga",
|
||
filterTo: "Deri",
|
||
allOperators: "Të gjithë operatorët",
|
||
apply: "Apliko",
|
||
clear: "Pastro",
|
||
timeframe: "Periudha",
|
||
preset_yesterday: "Dje",
|
||
preset_week: "Javën e fundit",
|
||
preset_month: "Muajin e fundit",
|
||
preset_all: "Të gjitha",
|
||
preset_custom: "Zgjidh periudhë",
|
||
selectAShift: "Zgjidh një turn për të parë aktivitetin e tij.",
|
||
noActivity: "Asnjë aktivitet në këtë turn.",
|
||
current: "aktual",
|
||
// Expanded drawer detail.
|
||
drawerSection: "Arka",
|
||
openingFloat: "Arka fillestare",
|
||
cashTaken: "Xhiro ditore",
|
||
cashAdded: "Arkëtime",
|
||
cashRemoved: "Pagesa",
|
||
loadFailed: "Ngarkimi i turneve dështoi.",
|
||
},
|
||
reports: {
|
||
title: "Raportet",
|
||
groupBy: "Grupo sipas",
|
||
exportCsv: "Eksporto CSV",
|
||
loadFailed: "Raporti nuk u ngarkua dot: {{error}}",
|
||
noData: "Nuk ka të dhëna në këtë interval.",
|
||
footnote: "Numërimet dhe paratë mblidhen nga regjistri i nënshkruar. Oraret në {{tz}}.",
|
||
preset: { today: "Sot", "7d": "7 ditë", "30d": "30 ditë", "90d": "90 ditë" },
|
||
bucket: { hour: "Orë", day: "Ditë", month: "Muaj" },
|
||
kpi: {
|
||
entries: "Hyrje",
|
||
exits: "Dalje",
|
||
revenue: "Të ardhura",
|
||
payments: "Pagesa",
|
||
avgStay: "Qëndrim mes.",
|
||
subscribers: "Abonentë",
|
||
},
|
||
chart: {
|
||
flow: "Hyrjet & daljet me kalimin e kohës",
|
||
revenue: "Të ardhurat ({{currency}})",
|
||
mix: "Përbërja e të ardhurave",
|
||
peakHours: "Hyrjet sipas orës së ditës",
|
||
breakdown: "Ndarja",
|
||
},
|
||
mix: { ticket: "Tranzit", subSales: "Abonime", subWindow: "Jashtë orarit" },
|
||
row: {
|
||
cash: "Para në dorë",
|
||
card: "Kartë",
|
||
closed: "Sesione të mbyllura",
|
||
medianStay: "Qëndrim mesatar (median)",
|
||
subActive: "Abonime aktive",
|
||
subCars: "Makina të mbuluara",
|
||
},
|
||
},
|
||
recycleBin: {
|
||
title: "Koshi",
|
||
retentionNote: "Artikujt e fshirë mbahen për {{days}} ditë, pastaj hiqen përgjithmonë.",
|
||
empty: "Asgjë e fshirë. Artikujt që fshini shfaqen këtu, të rikuperueshëm derisa të skadojnë.",
|
||
col: { type: "Lloji", item: "Artikulli", deleted: "Fshirë", actions: "" },
|
||
kind: {
|
||
user: "Përdorues",
|
||
role: "Rol",
|
||
subscription: "Abonim",
|
||
plan: "Plan",
|
||
tariff: "Tarifë",
|
||
},
|
||
restore: "Rikthe",
|
||
purge: "Fshi përfundimisht",
|
||
purgeConfirmTitle: "Të fshihet përfundimisht?",
|
||
purgeConfirmBody: "Të fshihet përgjithmonë “{{label}}”? Nuk mund të rikthehet pas kësaj.",
|
||
purgeIrreversible: "Ky veprim është i pakthyeshëm.",
|
||
},
|
||
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.",
|
||
},
|
||
backup: {
|
||
title: "Kopje rezervë",
|
||
intro:
|
||
"Kopje e enkriptuar e bazës së të dhënave (regjistri i nënshkruar) në një disk të jashtëm. Bëhet automatikisht çdo ditë dhe me butonin më poshtë.",
|
||
statusTitle: "Gjendja",
|
||
configured: "Aktive",
|
||
notConfigured: "E pakonfiguruar",
|
||
notConfiguredHint:
|
||
"Cakto BACKUP_TARGET_DIR dhe BACKUP_KEY në server që të aktivizohet kopja rezervë.",
|
||
running: "Duke u kryer…",
|
||
idle: "Në pritje",
|
||
lastSuccess: "Kopja e fundit e suksesshme",
|
||
lastError: "Gabimi i fundit",
|
||
never: "Asnjëherë",
|
||
lastFile: "Skedari",
|
||
size: "Madhësia",
|
||
pruned: "Të hequra",
|
||
runNow: "Bëj kopje tani",
|
||
runSuccess: "Kopja rezervë u krye.",
|
||
runFailed: "Kopja rezervë dështoi.",
|
||
notConfiguredError: "Kopja rezervë nuk është e konfiguruar.",
|
||
restoreNote:
|
||
"Rikthimi nuk bëhet nga këtu — është veprim i jashtëm gjatë instalimit të një aparati të ri (kërkon skedarin e kopjes + çelësat e ruajtur jashtë).",
|
||
targetLabel: "Vendndodhja e kopjes",
|
||
targetPlaceholder: "p.sh. /mnt/backup ose /media/usb",
|
||
targetHint: "Rrugë absolute drejt një disku të lidhur (USB/SATA) ose një ndarjeje rrjeti (SMB/NFS).",
|
||
save: "Ruaj",
|
||
saved: "U ruajt.",
|
||
test: "Testo vendndodhjen",
|
||
testOk: "Vendndodhja është e shkruajtshme.",
|
||
testEmpty: "Shkruaj një rrugë.",
|
||
testMissing: "Vendndodhja nuk ekziston.",
|
||
testNotDir: "Rruga nuk është një dosje.",
|
||
testNotWritable: "Dosja nuk është e shkruajtshme.",
|
||
keyMissing: "Çelësi i enkriptimit (BACKUP_KEY) mungon në server — caktoje që kopja të aktivizohet.",
|
||
keepLastLabel: "Mbaj kopjet e fundit",
|
||
keepLastHint: "Numri i kopjeve më të reja që mbahen gjithmonë.",
|
||
keepDailyLabel: "Mbaj ditore (ditë)",
|
||
keepDailyHint: "Përtej atyre, mbaj një kopje për ditë për kaq ditë.",
|
||
},
|
||
pay: {
|
||
ticket: "Bileta",
|
||
entry: "Hyrja",
|
||
now: "Tani",
|
||
exit: "Dalja",
|
||
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.",
|
||
closedWithinGrace: "Paguar",
|
||
closedWithinGraceHint: "Pagesa dhe dalja u regjistruan — barriera nuk u konfirmua ende. Makina mbetet në listë derisa të mbarojë afati. Hapni barrierën manualisht nëse pret ende.",
|
||
topUp: "Periudha e re për pagesë",
|
||
total: "Totali",
|
||
paidAmount: "Paguar",
|
||
noTariff: "pa tarifë",
|
||
tender: "Mënyra",
|
||
cash: "Para",
|
||
card: "Kartë",
|
||
printExitVoucher: "Printo biletë dalje",
|
||
selfExitHint: "(klienti del duke skanuar biletën)",
|
||
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}}.",
|
||
swapTitle: "Mundësi ndërrimi biletash",
|
||
swapBody: "Targa {{plate}} është tashmë brenda me biletën {{other}} (hyri {{when}}). Ky automjet mund të jetë duke dalë me një biletë tjetër nga ajo me të cilën hyri.",
|
||
swapHint: "Verifiko automjetin para se ta lëshosh. Anashkalimi regjistrohet në emrin tënd.",
|
||
swapOverride: "Anashkalo & lësho",
|
||
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ë.",
|
||
assistOpenReveal: "Ndihmë për hapje (lexues me defekt / kartë e humbur)…",
|
||
payWindowCharge: "Merr pagesën",
|
||
windowPaidHint: "Pagesa jashtë orarit u krye. Hap barrierën që abonenti të dalë.",
|
||
windowCharge: "JASHTË ORARIT",
|
||
windowChargeHint: "Ky abonent parkoi jashtë orarit të lejuar të planit. Detyrohet të paguajë tarifën kalimtare për kohën jashtë orarit — merr pagesën, pastaj hap barrierën.",
|
||
subBarrierOpened: "Barriera u hap për abonentin (ndërhyrje e regjistruar).",
|
||
voucherPrinted: "Bileta e daljes u printua në {{printer}}. Klienti del duke skanuar biletën.",
|
||
// 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…",
|
||
cancelTicket: "Anulo biletën",
|
||
cancelTicketTitle: "Anulo këtë biletë",
|
||
cancelTicketHint: "Anulon një biletë të printuar gabimisht. Ruhet një gjurmë e nënshkruar (operatori + arsyeja); hyrja origjinale nuk fshihet kurrë.",
|
||
cancelReason: {
|
||
misprint: "Printim i gabuar",
|
||
test: "Test",
|
||
wrongVehicle: "Automjet i gabuar",
|
||
},
|
||
cancelReasonPlaceholder: "Arsyeja e anulimit (e detyrueshme)…",
|
||
confirmCancelTicket: "Konfirmo anulimin",
|
||
cancelling: "duke anuluar…",
|
||
ticketCancelled: "Bileta u anulua.",
|
||
// 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>;
|