# Librerie di terze parti — copie locali Queste copie servono al **punto 12** del documento delle modifiche: l'installazione a Tràfilo è on-premise, su rete di produzione isolata. Finché queste librerie venivano scaricate da CDN a ogni apertura di pagina, senza internet l'interfaccia non partiva affatto (Alpine.js governa tutta la UI). Secondo effetto, non meno importante: le versioni sono **congelate**. Prima Alpine.js era agganciato a `alpinejs@3.x.x`, cioè l'applicazione cambiava da sola a ogni rilascio degli autori, senza validazione. Per un sistema che produce evidenze per audit ISO 9001 / IATF 16949 questo è di per sé un difetto. Scaricate il **28 luglio 2026**. ## JavaScript | File | Versione | Origine | |---|---|---| | `alpinejs-3.15.12.min.js` | 3.15.12 | `https://cdn.jsdelivr.net/npm/alpinejs@3.15.12/dist/cdn.min.js` | | `plotly-2.32.0.min.js` | 2.32.0 | `https://cdn.plot.ly/plotly-2.32.0.min.js` | | `pdf-3.11.174.min.js` | 3.11.174 | `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js` | | `pdf.worker-3.11.174.min.js` | 3.11.174 | `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js` | | `fabric-5.3.1.min.js` | 5.3.1 | `https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js` | La versione di Alpine è quella a cui `3.x.x` risolveva il giorno del congelamento: il pin non cambia il comportamento rispetto a quanto già in esercizio. `pdf.worker` è un file a sé che PDF.js carica **a runtime** via `pdfjsLib.GlobalWorkerOptions.workerSrc`. Va ripuntato in tutti i template che usano PDF.js, non basta lo script principale: altrimenti la libreria si carica in locale e il worker continua a cercare internet — sembra funzionare finché non si apre un disegno. ## Font `fonts.css` sostituisce il `` a `fonts.googleapis.com` in `base.html`. | File | Famiglia | Subset | |---|---|---| | `fonts/inter-latin.woff2` | Inter | latin | | `fonts/inter-latin-ext.woff2` | Inter | latin-ext | | `fonts/jetbrains-mono-latin.woff2` | JetBrains Mono | latin | | `fonts/jetbrains-mono-latin-ext.woff2` | JetBrains Mono | latin-ext | Entrambe le famiglie sono **font variabili** (asse `wght`: Inter 100–900, JetBrains Mono 400–800): un solo file per subset copre tutti i pesi usati dall'interfaccia. Google serviva lo stesso woff2 sotto otto URL diversi, uno per peso dichiarato. Tenuti i soli subset **latin** e **latin-ext**, che coprono per intero italiano e inglese. Per gli altri alfabeti il browser ricade sul font di sistema — scelta consapevole: cirillico, greco e vietnamita valevano 600 KB di peso morto. ## Impronte SHA-256 ``` 57b37d7cae9a27d965fdae4adcc844245dfdc407e655aee85dcfff3a08036a3f alpinejs-3.15.12.min.js bb0442d69a4d4673320f689bc6e16c05a0e3f16ccfbf551f394d90a7e7cfc772 fabric-5.3.1.min.js 5b5799e6f8c680663207ac5b42ee14eed2a406fa7af48f50c154f0c0b1566946 pdf-3.11.174.min.js feabdf309770ed24bba31a5467836cdc8cf639c705af27d52b585b041bb8527b pdf.worker-3.11.174.min.js 0a17719a72751704861215da0e5c5cdb3f9a8d50eff5cb84cb6f8b80786682b0 plotly-2.32.0.min.js 34b9c504cab7a73e37b746343a449132e56cf7b5481af2cb81dc74dcff25c956 fonts/inter-latin-ext.woff2 3100e775e8616cd2611beecfa23a4263d7037586789b43f035236a2e6fbd4c62 fonts/inter-latin.woff2 db5ff4db83e580426280e9337a58dc57d3a83784a1b03ad80914651594441d52 fonts/jetbrains-mono-latin-ext.woff2 83c005d49d8a6a50474c73a5a36ac0468076e9c4a29da7bdb14995d80560a5be fonts/jetbrains-mono-latin.woff2 ``` Verifica: `sha256sum -c` da questa cartella, oppure `sha256sum *.js fonts/*.woff2`. Il confronto è anche un test (`tests/test_offline.py::test_the_shipped_libraries_are_the_ones_that_were_checked`): una libreria sostituita sul posto tiene lo stesso nome e la stessa riga in tabella, e l'impronta è l'unica parte che se ne accorge. ## La regola che tiene il punto chiuso Le copie locali risolvono il problema una volta; quello che lo tiene risolto è la **Content-Security-Policy** servita dal client Flask (`app.py`, `CSP`), che ammette solo l'origine locale. Prima esisteva solo sul backend — cioè sulle risposte API, non sulle pagine che il browser disegna: la regola stava scritta dove non poteva essere infranta e mancava dove poteva. Con la policy in vigore, un `