diff --git a/internal/catalog/findings.go b/internal/catalog/findings.go
index a72ce4a..0f72a12 100644
--- a/internal/catalog/findings.go
+++ b/internal/catalog/findings.go
@@ -2,6 +2,7 @@ package catalog
import (
"fmt"
+ "regexp"
"strings"
"openscale/internal/domain"
@@ -86,13 +87,16 @@ func noBarcode(r Row) domain.Finding {
}
}
-// invalidBarcode reports thirteen characters that are not a readable EAN-13.
+// invalidBarcode reports a code the till could not read as an EAN-13.
//
// It NAMES the check digit that was expected, because that is the difference between
// « code-barres invalide » and a correction somebody can type: six of the seven
// offending codes of flv_1.csv are one digit away from being right.
+//
+// A code a spreadsheet turned into a number gets its OWN sentence, and that is not
+// cosmetic: the work it asks for is not in Odoo at all (see spreadsheetNumber).
func invalidBarcode(r Row) domain.Finding {
- return domain.Finding{
+ f := domain.Finding{
CSVLine: r.Line,
ProductID: r.ID,
ProductName: r.Name,
@@ -102,8 +106,28 @@ func invalidBarcode(r Row) domain.Finding {
Message: fmt.Sprintf("Corriger le code-barres « %s » : %s. "+
"Un scanner de caisse le refusera.", r.Barcode, whyNotEAN13(r.Barcode)),
}
+ if spreadsheetNumber.MatchString(r.Barcode) {
+ f.Message = fmt.Sprintf("Réexporter le catalogue depuis Odoo sans ouvrir le "+
+ "fichier dans un tableur : « %s » n'est pas un code-barres mais un nombre en "+
+ "notation scientifique, ce qu'un tableur fait d'une colonne de treize "+
+ "chiffres dès qu'il l'enregistre. Les chiffres perdus ne se devinent pas, et "+
+ "les autres codes du fichier sont sans doute dans le même état.", r.Barcode)
+ }
+ return f
}
+// spreadsheetNumber recognises a code that went through a spreadsheet on its way here.
+//
+// Opening the export in Excel or LibreOffice and saving it back reads a column of
+// thirteen digits as a NUMBER: 3700147202196 comes out « 3,70015E+12 », six significant
+// figures and seven digits gone for good. Saying it counts eleven characters instead of
+// thirteen is true and useless — nobody can retype what the file no longer carries, the
+// record in Odoo is very probably intact, and the fix is to produce the file again.
+//
+// No genuine barcode can match: a barcode is digits and nothing else, and this pattern
+// requires an exponent.
+var spreadsheetNumber = regexp.MustCompile(`^[0-9]+([.,][0-9]+)?[eE][+-]?[0-9]+$`)
+
// whyNotEAN13 says, in French, which of the two faults a code carries.
//
// The two lead to different work: a wrong check digit is a typing mistake to fix at
diff --git a/internal/catalog/qualify_test.go b/internal/catalog/qualify_test.go
index e301c2f..eb8516b 100644
--- a/internal/catalog/qualify_test.go
+++ b/internal/catalog/qualify_test.go
@@ -356,6 +356,39 @@ func TestTheReservedZoneMessageNamesTheDigitsAndTheValue(t *testing.T) {
}
}
+// TestASpreadsheetNumberIsNamedForWhatItIs covers the one invalid barcode nobody can
+// fix in Odoo, because Odoo is not where it broke.
+//
+// « 3,70015E+12 » is what a spreadsheet leaves of 3700147202196 after opening the
+// export and saving it back: thirteen digits read as a number, kept to six significant
+// figures. Counting its eleven characters is TRUE and worth nothing — the digits are
+// gone, they cannot be typed back from the report, and every other code of the file is
+// in the same state. The only usable instruction is to export again.
+func TestASpreadsheetNumberIsNamedForWhatItIs(t *testing.T) {
+ for _, mangled := range []string{"3,70015E+12", "3.70015E+12", "3,70015e+12", "4,93E+11"} {
+ _, findings, _ := catalog.Qualify(row(func(r *catalog.Row) { r.Barcode = mangled }))
+ if len(findings) != 1 || findings[0].Code != domain.FindingInvalidBarcode {
+ t.Fatalf("%s : signalements %v, attendu INVALID_BARCODE", mangled, codes(findings))
+ }
+ message := findings[0].Message
+ if strings.Contains(message, "caractères au lieu de 13") {
+ t.Errorf("%s : le message compte les caractères d'un nombre : %s", mangled, message)
+ }
+ for _, expected := range []string{mangled, "Réexporter", "tableur"} {
+ if !strings.Contains(message, expected) {
+ t.Errorf("le message ne contient pas %q : %s", expected, message)
+ }
+ }
+ }
+
+ // A code that really is a short string of digits keeps the count: there, the number
+ // of characters IS the fault, and someone retypes it in Odoo.
+ _, findings, _ := catalog.Qualify(row(func(r *catalog.Row) { r.Barcode = "049302100000" }))
+ if !strings.Contains(findings[0].Message, "12 caractères au lieu de 13") {
+ t.Errorf("un code court a perdu son décompte : %s", findings[0].Message)
+ }
+}
+
// codes lists the codes of a slice of findings, for a failure message.
func codes(findings []domain.Finding) []string {
out := make([]string, 0, len(findings))
diff --git a/internal/web/dist/admin.html b/internal/web/dist/admin.html
index 7e6fcba..d1a5580 100644
--- a/internal/web/dist/admin.html
+++ b/internal/web/dist/admin.html
@@ -5,9 +5,9 @@
Administration
-
+
-
+
diff --git a/internal/web/dist/assets/admin-DEu9sOlj.js b/internal/web/dist/assets/admin-DEu9sOlj.js
deleted file mode 100644
index aba8cec..0000000
--- a/internal/web/dist/assets/admin-DEu9sOlj.js
+++ /dev/null
@@ -1 +0,0 @@
-import"./app-BaRSXv80.js";import{mountAdmin as m}from"./mount-D3UhzFzr.js";m(document.getElementById("app"));
diff --git a/internal/web/dist/assets/admin-tZr91ixu.js b/internal/web/dist/assets/admin-tZr91ixu.js
new file mode 100644
index 0000000..d59f2ee
--- /dev/null
+++ b/internal/web/dist/assets/admin-tZr91ixu.js
@@ -0,0 +1 @@
+import"./app-BaRSXv80.js";import{mountAdmin as m}from"./mount-1OvlPcKC.js";m(document.getElementById("app"));
diff --git a/internal/web/dist/assets/index-BoOKWXIu.js b/internal/web/dist/assets/index-DPFlyzED.js
similarity index 99%
rename from internal/web/dist/assets/index-BoOKWXIu.js
rename to internal/web/dist/assets/index-DPFlyzED.js
index 9872a39..8a75d0d 100644
--- a/internal/web/dist/assets/index-BoOKWXIu.js
+++ b/internal/web/dist/assets/index-DPFlyzED.js
@@ -1,2 +1,2 @@
-const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mount-D3UhzFzr.js","assets/app-BaRSXv80.js","assets/app-Cfxw4Luj.css","assets/mount-MmpjwdB2.css"])))=>i.map(i=>d[i]);
-import{e as Ie,u as je,d as re,p as Y,a as q,i as W,I as ee,t as z,b as N,c as w,f as Z,g as E,h as t,s as h,j as ae,k as te,l as se,m as T,n as v,o as u,q as Pe,r as fe,w as De,v as Te,x as ne,y as Ce,R as Re,z as b,A as D,B as qe,T as Le,C as Ne,N as Oe,D as Me,E as We,F as Be,G as Fe,H as ze,M as He,J as Ue,K as Ve,L as Ge,O as Xe,P as Ke,Q as Je,S as Qe,U as Ye,V as Ze,W as $e,X as et}from"./app-BaRSXv80.js";class be{#e=new WeakMap;#t;#n;static entries=new WeakMap;constructor(e){this.#n=e}observe(e,n){var r=this.#e.get(e)||new Set;return r.add(n),this.#e.set(e,r),this.#s().observe(e,this.#n),()=>{var l=this.#e.get(e);l.delete(n),l.size===0&&(this.#e.delete(e),this.#t.unobserve(e))}}#s(){return this.#t??(this.#t=new ResizeObserver(e=>{for(var n of e){be.entries.set(n.target,n);for(var r of this.#e.get(n.target)||[])r(n)}}))}}var tt=new be({box:"border-box"});function he(s,e,n){var r=tt.observe(s,()=>n(s[e]));Ie(()=>(je(()=>n(s[e])),r))}const nt="modulepreload",at=function(s){return"/"+s},ye={},st=function(e,n,r){let l=Promise.resolve();if(n&&n.length>0){let _=function(o){return Promise.all(o.map(i=>Promise.resolve(i).then(y=>({status:"fulfilled",value:y}),y=>({status:"rejected",reason:y}))))};document.getElementsByTagName("link");const c=document.querySelector("meta[property=csp-nonce]"),d=c?.nonce||c?.getAttribute("nonce");l=_(n.map(o=>{if(o=at(o),o in ye)return;ye[o]=!0;const i=o.endsWith(".css"),y=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${y}`))return;const k=document.createElement("link");if(k.rel=i?"stylesheet":nt,i||(k.as="script"),k.crossOrigin="",k.href=o,d&&k.setAttribute("nonce",d),document.head.appendChild(k),i)return new Promise((m,I)=>{k.addEventListener("load",m),k.addEventListener("error",()=>I(new Error(`Unable to preload CSS for ${o}`)))})}))}function f(c){const d=new Event("vite:preloadError",{cancelable:!0});if(d.payload=c,window.dispatchEvent(d),!d.defaultPrevented)throw c}return l.then(c=>{for(const d of c||[])d.status==="rejected"&&f(d.reason);return e().catch(f)})};var rt=E('
');function Ot(s,e){Y(e,!0);const n=["1","2","3","4","5","6","7","8","9","0"];var r=Nt(),l=u(r),f=h(u(l),2),c=u(f),d=h(l,2);fe(d,20,()=>n,m=>m,(m,I)=>{var g=Lt(),P=u(g);z(()=>T(P,I)),N("click",g,()=>e.ondigit(I)),w(m,g)});var _=h(d,2),o=u(_),i=h(o,2),y=h(i,2),k=u(y);ee(k,{name:"check",size:"1.5rem"}),z(()=>T(c,e.grams===""?"0":e.grams)),N("click",o,function(...m){e.onclear?.apply(this,m)}),N("click",i,function(...m){e.oncancel?.apply(this,m)}),N("click",y,function(...m){e.onconfirm?.apply(this,m)}),w(s,r),Z()}re(["click"]);function Mt(s){return s===null||s.state==="initializing"?!1:s.scale.connected&&s.printer.health!=="faulted"}const Ee=1500,Wt=2e3,ke=5e3;function Bt(s,e){return e?s>=ke?{showWeight:!1,banner:"Poids indisponible",mustReconnect:!0}:s>=Wt?{showWeight:!1,banner:"Poids indisponible",mustReconnect:!1}:s>=Ee?{showWeight:!1,banner:"",mustReconnect:!1}:{showWeight:!0,banner:"",mustReconnect:!1}:{showWeight:s=ke}}const Ft=250,Ht={show_grid_prices:!0,idle_timeout_s:45,reprint_window_s:60,sound:!0,show_by_unit_products:!1,grid_columns:0,min_products_for_chip:He};class Ut{#e=D(null);get state(){return t(this.#e)}set state(e){b(this.#e,e,!0)}#t=D(null);get catalog(){return t(this.#t)}set catalog(e){b(this.#t,e,!0)}#n=D(ze({showWeight:!0,banner:"",mustReconnect:!1}));get link(){return t(this.#n)}set link(e){b(this.#n,e,!0)}#s=D("");get catalogError(){return t(this.#s)}set catalogError(e){b(this.#s,e,!0)}#r=null;#i=null;#l=Date.now();#a=!1;#o=!1;get presentation(){return this.catalog?.presentation??Ht}start(){this.#u(),this.#c(),this.#i=setInterval(()=>this.#v(),Ft)}stop(){this.#i!==null&&clearInterval(this.#i),this.#i=null,this.#r?.close(),this.#r=null,this.#a=!1}#c(){const e=new EventSource("/api/v1/stream");this.#r=e,e.onopen=()=>{this.#a=!0,this.#l=Date.now()},e.addEventListener("state",n=>this.#d(n)),e.onerror=()=>{this.#a=!1}}#d(e){this.#l=Date.now(),this.#a=!0;const n=JSON.parse(e.data),r=this.state;if(this.state=n,this.catalog===null)return;const l=n.catalog_count!==this.catalog.product_count,f=r!==null&&n.presentation_digest!==r.presentation_digest;(l||f)&&this.#u()}#v(){const e=Bt(Date.now()-this.#l,this.#a);this.link=e,e.mustReconnect&&(this.#r?.close(),this.#l=Date.now(),this.#c())}async#u(){if(!this.#o){this.#o=!0;try{this.catalog=await Ue(),this.catalogError=""}catch{this.catalog===null&&(this.catalogError="Catalogue indisponible. Prévenez un responsable.")}finally{this.#o=!1}}}}const xe="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ae(){let s=Date.now();const e=new Array(26);for(let r=9;r>=0;r--)e[r]=xe[s%32],s=Math.floor(s/32);const n=new Uint8Array(16);crypto.getRandomValues(n);for(let r=0;r<16;r++)e[10+r]=xe[n[r]%32];return e.join("")}var Vt=E('');function Gt(s,e){Y(e,!0);const n=new Ut;let r=D(ze(Ve)),l=D(""),f=D(!1);const c=v(()=>t(l)!==""||t(f));let d=D(null),_=D(-1),o=D(null);const i=v(()=>n.catalog),y=v(()=>t(i)===null?[]:Qe(t(i))),k=v(()=>t(i)===null?[]:Ke(t(i))),m=v(()=>Xe(t(y),t(r),t(l))),I=v(()=>{const a={};for(const S of t(i)?.categories??[])a[S.code]=S.color;return a}),g=v(()=>n.state),P=v(()=>n.presentation),B=v(()=>Mt(t(g))),R=v(()=>{if(n.catalogError!=="")return{message:n.catalogError,hint:"Le poste réessaie tout seul."};if(t(y).length>0)return{message:"Aucun produit ne correspond.",hint:"Effacez des lettres ou changez de rayon."};if(t(i)!==null&&t(i).products.length>0)return{message:t(i).products.every(U=>U.mode==="by_unit")&&!t(P).show_by_unit_products?"Aucun produit à montrer : ce poste masque les produits vendus à l’unité, et le catalogue reçu ne contient que ceux-là.":"Aucun produit à montrer : les réglages d’affichage de ce poste masquent tout ce qu’il a reçu.",hint:"Le fichier est bien arrivé : prévenez un responsable, c’est un réglage de ce poste qui vide la grille."};const a=t(g)?.station??0;return{message:a>0?`Catalogue vide. En attente du fichier flv_${a}.csv.`:"Catalogue vide. En attente du fichier du poste.",hint:"Prévenez un responsable : aucun produit ne peut être pesé."}}),H=v(()=>t(g)?.state==="rejected"?t(g).product?.id??null:null),V=v(()=>t(g)?.state==="faulted"||t(g)?.state==="out_of_service"),A=["product_armed","weight_present","weight_stable","awaiting_stability","validating","printing"],O=v(()=>t(g)!==null&&A.includes(t(g).state)?t(g).product?.id??null:null),G=v(()=>Pt(t(i)?.updated_at??""));ne(()=>(n.start(),()=>n.stop())),ne(()=>{const a=n.state?.revision??-1;t(d)!==null&&a>t(_)&&(b(d,null),b(_,-1))});async function X(a){if(t(d)===null){b(d,a.id,!0),b(_,n.state?.revision??-1,!0);try{await Ge({product_id:a.id,tare_g:n.state?.weight.tare_g??0,units:1,manual_weight_g:0,seen_weight_g:n.state?.weight.gross_g??0,measurement_seq:n.state?.weight.seq??0,key:Ae()})}catch{b(d,null)}}}async function K(){const a=n.state?.reprint.job_id;a===void 0||a===""||await Je(a,Ae())}function F(){b(l,""),b(f,!1)}function p(){b(f,!0)}function C(){const a=t(m).length===1?t(m)[0]:void 0;a!==void 0&&X(a)}function M(a){if(!(a.metaKey||a.ctrlKey||a.altKey)&&!(a.target instanceof HTMLElement&&a.target.tagName==="INPUT")&&!(t(o)!==null||t(V))){if(a.key==="Escape"){a.preventDefault(),F();return}if(a.key==="Backspace"){a.preventDefault(),b(l,t(l).slice(0,-1),!0);return}if(a.key==="Enter"){C();return}a.key.length===1&&/[a-zA-Z0-9 ]/.test(a.key)&&(a.key===" "&&t(l)===""||(a.preventDefault(),b(l,t(l)+a.key)))}}ne(()=>(window.addEventListener("keydown",M),()=>window.removeEventListener("keydown",M)));async function $(){(await st(()=>import("./mount-D3UhzFzr.js"),__vite__mapDeps([0,1,2,3]))).mountAdmin(document.body)}var ie=Vt(),oe=u(ie);{let a=v(()=>t(o)!==null);ot(oe,{get snapshot(){return t(g)},get showWeight(){return n.link.showWeight},get linkBanner(){return n.link.banner},get taring(){return t(a)},ontare:()=>b(o,"")})}var J=h(oe,2);{var ce=a=>{Ot(a,{get grams(){return t(o)},ondigit:S=>b(o,(t(o)??"")+S),onclear:()=>b(o,""),oncancel:()=>b(o,null),onconfirm:()=>b(o,null)})};W(J,a=>{t(o)!==null&&a(ce)})}var le=h(J,2);{let a=v(()=>t(i)?.pricing.primary_code??""),S=v(()=>Object.fromEntries((t(i)?.pricing.tiers??[]).map(Q=>[Q.code,Q.abbrev]))),U=v(()=>t(i)===null&&n.catalogError==="");Et(le,{get products(){return t(m)},get colors(){return t(I)},get primaryCode(){return t(a)},get tierAbbrev(){return t(S)},get selectedID(){return t(O)},get rejectedID(){return t(H)},get busyID(){return t(d)},get showPrices(){return t(P).show_grid_prices},get gridColumns(){return t(P).grid_columns},get loading(){return t(U)},get emptyMessage(){return t(R).message},get emptyHint(){return t(R).hint},onpick:X})}var ue=h(le,2);{var pe=a=>{At(a,{get query(){return t(l)},onquery:S=>b(l,S,!0),onclose:F,onenter:C})};W(ue,a=>{t(c)&&a(pe)})}var de=h(ue,2);dt(de,{get chips(){return t(k)},get active(){return t(r)},get searchFieldOpen(){return t(c)},onselect:a=>b(r,a,!0),onopensearch:p});var ve=h(de,2);{let a=v(()=>t(g)?.last_label??null),S=v(()=>t(g)?.reprint.available??!1),U=v(()=>t(i)?.app_version??"");qt(ve,{get label(){return t(a)},get available(){return t(S)},get catalogAt(){return t(G)},get productCount(){return t(y).length},get appVersion(){return t(U)},get healthy(){return t(B)},onreprint:K,onadmin:$})}var x=h(ve,2);{var L=a=>{{let S=v(()=>t(g).message?.text??"Prévenez un responsable.");we(a,{title:"Poste indisponible",get detail(){return t(S)},get code(){return t(g).fault_code},action:{label:"J’ai compris",run:()=>{Ye()}}})}},j=a=>{we(a,{title:"Poste hors service",detail:"Ce poste ne peut pas peser. Prévenez un responsable.",get code(){return t(g).fault_code}})};W(x,a=>{t(g)?.state==="faulted"?a(L):t(g)?.state==="out_of_service"&&a(j,1)})}w(s,ie),Z()}const Xt=5,Kt="ResizeObserver loop";function Jt(){let s=!1,e=!1;const n=(c,d)=>{s||(s=!0,$e(c,d),Qt(),setTimeout(()=>location.reload(),Xt*1e3))},r=c=>{e||(e=!0,Ze(c))},l=c=>{if((c.error===void 0||c.error===null)&&c.message.startsWith(Kt)){r(c.message);return}n(c.message,c.error?.stack??"")},f=c=>{n(String(c.reason),c.reason?.stack??"")};return window.addEventListener("error",l),window.addEventListener("unhandledrejection",f),()=>{window.removeEventListener("error",l),window.removeEventListener("unhandledrejection",f)}}function Qt(){const s=document.createElement("div");s.className="fatal",s.append(me("h1","Une erreur est survenue"),me("p","L’écran va se recharger tout seul."),me("p","ERR-UI-01","code")),document.body.appendChild(s)}function me(s,e,n=""){const r=document.createElement(s);return r.textContent=e,n!==""&&(r.className=n),r}Jt();document.addEventListener("contextmenu",s=>{Yt(s.target)||s.preventDefault()});document.addEventListener("dragstart",s=>s.preventDefault());et(Gt,{target:document.getElementById("app")});function Yt(s){return s instanceof Element&&s.closest("[data-admin]")!==null}
+const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mount-1OvlPcKC.js","assets/app-BaRSXv80.js","assets/app-Cfxw4Luj.css","assets/mount-MmpjwdB2.css"])))=>i.map(i=>d[i]);
+import{e as Ie,u as je,d as re,p as Y,a as q,i as W,I as ee,t as z,b as N,c as w,f as Z,g as E,h as t,s as h,j as ae,k as te,l as se,m as T,n as v,o as u,q as Pe,r as fe,w as De,v as Te,x as ne,y as Ce,R as Re,z as b,A as D,B as qe,T as Le,C as Ne,N as Oe,D as Me,E as We,F as Be,G as Fe,H as ze,M as He,J as Ue,K as Ve,L as Ge,O as Xe,P as Ke,Q as Je,S as Qe,U as Ye,V as Ze,W as $e,X as et}from"./app-BaRSXv80.js";class be{#e=new WeakMap;#t;#n;static entries=new WeakMap;constructor(e){this.#n=e}observe(e,n){var r=this.#e.get(e)||new Set;return r.add(n),this.#e.set(e,r),this.#s().observe(e,this.#n),()=>{var l=this.#e.get(e);l.delete(n),l.size===0&&(this.#e.delete(e),this.#t.unobserve(e))}}#s(){return this.#t??(this.#t=new ResizeObserver(e=>{for(var n of e){be.entries.set(n.target,n);for(var r of this.#e.get(n.target)||[])r(n)}}))}}var tt=new be({box:"border-box"});function he(s,e,n){var r=tt.observe(s,()=>n(s[e]));Ie(()=>(je(()=>n(s[e])),r))}const nt="modulepreload",at=function(s){return"/"+s},ye={},st=function(e,n,r){let l=Promise.resolve();if(n&&n.length>0){let _=function(o){return Promise.all(o.map(i=>Promise.resolve(i).then(y=>({status:"fulfilled",value:y}),y=>({status:"rejected",reason:y}))))};document.getElementsByTagName("link");const c=document.querySelector("meta[property=csp-nonce]"),d=c?.nonce||c?.getAttribute("nonce");l=_(n.map(o=>{if(o=at(o),o in ye)return;ye[o]=!0;const i=o.endsWith(".css"),y=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${y}`))return;const k=document.createElement("link");if(k.rel=i?"stylesheet":nt,i||(k.as="script"),k.crossOrigin="",k.href=o,d&&k.setAttribute("nonce",d),document.head.appendChild(k),i)return new Promise((m,I)=>{k.addEventListener("load",m),k.addEventListener("error",()=>I(new Error(`Unable to preload CSS for ${o}`)))})}))}function f(c){const d=new Event("vite:preloadError",{cancelable:!0});if(d.payload=c,window.dispatchEvent(d),!d.defaultPrevented)throw c}return l.then(c=>{for(const d of c||[])d.status==="rejected"&&f(d.reason);return e().catch(f)})};var rt=E('
');function Ot(s,e){Y(e,!0);const n=["1","2","3","4","5","6","7","8","9","0"];var r=Nt(),l=u(r),f=h(u(l),2),c=u(f),d=h(l,2);fe(d,20,()=>n,m=>m,(m,I)=>{var g=Lt(),P=u(g);z(()=>T(P,I)),N("click",g,()=>e.ondigit(I)),w(m,g)});var _=h(d,2),o=u(_),i=h(o,2),y=h(i,2),k=u(y);ee(k,{name:"check",size:"1.5rem"}),z(()=>T(c,e.grams===""?"0":e.grams)),N("click",o,function(...m){e.onclear?.apply(this,m)}),N("click",i,function(...m){e.oncancel?.apply(this,m)}),N("click",y,function(...m){e.onconfirm?.apply(this,m)}),w(s,r),Z()}re(["click"]);function Mt(s){return s===null||s.state==="initializing"?!1:s.scale.connected&&s.printer.health!=="faulted"}const Ee=1500,Wt=2e3,ke=5e3;function Bt(s,e){return e?s>=ke?{showWeight:!1,banner:"Poids indisponible",mustReconnect:!0}:s>=Wt?{showWeight:!1,banner:"Poids indisponible",mustReconnect:!1}:s>=Ee?{showWeight:!1,banner:"",mustReconnect:!1}:{showWeight:!0,banner:"",mustReconnect:!1}:{showWeight:s=ke}}const Ft=250,Ht={show_grid_prices:!0,idle_timeout_s:45,reprint_window_s:60,sound:!0,show_by_unit_products:!1,grid_columns:0,min_products_for_chip:He};class Ut{#e=D(null);get state(){return t(this.#e)}set state(e){b(this.#e,e,!0)}#t=D(null);get catalog(){return t(this.#t)}set catalog(e){b(this.#t,e,!0)}#n=D(ze({showWeight:!0,banner:"",mustReconnect:!1}));get link(){return t(this.#n)}set link(e){b(this.#n,e,!0)}#s=D("");get catalogError(){return t(this.#s)}set catalogError(e){b(this.#s,e,!0)}#r=null;#i=null;#l=Date.now();#a=!1;#o=!1;get presentation(){return this.catalog?.presentation??Ht}start(){this.#u(),this.#c(),this.#i=setInterval(()=>this.#v(),Ft)}stop(){this.#i!==null&&clearInterval(this.#i),this.#i=null,this.#r?.close(),this.#r=null,this.#a=!1}#c(){const e=new EventSource("/api/v1/stream");this.#r=e,e.onopen=()=>{this.#a=!0,this.#l=Date.now()},e.addEventListener("state",n=>this.#d(n)),e.onerror=()=>{this.#a=!1}}#d(e){this.#l=Date.now(),this.#a=!0;const n=JSON.parse(e.data),r=this.state;if(this.state=n,this.catalog===null)return;const l=n.catalog_count!==this.catalog.product_count,f=r!==null&&n.presentation_digest!==r.presentation_digest;(l||f)&&this.#u()}#v(){const e=Bt(Date.now()-this.#l,this.#a);this.link=e,e.mustReconnect&&(this.#r?.close(),this.#l=Date.now(),this.#c())}async#u(){if(!this.#o){this.#o=!0;try{this.catalog=await Ue(),this.catalogError=""}catch{this.catalog===null&&(this.catalogError="Catalogue indisponible. Prévenez un responsable.")}finally{this.#o=!1}}}}const xe="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ae(){let s=Date.now();const e=new Array(26);for(let r=9;r>=0;r--)e[r]=xe[s%32],s=Math.floor(s/32);const n=new Uint8Array(16);crypto.getRandomValues(n);for(let r=0;r<16;r++)e[10+r]=xe[n[r]%32];return e.join("")}var Vt=E('');function Gt(s,e){Y(e,!0);const n=new Ut;let r=D(ze(Ve)),l=D(""),f=D(!1);const c=v(()=>t(l)!==""||t(f));let d=D(null),_=D(-1),o=D(null);const i=v(()=>n.catalog),y=v(()=>t(i)===null?[]:Qe(t(i))),k=v(()=>t(i)===null?[]:Ke(t(i))),m=v(()=>Xe(t(y),t(r),t(l))),I=v(()=>{const a={};for(const S of t(i)?.categories??[])a[S.code]=S.color;return a}),g=v(()=>n.state),P=v(()=>n.presentation),B=v(()=>Mt(t(g))),R=v(()=>{if(n.catalogError!=="")return{message:n.catalogError,hint:"Le poste réessaie tout seul."};if(t(y).length>0)return{message:"Aucun produit ne correspond.",hint:"Effacez des lettres ou changez de rayon."};if(t(i)!==null&&t(i).products.length>0)return{message:t(i).products.every(U=>U.mode==="by_unit")&&!t(P).show_by_unit_products?"Aucun produit à montrer : ce poste masque les produits vendus à l’unité, et le catalogue reçu ne contient que ceux-là.":"Aucun produit à montrer : les réglages d’affichage de ce poste masquent tout ce qu’il a reçu.",hint:"Le fichier est bien arrivé : prévenez un responsable, c’est un réglage de ce poste qui vide la grille."};const a=t(g)?.station??0;return{message:a>0?`Catalogue vide. En attente du fichier flv_${a}.csv.`:"Catalogue vide. En attente du fichier du poste.",hint:"Prévenez un responsable : aucun produit ne peut être pesé."}}),H=v(()=>t(g)?.state==="rejected"?t(g).product?.id??null:null),V=v(()=>t(g)?.state==="faulted"||t(g)?.state==="out_of_service"),A=["product_armed","weight_present","weight_stable","awaiting_stability","validating","printing"],O=v(()=>t(g)!==null&&A.includes(t(g).state)?t(g).product?.id??null:null),G=v(()=>Pt(t(i)?.updated_at??""));ne(()=>(n.start(),()=>n.stop())),ne(()=>{const a=n.state?.revision??-1;t(d)!==null&&a>t(_)&&(b(d,null),b(_,-1))});async function X(a){if(t(d)===null){b(d,a.id,!0),b(_,n.state?.revision??-1,!0);try{await Ge({product_id:a.id,tare_g:n.state?.weight.tare_g??0,units:1,manual_weight_g:0,seen_weight_g:n.state?.weight.gross_g??0,measurement_seq:n.state?.weight.seq??0,key:Ae()})}catch{b(d,null)}}}async function K(){const a=n.state?.reprint.job_id;a===void 0||a===""||await Je(a,Ae())}function F(){b(l,""),b(f,!1)}function p(){b(f,!0)}function C(){const a=t(m).length===1?t(m)[0]:void 0;a!==void 0&&X(a)}function M(a){if(!(a.metaKey||a.ctrlKey||a.altKey)&&!(a.target instanceof HTMLElement&&a.target.tagName==="INPUT")&&!(t(o)!==null||t(V))){if(a.key==="Escape"){a.preventDefault(),F();return}if(a.key==="Backspace"){a.preventDefault(),b(l,t(l).slice(0,-1),!0);return}if(a.key==="Enter"){C();return}a.key.length===1&&/[a-zA-Z0-9 ]/.test(a.key)&&(a.key===" "&&t(l)===""||(a.preventDefault(),b(l,t(l)+a.key)))}}ne(()=>(window.addEventListener("keydown",M),()=>window.removeEventListener("keydown",M)));async function $(){(await st(()=>import("./mount-1OvlPcKC.js"),__vite__mapDeps([0,1,2,3]))).mountAdmin(document.body)}var ie=Vt(),oe=u(ie);{let a=v(()=>t(o)!==null);ot(oe,{get snapshot(){return t(g)},get showWeight(){return n.link.showWeight},get linkBanner(){return n.link.banner},get taring(){return t(a)},ontare:()=>b(o,"")})}var J=h(oe,2);{var ce=a=>{Ot(a,{get grams(){return t(o)},ondigit:S=>b(o,(t(o)??"")+S),onclear:()=>b(o,""),oncancel:()=>b(o,null),onconfirm:()=>b(o,null)})};W(J,a=>{t(o)!==null&&a(ce)})}var le=h(J,2);{let a=v(()=>t(i)?.pricing.primary_code??""),S=v(()=>Object.fromEntries((t(i)?.pricing.tiers??[]).map(Q=>[Q.code,Q.abbrev]))),U=v(()=>t(i)===null&&n.catalogError==="");Et(le,{get products(){return t(m)},get colors(){return t(I)},get primaryCode(){return t(a)},get tierAbbrev(){return t(S)},get selectedID(){return t(O)},get rejectedID(){return t(H)},get busyID(){return t(d)},get showPrices(){return t(P).show_grid_prices},get gridColumns(){return t(P).grid_columns},get loading(){return t(U)},get emptyMessage(){return t(R).message},get emptyHint(){return t(R).hint},onpick:X})}var ue=h(le,2);{var pe=a=>{At(a,{get query(){return t(l)},onquery:S=>b(l,S,!0),onclose:F,onenter:C})};W(ue,a=>{t(c)&&a(pe)})}var de=h(ue,2);dt(de,{get chips(){return t(k)},get active(){return t(r)},get searchFieldOpen(){return t(c)},onselect:a=>b(r,a,!0),onopensearch:p});var ve=h(de,2);{let a=v(()=>t(g)?.last_label??null),S=v(()=>t(g)?.reprint.available??!1),U=v(()=>t(i)?.app_version??"");qt(ve,{get label(){return t(a)},get available(){return t(S)},get catalogAt(){return t(G)},get productCount(){return t(y).length},get appVersion(){return t(U)},get healthy(){return t(B)},onreprint:K,onadmin:$})}var x=h(ve,2);{var L=a=>{{let S=v(()=>t(g).message?.text??"Prévenez un responsable.");we(a,{title:"Poste indisponible",get detail(){return t(S)},get code(){return t(g).fault_code},action:{label:"J’ai compris",run:()=>{Ye()}}})}},j=a=>{we(a,{title:"Poste hors service",detail:"Ce poste ne peut pas peser. Prévenez un responsable.",get code(){return t(g).fault_code}})};W(x,a=>{t(g)?.state==="faulted"?a(L):t(g)?.state==="out_of_service"&&a(j,1)})}w(s,ie),Z()}const Xt=5,Kt="ResizeObserver loop";function Jt(){let s=!1,e=!1;const n=(c,d)=>{s||(s=!0,$e(c,d),Qt(),setTimeout(()=>location.reload(),Xt*1e3))},r=c=>{e||(e=!0,Ze(c))},l=c=>{if((c.error===void 0||c.error===null)&&c.message.startsWith(Kt)){r(c.message);return}n(c.message,c.error?.stack??"")},f=c=>{n(String(c.reason),c.reason?.stack??"")};return window.addEventListener("error",l),window.addEventListener("unhandledrejection",f),()=>{window.removeEventListener("error",l),window.removeEventListener("unhandledrejection",f)}}function Qt(){const s=document.createElement("div");s.className="fatal",s.append(me("h1","Une erreur est survenue"),me("p","L’écran va se recharger tout seul."),me("p","ERR-UI-01","code")),document.body.appendChild(s)}function me(s,e,n=""){const r=document.createElement(s);return r.textContent=e,n!==""&&(r.className=n),r}Jt();document.addEventListener("contextmenu",s=>{Yt(s.target)||s.preventDefault()});document.addEventListener("dragstart",s=>s.preventDefault());et(Gt,{target:document.getElementById("app")});function Yt(s){return s instanceof Element&&s.closest("[data-admin]")!==null}
diff --git a/internal/web/dist/assets/mount-D3UhzFzr.js b/internal/web/dist/assets/mount-1OvlPcKC.js
similarity index 94%
rename from internal/web/dist/assets/mount-D3UhzFzr.js
rename to internal/web/dist/assets/mount-1OvlPcKC.js
index 3f6541e..7800b83 100644
--- a/internal/web/dist/assets/mount-D3UhzFzr.js
+++ b/internal/web/dist/assets/mount-1OvlPcKC.js
@@ -1,4 +1,4 @@
-import{Y as Tr,Z as zr,_ as jr,$ as Ea,a0 as Vt,e as Rr,a1 as or,a2 as Or,a3 as Ar,a4 as Nr,u as ma,a5 as Ca,a6 as Ir,a7 as ur,x as wt,A as B,h as e,z as v,H as vt,d as ot,a as Be,s as n,i as _,t as f,l as Nt,j as be,m as o,b as Ce,c as l,o as s,g as c,p as Ue,I as Dr,f as Me,n as u,q as ae,a8 as Ia,r as ze,G as Gt,a9 as ea,aa as Tt,B as da,ab as lt,ac as Xt,ad as ka,C as Fr,J as cr,y as sa,T as Ur,ae as Ht,F as Mr,E as Wr,D as Br,O as Vr,K as Gr,X as Hr,af as Jr}from"./app-BaRSXv80.js";function dr(a){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function Kr(a,t,...r){var i=new jr(a);Tr(()=>{const d=t()??null;i.ensure(d,d&&(p=>d(p,...r)))},zr)}function Pa(a,t,r=!1){if(a.multiple){if(t==null)return;if(!Or(t))return Ar();for(var i of a.options)i.selected=t.includes(la(i));return}for(i of a.options){var d=la(i);if(Nr(d,t)){i.selected=!0;return}}(!r||t!==void 0)&&(a.selectedIndex=-1)}function vr(a){var t=new MutationObserver(()=>{"__value"in a&&Pa(a,a.__value)});t.observe(a,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),or(()=>{t.disconnect()})}function $r(a,t,r=t){var i=new WeakSet,d=!0;Ea(a,"change",p=>{var y=p?"[selected]":":checked",z;if(a.multiple)z=[].map.call(a.querySelectorAll(y),la);else{var m=a.querySelector(y)??a.querySelector("option:not([disabled])");z=m&&la(m)}r(z),a.__value=z,Vt!==null&&i.add(Vt)}),Rr(()=>{var p=t();if(a===document.activeElement){var y=Vt;if(i.has(y))return}if(Pa(a,p,d),d&&p===void 0){var z=a.querySelector(":checked");z!==null&&(p=la(z),r(p))}a.__value=p,d=!1}),vr(a)}function la(a){return"__value"in a?a.__value:a.value}function ia(a,t,r=t){var i=new WeakSet;Ea(a,"input",async d=>{var p=d?a.defaultValue:a.value;if(p=ba(a)?wa(p):p,r(p),Vt!==null&&i.add(Vt),await Ir(),p!==(p=t())){var y=a.selectionStart,z=a.selectionEnd,m=a.value.length;if(a.value=p??"",z!==null){var j=a.value.length;y===z&&z===m&&j>m?(a.selectionStart=j,a.selectionEnd=j):(a.selectionStart=y,a.selectionEnd=Math.min(z,j))}}}),ma(t)==null&&a.value&&(r(ba(a)?wa(a.value):a.value),Vt!==null&&i.add(Vt)),Ca(()=>{var d=t();if(a===document.activeElement){var p=Vt;if(i.has(p))return}ba(a)&&d===wa(a.value)||a.type==="date"&&!d&&!a.value||d!==a.value&&(a.value=d??"")})}function Da(a,t,r=t){Ea(a,"change",i=>{var d=i?a.defaultChecked:a.checked;r(d)}),ma(t)==null&&r(a.checked),Ca(()=>{var i=t();a.checked=!!i})}function ba(a){var t=a.type;return t==="number"||t==="range"}function wa(a){return a===""?null:+a}function Fa(a,t,r,i,d){var p=()=>{i(r[a])};r.addEventListener(t,p),d?Ca(()=>{r[a]=d()}):p(),(r===document.body||r===window||r===document)&&or(()=>{r.removeEventListener(t,p)})}function Ta(a){ur===null&&dr(),wt(()=>{const t=ma(a);if(typeof t=="function")return t})}function Yr(a){ur===null&&dr(),Ta(()=>()=>ma(a))}const Xr="ERR-CFG-02";class Pt extends Error{constructor(t,r,i="",d=[]){super(r),this.status=t,this.code=i,this.faults=d,this.name="AdminError"}status;code;faults;get needsPassword(){return this.status===401}get needsFirstPassword(){return this.status===409&&this.code===Xr}get needsCredentials(){return this.needsPassword||this.needsFirstPassword}}function fa(a){return a instanceof Pt&&a.needsCredentials}function Qr(){return It("/admin/api/health")}function Zr(){return He("/admin/api/troubleshooting/reprint",{})}function en(){return He("/admin/api/troubleshooting/reload-catalog",{})}function tn(a){return He("/admin/api/troubleshooting/manual-entry",{on:a})}function an(){return He("/admin/api/troubleshooting/roll-changed",{})}function rn(a){return He("/admin/api/troubleshooting/fallback-printer",{on:a})}function nn(){return He("/admin/api/troubleshooting/test-scale",{})}function sn(){return He("/admin/api/troubleshooting/test-printer",{})}function ln(){return He("/admin/api/troubleshooting/test-label",{})}async function pr(a){const t=new FormData;t.append("file",a,a.name);const r=await fetch("/admin/api/catalog/import",{method:"POST",body:t});return Ra(r,"POST /admin/api/catalog/import")}const on="/admin/api/diagnostic.zip";function un(a){return He("/admin/api/session",{password:a})}async function cn(){await fetch("/admin/api/session",{method:"DELETE"})}function dn(a,t){return He("/admin/api/session/recovery",{code:a,password:t})}function za(){return It("/admin/api/config")}function vn(a){return ja("PUT","/admin/api/config",a)}function pn(){return He("/admin/api/config/reload",{})}function fn(){return He("/admin/api/restart",{})}function gn(){return He("/admin/api/reboot",{})}function mn(){return ja("DELETE","/admin/api/reboot",{})}function hn(){return He("/admin/api/config/confirm",{})}async function _n(){return(await It("/admin/api/config/versions")).versions}function bn(a){return He("/admin/api/config/restore",{version:a})}async function wn(){return(await It("/admin/api/ports")).ports}async function yn(){return(await It("/admin/api/printers")).printers}async function xn(){return(await He("/admin/api/printers/discover",{})).printers}function kn(a){return He("/admin/api/scale/detect",{port:a})}async function Ua(a,t){return(await He("/admin/api/scale/capture",{port:a,seconds:t})).frames}function fr(a){return He("/admin/api/printer/test?what="+a,{})}function qn(a,t,r,i){const d=new URLSearchParams({template:a,demo:t?"1":"0",dual:r?"1":"0"});return d.set("t",String(i)),"/admin/api/label/preview.png?"+d.toString()}async function Sn(a){const t=new URLSearchParams(a);return(await It("/admin/api/journal?"+t)).weighings}function Ln(a){return"/admin/api/journal/export.csv?"+new URLSearchParams(a).toString()}async function En(a){const t=new URLSearchParams(a);return(await It("/admin/api/technical?"+t)).entries}function Cn(a){const t=a===void 0?"":"?id="+String(a);return It("/admin/api/imports"+t)}function Pn(){return He("/admin/api/catalog/reload",{})}function Tn(){return He("/admin/api/catalog/forget-quarantine",{})}function Ma(a,t){return He("/admin/api/products/"+encodeURIComponent(a)+"/decision",t)}function zn(a){return He("/admin/api/replay",{frame:a})}async function It(a){const t=await fetch(a,{headers:{accept:"application/json"}});return Ra(t,"GET "+a)}function He(a,t){return ja("POST",a,t)}async function ja(a,t,r){const i=await fetch(t,{method:a,headers:{"content-type":"application/json"},body:JSON.stringify(r)});return Ra(i,a+" "+t)}async function Ra(a,t){const r=await a.text();if(!a.ok){const i=gr(r);throw new Pt(a.status,Rn(r,t,a.status)+jn(a),i?.code??"",i?.faults??[])}if(r!=="")return JSON.parse(r)}function jn(a){if(a.status!==429)return"";const t=Number(a.headers.get("Retry-After")??"");if(!Number.isFinite(t)||t<=0)return"";const r=Math.ceil(t/60);return r>1?` Réessayez dans ${String(r)} minutes.`:" Réessayez dans une minute."}function Rn(a,t,r){const i=gr(a);return i?.message!==void 0&&i.message!==""?i.message:`${t} a répondu ${String(r)}.`}function gr(a){try{return JSON.parse(a)}catch{return null}}function On(){return It("/admin/api/update")}function An(){return He("/admin/api/update/check",{})}function Nn(a){return He("/admin/api/update/apply",{version:a})}class In{constructor(t){this.admin=t}admin;#t=B(null);get config(){return e(this.#t)}set config(t){v(this.#t,t,!0)}#r=B("");get fingerprint(){return e(this.#r)}set fingerprint(t){v(this.#r,t,!0)}#a=B(vt([]));get retired(){return e(this.#a)}set retired(t){v(this.#a,t,!0)}#e=B(null);get pending(){return e(this.#e)}set pending(t){v(this.#e,t,!0)}#n=B(vt([]));get faults(){return e(this.#n)}set faults(t){v(this.#n,t,!0)}#l=B(!1);get dirty(){return e(this.#l)}set dirty(t){v(this.#l,t,!0)}async load(){const t=await this.admin.load(()=>za());t!==null&&(this.config=t.config,this.fingerprint=t.config_fingerprint,this.retired=t.retired_keys??[],this.pending=t.pending_confirmation,this.faults=[],this.dirty=!1)}value(t){let r=this.config;for(const i of t.split(".")){if(r===null||typeof r!="object")return;r=r[i]}return r}text(t){const r=this.value(t);return r==null?"":String(r)}number(t){const r=this.value(t);return typeof r=="number"?r:Number(r??0)}flag(t){return this.value(t)===!0}set(t,r){if(this.config===null)return;const i=t.split("."),d=i.pop();if(d===void 0)return;let p=this.config;for(const y of i){const z=p[y];(z===null||typeof z!="object")&&(p[y]={}),p=p[y]}p[d]=r,this.dirty=!0}unset(t){const r=t.split("."),i=r.pop();if(i===void 0||this.config===null)return!1;let d=this.config;for(const p of r){if(d===null||typeof d!="object")return!1;d=d[p]}return d===null||typeof d!="object"?!1:(delete d[i],this.dirty=!0,!0)}async save(){if(this.config===null)return!1;this.faults=[];const t=this.config;let r;try{r=await vn(t)}catch(i){if(fa(i))throw i;return this.admin.report(i),this.faults=Dn(this.admin),!1}return this.config=r.config,this.fingerprint=r.config_fingerprint,this.retired=r.retired_keys??[],this.pending=r.pending_confirmation,this.dirty=!1,!0}async confirm(){try{await hn()}catch(t){if(fa(t))throw t;this.admin.report(t);return}this.admin.notice="La configuration est confirmée.",this.pending=null,await this.admin.refresh()}dropRetired(t){if(t.includes("[")){this.admin.actionError=`« ${t} » est logée dans un tableau : cet écran ne sait pas la retirer de là. Modifiez le fichier de configuration lui-même.`;return}this.unset(t)&&(this.retired=this.retired.filter(r=>r!==t))}}function Dn(a){return a.lastFaults}const Fn={"station.number":"Numéro du poste","station.name":"Nom du poste","station.coop":"Nom de la coopérative","network.listen":"Adresse d’écoute","network.admin_on_lan":"Administration accessible depuis le réseau","ui.language":"Langue","ui.sound":"Son","ui.idle_timeout_s":"Retour à l’accueil après (secondes)","ui.reprint_window_s":"Réimpression possible pendant (secondes)","ui.show_grid_prices":"Afficher les prix sur les tuiles","ui.show_by_unit_products":"Afficher les produits vendus à l’unité","ui.grid_columns":"Colonnes de la grille","ui.min_products_for_chip":"Tuiles minimum pour donner sa puce à une catégorie","scale.type":"Protocole de la balance","scale.present":"Ce poste a une balance","scale.manual_entry_allowed":"Saisie manuelle autorisée","scale.degrade_after_s":"Passer en mode dégradé après (secondes)","scale.options.port":"Port série","scale.options.baud":"Vitesse (bauds)","scale.options.bits":"Bits de données","scale.options.parity":"Parité","scale.options.stop":"Bits d’arrêt","scale.options.backoff_min_ms":"Attente minimale avant réessai (ms)","scale.options.backoff_max_ms":"Attente maximale avant réessai (ms)","printer.type":"Pilote d’impression","printer.template":"Gabarit d’étiquette","printer.options.transport":"Transport","printer.options.queue":"File d’impression","printer.options.path":"Fichier de périphérique","printer.options.address":"Adresse réseau","printer.options.darkness":"Noircissement","printer.options.speed":"Vitesse d’impression","printer.options.offset_x":"Décalage horizontal (dots)","printer.options.offset_y":"Décalage vertical (dots)","printer.options.invert_bits":"Inverser les points","printer.options.copies":"Exemplaires","printer.options.roll_capacity":"Étiquettes par rouleau","pricing.amount_rounding":"Arrondi du montant","pricing.unit_price_rounding":"Arrondi du prix au kilo","pricing.primary_code":"Tarif principal","pricing.reference_code":"Tarif de référence","barcode.verify_reference_check_digit":"Vérifier la clé de contrôle","limits.empty_max_g":"Plateau considéré vide en dessous de (g)","limits.basket_check_enabled":"Vérifier la présence du panier","limits.basket_min_g":"Poids du panier, borne basse (g)","limits.basket_max_g":"Poids du panier, borne haute (g)","limits.min_weight_g":"Poids minimum accepté","limits.max_weight_g":"Poids maximum accepté","limits.max_tare_g":"Tare maximale","limits.min_units":"Unités minimum","limits.max_units":"Unités maximum","limits.max_amount_cents":"Montant maximum (centimes)","stability.mode":"Exigence de stabilité","stability.min_duration_ms":"Durée de stabilité (ms)","stability.tolerance_g":"Tolérance de stabilité (g)","stability.timeout_ms":"Délai d’attente de stabilité (ms)","stability.on_timeout":"Au bout du délai","stability.min_latch_rate":"Taux d’accroche minimal","stability.latch_rate_window_ms":"Fenêtre de mesure du taux (ms)","stability.expiry_floor_ms":"Péremption, plancher (ms)","stability.expiry_ceiling_ms":"Péremption, plafond (ms)","stability.expiry_factor":"Péremption, facteur","catalog.type":"Où le poste va chercher le catalogue","catalog.options.directory":"Répertoire surveillé","catalog.options.url":"Adresse du serveur","catalog.options.username":"Compte","catalog.options.password":"Mot de passe","catalog.options.separator":"Séparateur du CSV","catalog.options.poll_interval_s":"Vérifier toutes les (secondes)","catalog.options.stable_polls":"Vérifications avant lecture","catalog.options.max_file_size_mb":"Taille maximale du fichier (Mo)","catalog.options.max_image_size_kb":"Taille maximale d’une image (Ko)","catalog.options.min_readable_ratio":"Part minimale de lignes lisibles","catalog.options.max_weighable_drop":"Baisse maximale des produits pesables","catalog.options.max_archives":"Archives conservées","catalog.options.archive_days":"Archives conservées (jours)","catalog.options.failures_before_reject":"Échecs avant mise en quarantaine","catalog.images.source":"Origine des photos","catalog.images.path":"Répertoire des photos","catalog.fallback_category":"Rayon par défaut","journal.max_rows":"Pesées conservées","journal.max_days":"Pesées conservées (jours)","journal.max_technical":"Événements techniques conservés","admin.session_minutes":"Durée d’une session (minutes)","admin.attempts_per_minute":"Tentatives par minute","maintenance.weekly_integrity_check":"Contrôle d’intégrité hebdomadaire","maintenance.disk_alert_mb":"Alerte disque en dessous de (Mo)"};function qt(a){return Fn[a]??a}const Un={station:"l’identité du poste",network:"le réseau",ui:"l’écran client",scale:"la balance",printer:"l’imprimante",pricing:"les tarifs",barcode:"le code-barres",limits:"les garde-fous",stability:"la stabilité",catalog:"le catalogue",journal:"le journal",maintenance:"la maintenance"};function Mn(a){return Un[a]??a}const Wn={scale:"balance",printer:"imprimante",catalog:"catalogue",ui:"écran",config:"configuration",http:"réseau",system:"système"};function mr(a){return Wn[a]??"origine inconnue"}const qa="openscale.admin.preferences",hr="technical";class Bn{#t=B(vt(Vn()));get showTechnicalNames(){return e(this.#t)}set showTechnicalNames(t){v(this.#t,t,!0)}toggleTechnicalNames(){this.showTechnicalNames=!this.showTechnicalNames,Gn(this.showTechnicalNames)}}function Vn(){try{return globalThis.localStorage?.getItem(qa)===hr}catch{return!1}}function Gn(a){try{a?globalThis.localStorage?.setItem(qa,hr):globalThis.localStorage?.removeItem(qa)}catch{}}const St=new Bn,Hn=3e3,Jn=["hardware","label","rules","catalog","journal","station","update"];function Wa(a){return Jn.includes(a)}function Kn(a){return a instanceof Pt&&a.needsCredentials}class $n{constructor(t=Hn){this.periodMs=t}periodMs;#t=B(null);get health(){return e(this.#t)}set health(t){v(this.#t,t,!0)}#r=B("dashboard");get page(){return e(this.#r)}set page(t){v(this.#r,t,!0)}#a=B(!1);get expert(){return e(this.#a)}set expert(t){v(this.#a,t,!0)}#e=B("");get linkError(){return e(this.#e)}set linkError(t){v(this.#e,t,!0)}#n=B("");get actionError(){return e(this.#n)}set actionError(t){v(this.#n,t,!0)}#l=B(!1);get needsFirstPassword(){return e(this.#l)}set needsFirstPassword(t){v(this.#l,t,!0)}#d=B("");get notice(){return e(this.#d)}set notice(t){v(this.#d,t,!0)}#v=B(!1);get busy(){return e(this.#v)}set busy(t){v(this.#v,t,!0)}#p=B(vt([]));get lastFaults(){return e(this.#p)}set lastFaults(t){v(this.#p,t,!0)}#f=B(null);get pending(){return e(this.#f)}set pending(t){v(this.#f,t,!0)}#i=null;#o=null;start(){this.refresh(),this.#i=setInterval(()=>{this.refresh()},this.periodMs)}stop(){this.#i!==null&&clearInterval(this.#i),this.#i=null}async refresh(){try{this.health=await Qr(),this.linkError=""}catch(t){this.linkError=Ba(t)}}#u(){this.busy=!0,this.notice="",this.actionError="",this.needsFirstPassword=!1}#s(t){this.actionError=Ba(t),this.needsFirstPassword=t instanceof Pt&&t.needsFirstPassword,this.#m(t)}async run(t){this.#u();let r=null;try{r=await t(),this.notice=r.message}catch(i){this.#s(i)}finally{this.busy=!1}return await this.refresh(),r}async login(t){this.#u();try{return await un(t),this.expert=!0,this.notice="Session d’administration ouverte.",!0}catch(r){return this.expert=!1,this.#s(r),!1}finally{this.busy=!1}}async recover(t,r){this.#u();try{const i=await dn(t,r);return this.expert=!0,this.notice=i.warning??"Le mot de passe est remplacé et la session est ouverte.",!0}catch(i){return this.#s(i),!1}finally{this.busy=!1}}async protect(t){try{return await t()}catch(r){if(!Kn(r))return this.#s(r),null;if(!await this.#g(r))return null;try{return await t()}catch(i){return this.#s(i),null}}}#g(t){return this.pending={kind:t.needsFirstPassword?"first-password":"password",message:t.message},new Promise(r=>{this.#o=r})}async answerPassword(t){await this.login(t)&&this.#c(!0)}async answerRecovery(t,r){await this.recover(t,r)&&this.#c(!0)}cancelPassword(){this.#c(!1)}#c(t){this.pending=null,this.notice="";const r=this.#o;this.#o=null,r?.(t)}async logout(){await cn(),this.expert=!1,this.page="dashboard",this.notice="Session d’administration fermée."}open(t){this.actionError="",this.notice="",this.needsFirstPassword=!1,this.page=t}async load(t){try{const r=await t();return this.actionError="",this.lastFaults=[],r}catch(r){return this.lastFaults=r instanceof Pt?r.faults:[],this.#s(r),null}}report(t){this.lastFaults=t instanceof Pt?t.faults:[],this.#s(t)}#m(t){t instanceof Pt&&t.needsPassword&&(this.expert=!1)}}function Ba(a){return a instanceof Pt?a.message:a instanceof Error?"Le poste n’a pas répondu : "+a.message:"Le poste n’a pas répondu."}var Yn=c('clé'),Xn=c('');function Te(a,t){const r=Be(t,"kind",3,"read"),i=Be(t,"busy",3,!1),d=Be(t,"disabled",3,!1),p=Be(t,"protected",3,!1),y=Be(t,"act",3,void 0);var z=Xn();let m;var j=s(z),S=n(j);{var A=L=>{var W=Yn();l(L,W)};_(S,L=>{p()&&L(A)})}f(()=>{m=Nt(z,1,`act ${r()??""}`,"svelte-5tpq0o",m,{"touch-target":r()==="destructive",busy:i()}),be(z,"data-kind",r()),be(z,"data-act",y()),z.disabled=d()||i(),o(j,`${(i()?"En cours…":t.label)??""} `)}),Ce("click",z,function(...L){t.onrun?.apply(this,L)}),l(a,z)}ot(["click"]);var Qn=c(`
Le code de secours a été tiré à l’installation de ce poste et imprimé
+import{Y as Tr,Z as zr,_ as jr,$ as Ea,a0 as Vt,e as Rr,a1 as or,a2 as Or,a3 as Ar,a4 as Nr,u as ma,a5 as Ca,a6 as Ir,a7 as ur,x as wt,A as B,h as e,z as v,H as vt,d as ot,a as Be,s as n,i as _,t as f,l as Nt,j as be,m as o,b as Ce,c as l,o as s,g as c,p as Ue,I as Dr,f as Me,n as u,q as ae,a8 as Ia,r as ze,G as Gt,a9 as ea,aa as Tt,B as da,ab as lt,ac as Xt,ad as ka,C as Fr,J as cr,y as sa,T as Ur,ae as Ht,F as Mr,E as Wr,D as Br,O as Vr,K as Gr,X as Hr,af as Jr}from"./app-BaRSXv80.js";function dr(a){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function Kr(a,t,...r){var i=new jr(a);Tr(()=>{const d=t()??null;i.ensure(d,d&&(p=>d(p,...r)))},zr)}function Pa(a,t,r=!1){if(a.multiple){if(t==null)return;if(!Or(t))return Ar();for(var i of a.options)i.selected=t.includes(la(i));return}for(i of a.options){var d=la(i);if(Nr(d,t)){i.selected=!0;return}}(!r||t!==void 0)&&(a.selectedIndex=-1)}function vr(a){var t=new MutationObserver(()=>{"__value"in a&&Pa(a,a.__value)});t.observe(a,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),or(()=>{t.disconnect()})}function $r(a,t,r=t){var i=new WeakSet,d=!0;Ea(a,"change",p=>{var y=p?"[selected]":":checked",z;if(a.multiple)z=[].map.call(a.querySelectorAll(y),la);else{var m=a.querySelector(y)??a.querySelector("option:not([disabled])");z=m&&la(m)}r(z),a.__value=z,Vt!==null&&i.add(Vt)}),Rr(()=>{var p=t();if(a===document.activeElement){var y=Vt;if(i.has(y))return}if(Pa(a,p,d),d&&p===void 0){var z=a.querySelector(":checked");z!==null&&(p=la(z),r(p))}a.__value=p,d=!1}),vr(a)}function la(a){return"__value"in a?a.__value:a.value}function ia(a,t,r=t){var i=new WeakSet;Ea(a,"input",async d=>{var p=d?a.defaultValue:a.value;if(p=ba(a)?wa(p):p,r(p),Vt!==null&&i.add(Vt),await Ir(),p!==(p=t())){var y=a.selectionStart,z=a.selectionEnd,m=a.value.length;if(a.value=p??"",z!==null){var j=a.value.length;y===z&&z===m&&j>m?(a.selectionStart=j,a.selectionEnd=j):(a.selectionStart=y,a.selectionEnd=Math.min(z,j))}}}),ma(t)==null&&a.value&&(r(ba(a)?wa(a.value):a.value),Vt!==null&&i.add(Vt)),Ca(()=>{var d=t();if(a===document.activeElement){var p=Vt;if(i.has(p))return}ba(a)&&d===wa(a.value)||a.type==="date"&&!d&&!a.value||d!==a.value&&(a.value=d??"")})}function Da(a,t,r=t){Ea(a,"change",i=>{var d=i?a.defaultChecked:a.checked;r(d)}),ma(t)==null&&r(a.checked),Ca(()=>{var i=t();a.checked=!!i})}function ba(a){var t=a.type;return t==="number"||t==="range"}function wa(a){return a===""?null:+a}function Fa(a,t,r,i,d){var p=()=>{i(r[a])};r.addEventListener(t,p),d?Ca(()=>{r[a]=d()}):p(),(r===document.body||r===window||r===document)&&or(()=>{r.removeEventListener(t,p)})}function Ta(a){ur===null&&dr(),wt(()=>{const t=ma(a);if(typeof t=="function")return t})}function Yr(a){ur===null&&dr(),Ta(()=>()=>ma(a))}const Xr="ERR-CFG-02";class Pt extends Error{constructor(t,r,i="",d=[]){super(r),this.status=t,this.code=i,this.faults=d,this.name="AdminError"}status;code;faults;get needsPassword(){return this.status===401}get needsFirstPassword(){return this.status===409&&this.code===Xr}get needsCredentials(){return this.needsPassword||this.needsFirstPassword}}function fa(a){return a instanceof Pt&&a.needsCredentials}function Qr(){return It("/admin/api/health")}function Zr(){return He("/admin/api/troubleshooting/reprint",{})}function en(){return He("/admin/api/troubleshooting/reload-catalog",{})}function tn(a){return He("/admin/api/troubleshooting/manual-entry",{on:a})}function an(){return He("/admin/api/troubleshooting/roll-changed",{})}function rn(a){return He("/admin/api/troubleshooting/fallback-printer",{on:a})}function nn(){return He("/admin/api/troubleshooting/test-scale",{})}function sn(){return He("/admin/api/troubleshooting/test-printer",{})}function ln(){return He("/admin/api/troubleshooting/test-label",{})}async function pr(a){const t=new FormData;t.append("file",a,a.name);const r=await fetch("/admin/api/catalog/import",{method:"POST",body:t});return Ra(r,"POST /admin/api/catalog/import")}const on="/admin/api/diagnostic.zip";function un(a){return He("/admin/api/session",{password:a})}async function cn(){await fetch("/admin/api/session",{method:"DELETE"})}function dn(a,t){return He("/admin/api/session/recovery",{code:a,password:t})}function za(){return It("/admin/api/config")}function vn(a){return ja("PUT","/admin/api/config",a)}function pn(){return He("/admin/api/config/reload",{})}function fn(){return He("/admin/api/restart",{})}function gn(){return He("/admin/api/reboot",{})}function mn(){return ja("DELETE","/admin/api/reboot",{})}function hn(){return He("/admin/api/config/confirm",{})}async function _n(){return(await It("/admin/api/config/versions")).versions}function bn(a){return He("/admin/api/config/restore",{version:a})}async function wn(){return(await It("/admin/api/ports")).ports}async function yn(){return(await It("/admin/api/printers")).printers}async function xn(){return(await He("/admin/api/printers/discover",{})).printers}function kn(a){return He("/admin/api/scale/detect",{port:a})}async function Ua(a,t){return(await He("/admin/api/scale/capture",{port:a,seconds:t})).frames}function fr(a){return He("/admin/api/printer/test?what="+a,{})}function qn(a,t,r,i){const d=new URLSearchParams({template:a,demo:t?"1":"0",dual:r?"1":"0"});return d.set("t",String(i)),"/admin/api/label/preview.png?"+d.toString()}async function Sn(a){const t=new URLSearchParams(a);return(await It("/admin/api/journal?"+t)).weighings}function Ln(a){return"/admin/api/journal/export.csv?"+new URLSearchParams(a).toString()}async function En(a){const t=new URLSearchParams(a);return(await It("/admin/api/technical?"+t)).entries}function Cn(a){const t=a===void 0?"":"?id="+String(a);return It("/admin/api/imports"+t)}function Pn(){return He("/admin/api/catalog/reload",{})}function Tn(){return He("/admin/api/catalog/forget-quarantine",{})}function Ma(a,t){return He("/admin/api/products/"+encodeURIComponent(a)+"/decision",t)}function zn(a){return He("/admin/api/replay",{frame:a})}async function It(a){const t=await fetch(a,{headers:{accept:"application/json"}});return Ra(t,"GET "+a)}function He(a,t){return ja("POST",a,t)}async function ja(a,t,r){const i=await fetch(t,{method:a,headers:{"content-type":"application/json"},body:JSON.stringify(r)});return Ra(i,a+" "+t)}async function Ra(a,t){const r=await a.text();if(!a.ok){const i=gr(r);throw new Pt(a.status,Rn(r,t,a.status)+jn(a),i?.code??"",i?.faults??[])}if(r!=="")return JSON.parse(r)}function jn(a){if(a.status!==429)return"";const t=Number(a.headers.get("Retry-After")??"");if(!Number.isFinite(t)||t<=0)return"";const r=Math.ceil(t/60);return r>1?` Réessayez dans ${String(r)} minutes.`:" Réessayez dans une minute."}function Rn(a,t,r){const i=gr(a);return i?.message!==void 0&&i.message!==""?i.message:`${t} a répondu ${String(r)}.`}function gr(a){try{return JSON.parse(a)}catch{return null}}function On(){return It("/admin/api/update")}function An(){return He("/admin/api/update/check",{})}function Nn(a){return He("/admin/api/update/apply",{version:a})}class In{constructor(t){this.admin=t}admin;#t=B(null);get config(){return e(this.#t)}set config(t){v(this.#t,t,!0)}#r=B("");get fingerprint(){return e(this.#r)}set fingerprint(t){v(this.#r,t,!0)}#a=B(vt([]));get retired(){return e(this.#a)}set retired(t){v(this.#a,t,!0)}#e=B(null);get pending(){return e(this.#e)}set pending(t){v(this.#e,t,!0)}#n=B(vt([]));get faults(){return e(this.#n)}set faults(t){v(this.#n,t,!0)}#l=B(!1);get dirty(){return e(this.#l)}set dirty(t){v(this.#l,t,!0)}async load(){const t=await this.admin.load(()=>za());t!==null&&(this.config=t.config,this.fingerprint=t.config_fingerprint,this.retired=t.retired_keys??[],this.pending=t.pending_confirmation,this.faults=[],this.dirty=!1)}value(t){let r=this.config;for(const i of t.split(".")){if(r===null||typeof r!="object")return;r=r[i]}return r}text(t){const r=this.value(t);return r==null?"":String(r)}number(t){const r=this.value(t);return typeof r=="number"?r:Number(r??0)}flag(t){return this.value(t)===!0}set(t,r){if(this.config===null)return;const i=t.split("."),d=i.pop();if(d===void 0)return;let p=this.config;for(const y of i){const z=p[y];(z===null||typeof z!="object")&&(p[y]={}),p=p[y]}p[d]=r,this.dirty=!0}unset(t){const r=t.split("."),i=r.pop();if(i===void 0||this.config===null)return!1;let d=this.config;for(const p of r){if(d===null||typeof d!="object")return!1;d=d[p]}return d===null||typeof d!="object"?!1:(delete d[i],this.dirty=!0,!0)}async save(){if(this.config===null)return!1;this.faults=[];const t=this.config;let r;try{r=await vn(t)}catch(i){if(fa(i))throw i;return this.admin.report(i),this.faults=Dn(this.admin),!1}return this.config=r.config,this.fingerprint=r.config_fingerprint,this.retired=r.retired_keys??[],this.pending=r.pending_confirmation,this.dirty=!1,!0}async confirm(){try{await hn()}catch(t){if(fa(t))throw t;this.admin.report(t);return}this.admin.notice="La configuration est confirmée.",this.pending=null,await this.admin.refresh()}dropRetired(t){if(t.includes("[")){this.admin.actionError=`« ${t} » est logée dans un tableau : cet écran ne sait pas la retirer de là. Modifiez le fichier de configuration lui-même.`;return}this.unset(t)&&(this.retired=this.retired.filter(r=>r!==t))}}function Dn(a){return a.lastFaults}const Fn={"station.number":"Numéro du poste","station.name":"Nom du poste","station.coop":"Nom de la coopérative","network.listen":"Adresse d’écoute","network.admin_on_lan":"Administration accessible depuis le réseau","ui.language":"Langue","ui.sound":"Son","ui.idle_timeout_s":"Retour à l’accueil après (secondes)","ui.reprint_window_s":"Réimpression possible pendant (secondes)","ui.show_grid_prices":"Afficher les prix sur les tuiles","ui.show_by_unit_products":"Afficher les produits vendus à l’unité","ui.grid_columns":"Colonnes de la grille","ui.min_products_for_chip":"Articles minimum pour afficher une catégorie","scale.type":"Protocole de la balance","scale.present":"Ce poste a une balance","scale.manual_entry_allowed":"Saisie manuelle autorisée","scale.degrade_after_s":"Passer en mode dégradé après (secondes)","scale.options.port":"Port série","scale.options.baud":"Vitesse (bauds)","scale.options.bits":"Bits de données","scale.options.parity":"Parité","scale.options.stop":"Bits d’arrêt","scale.options.backoff_min_ms":"Attente minimale avant réessai (ms)","scale.options.backoff_max_ms":"Attente maximale avant réessai (ms)","printer.type":"Pilote d’impression","printer.template":"Gabarit d’étiquette","printer.options.transport":"Transport","printer.options.queue":"File d’impression","printer.options.path":"Fichier de périphérique","printer.options.address":"Adresse réseau","printer.options.darkness":"Noircissement","printer.options.speed":"Vitesse d’impression","printer.options.offset_x":"Décalage horizontal (dots)","printer.options.offset_y":"Décalage vertical (dots)","printer.options.invert_bits":"Inverser les points","printer.options.copies":"Exemplaires","printer.options.roll_capacity":"Étiquettes par rouleau","pricing.amount_rounding":"Arrondi du montant","pricing.unit_price_rounding":"Arrondi du prix au kilo","pricing.primary_code":"Tarif principal","pricing.reference_code":"Tarif de référence","barcode.verify_reference_check_digit":"Vérifier la clé de contrôle","limits.empty_max_g":"Plateau considéré vide en dessous de (g)","limits.basket_check_enabled":"Vérifier la présence du panier","limits.basket_min_g":"Poids du panier, borne basse (g)","limits.basket_max_g":"Poids du panier, borne haute (g)","limits.min_weight_g":"Poids minimum accepté","limits.max_weight_g":"Poids maximum accepté","limits.max_tare_g":"Tare maximale","limits.min_units":"Unités minimum","limits.max_units":"Unités maximum","limits.max_amount_cents":"Montant maximum (centimes)","stability.mode":"Exigence de stabilité","stability.min_duration_ms":"Durée de stabilité (ms)","stability.tolerance_g":"Tolérance de stabilité (g)","stability.timeout_ms":"Délai d’attente de stabilité (ms)","stability.on_timeout":"Au bout du délai","stability.min_latch_rate":"Taux d’accroche minimal","stability.latch_rate_window_ms":"Fenêtre de mesure du taux (ms)","stability.expiry_floor_ms":"Péremption, plancher (ms)","stability.expiry_ceiling_ms":"Péremption, plafond (ms)","stability.expiry_factor":"Péremption, facteur","catalog.type":"Où le poste va chercher le catalogue","catalog.options.directory":"Répertoire surveillé","catalog.options.url":"Adresse du serveur","catalog.options.username":"Compte","catalog.options.password":"Mot de passe","catalog.options.separator":"Séparateur du CSV","catalog.options.poll_interval_s":"Vérifier toutes les (secondes)","catalog.options.stable_polls":"Vérifications avant lecture","catalog.options.max_file_size_mb":"Taille maximale du fichier (Mo)","catalog.options.max_image_size_kb":"Taille maximale d’une image (Ko)","catalog.options.min_readable_ratio":"Part minimale de lignes lisibles","catalog.options.max_weighable_drop":"Baisse maximale des produits pesables","catalog.options.max_archives":"Archives conservées","catalog.options.archive_days":"Archives conservées (jours)","catalog.options.failures_before_reject":"Échecs avant mise en quarantaine","catalog.images.source":"Origine des photos","catalog.images.path":"Répertoire des photos","catalog.fallback_category":"Rayon par défaut","journal.max_rows":"Pesées conservées","journal.max_days":"Pesées conservées (jours)","journal.max_technical":"Événements techniques conservés","admin.session_minutes":"Durée d’une session (minutes)","admin.attempts_per_minute":"Tentatives par minute","maintenance.weekly_integrity_check":"Contrôle d’intégrité hebdomadaire","maintenance.disk_alert_mb":"Alerte disque en dessous de (Mo)"};function qt(a){return Fn[a]??a}const Un={station:"l’identité du poste",network:"le réseau",ui:"l’écran client",scale:"la balance",printer:"l’imprimante",pricing:"les tarifs",barcode:"le code-barres",limits:"les garde-fous",stability:"la stabilité",catalog:"le catalogue",journal:"le journal",maintenance:"la maintenance"};function Mn(a){return Un[a]??a}const Wn={scale:"balance",printer:"imprimante",catalog:"catalogue",ui:"écran",config:"configuration",http:"réseau",system:"système"};function mr(a){return Wn[a]??"origine inconnue"}const qa="openscale.admin.preferences",hr="technical";class Bn{#t=B(vt(Vn()));get showTechnicalNames(){return e(this.#t)}set showTechnicalNames(t){v(this.#t,t,!0)}toggleTechnicalNames(){this.showTechnicalNames=!this.showTechnicalNames,Gn(this.showTechnicalNames)}}function Vn(){try{return globalThis.localStorage?.getItem(qa)===hr}catch{return!1}}function Gn(a){try{a?globalThis.localStorage?.setItem(qa,hr):globalThis.localStorage?.removeItem(qa)}catch{}}const St=new Bn,Hn=3e3,Jn=["hardware","label","rules","catalog","journal","station","update"];function Wa(a){return Jn.includes(a)}function Kn(a){return a instanceof Pt&&a.needsCredentials}class $n{constructor(t=Hn){this.periodMs=t}periodMs;#t=B(null);get health(){return e(this.#t)}set health(t){v(this.#t,t,!0)}#r=B("dashboard");get page(){return e(this.#r)}set page(t){v(this.#r,t,!0)}#a=B(!1);get expert(){return e(this.#a)}set expert(t){v(this.#a,t,!0)}#e=B("");get linkError(){return e(this.#e)}set linkError(t){v(this.#e,t,!0)}#n=B("");get actionError(){return e(this.#n)}set actionError(t){v(this.#n,t,!0)}#l=B(!1);get needsFirstPassword(){return e(this.#l)}set needsFirstPassword(t){v(this.#l,t,!0)}#d=B("");get notice(){return e(this.#d)}set notice(t){v(this.#d,t,!0)}#v=B(!1);get busy(){return e(this.#v)}set busy(t){v(this.#v,t,!0)}#p=B(vt([]));get lastFaults(){return e(this.#p)}set lastFaults(t){v(this.#p,t,!0)}#f=B(null);get pending(){return e(this.#f)}set pending(t){v(this.#f,t,!0)}#i=null;#o=null;start(){this.refresh(),this.#i=setInterval(()=>{this.refresh()},this.periodMs)}stop(){this.#i!==null&&clearInterval(this.#i),this.#i=null}async refresh(){try{this.health=await Qr(),this.linkError=""}catch(t){this.linkError=Ba(t)}}#u(){this.busy=!0,this.notice="",this.actionError="",this.needsFirstPassword=!1}#s(t){this.actionError=Ba(t),this.needsFirstPassword=t instanceof Pt&&t.needsFirstPassword,this.#m(t)}async run(t){this.#u();let r=null;try{r=await t(),this.notice=r.message}catch(i){this.#s(i)}finally{this.busy=!1}return await this.refresh(),r}async login(t){this.#u();try{return await un(t),this.expert=!0,this.notice="Session d’administration ouverte.",!0}catch(r){return this.expert=!1,this.#s(r),!1}finally{this.busy=!1}}async recover(t,r){this.#u();try{const i=await dn(t,r);return this.expert=!0,this.notice=i.warning??"Le mot de passe est remplacé et la session est ouverte.",!0}catch(i){return this.#s(i),!1}finally{this.busy=!1}}async protect(t){try{return await t()}catch(r){if(!Kn(r))return this.#s(r),null;if(!await this.#g(r))return null;try{return await t()}catch(i){return this.#s(i),null}}}#g(t){return this.pending={kind:t.needsFirstPassword?"first-password":"password",message:t.message},new Promise(r=>{this.#o=r})}async answerPassword(t){await this.login(t)&&this.#c(!0)}async answerRecovery(t,r){await this.recover(t,r)&&this.#c(!0)}cancelPassword(){this.#c(!1)}#c(t){this.pending=null,this.notice="";const r=this.#o;this.#o=null,r?.(t)}async logout(){await cn(),this.expert=!1,this.page="dashboard",this.notice="Session d’administration fermée."}open(t){this.actionError="",this.notice="",this.needsFirstPassword=!1,this.page=t}async load(t){try{const r=await t();return this.actionError="",this.lastFaults=[],r}catch(r){return this.lastFaults=r instanceof Pt?r.faults:[],this.#s(r),null}}report(t){this.lastFaults=t instanceof Pt?t.faults:[],this.#s(t)}#m(t){t instanceof Pt&&t.needsPassword&&(this.expert=!1)}}function Ba(a){return a instanceof Pt?a.message:a instanceof Error?"Le poste n’a pas répondu : "+a.message:"Le poste n’a pas répondu."}var Yn=c('clé'),Xn=c('');function Te(a,t){const r=Be(t,"kind",3,"read"),i=Be(t,"busy",3,!1),d=Be(t,"disabled",3,!1),p=Be(t,"protected",3,!1),y=Be(t,"act",3,void 0);var z=Xn();let m;var j=s(z),S=n(j);{var A=L=>{var W=Yn();l(L,W)};_(S,L=>{p()&&L(A)})}f(()=>{m=Nt(z,1,`act ${r()??""}`,"svelte-5tpq0o",m,{"touch-target":r()==="destructive",busy:i()}),be(z,"data-kind",r()),be(z,"data-act",y()),z.disabled=d()||i(),o(j,`${(i()?"En cours…":t.label)??""} `)}),Ce("click",z,function(...L){t.onrun?.apply(this,L)}),l(a,z)}ot(["click"]);var Qn=c(`
Le code de secours a été tiré à l’installation de ce poste et imprimé
sur sa fiche, rangée dans le classeur du magasin. Il n’existe nulle part ailleurs.
`,1),Zn=c(`
Oublié ? Le code de secours de la fiche d’installation en repose un.
Un responsable peut aussi le faire en ligne de commande, avec openscale config password.
`,1),es=c('
'),ts=c('
');function as(a,t){Ue(t,!0);const r=u(()=>t.admin.pending?.kind==="first-password");let i=B(""),d=B("");const p=8,y=u(()=>e(r)?e(d).trim().length>0&&e(i).length>=p:e(i).length>0);async function z(){!e(y)||t.admin.busy||(e(r)?await t.admin.answerRecovery(e(d),e(i)):await t.admin.answerPassword(e(i)),v(i,""),v(d,""))}var m=ts(),j=s(m),S=s(j),A=s(S),L=s(A);Dr(L,{name:"settings",size:"1.5rem"});var W=n(A,2),O=s(W),C=n(S,2),K=s(C),U=n(C,2);{var E=T=>{var w=Qn(),k=n(ae(w),2),R=n(s(k),2);Ia(R);var F=n(k,2),h=s(F);h.textContent="Nouveau mot de passe — 8 caractères au moins";var G=n(h,2);Ce("keydown",R,Y=>Y.key==="Enter"&&void z()),ia(R,()=>e(d),Y=>v(d,Y)),Ce("keydown",G,Y=>Y.key==="Enter"&&void z()),ia(G,()=>e(i),Y=>v(i,Y)),l(T,w)},x=T=>{var w=Zn(),k=ae(w),R=n(s(k),2);Ia(R),Ce("keydown",R,F=>F.key==="Enter"&&void z()),ia(R,()=>e(i),F=>v(i,F)),l(T,w)};_(U,T=>{e(r)?T(E):T(x,-1)})}var g=n(U,2);{var D=T=>{var w=es(),k=s(w);f(()=>o(k,t.admin.actionError)),l(T,w)};_(g,T=>{t.admin.actionError!==""&&T(D)})}var H=n(g,2),V=s(H);Te(V,{label:"Annuler",onrun:()=>t.admin.cancelPassword()});var $=n(V,2);{let T=u(()=>e(r)?"Poser ce mot de passe":"Continuer"),w=u(()=>!e(y)||t.admin.busy);Te($,{kind:"write",get label(){return e(T)},get disabled(){return e(w)},onrun:()=>{z()}})}f(()=>{o(O,e(r)?"Ce poste n’a pas encore de mot de passe":"Mot de passe d’administration"),o(K,t.admin.pending?.message??"")}),l(a,m),Me()}ot(["keydown"]);var rs=c(''),ns=c(""),ss=c(''),ls=c(''),is=c(""),os=c(""),us=c('
Le poste y cherche le fichier , et le supprime
une fois lu : c’est ce qui dit au producteur que la livraison est prise.
`,1),hs=c(`
Sur un serveur WebDAV, le dépôt d’un fichier CSV depuis cet écran n’est plus
@@ -7,7 +7,7 @@ import{Y as Tr,Z as zr,_ as jr,$ as Ea,a0 as Vt,e as Rr,a1 as or,a2 as Or,a3 as
chercher aucun catalogue.
`),bs=c('
',1);function ws(a,t){Ue(t,!0);const r={local_drop:["catalog.options.directory"],webdav:["catalog.options.url","catalog.options.username","catalog.options.password"]},i=u(()=>t.draft.text("catalog.type"));function d(p){t.draft.set("catalog.type",p);for(const[y,z]of Object.entries(r))if(y!==p)for(const m of z)t.draft.unset(m)}Oe(a,{title:"Où le poste va chercher le catalogue",children:(p,y)=>{var z=bs(),m=ae(z),j=s(m),S=s(j),A=n(j,2),L=s(A),W=n(m,2);{var O=E=>{var x=gs();l(E,x)},C=E=>{var x=ms(),g=ae(x);{let $=u(()=>qt("catalog.options.directory")),T=u(()=>t.draft.text("catalog.options.directory")),w=u(()=>$e(t.draft,"catalog.options.directory"));at(g,{get label(){return e($)},path:"catalog.options.directory",get value(){return e(T)},hint:"Laissez vide pour le répertoire du poste, celui que le service crée lui-même. Un répertoire nommé ici doit exister : le poste ne le crée pas.",get fault(){return e(w)},onchange:k=>t.draft.set("catalog.options.directory",k)})}var D=n(g,2),H=n(s(D)),V=s(H);f(()=>o(V,`flv_${t.station??""}.csv`)),l(E,x)},K=E=>{var x=hs(),g=ae(x);{let V=u(()=>qt("catalog.options.url")),$=u(()=>t.draft.text("catalog.options.url")),T=u(()=>$e(t.draft,"catalog.options.url"));at(g,{get label(){return e(V)},path:"catalog.options.url",get value(){return e($)},get fault(){return e(T)},onchange:w=>t.draft.set("catalog.options.url",w)})}var D=n(g,2);{let V=u(()=>qt("catalog.options.username")),$=u(()=>t.draft.text("catalog.options.username")),T=u(()=>$e(t.draft,"catalog.options.username"));at(D,{get label(){return e(V)},path:"catalog.options.username",get value(){return e($)},get fault(){return e(T)},onchange:w=>t.draft.set("catalog.options.username",w)})}var H=n(D,2);{let V=u(()=>qt("catalog.options.password")),$=u(()=>$e(t.draft,"catalog.options.password"));at(H,{get label(){return e(V)},path:"catalog.options.password",kind:"password",value:"",hint:"Laissez vide : le mot de passe actuel est conservé.",get fault(){return e($)},onchange:T=>t.draft.set("catalog.options.password",T)})}l(E,x)},U=E=>{var x=_s();l(E,x)};_(W,E=>{t.draft.config===null?E(O):e(i)==="local_drop"?E(C,1):e(i)==="webdav"?E(K,2):E(U,-1)})}f(()=>{ea(S,e(i)==="local_drop"),ea(L,e(i)==="webdav")}),Ce("change",S,()=>d("local_drop")),Ce("change",L,()=>d("webdav")),l(p,z)},$$slots:{default:!0}}),Me()}ot(["change"]);const Va=1e3;function va(a){const t=Oa(a);return t===null?"":[Zt(t.getDate()),Zt(t.getMonth()+1),String(t.getFullYear())].join("/")}function Lt(a){const t=Oa(a);return t===null?"":`${va(a)} à ${Zt(t.getHours())}:${Zt(t.getMinutes())}`}function ys(a){const t=Oa(a);return t===null?"":[Zt(t.getHours()),Zt(t.getMinutes()),Zt(t.getSeconds())].join(":")}function Sa(a){const t=a/1e6;return t<1e3?`${Math.round(t)} Mo`:`${_r(t/1e3)} Go`}function se(a){const t=String(Math.abs(Math.trunc(a))),r=[];for(let i=t.length;i>0;i-=3)r.unshift(t.slice(Math.max(0,i-3),i));return(a<0?"-":"")+r.join(" ")}function ua(a){return a0}function qs(a){const t=a.motive!=="";return{canWithdraw:t||!pa(!1,a.waiverInForce),canOfferAgain:t||!pa(!0,a.waiverInForce),canSaveWaiver:ks(a.typedWaiver)&&(t||!pa(a.offeredInForce,a.typedWaiver)),canDropWaiver:t||!pa(a.offeredInForce,null)}}function br(a){const t=[];return a.offered||t.push("retiré de la grille"),a.min_weight_g!==null&&t.push(`peut peser à partir de ${se(a.min_weight_g)} g`),t.length===0?"aucune restriction":t.join(" · ")}function ca(a,t,r,i){const d=t>1?i:r;return a>=t?`${se(t)} ${d}.`:`${se(a)} lignes affichées sur ${se(t)} ${d}.`}function Ss(a,t){return t>a?`${se(a)} produits affichés sur ${se(t)} trouvés — précisez votre recherche.`:`${se(t)} ${t>1?"produits trouvés":"produit trouvé"}.`}function Ls(a){return`${se(a)} ${a>1?"imports affichés":"import affiché"} : le poste n’en publie jamais plus de vingt.`}function ya(a,t,r,i){const d=`${se(r)} ${r>1?t:a}`;return r<=i?d+".":`${d} — seules les ${se(i)} premières lignes sont affichées.`}function Es(a,t){const r=`${se(a)} ${a>1?"produits retirés":"produit retiré"}`;return t===""?r+".":`${r} depuis l’import du ${Lt(t)}.`}var Cs=c('
Aucune décision locale : la grille est celle du fichier.
'),Ps=c('
'),Ts=c('
',1);function zs(a,t){Ue(t,!0);const r=20,i=u(()=>t.decisions.slice(0,r));Oe(a,{title:"Décisions en vigueur",note:"Ce qu’un humain a décidé, produit par produit. C’est ici que se reprend un produit retiré de la grille.",children:(d,p)=>{var y=Tt(),z=ae(y);{var m=S=>{var A=Cs();l(S,A)},j=S=>{var A=Ts(),L=ae(A),W=s(L),O=n(L,2),C=s(O);ze(C,21,()=>e(i),K=>K.product_id,(K,U)=>{var E=Ps(),x=s(E),g=n(x,2),D=s(g),H=n(g,2),V=s(H),$=n(H,2),T=s($),w=n($,2),k=s(w),R=n(w,2),F=s(R);f((h,G,Y)=>{o(D,h),o(V,e(U).product_id),o(T,G),o(k,e(U).reason),o(F,Y)},[()=>t.nameOf(e(U).product_id),()=>br(e(U)),()=>va(e(U).decided_at)]),Ce("click",x,()=>t.onchoose(e(U).product_id)),l(K,E)}),f(K=>o(W,K),[()=>ca(e(i).length,t.decisions.length,"décision en vigueur","décisions en vigueur")]),l(S,A)};_(z,S=>{t.decisions.length===0?S(m):S(j,-1)})}l(d,y)},$$slots:{default:!0}}),Me()}ot(["click"]);function js(a){return a==="loading"?"Lecture des signalements du dernier import…":"Les signalements du dernier import n’ont pas pu être lus : cet écran ne sait pas ce qu’ils disent."}function Rs(a){return a==="loading"?"Lecture de l’historique des imports…":"L’historique des imports n’a pas pu être lu : cet écran ne sait pas ce qu’il contient."}function Aa(a,t,r){return a!==void 0?a:t==="loading"?"Lecture du nom…":t==="unread"?r:"Produit absent du catalogue en service"}var Ga=c('
'),Os=c(''),As=c('
'),Ns=c('
',1);function xa(a,t){Ue(t,!0);const r=Be(t,"remedy",3,""),i=50,d=u(()=>t.findings.slice(0,i)),p=u(()=>t.findings.length>e(d).length);Oe(a,{get title(){return t.title},get note(){return t.note},children:(y,z)=>{var m=Tt(),j=ae(m);{var S=W=>{var O=Ga(),C=s(O);f(K=>{be(O,"data-unread",t.list),o(C,K)},[()=>js(t.state)]),l(W,O)},A=W=>{var O=Ga(),C=s(O);f(()=>o(C,t.none)),l(W,O)},L=W=>{var O=Ns(),C=ae(O),K=s(C),U=n(K);{var E=D=>{var H=lt();f(()=>o(H,r())),l(D,H)};_(U,D=>{e(p)&&r()!==""&&D(E)})}var x=n(C,2),g=s(x);ze(g,21,()=>e(d),da,(D,H)=>{var V=As(),$=s(V),T=s($),w=n($,2);{var k=M=>{var b=Os(),N=s(b);f(()=>o(N,e(H).product_name)),l(M,b)};_(w,M=>{e(H).product_name!==""&&M(k)})}var R=n(w,2),F=s(R),h=n(R,2),G=s(h),Y=n(h,2),ne=s(Y);f(M=>{o(T,`ligne ${M??""}`),o(F,e(H).product_id),o(G,e(H).value),o(ne,e(H).message)},[()=>se(e(H).csv_line)]),l(D,V)}),f(D=>{be(C,"data-tally",t.list),o(K,`${D??""} `),be(x,"data-rows",t.list)},[()=>ca(e(d).length,t.findings.length,t.singular,t.plural)]),l(W,O)};_(j,W=>{t.state!=="read"?W(S):t.findings.length===0?W(A,1):W(L,-1)})}l(y,m)},$$slots:{default:!0}}),Me()}function wr(a,t){const r=a.rows_read_count,i=a.images_decoded_count,d=r-i,p=[{count:_t(a.weighable_count),label:"pesables",note:`(${_t(i)} avec photo, ${_t(d)} sans)`,link:""},{count:_t(a.not_weighable_count),label:"non pesables",note:Bs(t),link:""}];if(a.anomalies_count>0&&p.push({count:_t(a.anomalies_count),label:"anomalies",note:"à corriger dans Odoo",link:Ha(a.anomalies_count)}),a.unit_mismatches_count>0){const y=a.unit_mismatches_count;p.push({count:"+ "+_t(y),label:y===1?"unité divergente":"unités divergentes",note:"pesable, unité à corriger",link:Ha(y)})}return{headline:`Catalogue du ${va(a.occurred_at)} — ${_t(r)} produits reçus`,lines:p,oneLine:Is(a)}}function Is(a){const t=[`${_t(a.rows_read_count)} reçus`,`${_t(a.weighable_count)} pesables`,`${_t(a.not_weighable_count)} non pesables`,`${_t(a.anomalies_count)} anomalies`],r=a.unit_mismatches_count;return r>0&&t.push(`${_t(r)} ${r===1?"unité divergente":"unités divergentes"}`),t.join(" · ")}const Ds={applied:"appliqué",unchanged:"identique au précédent",rejected:"refusé",failed:"échec"},Fs={local_drop:"dépôt local",webdav:"WebDAV",manual:"déposé sur l’écran"};function ha(a){return Ds[a]??"résultat inconnu"}function yr(a){return Fs[a]??"source inconnue"}function Us(a,t){const r=[a.file_name===""?"Le dernier fichier":a.file_name,ha(a.result)],i=Lt(a.occurred_at);i!==""&&r.push("le "+i),r.push("via "+yr(a.source));const d=a.reason===""?"":" "+a.reason;return`${r.join(" ")} — ${wr(a,t).oneLine}.${d}`}function Ms(a){return a===""?"Aucun nouvel import enregistré à cet instant, et ce poste ne publie pas ce qu’il surveille.":"Aucun nouvel import enregistré à cet instant. Le poste surveille "+a+" : le fichier n’y était pas, ou il n’a pas encore fini d’arriver."}function Ws(a){return"Ce poste n’a pas de journal : il ne pourra rien dire de l’issue de cette relecture."+(a===""?"":" Le poste surveille "+a+".")}function Ha(a){return a===1?"voir la ligne":`voir les ${_t(a)} lignes`}function Bs(a){return a.map(t=>`${Vs(t)} (${_t(t.count)})`).join(", ")}function Vs(a){switch(a.code){case"PREPACKAGED_PRODUCT":return"préemballés";case"INTERNAL_CODE_NOT_WEIGHABLE":return a.value===""?"code interne":"code interne "+a.value;case"NO_BARCODE":return"sans code-barres";default:return a.code}}function _t(a){return String(a)}var Gs=c('
');function xr(a,t){Ue(t,!0);const r=u(()=>wr(t.record,t.motives));var i=Zs(),d=s(i),p=s(d),y=n(d,2);ze(y,21,()=>e(r).lines,j=>j.label,(j,S)=>{var A=Qs(),L=s(A),W=s(L),O=n(L,2),C=s(O),K=s(C),U=n(C,2);{var E=D=>{var H=Ys(),V=s(H);f(()=>o(V,e(S).note)),l(D,H)};_(U,D=>{e(S).note!==""&&D(E)})}var x=n(U,2);{var g=D=>{var H=Xs(),V=s(H);f(()=>o(V,e(S).link)),Ce("click",H,()=>t.onshowrows(e(S).label==="anomalies"?"anomalies":"units")),l(D,H)};_(x,D=>{e(S).link!==""&&t.onshowrows!==void 0&&D(g)})}f(()=>{be(A,"data-row",e(S).label),o(W,e(S).count),o(K,e(S).label)}),l(j,A)});var z=n(y,2),m=s(z);f(()=>{o(p,e(r).headline),o(m,e(r).oneLine)}),l(a,i),Me()}ot(["click"]);var el=c(""),tl=c(''),al=c('');function Na(a,t){Ue(t,!0);const r=Be(t,"hint",3,"");var i=al(),d=s(i),p=n(d,2),y=s(p),z=s(y),m=n(y,2);{var j=L=>{var W=el(),O=s(W);f(()=>o(O,t.path)),l(L,W)};_(m,L=>{St.showTechnicalNames&&L(j)})}var S=n(m,2);{var A=L=>{var W=tl(),O=s(W);f(()=>o(O,r())),l(L,W)};_(S,L=>{r()!==""&&L(A)})}f(L=>{be(i,"data-flag",t.path),be(i,"data-on",L),ea(d,t.on),o(z,t.label)},[()=>String(t.on)]),Ce("change",d,L=>t.onchange(L.currentTarget.checked)),l(a,i),Me()}ot(["change"]);function Ja(a){const t=`${se(a.columns)} ${a.columns>1?"colonnes":"colonne"}`,r=`${se(a.rows)} ${a.rows>1?"rangées":"rangée"}`;return`${t} × ${r}`}function rl(a){const t=a.layout,r=[];if(a.columns===Xt)return r.push(t===null?"Automatique : la grille suit la largeur de l’écran. Un écran plus large en montre davantage sans qu’on y revienne.":`Automatique : ${Ja(t)} sur cet écran. Un écran plus large en montrera davantage sans qu’on y revienne.`),r;if(t===null)return r.push(`${se(a.columns)} ${a.columns>1?"colonnes":"colonne"} sur tous les écrans. Cet écran ne sait pas dire combien de rangées cela fait ici.`),r;const i=t.columns*t.rows;if(r.push(`${Ja(t)} — ${se(i)} ${i>1?"tuiles":"tuile"} d’un coup, sur cet écran (${String(a.viewport.width)} × ${String(a.viewport.height)}).`),a.tileCount>0){const p=Math.ceil(a.tileCount/i);r.push(a.tileCount>1?`Les ${se(a.tileCount)} tuiles de la grille tiennent en ${se(p)} ${p>1?"écrans":"écran"}.`:"La seule tuile de la grille tient en un écran.")}const d=a.floor;if(d!==null&&d.names>0){const p=d.names>1;r.push(`${se(d.names)} ${p?"noms":"nom"} sur ${se(a.tileCount)} ${p?"atteignent":"atteint"} le plancher de ${se(ka)} px : `+(d.rows>1?`leurs ${se(d.rows)} rangées peuvent être plus hautes que les autres.`:"leur rangée peut être plus haute que les autres."))}return r}function nl(a,t,r){if(a==="loading")return"Lecture du catalogue en service…";if(a==="unread")return"Le catalogue en service n’a pas pu être lu : cet écran ne sait pas combien de produits se vendent à l’unité.";if(t===0)return"Aucun produit vendu à l’unité dans le catalogue en service.";const i=t>1,d=i?"produits vendus à l’unité sont":"produit vendu à l’unité est",p=r?`${i?"montrés":"montré"} dans la grille de ce poste`:`${i?"masqués":"masqué"} sur ce poste`;return`${se(t)} ${d} ${p}.`}function sl(a){return["localhost","127.0.0.1"].includes(a)?"":"Cet écran n’est pas celui du poste : ce compte vaut pour l’écran que vous lisez."}const ll=-1,il=10;class kr{#t=B("");get sentence(){return e(this.#t)}set sentence(t){v(this.#t,t,!0)}#r=0;#a="";#e=0;begin(t){this.sentence="",this.#r=t.last_import_id,this.#a=t.watched,this.#e=il}forget(){this.sentence="",this.#e=0}observe(t){if(this.#e===0)return;if(t.counters.journal_rows_count===ll){this.#n(Ws(this.#a));return}const r=t.catalog;if(r!==null&&r.id!==this.#r){this.#n(Us(r,t.catalog_motives));return}this.#e-=1,this.#e===0&&(this.sentence=Ms(this.#a))}#n(t){this.sentence=t,this.#e=0}}var ol=c('
Aucun import enregistré sur ce poste.
'),ul=c('
'),cl=c(`
« Oublier la quarantaine » fait relire un fichier que le poste avait écarté : c’est le
seul geste de cette page qui puisse remettre en service un catalogue refusé.
`,1),Ka=c(""),dl=c(''),vl=c('
'),pl=c('
'),fl=c(''),gl=c(`
Un produit masqué reste vendable : la caisse lit toujours son code-barres, et une
étiquette déjà imprimée reste valable. Ce réglage ne fait que retirer sa tuile.
Colonnes de la grille
Se tromper ne coûte rien d’autre que de revenir ici : le réglage ne change ni le
- fichier reçu, ni les étiquettes déjà imprimées.
En dessous de ce nombre, la catégorie n’a pas de puce dans la barre du bas. Ses
+ fichier reçu, ni les étiquettes déjà imprimées.
En dessous de ce nombre, la catégorie n’a pas de puce dans la barre du bas. Ses
produits restent dans « Tout » et à la recherche : ce réglage ne retire aucune
tuile. Pour ne plus montrer une catégorie du tout, c’est sa case « visible » qu’il
faut décocher.
`,1),ml=c('
'),hl=c(`
Déposez ici le fichier clé
Ce dépôt remplace toute la grille par le fichier apporté : il change ce que le poste
diff --git a/internal/web/dist/index.html b/internal/web/dist/index.html
index 1f104c9..6dcfac1 100644
--- a/internal/web/dist/index.html
+++ b/internal/web/dist/index.html
@@ -6,7 +6,7 @@
Pesée
-
+
diff --git a/web/src/admin/lib/fields.ts b/web/src/admin/lib/fields.ts
index 5f28d1a..b4d733a 100644
--- a/web/src/admin/lib/fields.ts
+++ b/web/src/admin/lib/fields.ts
@@ -29,7 +29,7 @@ export const FIELD_LABELS: Readonly> = {
'ui.show_grid_prices': 'Afficher les prix sur les tuiles',
'ui.show_by_unit_products': 'Afficher les produits vendus à l’unité',
'ui.grid_columns': 'Colonnes de la grille',
- 'ui.min_products_for_chip': 'Tuiles minimum pour donner sa puce à une catégorie',
+ 'ui.min_products_for_chip': 'Articles minimum pour afficher une catégorie',
'scale.type': 'Protocole de la balance',
'scale.present': 'Ce poste a une balance',
diff --git a/web/src/admin/pages/Catalog.svelte b/web/src/admin/pages/Catalog.svelte
index 3711596..deff45a 100644
--- a/web/src/admin/pages/Catalog.svelte
+++ b/web/src/admin/pages/Catalog.svelte
@@ -879,7 +879,7 @@