@javierfrancoleal/dsh-supervisor 0.0.0-stage โ†’ 1.0.0

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 ADDED
@@ -0,0 +1,460 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="theme-color" content="#4D6BFE">
7
+ <title>Supervisor โ€” J.Franco Suite</title>
8
+ <style>
9
+ :root{--blue:#4D6BFE;--green:#22c55e;--amber:#facc15;--red:#ef4444;--ink:#101828;--muted:#667085;--bg:#f6f7fb;--card:#fff;--card2:var(--card2);--line:var(--line);--line2:var(--line2)}
10
+ body.dark{--ink:#e6ecf7;--muted:#94a3b8;--bg:#0b1220;--card:#141f31;--card2:#18253a;--line:#26334d;--line2:#26334d}
11
+ .anim{animation:slidein .28s ease}
12
+ @keyframes slidein{from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}}
13
+ .empty{text-align:center;padding:26px 12px;color:var(--muted);font-size:14px;border:1px dashed var(--line);border-radius:14px}
14
+ .empty .ico{font-size:30px;display:block;margin-bottom:6px}
15
+ *{box-sizing:border-box}
16
+ body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:var(--bg);color:var(--ink);-webkit-tap-highlight-color:transparent}
17
+ header{background:var(--blue);color:#fff;padding:12px 16px;display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
18
+ header h1{margin:0;font-size:18px}
19
+ header .who{font-size:13px;opacity:.9}
20
+ button{font-family:inherit;cursor:pointer}
21
+ .btn{border:none;border-radius:12px;padding:12px 16px;font-size:15px;font-weight:600;color:#fff;background:var(--blue)}
22
+ .btn.gray{background:var(--line2);color:var(--ink)}
23
+ .btn.small{padding:8px 12px;font-size:13px}
24
+ main{max-width:960px;margin:0 auto;padding:14px}
25
+ .card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:16px;margin:12px 0}
26
+ .card h2{margin:0 0 10px;font-size:16px}
27
+ 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)}
28
+ textarea{resize:vertical;min-height:80px}
29
+ 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}
30
+ .metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px}
31
+ .metric{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:12px;text-align:center}
32
+ .metric .v{font-size:26px;font-weight:700;color:var(--blue)}
33
+ .metric .l{font-size:12px;color:var(--muted);margin-top:2px}
34
+ .tabs{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
35
+ .tabs button{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:10px 16px;font-size:15px;font-weight:600}
36
+ .tabs button.active{background:var(--blue);color:#fff;border-color:var(--blue)}
37
+ table{width:100%;border-collapse:collapse;font-size:14px}
38
+ td,th{border-bottom:1px solid var(--line);padding:9px 6px;text-align:left}
39
+ .hidden{display:none}
40
+ .kban{background:#fef3c7;border:1px solid #f59e0b;color:#92400e;border-radius:12px;padding:12px 14px;margin:10px 0;font-weight:700;font-size:15px}
41
+ .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}
42
+ .foot{text-align:center;padding:6px 16px 16px}
43
+ .foot .copyr{font-size:12px;color:var(--muted)}
44
+ .eye{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;font-size:18px;cursor:pointer;padding:4px}
45
+ .passwrap{position:relative}
46
+ .loginerr{background:#fee2e2;color:#b91c1c;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
47
+ .loginok{background:#dcfce7;color:#15803d;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
48
+ .note{color:var(--muted);font-size:13px}
49
+ .hint{font-size:12.5px;color:var(--muted);margin-top:4px}
50
+ .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}
51
+ .listen:active{transform:scale(.98)}
52
+ .listen.pulse{animation:pulse 1.6s infinite}
53
+ @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)}}
54
+ .stopbtn{background:var(--red)!important;box-shadow:0 6px 20px rgba(239,68,68,.35)!important}
55
+ .row{display:flex;gap:8px;flex-wrap:wrap}
56
+ .row .btn{flex:1;min-width:110px}
57
+ .switchuser{margin-top:26px;text-align:center}
58
+ .langs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:8px 0 14px}
59
+ .pill{background:var(--card);border:1px solid var(--line);border-radius:999px;padding:8px 13px;font-size:13px;cursor:pointer}
60
+ .pill.active{background:var(--blue);color:#fff;border-color:var(--blue)}
61
+ .person{background:var(--card2);border:1px solid var(--line);border-radius:16px;padding:14px;margin:10px 0}
62
+ .person .pname{font-size:17px;font-weight:700;margin-bottom:8px}
63
+ .req{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card);border:1px solid var(--line2);margin:6px 0}
64
+ .req .txt{flex:1;font-size:15px}
65
+ .req .tier{font-size:12px;font-weight:700;padding:4px 8px;border-radius:999px}
66
+ .tier-GREEN{background:#dcfce7;color:#15803d}
67
+ .tier-SEMI{background:#fef9c3;color:#a16207}
68
+ .tier-YELLOW{background:#fef9c3;color:#a16207}
69
+ .tier-RED{background:#fee2e2;color:#b91c1c}
70
+ .confirmBtn{background:var(--blue);color:#fff;border:none;border-radius:12px;padding:10px 14px;font-size:14px;font-weight:700;white-space:nowrap}
71
+ .confirmBtn.done{background:#dcfce7;color:#15803d}
72
+ .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}
73
+ .order .stat{font-size:12px;font-weight:700;padding:4px 10px;border-radius:999px;background:#e0e7ff;color:#3730a3}
74
+ #wallView{max-width:1100px}
75
+ .wall-head{font-size:34px;font-weight:800;color:#fff;text-align:center;margin:10px 0}
76
+ .wall-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
77
+ .wall-card{background:#1b2436;color:#fff;border-radius:16px;padding:20px;text-align:center}
78
+ .wall-card .v{font-size:44px;font-weight:800}
79
+ .wall-card .l{font-size:15px;opacity:.85}
80
+ body.wall{background:#0b1220}
81
+ body.wall pre{max-height:40vh}
82
+ @media (max-width:560px){header h1{font-size:15px}.listen{font-size:24px;padding:26px 12px}input,select,textarea,button{font-size:16px}}
83
+ </style>
84
+ </head>
85
+ <body>
86
+ <header>
87
+ <h1 id="appTitle">๐Ÿข Supervisor ยท J.Franco Suite</h1>
88
+ <span class="who" id="who"></span>
89
+ <span class="chip" id="idChip" style="display:none"></span>
90
+ <button class="btn small gray" id="darkBtn">๐ŸŒ™</button>
91
+ <button class="btn small gray" id="soundBtn">๐Ÿ”Š</button>
92
+ <button class="btn small gray" id="logoutBtn" style="display:none">Log out</button>
93
+ </header>
94
+ <main>
95
+ <div id="loginView" class="card" style="max-width:440px;margin:26px auto">
96
+ <h2 id="loginTitle">Log in</h2>
97
+ <div id="langs" class="langs"></div>
98
+ <input id="loginUser" placeholder="User" autocomplete="username">
99
+ <div class="passwrap">
100
+ <input id="loginPass" type="password" placeholder="Password" autocomplete="current-password">
101
+ <button class="eye" id="eyeBtn" type="button" aria-label="Show password"><svg id="eyeOn" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg><svg id="eyeOff" class="hidden" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg></button>
102
+ </div>
103
+ <div id="loginError" class="loginerr hidden"></div>
104
+ <button class="btn" id="loginBtn" style="width:100%">Log in</button>
105
+ <p class="hint" id="loginHint">Accounts are managed by the business owner.</p>
106
+ <a href="/dashboard?wall=1"><button class="btn gray small" id="openWall" style="width:100%;margin-top:6px">Live wallboard</button></a>
107
+ </div>
108
+
109
+ <div id="ownerView" class="hidden">
110
+ <div class="metrics" id="ownerMetrics"></div>
111
+ <div class="tabs">
112
+ <button data-tab="overview" class="active" id="tabOverview">Overview</button>
113
+ <button data-tab="field" id="tabField">Field</button>
114
+ <button data-tab="rules" id="tabRules">Rules</button>
115
+ <button data-tab="sector" id="tabSector">Sector</button>
116
+ </div>
117
+ <div id="tab-overview">
118
+ <div class="card"><h2 id="workersTitle">Workers</h2>
119
+ <table id="usersTable"><thead><tr><th id="thUser">User</th><th id="thRole">Role</th></tr></thead><tbody></tbody></table>
120
+ <h2 style="margin-top:14px" id="addWorkerTitle">Add worker</h2>
121
+ <div id="suggestUsers" class="row"></div>
122
+ <input id="newUser" placeholder="User name"><input id="newPass" type="password" placeholder="Password">
123
+ <input id="newLabel" placeholder="Role label (e.g. Cook)">
124
+ <select id="newRole"><option id="optEmployee" value="employee">employee</option><option id="optLead" value="lead">lead</option><option id="optOwner" value="owner">owner</option></select>
125
+ <button class="btn" id="addUserBtn">Add worker</button>
126
+ </div>
127
+ <div class="card"><h2 id="ordersTitle">Orders โ€” kitchen & bill</h2><div id="ownerOrders"></div></div>
128
+ <div class="card"><h2 id="usageTitle">Usage & cost</h2><p class="hint" id="usageSub">(per worker, estimated)</p>
129
+ <table id="usageTable"><thead><tr><th id="thWorker">Worker</th><th id="thSessions">Sessions</th><th id="thTokens">Tokens</th><th id="thCost">Est. cost</th></tr></thead><tbody></tbody></table>
130
+ </div>
131
+ <div class="card"><h2 id="panelTitle">Action Panel</h2><p class="note" id="panelNote">Workers open the panel from their tablet or phone.</p>
132
+ <a href="/panel" target="_blank" id="openPanelLink"><button class="btn" id="openPanel">Open Action Panel</button></a>
133
+ </div>
134
+ </div>
135
+ <div id="tab-field" class="hidden">
136
+ <div class="card"><h2 id="fieldReportsTitle">Field reports</h2>
137
+ <div class="row" style="margin-bottom:8px"><button class="btn small gray" id="refreshReports">Refresh</button><button class="btn small gray" id="autoRefresh">Auto-refresh: OFF</button></div>
138
+ <pre id="reports"></pre>
139
+ </div>
140
+ <div class="card"><h2 id="trailTitle">Conversation trail</h2><p class="hint" id="trailHint">The raw phrases captured from the field, in order.</p><pre id="trail"></pre></div>
141
+ <div class="card"><h2 id="feedbackTitle">Feedback queue</h2><pre id="feedback"></pre>
142
+ <p class="hint" id="feedbackHint">The agent reads this queue and resolves errors and improvements.</p>
143
+ </div>
144
+ </div>
145
+ <div id="tab-sector" class="hidden">
146
+ <div class="card"><h2 id="sectorPresetsTitle">Sector presets</h2><div id="presetGrid" class="row"></div></div>
147
+ <div class="card">
148
+ <h2 id="customSectorTitle">Custom sector</h2>
149
+ <input id="csId" placeholder="id (e.g. bakery)">
150
+ <input id="csLabelEn" placeholder="Label (EN)"><input id="csLabelFr" placeholder="Label (FR)">
151
+ <input id="csOrdersEn" placeholder="Orders title (EN)"><input id="csOrdersFr" placeholder="Orders title (FR)">
152
+ <input id="csF1Id" placeholder="Field 1 id (e.g. orderNo)"><input id="csF1Label" placeholder="Field 1 label (EN)">
153
+ <input id="csF2Id" placeholder="Field 2 id (optional)"><input id="csF2Label" placeholder="Field 2 label (EN)">
154
+ <button class="btn" id="saveSectorBtn">Save sector</button>
155
+ <button class="btn gray" id="aiSectorBtn" style="margin-top:6px">Suggest with AI (copy prompt)</button>
156
+ </div>
157
+ </div>
158
+ <div id="tab-rules" class="hidden">
159
+ <div class="card"><h2 id="rulesTitle">Business rules</h2><p class="hint" id="rulesHint">These rules train the traffic light.</p>
160
+ <textarea id="decisions" rows="14"></textarea>
161
+ <button class="btn" id="saveDecisions">Save rules</button><span id="decisionsSaved" class="note"></span>
162
+ </div>
163
+ </div>
164
+ </div>
165
+
166
+ <div id="leadView" class="hidden">
167
+ <div class="metrics" id="leadMetrics"></div>
168
+ <div id="kitchenBanner" class="kban hidden"></div>
169
+ <div class="card"><h2 id="leadOrdersTitle">Orders โ€” kitchen & bill</h2>
170
+ <button class="btn small gray" id="notifBtn" style="margin-bottom:8px">๐Ÿ”” Enable notifications</button>
171
+ <p class="hint" id="notifHint">The kitchen tablet beeps and flashes when an order arrives.</p>
172
+ <div id="leadOrders"></div></div>
173
+ <div class="card"><h2 id="leadReportsTitle">Field reports</h2><button class="btn small gray" id="leadRefresh">Refresh</button><pre id="leadReports"></pre></div>
174
+ <div class="card"><h2 id="leadFeedbackTitle">Feedback queue</h2><pre id="leadFeedback"></pre></div>
175
+ <div class="card"><a href="/panel" target="_blank" id="leadOpenPanelLink"><button class="btn" id="leadOpenPanel">Open Action Panel</button></a></div>
176
+ </div>
177
+
178
+ <div id="employeeView" class="hidden">
179
+ <div id="wHome">
180
+ <div class="card" style="text-align:center;padding:8px"><h2 id="workerHi" style="margin:0"></h2></div>
181
+ <input id="tableInput" placeholder="Table #" style="margin:8px 0">
182
+ <div id="packFields" class="row"></div>
183
+ <button class="listen" id="startBtn">โ–ถ START</button>
184
+ <div class="card"><h2 id="reportTitle">Field report</h2><textarea id="reportText" rows="4" placeholder="What happened on your shift?"></textarea><button class="btn" id="reportBtn">Send report</button></div>
185
+ <div class="card"><h2 id="fbTitle">Field feedback</h2>
186
+ <select id="empFbCat"><option value="error">Error</option><option value="improvement">Improvement</option><option value="idea">Idea</option></select>
187
+ <textarea id="empFbText" rows="3" placeholder="What happened? What should improve?"></textarea><button class="btn" id="empFbBtn">Send feedback</button>
188
+ </div>
189
+ <div class="switchuser"><button class="btn small gray" id="switchBtn">Switch user</button></div>
190
+ </div>
191
+ <div id="wListen" class="hidden">
192
+ <button class="listen pulse" id="listeningBtn">๐ŸŽ™๏ธ</button>
193
+ <div class="card" style="text-align:center"><h2 id="listeningText">Listeningโ€ฆ speak now</h2><p class="note" id="listeningHint">The conversation is being captured and split by person.</p></div>
194
+ <div class="card">
195
+ <textarea id="sayText" rows="3" placeholder="What did they say?"></textarea>
196
+ <div class="row">
197
+ <button class="btn" id="sayBtn">Send phrase</button>
198
+ <button class="btn gray" id="micBtn">๐ŸŽ™๏ธ Dictate</button>
199
+ </div>
200
+ <p class="hint" id="aiHint">Speech and text go straight to the AI โ€” the summary appears automatically.</p>
201
+ </div>
202
+ <button class="listen stopbtn" id="stopBtn">โน Stop listening</button>
203
+ </div>
204
+ <div id="wSummary" class="hidden">
205
+ <div class="card" style="text-align:center"><h2 id="summaryTitle">Conversation summary</h2></div>
206
+ <div id="summaryBody"></div>
207
+ <div class="card"><h2 id="ordersTitle2">Orders โ€” kitchen & bill</h2><div id="workerOrders"></div></div>
208
+ <div class="row" style="margin:12px 0">
209
+ <button class="btn" id="newConvBtn">New conversation</button>
210
+ <button class="btn gray" id="toHomeBtn">Back</button>
211
+ </div>
212
+ </div>
213
+ </div>
214
+
215
+ <div id="wallView" class="hidden">
216
+ <div class="wall-head" id="wallHead">๐Ÿญ J.Franco Suite โ€” Live</div>
217
+ <div class="wall-grid" id="wallCards"></div>
218
+ <div class="card" style="margin-top:14px"><h2 style="color:#fff" id="wallPulseTitle">Field pulse</h2><pre id="wallFeed"></pre></div>
219
+ </div>
220
+
221
+ <div id="msg" class="note" style="text-align:center"></div>
222
+ </main>
223
+ <footer class="foot"><div class="langs" id="footLangs"></div><div class="copyr">Suite J.Franco ยท open source (MIT) ยท autor J.Franco</div></footer>
224
+ <script>
225
+ "use strict";
226
+ const LANG={es:"ES",en:"EN",fr:"FR",de:"DE",it:"IT",pt:"PT",zh:"ไธญๆ–‡",ja:"ๆ—ฅๆœฌ่ชž",ko:"ํ•œ๊ตญ์–ด",ar:"ุงู„ุนุฑุจูŠุฉ"};
227
+ const S={
228
+ 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:"๐Ÿญ J.Franco Suite โ€” 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."},
229
+ 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:"๐Ÿญ Suite J.Franco โ€” 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."},
230
+ 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:"๐Ÿญ Suite J.Franco โ€” 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."},
231
+ 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:"๐Ÿญ J.Franco-Suite โ€” 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."},
232
+ 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:"๐Ÿญ Suite J.Franco โ€” 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."},
233
+ 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:"๐Ÿญ Suite J.Franco โ€” 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."},
234
+ 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:"๐Ÿญ J.Franco ๅฅ—ไปถ โ€” ๅฎžๆ—ถ",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:"ๆ–ฐ่ฎขๅ•ๅˆฐ่พพๆ—ถๅŽจๆˆฟๅนณๆฟไผšๅ“้“ƒๅนถ้—ช็ƒใ€‚"},
235
+ 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:"๐Ÿญ J.Franco ใ‚นใ‚คใƒผใƒˆ โ€” ใƒฉใ‚คใƒ–",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:"ๆณจๆ–‡ใŒๅฑŠใใจๅŽจๆˆฟใ‚ฟใƒ–ใƒฌใƒƒใƒˆใŒ้Ÿณใจ็‚นๆป…ใง็Ÿฅใ‚‰ใ›ใพใ™ใ€‚"},
236
+ 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:"๐Ÿญ J.Franco ์Šค์œ„ํŠธ โ€” ๋ผ์ด๋ธŒ",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:"์ฃผ๋ฌธ์ด ๋„์ฐฉํ•˜๋ฉด ์ฃผ๋ฐฉ ํƒœ๋ธ”๋ฆฟ์ด ์†Œ๋ฆฌ์™€ ํ•จ๊ป˜ ๊นœ๋ฐ•์ž…๋‹ˆ๋‹ค."},
237
+ 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:"๐Ÿญ ู…ุฌู…ูˆุนุฉ J.Franco โ€” ู…ุจุงุดุฑ",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:"ูŠุตุฏุฑ ุตูˆุช ูˆูŠูˆู…ุถ ู„ูˆุญ ุงู„ู…ุทุจุฎ ุนู†ุฏ ูˆุตูˆู„ ุทู„ุจ ุฌุฏูŠุฏ."}
238
+ };
239
+ 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){}}}
240
+ const $=id=>document.getElementById(id);
241
+ 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;
242
+ function t(k){return (S[cur]&&S[cur][k])||S.en[k]||k;}
243
+ function applyToggles(){document.body.classList.toggle("dark",darkOn);$("darkBtn").textContent=darkOn?"โ˜€๏ธ":"๐ŸŒ™";$("soundBtn").textContent=soundOn?"๐Ÿ”Š":"๐Ÿ”‡";}
244
+ $("darkBtn").onclick=()=>{darkOn=!darkOn;try{localStorage.setItem("dsh-dark",darkOn?"1":"0");}catch(e){}applyToggles();};
245
+ $("soundBtn").onclick=()=>{soundOn=!soundOn;try{localStorage.setItem("dsh-sound",soundOn?"1":"0");}catch(e){}applyToggles();};
246
+ try{darkOn=localStorage.getItem("dsh-dark")==="1";soundOn=localStorage.getItem("dsh-sound")!=="0";}catch(e){}
247
+ applyToggles();
248
+ async function reRenderDynamic(){
249
+ if(!me)return;
250
+ if(me.role==="owner"){loadMetrics($("ownerMetrics"));loadUsers();loadUsage();loadField();renderOrders();renderSuggest();}
251
+ else if(me.role==="lead"){loadMetrics($("leadMetrics"));loadLead();renderOrders();}
252
+ else{$("workerHi").textContent=t("hi")+(me.label||me.name);workerFlow();}
253
+ if(location.search.indexOf("wall=1")>=0)wallTick();
254
+ }
255
+ async function kitchenWatch(){
256
+ const live=await api("/api/live");
257
+ const n=(live.orders||[]).length;
258
+ if(n>lastOrders&&lastOrders>0){
259
+ const o=live.orders[n-1];
260
+ $("kitchenBanner").textContent="๐Ÿ”” "+t("newOrder")+": "+o.person+" โ€” "+o.request;
261
+ $("kitchenBanner").classList.remove("hidden");
262
+ haptic();
263
+ try{if("Notification" in window&&Notification.permission==="granted"){new Notification(t("newOrder"),{body:o.person+" โ€” "+o.request});}}catch(e){}
264
+ setTimeout(()=>$("kitchenBanner").classList.add("hidden"),6000);
265
+ }
266
+ lastOrders=n;
267
+ }
268
+ $("notifBtn").onclick=()=>{
269
+ try{
270
+ if("Notification" in window&&Notification.permission!=="granted"){
271
+ Notification.requestPermission().then(()=>{renderOrders();});
272
+ }
273
+ }catch(e){}
274
+ };
275
+ 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);}
276
+ function applyLang(){
277
+ try{localStorage.setItem("dsh-lang",cur);}catch(e){}
278
+ $("loginTitle").textContent=t("login");$("loginUser").placeholder=t("user");
279
+ ["loginUser","loginPass"].forEach(id=>$(id).addEventListener("input",()=>$("loginError").classList.add("hidden")));$("loginPass").placeholder=t("password");
280
+ $("loginBtn").textContent=t("loginBtn");$("loginHint").textContent=t("loginHint");$("openWall").textContent=t("wallOpen");$("logoutBtn").textContent=t("logout");
281
+ $("tabOverview").textContent=t("overview");$("tabField").textContent=t("field");$("tabRules").textContent=t("rules");
282
+ $("workersTitle").textContent=t("workers");$("thUser").textContent=t("thUser");$("thRole").textContent=t("thRole");
283
+ $("addWorkerTitle").textContent=t("addWorker");$("newUser").placeholder=t("userName");$("addUserBtn").textContent=t("addBtn");
284
+ $("ordersTitle").textContent=t("ordersTitle");$("leadOrdersTitle").textContent=t("ordersTitle");$("ordersTitle2").textContent=t("ordersTitle");
285
+ $("usageTitle").textContent=t("usage");$("usageSub").textContent=t("usageSub");
286
+ $("thWorker").textContent=t("thWorker");$("thSessions").textContent=t("thSessions");$("thTokens").textContent=t("thTokens");$("thCost").textContent=t("thCost");
287
+ $("panelTitle").textContent=t("panel");$("panelNote").textContent=t("panelNote");$("openPanel").textContent=t("openPanel");
288
+ $("fieldReportsTitle").textContent=t("fieldReports");$("feedbackTitle").textContent=t("feedbackQueue");$("feedbackHint").textContent=t("feedbackHint");
289
+ $("refreshReports").textContent=t("refresh");if(!auto)$("autoRefresh").textContent=t("autoOff");
290
+ $("rulesTitle").textContent=t("rulesTitle");$("rulesHint").textContent=t("rulesHint");$("saveDecisions").textContent=t("saveRules");
291
+ $("leadReportsTitle").textContent=t("fieldReports");$("leadFeedbackTitle").textContent=t("feedbackQueue");$("leadRefresh").textContent=t("refresh");$("leadOpenPanel").textContent=t("openPanel");
292
+ $("startBtn").textContent=t("start");$("listeningText").textContent=t("listening");$("listeningHint").textContent=t("listeningHint");
293
+ $("stopBtn").textContent=t("stopListening");$("summaryTitle").textContent=t("summaryTitle");$("newConvBtn").textContent=t("newConv");$("toHomeBtn").textContent=t("back");
294
+ $("reportTitle").textContent=t("reportTitle");$("reportText").placeholder=t("reportPh");$("reportBtn").textContent=t("sendReport");
295
+ $("fbTitle").textContent=t("fbTitle");$("empFbText").placeholder=t("fbPh");$("empFbBtn").textContent=t("sendFeedback");$("switchBtn").textContent=t("switchUser");
296
+ $("wallHead").textContent=t("wallHead");$("wallPulseTitle").textContent=t("wallPulse");
297
+ $("notifBtn").textContent=t("enableNotif");$("notifHint").textContent=t("notifHint");
298
+ $("optEmployee").textContent=t("lvlEmployee");$("optLead").textContent=t("lvlLead");$("optOwner").textContent=t("lvlOwner");$("newLabel").placeholder=t("labelPh");
299
+ $("tabSector").textContent=t("sectorTab");$("sectorPresetsTitle").textContent=t("sectorPresets");$("customSectorTitle").textContent=t("customSector");$("saveSectorBtn").textContent=t("saveSector");$("aiSectorBtn").textContent=t("aiSuggest");
300
+ $("trailTitle").textContent=t("conversationTrail");$("trailHint").textContent=t("trailHint");
301
+ $("sayText").placeholder=t("sayPh");$("sayBtn").textContent=t("sendPhrase");$("aiHint").textContent=t("aiHint");if(!recording)$("micBtn").textContent=t("dictate");
302
+ document.querySelectorAll(".pill").forEach(p=>p.classList.toggle("active",p.dataset.l===cur));
303
+ panelLinks();
304
+ reRenderDynamic();
305
+ }
306
+ function pill(l){for(const host of ["langs","footLangs"]){const b=document.createElement("button");b.className="pill";b.dataset.l=l;b.textContent=LANG[l];b.onclick=()=>{cur=l;applyLang();};$(host).appendChild(b);}}
307
+ for(const l of Object.keys(LANG))pill(l);
308
+ try{const saved=localStorage.getItem("dsh-lang");if(saved&&S[saved])cur=saved;}catch(e){}
309
+ applyLang();
310
+ 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;}
311
+ 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"};}};
312
+ 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");}
313
+ const LVL={employee:"lvlEmployee",lead:"lvlLead",owner:"lvlOwner"};
314
+ 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";}
315
+ function empty(ico,txt){return '<div class="empty"><span class="ico">'+ico+'</span>'+txt+'</div>';}
316
+ function showMsg(x){$("msg").textContent=x;setTimeout(()=>$("msg").textContent="",2500);}
317
+ async function loadMetrics(into){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">'+(v===undefined?"โ€“":v)+'</div><div class="l">'+l+'</div>';into.appendChild(d);}}
318
+ async function loadUsage(){const tb=$("usageTable")?$("usageTable").querySelector("tbody"):null;if(!tb)return;const r=await api("/api/usage");tb.innerHTML="";
319
+ if(!(r.rows||[]).length){tb.innerHTML='<tr><td colspan="4">'+empty("๐Ÿ“Š",t("noUsage"))+'</td></tr>';return;}
320
+ (r.rows||[]).forEach(x=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+x.worker+"</td><td>"+x.sessions+"</td><td>"+(x.tokens||0).toLocaleString()+"</td><td>$"+(x.cost||0).toFixed(2)+"</td>";tb.appendChild(tr);});}
321
+ function orderRow(o,canUpdate){
322
+ const d=document.createElement("div");d.className="order";
323
+ const stat=document.createElement("span");stat.className="stat";stat.textContent=t(o.status||"sent");
324
+ d.innerHTML="<b>"+(o.table?((PACK&&PACK.tableLabel&&PACK.tableLabel[cur]?PACK.tableLabel[cur]:"Table")+" "+o.table+" ยท "):"")+o.person+"</b>";
325
+ const txt=document.createElement("span");txt.className="txt";txt.textContent=o.request;
326
+ d.appendChild(txt);d.appendChild(stat);
327
+ if(canUpdate&&o.status!=="delivered"){
328
+ const next=o.status==="sent"?"prep":o.status==="prep"?"ready":"delivered";
329
+ const b=document.createElement("button");b.className="btn small";b.textContent=t(next)+" โ†’";
330
+ b.onclick=async()=>{await api("/api/live/order",{orderId:o.id,status:next});haptic();renderOrders();};
331
+ d.appendChild(b);
332
+ }
333
+ return d;
334
+ }
335
+ async function renderOrders(){
336
+ const live=await api("/api/live");
337
+ for(const id of ["ownerOrders","leadOrders","workerOrders"]){
338
+ const el=$(id);if(!el)continue;
339
+ el.innerHTML="";
340
+ (live.orders||[]).forEach(o=>el.appendChild(orderRow(o,id!=="workerOrders")));
341
+ if(!(live.orders||[]).length)el.innerHTML=empty("๐Ÿ“ฆ",t("noOrders"));
342
+ }
343
+ }
344
+ $("sayBtn").onclick=async()=>{const v=$("sayText").value.trim();if(!v)return;await api("/api/live/transcript",{worker:me?me.name:"worker",text:v});$("sayText").value="";showMsg(t("processing"));};
345
+ const SR=window.SpeechRecognition||window.webkitSpeechRecognition;
346
+ if(SR){$("micBtn").onclick=()=>{
347
+ if(rec){rec.stop();return;}
348
+ 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()));
349
+ rec.continuous=false;rec.interimResults=false;recording=true;$("micBtn").textContent="โน";
350
+ 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"));};
351
+ rec.onend=()=>{recording=false;$("micBtn").textContent=t("dictate");rec=null;};
352
+ rec.start();
353
+ };}else{$("micBtn").disabled=true;$("micBtn").textContent=t("micUnsupported");}
354
+ 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("");}
355
+ async function workerFlow(){
356
+ const live=await api("/api/live");
357
+ const wv=$("employeeView");
358
+ if(!me){return;}
359
+ $("wHome").classList.add("hidden");$("wListen").classList.add("hidden");$("wSummary").classList.add("hidden");
360
+ if(live.status==="listening"){$("wListen").classList.remove("hidden");$("listeningBtn").textContent="๐ŸŽ™๏ธ "+ (live.worker||"");$("packFields").innerHTML=packFieldsHTML();$("tableInput").value=live.table||"";}
361
+ 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);}
362
+ else{$("wHome").classList.remove("hidden");}
363
+ renderOrders();
364
+ }
365
+ function renderSummary(live){
366
+ const body=$("summaryBody");body.innerHTML="";
367
+ if(!(live.speakers||[]).length){body.innerHTML='<div class="card"><p class="note">'+t("noSummary")+'</p></div>';return;}
368
+ for(const p of live.speakers){
369
+ const d=document.createElement("div");d.className="person";
370
+ let h='<div class="pname">'+t("person")+" "+(p.id.replace("p",""))+" โ€” "+p.name+'</div>';
371
+ for(const r of p.requests){
372
+ const confirmed=r.status==="confirmed";
373
+ h+='<div class="req"><span class="txt">'+r.text+'</span>'+
374
+ '<span class="tier tier-'+r.tier+'">'+r.tier+'</span>'+
375
+ '<button class="confirmBtn'+(confirmed?" done":"")+'" data-req="'+r.id+'">'+(confirmed?t("confirmed"):t("confirm"))+'</button></div>';
376
+ }
377
+ d.innerHTML=h;
378
+ d.querySelectorAll(".confirmBtn").forEach(b=>b.onclick=async()=>{
379
+ await api("/api/live/confirm",{requestId:b.dataset.req});
380
+ haptic();
381
+ workerFlow();
382
+ });
383
+ body.appendChild(d);
384
+ }
385
+ }
386
+ $("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();};
387
+ $("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();};
388
+ $("newConvBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
389
+ $("toHomeBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
390
+ async function enter(){
391
+ if(!PACK){PACK=await api("/api/sector");applyPack();}
392
+ setWho();
393
+ if(me.role==="owner"){show("ownerView");loadMetrics($("ownerMetrics"));loadUsers();loadField();loadRules();loadUsage();renderOrders();loadPresets();}
394
+ else if(me.role==="lead"){show("leadView");loadMetrics($("leadMetrics"));loadLead();renderOrders();if(kitchenPoll)clearInterval(kitchenPoll);kitchenPoll=setInterval(kitchenWatch,4000);}
395
+ else{show("employeeView");$("workerHi").textContent=t("hi")+(me.label||me.name);workerFlow();if(livePoll)clearInterval(livePoll);livePoll=setInterval(()=>{if(me&&me.role==="employee")workerFlow();},3000);}
396
+ }
397
+ let pwVisible=false;
398
+ $("eyeBtn").onclick=()=>{pwVisible=!pwVisible;$("loginPass").type=pwVisible?"text":"password";$("eyeOn").classList.toggle("hidden",pwVisible);$("eyeOff").classList.toggle("hidden",!pwVisible);};
399
+ $("loginBtn").onclick=async()=>{
400
+ const err=$("loginError");
401
+ err.classList.add("hidden");
402
+ const u=$("loginUser").value.trim(),p=$("loginPass").value;
403
+ if(!u||!p){err.textContent=t("fillBoth");err.classList.remove("hidden");return;}
404
+ $("loginBtn").disabled=true;$("loginBtn").textContent=t("loggingIn");
405
+ const r=await api("/api/login",{user:u,password:p});
406
+ $("loginBtn").disabled=false;$("loginBtn").textContent=t("loginBtn");
407
+ if(r.error){err.textContent=r.error==="network"?t("cannotReach"):t("loginFailed");err.classList.remove("hidden");return;}
408
+ err.classList.add("hidden");
409
+ token=r.token;me={name:r.name,role:r.role,label:r.label||r.name};
410
+ sessionStorage.setItem("dsh-sup-token",token);sessionStorage.setItem("dsh-sup-me",JSON.stringify(me));
411
+ $("loginPass").value="";enter();
412
+ };
413
+ function logout(){api("/api/logout",{});token=null;me=null;sessionStorage.clear();if(livePoll)clearInterval(livePoll);if(kitchenPoll)clearInterval(kitchenPoll);setWho();show("loginView");}
414
+ $("logoutBtn").onclick=logout;
415
+ const sb=$("switchBtn");if(sb)sb.onclick=logout;
416
+ async function loadUsers(){const r=await api("/api/users");const tb=$("usersTable").querySelector("tbody");tb.innerHTML="";(r.users||[]).forEach(u=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+u.name+"</td><td>"+(u.label||u.name)+" ยท "+t(LVL[u.role]||"lvlEmployee")+"</td>";tb.appendChild(tr);});}
417
+ $("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="";}};
418
+ async function loadField(){const rc=(await api("/api/reports")).content;if(rc){$("reports").innerHTML="<pre>"+rc+"</pre>";}else{$("reports").innerHTML=empty("๐Ÿ“‹",t("noReports"));}const fc=(await api("/api/feedback")).content;if(fc){$("feedback").innerHTML="<pre>"+fc+"</pre>";}else{$("feedback").innerHTML=empty("๐Ÿ’ฌ",t("feedbackQueue"));}const live=await api("/api/live");const ib=(live.inbox||[]).map(x=>"[โ€ข] "+x.worker+": "+x.text).join("\n");if(ib){$("trail").innerHTML="<pre>"+ib+"</pre>";}else{$("trail").innerHTML=empty("๐Ÿ—’๏ธ",t("conversationTrail"));}}
419
+ async function loadLead(){$("leadReports").textContent=(await api("/api/reports")).content||"(empty)";$("leadFeedback").textContent=(await api("/api/feedback")).content||"(empty)";}
420
+ $("refreshReports").onclick=loadField;$("leadRefresh").onclick=loadLead;
421
+ const ar=$("autoRefresh");
422
+ 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);}};
423
+ async function loadPresets(){
424
+ const r=await api("/api/sector-presets");
425
+ const g=$("presetGrid");if(!g)return;g.innerHTML="";
426
+ (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);});
427
+ renderSuggest();
428
+ }
429
+ 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);});}
430
+ $("saveSectorBtn").onclick=async()=>{
431
+ const pack={id:$("csId").value.trim()||"custom",
432
+ tableLabel:{en:$("csLabelEn").value.trim()||"Table",fr:$("csLabelFr").value.trim(),es:$("csLabelEn").value.trim()||"Table"},
433
+ ordersTarget:{en:$("csOrdersEn").value.trim()||"Orders",fr:$("csOrdersFr").value.trim()},
434
+ entity:{en:"person",fr:"personne"},
435
+ fields:[]};
436
+ if($("csF1Id").value.trim())pack.fields.push({id:$("csF1Id").value.trim(),type:"text",label:{en:$("csF1Label").value.trim()||$("csF1Id").value.trim()}});
437
+ if($("csF2Id").value.trim())pack.fields.push({id:$("csF2Id").value.trim(),type:"text",label:{en:$("csF2Label").value.trim()||$("csF2Id").value.trim()}});
438
+ const r=await api("/api/sector",pack);showMsg(r.error?"Error":t("sectorSaved"));PACK=pack;applyPack();
439
+ };
440
+ $("aiSectorBtn").onclick=async()=>{
441
+ 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.";
442
+ try{await navigator.clipboard.writeText(prompt);}catch(e){}
443
+ showMsg(t("aiSectorCopied"));
444
+ };
445
+ async function loadRules(){$("decisions").value=(await api("/api/decisions")).content||"";}
446
+ $("saveDecisions").onclick=async()=>{await api("/api/decisions",{content:$("decisions").value});$("decisionsSaved").textContent=t("saved");setTimeout(()=>$("decisionsSaved").textContent="",2000);};
447
+ document.querySelectorAll(".tabs button").forEach(b=>b.onclick=()=>{document.querySelectorAll(".tabs 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");});
448
+ $("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"));};
449
+ $("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"));};
450
+ const st=sessionStorage.getItem("dsh-sup-token");
451
+ 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();})();}
452
+ else setWho();
453
+ async function wallTick(){try{const r=await (await fetch("/api/wall")).json();const cards=[[t("week"),r.reportsWeek],[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("");$("wallFeed").textContent=r.feedbackTail||t("noActivity");}catch(e){$("wallFeed").textContent=t("cannotReach");}}
454
+ if(location.search.indexOf("wall=1")>=0){
455
+ document.body.classList.add("wall");show("wallView");
456
+ wallTick();setInterval(wallTick,30000);
457
+ }
458
+ </script>
459
+ </body>
460
+ </html>
Binary file
Binary file
Binary file
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "DSH Assistant โ€” Action Panel",
3
+ "short_name": "DSH Assistant",
4
+ "description": "One-button listening for the J.Franco Agentic Workflow Suite on DeepSeek Harness. The AI listens, works, proposes, and reports โ€” you verify and decide.",
5
+ "start_url": "./panel.html",
6
+ "scope": "./",
7
+ "display": "standalone",
8
+ "orientation": "any",
9
+ "background_color": "#f6f7fb",
10
+ "theme_color": "#4D6BFE",
11
+ "lang": "en",
12
+ "categories": ["productivity", "business", "utilities"],
13
+ "icons": [
14
+ { "src": "icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
15
+ { "src": "icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
16
+ ]
17
+ }