Nella scheda Prodotti c'è il pulsante che rilegge tutto lo storico e rifà da capo i
numeri di ogni articolo: aste viste, prezzo minimo, massimo e medio, puntate del
vincitore, vittorie, osservazioni. I limiti scritti a mano e la stellina non cambiano.
Il ricalcolo si costruisce da parte e sostituisce le schede solo alla fine: un
annullamento a metà lascia quelle di prima.
Ogni operazione massiva passa da una finestra di avanzamento (ProgressDialog): titolo,
a che punto si è, barra, conto fatto/totale, tempo passato e Annulla. Modale quando è
questione di secondi, altrimenti si continua a usare l'applicazione: il recupero delle
puntate dei vincitori e lo studio delle aste vanno piano di proposito.
La scheda Apprendimento ha un menu di operazioni: studiare le aste chiuse non ancora
apprese (lo studio all'avvio si ferma dopo qualche minuto, questo va in fondo),
ricostruire il profilo per prodotto e fascia oraria, rifare il bandit dalle decisioni
registrate, azzerare lo sfidante o la calibrazione, ricominciare da capo. Lo studio
delle aste è una sola routine con budget di tempo facoltativo, avanzamento e
annullamento; quello che è già studiato resta studiato.
Le barre in alto di tutte le schede hanno la stessa altezza (stile TabToolbar): passando
da una scheda all'altra i pulsanti restano allo stesso posto.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Tutto ciò che l'applicazione registra sta ora in due file SQLite in
%LocalAppData%\AutoBidder\Database: autobidder.sqlite per le osservazioni e
esercizio.sqlite per i documenti d'esercizio (aste nel monitor, prodotti, promozioni,
modelli appresi con prefisso ml/) e per i registri applicativo e del riscatto puntate.
Il motore comune è SqliteDatabase; i file JSON e la cartella Apprendimento delle
versioni precedenti vengono importati la prima volta e lasciati dove sono. La cartella
si cambia dalle Impostazioni: al salvataggio si chiede se spostare i file, e si riavvia.
Le cartelle Dati/Statistiche/Registri, i registri su file, le misure dell'anticipo e
le impostazioni morte (LogBids, AutoApplyProductDefaults, NewAuctionLimitsPriority…)
non esistono più.
Il kill-switch se ne va: al suo posto un solo interruttore in barra, accanto ad
Avvia/Osserva/Ferma, che spegne l'apprendimento. Spento, il motore punta solo entro i
limiti dell'utente (prezzo, puntate, budget, fascia oraria, rischio) con l'anticipo
fisso: niente valore atteso, regime, duello, bandit, anticipo adattivo. Le aste vengono
comunque registrate e studiate.
Tre difetti visti osservando il motore dal vivo per un'ora, in Osserva:
- la copertura «Compralo Ora» con V lasciato al listino azzerava la perdita coperta e
il motore diceva BID a ogni scadenza con P dell'1%: ora vale solo per i prodotti con
«Valore reale €» scritto, altrimenti la puntata si conta persa e P decide;
- la chiusura di un'asta arrivava due volte (fine, poi rimozione dal monitor) e di
nuovo al riavvio: modello, profilo, bandit e statistiche per prodotto contavano ogni
asta due volte. Il monitor la comunica una volta sola, l'apprendimento salta le aste
già apprese, e le schede prodotto vengono ricostruite una volta dallo storico;
- la pagina delle ricompense veniva scambiata per la pagina di accesso perché porta un
collegamento a /login.php: prima si guarda se è la pagina delle ricompense.
Interfaccia: la scheda Esporta e tutto il suo codice sono tolti; le esportazioni
chiedono sempre dove salvare. Prodotti, Storico e Apprendimento hanno barre a sole
icone con tooltip che dicono esattamente cosa succede, colorate come il monitor, con
i nuovi pulsanti di pulizia (spegni tutte le stelline, togli i non seguiti, pulizia
completa; seleziona tutte / elimina le selezionate / svuota lo storico). Impostazioni:
sezione Database, Manutenzione con «Elimina tutti i dati (tranne la login)» e
«Impostazioni di fabbrica», esportazione dei registri in testo. Modifiche.txt, il
prompt ormai realizzato, esce dal repository.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
La riga «valore atteso +11,99 € (P 1.199,10%)» nel registro e nelle decisioni
mostrava il valore atteso al posto di P(senza risposta).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Le aste non si salvano più in un file JSON per asta più tre archivi da tenere allineati:
un solo database SQLite (winsqlite3.dll di Windows via P/Invoke, nessun pacchetto) con
prodotti, aste, puntate, interrogazioni coalescenti, reset con profondità del ciclo,
nostre puntate, decisioni del motore, misure di rete, puntatori, sessioni e contabilità.
Scrittura in coda su un thread dedicato, letture in WAL. Per scelta dell'utente si parte
da zero: il database si riempie man mano che si osservano le aste; i vecchi dossier
restano leggibili per un'importazione futura ma non si scrivono più. Storico, schede,
apprendimento, rigiocata ed esportazioni leggono tutti da lì.
Il documento di progetto (Modifiche.txt) tradotto in C# senza librerie:
- RiskManager: kill-switch (file KILL_SWITCH, anche dalla barra), HALT persistente per
stop-loss e drawdown, tetto del giorno, aste in gioco insieme, contabilità in euro.
- Theory: valore atteso con fee, spedizione, valore reale per prodotto (nuova colonna
nella scheda Prodotti) e copertura «Compralo Ora»; null-model; sopravvivenza empirica e
Kaplan-Meier dai reset; arrivi di Poisson.
- Shadow per asta: in Osserva il cecchino arriva allo stesso istante, registra cosa
avrebbe fatto e non punta; alla chiusura ogni decisione riceve l'esito, e ShadowReport
confronta le policy sugli stessi istanti con intervallo di confidenza sul ROI.
- NeuralNet (MLP, Adam) come sfidante del logistico, scelto dal Brier prequenziale;
ThompsonBandit come seconda policy che impara dagli esiti delle decisioni;
PennyAuctionEnv con avversari tarati sul database e QLearningAgent conservativo;
SimulationLab per il confronto fra policy; esportazione CSV delle decisioni con
reason_detail. Tutto nella scheda Apprendimento.
Ml/LEGGIMI.md riscritto con le avvertenze su termini d'uso, quadro legale e realtà
economica, lo schema del database e lo stato delle milestone.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Le strategie a numero fisso (calore, ritiro morbido, anti-bot, avversari aggressivi,
puntata probabilistica, velocità del prezzo, esaurimento, concorrenza) e le impostazioni
morte (cadenze di polling, finestra critica, database, log avanzati, suggerimenti
sull'anticipo, schede dettagliate) non ci sono più: rigiocate sui dossier non fermavano
una puntata sbagliata senza fermarne anche di giuste, e i loro numeri andavano tarati a
mano. Restano i paletti dell'utente (tetti, budget, fascia oraria) e il duello.
Al loro posto due componenti che imparano dalla sessione in corso, dentro i paletti:
- CompetitionRegime per asta (Calmo / Sfogo / Sondaggio) guidato dal valore atteso
appreso: tre negativi di fila e si lascia sfogare gli altri, si rientra con una
puntata di prova dopo abbastanza cicli buoni, e se viene coperta subito la pazienza
raddoppia. È il "capire da soli quando tornare a puntare".
- LatencyModel per l'anticipo: margine + p99 della latenza misurata adesso, tenuto fra
LeadMinMs e LeadMaxMs; una puntata tardiva alza il margine subito, venti in tempo lo
abbassano piano. Un anticipo scritto a mano su un'asta vince sempre (BidLeadIsManual).
Archiviazione: l'archivio mensile aste-AAAA-MM.jsonl (95 MB) duplicava il riepilogo che
ogni dossier ha già in coda. AuctionDetailStore ora legge testa e coda dei dossier, con
cache: 6349 file in 6 s la prima volta. Pulsanti per svuotare le esportazioni e per
azzerare le statistiche voce per voce (lo storico passa dalla copia di sicurezza).
Scheda Apprendimento: sezione "Autonomia sul momento" con il modello di latenza e il
regime di ogni asta seguita. Ml/LEGGIMI.md descrive l'algoritmo per intero.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Una scheda nuova nella barra laterale, fra Esporta e Impostazioni, che legge
direttamente dal servizio e si aggiorna da sola ogni cinque secondi mentre e'
visibile: nessun altro pezzo dell'applicazione sa che esiste.
Mostra: lo stato (aste apprese, esempi visti, aste nel profilo, fattore di
calibrazione, soglia per decidere, se lo studio dei dossier e' in corso); i pesi
dal piu' forte con il verso dell'effetto, perche' le variabili sono a fasce e il
modello e' lineare proprio per poterli leggere; le ultime decisioni date al
motore, con probabilita', valore atteso ed esito (fermata, passa, o solo parere
se il modello non aveva ancora appreso abbastanza); il profilo per prodotto e
fascia oraria; e l'ultima valutazione.
La valutazione si lancia dalla scheda, in sottofondo e annullabile. La logica e'
uscita dal test ed e' entrata in LearningEvaluator, condivisa fra il target da
riga di comando e la scheda: i numeri che vede l'utente sono gli stessi che vede
chi sviluppa. "Ricomincia da capo" butta modello, profilo ed elenco dei dossier
letti e ristudia tutto l'archivio, con una conferma prima.
Le decisioni si tengono in una coda corta; lo stesso giro di un'asta ne
produrrebbe molte uguali di fila, quindi si registra solo il cambiamento.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Via le due modalita' Addestramento/Gara, per scelta dell'utente: la misura aveva
detto che il lavoro di registrazione costa mezzo punto di un core, e allora tanto
vale registrare sempre. Resta la coalescenza verso l'interfaccia, che era la
correzione vera.
COSA IMPARA. Per ogni puntata di ogni asta chiusa: e' rimasta senza risposta?
E' l'unica etichetta abbondante — 1,8 milioni di esempi sui dossier locali —
contro le diciannove aste vinte dall'utente, che non farebbero un modello. Il
comportamento avversario non dipende da chi ha puntato, e questo rende
utilizzabili le puntate altrui. Regressione logistica online scritta a mano,
senza librerie, in Ml/: un passo di gradiente per esempio, aggiornata a ogni
chiusura, salvata subito. Variabili a fasce: durata del ciclo, quota di
autopuntate recenti, puntatori distinti, prezzo sul valore, fascia oraria (le
fasce ricalcano la curva misurata sulle chiusure), feriale/festivo, ora di
aggancio, tipo di puntata, profondita' dell'asta, stesso puntatore di due fa,
prodotto in 32 cassetti con hash stabile. In parallelo un profilo per prodotto x
fascia oraria x tipo di giorno, con restringimento verso il prodotto e poi verso
il globale dove i dati scarseggiano.
COME DECIDE. In ShouldPlaceBid: probabilita' appresa per il margine residuo meno
il costo della puntata; sotto zero non si punta, e il registro riporta i numeri.
Il modello parla sempre ma decide solo dopo 300 aste apprese. Le previsioni sono
calibrate in linea con il rapporto osservato/previsto sugli ultimi 20.000 esempi.
QUANTO VALE, MISURATO. Valutazione prequenziale sui 3000 dossier piu' recenti
(ogni asta prima prevista poi appresa, come nell'uso): sollevamento 10,8x nella
cima dell'1%, 5,8x al 5%; calibrazione entro il 10-30% in ogni fascia. Sulle 116
puntate vere dell'utente di agosto: nessuna era finale, e il cancello ne avrebbe
fermate 45 senza perderne una vincente. La valutazione congelata (addestra sui
vecchi, giudica sui nuovi) sovrastima di 1,5-1,8x per deriva del mercato, non per
passo o regolarizzazione: provati entrambi. Griglia e prequenziale stanno nel
test MlModelBacktest, target Apprendimento, attivita' VS Code "valuta
apprendimento".
PRIMO ADDESTRAMENTO. In sottofondo, dal piu' recente, con un tempo massimo per
avvio. Il lettore salta le righe di poll prima del JSON: 6289 dossier per 8,8 GB
in 64 secondi, verificato dal vivo, archivio completo al primo avvio.
ACQUISIZIONE. I poll nel dossier si scrivono solo quando cambia qualcosa di
visibile, e comunque uno al secondo: -88,8% misurato, senza perdere la
profondita' di nessun ciclo. Il reset porta il minimo del cronometro e la durata
del ciclo chiuso. Via le righe di log che copiavano i reset parola per parola.
Corretto un difetto vecchio: nessun dossier marcava le puntate nostre, perche' il
parser lo faceva solo se riceveva il nome utente e nel percorso dei poll non gli
arrivava. Ora si marcano in MergeBidHistory e l'intestazione porta il nome
utente; per i dossier vecchi il lettore accetta il nome da fuori.
Trovato dal vivo e corretto: salvataggi concorrenti all'avvio quando piu' aste
chiudono insieme. Il modello salvato non rilegge piu' i parametri (passo,
regolarizzazione): sono scelte del codice, e un cambio vale dal riavvio dopo.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Tre richieste, piu' la causa vera della lentezza trovata misurando.
PERCORSI. Le impostazioni e i dati vanno in Documenti\AutoBidder per chi installa
da zero; sessione, riferimenti del sito e profilo del browser restano in
%LocalAppData%, perche' la sessione e' protetta con DPAPI e legata all'utente
Windows. Chi ha gia' un'installazione non viene spostato: se le impostazioni
esistono in %LocalAppData% e non in Documenti si continua a usare quelle dove
sono (scelta esplicita dell'utente, per non toccare mesi di raccolta). La radice
si decide una volta sola all'avvio e non cambia piu' nel processo. La suite di
test la dirotta in una cartella temporanea: senza, un test che tocca le
impostazioni leggerebbe quelle vere.
PULIZIA. Tre criteri nuovi: per prodotto (elenco con i conteggi, confronto senza
maiuscole), solo osservate / con mie puntate (i due versi: storico compatto delle
proprie partite, o storico "di mercato" senza le proprie mosse), prezzo finale
oltre una percentuale del valore (le chiusure incaponite spostano medie e limiti
consigliati verso l'alto per tutti; senza valore noto l'asta resta, non si
indovina). Dopo ogni pulizia le statistiche per prodotto si ricostruiscono da
zero dallo storico rimasto: sono un archivio a parte alimentato asta per asta, e
avrebbero continuato a descrivere aste che non ci sono piu'.
MODALITA'. Addestramento registra tutto; Gara toglie i poll grezzi nel dossier,
le righe informative del registro dell'asta e il dettaglio esteso. Letta una
volta all'avvio e immutabile fino alla chiusura, come chiesto: la scheda mostra
la modalita' in vigore e avvisa del riavvio solo se la scelta differisce.
Misurato prima di promettere: il lavoro che Gara evita costa 4,9 microsecondi
per poll. A 57 aste per 17 poll al secondo sono 4,7 ms di CPU al secondo, mezzo
punto di un core. La scrittura su disco era gia' asincrona. Gara fa bene al disco
e ai dossier, non alla velocita'.
LA LENTEZZA VERA. Ogni poll arrivava al thread dell'interfaccia: un
BeginInvoke, una scansione lineare dei ViewModel e venti notifiche di
proprieta'. Con trenta aste diecimila notifiche al secondo, con cinquantasette
quasi ventimila. Adesso si manda all'interfaccia solo il poll in cui cambia
qualcosa di visibile (prezzo, puntatore, stato, secondo intero, se e' mio), e
comunque uno al secondo per asta perche' ping e contatori si rinfreschino. Il
conto alla rovescia scorre gia' da solo con il battito da 200 ms. Il motore non
e' toccato: la decisione di puntare vede ogni poll come prima.
Misurato su 40 dossier veri, 146.138 poll: ne passano 16.375, l'88,8% viene
scartato. Nove volte meno lavoro sul thread dell'interfaccia.
Nella scheda Impostazioni entrano anche la fascia oraria e la pulizia
dell'elenco, che il motore usava gia' ma che non si potevano ancora cambiare.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Con l'aggiunta automatica accesa le aste concluse si accumulano a centinaia e
seppelliscono quelle vive, che e' il contrario di quello che serve guardando un
cruscotto. Il pulsante manuale "rimuovi le aste concluse" c'era gia', ma toglieva
tutto senza distinguere.
La rimozione automatica e' accesa di serie e toglie solo le aste che non hanno
piu' niente da dire. Restano invece, ciascuna con la sua opzione:
- quelle su cui si e' puntato, perche' sono le uniche che vale la pena riguardare
e i soldi erano veri;
- quelle vinte, perche' c'e' da confermare l'acquisto su Bidoo e una vittoria
sparita dall'elenco e' il modo piu' semplice di dimenticarsene;
- quelle di cui non si e' vista la fine, perche' sono esattamente quelle da
controllare.
L'ordine dei controlli conta: prima le ragioni per trattenere, cosi' il motivo
scritto nel registro e' il piu' importante e non l'ultimo incontrato. Una vinta su
cui si e' anche puntato resta "vinta", che e' quella che richiede un'azione. Il
motivo finisce nel registro anche quando l'asta resta: senza, un'asta che sparisce
e una che non sparisce sarebbero entrambe inspiegabili.
La rimozione avviene come ultimo passo, dopo che storico, dossier e statistiche
del prodotto sono gia' scritti: a quel punto togliere l'asta dall'elenco non perde
niente.
Corretto anche un difetto introdotto ieri con la fascia oraria: la rigiocata sui
dossier usava le impostazioni vere, fascia compresa, e la fascia guarda l'orologio
di parete. Una rigiocata ripercorre aste gia' concluse e l'ora in cui la si lancia
non c'entra nulla con l'ora in cui quelle aste correvano: lanciata di notte
avrebbe rifiutato ogni puntata e riportato zero, che e' il tipo di risultato che
sembra vero e non lo e'. Adesso la rigiocata lavora su una copia delle
impostazioni con la fascia spenta, senza mutare quelle dell'utente.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sintomo: una raffica di CS2001 "file di origine MainWindow.g.cs non trovato" su
otto file .g.cs, lanciando la normale compilazione di debug da VS Code, senza che
il codice fosse cambiato. Il classico guasto intermittente della compilazione WPF.
Causa: il target Pubblica usava la sola opzione -o, che sposta il risultato ma
lascia gli INTERMEDI nella obj/ del progetto, cioe' la stessa cartella che usa la
compilazione di debug. La compilazione WPF genera un progetto temporaneo
_wpftmp.csproj a ogni giro, e quando ci trova dentro lo stato di un'altra
configurazione smette di produrre le classi parziali dello XAML. Bastava
pubblicare mentre si compilava in VS Code, o subito prima, per rompere tutto.
Era gia' il rimedio adottato per i test, dove artifacts-path era stato messo
proprio per questo; il target Pubblica era rimasto indietro. Le due opzioni
convivono: artifacts-path sposta gli intermedi, -o continua a decidere dove
finisce l'eseguibile.
Verificato ripetendo tre volte la sequenza che rompeva - pubblica, poi compila in
debug - con la obj/ svuotata all'inizio: zero errori tutte e tre le volte, e la
pubblicazione non crea piu' obj/Release.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Trovato provando davvero l'applicazione, non dai test. Il settings.json esistente
conteneva MaxRequestsPerSecond 40 e DefaultBidBeforeDeadlineMs 1000, e il valore
su disco vince sempre sui predefiniti: installando la versione nuova, le due
correzioni che pesano di piu' - tetto delle richieste tolto e anticipo a mezzo
secondo - sarebbero state annullate dal file dell'utente, che avrebbe concluso
che non funzionano.
Che il file vinca e' giusto: sono scelte di chi usa il programma. Ma quei due
valori non erano scelte, erano conseguenze di misure sbagliate. Erano stati
tarati quando il tetto stesso accodava le chiamate e gonfiava il ping a 444 ms al
p99,9; senza tetto il ping misurato sta fra 47 e 78 ms.
Migrazione una tantum, con un numero di schema nel file perche' giri una volta
sola. Tocca solo chi ha ancora esattamente il vecchio valore: chi lo aveva gia'
cambiato di suo se lo tiene, perche' quella e' una scelta e non spetta a un
aggiornamento ribaltarla. Il salvataggio avviene dentro Load, che di norma non
tocca il disco, ma una migrazione capita una volta nella vita del file e
lasciarla non salvata la farebbe ripetere a ogni avvio.
Verificato dal vivo sull'eseguibile pubblicato: 40 diventa 0, 1000 diventa 500,
lo schema passa da assente a 1, e le impostazioni nuove (fascia oraria, ritiro
dai duelli) compaiono coi valori giusti.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Su 6060 aste concluse con prezzo e valore noti, la stessa asta non costa uguale a
tutte le ore. Prezzo di chiusura mediano in percentuale del valore del prodotto:
4,6% alle 12 e 5,3% fra le 10 e le 13, contro 8,6% a mezzanotte e 9,7% alle 9. Le
puntate necessarie per vincere seguono la stessa curva: 21-24 nelle ore buone,
26-29 in quelle cattive. Quasi il doppio del costo per lo stesso oggetto.
Il motivo e' che di notte Bidoo sospende le puntate: restano poche aste in corso e
la concorrenza si concentra li'. Le ore di confine, mezzanotte e le nove, sono le
peggiori, perche' c'e' ancora qualcosa da giocare e ci sono tutti addosso.
La fascia predefinita e' 00:00-10:00. Sospende le puntate, NON il monitoraggio:
l'asta resta in stato Attiva, continua a essere seguita e riprende a puntare da
sola alla fine della fascia. E' voluto: le aste lunghe attraversano la fascia, e
fermarle davvero significherebbe perderle invece che risparmiare. Ogni puntata
saltata scrive nel registro il motivo e l'orario di ripresa.
Tre livelli di override, dal piu' specifico al piu' generale: la singola asta
scavalca il prodotto, il prodotto scavalca le impostazioni generali. Un null non
vuol dire "no" ma "non ho un'opinione", ed e' la differenza che permette di
spegnere il filtro su una sola asta senza toccare il resto.
Una fascia a cavallo di mezzanotte (22-6) funziona; inizio uguale a fine vuol dire
filtro spento, che e' l'unica lettura sensata visto che l'alternativa sarebbe non
puntare mai.
Backtest della regola sul duello, completato su tutte le soglie. Sui dossier veri
in cui il bot ha puntato: 13 aste, 366 puntate, zero vittorie. Con soglia 5 le
puntate sarebbero state 49, risparmiate 317 (86,6%), nessuna vittoria persa. Il
risultato tiene da soglia 2 a soglia 10, che e' quanto ci si puo' aspettare da un
campione in cui non si era vinto niente.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Il pannello della singola asta consigliava di tenere l'anticipo fra 600 e 2000 ms
e proponeva 800: numeri nati da misure fatte quando il tetto di 40 richieste al
secondo accodava le chiamate e gonfiava il ping. Adesso dice quello che i dati
dicono davvero: tre quarti delle puntate avversarie sono automatiche e scattano a
2 secondi, sotto quella soglia resta solo chi punta a mano, e il predefinito e'
500 ms perche' e' circa nove volte il ping misurato.
Righe della griglia da 28 a 22 px con carattere piccolo: su un cruscotto che
serve a tenere d'occhio molte aste insieme l'altezza e' la risorsa scarsa, e sei
pixel di aria per riga costano una decina di aste sullo schermo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
La strategia A, dai numeri dei dossier: 5410 aste, 2,08 milioni di puntate.
Bidoo dichiara per ogni puntata se e' automatica o manuale. Le automatiche sono
il 75,3% del totale ma vincono il 46,0% delle aste; le manuali sono il 24,7% e ne
vincono il 53,9%. Una puntata manuale vale 3,6 volte una automatica: 178 puntate
per vittoria contro 634.
Il meccanismo del duello e' stato ricostruito esattamente. L'intervallo mediano
fra due puntate consecutive e' 6,0 s su 2.799.681 intervalli: il timer si azzera
a ~8 s e l'autopuntata scatta a 2 s, quindi 8-2=6. Il ciclo da 13,0 s osservato
nelle prove reali era la somma di 7 s di attesa nostra e 6 s della sua risposta.
Puntare tardi non evita l'autopuntata avversaria: la sveglia, perche' si riarma
quando il suo padrone perde la testa della classifica, non a un orario fisso.
Contro una macchina cosi' non esiste attrito vincibile. Adesso il motore conta le
risposte con la firma dei 6+/-2,5 s e dopo cinque di fila smette di puntare su
quell'asta. Una risposta fuori firma azzera il conteggio invece di scalarlo:
l'errore costoso e' ritirarsi da un'asta che si poteva vincere, non spendere
cinque puntate di troppo.
Rigiocato sui dossier veri in cui il bot ha puntato: 366 puntate spese, 13 aste,
zero vittorie. Con la regola a soglia 3 sarebbero state 31 puntate, 335
risparmiate (91,5%), nessuna vittoria persa.
L'anticipo passa da 1000 a 500 ms. Le due ragioni per stare larghi sono cadute:
il p99,9 del ping a 444 ms era misurato col tetto di 40 richieste al secondo che
accodava le chiamate, e senza tetto il ping sta fra 47 e 78 ms; e la concorrenza
sotto i due secondi non e' fitta ma rada, visto che tre quarti degli avversari
sono autopuntate che hanno gia' sparato.
Il tipo di puntata non viene piu' inventato. In due punti il motore ricostruiva
una puntata da un cambio di prezzo fra due interrogazioni e la marcava "Auto"
comunque: adesso quelle portano un trattino, perche' il tipo non lo ha detto
nessuno. La colonna in cronologia mostra quindi solo tipi dichiarati dal server.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Due difetti che i registri di tre giorni mostravano chiaramente.
Il riscatto dei buoni giudicava la risposta del sito, e la giudicava male: ogni
singolo tentativo risultava "sessione scaduta: risposta la pagina di accesso" —
6 trovati, 0 riscossi, 6 non riusciti, giro dopo giro per tre giorni — mentre le
puntate arrivavano lo stesso. Il riconoscimento della pagina di accesso scattava
su pagine che di accesso non erano, e il servizio dichiarava di non funzionare
mentre funzionava.
Adesso aprire il collegamento e' il riscatto: si apre, si scrive che e' stato
aperto, e il numero vero lo da' la differenza di saldo, che e' l'unica misura che
non mente. Resta un solo fallimento possibile, l'errore di trasporto, dove il
collegamento non e' stato aperto affatto. Un premio si riscuote una volta sola:
fra i due errori, insistere su un premio gia' preso non costa niente, mentre
dichiarare falliti dei riscatti riusciti riempie il registro di allarmi inutili.
Il giudizio vecchio non e' stato cancellato, e' in GiudicaRisposta.
Il conto alla rovescia in griglia restava fermo fra un poll e l'altro. Il valore
era gia' giusto — si ricava dalla scadenza ancorata all'orologio del server, non
dall'ultimo poll — ma nessuno lo richiedeva finche' non arrivava una risposta, e
nelle prove reali fra un poll e l'altro passava anche un secondo e mezzo:
sembrava un'applicazione bloccata. Un battito da cinque volte al secondo notifica
ora le tre sole proprieta' che dipendono dal tempo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Misurato sui registri di tre giorni di prove reali (886 dossier, 4,86 milioni di
interrogazioni). Il tetto globale di 40 richieste al secondo veniva spartito fra
tutte le aste seguite, fino a 31 insieme: la distribuzione risultava tagliata
netta sul limite (p90 39, p99 41, saturo nell'8% dei secondi) e ogni singola asta
finiva interrogata ogni ~596 ms invece dei 220 configurati per la finestra
critica. Con il timer a un secondo restava un solo sguardo prima della scadenza,
e la puntata partiva su una stima della scadenza vecchia di mezzo secondo.
Le quattro soglie di cadenza (lontano/medio/vicino/critico) non descrivevano
quindi niente di reale: qualunque numero ci si scrivesse, il tetto decideva al
posto loro. Adesso non c'e' nessuna attesa fra un poll e il successivo: si
riparte appena la risposta e' arrivata, cioe' ~17 interrogazioni al secondo per
asta con il ping misurato di 57 ms. Resta la sola cadenza allargata per le aste
non ancora cominciate, che non e' una scelta di ritmo: fino all'apertura il
server non ha nulla di diverso da dire.
Senza tetto fisso serviva pero' qualcosa che reagisse, altrimenti l'unico segnale
di "troppe richieste" sarebbe stato un blocco dell'account. Il freno ora lo detta
il server: un 429 o un 503 mette in pausa il polling per un secondo, raddoppiando
fino a otto se insistono, e la pausa si azzera al primo giro riuscito. Le puntate
hanno priorita' Critical e non passano dal freno: se il momento giusto e' adesso,
una pausa preventiva costerebbe l'asta.
Il tetto resta configurabile per chi lo vuole, con 0 = nessun limite come nuovo
predefinito.
Scelta dell'utente, dopo avergli mostrato il rischio: niente tetto, il massimo
che regge la rete.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sei modifiche chieste in questa sessione, di cui una pesa piu' di tutte le altre.
CompletedAuctionsStore rileggeva e rideserializzava l'intero file a ogni chiamata:
misurati 72 ms su 5876 record, 3,9 MB. Append pagava quel prezzo piu' la
riserializzazione e la riscrittura completa per cambiare un record solo, 120 ms
in tutto, e la chiamata arriva da un gestore di eventi di MainWindow, quindi dal
thread dell'interfaccia, che restava fermo a ogni asta conclusa. Il recupero
delle puntate dei vincitori lo faceva in un ciclo: 4675 aste erano 7,2 minuti di
solo rimescolamento JSON e 17,8 GB scritti sul disco.
Adesso c'e' una copia in memoria invalidata sulla data di modifica del file, cosi'
resta giusta anche se il file viene sostituito da fuori (ripristino di un backup),
e un AppendMany che applica molti record con un salvataggio solo, con un indice
per id perche' il caso per cui esiste non torni quadratico. Il recupero salva a
blocchi di cinquanta e deposita comunque quello che ha in mano quando esce, anche
per annullamento: le richieste gia' fatte sono state pagate al server.
Misurato sullo stesso file: 95 volte piu' veloce, 7,2 minuti diventano 4,5
secondi, 17,8 GB diventano 0,36 GB.
Le altre cinque:
- Il setup si chiama AutoBidder_<versione>.exe.
- I pulsanti di stop sono rossi, sia quello globale sia quelli per asta nella
griglia: erano gli unici tre senza colore mentre avvia e osserva ce l'avevano.
- La pulizia dello storico sa togliere le aste seguite solo in parte. Non serve
nessun campo nuovo: il prezzo finale in centesimi e' il totale delle puntate
dell'asta, quindi il rapporto con i reset osservati dice quanta asta si e'
vista, e la regola vale anche sullo storico gia' raccolto. Verificata sui dati
veri: su 5876 aste nessuna supera copertura 1,02, che e' quanto ci si aspetta
se l'identita' e' giusta.
- La griglia ricicla i contenitori di riga invece di ricrearli.
- Il costo puntata gia' esisteva col predefinito giusto: al suggerimento e' stato
aggiunto perche' 0,20 e' il numero da tenere.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
MSBuild divide il valore di una proprieta' sulle virgole: -p:Note=uno, due
diventa la proprieta' Note=uno piu' un'opzione ` due`, e si finisce su MSB1006
`proprieta' non valida`. Una nota di rilascio in italiano contiene quasi sempre
una virgola, quindi l'attivita' di rilascio si sarebbe rotta al primo uso reale
del prompt delle note.
Le note arrivano ora in AUTOBIDDER_NOTE, che MSBuild legge come proprieta' senza
passare dal parsing della riga di comando. Provato con virgole, apostrofi, due
punti e virgolette: arrivano integri. -p:Note= resta accettato per chi lo passa
a mano senza virgole.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Solo impaginazione: gli oggetti group e presentation passano da una riga a piu'
righe. Nessuna differenza di contenuto (git diff --ignore-all-space e' vuoto).
Committato per non lasciare l'albero sporco a ogni salvataggio del file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Il push dei tag non porta con se' i commit: a ramo indietro il tag punta a un
oggetto che il remoto non conosce e viene rifiutato. La creazione della release
pero' non falliva — Gitea, non trovando il tag, lo crea da se' sulla testa del
ramo predefinito. Sarebbe stata pubblicata una release che dichiara un commit e
allega il codice di un altro, senza che niente lo segnalasse.
Adesso il tag viene riletto dal remoto dopo il push e il rilascio si ferma se
non c'e', dicendo di spingere il ramo. I commit restano da spingere a mano:
quando farlo lo decide chi lavora, non la catena di rilascio.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AppInfo e il .csproj dicevano entrambi di alzare <Version> per pubblicare. Da
quando la versione viene dal tag non e' piu' vero, ed e' il tipo di commento che
fa perdere tempo fra sei mesi: adesso dicono a cosa serve davvero quel numero
(le compilazioni di sviluppo) e dove sta la fonte dei rilasci.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Il .csproj non viene piu' riscritto a ogni rilascio: i quattro numeri di
versione arrivano a dotnet publish come proprieta' da riga di comando, ricavati
dal tag su HEAD. Tag, eseguibile, installatore e release portano lo stesso
numero per costruzione invece che per disciplina, e un rilascio non lascia piu'
una modifica al progetto da committare dopo il fatto.
Se HEAD non ha un tag la catena lo crea da se' — numero chiesto o minor
successiva alla piu' alta esistente — ma lo fa in fondo, a installatore
prodotto: un giro fallito non lascia dietro il tag di una versione mai
costruita. Rifiuta di taggare un albero con modifiche non committate, perche'
sarebbe un tag che non indica niente di ricostruibile.
La configurazione di Gitea viene letta prima di compilare: senza token ci si
ferma in due secondi invece che dopo tre minuti di build.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
.idea/, Thumbs.db e Desktop.ini erano coperte nella cartella BidooBidder ma
non qui. Aggiunte prima di cancellarla, cosi' non si perde nulla.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Il progetto viveva in una cartella senza alcun commit: tutto il lavoro stava
solo sul disco. Trasferito qui, dove esiste una storia e un remoto.
Mancava soltanto build/: i sorgenti erano gia' allineati e identici. Nessun
percorso e' stato toccato — Release.proj usa MSBuildThisFileDirectory e
tasks.json usa ${workspaceFolder}, quindi il trasloco non li riguarda.
- build/Release.proj: verifica, backtest, pacchetto e rilascio in un solo file
MSBuild, senza script. Provato dalla nuova posizione: 287 test verdi,
installatore prodotto, backtest eseguito.
- build/gitea.example.json: url, owner e repo veri; resta da mettere il token
in build/gitea.json, che e' ignorato da git.
- build/sostituiti/: i quattro .ps1 rimpiazzati da Release.proj. Entrano qui
solo per non perderli con la vecchia cartella: da ora sono recuperabili
dalla storia e si possono cancellare.
- .gitignore: gitea.json (contiene una credenziale), i riepiloghi del backtest
e i pacchetti in bin/installer.
Versione 4.12.0 -> 4.13.0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Implement ThemeManager for dynamic light/dark theme switching in the application.
- Create Wait class for cancellable delays without exceptions for smoother user experience.
- Introduce WatchedProductsStore to manage and persist watched products in JSON format.
- Add WindowsNotifier for system notifications to inform users of important events.
- Develop ProductViewModel to encapsulate product data and manage UI interactions effectively.
Implementata una nuova funzionalità per garantire che tutti i campi numerici accettino solo input validi.
- Introdotta la classe helper `NumericTextBoxHelper` per configurare campi interi e decimali.
- Gestiti input non validi, campi vuoti e normalizzazione dei decimali.
- Applicata validazione a 13 campi numerici in tutta l'applicazione.
- Aggiunto supporto per tastiere internazionali (punto e virgola).
- Aggiornati `MainWindow.xaml.cs`, `CHANGELOG.md` e documentazione.
- Definiti test e casi d'uso per verificare il corretto funzionamento.
- Introdotti pulsanti "Sposta Su" e "Sposta Giù" per il
riordinamento manuale delle aste nella lista.
- Implementata navigazione con frecce direzionali nella griglia,
con aggiornamento automatico dei dettagli e scroll.
- Salvato automaticamente l'ordine delle aste su disco.
- Risolto conflitto con GridSplitter per le frecce direzionali.
- Aggiunti log dettagliati per le operazioni di riordinamento.
- Gestiti casi limite (es. asta già in cima o in fondo).
- Migliorata UX con pulsanti chiari e tooltip informativi.
- Aggiornati documentazione e changelog per riflettere le
modifiche.
- Modificato il binding della colonna "Latenza" in `AuctionMonitorControl.xaml` per utilizzare la nuova proprietà `LatencyDisplay`.
- Aggiunta la proprietà `LatencyDisplay` in `AuctionViewModel.cs` per calcolare dinamicamente la latenza in base allo stato dell'asta.
- Aggiunte notifiche di cambiamento per `LatencyDisplay` per aggiornare correttamente l'interfaccia utente.
- Documentata la proprietà `LatencyDisplay` con commenti XML per migliorarne la comprensione.
La colonna "Resets" è stata rimossa dal `DataGrid` in
`AuctionMonitorControl.xaml`. Era legata alla proprietà
`ResetCount` e aveva una larghezza di 60. Questa modifica
semplifica l'interfaccia utente, eliminando un'informazione
non più necessaria.
Introdotto un servizio centralizzato (`HtmlCacheService`) per gestire richieste HTTP con:
- Cache HTML (5 minuti) per ridurre richieste duplicate.
- Rate limiting (max 5 richieste/sec) e concorrenza limitata (3 richieste parallele).
- Retry automatico (max 2 tentativi) e timeout configurabile (15s).
- Logging dettagliato per cache hit, retry e richieste fallite.
Aggiornati i metodi di caricamento dei nomi e delle informazioni prodotto per utilizzare il nuovo servizio, migliorando caching, gestione degli errori e decodifica delle entità HTML.
Aggiunto supporto per il recupero automatico dei nomi generici delle aste e un timer per la pulizia periodica della cache.
Documentato il servizio in `FEATURE_HTML_CACHE_SERVICE.md`. Correzioni minori e miglioramenti alla leggibilità del codice.
È stata introdotta l'opzione "Ricorda Stato" che consente di ripristinare lo stato esatto (attiva, in pausa, ferma) di ogni asta salvata al caricamento.
- Aggiunto il `RadioButton` "Ricorda Stato" in `SettingsControl.xaml`.
- Gestita la nuova opzione in `MainWindow.EventHandlers.Settings.cs`.
- Aggiornata la logica di caricamento in `AuctionManagement.cs` per supportare "Ricorda Stato".
- Introdotto il salvataggio automatico dello stato delle aste in `ButtonHandlers.cs` e `Commands.cs`.
- Migliorati i log per riflettere il comportamento del sistema.
- Aggiunta la proprietà `RememberAuctionStates` in `SettingsManager` con valore predefinito `false`.
- Migliorata la leggibilità e manutenibilità del codice.
Queste modifiche migliorano la flessibilità e l'esperienza utente, garantendo coerenza dei dati e maggiore chiarezza nei log.
È stato aggiornato il layout del `Header` per passare da una struttura compatta su 2 righe a una su 3 righe.
- Aggiunta una nuova `RowDefinition` per gestire la terza riga.
- Modificato il `Padding` del `Border` da `15,10` a `15,8`.
- Aggiornata `Riga 1` per mostrare solo le `Puntate` con margine ridotto.
- Aggiunta `Riga 2` per visualizzare il `Credito Shop` con margini e font ridotti.
- Aggiornata `Riga 3` per mostrare solo le `Aste vinte da confermare`.
- Esteso lo `StackPanel` dei pulsanti di controllo per coprire tutte e 3 le righe.
- Migliorata la leggibilità dei commenti relativi agli indicatori di limite minimo.
- Aggiunto il pulsante "Rimuovi Tutte" in `AuctionMonitorControl.xaml` per eliminare tutte le aste monitorate.
- Implementato il metodo `RemoveAllButton_Click` in `AuctionMonitorControl.xaml.cs` e registrato il nuovo evento routed `RemoveAllClickedEvent`.
- Aggiunto il gestore `AuctionMonitor_RemoveAllClicked` in `MainWindow.ControlEvents.cs` e collegato l'evento in `MainWindow.xaml`.
- Migliorata la gestione degli errori e aggiunti messaggi di conferma dettagliati.
- Introdotti nuovi metodi di utilità per resettare le impostazioni, pulire la lista utenti e il log di un'asta selezionata.
- Rimosso codice obsoleto per semplificare la base di codice.
Introdotta la possibilità di configurare un limite massimo di puntate visualizzabili nella scheda "Storia Puntate" tramite l'interfaccia utente. La nuova proprietà `MaxBidHistoryEntries` è stata aggiunta alle impostazioni e salvata in modo persistente.
- Aggiunti controlli UI per configurare il limite.
- Implementata persistenza della lista `RecentBids` con serializzazione JSON.
- Introdotto il metodo `MergeBidHistory` per unire puntate evitando duplicati e mantenendo ordine cronologico decrescente.
- Sincronizzate le statistiche utenti (`BidderStats`) con la lista `RecentBids`.
- Ripristinata la proprietà `IsMyBid` al caricamento delle aste salvate.
- Ottimizzate le performance con `HashSet` per deduplicazione e limite configurabile.
- Creato il file `FIX_BID_HISTORY_PERSISTENCE.md` per documentare il problema e la soluzione.
- Garantita compatibilità retroattiva con aste salvate.
Questi aggiornamenti migliorano la gestione, la visualizzazione e la persistenza della storia delle puntate, offrendo un'esperienza utente più robusta e intuitiva.
Introdotta una nuova scheda "Storia Puntate" nel pannello
dell'asta selezionata, che mostra la cronologia delle ultime
puntate in tempo reale. La scheda utilizza un `TabControl`
con due `TabItem`: uno per gli utenti e uno per la storia
delle puntate.
- Creata la classe `BidHistoryEntry` per rappresentare una
singola puntata, con proprietà come `Price`, `BidType`,
`Timestamp`, e calcoli formattati.
- Aggiunte proprietà `RecentBids` in `AuctionInfo` e
`RecentBidsHistory` in `AuctionState` per gestire i dati
della cronologia.
- Modificato il parsing API in `BidooApiClient` per includere
la cronologia delle puntate.
- Aggiornato il monitor delle aste (`AuctionMonitor.cs`) per
sincronizzare i dati della cronologia con il backend.
- Aggiunta la proprietà `BidHistoryEntries` in
`AuctionViewModel` per il binding della griglia.
- Modificata la UI (`AuctionMonitorControl.xaml`) per
includere la nuova scheda e personalizzare gli stili.
- Aggiornata la logica di aggiornamento UI in
`MainWindow.xaml.cs` per gestire i dati della cronologia.
- Documentata la funzionalità in `FEATURE_BID_HISTORY_TAB.md`.
- Aggiunto uno screenshot (`Screenshot 2025-11-25 113552.png`).
Questa funzionalità migliora la trasparenza e fornisce agli
utenti informazioni dettagliate sulle attività recenti,
aiutandoli a prendere decisioni strategiche durante le aste.
- Introdotto il pre-caricamento di WebView2 per ridurre i tempi di attesa.
- Implementato il pattern TaskCompletionSource per attendere l'inizializzazione di WebView2 (timeout 60s).
- Centralizzata la logica di verifica e importazione automatica dei cookie.
- Mostrate istruzioni di login solo se necessario, migliorando l'UX.
- Risolti problemi di timeout e threading durante l'inizializzazione di WebView2.
- Puliti e ottimizzati i log per maggiore chiarezza.
- Rimossa la gestione manuale dei cookie, ora automatizzata.
Introdotto `SessionService` per centralizzare la gestione della
sessione utente, migliorando la separazione delle responsabilità
e la testabilità. Risolto il problema del caricamento del cookie
di autenticazione all'avvio e garantita la persistenza delle
checkbox di esportazione (`IncludeMetadata`, `RemoveAfterExport`,
`OverwriteExisting`).
Ottimizzata la gestione della barra degli indirizzi del browser
con aggiornamenti locali immediati. Applicato il pattern "Load ?
Modify ? Save" per il salvataggio delle impostazioni, migliorando
la simmetria e la leggibilità del codice. Logging centralizzato
e semplificato per eventi rilevanti.
Aggiornata la documentazione per riflettere i cambiamenti e
verificati i test per garantire il corretto funzionamento.
Implementato il calcolo del valore reale dei prodotti in asta,
includendo il prezzo "Compra Subito", spese di spedizione e
risparmio stimato. Aggiunta una nuova sezione "Info Prodotto"
nella UI per visualizzare i dettagli estratti e i calcoli.
- **AuctionMonitorControl.xaml**: Aggiunta sezione fissa per
mostrare informazioni prodotto e calcolo valore.
- **AuctionMonitorControl.xaml.cs**: Gestiti eventi per il
caricamento e aggiornamento delle informazioni prodotto.
- **MainWindow**: Integrati handler per il calcolo e refresh
delle informazioni prodotto.
- **AuctionInfo.cs**: Aggiunte proprietà per gestire prezzo
"Compra Subito", spese di spedizione e limiti di vincita.
- **ProductValueCalculator.cs**: Nuova utility per calcolare
il valore del prodotto e parsare informazioni dall'HTML.
- **AuctionViewModel.cs**: Binding per visualizzare risparmio,
costo totale e convenienza nella UI.
- **Documentazione**: Aggiornata con dettagli sull'algoritmo
di calcolo e layout UI.
Fix:
- Risolto problema di encoding UTF-8 per emoji nella UI.
- Migliorato parsing HTML per prezzi e limiti di vincita.
TODO:
- Testare parsing su più aste e gestire edge cases.
- Implementare caricamento automatico delle informazioni.
- Riorganizzati i pulsanti azione asta in layout 2x2:
* Aggiunti pulsanti per Browser Interno, Browser Esterno,
Copia URL ed Esporta (funzionalità in sviluppo).
* Migliorati stile, tooltip e colori per maggiore chiarezza.
- Aggiunti nuovi RoutedEvent e gestori per le azioni.
- Migliorata gestione errori per "Copia URL":
* Controllo asta selezionata e retry per clipboard occupato.
- Rimosse emoji non visualizzate per compatibilità universale.
- Arricchiti i log con messaggi dettagliati per ogni azione.
- Creata documentazione dettagliata delle modifiche e test.
- Migliorata compatibilità e robustezza generale.
- Introdotta una nuova sezione "Limiti Log" nell'interfaccia utente per configurare:
- Numero massimo di righe di log per asta (default: 500).
- Numero massimo di righe di log globale (default: 1000).
- Aggiunte proprietà in `SettingsManager` per salvare/caricare i limiti.
- Applicati i limiti al log globale e ai log delle aste:
- Log globale: rimozione automatica dei paragrafi più vecchi.
- Log per asta: ottimizzato `AddLog` con `RemoveRange` per migliorare le performance.
- Documentazione dettagliata in `FEATURE_CONFIGURABLE_LOG_LIMITS.md` e `FEATURE_LOG_MAX_LINES.md`.
- Migliorata la gestione della memoria, riducendo il rischio di rallentamenti o crash.
- Test e checklist definiti per verificare il corretto funzionamento.
- Implementato focus automatico sulla riga successiva dopo la
cancellazione di un'asta, con scrolling e reset focus.
- Utilizzo dei dati ufficiali del server per il conteggio
delle puntate residue e usate su asta, con fallback manuale.
- Corretto il parsing dei campi della risposta server
(campo 2: puntate residue, campo 5: puntate usate).
- Risolto il mancato aggiornamento immediato della UI
(colonna "Clicks" e banner "Puntate residue").
- Aggiunto logging dettagliato per il parsing della risposta
server e il debugging di eventuali problemi.
- Documentate le modifiche in file dedicati con scenari di
test e istruzioni per il troubleshooting.
La soluzione `AutoBidder.sln` è stata aggiornata per supportare
Visual Studio 18 (18.0.11217.181), sostituendo la versione
precedente (17.14.36511.14).
Il progetto "Template" (`Template.wapproj`) è stato rimosso
insieme a tutte le configurazioni di build e deploy associate
per le piattaforme Any CPU, ARM, ARM64, x64 e x86 in modalità
Debug e Release.
Le configurazioni di build per il progetto "AutoBidder" sono
state mantenute, ma alcune configurazioni di Release sono state
modificate per utilizzare `Any CPU` invece di configurazioni
specifiche per piattaforma.