@javierfrancoleal/dsh-supervisor 1.0.37 โ†’ 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dashboard.html CHANGED
@@ -3,180 +3,11 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="theme-color" content="#4D6BFE">
6
+ <link rel="stylesheet" href="./dashboard.css">
7
+ <meta name="theme-color" content="#4D6BFE">
7
8
  <title>Le Veilleux โ€” Dashboard</title>
8
9
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='16' fill='%234D6BFE'/%3E%3Cpath d='M32 16 C 15 16, 8.5 25.5, 8.5 32 C 8.5 38.5, 15 48, 32 48 C 49 48, 55.5 38.5, 55.5 32 C 55.5 25.5, 49 16, 32 16 Z' fill='none' stroke='%23fff' stroke-width='4.5'/%3E%3Cpath d='M32 23.5 C 36.6 28.2, 38.6 31.4, 38.6 34.8 A 6.6 6.6 0 1 1 25.4 34.8 C 25.4 31.4, 27.4 28.2, 32 23.5 Z' fill='%23FACC15'/%3E%3C/svg%3E">
9
- <style>
10
- :root{--blue:#4D6BFE;--violet:#7c5cff;--green:#22c55e;--amber:#facc15;--red:#ef4444;--ink:#101828;--muted:#667085;--bg:#eef2ff;--card:rgba(255,255,255,.78);--card2:rgba(255,255,255,.62);--line:rgba(15,23,42,.10);--line2:rgba(15,23,42,.06)}
11
- body.dark{background:linear-gradient(165deg,#0b1220 0%,#141f31 50%,#1e1b4b 100%);background-attachment:fixed;--ink:#e6ecf7;--muted:#94a3b8;--bg:#0b1220;--card:rgba(20,31,49,.8);--card2:rgba(24,37,58,.62);--line:rgba(148,163,184,.16);--line2:rgba(148,163,184,.10)}
12
- .anim{animation:slidein .28s ease}
13
- @keyframes slidein{from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}}
14
- .empty{text-align:center;padding:26px 12px;color:var(--muted);font-size:14px;border:1px dashed var(--line);border-radius:14px}
15
- .empty .ico{font-size:30px;display:block;margin-bottom:6px}
16
- .skel{background:linear-gradient(90deg,var(--line) 25%,var(--line2) 50%,var(--line) 75%);background-size:200% 100%;animation:shimmer 1.2s infinite;border-radius:10px;min-height:16px}
17
- @keyframes shimmer{to{background-position:-200% 0}}
18
- .toast{position:fixed;bottom:90px;left:50%;transform:translateX(-50%);background:#111827;color:#fff;padding:10px 18px;border-radius:999px;font-size:14px;font-weight:600;z-index:60;opacity:0;transition:opacity .25s;pointer-events:none;max-width:86%;text-align:center}
19
- .toast.show{opacity:1}
20
- body.dark .toast{background:#e6ecf7;color:#0b1220}
21
- .bnav{position:fixed;bottom:0;left:0;right:0;background:var(--card);border-top:1px solid var(--line);display:none;justify-content:space-around;padding:6px 0 8px;z-index:50}
22
- .bnav button{background:none;border:none;color:var(--muted);font-size:11px;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 12px;border-radius:12px;min-height:44px;font-family:inherit}
23
- .bnav button.active{color:var(--blue);font-weight:700}
24
- .checkpop{animation:pop .3s ease}
25
- @keyframes pop{0%{transform:scale(.6);opacity:0}70%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
26
- @keyframes flick{0%,100%{opacity:1}42%{opacity:.82}50%{opacity:1}58%{opacity:.9}}
27
- @keyframes drawStroke{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
28
- /* Visible by default; the self-draw runs only when motion is allowed */
29
- .mark svg path{stroke-dasharray:100}
30
- @media (prefers-reduced-motion: no-preference){.mark svg path{stroke-dashoffset:100;animation:drawStroke 1.6s cubic-bezier(.4,0,.2,1) forwards}}
31
10
 
32
- .person{animation:rise .3s ease backwards}
33
- .person:nth-child(1){animation-delay:.03s}
34
- .person:nth-child(2){animation-delay:.09s}
35
- .person:nth-child(3){animation-delay:.15s}
36
- .person:nth-child(4){animation-delay:.21s}
37
- @keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
38
- @media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
39
- body.loginpage{background:linear-gradient(135deg,#4D6BFE 0%,#7c5cff 55%,#a78bfa 100%);min-height:100vh}
40
- body.loginpage.dark{background:linear-gradient(135deg,#0b1220 0%,#1e1b4b 100%)}
41
- body.loginpage header{background:transparent;box-shadow:none}
42
- #loginView{backdrop-filter:blur(14px);background:rgba(255,255,255,.93);border:1px solid rgba(255,255,255,.55);box-shadow:0 24px 60px rgba(15,23,42,.28);max-width:420px;margin:6vh auto 0;padding:26px 22px;animation:rise .5s ease backwards;animation-delay:.12s}
43
- body.dark #loginView{background:rgba(20,31,49,.93)}
44
- .loginbrand{text-align:center;margin-bottom:16px;animation:rise .5s ease backwards;animation-delay:.02s}
45
- .loginbrand .mark{width:64px;height:64px;border-radius:18px;background:linear-gradient(135deg,#4D6BFE,#7c5cff);display:inline-flex;align-items:center;justify-content:center;font-size:30px;box-shadow:0 10px 24px rgba(77,107,254,.45)}
46
- .loginbrand h2{margin:10px 0 2px;font-size:20px;font-weight:800}
47
- .loginbrand p{color:var(--muted);font-size:13px;margin:0}
48
- .spin{display:inline-block;width:15px;height:15px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:rot .7s linear infinite;vertical-align:-3px;margin-right:8px}
49
- @keyframes rot{to{transform:rotate(360deg)}}
50
- .shake{animation:shake .4s ease}
51
- @keyframes shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-6px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(4px)}}
52
- input:focus,select:focus,textarea:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(77,107,254,.18)}
53
- @media(max-width:560px){.bnav{display:flex}.tabs{display:none}body{padding-bottom:70px}button,.btn,.pill,.confirmBtn{min-height:44px}}
54
- *{box-sizing:border-box}
55
- body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:linear-gradient(165deg,#e8edff 0%,#f6f7fb 45%,#fdf1f8 100%);background-attachment:fixed;color:var(--ink);-webkit-tap-highlight-color:transparent}
56
- header{background:linear-gradient(135deg,#4D6BFE,#7c5cff);box-shadow:0 4px 18px rgba(77,107,254,.28);color:#fff;padding:12px 16px;display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
57
- header h1{margin:0;font-size:18px}
58
- header .who{font-size:13px;opacity:.9}
59
- button{font-family:inherit;cursor:pointer}
60
- .btn{border:none;border-radius:12px;padding:12px 16px;font-size:15px;font-weight:600;color:#fff;background:linear-gradient(135deg,#4D6BFE,#7c5cff);box-shadow:0 4px 12px rgba(77,107,254,.22)}
61
- .btn.gray{background:var(--line2);color:var(--ink)}
62
- .btn.small{padding:8px 12px;font-size:13px}
63
- main{max-width:960px;margin:0 auto;padding:14px}
64
- .card{background:var(--card);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--line);border-radius:20px;box-shadow:0 8px 24px rgba(15,23,42,.06);padding:16px;margin:12px 0}
65
- .card h2{margin:0 0 10px;font-size:16px}
66
- input,select,textarea{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;font-size:16px;margin-bottom:8px;font-family:inherit;background:var(--card)}
67
- textarea{resize:vertical;min-height:80px}
68
- pre{background:#0f172a;color:#d7e3f4;border-radius:12px;padding:12px;font-size:12.5px;overflow:auto;max-height:320px;white-space:pre-wrap;margin:0}
69
- .metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px}
70
- .metric{background:var(--card);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--line);border-radius:16px;box-shadow:0 4px 14px rgba(15,23,42,.05);padding:12px;text-align:center}
71
- .metric .v{font-size:26px;font-weight:700;color:var(--blue)}
72
- .metric .l{font-size:12px;color:var(--muted);margin-top:2px}
73
- .tabs{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
74
- .tabs button{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:10px 16px;font-size:15px;font-weight:600}
75
- .tabs button.active{background:var(--blue);color:#fff;border-color:var(--blue)}
76
- table{width:100%;border-collapse:collapse;font-size:14px}
77
- td,th{border-bottom:1px solid var(--line);padding:9px 6px;text-align:left}
78
- #splash{position:fixed;inset:0;background:linear-gradient(135deg,#4D6BFE,#7c5cff);display:flex;align-items:center;justify-content:center;z-index:100;transition:opacity .5s,visibility .5s}
79
- #splash.done{opacity:0;visibility:hidden}
80
- .splash-inner{text-align:center;color:#fff;padding:20px}
81
- .splash-inner b{display:block;font-size:22px;margin-top:14px;letter-spacing:.02em}
82
- .splash-inner span{font-size:12.5px;opacity:.85}
83
- @media (prefers-reduced-motion: no-preference){.splash-inner svg path{stroke-dasharray:100;stroke-dashoffset:100;animation:drawStroke 1.2s cubic-bezier(.4,0,.2,1) forwards}}
84
- @media (prefers-reduced-motion: reduce){#splash{display:none}}
85
- .hidden{display:none}
86
- .kban{background:#fef3c7;border:1px solid #f59e0b;color:#92400e;border-radius:12px;padding:12px 14px;margin:10px 0;font-weight:700;font-size:15px}
87
- .chip{background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.35);border-radius:999px;padding:5px 12px;font-size:13px;font-weight:600}
88
- .foot{text-align:center;padding:6px 16px 16px}
89
- .foot .copyr{font-size:12px;color:var(--muted)}
90
- .eye{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;font-size:18px;cursor:pointer;padding:4px}
91
- .passwrap{position:relative}
92
- .loginerr{background:#fee2e2;color:#b91c1c;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
93
- .loginok{background:#dcfce7;color:#15803d;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
94
- .note{color:var(--muted);font-size:13px}
95
- .hint{font-size:12.5px;color:var(--muted);margin-top:4px}
96
- .listen{display:block;width:100%;border:none;border-radius:24px;padding:34px 16px;font-size:28px;font-weight:800;color:#fff;background:var(--green);box-shadow:0 6px 20px rgba(34,197,94,.4);margin:14px 0}
97
- .listen:active{transform:scale(.98)}
98
- .listen.pulse{animation:pulse 1.6s infinite}
99
- @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(34,197,94,.55)}70%{box-shadow:0 0 0 26px rgba(34,197,94,0)}100%{box-shadow:0 0 0 0 rgba(34,197,94,0)}}
100
- .stopbtn{background:var(--red)!important;box-shadow:0 6px 20px rgba(239,68,68,.35)!important}
101
- .row{display:flex;gap:8px;flex-wrap:wrap}
102
- .row .btn{flex:1;min-width:110px}
103
- .switchuser{margin-top:26px;text-align:center}
104
- .langs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:8px 0 14px}
105
- .langov{position:fixed;inset:0;background:linear-gradient(160deg,#4D6BFE,#7c5cff 60%,#a78bfa);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:110;animation:rise .3s ease}
106
- .langov .top{position:absolute;top:22px;right:26px}
107
- .langov .close{background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.3);color:#fff;border-radius:999px;width:44px;height:44px;font-size:18px;cursor:pointer}
108
- .orow{width:min(520px,92vw);display:flex;justify-content:space-between;align-items:center;padding:15px 22px;border-radius:14px;font-size:19px;color:#fff;cursor:pointer;transition:background .15s,transform .1s}
109
- .orow:hover{background:rgba(255,255,255,.12)}
110
- .orow:active{transform:scale(.98)}
111
- .orow .sub{font-size:13px;opacity:.7}
112
- .orow.center{background:rgba(255,255,255,.30);font-size:23px;font-weight:800;border:1px solid rgba(255,255,255,.45)}
113
- .orow.center .sub{opacity:.9}
114
- #langStep{position:fixed;inset:0;background:linear-gradient(160deg,#4D6BFE,#7c5cff 60%,#a78bfa);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:95;transition:opacity .45s,visibility .45s;animation:stepin .55s ease}
115
- @keyframes stepin{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
116
- #langStep.done{opacity:0;visibility:hidden}
117
- .langstep-inner{text-align:center}
118
- .langstep-hint{color:rgba(255,255,255,.9);font-size:14px;margin:18px 0 4px}
119
- .langstep-inner .langreel{width:min(340px,86vw);background:rgba(167,139,250,.55)!important;border:1px solid rgba(255,255,255,.6)!important;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
120
- .langstep-inner svg{width:150px;height:150px}
121
- .langstep-inner svg path.draw{stroke-dasharray:100;animation:drawStroke 1.2s cubic-bezier(.4,0,.2,1) forwards}
122
- @media (prefers-reduced-motion: reduce){.langstep-inner svg path.draw{animation:none}}
123
- #loginView{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;box-shadow:none;text-align:center}
124
- #loginView h2,#loginView .loginbrand h2{color:#fff}
125
- #loginView .loginbrand p,#loginView .hint,#loginView .note{color:rgba(255,255,255,.82)}
126
- #loginView input,#loginView select{background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.35);color:#fff}
127
- #loginView input::placeholder{color:rgba(255,255,255,.7)}
128
- #loginView .loginerr{background:rgba(239,68,68,.25);color:#fff;border:1px solid rgba(255,255,255,.3)}
129
- #loginView .eye{color:#fff}
130
- #loginView .btn.gray{background:rgba(255,255,255,.16);color:#fff;border:1px solid rgba(255,255,255,.3)}
131
- .langreel{width:min(340px,86vw);height:58px;margin:10px auto;background:rgba(167,139,250,.45);border:1px solid rgba(255,255,255,.55);border-radius:10px;backdrop-filter:blur(14px);overflow:hidden;cursor:pointer;position:relative;box-shadow:0 10px 30px rgba(76,29,149,.20)}
132
- body.dark .langreel{background:rgba(124,92,255,.35)}
133
- .ticks{display:flex;flex-direction:column;will-change:transform}
134
- .tick{height:58px;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;opacity:.85;color:#fff}
135
- .pill{background:var(--card);border:1px solid var(--line);border-radius:999px;padding:8px 13px;font-size:13px;cursor:pointer}
136
- .pill.active{background:var(--blue);color:#fff;border-color:var(--blue)}
137
- .person{background:var(--card2);border:1px solid var(--line);border-radius:16px;padding:14px;margin:10px 0}
138
- .person .pname{font-size:17px;font-weight:700;margin-bottom:8px}
139
- .req{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card);border:1px solid var(--line2);margin:6px 0}
140
- .req .txt{flex:1;font-size:15px}
141
- .req .tier{font-size:12px;font-weight:700;padding:4px 8px;border-radius:999px}
142
- .sentline{font-size:12px;color:#16a34a;margin-top:4px;font-weight:600}
143
- .pcnt{font-size:12.5px;color:var(--muted);font-weight:600;margin-left:6px}
144
- .tier-GREEN{background:#dcfce7;color:#15803d}
145
- .tier-SEMI{background:#fef9c3;color:#a16207}
146
- .tier-YELLOW{background:#fef9c3;color:#a16207}
147
- .tier-RED{background:#fee2e2;color:#b91c1c}
148
- .confirmBtn{background:var(--blue);color:#fff;border:none;border-radius:12px;padding:10px 14px;font-size:14px;font-weight:700;white-space:nowrap}
149
- .confirmBtn.done{background:#dcfce7;color:#15803d}
150
- .order{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card2);border:1px solid var(--line);margin:6px 0;font-size:14px}
151
- .order .stat{font-size:12px;font-weight:700;padding:4px 10px;border-radius:999px;background:#e0e7ff;color:#3730a3}
152
- #wallView{max-width:1100px}
153
- .wall-head{font-size:34px;font-weight:800;color:#fff;text-align:center;margin:10px 0}
154
- .wall-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
155
- .wall-card{background:#1b2436;color:#fff;border-radius:16px;padding:20px;text-align:center}
156
- .wall-card .v{font-size:44px;font-weight:800}
157
- .wall-card .l{font-size:15px;opacity:.85}
158
- .wall-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:6px 0 16px;flex-wrap:wrap}
159
- .wall-brand{display:flex;align-items:center;gap:10px;color:#fff}
160
- .wall-brand b{font-size:20px;display:block}
161
- .wall-brand span{font-size:12px;opacity:.75;text-transform:uppercase;letter-spacing:.06em}
162
- .wall-clock{text-align:right;color:#fff}
163
- .wall-clock b{font-size:20px;display:block}
164
- .wall-clock span{font-size:12px;opacity:.75}
165
- .live-dot{display:flex;align-items:center;gap:7px;color:#4ade80;font-weight:800;font-size:13px;letter-spacing:.08em}
166
- .live-dot::before{content:"";width:9px;height:9px;border-radius:50%;background:#4ade80;animation:pulse 1.6s infinite}
167
- .wtick{background:#1b2436;color:#d7e3f4;border-radius:10px;padding:8px 12px;font-size:13.5px;margin:6px 0}
168
- .wtick.dim{color:#64748b;background:none;border:1px dashed #334155}
169
- .wall-note{color:#64748b;font-size:12px;text-align:center;margin-top:10px}
170
- .welcome{position:relative;border-left:4px solid var(--blue);animation:rise .4s ease}
171
- .welcome .wclose{position:absolute;top:10px;right:10px;background:none;border:none;font-size:16px;color:var(--muted);cursor:pointer}
172
- button{transition:transform .12s ease}
173
- button:active{transform:scale(.97)}
174
- button:focus-visible,.pill:focus-visible,input:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
175
- body.wall{background:linear-gradient(165deg,#0b1220 0%,#131c30 60%,#1e1b4b 100%);background-attachment:fixed}
176
- body.firstboot header,body.firstboot main,body.firstboot footer{display:none}
177
- body.wall pre{max-height:40vh}
178
- @media (max-width:560px){header h1{font-size:15px}.listen{font-size:24px;padding:26px 12px}input,select,textarea,button{font-size:16px}}
179
- </style>
180
11
  </head>
181
12
  <body>
182
13
  <div id="langOverlay" class="langov hidden" style="display:none">
@@ -391,377 +222,8 @@ body.wall pre{max-height:40vh}
391
222
  <div id="msg" class="note" style="text-align:center"></div>
392
223
  </main>
393
224
  <footer class="foot"><div class="langs" id="footLangs"></div><div class="copyr">Le Veilleux ยท open source (MIT) ยท autor J.Franco</div><div class="copyr" id="verBadge" style="opacity:.75;margin-top:2px"></div></footer>
394
- <script>
395
- "use strict";
396
- const LANG={es:"ES",en:"EN",fr:"FR",de:"DE",it:"IT",pt:"PT",zh:"ไธญๆ–‡",ja:"ๆ—ฅๆœฌ่ชž",ko:"ํ•œ๊ตญ์–ด",ar:"ุงู„ุนุฑุจูŠุฉ"};
397
- const S={
398
- en:{login:"Log in",user:"User",password:"Password",loginBtn:"Log in",loginHint:"Accounts are managed by the business owner.",loginFailed:"Login failed.",cannotReach:"Cannot reach the supervisor server. Is it running?",workerAdded:"Worker added.",saved:"Saved.",reportSent:"Report sent.",feedbackSent:"Feedback sent.",wallOpen:"Live wallboard",logout:"Log out",overview:"Overview",field:"Field",rules:"Rules",reports:"Reports",week:"This week",feedback:"Feedback",workersActive:"Workers active",reportsTotal:"Reports total",workers:"Workers",thUser:"User",thRole:"Role",addWorker:"Add worker",userName:"User name",addBtn:"Add worker",usage:"Usage & cost",usageSub:"(per worker, estimated)",thWorker:"Worker",thSessions:"Sessions",thTokens:"Tokens",thCost:"Est. cost",panel:"Action Panel",panelNote:"Workers open the panel from their tablet or phone.",openPanel:"Open Action Panel",fieldReports:"Field reports",feedbackQueue:"Feedback queue",feedbackHint:"The agent reads this queue and resolves errors and improvements.",refresh:"Refresh",autoOn:"Auto-refresh: ON",autoOff:"Auto-refresh: OFF",rulesTitle:"Business rules",rulesHint:"These rules train the traffic light.",saveRules:"Save rules",listen:"๐ŸŽ™๏ธ LISTEN",hi:"๐Ÿ‘‹ ",reportTitle:"Field report",reportPh:"What happened on your shift?",sendReport:"Send report",fbTitle:"Field feedback",fbPh:"What happened? What should improve?",sendFeedback:"Send feedback",switchUser:"Switch user",wallHead:"๐Ÿญ Le Veilleux โ€” Live",wallPulse:"Field pulse",noActivity:"(no field activity yet)",start:"โ–ถ START",listening:"Listeningโ€ฆ speak now",listeningHint:"The conversation is being captured and split by person.",stopListening:"โน Stop listening",summaryTitle:"Conversation summary",confirm:"Confirm โœ“",confirmed:"Confirmed โœ“",sentNote:"Sent to kitchen & central",newConv:"New conversation",ordersTitle:"Orders โ€” kitchen & bill",person:"Person",noSummary:"The summary will appear here as the conversation is detected.",prep:"Preparing",ready:"Ready",delivered:"Delivered",sent:"Sent",back:"Back",sayPh:"Speak or type what each person saidโ€ฆ",sendPhrase:"Send phrase",dictate:"๐ŸŽ™๏ธ Dictate",aiHint:"Speech and text go straight to the AI โ€” the summary appears automatically.",micUnsupported:"Dictation not supported in this browser",processing:"The AI is summarizingโ€ฆ",sectorTab:"Sector",sectorPresets:"Sector presets",customSector:"Custom sector",saveSector:"Save sector",sectorSaved:"Sector saved.",aiSuggest:"Suggest with AI (copy prompt)",aiSectorCopied:"AI prompt copied โ€” paste it in DeepSeek Harness.",fillBoth:"Enter your user and password.",loggingIn:"Logging inโ€ฆ",noOrders:"No orders yet โ€” confirm items in the summary.",noUsage:"No usage reported yet.",noReports:"No field reports yet.",lvlEmployee:"Field",lvlLead:"Supervisor",lvlOwner:"Owner",labelPh:"Role label (e.g. Cook)",newOrder:"NEW ORDER",enableNotif:"๐Ÿ”” Enable notifications",notifHint:"The kitchen tablet beeps and flashes when an order arrives.",tagline:"The AI works. The human watches, decides, reviews.",welcomeTitle:"Welcome to Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"Three steps to your first live flow: 1) Add your workers. 2) Choose your sector. 3) Run a real conversation โ€” the AI proposes, you confirm.",wallNote:"Updates every 30 s",tierGREEN:"Auto",tierSEMI:"Semi",tierYELLOW:"Proposal",tierRED:"Ask",export:"โฌ‡ Export reports",exportOrders:"โฌ‡ Export bill",exportDone:"Export downloaded.",deepTitle:"Deep analysis (Reasoner)",deepPh:"Ask a deep questionโ€ฆ",deepSend:"Ask deep",deepSent:"Sent to the Reasoner brain.",deepHint:"The Reasoner brain thinks deeply and appends its answer to the reports.",budget:"Today's budget",budgetReached:"Limit reached โ€” raise it in Settings.",paid:"๐Ÿ’ต Paid",markPaid:"Mark paid",billSummary:"Collected: X of Y orders",regTitle:"๐Ÿช™ Virtual register",regOpen:"Open register",regItem:"Item",regPrice:"Price",regAdd:"Add",regTotal:"Total",regSale:"๐Ÿ’ณ Record sale",regHint:"Record the sale here, then charge the customer with the physical terminal.",regClose:"Close register",regDeclared:"Terminal total at close",regDayTitle:"๐Ÿช™ Day register (counter-audit)",regRecorded:"Recorded (Le Veilleux)",regDeclared2:"Declared (terminal)",regVariance:"Variance",exportReg:"โฌ‡ Export Z-report",regSearch:"Search itemsโ€ฆ",allMethods:"All",cash:"Cash",card:"Card",terminal:"Terminal",salesToday:"sales today",setupTitle:"Create your Le Veilleux",setupUser:"Your name (the owner)",setupPass:"Password (min. 8 characters)",setupBtn:"Create my Le Veilleux",setupHint:"First run: create the owner account. This becomes your login."},
399
- es:{login:"Iniciar sesiรณn",user:"Usuario",password:"Contraseรฑa",loginBtn:"Entrar",loginHint:"Las cuentas las gestiona el dueรฑo del negocio.",loginFailed:"Datos incorrectos.",cannotReach:"No se puede contactar el servidor. ยฟEstรก corriendo?",workerAdded:"Trabajador aรฑadido.",saved:"Guardado.",reportSent:"Reporte enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Wallboard en vivo",logout:"Salir",overview:"Resumen",field:"Campo",rules:"Reglas",reports:"Reportes",week:"Esta semana",feedback:"Feedback",workersActive:"Trabajadores activos",reportsTotal:"Reportes totales",workers:"Trabajadores",thUser:"Usuario",thRole:"Rol",addWorker:"Aรฑadir trabajador",userName:"Nombre de usuario",addBtn:"Aรฑadir trabajador",usage:"Uso y coste",usageSub:"(por trabajador, estimado)",thWorker:"Trabajador",thSessions:"Sesiones",thTokens:"Tokens",thCost:"Coste est.",panel:"Panel de Acciรณn",panelNote:"Los trabajadores abren el panel desde su tablet o telรฉfono.",openPanel:"Abrir Panel de Acciรณn",fieldReports:"Reportes de campo",feedbackQueue:"Cola de feedback",feedbackHint:"El agente lee esta cola y resuelve errores y mejoras.",refresh:"Actualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Reglas del negocio",rulesHint:"Estas reglas entrenan el semรกforo.",saveRules:"Guardar reglas",listen:"๐ŸŽ™๏ธ ESCUCHAR",hi:"๐Ÿ‘‹ ",reportTitle:"Reporte de campo",reportPh:"ยฟQuรฉ pasรณ en tu turno?",sendReport:"Enviar reporte",fbTitle:"Feedback de campo",fbPh:"ยฟQuรฉ pasรณ? ยฟQuรฉ debe mejorar?",sendFeedback:"Enviar feedback",switchUser:"Cambiar de usuario",wallHead:"๐Ÿญ Le Veilleux โ€” En vivo",wallPulse:"Pulso del campo",noActivity:"(sin actividad de campo aรบn)",start:"โ–ถ INICIAR",listening:"Escuchandoโ€ฆ habla ahora",listeningHint:"La conversaciรณn se captura y divide por persona.",stopListening:"โน Detener",summaryTitle:"Resumen de la conversaciรณn",confirm:"Confirmar โœ“",confirmed:"Confirmado โœ“",sentNote:"Enviado a cocina y central",newConv:"Nueva conversaciรณn",ordersTitle:"Pedidos โ€” cocina y cuenta",person:"Persona",noSummary:"El resumen aparecerรก aquรญ conforme se detecta la conversaciรณn.",prep:"Preparando",ready:"Listo",delivered:"Entregado",sent:"Enviado",back:"Volver",sayPh:"Habla o escribe lo que dijo cada personaโ€ฆ",sendPhrase:"Enviar frase",dictate:"๐ŸŽ™๏ธ Dictar",aiHint:"Voz y texto van directo a la IA โ€” el resumen aparece solo.",micUnsupported:"Dictado no soportado en este navegador",processing:"La IA estรก resumiendoโ€ฆ",sectorTab:"Sector",sectorPresets:"Sectores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar sector",sectorSaved:"Sector guardado.",aiSuggest:"Sugerir con IA (copiar prompt)",aiSectorCopied:"Prompt de IA copiado โ€” pรฉgalo en DeepSeek Harness.",fillBoth:"Escribe tu usuario y contraseรฑa.",loggingIn:"Entrandoโ€ฆ",noOrders:"Aรบn no hay pedidos โ€” confirma elementos en el resumen.",noUsage:"Aรบn no hay uso reportado.",noReports:"Aรบn no hay reportes de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dueรฑo",labelPh:"Etiqueta de rol (ej. Cocinero)",newOrder:"NUEVO PEDIDO",enableNotif:"๐Ÿ”” Activar notificaciones",notifHint:"La tablet de cocina suena y parpadea cuando llega un pedido.",tagline:"La IA trabaja. El humano vela, decide, revisa.",welcomeTitle:"Bienvenido a Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"Tres pasos para tu primer flujo en vivo: 1) Aรฑade a tus trabajadores. 2) Elige tu sector. 3) Corre una conversaciรณn real โ€” la IA propone, tรบ confirmas.",wallNote:"Se actualiza cada 30 s",tierGREEN:"Auto",tierSEMI:"Semi",tierYELLOW:"Propuesta",tierRED:"Preguntar",export:"โฌ‡ Exportar reportes",exportOrders:"โฌ‡ Exportar cuenta",exportDone:"Exportaciรณn descargada.",deepTitle:"Anรกlisis profundo (Reasoner)",deepPh:"Haz una pregunta profundaโ€ฆ",deepSend:"Preguntar",deepSent:"Enviada al cerebro Reasoner.",deepHint:"El cerebro Reasoner piensa a fondo y anexa su respuesta a los reportes.",budget:"Presupuesto de hoy",budgetReached:"Lรญmite alcanzado โ€” sรบbelo en Ajustes.",paid:"๐Ÿ’ต Pagado",markPaid:"Marcar pagado",billSummary:"Cobrado: X de Y pedidos",regTitle:"๐Ÿช™ Caja virtual",regOpen:"Abrir caja",regItem:"Artรญculo",regPrice:"Precio",regAdd:"Aรฑadir",regTotal:"Total",regSale:"๐Ÿ’ณ Registrar venta",regHint:"Registra la venta aquรญ y cobra con la terminal fรญsica.",regClose:"Cerrar caja",regDeclared:"Total de la terminal al cierre",regDayTitle:"๐Ÿช™ Caja del dรญa (contra-auditorรญa)",regRecorded:"Registrado (Le Veilleux)",regDeclared2:"Declarado (terminal)",regVariance:"Diferencia",exportReg:"โฌ‡ Exportar reporte Z",regSearch:"Buscar artรญculosโ€ฆ",allMethods:"Todos",cash:"Efectivo",card:"Tarjeta",terminal:"Terminal",salesToday:"ventas hoy",setupTitle:"Crea tu Le Veilleux",setupUser:"Tu nombre (el dueรฑo)",setupPass:"Contraseรฑa (mรญn. 8 caracteres)",setupBtn:"Crear mi Le Veilleux",setupHint:"Primer arranque: crea la cuenta del dueรฑo. Serรก tu acceso."},
400
- fr:{login:"Connexion",user:"Utilisateur",password:"Mot de passe",loginBtn:"Se connecter",loginHint:"Les comptes sont gรฉrรฉs par le propriรฉtaire.",loginFailed:"ร‰chec de connexion.",cannotReach:"Serveur injoignable. Est-il lancรฉ ?",workerAdded:"Employรฉ ajoutรฉ.",saved:"Enregistrรฉ.",reportSent:"Rapport envoyรฉ.",feedbackSent:"Feedback envoyรฉ.",wallOpen:"Tableau en direct",logout:"Dรฉconnexion",overview:"Vue d'ensemble",field:"Terrain",rules:"Rรจgles",reports:"Rapports",week:"Cette semaine",feedback:"Feedback",workersActive:"Employรฉs actifs",reportsTotal:"Total rapports",workers:"Employรฉs",thUser:"Utilisateur",thRole:"Rรดle",addWorker:"Ajouter un employรฉ",userName:"Nom d'utilisateur",addBtn:"Ajouter",usage:"Usage et coรปt",usageSub:"(par employรฉ, estimรฉ)",thWorker:"Employรฉ",thSessions:"Sessions",thTokens:"Jetons",thCost:"Coรปt est.",panel:"Panneau d'action",panelNote:"Les employรฉs ouvrent le panneau depuis leur tablette ou tรฉlรฉphone.",openPanel:"Ouvrir le panneau",fieldReports:"Rapports terrain",feedbackQueue:"File de feedback",feedbackHint:"L'agent lit cette file et rรฉsout erreurs et amรฉliorations.",refresh:"Actualiser",autoOn:"Auto : ON",autoOff:"Auto : OFF",rulesTitle:"Rรจgles du commerce",rulesHint:"Ces rรจgles entraรฎnent le feu tricolore.",saveRules:"Enregistrer",listen:"๐ŸŽ™๏ธ ร‰COUTER",hi:"๐Ÿ‘‹ ",reportTitle:"Rapport terrain",reportPh:"Que s'est-il passรฉ pendant votre quart ?",sendReport:"Envoyer",fbTitle:"Feedback terrain",fbPh:"Que s'est-il passรฉ ? Que faut-il amรฉliorer ?",sendFeedback:"Envoyer",switchUser:"Changer d'utilisateur",wallHead:"๐Ÿญ Le Veilleux โ€” En direct",wallPulse:"Pouls du terrain",noActivity:"(aucune activitรฉ)",start:"โ–ถ Dร‰MARRER",listening:"ร‰couteโ€ฆ parlez maintenant",listeningHint:"La conversation est captรฉe et rรฉpartie par personne.",stopListening:"โน Arrรชter",summaryTitle:"Rรฉsumรฉ de la conversation",confirm:"Confirmer โœ“",confirmed:"Confirmรฉ โœ“",sentNote:"Envoyรฉ en cuisine et au central",newConv:"Nouvelle conversation",ordersTitle:"Commandes โ€” cuisine et addition",person:"Personne",noSummary:"Le rรฉsumรฉ apparaรฎtra ici au fil de la conversation.",prep:"En prรฉparation",ready:"Prรชt",delivered:"Servi",sent:"Envoyรฉ",back:"Retour",sayPh:"Parlez ou รฉcrivez ce que chaque personne a ditโ€ฆ",sendPhrase:"Envoyer",dictate:"๐ŸŽ™๏ธ Dicter",aiHint:"La voix et le texte vont directement ร  lโ€™IA โ€” le rรฉsumรฉ apparaรฎt seul.",micUnsupported:"Dictรฉe non prise en charge",processing:"Lโ€™IA rรฉsumeโ€ฆ",sectorTab:"Secteur",sectorPresets:"Secteurs prรฉdรฉfinis",customSector:"Secteur personnalisรฉ",saveSector:"Enregistrer le secteur",sectorSaved:"Secteur enregistrรฉ.",aiSuggest:"Suggรฉrer avec lโ€™IA (copier lโ€™invite)",aiSectorCopied:"Invite copiรฉe โ€” collez-la dans DeepSeek Harness.",fillBoth:"Saisissez votre utilisateur et votre mot de passe.",loggingIn:"Connexionโ€ฆ",noOrders:"Aucune commande โ€” confirmez des รฉlรฉments dans le rรฉsumรฉ.",noUsage:"Aucun usage signalรฉ.",noReports:"Aucun rapport terrain.",lvlEmployee:"Terrain",lvlLead:"Superviseur",lvlOwner:"Propriรฉtaire",labelPh:"Intitulรฉ du rรดle (ex. Cuisinier)",newOrder:"NOUVELLE COMMANDE",enableNotif:"๐Ÿ”” Activer les notifications",notifHint:"La tablette de cuisine sonne et clignote ร  l'arrivรฉe d'une commande.",tagline:"L'IA travaille. L'humain veille, dรฉcide, revoit.",welcomeTitle:"Bienvenue chez Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"Trois รฉtapes vers votre premier flux en direct : 1) Ajoutez vos employรฉs. 2) Choisissez votre secteur. 3) Dรฉroulez une vraie conversation โ€” l'IA propose, vous confirmez.",wallNote:"Mise ร  jour toutes les 30 s",tierGREEN:"Auto",tierSEMI:"Semi",tierYELLOW:"Proposition",tierRED:"Demander",export:"โฌ‡ Exporter les rapports",exportOrders:"โฌ‡ Exporter l'addition",exportDone:"Exportation tรฉlรฉchargรฉe.",deepTitle:"Analyse approfondie (Reasoner)",deepPh:"Posez une question profondeโ€ฆ",deepSend:"Demander",deepSent:"Envoyรฉe au cerveau Reasoner.",deepHint:"Le cerveau Reasoner rรฉflรฉchit en profondeur et ajoute sa rรฉponse aux rapports.",budget:"Budget du jour",budgetReached:"Limite atteinte โ€” augmentez-la dans les rรฉglages.",paid:"๐Ÿ’ต Payรฉ",markPaid:"Marquer payรฉ",billSummary:"Encaissรฉ : X sur Y commandes",regTitle:"๐Ÿช™ Caisse virtuelle",regOpen:"Ouvrir la caisse",regItem:"Article",regPrice:"Prix",regAdd:"Ajouter",regTotal:"Total",regSale:"๐Ÿ’ณ Enregistrer la vente",regHint:"Enregistrez la vente ici, puis encaissez avec le terminal physique.",regClose:"Fermer la caisse",regDeclared:"Total du terminal ร  la fermeture",regDayTitle:"๐Ÿช™ Caisse du jour (contre-audit)",regRecorded:"Enregistrรฉ (Le Veilleux)",regDeclared2:"Dรฉclarรฉ (terminal)",regVariance:"ร‰cart",exportReg:"โฌ‡ Exporter le rapport Z",regSearch:"Rechercher des articlesโ€ฆ",allMethods:"Tous",cash:"Espรจces",card:"Carte",terminal:"Terminal",salesToday:"ventes aujourd'hui",setupTitle:"Crรฉez votre Le Veilleux",setupUser:"Votre nom (le propriรฉtaire)",setupPass:"Mot de passe (min. 8 caractรจres)",setupBtn:"Crรฉer mon Le Veilleux",setupHint:"Premier lancement : crรฉez le compte du propriรฉtaire. Ce sera votre identifiant."},
401
- de:{login:"Anmelden",user:"Benutzer",password:"Passwort",loginBtn:"Anmelden",loginHint:"Konten verwaltet der Inhaber.",loginFailed:"Anmeldung fehlgeschlagen.",cannotReach:"Server nicht erreichbar. Lรคuft er?",workerAdded:"Mitarbeiter hinzugefรผgt.",saved:"Gespeichert.",reportSent:"Bericht gesendet.",feedbackSent:"Feedback gesendet.",wallOpen:"Live-Anzeige",logout:"Abmelden",overview:"รœbersicht",field:"Feld",rules:"Regeln",reports:"Berichte",week:"Diese Woche",feedback:"Feedback",workersActive:"Aktive Mitarbeiter",reportsTotal:"Berichte gesamt",workers:"Mitarbeiter",thUser:"Benutzer",thRole:"Rolle",addWorker:"Mitarbeiter hinzufรผgen",userName:"Benutzername",addBtn:"Hinzufรผgen",usage:"Nutzung & Kosten",usageSub:"(pro Mitarbeiter, geschรคtzt)",thWorker:"Mitarbeiter",thSessions:"Sitzungen",thTokens:"Tokens",thCost:"Kosten ca.",panel:"Aktionspanel",panelNote:"Mitarbeiter รถffnen das Panel auf Tablet oder Handy.",openPanel:"Panel รถffnen",fieldReports:"Feldberichte",feedbackQueue:"Feedback-Warteschlange",feedbackHint:"Der Agent liest diese Warteschlange und behebt Fehler.",refresh:"Aktualisieren",autoOn:"Auto: AN",autoOff:"Auto: AUS",rulesTitle:"Geschรคftsregeln",rulesHint:"Diese Regeln trainieren die Ampel.",saveRules:"Regeln speichern",listen:"๐ŸŽ™๏ธ ZUHร–REN",hi:"๐Ÿ‘‹ ",reportTitle:"Feldbericht",reportPh:"Was ist in Ihrer Schicht passiert?",sendReport:"Senden",fbTitle:"Feld-Feedback",fbPh:"Was ist passiert? Was soll besser werden?",sendFeedback:"Senden",switchUser:"Benutzer wechseln",wallHead:"๐Ÿญ Le Veilleux โ€” Live",wallPulse:"Puls im Feld",noActivity:"(noch keine Aktivitรคt)",start:"โ–ถ STARTEN",listening:"Hรถre zuโ€ฆ sprich jetzt",listeningHint:"Das Gesprรคch wird erfasst und pro Person aufgeteilt.",stopListening:"โน Stopp",summaryTitle:"Gesprรคchsรผbersicht",confirm:"Bestรคtigen โœ“",confirmed:"Bestรคtigt โœ“",sentNote:"An Kรผche & Zentrale gesendet",newConv:"Neues Gesprรคch",ordersTitle:"Bestellungen โ€” Kรผche & Rechnung",person:"Person",noSummary:"Die รœbersicht erscheint hier, sobald das Gesprรคch erkannt wird.",prep:"In Zubereitung",ready:"Fertig",delivered:"Serviert",sent:"Gesendet",back:"Zurรผck",sayPh:"Sprechen oder tippen Sie, was jede Person gesagt hatโ€ฆ",sendPhrase:"Senden",dictate:"๐ŸŽ™๏ธ Diktieren",aiHint:"Sprache und Text gehen direkt an die KI โ€” die รœbersicht erscheint automatisch.",micUnsupported:"Diktat nicht unterstรผtzt",processing:"Die KI fasst zusammenโ€ฆ",sectorTab:"Branche",sectorPresets:"Branchen-Vorlagen",customSector:"Eigene Branche",saveSector:"Branche speichern",sectorSaved:"Branche gespeichert.",aiSuggest:"Mit KI vorschlagen (Prompt kopieren)",aiSectorCopied:"KI-Prompt kopiert โ€” in DeepSeek Harness einfรผgen.",fillBoth:"Benutzer und Passwort eingeben.",loggingIn:"Anmeldungโ€ฆ",noOrders:"Noch keine Bestellungen โ€” Elemente in der รœbersicht bestรคtigen.",noUsage:"Noch keine Nutzung gemeldet.",noReports:"Noch keine Feldberichte.",lvlEmployee:"Feld",lvlLead:"Aufsicht",lvlOwner:"Inhaber",labelPh:"Rollenname (z. B. Koch)",newOrder:"NEUE BESTELLUNG",enableNotif:"๐Ÿ”” Benachrichtigungen aktivieren",notifHint:"Das Kรผchen-Tablet piept und blinkt bei neuer Bestellung.",tagline:"Die KI arbeitet. Der Mensch wacht, entscheidet, prรผft.",welcomeTitle:"Willkommen bei Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"Drei Schritte zu Ihrem ersten Live-Ablauf: 1) Mitarbeiter hinzufรผgen. 2) Branche wรคhlen. 3) Ein echtes Gesprรคch fรผhren โ€” die KI schlรคgt vor, Sie bestรคtigen.",wallNote:"Aktualisiert alle 30 s",tierGREEN:"Auto",tierSEMI:"Semi",tierYELLOW:"Vorschlag",tierRED:"Fragen",export:"โฌ‡ Berichte exportieren",exportOrders:"โฌ‡ Rechnung exportieren",exportDone:"Export heruntergeladen.",deepTitle:"Tiefenanalyse (Reasoner)",deepPh:"Stellen Sie eine tiefe Frageโ€ฆ",deepSend:"Fragen",deepSent:"An das Reasoner-Gehirn gesendet.",deepHint:"Das Reasoner-Gehirn denkt grรผndlich nach und hรคngt die Antwort an die Berichte an.",budget:"Tagesbudget",budgetReached:"Limit erreicht โ€” in den Einstellungen erhรถhen.",paid:"๐Ÿ’ต Bezahlt",markPaid:"Als bezahlt markieren",billSummary:"Kassiert: X von Y Bestellungen",regTitle:"๐Ÿช™ Virtuelle Kasse",regOpen:"Kasse รถffnen",regItem:"Artikel",regPrice:"Preis",regAdd:"Hinzufรผgen",regTotal:"Summe",regSale:"๐Ÿ’ณ Verkauf erfassen",regHint:"Erfassen Sie den Verkauf hier und kassieren Sie am physischen Terminal.",regClose:"Kasse schlieรŸen",regDeclared:"Terminal-Summe beim Abschluss",regDayTitle:"๐Ÿช™ Tageskasse (Gegenprรผfung)",regRecorded:"Erfasst (Le Veilleux)",regDeclared2:"Gemeldet (Terminal)",regVariance:"Abweichung",exportReg:"โฌ‡ Z-Bericht exportieren",regSearch:"Artikel suchenโ€ฆ",allMethods:"Alle",cash:"Bar",card:"Karte",terminal:"Terminal",salesToday:"Verkรคufe heute",setupTitle:"Erstellen Sie Ihr Le Veilleux",setupUser:"Ihr Name (der Inhaber)",setupPass:"Passwort (min. 8 Zeichen)",setupBtn:"Mein Le Veilleux erstellen",setupHint:"Erster Start: Inhaberkonto anlegen. Das wird Ihr Zugang."},
402
- it:{login:"Accedi",user:"Utente",password:"Password",loginBtn:"Accedi",loginHint:"Gli account li gestisce il proprietario.",loginFailed:"Accesso fallito.",cannotReach:"Server non raggiungibile. รˆ in esecuzione?",workerAdded:"Lavoratore aggiunto.",saved:"Salvato.",reportSent:"Report inviato.",feedbackSent:"Feedback inviato.",wallOpen:"Schermo live",logout:"Esci",overview:"Panoramica",field:"Campo",rules:"Regole",reports:"Report",week:"Questa settimana",feedback:"Feedback",workersActive:"Lavoratori attivi",reportsTotal:"Report totali",workers:"Lavoratori",thUser:"Utente",thRole:"Ruolo",addWorker:"Aggiungi lavoratore",userName:"Nome utente",addBtn:"Aggiungi",usage:"Uso e costi",usageSub:"(per lavoratore, stimato)",thWorker:"Lavoratore",thSessions:"Sessioni",thTokens:"Token",thCost:"Costo stim.",panel:"Pannello Azioni",panelNote:"I lavoratori aprono il pannello da tablet o telefono.",openPanel:"Apri il pannello",fieldReports:"Report di campo",feedbackQueue:"Coda feedback",feedbackHint:"L'agente legge questa coda e risolve errori e migliorie.",refresh:"Aggiorna",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regole del negozio",rulesHint:"Queste regole addestrano il semaforo.",saveRules:"Salva regole",listen:"๐ŸŽ™๏ธ ASCOLTA",hi:"๐Ÿ‘‹ ",reportTitle:"Report di campo",reportPh:"Cosa รจ successo nel tuo turno?",sendReport:"Invia",fbTitle:"Feedback di campo",fbPh:"Cosa รจ successo? Cosa va migliorato?",sendFeedback:"Invia",switchUser:"Cambia utente",wallHead:"๐Ÿญ Le Veilleux โ€” Live",wallPulse:"Battito del campo",noActivity:"(nessuna attivitร )",start:"โ–ถ INIZIA",listening:"In ascoltoโ€ฆ parla ora",listeningHint:"La conversazione viene catturata e divisa per persona.",stopListening:"โน Ferma",summaryTitle:"Riepilogo conversazione",confirm:"Conferma โœ“",confirmed:"Confermato โœ“",sentNote:"Inviato a cucina e centrale",newConv:"Nuova conversazione",ordersTitle:"Ordini โ€” cucina e conto",person:"Persona",noSummary:"Il riepilogo apparirร  qui man mano che la conversazione viene rilevata.",prep:"In preparazione",ready:"Pronto",delivered:"Servito",sent:"Inviato",back:"Indietro",sayPh:"Parla o scrivi cosa ha detto ogni personaโ€ฆ",sendPhrase:"Invia",dictate:"๐ŸŽ™๏ธ Detta",aiHint:"Voce e testo vanno direttamente allโ€™IA โ€” il riepilogo appare da solo.",micUnsupported:"Dettatura non supportata",processing:"Lโ€™IA sta riassumendoโ€ฆ",sectorTab:"Settore",sectorPresets:"Settori predefiniti",customSector:"Settore personalizzato",saveSector:"Salva settore",sectorSaved:"Settore salvato.",aiSuggest:"Suggerisci con lโ€™IA (copia prompt)",aiSectorCopied:"Prompt copiato โ€” incollalo in DeepSeek Harness.",fillBoth:"Inserisci utente e password.",loggingIn:"Accessoโ€ฆ",noOrders:"Ancora nessun ordine โ€” conferma elementi nel riepilogo.",noUsage:"Nessun utilizzo segnalato.",noReports:"Nessun report di campo.",lvlEmployee:"Terreno",lvlLead:"Supervisore",lvlOwner:"Proprietario",labelPh:"Etichetta ruolo (es. Cuoco)",newOrder:"NUOVO ORDINE",enableNotif:"๐Ÿ”” Attiva notifiche",notifHint:"Il tablet di cucina suona e lampeggia all'arrivo di un ordine.",tagline:"L'IA lavora. L'umano veglia, decide, rivede.",welcomeTitle:"Benvenuto in Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"Tre passi per il tuo primo flusso dal vivo: 1) Aggiungi i lavoratori. 2) Scegli il settore. 3) Svolgi una conversazione reale โ€” l'IA propone, tu confermi.",wallNote:"Si aggiorna ogni 30 s",tierGREEN:"Auto",tierSEMI:"Semi",tierYELLOW:"Proposta",tierRED:"Chiedere",export:"โฌ‡ Esporta report",exportOrders:"โฌ‡ Esporta conto",exportDone:"Esportazione scaricata.",deepTitle:"Analisi profonda (Reasoner)",deepPh:"Fai una domanda profondaโ€ฆ",deepSend:"Chiedi",deepSent:"Inviata al cervello Reasoner.",deepHint:"Il cervello Reasoner pensa a fondo e aggiunge la risposta ai report.",budget:"Budget di oggi",budgetReached:"Limite raggiunto โ€” alzalo nelle impostazioni.",paid:"๐Ÿ’ต Pagato",markPaid:"Segna pagato",billSummary:"Incassato: X di Y ordini",regTitle:"๐Ÿช™ Cassa virtuale",regOpen:"Apri cassa",regItem:"Articolo",regPrice:"Prezzo",regAdd:"Aggiungi",regTotal:"Totale",regSale:"๐Ÿ’ณ Registra vendita",regHint:"Registra la vendita qui, poi incassa con il terminale fisico.",regClose:"Chiudi cassa",regDeclared:"Totale terminale alla chiusura",regDayTitle:"๐Ÿช™ Cassa del giorno (contro-verifica)",regRecorded:"Registrato (Le Veilleux)",regDeclared2:"Dichiarato (terminale)",regVariance:"Scarto",exportReg:"โฌ‡ Esporta rapporto Z",regSearch:"Cerca articoliโ€ฆ",allMethods:"Tutti",cash:"Contanti",card:"Carta",terminal:"Terminale",salesToday:"vendite oggi",setupTitle:"Crea il tuo Le Veilleux",setupUser:"Il tuo nome (il proprietario)",setupPass:"Password (min. 8 caratteri)",setupBtn:"Crea il mio Le Veilleux",setupHint:"Primo avvio: crea l'account del proprietario. Sarร  il tuo accesso."},
403
- pt:{login:"Entrar",user:"Usuรกrio",password:"Senha",loginBtn:"Entrar",loginHint:"As contas sรฃo geridas pelo dono.",loginFailed:"Falha no login.",cannotReach:"Servidor inacessรญvel. Estรก a correr?",workerAdded:"Trabalhador adicionado.",saved:"Guardado.",reportSent:"Relatรณrio enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Painel ao vivo",logout:"Sair",overview:"Visรฃo geral",field:"Campo",rules:"Regras",reports:"Relatรณrios",week:"Esta semana",feedback:"Feedback",workersActive:"Trabalhadores ativos",reportsTotal:"Total de relatรณrios",workers:"Trabalhadores",thUser:"Usuรกrio",thRole:"Funรงรฃo",addWorker:"Adicionar trabalhador",userName:"Nome de usuรกrio",addBtn:"Adicionar",usage:"Uso e custo",usageSub:"(por trabalhador, estimado)",thWorker:"Trabalhador",thSessions:"Sessรตes",thTokens:"Tokens",thCost:"Custo est.",panel:"Painel de Aรงรฃo",panelNote:"Os trabalhadores abrem o painel no tablet ou telemรณvel.",openPanel:"Abrir painel",fieldReports:"Relatรณrios de campo",feedbackQueue:"Fila de feedback",feedbackHint:"O agente lรช esta fila e resolve erros e melhorias.",refresh:"Atualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regras do negรณcio",rulesHint:"Estas regras treinam o semรกforo.",saveRules:"Guardar regras",listen:"๐ŸŽ™๏ธ OUVIR",hi:"๐Ÿ‘‹ ",reportTitle:"Relatรณrio de campo",reportPh:"O que aconteceu no seu turno?",sendReport:"Enviar",fbTitle:"Feedback de campo",fbPh:"O que aconteceu? O que deve melhorar?",sendFeedback:"Enviar",switchUser:"Trocar de usuรกrio",wallHead:"๐Ÿญ Le Veilleux โ€” Ao vivo",wallPulse:"Pulso do campo",noActivity:"(sem atividade)",start:"โ–ถ INICIAR",listening:"A ouvirโ€ฆ fale agora",listeningHint:"A conversa รฉ captada e dividida por pessoa.",stopListening:"โน Parar",summaryTitle:"Resumo da conversa",confirm:"Confirmar โœ“",confirmed:"Confirmado โœ“",sentNote:"Enviado para cozinha e central",newConv:"Nova conversa",ordersTitle:"Pedidos โ€” cozinha e conta",person:"Pessoa",noSummary:"O resumo aparece aqui conforme a conversa รฉ detetada.",prep:"A preparar",ready:"Pronto",delivered:"Entregue",sent:"Enviado",back:"Voltar",sayPh:"Fale ou escreva o que cada pessoa disseโ€ฆ",sendPhrase:"Enviar",dictate:"๐ŸŽ™๏ธ Ditar",aiHint:"Voz e texto vรฃo direto ร  IA โ€” o resumo aparece sozinho.",micUnsupported:"Ditado nรฃo suportado",processing:"A IA estรก a resumirโ€ฆ",sectorTab:"Setor",sectorPresets:"Setores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar setor",sectorSaved:"Setor guardado.",aiSuggest:"Sugerir com IA (copiar prompt)",aiSectorCopied:"Prompt copiado โ€” cole no DeepSeek Harness.",fillBoth:"Digite usuรกrio e senha.",loggingIn:"A entrarโ€ฆ",noOrders:"Ainda sem pedidos โ€” confirme itens no resumo.",noUsage:"Ainda sem uso reportado.",noReports:"Ainda sem relatรณrios de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dono",labelPh:"Funรงรฃo (ex. Cozinheiro)",newOrder:"NOVO PEDIDO",enableNotif:"๐Ÿ”” Ativar notificaรงรตes",notifHint:"O tablet da cozinha apita e pisca quando chega um pedido.",tagline:"A IA trabalha. O humano vela, decide, revรช.",welcomeTitle:"Bem-vindo ao Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"Trรชs passos para o seu primeiro fluxo ao vivo: 1) Adicione os trabalhadores. 2) Escolha o setor. 3) Faรงa uma conversa real โ€” a IA propรตe, vocรช confirma.",wallNote:"Atualiza a cada 30 s",tierGREEN:"Auto",tierSEMI:"Semi",tierYELLOW:"Proposta",tierRED:"Perguntar",export:"โฌ‡ Exportar relatรณrios",exportOrders:"โฌ‡ Exportar conta",exportDone:"Exportaรงรฃo transferida.",deepTitle:"Anรกlise profunda (Reasoner)",deepPh:"Faรงa uma pergunta profundaโ€ฆ",deepSend:"Perguntar",deepSent:"Enviada ao cรฉrebro Reasoner.",deepHint:"O cรฉrebro Reasoner pensa a fundo e anexa a resposta aos relatรณrios.",budget:"Orรงamento de hoje",budgetReached:"Limite atingido โ€” aumente nas definiรงรตes.",paid:"๐Ÿ’ต Pago",markPaid:"Marcar pago",billSummary:"Recebido: X de Y pedidos",regTitle:"๐Ÿช™ Caixa virtual",regOpen:"Abrir caixa",regItem:"Artigo",regPrice:"Preรงo",regAdd:"Adicionar",regTotal:"Total",regSale:"๐Ÿ’ณ Registar venda",regHint:"Registe a venda aqui e cobre no terminal fรญsico.",regClose:"Fechar caixa",regDeclared:"Total do terminal no fecho",regDayTitle:"๐Ÿช™ Caixa do dia (contra-auditoria)",regRecorded:"Registado (Le Veilleux)",regDeclared2:"Declarado (terminal)",regVariance:"Diferenรงa",exportReg:"โฌ‡ Exportar relatรณrio Z",regSearch:"Pesquisar artigosโ€ฆ",allMethods:"Todos",cash:"Dinheiro",card:"Cartรฃo",terminal:"Terminal",salesToday:"vendas hoje",setupTitle:"Crie o seu Le Veilleux",setupUser:"O seu nome (o dono)",setupPass:"Senha (mรญn. 8 caracteres)",setupBtn:"Criar o meu Le Veilleux",setupHint:"Primeiro arranque: crie a conta do dono. Serรก o seu acesso."},
404
- zh:{login:"็™ปๅฝ•",user:"็”จๆˆท",password:"ๅฏ†็ ",loginBtn:"็™ปๅฝ•",loginHint:"่ดฆๆˆท็”ฑไผไธšไธป็ฎก็†ใ€‚",loginFailed:"็™ปๅฝ•ๅคฑ่ดฅใ€‚",cannotReach:"ๆ— ๆณ•่ฟžๆŽฅๆœๅŠกๅ™จใ€‚ๅฎƒๆ˜ฏๅฆๅœจ่ฟ่กŒ๏ผŸ",workerAdded:"ๅ‘˜ๅทฅๅทฒๆทปๅŠ ใ€‚",saved:"ๅทฒไฟๅญ˜ใ€‚",reportSent:"ๆŠฅๅ‘Šๅทฒๅ‘้€ใ€‚",feedbackSent:"ๅ้ฆˆๅทฒๅ‘้€ใ€‚",wallOpen:"ๅฎžๆ—ถ็œ‹ๆฟ",logout:"้€€ๅ‡บ",overview:"ๆ€ป่งˆ",field:"็Žฐๅœบ",rules:"่ง„ๅˆ™",reports:"ๆŠฅๅ‘Š",week:"ๆœฌๅ‘จ",feedback:"ๅ้ฆˆ",workersActive:"ๆดป่ทƒๅ‘˜ๅทฅ",reportsTotal:"ๆŠฅๅ‘Šๆ€ปๆ•ฐ",workers:"ๅ‘˜ๅทฅ",thUser:"็”จๆˆท",thRole:"่ง’่‰ฒ",addWorker:"ๆทปๅŠ ๅ‘˜ๅทฅ",userName:"็”จๆˆทๅ",addBtn:"ๆทปๅŠ ",usage:"็”จ้‡ไธŽๆˆๆœฌ",usageSub:"๏ผˆๆฏไฝๅ‘˜ๅทฅ๏ผŒไผฐ็ฎ—๏ผ‰",thWorker:"ๅ‘˜ๅทฅ",thSessions:"ไผš่ฏ",thTokens:"Token",thCost:"้ข„ไผฐๆˆๆœฌ",panel:"ๆ“ไฝœ้ขๆฟ",panelNote:"ๅ‘˜ๅทฅๅœจๅนณๆฟๆˆ–ๆ‰‹ๆœบไธŠๆ‰“ๅผ€้ขๆฟใ€‚",openPanel:"ๆ‰“ๅผ€้ขๆฟ",fieldReports:"็ŽฐๅœบๆŠฅๅ‘Š",feedbackQueue:"ๅ้ฆˆ้˜Ÿๅˆ—",feedbackHint:"ๆ™บ่ƒฝไฝ“่ฏปๅ–ๆญค้˜Ÿๅˆ—ๅนถ่งฃๅ†ณ้—ฎ้ข˜ใ€‚",refresh:"ๅˆทๆ–ฐ",autoOn:"่‡ชๅŠจ๏ผšๅผ€",autoOff:"่‡ชๅŠจ๏ผšๅ…ณ",rulesTitle:"ไธšๅŠก่ง„ๅˆ™",rulesHint:"่ฟ™ไบ›่ง„ๅˆ™่ฎญ็ปƒ็บข็ปฟ็ฏใ€‚",saveRules:"ไฟๅญ˜่ง„ๅˆ™",listen:"๐ŸŽ™๏ธ ่†ๅฌ",hi:"๐Ÿ‘‹ ",reportTitle:"็ŽฐๅœบๆŠฅๅ‘Š",reportPh:"ไฝ ็š„็ญๆฌกๅ‘็”Ÿไบ†ไป€ไนˆ๏ผŸ",sendReport:"ๅ‘้€",fbTitle:"็Žฐๅœบๅ้ฆˆ",fbPh:"ๅ‘็”Ÿไบ†ไป€ไนˆ๏ผŸไป€ไนˆ้œ€่ฆๆ”น่ฟ›๏ผŸ",sendFeedback:"ๅ‘้€",switchUser:"ๅˆ‡ๆข็”จๆˆท",wallHead:"๐Ÿญ Le Veilleux โ€” ๅฎžๆ—ถ",wallPulse:"็Žฐๅœบ่„‰ๆ",noActivity:"๏ผˆๆš‚ๆ— ็ŽฐๅœบๆดปๅŠจ๏ผ‰",start:"โ–ถ ๅผ€ๅง‹",listening:"ๆญฃๅœจ่†ๅฌโ€ฆ่ฏท่ฏด่ฏ",listeningHint:"ๅฏน่ฏๆญฃๅœจ่ขซๆ•ๆ‰ๅนถๆŒ‰ไบบๅ‘˜ๅˆ’ๅˆ†ใ€‚",stopListening:"โน ๅœๆญข",summaryTitle:"ๅฏน่ฏๆ‘˜่ฆ",confirm:"็กฎ่ฎค โœ“",confirmed:"ๅทฒ็กฎ่ฎค โœ“",sentNote:"ๅทฒๅ‘้€่‡ณๅŽจๆˆฟไธŽไธญๅคฎ็ณป็ปŸ",newConv:"ๆ–ฐๅฏน่ฏ",ordersTitle:"่ฎขๅ• โ€” ๅŽจๆˆฟไธŽ่ดฆๅ•",person:"ไบบๅ‘˜",noSummary:"้š็€ๅฏน่ฏ่ขซ่ฏ†ๅˆซ๏ผŒๆ‘˜่ฆๅฐ†ๆ˜พ็คบๅœจ่ฟ™้‡Œใ€‚",prep:"ๅˆถไฝœไธญ",ready:"ๅฎŒๆˆ",delivered:"ๅทฒ้€่พพ",sent:"ๅทฒๅ‘้€",back:"่ฟ”ๅ›ž",sayPh:"่ฏดๅ‡บๆˆ–่พ“ๅ…ฅๆฏไธชไบบ่ฏด็š„่ฏโ€ฆโ€ฆ",sendPhrase:"ๅ‘้€",dictate:"๐ŸŽ™๏ธ ๅฌๅ†™",aiHint:"่ฏญ้Ÿณๅ’Œๆ–‡ๅญ—็›ด่พพ AI โ€” ๆ‘˜่ฆ่‡ชๅŠจๅ‡บ็Žฐใ€‚",micUnsupported:"ๆญคๆต่งˆๅ™จไธๆ”ฏๆŒๅฌๅ†™",processing:"AI ๆญฃๅœจๆ€ป็ป“โ€ฆโ€ฆ",sectorTab:"่กŒไธš",sectorPresets:"้ข„่ฎพ่กŒไธš",customSector:"่‡ชๅฎšไน‰่กŒไธš",saveSector:"ไฟๅญ˜่กŒไธš",sectorSaved:"่กŒไธšๅทฒไฟๅญ˜ใ€‚",aiSuggest:"็”จ AI ๅปบ่ฎฎ๏ผˆๅคๅˆถๆ็คบ๏ผ‰",aiSectorCopied:"AI ๆ็คบๅทฒๅคๅˆถ โ€” ็ฒ˜่ดดๅˆฐ DeepSeek Harnessใ€‚",fillBoth:"่ฏท่พ“ๅ…ฅ็”จๆˆทๅๅ’Œๅฏ†็ ใ€‚",loggingIn:"็™ปๅฝ•ไธญโ€ฆโ€ฆ",noOrders:"ๆš‚ๆ— ่ฎขๅ• โ€” ่ฏทๅœจๆ‘˜่ฆไธญ็กฎ่ฎค้กน็›ฎใ€‚",noUsage:"ๆš‚ๆ— ็”จ้‡ๆŠฅๅ‘Šใ€‚",noReports:"ๆš‚ๆ— ็ŽฐๅœบๆŠฅๅ‘Šใ€‚",lvlEmployee:"็Žฐๅœบ",lvlLead:"ไธป็ฎก",lvlOwner:"ไธšไธป",labelPh:"่ง’่‰ฒๆ ‡็ญพ๏ผˆๅฆ‚๏ผšๅŽจๅธˆ๏ผ‰",newOrder:"ๆ–ฐ่ฎขๅ•",enableNotif:"๐Ÿ”” ๅผ€ๅฏ้€š็Ÿฅ",notifHint:"ๆ–ฐ่ฎขๅ•ๅˆฐ่พพๆ—ถๅŽจๆˆฟๅนณๆฟไผšๅ“้“ƒๅนถ้—ช็ƒใ€‚",tagline:"AI ๅทฅไฝœ๏ผŒไบบๆฅๅฎˆๆŠคใ€ๅ†ณๅฎšใ€ๅคๆ ธใ€‚",welcomeTitle:"ๆฌข่ฟŽไฝฟ็”จ Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"ไธ‰ๆญฅๅผ€ๅง‹ๆ‚จ็š„็ฌฌไธ€ไธชๅฎžๆ—ถๆต็จ‹๏ผš1) ๆทปๅŠ ๅ‘˜ๅทฅใ€‚2) ้€‰ๆ‹ฉ่กŒไธšใ€‚3) ่ฟ›่กŒ็œŸๅฎžๅฏน่ฏ โ€” AI ๆ่ฎฎ๏ผŒๆ‚จ็กฎ่ฎคใ€‚",wallNote:"ๆฏ 30 ็ง’ๆ›ดๆ–ฐ",tierGREEN:"่‡ชๅŠจ",tierSEMI:"ๅŠ่‡ชๅŠจ",tierYELLOW:"ๆ่ฎฎ",tierRED:"่ฏข้—ฎ",export:"โฌ‡ ๅฏผๅ‡บๆŠฅๅ‘Š",exportOrders:"โฌ‡ ๅฏผๅ‡บ่ดฆๅ•",exportDone:"ๅฏผๅ‡บๅทฒไธ‹่ฝฝใ€‚",deepTitle:"ๆทฑๅบฆๅˆ†ๆž๏ผˆReasoner๏ผ‰",deepPh:"ๆๅ‡บไธ€ไธชๆทฑๅบฆ้—ฎ้ข˜โ€ฆโ€ฆ",deepSend:"ๆ้—ฎ",deepSent:"ๅทฒๅ‘้€่‡ณ Reasoner ๅคง่„‘ใ€‚",deepHint:"Reasoner ๅคง่„‘ๆทฑๅ…ฅๆ€่€ƒๅนถๅฐ†็ญ”ๆกˆ้™„ๅŠ ๅˆฐๆŠฅๅ‘Šไธญใ€‚",budget:"ไปŠๆ—ฅ้ข„็ฎ—",budgetReached:"ๅทฒ่พพไธŠ้™ โ€” ่ฏทๅœจ่ฎพ็ฝฎไธญๆ้ซ˜ใ€‚",paid:"๐Ÿ’ต ๅทฒไป˜",markPaid:"ๆ ‡่ฎฐๅทฒไป˜",billSummary:"ๅทฒๆ”ถ๏ผšX / Y ๅ•",regTitle:"๐Ÿช™ ่™šๆ‹Ÿๆ”ถ้“ถๅฐ",regOpen:"ๅผ€ๅฐ",regItem:"ๅ•†ๅ“",regPrice:"ไปทๆ ผ",regAdd:"ๆทปๅŠ ",regTotal:"ๅˆ่ฎก",regSale:"๐Ÿ’ณ ่ฎฐๅฝ•้”€ๅ”ฎ",regHint:"ๅœจๆญค่ฎฐๅฝ•้”€ๅ”ฎ๏ผŒ็„ถๅŽ็”จๅฎžไฝ“็ปˆ็ซฏๆ”ถๆฌพใ€‚",regClose:"ๅ…ณๅฐ",regDeclared:"ๅ…ณๅฐๆ—ถ็ปˆ็ซฏๆ€ป้ข",regDayTitle:"๐Ÿช™ ๅฝ“ๆ—ฅๆ”ถ้“ถ๏ผˆๅฏน่ดฆๅฎก่ฎก๏ผ‰",regRecorded:"ๅทฒ่ฎฐๅฝ•๏ผˆLe Veilleux๏ผ‰",regDeclared2:"ๅทฒ็”ณๆŠฅ๏ผˆ็ปˆ็ซฏ๏ผ‰",regVariance:"ๅทฎ้ข",exportReg:"โฌ‡ ๅฏผๅ‡บ Z ๆŠฅ่กจ",regSearch:"ๆœ็ดขๅ•†ๅ“โ€ฆโ€ฆ",allMethods:"ๅ…จ้ƒจ",cash:"็Žฐ้‡‘",card:"้“ถ่กŒๅก",terminal:"็ปˆ็ซฏ",salesToday:"ไปŠๆ—ฅ้”€ๅ”ฎ",setupTitle:"ๅˆ›ๅปบๆ‚จ็š„ Le Veilleux",setupUser:"ๆ‚จ็š„ๅง“ๅ๏ผˆๆ‰€ๆœ‰่€…๏ผ‰",setupPass:"ๅฏ†็ ๏ผˆ่‡ณๅฐ‘8ไธชๅญ—็ฌฆ๏ผ‰",setupBtn:"ๅˆ›ๅปบๆˆ‘็š„ Le Veilleux",setupHint:"้ฆ–ๆฌก่ฟ่กŒ๏ผšๅˆ›ๅปบๆ‰€ๆœ‰่€…่ดฆๆˆท๏ผŒ่ฟ™ๅฐ†ๆˆไธบๆ‚จ็š„็™ปๅฝ•ๆ–นๅผใ€‚"},
405
- ja:{login:"ใƒญใ‚ฐใ‚คใƒณ",user:"ใƒฆใƒผใ‚ถใƒผ",password:"ใƒ‘ใ‚นใƒฏใƒผใƒ‰",loginBtn:"ใƒญใ‚ฐใ‚คใƒณ",loginHint:"ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฏไบ‹ๆฅญไธปใŒ็ฎก็†ใ—ใพใ™ใ€‚",loginFailed:"ใƒญใ‚ฐใ‚คใƒณๅคฑๆ•—ใ€‚",cannotReach:"ใ‚ตใƒผใƒใƒผใซๆŽฅ็ถšใงใใพใ›ใ‚“ใ€‚่ตทๅ‹•ใ—ใฆใ„ใพใ™ใ‹๏ผŸ",workerAdded:"ๅพ“ๆฅญๅ“กใ‚’่ฟฝๅŠ ใ—ใพใ—ใŸใ€‚",saved:"ไฟๅญ˜ใ—ใพใ—ใŸใ€‚",reportSent:"ๅ ฑๅ‘Šใ‚’้€ไฟกใ—ใพใ—ใŸใ€‚",feedbackSent:"ใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏใ‚’้€ไฟกใ—ใพใ—ใŸใ€‚",wallOpen:"ใƒฉใ‚คใƒ–ๆŽฒ็คบๆฟ",logout:"ใƒญใ‚ฐใ‚ขใ‚ฆใƒˆ",overview:"ๆฆ‚่ฆ",field:"็พๅ ด",rules:"ใƒซใƒผใƒซ",reports:"ๅ ฑๅ‘Š",week:"ไปŠ้€ฑ",feedback:"ใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏ",workersActive:"็จผๅƒไธญใฎๅพ“ๆฅญๅ“ก",reportsTotal:"ๅ ฑๅ‘Š็ทๆ•ฐ",workers:"ๅพ“ๆฅญๅ“ก",thUser:"ใƒฆใƒผใ‚ถใƒผ",thRole:"ๅฝนๅ‰ฒ",addWorker:"ๅพ“ๆฅญๅ“กใ‚’่ฟฝๅŠ ",userName:"ใƒฆใƒผใ‚ถใƒผๅ",addBtn:"่ฟฝๅŠ ",usage:"ๅˆฉ็”จ้‡ใจใ‚ณใ‚นใƒˆ",usageSub:"๏ผˆๅพ“ๆฅญๅ“กใ”ใจใ€ๆŽจๅฎš๏ผ‰",thWorker:"ๅพ“ๆฅญๅ“ก",thSessions:"ใ‚ปใƒƒใ‚ทใƒงใƒณ",thTokens:"ใƒˆใƒผใ‚ฏใƒณ",thCost:"ๆŽจๅฎšใ‚ณใ‚นใƒˆ",panel:"ใ‚ขใ‚ฏใ‚ทใƒงใƒณใƒ‘ใƒใƒซ",panelNote:"ๅพ“ๆฅญๅ“กใฏใ‚ฟใƒ–ใƒฌใƒƒใƒˆใ‚„ใ‚นใƒžใƒ›ใงใƒ‘ใƒใƒซใ‚’้–‹ใใพใ™ใ€‚",openPanel:"ใƒ‘ใƒใƒซใ‚’้–‹ใ",fieldReports:"็พๅ ดๅ ฑๅ‘Š",feedbackQueue:"ใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏๅพ…ใก่กŒๅˆ—",feedbackHint:"ใ‚จใƒผใ‚ธใ‚งใƒณใƒˆใŒใ“ใฎ่กŒๅˆ—ใ‚’่ชญใฟใ€ๅ•้กŒใ‚’่งฃๆฑบใ—ใพใ™ใ€‚",refresh:"ๆ›ดๆ–ฐ",autoOn:"่‡ชๅ‹•: ON",autoOff:"่‡ชๅ‹•: OFF",rulesTitle:"ๆฅญๅ‹™ใƒซใƒผใƒซ",rulesHint:"ใ“ใ‚Œใ‚‰ใฎใƒซใƒผใƒซใŒไฟกๅทใ‚’่จ“็ทดใ—ใพใ™ใ€‚",saveRules:"ใƒซใƒผใƒซใ‚’ไฟๅญ˜",listen:"๐ŸŽ™๏ธ ่žใ",hi:"๐Ÿ‘‹ ",reportTitle:"็พๅ ดๅ ฑๅ‘Š",reportPh:"ใ‚ทใƒ•ใƒˆใงไฝ•ใŒใ‚ใ‚Šใพใ—ใŸใ‹๏ผŸ",sendReport:"้€ไฟก",fbTitle:"็พๅ ดใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏ",fbPh:"ไฝ•ใŒ่ตทใใพใ—ใŸใ‹๏ผŸไฝ•ใ‚’ๆ”นๅ–„ใ™ในใ๏ผŸ",sendFeedback:"้€ไฟก",switchUser:"ใƒฆใƒผใ‚ถใƒผๅˆ‡ๆ›ฟ",wallHead:"๐Ÿญ Le Veilleux โ€” ใƒฉใ‚คใƒ–",wallPulse:"็พๅ ดใฎ้ผ“ๅ‹•",noActivity:"๏ผˆใพใ ็พๅ ดๆดปๅ‹•ใชใ—๏ผ‰",start:"โ–ถ ้–‹ๅง‹",listening:"่žใ„ใฆใ„ใพใ™โ€ฆใฉใ†ใž",listeningHint:"ไผš่ฉฑใ‚’ๆ•ๆ‰ใ—ใ€ไบบ็‰ฉใ”ใจใซๅˆ†ใ‘ใฆใ„ใพใ™ใ€‚",stopListening:"โน ๅœๆญข",summaryTitle:"ไผš่ฉฑใฎใพใจใ‚",confirm:"็ขบ่ช โœ“",confirmed:"็ขบ่ชๆธˆใฟ โœ“",sentNote:"ๅŽจๆˆฟใจไธญๅคฎใธ้€ไฟกๆธˆใฟ",newConv:"ๆ–ฐใ—ใ„ไผš่ฉฑ",ordersTitle:"ๆณจๆ–‡ โ€” ๅŽจๆˆฟใจไผš่จˆ",person:"ไบบ",noSummary:"ไผš่ฉฑใŒๆคœๅ‡บใ•ใ‚Œใ‚‹ใจใ“ใ“ใซใพใจใ‚ใŒ่กจ็คบใ•ใ‚Œใพใ™ใ€‚",prep:"่ชฟ็†ไธญ",ready:"ๅฎŒๆˆ",delivered:"ๆไพ›ๆธˆใฟ",sent:"้€ไฟกๆธˆใฟ",back:"ๆˆปใ‚‹",sayPh:"ๅ„ไบบใŒ่ฉฑใ—ใŸๅ†…ๅฎนใ‚’่ฉฑใ™ใ‹ๅ…ฅๅŠ›โ€ฆ",sendPhrase:"้€ไฟก",dictate:"๐ŸŽ™๏ธ ้Ÿณๅฃฐๅ…ฅๅŠ›",aiHint:"้Ÿณๅฃฐใจใƒ†ใ‚ญใ‚นใƒˆใฏ็›ดๆŽฅAIใธ โ€” ใพใจใ‚ใฏ่‡ชๅ‹•ใง่กจ็คบใ•ใ‚Œใพใ™ใ€‚",micUnsupported:"้Ÿณๅฃฐๅ…ฅๅŠ›้žๅฏพๅฟœ",processing:"AIใŒ่ฆ็ด„ไธญโ€ฆ",sectorTab:"ใ‚ปใ‚ฏใ‚ฟใƒผ",sectorPresets:"ใ‚ปใ‚ฏใ‚ฟใƒผใƒ—ใƒชใ‚ปใƒƒใƒˆ",customSector:"ใ‚ซใ‚นใ‚ฟใƒ ใ‚ปใ‚ฏใ‚ฟใƒผ",saveSector:"ใ‚ปใ‚ฏใ‚ฟใƒผใ‚’ไฟๅญ˜",sectorSaved:"ใ‚ปใ‚ฏใ‚ฟใƒผใ‚’ไฟๅญ˜ใ—ใพใ—ใŸใ€‚",aiSuggest:"AIใงๆๆกˆ๏ผˆใƒ—ใƒญใƒณใƒ—ใƒˆใ‚’ใ‚ณใƒ”ใƒผ๏ผ‰",aiSectorCopied:"AIใƒ—ใƒญใƒณใƒ—ใƒˆใ‚’ใ‚ณใƒ”ใƒผใ—ใพใ—ใŸ โ€” DeepSeek Harnessใซ่ฒผใ‚Šไป˜ใ‘ใ€‚",fillBoth:"ใƒฆใƒผใ‚ถใƒผใจใƒ‘ใ‚นใƒฏใƒผใƒ‰ใ‚’ๅ…ฅๅŠ›ใ—ใฆใใ ใ•ใ„ใ€‚",loggingIn:"ใƒญใ‚ฐใ‚คใƒณไธญโ€ฆ",noOrders:"ใพใ ๆณจๆ–‡ใŒใ‚ใ‚Šใพใ›ใ‚“ โ€” ใพใจใ‚ใง้ …็›ฎใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚",noUsage:"ใพใ ๅˆฉ็”จๅ ฑๅ‘ŠใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚",noReports:"ใพใ ็พๅ ดๅ ฑๅ‘ŠใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚",lvlEmployee:"็พๅ ด",lvlLead:"็›ฃ็ฃ",lvlOwner:"ใ‚ชใƒผใƒŠใƒผ",labelPh:"ๅฝนๅ‰ฒๅ๏ผˆไพ‹๏ผš่ชฟ็†ๅธซ๏ผ‰",newOrder:"ๆ–ฐ่ฆๆณจๆ–‡",enableNotif:"๐Ÿ”” ้€š็Ÿฅใ‚’ๆœ‰ๅŠนๅŒ–",notifHint:"ๆณจๆ–‡ใŒๅฑŠใใจๅŽจๆˆฟใ‚ฟใƒ–ใƒฌใƒƒใƒˆใŒ้Ÿณใจ็‚นๆป…ใง็Ÿฅใ‚‰ใ›ใพใ™ใ€‚",tagline:"AIใŒๅƒใใ€ไบบ้–“ใŒ่ฆ‹ๅฎˆใ‚Šใ€ๆฑบใ‚ใ€่ฆ‹็›ดใ™ใ€‚",welcomeTitle:"Le Veilleux ใธใ‚ˆใ†ใ“ใ ๐Ÿ‘๏ธ",welcomeBody:"ๆœ€ๅˆใฎใƒฉใ‚คใƒ–ใƒ•ใƒญใƒผใพใงใฎ3ใ‚นใƒ†ใƒƒใƒ—๏ผš1) ๅพ“ๆฅญๅ“กใ‚’่ฟฝๅŠ ใ€‚2) ใ‚ปใ‚ฏใ‚ฟใƒผใ‚’้ธๆŠžใ€‚3) ๅฎŸ้š›ใฎไผš่ฉฑใ‚’่กŒใ† โ€” AIใŒๆๆกˆใ—ใ€ใ‚ใชใŸใŒ็ขบ่ชใ—ใพใ™ใ€‚",wallNote:"30็ง’ใ”ใจใซๆ›ดๆ–ฐ",tierGREEN:"่‡ชๅ‹•",tierSEMI:"ๅŠ่‡ชๅ‹•",tierYELLOW:"ๆๆกˆ",tierRED:"็ขบ่ช",export:"โฌ‡ ๅ ฑๅ‘Šใ‚’ใ‚จใ‚ฏใ‚นใƒใƒผใƒˆ",exportOrders:"โฌ‡ ไผš่จˆใ‚’ใ‚จใ‚ฏใ‚นใƒใƒผใƒˆ",exportDone:"ใ‚จใ‚ฏใ‚นใƒใƒผใƒˆใ‚’ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใพใ—ใŸใ€‚",deepTitle:"ๆทฑๅฑคๅˆ†ๆž๏ผˆReasoner๏ผ‰",deepPh:"ๆทฑใ„่ณชๅ•ใ‚’ใฉใ†ใžโ€ฆ",deepSend:"่ณชๅ•ใ™ใ‚‹",deepSent:"Reasoner่„ณใซ้€ไฟกใ—ใพใ—ใŸใ€‚",deepHint:"Reasoner่„ณใŒๆทฑใ่€ƒใˆใ€ๅ›ž็ญ”ใ‚’ๅ ฑๅ‘Šใซ่ฟฝ่จ˜ใ—ใพใ™ใ€‚",budget:"ไปŠๆ—ฅใฎไบˆ็ฎ—",budgetReached:"ไธŠ้™ใซ้”ใ—ใพใ—ใŸ โ€” ่จญๅฎšใงๅผ•ใไธŠใ’ใฆใใ ใ•ใ„ใ€‚",paid:"๐Ÿ’ต ๆ”ฏๆ‰•ๆธˆ",markPaid:"ๆ”ฏๆ‰•ๆธˆใซใ™ใ‚‹",billSummary:"ๅ›žๅŽๆธˆใฟ๏ผšYไปถไธญXไปถ",regTitle:"๐Ÿช™ ไปฎๆƒณใƒฌใ‚ธ",regOpen:"ใƒฌใ‚ธใ‚’้–‹ใ",regItem:"ๅ•†ๅ“",regPrice:"ไพกๆ ผ",regAdd:"่ฟฝๅŠ ",regTotal:"ๅˆ่จˆ",regSale:"๐Ÿ’ณ ๅฃฒไธŠใ‚’่จ˜้Œฒ",regHint:"ใ“ใ“ใงๅฃฒไธŠใ‚’่จ˜้Œฒใ—ใ€็‰ฉ็†็ซฏๆœซใงๆฑบๆธˆใ—ใฆใใ ใ•ใ„ใ€‚",regClose:"ใƒฌใ‚ธใ‚’้–‰ใ˜ใ‚‹",regDeclared:"้–‰ๅบ—ๆ™‚ใฎ็ซฏๆœซๅˆ่จˆ",regDayTitle:"๐Ÿช™ ๆ—ฅๆฌกใƒฌใ‚ธ๏ผˆๅฏพ็…ง็›ฃๆŸป๏ผ‰",regRecorded:"่จ˜้Œฒ๏ผˆLe Veilleux๏ผ‰",regDeclared2:"็”ณๅ‘Š๏ผˆ็ซฏๆœซ๏ผ‰",regVariance:"ๅทฎ้ก",exportReg:"โฌ‡ Zใƒฌใƒใƒผใƒˆใ‚’ใ‚จใ‚ฏใ‚นใƒใƒผใƒˆ",regSearch:"ๅ•†ๅ“ใ‚’ๆคœ็ดขโ€ฆ",allMethods:"ใ™ในใฆ",cash:"็พ้‡‘",card:"ใ‚ซใƒผใƒ‰",terminal:"็ซฏๆœซ",salesToday:"ๆœฌๆ—ฅใฎๅฃฒไธŠ",setupTitle:"Le Veilleux ใ‚’ไฝœๆˆ",setupUser:"ใŠๅๅ‰๏ผˆใ‚ชใƒผใƒŠใƒผ๏ผ‰",setupPass:"ใƒ‘ใ‚นใƒฏใƒผใƒ‰๏ผˆ8ๆ–‡ๅญ—ไปฅไธŠ๏ผ‰",setupBtn:"Le Veilleux ใ‚’ไฝœๆˆ",setupHint:"ๅˆๅ›ž่ตทๅ‹•๏ผšใ‚ชใƒผใƒŠใƒผใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‚’ไฝœๆˆใ—ใพใ™ใ€‚ใ“ใ‚ŒใŒใƒญใ‚ฐใ‚คใƒณใซใชใ‚Šใพใ™ใ€‚"},
406
- ko:{login:"๋กœ๊ทธ์ธ",user:"์‚ฌ์šฉ์ž",password:"๋น„๋ฐ€๋ฒˆํ˜ธ",loginBtn:"๋กœ๊ทธ์ธ",loginHint:"๊ณ„์ •์€ ์‚ฌ์—…์ฃผ๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.",loginFailed:"๋กœ๊ทธ์ธ ์‹คํŒจ.",cannotReach:"์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‹คํ–‰ ์ค‘์ธ๊ฐ€์š”?",workerAdded:"์ง์›์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.",saved:"์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.",reportSent:"๋ณด๊ณ ์„œ๋ฅผ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค.",feedbackSent:"ํ”ผ๋“œ๋ฐฑ์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค.",wallOpen:"๋ผ์ด๋ธŒ ๋ณด๋“œ",logout:"๋กœ๊ทธ์•„์›ƒ",overview:"๊ฐœ์š”",field:"ํ˜„์žฅ",rules:"๊ทœ์น™",reports:"๋ณด๊ณ ์„œ",week:"์ด๋ฒˆ ์ฃผ",feedback:"ํ”ผ๋“œ๋ฐฑ",workersActive:"ํ™œ์„ฑ ์ง์›",reportsTotal:"์ด ๋ณด๊ณ ์„œ",workers:"์ง์›",thUser:"์‚ฌ์šฉ์ž",thRole:"์—ญํ• ",addWorker:"์ง์› ์ถ”๊ฐ€",userName:"์‚ฌ์šฉ์ž ์ด๋ฆ„",addBtn:"์ถ”๊ฐ€",usage:"์‚ฌ์šฉ๋Ÿ‰ ๋ฐ ๋น„์šฉ",usageSub:"(์ง์›๋ณ„, ์ถ”์ •)",thWorker:"์ง์›",thSessions:"์„ธ์…˜",thTokens:"ํ† ํฐ",thCost:"์ถ”์ • ๋น„์šฉ",panel:"์•ก์…˜ ํŒจ๋„",panelNote:"์ง์›์€ ํƒœ๋ธ”๋ฆฟ์ด๋‚˜ ํœด๋Œ€ํฐ์—์„œ ํŒจ๋„์„ ์—ฝ๋‹ˆ๋‹ค.",openPanel:"ํŒจ๋„ ์—ด๊ธฐ",fieldReports:"ํ˜„์žฅ ๋ณด๊ณ ์„œ",feedbackQueue:"ํ”ผ๋“œ๋ฐฑ ๋Œ€๊ธฐ์—ด",feedbackHint:"์—์ด์ „ํŠธ๊ฐ€ ์ด ๋Œ€๊ธฐ์—ด์„ ์ฝ๊ณ  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.",refresh:"์ƒˆ๋กœ๊ณ ์นจ",autoOn:"์ž๋™: ON",autoOff:"์ž๋™: OFF",rulesTitle:"์‚ฌ์—… ๊ทœ์น™",rulesHint:"์ด ๊ทœ์น™์ด ์‹ ํ˜ธ๋“ฑ์„ ํ›ˆ๋ จํ•ฉ๋‹ˆ๋‹ค.",saveRules:"๊ทœ์น™ ์ €์žฅ",listen:"๐ŸŽ™๏ธ ๋“ฃ๊ธฐ",hi:"๐Ÿ‘‹ ",reportTitle:"ํ˜„์žฅ ๋ณด๊ณ ์„œ",reportPh:"๊ทผ๋ฌด ์ค‘ ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋‚˜์š”?",sendReport:"๋ณด๋‚ด๊ธฐ",fbTitle:"ํ˜„์žฅ ํ”ผ๋“œ๋ฐฑ",fbPh:"๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋‚˜์š”? ๋ฌด์—‡์„ ๊ฐœ์„ ํ• ๊นŒ์š”?",sendFeedback:"๋ณด๋‚ด๊ธฐ",switchUser:"์‚ฌ์šฉ์ž ์ „ํ™˜",wallHead:"๐Ÿญ Le Veilleux โ€” ๋ผ์ด๋ธŒ",wallPulse:"ํ˜„์žฅ์˜ ๋งฅ๋ฐ•",noActivity:"(ํ˜„์žฅ ํ™œ๋™ ์—†์Œ)",start:"โ–ถ ์‹œ์ž‘",listening:"๋“ฃ๋Š” ์ค‘โ€ฆ ๋ง์”€ํ•˜์„ธ์š”",listeningHint:"๋Œ€ํ™”๋ฅผ ํฌ์ฐฉํ•˜์—ฌ ์‚ฌ๋žŒ๋ณ„๋กœ ๋‚˜๋ˆ„๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.",stopListening:"โน ์ค‘์ง€",summaryTitle:"๋Œ€ํ™” ์š”์•ฝ",confirm:"ํ™•์ธ โœ“",confirmed:"ํ™•์ธ๋จ โœ“",sentNote:"์ฃผ๋ฐฉ ๋ฐ ์ค‘์•™์œผ๋กœ ์ „์†ก๋จ",newConv:"์ƒˆ ๋Œ€ํ™”",ordersTitle:"์ฃผ๋ฌธ โ€” ์ฃผ๋ฐฉ ๋ฐ ๊ณ„์‚ฐ",person:"์‚ฌ๋žŒ",noSummary:"๋Œ€ํ™”๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์š”์•ฝ์ด ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.",prep:"์กฐ๋ฆฌ ์ค‘",ready:"์™„๋ฃŒ",delivered:"์„œ๋น™๋จ",sent:"์ „์†ก๋จ",back:"๋’ค๋กœ",sayPh:"๊ฐ ์‚ฌ๋žŒ์ด ๋งํ•œ ๋‚ด์šฉ์„ ๋งํ•˜๊ฑฐ๋‚˜ ์ž…๋ ฅโ€ฆ",sendPhrase:"๋ณด๋‚ด๊ธฐ",dictate:"๐ŸŽ™๏ธ ๋ฐ›์•„์“ฐ๊ธฐ",aiHint:"์Œ์„ฑ๊ณผ ํ…์ŠคํŠธ๊ฐ€ AI๋กœ ๋ฐ”๋กœ ์ „๋‹ฌ โ€” ์š”์•ฝ์ด ์ž๋™ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.",micUnsupported:"๋ฐ›์•„์“ฐ๊ธฐ ๋ฏธ์ง€์›",processing:"AI๊ฐ€ ์š”์•ฝ ์ค‘โ€ฆ",sectorTab:"์—…์ข…",sectorPresets:"์—…์ข… ํ”„๋ฆฌ์…‹",customSector:"์‚ฌ์šฉ์ž ์ •์˜ ์—…์ข…",saveSector:"์—…์ข… ์ €์žฅ",sectorSaved:"์—…์ข…์ด ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.",aiSuggest:"AI๋กœ ์ œ์•ˆ(ํ”„๋กฌํ”„ํŠธ ๋ณต์‚ฌ)",aiSectorCopied:"AI ํ”„๋กฌํ”„ํŠธ ๋ณต์‚ฌ๋จ โ€” DeepSeek Harness์— ๋ถ™์—ฌ๋„ฃ๊ธฐ.",fillBoth:"์‚ฌ์šฉ์ž์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.",loggingIn:"๋กœ๊ทธ์ธ ์ค‘โ€ฆ",noOrders:"์•„์ง ์ฃผ๋ฌธ์ด ์—†์Šต๋‹ˆ๋‹ค โ€” ์š”์•ฝ์—์„œ ํ•ญ๋ชฉ์„ ํ™•์ธํ•˜์„ธ์š”.",noUsage:"์•„์ง ์‚ฌ์šฉ ๋ณด๊ณ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.",noReports:"์•„์ง ํ˜„์žฅ ๋ณด๊ณ ์„œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.",lvlEmployee:"ํ˜„์žฅ",lvlLead:"๊ฐ๋…",lvlOwner:"์†Œ์œ ์ฃผ",labelPh:"์—ญํ•  ์ด๋ฆ„(์˜ˆ: ์š”๋ฆฌ์‚ฌ)",newOrder:"์ƒˆ ์ฃผ๋ฌธ",enableNotif:"๐Ÿ”” ์•Œ๋ฆผ ํ™œ์„ฑํ™”",notifHint:"์ฃผ๋ฌธ์ด ๋„์ฐฉํ•˜๋ฉด ์ฃผ๋ฐฉ ํƒœ๋ธ”๋ฆฟ์ด ์†Œ๋ฆฌ์™€ ํ•จ๊ป˜ ๊นœ๋ฐ•์ž…๋‹ˆ๋‹ค.",tagline:"AI๊ฐ€ ์ผํ•˜๊ณ  ์‚ฌ๋žŒ์ด ์ง€ํ‚ค๊ณ , ๊ฒฐ์ •ํ•˜๊ณ , ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค.",welcomeTitle:"Le Veilleux์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘๏ธ",welcomeBody:"์ฒซ ๋ผ์ด๋ธŒ ํ๋ฆ„๊นŒ์ง€ 3๋‹จ๊ณ„: 1) ์ง์› ์ถ”๊ฐ€. 2) ์—…์ข… ์„ ํƒ. 3) ์‹ค์ œ ๋Œ€ํ™” ์ง„ํ–‰ โ€” AI๊ฐ€ ์ œ์•ˆํ•˜๊ณ  ๋‹น์‹ ์ด ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.",wallNote:"30์ดˆ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ",tierGREEN:"์ž๋™",tierSEMI:"๋ฐ˜์ž๋™",tierYELLOW:"์ œ์•ˆ",tierRED:"์งˆ๋ฌธ",export:"โฌ‡ ๋ณด๊ณ ์„œ ๋‚ด๋ณด๋‚ด๊ธฐ",exportOrders:"โฌ‡ ๊ณ„์‚ฐ์„œ ๋‚ด๋ณด๋‚ด๊ธฐ",exportDone:"๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.",deepTitle:"์‹ฌ์ธต ๋ถ„์„(Reasoner)",deepPh:"๊นŠ์€ ์งˆ๋ฌธ์„ ํ•˜์„ธ์š”โ€ฆ",deepSend:"์งˆ๋ฌธํ•˜๊ธฐ",deepSent:"Reasoner ๋‘๋‡Œ๋กœ ์ „์†ก๋จ.",deepHint:"Reasoner ๋‘๋‡Œ๊ฐ€ ๊นŠ์ด ์ƒ๊ฐํ•˜๊ณ  ๋‹ต๋ณ€์„ ๋ณด๊ณ ์„œ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.",budget:"์˜ค๋Š˜์˜ ์˜ˆ์‚ฐ",budgetReached:"ํ•œ๋„ ๋„๋‹ฌ โ€” ์„ค์ •์—์„œ ์˜ฌ๋ฆฌ์„ธ์š”.",paid:"๐Ÿ’ต ๊ฒฐ์ œ๋จ",markPaid:"๊ฒฐ์ œ ํ‘œ์‹œ",billSummary:"์ˆ˜๊ธˆ: Y๊ฑด ์ค‘ X๊ฑด",regTitle:"๐Ÿช™ ๊ฐ€์ƒ ๊ธˆ์ „๋“ฑ๋ก๊ธฐ",regOpen:"์‹œ์žฌ ์—ด๊ธฐ",regItem:"ํ’ˆ๋ชฉ",regPrice:"๊ฐ€๊ฒฉ",regAdd:"์ถ”๊ฐ€",regTotal:"ํ•ฉ๊ณ„",regSale:"๐Ÿ’ณ ํŒ๋งค ๊ธฐ๋ก",regHint:"์—ฌ๊ธฐ์— ํŒ๋งค๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ์‹ค์ œ ๋‹จ๋ง๊ธฐ๋กœ ๊ฒฐ์ œํ•˜์„ธ์š”.",regClose:"์‹œ์žฌ ๋งˆ๊ฐ",regDeclared:"๋งˆ๊ฐ ์‹œ ๋‹จ๋ง๊ธฐ ํ•ฉ๊ณ„",regDayTitle:"๐Ÿช™ ์ผ์ผ ์‹œ์žฌ(๋Œ€์กฐ ๊ฐ์‚ฌ)",regRecorded:"๊ธฐ๋ก(Le Veilleux)",regDeclared2:"์‹ ๊ณ (๋‹จ๋ง๊ธฐ)",regVariance:"์ฐจ์•ก",exportReg:"โฌ‡ Z๋ฆฌํฌํŠธ ๋‚ด๋ณด๋‚ด๊ธฐ",regSearch:"ํ’ˆ๋ชฉ ๊ฒ€์ƒ‰โ€ฆ",allMethods:"์ „์ฒด",cash:"ํ˜„๊ธˆ",card:"์นด๋“œ",terminal:"๋‹จ๋ง๊ธฐ",salesToday:"์˜ค๋Š˜์˜ ํŒ๋งค",setupTitle:"Le Veilleux ๋งŒ๋“ค๊ธฐ",setupUser:"์ด๋ฆ„(์†Œ์œ ์ž)",setupPass:"๋น„๋ฐ€๋ฒˆํ˜ธ(8์ž ์ด์ƒ)",setupBtn:"๋‚ด Le Veilleux ๋งŒ๋“ค๊ธฐ",setupHint:"์ฒซ ์‹คํ–‰: ์†Œ์œ ์ž ๊ณ„์ •์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค."},
407
- ar:{login:"ุชุณุฌูŠู„ ุงู„ุฏุฎูˆู„",user:"ุงู„ู…ุณุชุฎุฏู…",password:"ูƒู„ู…ุฉ ุงู„ู…ุฑูˆุฑ",loginBtn:"ุฏุฎูˆู„",loginHint:"ุงู„ุญุณุงุจุงุช ูŠุฏูŠุฑู‡ุง ุตุงุญุจ ุงู„ุนู…ู„.",loginFailed:"ูุดู„ ุชุณุฌูŠู„ ุงู„ุฏุฎูˆู„.",cannotReach:"ุชุนุฐุฑ ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุงู„ุฎุงุฏู…. ู‡ู„ ู‡ูˆ ู‚ูŠุฏ ุงู„ุชุดุบูŠู„ุŸ",workerAdded:"ุชู…ุช ุฅุถุงูุฉ ุงู„ู…ูˆุธู.",saved:"ุชู… ุงู„ุญูุธ.",reportSent:"ุชู… ุฅุฑุณุงู„ ุงู„ุชู‚ุฑูŠุฑ.",feedbackSent:"ุชู… ุฅุฑุณุงู„ ุงู„ู…ู„ุงุญุธุงุช.",wallOpen:"ุงู„ู„ูˆุญุฉ ุงู„ู…ุจุงุดุฑุฉ",logout:"ุฎุฑูˆุฌ",overview:"ู†ุธุฑุฉ ุนุงู…ุฉ",field:"ุงู„ู…ูŠุฏุงู†",rules:"ุงู„ู‚ูˆุงุนุฏ",reports:"ุงู„ุชู‚ุงุฑูŠุฑ",week:"ู‡ุฐุง ุงู„ุฃุณุจูˆุน",feedback:"ุงู„ู…ู„ุงุญุธุงุช",workersActive:"ู…ูˆุธููˆู† ู†ุดุทูˆู†",reportsTotal:"ุฅุฌู…ุงู„ูŠ ุงู„ุชู‚ุงุฑูŠุฑ",workers:"ุงู„ู…ูˆุธููˆู†",thUser:"ุงู„ู…ุณุชุฎุฏู…",thRole:"ุงู„ุฏูˆุฑ",addWorker:"ุฅุถุงูุฉ ู…ูˆุธู",userName:"ุงุณู… ุงู„ู…ุณุชุฎุฏู…",addBtn:"ุฅุถุงูุฉ",usage:"ุงู„ุงุณุชุฎุฏุงู… ูˆุงู„ุชูƒู„ูุฉ",usageSub:"(ู„ูƒู„ ู…ูˆุธูุŒ ุชู‚ุฏูŠุฑูŠ)",thWorker:"ุงู„ู…ูˆุธู",thSessions:"ุงู„ุฌู„ุณุงุช",thTokens:"ุงู„ุฑู…ูˆุฒ",thCost:"ุงู„ุชูƒู„ูุฉ ุงู„ุชู‚ุฏูŠุฑูŠุฉ",panel:"ู„ูˆุญุฉ ุงู„ุฅุฌุฑุงุกุงุช",panelNote:"ูŠูุชุญ ุงู„ู…ูˆุธููˆู† ุงู„ู„ูˆุญุฉ ู…ู† ุฃุฌู‡ุฒุชู‡ู….",openPanel:"ูุชุญ ุงู„ู„ูˆุญุฉ",fieldReports:"ุชู‚ุงุฑูŠุฑ ุงู„ู…ูŠุฏุงู†",feedbackQueue:"ู‚ุงุฆู…ุฉ ุงู„ู…ู„ุงุญุธุงุช",feedbackHint:"ูŠู‚ุฑุฃ ุงู„ูˆูƒูŠู„ ู‡ุฐู‡ ุงู„ู‚ุงุฆู…ุฉ ูˆูŠุญู„ ุงู„ู…ุดูƒู„ุงุช.",refresh:"ุชุญุฏูŠุซ",autoOn:"ุชู„ู‚ุงุฆูŠ: ON",autoOff:"ุชู„ู‚ุงุฆูŠ: OFF",rulesTitle:"ู‚ูˆุงุนุฏ ุงู„ุนู…ู„",rulesHint:"ู‡ุฐู‡ ุงู„ู‚ูˆุงุนุฏ ุชุฏุฑู‘ุจ ุงู„ุฅุดุงุฑุฉ ุงู„ุถูˆุฆูŠุฉ.",saveRules:"ุญูุธ ุงู„ู‚ูˆุงุนุฏ",listen:"๐ŸŽ™๏ธ ุงุณุชู…ุน",hi:"๐Ÿ‘‹ ",reportTitle:"ุชู‚ุฑูŠุฑ ู…ูŠุฏุงู†ูŠ",reportPh:"ู…ุงุฐุง ุญุฏุซ ููŠ ู†ูˆุจุชูƒุŸ",sendReport:"ุฅุฑุณุงู„",fbTitle:"ู…ู„ุงุญุธุงุช ู…ูŠุฏุงู†ูŠุฉ",fbPh:"ู…ุงุฐุง ุญุฏุซุŸ ู…ุง ุงู„ุฐูŠ ูŠุฌุจ ุชุญุณูŠู†ู‡ุŸ",sendFeedback:"ุฅุฑุณุงู„",switchUser:"ุชุจุฏูŠู„ ุงู„ู…ุณุชุฎุฏู…",wallHead:"๐Ÿญ Le Veilleux โ€” ู…ุจุงุดุฑ",wallPulse:"ู†ุจุถ ุงู„ู…ูŠุฏุงู†",noActivity:"(ู„ุง ู†ุดุงุท ุจุนุฏ)",start:"โ–ถ ุงุจุฏุฃ",listening:"ุฃุณุชู…ุนโ€ฆ ุชูุถู„ ุจุงู„ุญุฏูŠุซ",listeningHint:"ูŠุชู… ุงู„ุชู‚ุงุท ุงู„ู…ุญุงุฏุซุฉ ูˆุชู‚ุณูŠู…ู‡ุง ุญุณุจ ุงู„ุฃุดุฎุงุต.",stopListening:"โน ุฅูŠู‚ุงู",summaryTitle:"ู…ู„ุฎุต ุงู„ู…ุญุงุฏุซุฉ",confirm:"ุชุฃูƒูŠุฏ โœ“",confirmed:"ู…ุคูƒุฏ โœ“",sentNote:"ุฃูุฑุณู„ ุฅู„ู‰ ุงู„ู…ุทุจุฎ ูˆุงู„ู†ุธุงู… ุงู„ู…ุฑูƒุฒูŠ",newConv:"ู…ุญุงุฏุซุฉ ุฌุฏูŠุฏุฉ",ordersTitle:"ุงู„ุทู„ุจุงุช โ€” ุงู„ู…ุทุจุฎ ูˆุงู„ุญุณุงุจ",person:"ุดุฎุต",noSummary:"ุณูŠุธู‡ุฑ ุงู„ู…ู„ุฎุต ู‡ู†ุง ู…ุน ุงูƒุชุดุงู ุงู„ู…ุญุงุฏุซุฉ.",prep:"ู‚ูŠุฏ ุงู„ุชุญุถูŠุฑ",ready:"ุฌุงู‡ุฒ",delivered:"ุชู… ุงู„ุชุณู„ูŠู…",sent:"ุฃูุฑุณู„",back:"ุฑุฌูˆุน",sayPh:"ุชุญุฏุซ ุฃูˆ ุงูƒุชุจ ู…ุง ู‚ุงู„ู‡ ูƒู„ ุดุฎุตโ€ฆ",sendPhrase:"ุฅุฑุณุงู„",dictate:"๐ŸŽ™๏ธ ุฅู…ู„ุงุก",aiHint:"ุงู„ุตูˆุช ูˆุงู„ู†ุต ูŠุตู„ุงู† ู…ุจุงุดุฑุฉ ุฅู„ู‰ ุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ โ€” ูŠุธู‡ุฑ ุงู„ู…ู„ุฎุต ุชู„ู‚ุงุฆูŠู‹ุง.",micUnsupported:"ุงู„ุฅู…ู„ุงุก ุบูŠุฑ ู…ุฏุนูˆู…",processing:"ุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ ูŠู„ุฎู‘ุตโ€ฆ",sectorTab:"ุงู„ู‚ุทุงุน",sectorPresets:"ุงู„ู‚ุทุงุนุงุช ุงู„ู…ุญุฏุฏุฉ ู…ุณุจู‚ู‹ุง",customSector:"ู‚ุทุงุน ู…ุฎุตุต",saveSector:"ุญูุธ ุงู„ู‚ุทุงุน",sectorSaved:"ุชู… ุญูุธ ุงู„ู‚ุทุงุน.",aiSuggest:"ุงู‚ุชุฑุญ ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ (ู†ุณุฎ ุงู„ู…ูˆุฌู‡)",aiSectorCopied:"ุชู… ู†ุณุฎ ุงู„ู…ูˆุฌู‡ โ€” ุงู„ุตู‚ู‡ ููŠ DeepSeek Harness.",fillBoth:"ุฃุฏุฎู„ ุงู„ู…ุณุชุฎุฏู… ูˆูƒู„ู…ุฉ ุงู„ู…ุฑูˆุฑ.",loggingIn:"ุฌุงุฑู ุงู„ุฏุฎูˆู„โ€ฆ",noOrders:"ู„ุง ุชูˆุฌุฏ ุทู„ุจุงุช ุจุนุฏ โ€” ุฃูƒู‘ุฏ ุงู„ุนู†ุงุตุฑ ููŠ ุงู„ู…ู„ุฎุต.",noUsage:"ู„ุง ูŠูˆุฌุฏ ุงุณุชุฎุฏุงู… ู…ูุจู„ู‘ุบ ุจุนุฏ.",noReports:"ู„ุง ุชูˆุฌุฏ ุชู‚ุงุฑูŠุฑ ู…ูŠุฏุงู†ูŠุฉ ุจุนุฏ.",lvlEmployee:"ุงู„ู…ูŠุฏุงู†",lvlLead:"ู…ุดุฑู",lvlOwner:"ุงู„ู…ุงู„ูƒ",labelPh:"ู…ุณู…ู‰ ุงู„ุฏูˆุฑ (ู…ุซุงู„: ุทุจุงุฎ)",newOrder:"ุทู„ุจ ุฌุฏูŠุฏ",enableNotif:"๐Ÿ”” ุชูุนูŠู„ ุงู„ุฅุดุนุงุฑุงุช",notifHint:"ูŠุตุฏุฑ ุตูˆุช ูˆูŠูˆู…ุถ ู„ูˆุญ ุงู„ู…ุทุจุฎ ุนู†ุฏ ูˆุตูˆู„ ุทู„ุจ ุฌุฏูŠุฏ.",tagline:"ุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ ูŠุนู…ู„ุŒ ูˆุงู„ุฅู†ุณุงู† ูŠุฑุงู‚ุจ ูˆูŠู‚ุฑุฑ ูˆูŠุฑุงุฌุน.",welcomeTitle:"ู…ุฑุญุจู‹ุง ุจูƒ ููŠ Le Veilleux ๐Ÿ‘๏ธ",welcomeBody:"ุซู„ุงุซ ุฎุทูˆุงุช ู„ุฃูˆู„ ุชุฏูู‚ ู…ุจุงุดุฑ: 1) ุฃุถู ุงู„ุนุงู…ู„ูŠู†. 2) ุงุฎุชุฑ ุงู„ู‚ุทุงุน. 3) ุฃุฌุฑูŠ ู…ุญุงุฏุซุฉ ุญู‚ูŠู‚ูŠุฉ โ€” ุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ ูŠู‚ุชุฑุญ ูˆุฃู†ุช ุชุคูƒุฏ.",wallNote:"ูŠุชุญุฏุซ ูƒู„ 30 ุซุงู†ูŠุฉ",tierGREEN:"ุชู„ู‚ุงุฆูŠ",tierSEMI:"ุดุจู‡ ุชู„ู‚ุงุฆูŠ",tierYELLOW:"ู…ู‚ุชุฑุญ",tierRED:"ุงุณุฃู„",export:"โฌ‡ ุชุตุฏูŠุฑ ุงู„ุชู‚ุงุฑูŠุฑ",exportOrders:"โฌ‡ ุชุตุฏูŠุฑ ุงู„ุญุณุงุจ",exportDone:"ุชู… ุชู†ุฒูŠู„ ุงู„ุชุตุฏูŠุฑ.",deepTitle:"ุชุญู„ูŠู„ ุนู…ูŠู‚ (Reasoner)",deepPh:"ุงุทุฑุญ ุณุคุงู„ู‹ุง ุนู…ูŠู‚ู‹ุงโ€ฆ",deepSend:"ุงุณุฃู„",deepSent:"ุฃูุฑุณู„ ุฅู„ู‰ ุฏู…ุงุบ Reasoner.",deepHint:"ูŠููƒุฑ ุฏู…ุงุบ Reasoner ุจุนู…ู‚ ูˆูŠุถูŠู ุฅุฌุงุจุชู‡ ุฅู„ู‰ ุงู„ุชู‚ุงุฑูŠุฑ.",budget:"ู…ูŠุฒุงู†ูŠุฉ ุงู„ูŠูˆู…",budgetReached:"ุชู… ุจู„ูˆุบ ุงู„ุญุฏ โ€” ุงุฑูุนู‡ ููŠ ุงู„ุฅุนุฏุงุฏุงุช.",paid:"๐Ÿ’ต ู…ุฏููˆุน",markPaid:"ูˆุถุน ุนู„ุงู…ุฉ ู…ุฏููˆุน",billSummary:"ุงู„ู…ูุญุตูŽู‘ู„: X ู…ู† Y ุทู„ุจู‹ุง",regTitle:"๐Ÿช™ ุงู„ุตู†ุฏูˆู‚ ุงู„ุงูุชุฑุงุถูŠ",regOpen:"ุงูุชุญ ุงู„ุตู†ุฏูˆู‚",regItem:"ุงู„ุตู†ู",regPrice:"ุงู„ุณุนุฑ",regAdd:"ุฅุถุงูุฉ",regTotal:"ุงู„ุฅุฌู…ุงู„ูŠ",regSale:"๐Ÿ’ณ ุชุณุฌูŠู„ ุงู„ุจูŠุน",regHint:"ุณุฌู‘ู„ ุงู„ุจูŠุน ู‡ู†ุง ุซู… ุญุตู‘ู„ ุงู„ู…ุจู„ุบ ุจุงู„ุฌู‡ุงุฒ ุงู„ูุนู„ูŠ.",regClose:"ุฅุบู„ุงู‚ ุงู„ุตู†ุฏูˆู‚",regDeclared:"ุฅุฌู…ุงู„ูŠ ุงู„ุฌู‡ุงุฒ ุนู†ุฏ ุงู„ุฅุบู„ุงู‚",regDayTitle:"๐Ÿช™ ุตู†ุฏูˆู‚ ุงู„ูŠูˆู… (ุชุฏู‚ูŠู‚ ู…ู‚ุงุจู„)",regRecorded:"ุงู„ู…ูุณุฌูŽู‘ู„ (Le Veilleux)",regDeclared2:"ุงู„ู…ูุนู„ูŽู† (ุงู„ุฌู‡ุงุฒ)",regVariance:"ุงู„ูุฑู‚",exportReg:"โฌ‡ ุชุตุฏูŠุฑ ุชู‚ุฑูŠุฑ Z",regSearch:"ุงุจุญุซ ุนู† ุงู„ุฃุตู†ุงูโ€ฆ",allMethods:"ุงู„ูƒู„",cash:"ู†ู‚ุฏู‹ุง",card:"ุจุทุงู‚ุฉ",terminal:"ุงู„ุฌู‡ุงุฒ",salesToday:"ู…ุจูŠุนุงุช ุงู„ูŠูˆู…",setupTitle:"ุฃู†ุดุฆ Le Veilleux ุงู„ุฎุงุต ุจูƒ",setupUser:"ุงุณู…ูƒ (ุงู„ู…ุงู„ูƒ)",setupPass:"ูƒู„ู…ุฉ ุงู„ู…ุฑูˆุฑ (8 ุฃุญุฑู ุนู„ู‰ ุงู„ุฃู‚ู„)",setupBtn:"ุฅู†ุดุงุก Le Veilleux ุงู„ุฎุงุต ุจูŠ",setupHint:"ุงู„ุชุดุบูŠู„ ุงู„ุฃูˆู„: ุฃู†ุดุฆ ุญุณุงุจ ุงู„ู…ุงู„ูƒ. ุณูŠุตุจุญ ู‡ุฐุง ุชุณุฌูŠู„ ุฏุฎูˆู„ูƒ."}
408
- };
409
- function haptic(){try{if(navigator.vibrate)navigator.vibrate(25);}catch(e){}if(soundOn){try{const C=window.AudioContext||window.webkitAudioContext;if(!window.__ac)window.__ac=new C();const c=window.__ac;const o=c.createOscillator(),g=c.createGain();o.frequency.value=880;o.connect(g);g.connect(c.destination);g.gain.setValueAtTime(.12,c.currentTime);g.gain.exponentialRampToValueAtTime(.001,c.currentTime+.12);o.start();o.stop(c.currentTime+.12);}catch(e){}}}
410
- const $=id=>document.getElementById(id);
411
- let token=null,me=null,auto=false,cur="en",livePoll=null,PACK=null,recording=false,rec=null,soundOn=true,darkOn=false,kitchenPoll=null,lastOrders=0;
412
- function t(k){return (S[cur]&&S[cur][k])||S.en[k]||k;}
413
- function applyToggles(){document.body.classList.toggle("dark",darkOn);$("darkBtn").textContent=darkOn?"โ˜€๏ธ":"๐ŸŒ™";$("soundBtn").textContent=soundOn?"๐Ÿ”Š":"๐Ÿ”‡";}
414
- $("darkBtn").onclick=()=>{darkOn=!darkOn;try{localStorage.setItem("dsh-dark",darkOn?"1":"0");}catch(e){}applyToggles();};
415
- $("soundBtn").onclick=()=>{soundOn=!soundOn;try{localStorage.setItem("dsh-sound",soundOn?"1":"0");}catch(e){}applyToggles();};
416
- try{darkOn=localStorage.getItem("dsh-dark")==="1";soundOn=localStorage.getItem("dsh-sound")!=="0";}catch(e){}
417
- applyToggles();
418
- document.body.classList.add("loginpage");
419
- const firstRun=(()=>{try{return !localStorage.getItem("dsh-lang");}catch(e){return true;}})();
420
- if(firstRun){
421
- $("splash").style.display="none";
422
- $("loginView").style.display="none";
423
- document.body.classList.add("firstboot");
424
- $("langStep").style.display="flex";
425
- }else{
426
- setTimeout(()=>{$("splash").classList.add("done");},1300);
427
- }
428
- async function reRenderDynamic(){
429
- if(!me)return;
430
- if(me.role==="owner"){loadMetrics($("ownerMetrics"));loadUsers();loadUsage();loadField();renderOrders();renderSuggest();}
431
- else if(me.role==="lead"){loadMetrics($("leadMetrics"));loadLead();renderOrders();}
432
- else{$("workerHi").textContent=t("hi")+(me.label||me.name);workerFlow();}
433
- if(location.search.indexOf("wall=1")>=0)wallTick();
434
- }
435
- async function kitchenWatch(){
436
- const live=await api("/api/live");
437
- const n=(live.orders||[]).length;
438
- if(n>lastOrders&&lastOrders>0){
439
- const o=live.orders[n-1];
440
- $("kitchenBanner").textContent="๐Ÿ”” "+t("newOrder")+": "+o.person+" โ€” "+o.request;
441
- $("kitchenBanner").classList.remove("hidden");
442
- haptic();
443
- try{if("Notification" in window&&Notification.permission==="granted"){new Notification(t("newOrder"),{body:o.person+" โ€” "+o.request});}}catch(e){}
444
- setTimeout(()=>$("kitchenBanner").classList.add("hidden"),6000);
445
- }
446
- lastOrders=n;
447
- }
448
- $("notifBtn").onclick=()=>{
449
- try{
450
- if("Notification" in window&&Notification.permission!=="granted"){
451
- Notification.requestPermission().then(()=>{renderOrders();});
452
- }
453
- }catch(e){}
454
- };
455
- async function doExport(type){
456
- try{
457
- const r=await fetch("/api/export?type="+type,{headers:{"Authorization":"Bearer "+token}});
458
- if(!r.ok){toast("Error");return;}
459
- const blob=await r.blob();
460
- const a=document.createElement("a");a.href=URL.createObjectURL(blob);
461
- const cd=r.headers.get("Content-Disposition")||"";
462
- const m=/filename="?([^";]+)"?/.exec(cd);
463
- a.download=m?m[1]:("le-veilleux-"+type+".md");
464
- document.body.appendChild(a);a.click();a.remove();
465
- toast(t("exportDone"));
466
- }catch(e){toast(t("cannotReach"));}
467
- }
468
- async function loadRegister(){
469
- const r=await api("/api/register");
470
- if(!r||r.error)return;
471
- const open=r.status==="open";
472
- $("regClosed").classList.toggle("hidden",open);
473
- $("regOpenState").classList.toggle("hidden",!open);
474
- if(open){
475
- $("regItems").textContent=(r.items||[]).map(x=>x.name+" โ€” $"+x.price).join(" ยท ");
476
- const cur=Math.round((r.items||[]).reduce((a,x)=>a+x.price,0)*100)/100;
477
- $("regTotal").textContent=t("regTotal")+": $"+cur;
478
- }
479
- if(me&&me.role==="owner"){
480
- if(r.status==="closed"){
481
- $("regDay").innerHTML='<p class="note">'+t("regRecorded")+": $"+r.recorded+" ยท "+t("regDeclared2")+": $"+(r.declared==null?"โ€”":r.declared)+'</p><p class="note" style="'+(r.variance!==null&&Math.abs(r.variance)>0.01?"color:#b45309;font-weight:700":"")+'">'+t("regVariance")+": $"+(r.variance==null?"โ€”":r.variance)+'</p>';
482
- } else {
483
- $("regDay").innerHTML='<p class="hint">โ€”</p>';
484
- }
485
- renderRegSales(r);
486
- }
487
- if(me&&me.role==="employee"){$("regCount").textContent=(r.sales||[]).length+" "+t("salesToday");}
488
- try{api("/api/health").then(hp=>{if(hp&&hp.version)$("verBadge").textContent="supervisor v"+hp.version+" ยท app 0.1.0 ยท dsh "+((hp.workers!==undefined)?"":"")+"runtime";});}catch(e){}
489
- }
490
- function renderRegSales(r){
491
- const q=($("regSearch").value||"").toLowerCase();
492
- const m=$("regMethod").value;
493
- const list=(r.sales||[]).slice().reverse().filter(x=>{
494
- if(m!=="all"&&x.method!==m)return false;
495
- if(q&&!(x.items||[]).some(it=>it.name.toLowerCase().indexOf(q)>=0))return false;
496
- return true;
497
- });
498
- $("regSales").innerHTML=list.length?list.map(x=>'<div class="order"><b>'+esc(x.ts.slice(11,16))+'</b><span class="txt">'+esc((x.items||[]).map(it=>it.name).join(", "))+' ยท '+esc(x.worker||"?")+'</span><span class="stat">$ '+x.total+'</span></div>').join(""):empty("๐Ÿงพ","โ€”");
499
- }
500
- $("regSearch").oninput=()=>{api("/api/register").then(renderRegSales);};
501
- $("regMethod").onchange=()=>{api("/api/register").then(renderRegSales);};
502
- $("regOpen").onclick=async()=>{await api("/api/register/open",{worker:me?me.name:"worker"});loadRegister();};
503
- $("regAdd").onclick=async()=>{const n=$("regItem").value.trim();const p=$("regPrice").value;if(!n||!p)return;await api("/api/register/add",{name:n,price:Number(p)});$("regItem").value="";$("regPrice").value="";loadRegister();};
504
- $("regSale").onclick=async()=>{await api("/api/register/charge",{method:$("regSaleMethod").value});loadRegister();toast(t("regSale"));};
505
- $("regClose").onclick=async()=>{await api("/api/register/close",{declared:Number($("regDeclared").value)||0});loadRegister();};
506
- $("exportRegisterBtn").onclick=()=>doExport("register");
507
- $("deepSend").onclick=async()=>{const v=$("deepText").value.trim();if(!v)return;const r=await api("/api/deep",{worker:me?me.name:"owner",text:v});if(r.error){toast(String(r.error).indexOf("budget")>=0?t("budgetReached"):"Error");return;}$("deepText").value="";toast(t("deepSent"));};
508
- $("exportBtn").onclick=()=>doExport("reports");
509
- $("exportOrdersBtn").onclick=()=>doExport("orders");
510
- function panelLinks(){const u=me?encodeURIComponent(me.name):"",r=me?encodeURIComponent(me.role):"",lb=me?encodeURIComponent(me.label||me.name):"";$("openPanelLink").setAttribute("href","/panel?user="+u+"&role="+r+"&label="+lb+"&lang="+cur);$("leadOpenPanelLink").setAttribute("href","/panel?user="+u+"&role="+r+"&label="+lb+"&lang="+cur);}
511
- function applyLang(){
512
- // (the language is persisted only on an explicit human choice)
513
- $("welcomeClose").onclick=()=>{$("welcomeCard").style.display="none";try{localStorage.setItem("lv-welcome","1");}catch(e){}};
514
- $("splashTag").textContent=t("tagline");
515
- $("welcomeTitle").textContent=t("welcomeTitle");$("welcomeBody").textContent=t("welcomeBody");$("wallNote").textContent=t("wallNote");
516
- $("setupUser").placeholder=t("setupUser");$("setupPass").placeholder=t("setupPass");$("setupBtn").textContent=t("setupBtn");$("setupHint").textContent=t("setupHint");
517
- $("loginTitle").textContent=t("login");$("tagline").textContent=t("tagline");$("loginUser").placeholder=t("user");
518
- ["loginUser","loginPass"].forEach(id=>$(id).addEventListener("input",()=>$("loginError").classList.add("hidden")));$("loginPass").placeholder=t("password");
519
- $("loginBtn").textContent=t("loginBtn");$("loginHint").textContent=t("loginHint");$("openWall").textContent=t("wallOpen");$("logoutBtn").textContent=t("logout");
520
- $("tabOverview").textContent=t("overview");$("tabField").textContent=t("field");$("tabRules").textContent=t("rules");
521
- $("workersTitle").textContent=t("workers");$("thUser").textContent=t("thUser");$("thRole").textContent=t("thRole");
522
- $("addWorkerTitle").textContent=t("addWorker");$("newUser").placeholder=t("userName");$("addUserBtn").textContent=t("addBtn");
523
- $("ordersTitle").textContent=t("ordersTitle");$("leadOrdersTitle").textContent=t("ordersTitle");$("ordersTitle2").textContent=t("ordersTitle");
524
- $("usageTitle").textContent=t("usage");$("usageSub").textContent=t("usageSub");
525
- $("thWorker").textContent=t("thWorker");$("thSessions").textContent=t("thSessions");$("thTokens").textContent=t("thTokens");$("thCost").textContent=t("thCost");
526
- $("panelTitle").textContent=t("panel");$("panelNote").textContent=t("panelNote");$("openPanel").textContent=t("openPanel");
527
- $("fieldReportsTitle").textContent=t("fieldReports");$("feedbackTitle").textContent=t("feedbackQueue");$("feedbackHint").textContent=t("feedbackHint");
528
- $("regSearch").placeholder=t("regSearch");$("regMethod").options[0].textContent=t("allMethods");$("regMethod").options[1].textContent=t("cash");$("regMethod").options[2].textContent=t("card");$("regMethod").options[3].textContent=t("terminal");$("regSaleMethod").options[0].textContent=t("terminal");$("regSaleMethod").options[1].textContent=t("cash");$("regSaleMethod").options[2].textContent=t("card");
529
- $("regTitle").textContent=t("regTitle");$("regOpen").textContent=t("regOpen");$("regItem").placeholder=t("regItem");$("regPrice").placeholder=t("regPrice");$("regAdd").textContent=t("regAdd");$("regSale").textContent=t("regSale");$("regHint").textContent=t("regHint");$("regClose").textContent=t("regClose");$("regDeclared").placeholder=t("regDeclared");$("regDayTitle").textContent=t("regDayTitle");$("exportRegisterBtn").textContent=t("exportReg");
530
- $("deepTitle").textContent=t("deepTitle");$("deepText").placeholder=t("deepPh");$("deepSend").textContent=t("deepSend");$("deepHint").textContent=t("deepHint");
531
- $("refreshReports").textContent=t("refresh");$("exportBtn").textContent=t("export");$("exportOrdersBtn").textContent=t("exportOrders");if(!auto)$("autoRefresh").textContent=t("autoOff");
532
- $("rulesTitle").textContent=t("rulesTitle");$("rulesHint").textContent=t("rulesHint");$("saveDecisions").textContent=t("saveRules");
533
- $("leadReportsTitle").textContent=t("fieldReports");$("leadFeedbackTitle").textContent=t("feedbackQueue");$("leadRefresh").textContent=t("refresh");$("leadOpenPanel").textContent=t("openPanel");
534
- $("startBtn").textContent=t("start");$("listeningText").textContent=t("listening");$("listeningHint").textContent=t("listeningHint");
535
- $("stopBtn").textContent=t("stopListening");$("summaryTitle").textContent=t("summaryTitle");$("newConvBtn").textContent=t("newConv");$("toHomeBtn").textContent=t("back");
536
- $("reportTitle").textContent=t("reportTitle");$("reportText").placeholder=t("reportPh");$("reportBtn").textContent=t("sendReport");
537
- $("fbTitle").textContent=t("fbTitle");$("empFbText").placeholder=t("fbPh");$("empFbBtn").textContent=t("sendFeedback");$("switchBtn").textContent=t("switchUser");
538
- $("wallPulseTitle").textContent=t("wallPulse");
539
- $("notifBtn").textContent=t("enableNotif");$("notifHint").textContent=t("notifHint");
540
- $("optEmployee").textContent=t("lvlEmployee");$("optLead").textContent=t("lvlLead");$("optOwner").textContent=t("lvlOwner");$("newLabel").placeholder=t("labelPh");
541
- $("tabSector").textContent=t("sectorTab");$("bnavOverview").textContent=t("overview");$("bnavField").textContent=t("field");$("bnavRules").textContent=t("rules");$("bnavSector").textContent=t("sectorTab");$("sectorPresetsTitle").textContent=t("sectorPresets");$("customSectorTitle").textContent=t("customSector");$("saveSectorBtn").textContent=t("saveSector");$("aiSectorBtn").textContent=t("aiSuggest");
542
- $("trailTitle").textContent=t("conversationTrail");$("trailHint").textContent=t("trailHint");
543
- $("sayText").placeholder=t("sayPh");$("sayBtn").textContent=t("sendPhrase");$("aiHint").textContent=t("aiHint");if(!recording)$("micBtn").textContent=t("dictate");
544
- document.querySelectorAll(".pill").forEach(p=>p.classList.toggle("active",p.dataset.l===cur));
545
- panelLinks();
546
- reRenderDynamic();
547
- }
548
- const LANGNAMES={es:"Espaรฑol",en:"English",fr:"Franรงais",de:"Deutsch",it:"Italiano",pt:"Portuguรชs",zh:"ไธญๆ–‡",ja:"ๆ—ฅๆœฌ่ชž",ko:"ํ•œ๊ตญ์–ด",ar:"ุงู„ุนุฑุจูŠุฉ"};
549
- const LANGORDER=["it","zh","de","es","en","fr","ja","pt","ko","ar"];
550
- function buildLangMenu(){
551
- const rows=$("langRows");
552
- for(const l of LANGORDER){
553
- const r=document.createElement("div");
554
- r.className="orow"+(l==="en"?" center":"");
555
- r.innerHTML='<span>'+LANGNAMES[l]+'</span><span class="sub">'+l.toUpperCase()+'</span>';
556
- r.onclick=()=>{cur=l;try{localStorage.setItem("dsh-lang",cur);}catch(e){}applyLang();$("langOverlay").style.display="none";markReel();$("langStep").classList.add("done");const sp=$("splash");sp.classList.remove("done");const p=sp.querySelector(".draw");if(p){p.style.animation="none";void p.offsetWidth;p.style.animation="";}setTimeout(()=>{$("loginView").style.display="";document.body.classList.remove("firstboot");},2100);setTimeout(()=>{sp.classList.add("done");},2600);};
557
- rows.appendChild(r);
558
- }
559
- }
560
- function markReel(){
561
- document.querySelectorAll("#langStepTicks .tick").forEach(t=>t.classList.toggle("active",t.dataset.l===cur));
562
- }
563
- function buildReel(ticksId){
564
- for(let pass=0;pass<2;pass++){
565
- for(const l of Object.keys(LANG)){
566
- const d=document.createElement("div");
567
- d.className="tick";d.dataset.l=l;d.textContent=LANGNAMES[l];
568
- $(ticksId).appendChild(d);
569
- }
570
- }
571
- const N=Object.keys(LANG).length,H=58,CYCLE=20000;
572
- const t0=performance.now();
573
- (function frame(now){
574
- const t=(now-t0)%CYCLE;
575
- $(ticksId).style.transform="translateY(-"+((t/CYCLE)*N*H)+"px)";
576
- requestAnimationFrame(frame);
577
- })(t0);
578
- }
579
- buildLangMenu();
580
- buildReel("langStepTicks");
581
- markReel();
582
- $("langStepReel").onclick=()=>{$("langOverlay").style.display="flex";const en=document.querySelector("#langRows .center");if(en)en.scrollIntoView({block:"center"});};
583
- $("closeOverlay").onclick=()=>{$("langOverlay").style.display="none";};
584
- // The Apple flow: after the splash, the language menu opens once (until chosen).
225
+ <script src="./i18n.js"></script>
226
+ <script src="./dashboard.js"></script>
585
227
 
586
- function pill(l){for(const host of ["footLangs"]){const el=$(host);if(!el)continue;const b=document.createElement("button");b.className="pill";b.dataset.l=l;b.textContent=LANG[l];b.onclick=()=>{cur=l;try{localStorage.setItem("dsh-lang",cur);}catch(e){}applyLang();};$(host).appendChild(b);}}
587
- for(const l of Object.keys(LANG))pill(l);
588
- try{const q=new URLSearchParams(location.search);const ql=q.get("lang");if(ql&&S[ql])cur=ql;}catch(e){}
589
- try{const saved=localStorage.getItem("dsh-lang");if(saved&&S[saved])cur=saved;}catch(e){}
590
- applyLang();
591
- function applyPack(){if(!PACK)return;$("tableInput").placeholder=(PACK.tableLabel&&PACK.tableLabel[cur])||"Table";const ot=(PACK.ordersTarget&&PACK.ordersTarget[cur])||t("ordersTitle");$("ordersTitle").textContent=ot;$("leadOrdersTitle").textContent=ot;$("ordersTitle2").textContent=ot;}
592
- const api=async(p,body)=>{try{const r=await fetch(p,{method:body?"POST":"GET",headers:{"Content-Type":"application/json",...(token?{Authorization:"Bearer "+token}:{})},body:body?JSON.stringify(body):undefined});return r.json();}catch(e){return {error:"network"};}};
593
- function show(view){["loginView","ownerView","leadView","employeeView","wallView"].forEach(v=>$(v).classList.add("hidden"));const el=$(view);el.classList.remove("hidden");el.classList.remove("anim");void el.offsetWidth;el.classList.add("anim");document.body.classList.toggle("loginpage",view==="loginView");}
594
- const LVL={employee:"lvlEmployee",lead:"lvlLead",owner:"lvlOwner"};
595
- function setWho(){const w=$("who");w.textContent=me?(me.label||me.name):"";const c=$("idChip");if(me){c.style.display="inline-block";c.textContent=me.name.slice(0,1).toUpperCase()+" ยท "+(me.label||me.name)+" ยท "+t(LVL[me.role]||"lvlEmployee");}else{c.style.display="none";}$("logoutBtn").style.display=me?"inline-block":"none";}
596
- function toast(m){const el=$("toast");el.textContent=m;el.classList.add("show");clearTimeout(el.__t);el.__t=setTimeout(()=>el.classList.remove("show"),2200);}
597
- function skel(n){let out="";for(let i=0;i<n;i++)out+='<div class="skel" style="height:38px;margin:8px 0"></div>';return out;}
598
- const esc=(s)=>String(s==null?"":s).replace(/[&<>"']/g,(c)=>({"&":"&amp;","<":"&lt;",">":"&gt;","\"":"&quot;","'":"&#39;"}[c]));
599
- function empty(ico,txt){return '<div class="empty"><span class="ico">'+ico+'</span>'+txt+'</div>';}
600
- function showMsg(x){$("msg").textContent=x;toast(x);setTimeout(()=>$("msg").textContent="",2500);}
601
- function countUp(el,target,dur){dur=dur||650;const t0=performance.now();const step=(now)=>{const p=Math.min(1,(now-t0)/dur);el.textContent=Math.round(target*p).toLocaleString();if(p<1)requestAnimationFrame(step);};requestAnimationFrame(step);}
602
- async function loadMetrics(into){into.innerHTML=skel(2);const m=await api("/api/metrics");into.innerHTML="";const cards=[[t("reports"),m.reports],[t("week"),m.reportsWeek],[t("feedback"),m.feedback],[t("workersActive"),m.workers]];for(const [l,v] of cards){const d=document.createElement("div");d.className="metric";d.innerHTML='<div class="v">โ€“</div><div class="l">'+l+'</div>';into.appendChild(d);if(typeof v==="number")countUp(d.querySelector(".v"),v);}}
603
- async function loadUsage(){const tb=$("usageTable")?$("usageTable").querySelector("tbody"):null;if(!tb)return;tb.innerHTML='<tr><td colspan="4">'+skel(2)+'</td></tr>';const r=await api("/api/usage");tb.innerHTML="";
604
- if(!(r.rows||[]).length){tb.innerHTML='<tr><td colspan="4">'+empty("๐Ÿ“Š",t("noUsage"))+'</td></tr>';return;}
605
- (r.rows||[]).forEach(x=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+esc(x.worker)+"</td><td>"+x.sessions+"</td><td>"+(x.tokens||0).toLocaleString()+"</td><td>$"+(x.cost||0).toFixed(2)+"</td>";tb.appendChild(tr);});try{const hp=await api("/api/health");if(hp&&hp.budgetUsd!==undefined){const spent=hp.spentTodayUsd||0;if(hp.budgetUsd>0){const pct=hp.budgetPct||0;$("usageBudget").textContent=t("budget")+": $"+spent+" / $"+hp.budgetUsd+" ("+pct+"%)";$("usageBudget").style.color=pct>=80?"#b45309":"";}else{$("usageBudget").textContent=t("budget")+": $"+spent+" โˆž";$("usageBudget").style.color="";}}}catch(e){}}
606
- function orderRow(o,canUpdate){
607
- const d=document.createElement("div");d.className="order";
608
- const stat=document.createElement("span");stat.className="stat";const ICON={sent:"๐Ÿ“ค",prep:"๐Ÿณ",ready:"โœ…",delivered:"๐Ÿ›Ž๏ธ"};
609
- stat.textContent=(ICON[o.status]||"๐Ÿ“ค")+" "+t(o.status||"sent");
610
- if(o.paid){const p=document.createElement("span");p.className="stat";p.style.background="#dcfce7";p.style.color="#15803d";p.textContent=t("paid");d.appendChild(p);}
611
- d.innerHTML="<b>"+(o.table?((PACK&&PACK.tableLabel&&PACK.tableLabel[cur]?PACK.tableLabel[cur]:"Table")+" "+o.table+" ยท "):"")+esc(o.person)+"</b>";
612
- const txt=document.createElement("span");txt.className="txt";txt.textContent=o.request;
613
- d.appendChild(txt);d.appendChild(stat);
614
- if(canUpdate&&!o.paid){const pb=document.createElement("button");pb.className="btn small";pb.textContent=t("markPaid");pb.style.background="#16a34a";pb.onclick=async()=>{await api("/api/live/order",{orderId:o.id,status:"paid"});haptic();renderOrders();};d.appendChild(pb);}
615
- if(canUpdate&&o.status!=="delivered"){
616
- const next=o.status==="sent"?"prep":o.status==="prep"?"ready":"delivered";
617
- const b=document.createElement("button");b.className="btn small";b.textContent=t(next)+" โ†’";
618
- b.onclick=async()=>{await api("/api/live/order",{orderId:o.id,status:next});haptic();renderOrders();};
619
- d.appendChild(b);
620
- }
621
- return d;
622
- }
623
- async function renderOrders(){
624
- for(const id of ["ownerOrders","leadOrders","workerOrders"]){const el=$(id);if(el)el.innerHTML=skel(2);}
625
- const live=await api("/api/live");
626
- for(const id of ["ownerOrders","leadOrders","workerOrders"]){
627
- const el=$(id);if(!el)continue;
628
- el.innerHTML="";
629
- (live.orders||[]).forEach(o=>el.appendChild(orderRow(o,id!=="workerOrders")));
630
- if(!(live.orders||[]).length)el.innerHTML=empty("๐Ÿ“ฆ",t("noOrders"));
631
- if(id==="ownerOrders"){const os=live.orders||[];const paid=os.filter(o=>o.paid).length;$("billSummary").textContent=t("billSummary").replace("X",paid).replace("Y",os.length);}
632
- }
633
- }
634
- $("sayBtn").onclick=async()=>{const v=$("sayText").value.trim();if(!v)return;const r=await api("/api/live/transcript",{worker:me?me.name:"worker",text:v});if(r&&r.error){toast(String(r.error).indexOf("budget")>=0?t("budgetReached"):r.error);return;}$("sayText").value="";showMsg(t("processing"));};
635
- const SR=window.SpeechRecognition||window.webkitSpeechRecognition;
636
- if(SR){$("micBtn").onclick=()=>{
637
- if(rec){rec.stop();return;}
638
- rec=new SR();rec.lang=(cur==="zh"?"zh-CN":cur==="ja"?"ja-JP":cur==="ko"?"ko-KR":cur==="ar"?"ar-SA":cur+"-"+(cur==="en"?"US":cur==="pt"?"PT":cur.toUpperCase()));
639
- rec.continuous=false;rec.interimResults=false;recording=true;$("micBtn").textContent="โน";
640
- rec.onresult=async(e)=>{let txt="";for(let i=0;i<e.results.length;i++)txt+=e.results[i][0].transcript;await api("/api/live/transcript",{worker:me?me.name:"worker",text:txt});showMsg(t("processing"));};
641
- rec.onend=()=>{recording=false;$("micBtn").textContent=t("dictate");rec=null;};
642
- rec.start();
643
- };}else{$("micBtn").disabled=true;$("micBtn").textContent=t("micUnsupported");}
644
- function packFieldsHTML(){if(!PACK||!PACK.fields||!PACK.fields.length)return "";return PACK.fields.map(f=>'<input class="packField" data-fid="'+f.id+'" placeholder="'+(f.label&&f.label[cur]?f.label[cur]:f.id)+'">').join("");}
645
- async function workerFlow(){
646
- const live=await api("/api/live");
647
- const wv=$("employeeView");
648
- if(!me){return;}
649
- $("wHome").classList.add("hidden");$("wListen").classList.add("hidden");$("wSummary").classList.add("hidden");
650
- if(live.status==="listening"){$("wListen").classList.remove("hidden");$("listeningBtn").textContent="๐ŸŽ™๏ธ "+ (live.worker||"");$("packFields").innerHTML=packFieldsHTML();$("tableInput").value=live.table||"";}
651
- else if(live.status==="summary"){$("wSummary").classList.remove("hidden");$("summaryTitle").textContent=t("summaryTitle")+(live.table?(" โ€” "+(PACK&&PACK.tableLabel&&PACK.tableLabel[cur]?PACK.tableLabel[cur]:"Table")+" "+live.table):"")+Object.entries(live.fields||{}).filter(([k,v])=>v).map(([k,v])=>" ยท "+v).join("");renderSummary(live);}
652
- else{$("wHome").classList.remove("hidden");}
653
- renderOrders();
654
- }
655
- function renderSummary(live){
656
- const body=$("summaryBody");body.innerHTML="";
657
- if(!(live.speakers||[]).length){body.innerHTML='<div class="card"><p class="note">'+t("noSummary")+'</p></div>';return;}
658
- for(const p of live.speakers){
659
- const d=document.createElement("div");d.className="person";
660
- const done=p.requests.filter(r=>r.status==="confirmed").length;
661
- let h='<div class="pname">'+t("person")+" "+(p.id.replace("p",""))+" โ€” "+esc(p.name)+'<span class="pcnt">('+done+'/'+p.requests.length+')</span></div>';
662
- for(const r of p.requests){
663
- const confirmed=r.status==="confirmed";
664
- h+='<div class="req"><span class="txt">'+esc(r.text)+'</span>'+
665
- '<span class="tier tier-'+r.tier+'">'+t("tier"+r.tier)+'</span>'+
666
- '<button class="confirmBtn'+(confirmed?" done":"")+'" data-req="'+r.id+'">'+(confirmed?t("confirmed"):t("confirm"))+'</button></div>'+
667
- (confirmed?'<div class="sentline">โœ“ '+t("sentNote")+'</div>':'');
668
- }
669
- d.innerHTML=h;
670
- d.querySelectorAll(".confirmBtn").forEach(b=>b.onclick=async()=>{
671
- if(b.classList.contains("done"))return;
672
- b.textContent=t("confirmed");b.classList.add("done","checkpop");haptic();toast(t("confirmed"));
673
- await api("/api/live/confirm",{requestId:b.dataset.req});
674
- workerFlow();
675
- });
676
- body.appendChild(d);
677
- }
678
- }
679
- $("startBtn").onclick=async()=>{const fields={};document.querySelectorAll(".packField").forEach(i=>{fields[i.dataset.fid]=i.value.trim();});await api("/api/live/start",{worker:me.name,table:$("tableInput").value.trim()||null,fields});workerFlow();};
680
- $("stopBtn").onclick=async()=>{const live=await api("/api/live");if((live.speakers||[]).length){live.status="summary";await api("/api/live/summary",{speakers:live.speakers});}else{await api("/api/live/close",{});}workerFlow();};
681
- $("newConvBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
682
- $("toHomeBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
683
- async function enter(){
684
- if(!PACK){PACK=await api("/api/sector");applyPack();}
685
- setWho();
686
- if(me.role==="owner"){show("ownerView");try{if(!localStorage.getItem("lv-welcome"))$("welcomeCard").style.display="block";}catch(e){}loadRegister();loadMetrics($("ownerMetrics"));loadUsers();loadField();loadRules();loadUsage();renderOrders();loadPresets();}
687
- else if(me.role==="lead"){show("leadView");loadMetrics($("leadMetrics"));loadLead();renderOrders();if(kitchenPoll)clearInterval(kitchenPoll);kitchenPoll=setInterval(kitchenWatch,4000);}
688
- else{show("employeeView");$("workerHi").textContent=t("hi")+(me.label||me.name);loadRegister();workerFlow();if(livePoll)clearInterval(livePoll);livePoll=setInterval(()=>{if(me&&me.role==="employee")workerFlow();},3000);}
689
- }
690
- let pwVisible=false;
691
- $("eyeBtn").onclick=()=>{pwVisible=!pwVisible;$("loginPass").type=pwVisible?"text":"password";$("eyeOn").classList.toggle("hidden",pwVisible);$("eyeOff").classList.toggle("hidden",!pwVisible);};
692
- $("setupBtn").onclick=async()=>{
693
- const user=$("setupUser").value.trim();
694
- const password=$("setupPass").value;
695
- if(!user||password.length<8){toast(t("fillBoth"));return;}
696
- $("setupBtn").disabled=true;$("setupBtn").innerHTML='<span class="spin"></span>'+t("loggingIn");
697
- const r=await api("/api/setup",{user,password,sector:$("setupSector").value});
698
- if(r.error){$("setupBtn").disabled=false;$("setupBtn").textContent=t("setupBtn");toast(String(r.error).indexOf("already")>=0?t("loginFailed"):r.error);return;}
699
- token=r.token;me={name:r.name,role:r.role,label:r.label||r.name};
700
- sessionStorage.setItem("dsh-sup-token",token);sessionStorage.setItem("dsh-sup-me",JSON.stringify(me));
701
- enter();
702
- };
703
- $("loginBtn").onclick=async()=>{
704
- const err=$("loginError");
705
- err.classList.add("hidden");
706
- const u=$("loginUser").value.trim(),p=$("loginPass").value;
707
- if(!u||!p){err.textContent=t("fillBoth");err.classList.remove("hidden");return;}
708
- $("loginBtn").disabled=true;$("loginBtn").innerHTML='<span class="spin"></span>'+t("loggingIn");
709
- const r=await api("/api/login",{user:u,password:p});
710
- $("loginBtn").disabled=false;$("loginBtn").textContent=t("loginBtn");
711
- if(r.error){err.textContent=r.error==="network"?t("cannotReach"):t("loginFailed");err.classList.remove("hidden");err.classList.remove("shake");void err.offsetWidth;err.classList.add("shake");return;}
712
- err.classList.add("hidden");
713
- token=r.token;me={name:r.name,role:r.role,label:r.label||r.name};
714
- sessionStorage.setItem("dsh-sup-token",token);sessionStorage.setItem("dsh-sup-me",JSON.stringify(me));
715
- $("loginPass").value="";enter();
716
- };
717
- function logout(){api("/api/logout",{});token=null;me=null;sessionStorage.clear();if(livePoll)clearInterval(livePoll);if(kitchenPoll)clearInterval(kitchenPoll);setWho();show("loginView");}
718
- $("logoutBtn").onclick=logout;
719
- const sb=$("switchBtn");if(sb)sb.onclick=logout;
720
- async function loadUsers(){const tb=$("usersTable").querySelector("tbody");tb.innerHTML='<tr><td colspan="2">'+skel(2)+'</td></tr>';const r=await api("/api/users");tb.innerHTML="";(r.users||[]).forEach(u=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+esc(u.name)+"</td><td>"+esc(u.label||u.name)+" ยท "+t(LVL[u.role]||"lvlEmployee")+"</td>";tb.appendChild(tr);});}
721
- $("addUserBtn").onclick=async()=>{const r=await api("/api/users",{name:$("newUser").value,password:$("newPass").value,role:$("newRole").value,label:$("newLabel").value});showMsg(r.error?"Error: "+r.error:t("workerAdded"));if(!r.error){loadUsers();$("newUser").value=$("newPass").value="";}};
722
- async function loadField(){$("reports").innerHTML=skel(2);$("feedback").innerHTML=skel(1);$("trail").innerHTML=skel(1);const rc=(await api("/api/reports")).content;if(rc){$("reports").innerHTML="<pre>"+esc(rc)+"</pre>";}else{$("reports").innerHTML=empty("๐Ÿ“‹",t("noReports"));}const fc=(await api("/api/feedback")).content;if(fc){$("feedback").innerHTML="<pre>"+esc(fc)+"</pre>";}else{$("feedback").innerHTML=empty("๐Ÿ’ฌ",t("feedbackQueue"));}const live=await api("/api/live");const ib=(live.inbox||[]).map(x=>"[โ€ข] "+esc(x.worker)+": "+esc(x.text)).join("\n");if(ib){$("trail").innerHTML="<pre>"+ib+"</pre>";}else{$("trail").innerHTML=empty("๐Ÿ—’๏ธ",t("conversationTrail"));}}
723
- async function loadLead(){$("leadReports").textContent=(await api("/api/reports")).content||"(empty)";$("leadFeedback").textContent=(await api("/api/feedback")).content||"(empty)";}
724
- $("refreshReports").onclick=loadField;$("leadRefresh").onclick=loadLead;
725
- const ar=$("autoRefresh");
726
- if(ar)ar.onclick=()=>{auto=!auto;ar.textContent=auto?t("autoOn"):t("autoOff");if(auto){const iv=setInterval(()=>{if(!auto){clearInterval(iv);return;}if(me&&me.role==="owner"){loadField();renderOrders();}},30000);}};
727
- async function loadPresets(){
728
- const r=await api("/api/sector-presets");
729
- const g=$("presetGrid");if(!g)return;g.innerHTML="";
730
- (r.presets||[]).forEach(p=>{const b=document.createElement("button");b.className="btn small gray";b.textContent=p.id;b.onclick=async()=>{await api("/api/sector",p);PACK=p;applyPack();showMsg(t("sectorSaved"));renderSuggest();};g.appendChild(b);});
731
- renderSuggest();
732
- }
733
- function renderSuggest(){const el=$("suggestUsers");if(!el||!PACK||!PACK.suggestedUsers)return;el.innerHTML="";(PACK.suggestedUsers||[]).forEach(su=>{const b=document.createElement("button");b.className="btn small gray";b.textContent="+ "+(su.label&&(su.label[cur]||su.label.en)||su.level);b.onclick=()=>{$("newUser").value="";$("newLabel").value=su.label&&(su.label[cur]||su.label.en)||"";$("newRole").value=su.level;};el.appendChild(b);});}
734
- $("saveSectorBtn").onclick=async()=>{
735
- const pack={id:$("csId").value.trim()||"custom",
736
- tableLabel:{en:$("csLabelEn").value.trim()||"Table",fr:$("csLabelFr").value.trim(),es:$("csLabelEn").value.trim()||"Table"},
737
- ordersTarget:{en:$("csOrdersEn").value.trim()||"Orders",fr:$("csOrdersFr").value.trim()},
738
- entity:{en:"person",fr:"personne"},
739
- fields:[]};
740
- if($("csF1Id").value.trim())pack.fields.push({id:$("csF1Id").value.trim(),type:"text",label:{en:$("csF1Label").value.trim()||$("csF1Id").value.trim()}});
741
- if($("csF2Id").value.trim())pack.fields.push({id:$("csF2Id").value.trim(),type:"text",label:{en:$("csF2Label").value.trim()||$("csF2Id").value.trim()}});
742
- const r=await api("/api/sector",pack);showMsg(r.error?"Error":t("sectorSaved"));PACK=pack;applyPack();
743
- };
744
- $("aiSectorBtn").onclick=async()=>{
745
- const prompt="Live mirror mode (workflow-master). Design a sector pack JSON for this business, in this exact shape: {\"id\":\"<sector-id>\",\"tableLabel\":{\"en\":\"<entity label>\",\"es\":\"โ€ฆ\",\"fr\":\"โ€ฆ\"},\"ordersTarget\":{\"en\":\"<orders title>\",\"fr\":\"โ€ฆ\"},\"entity\":{\"en\":\"<entity>\",\"fr\":\"โ€ฆ\"},\"fields\":[{\"id\":\"<field>\",\"type\":\"number|text\",\"label\":{\"en\":\"<label>\",\"fr\":\"โ€ฆ\"}}]}. Describe your business here: "+($("csLabelEn").value||"(your business)")+". Reply ONLY with the JSON.";
746
- try{await navigator.clipboard.writeText(prompt);}catch(e){}
747
- showMsg(t("aiSectorCopied"));
748
- };
749
- async function loadRules(){$("decisions").value=(await api("/api/decisions")).content||"";}
750
- $("saveDecisions").onclick=async()=>{await api("/api/decisions",{content:$("decisions").value});$("decisionsSaved").textContent=t("saved");setTimeout(()=>$("decisionsSaved").textContent="",2000);};
751
- document.querySelectorAll(".tabs button, .bnav button").forEach(b=>b.onclick=()=>{document.querySelectorAll(".tabs button, .bnav button").forEach(x=>x.classList.remove("active"));b.classList.add("active");["overview","field","rules","sector"].forEach(x=>$("tab-"+x).classList.add("hidden"));$("tab-"+b.dataset.tab).classList.remove("hidden");});
752
- $("reportBtn").onclick=async()=>{const r=await api("/api/report",{text:$("reportText").value});if(r.error){showMsg("Error: "+r.error);return;}$("reportText").value="";showMsg(t("reportSent"));};
753
- $("empFbBtn").onclick=async()=>{const r=await api("/api/feedback",{worker:me.name,role:me.role,category:$("empFbCat").value,text:$("empFbText").value});if(r.error){showMsg("Error: "+r.error);return;}$("empFbText").value="";showMsg(t("feedbackSent"));};
754
- api("/api/setup-status").then((st)=>{if(st&&st.users===0){$("setupSection").classList.remove("hidden");$("loginUser").parentNode.style.display="none";$("loginBtn").style.display="none";$("loginPass").closest(".passwrap").style.display="none";$("loginTitle").textContent=t("setupTitle");}}).catch(()=>{});
755
- const st=sessionStorage.getItem("dsh-sup-token");
756
- if(st){token=st;me=JSON.parse(sessionStorage.getItem("dsh-sup-me")||"null");(async()=>{const r=await api("/api/me");if(!r||!r.name){logout();return;}enter();})();}
757
- else setWho();
758
- async function wallTick(){try{const r=await (await fetch("/api/wall")).json();const cards=[[t("week"),r.reportsWeek],[t("ordersTitle"),r.orders],[t("feedback"),r.feedback],[t("workersActive"),r.workers],[t("reportsTotal"),r.reports]];$("wallCards").innerHTML=cards.map(c=>'<div class="wall-card"><div class="v">'+(c[1]===undefined?"โ€“":c[1])+'</div><div class="l">'+c[0]+'</div></div>').join("");const ticks=[...(r.ordersTail||[]).map(x=>"๐Ÿ”” "+esc(x)),...(r.feedbackTail||"").split("\n").filter(Boolean).slice(-4).map(esc)];$("wallFeed").innerHTML=ticks.length?ticks.map(x=>'<div class="wtick">'+x+'</div>').join(""):'<div class="wtick dim">'+t("noActivity")+'</div>';try{const s=await (await fetch("/api/sector")).json();$("wallSector").textContent=(s&&s.id)?s.id:"";}catch(e){}}catch(e){$("wallFeed").innerHTML='<div class="wtick dim">'+t("cannotReach")+'</div>';}}
759
- function clockTick(){const d=new Date();$("wallClock").textContent=d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});$("wallDate").textContent=d.toLocaleDateString([],{weekday:"short",day:"numeric",month:"short"});}
760
- if(location.search.indexOf("wall=1")>=0){
761
- document.body.classList.add("wall");show("wallView");
762
- clockTick();setInterval(clockTick,1000);
763
- wallTick();setInterval(wallTick,30000);
764
- }
765
- </script>
766
228
  </body>
767
229
  </html>