Che cosa è Dattiloscritto e perché si dovrebbe usare al posto di JavaScript?[chiuso]

StackOverflow https://stackoverflow.com//questions/12694530

  •  12-12-2019
  •  | 
  •  

Domanda

Può descrivere ciò che il Dattiloscritto in lingua è?

Che cosa può fare che JavaScript o librerie disponibili non può fare, che mi avrebbe dato ragione a considerare?

È stato utile?

Soluzione

.

I originariamente ha scritto questa risposta quando il dattilografia era ancora Hot-off-the-presse. Cinque anni dopo, questa è una panoramica OK, ma guarda A La risposta di Lodewijk qui sotto per ulteriori profondità

Vista 1000FT ...

Destinazione è un superset di JavaScript che fornisce principalmente la digitazione statica, le classi e le interfacce opzionali. Uno dei grandi vantaggi è quello di consentire IDES di fornire un ambiente più ricco per individuare gli errori comuni mentre si digita il codice .

Per avere un'idea di ciò che intendo, guarda Video introduttivo di Microsoft sulla lingua.

Per un progetto JavaScript di grandi dimensioni, l'adozione di dattilvi potrebbe comportare un software più robusto, mentre è ancora distribuibile dove sarebbe eseguito un'applicazione JavaScript regolare.

È open source, ma si ottiene solo intelligente intellisense come digiti se si utilizza un IDE supportato. Inizialmente, questo era solo Visual Studio di Microsoft (notato anche nel post del blog da Miguel de Icaza ). In questi giorni, Altri IDES offrono anche il supporto di tipo dattiloscritto .

Ci sono altre tecnologie come questa?

C'è CoffeeScript , ma questo serve davvero uno scopo diverso. IMHO, CoffeeScript fornisce la leggibilità per gli esseri umani, ma da solo fornisce una leggibilità profonda per strumenti attraverso la sua digitazione statica opzionale (vedere questa post blog recente per un po 'più critica). C'è anche DART Ma questo è pieno su sostituzione per JavaScript (anche se può produrre codice JavaScript ) < / P >.

Esempio

Ad esempio, ecco alcuni dattiloscritti (puoi giocare con questo in Destinatari Playground )

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}  
.

Ed ecco il JavaScript produrrebbe

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
.

AVVISO Come il dattilga definisce il tipo di variabili membri e parametri del metodo di classe. Questo viene rimosso quando si traduce in JavaScript, ma utilizzato dall'IDE e dal compilatore per individuare gli errori, come passare un tipo numerico al costruttore.

È anche in grado di inferire i tipi che non sono dichiarati esplicitamente, ad esempio, determinerebbe il metodo greet() restituisce una stringa.

DEBUGGING DEBUSCRICT

Molti browser e IDES offrono un supporto di debug diretto attraverso Sourcemaps. Vedere questa domanda di overflow stack per maggiori dettagli: Debug del codice dattiloscritto con Visual Studio < / P >.

Vuoi saperne di più?

I originariamente ha scritto questa risposta quando il dattiloscritto era ancora hot-off-the-presse. Check out La risposta di Lodewijk a questa domanda per alcuni dettagli più attuali.

Altri suggerimenti

Dattiloscritto della relazione di JavaScript

Dattiloscritto è digitato un superset di JavaScript che compila in pianura JavaScript - typescriptlang.org.

JavaScript è un linguaggio di programmazione sviluppato da EMCA Comitato Tecnico 39, è un gruppo di persone composto da molti attori.TC39 è un comitato ospitato da ECMA:un'standard interni di organizzazione.JavaScript ha molte diverse implementazioni da molti fornitori diversi (ad es.Google, Microsoft, Oracle, etc.).L'obiettivo di JavaScript è la lingua franca del web.

Dattiloscritto è un superset del linguaggio JavaScript, che ha una sola compilatore open-source ed è sviluppato principalmente da un unico fornitore di:Microsoft.L'obiettivo del Dattiloscritto è quello di aiutare a catturare errori all'inizio attraverso un sistema di tipo e per rendere JavaScript per lo sviluppo di più efficienti.

Essenzialmente Dattiloscritto raggiunge i suoi obiettivi in tre modi:

  1. Supporto per le moderne funzioni JavaScript - Il linguaggio JavaScript (e non il runtime) è standardizzato mediante l' ECMAScript gli standard.Non tutti i browser e JavaScript runtime di supportare tutte le funzioni di tutti ECMAScript standard (vedi questo panoramica).Dattiloscritto permette l'utilizzo di molte delle ultime ECMAScript caratteristiche e li traduce per anziani ECMAScript obiettivi di vostra scelta (vedi elenco compilare obiettivi sotto il --target opzione del compilatore).Questo significa che si può tranquillamente utilizzare le nuove funzionalità, come i moduli, lambda, funzioni, classi, la diffusione dell'operatore e destrutturazione, pur rimanendo compatibile con i browser più vecchi e JavaScript runtime.

  2. Avanzato sistema di tipo - Il tipo di supporto non è parte di standard ECMAScript e probabilmente non saranno mai a causa della natura interpretata invece di natura compilata in JavaScript.Il tipo di sistema di Registrazione è incredibilmente ricca e comprende:interfacce, enumerazioni, di tipo ibrido, farmaci generici, unione e intersezione tipi di modificatori di accesso e molto di più.Il sito ufficiale del Dattiloscritto fornisce una panoramica di tali caratteristiche.Dattiloscritto tipo di sistema è in pari con la maggior parte degli altri linguaggi tipizzati e, in alcuni casi, probabilmente più potente.

  3. Strumenti per sviluppatori di supporto - Dattiloscritto del compilatore può essere eseguito come processo in background per supportare sia la compilazione incrementale e IDE integrazione, in modo che possa più facilmente navigare, di identificare i problemi, ispezionare possibilità e il refactoring del codice.

Dattiloscritto in relazione ad altri JavaScript targeting lingue

Dattiloscritto ha una filosofia unica rispetto ad altre lingue che la compilazione del JavaScript.Il codice JavaScript è valido Dattiloscritto codice;Dattiloscritto è un superset di JavaScript.Si può quasi rinominare il .js file .ts i file e iniziare a utilizzare Dattiloscritto (vedere "JavaScript interoperabilità" di seguito).Dattiloscritto file vengono compilati leggibile JavaScript, in modo che la migrazione sia possibile tornare indietro e comprensione compilato Dattiloscritto non è difficile a tutti.Dattiloscritto basa sui successi di JavaScript migliorando le sue debolezze.

Da un lato, sono a prova di futuro di strumenti che prendere moderni standard ECMAScript e compilare verso il basso per le vecchie versioni di JavaScript con Babele di essere il più popolare.D'altra parte, si dispone di lingue che possono totalmente diversi da JavaScript che obiettivo di JavaScript, come CoffeeScript, Clojure, Dardo, Olmo, Haxe, Scala.js e tutta una serie di più (vedi questo elenco).Queste lingue, anche se potrebbe essere migliore di dove JavaScript futuro potrebbe mai condurre, corrono un maggiore rischio di non trovare abbastanza adozione per il loro futuro deve essere garantita.Si potrebbe anche avere più difficoltà a trovare sviluppatori esperti per alcune di queste lingue, e quelli che si troveranno spesso può essere più entusiasta.Interoperabilità con JavaScript può anche essere un po ' più complicato, dal momento che sono lontano da quello che JavaScript è in realtà.

Dattiloscritto si trova tra questi due estremi, bilanciando così il rischio.Dattiloscritto non è una scelta azzardata da qualsiasi standard.Basta poco per abituarsi, se si ha familiarità con JavaScript, in quanto non è un linguaggio completamente diverso, ha un'ottima JavaScript supporto per l'interoperabilità e ha visto un sacco di adozione di recente.

Facoltativamente, la tipizzazione statica e tipo di inferenza

JavaScript è dinamicamente tipizzati.Questo significa che di JavaScript non so che tipo di una variabile, fino a quando in realtà è creata un'istanza a run-time.Questo significa anche che potrebbe essere troppo tardi.Dattiloscritto aggiunge il supporto per il tipo di JavaScript.I bug che sono causati da falsi presupposti di una variabile di un certo tipo può essere completamente debellata se si gioca bene le tue carte (come severo si digita il codice o se si digita il tuo codice è fino a voi).

Dattiloscritto, scrivere un po ' più facile e molto meno esplicito, da un utilizzo di tipo di inferenza.Per esempio: var x = "hello" in Macchina è la stessa var x : string = "hello".Il tipo è semplicemente dedotto dal suo utilizzo.Anche non esplicitamente tipo i tipi, ci sono ancora, per salvare dal fare qualcosa che altrimenti sarebbe risultato un errore di run-time.

Dattiloscritto, facoltativamente, è digitato per impostazione predefinita.Per esempio function divideByTwo(x) { return x / 2 } è una funzione valida in Macchina, che può essere chiamato con il qualsiasi tipo di parametro, anche se chiamando con una stringa, ovviamente, risultato in un runtime errore.Proprio come te in JavaScript.Questo funziona, perché quando nessun tipo è stato assegnato in modo esplicito e il tipo non può essere dedotta, come nel divideByTwo esempio, Dattiloscritto sarà implicitamente assegnare il tipo any.Questo significa che il divideByTwo funzione del tipo di firma diventa automaticamente function divideByTwo(x : any) : any.C'è un flag del compilatore per impedire questo comportamento: --noImplicitAny.L'attivazione di questo flag ti dà un maggiore grado di sicurezza, ma significa anche che si dovrà fare più di digitazione.

I tipi hanno un costo associato con loro.Prima di tutto, c'è una curva di apprendimento, e in secondo luogo di tutti, naturalmente, il costo è un po ' più di tempo per impostare una base di codice utilizzando in modo corretto la tipizzazione troppo.Nella mia esperienza, questi costi sono completamente la pena su alcuna seria base di codice sono in condivisione con gli altri. Uno Studio su Larga Scala di Linguaggi di Programmazione e della Qualità del Codice in Github suggerisce che "staticamente tipizzato lingue, in generale, sono meno difetti rispetto alla dinamica tipi, e che la tipizzazione forte è meglio di tipizzazione debole a proposito di questo".

È interessante notare che questa stessa carta rileva che il Dattiloscritto è meno soggetto a errori di JavaScript:

Per quelli con coefficienti positivi ci si può aspettare che la lingua è associato con, ceteris paribus, un numero maggiore di difetto di correzioni.Queste lingue sono C, C++, JavaScript, Objective-C, Php, e Python.Le lingue Clojure, Haskell, il Rubino, la Scala, e Dattiloscritto, tutti negativi i coefficienti che implica che queste lingue sono meno probabile che la media di risultato in difetto di fissaggio si impegna.

Migliorato il supporto IDE

L'esperienza di sviluppo con il Dattiloscritto è un grande miglioramento rispetto JavaScript.L'IDE è informato in tempo reale tramite il file Generato dal compilatore sua ricca tipo di informazioni.Questo dà un paio di importanti vantaggi.Per esempio, con Dattiloscritto, si può tranquillamente fare a rifattorizzazione come rinomina in tutta la codebase.Attraverso il completamento del codice, è possibile ottenere aiuto in linea, qualunque sia funzioni di una libreria può offrire.Non è più necessario ricordare loro o in riferimenti online.Gli errori di compilazione sono riportate direttamente nell'IDE con un rosso linea ondulata, mentre si è occupato di codifica.Tutto sommato, questo permette un notevole guadagno in termini di produttività rispetto a lavorare con JavaScript.Si può trascorrere più tempo di codifica e meno tempo di debug.

C'è una vasta gamma di Ide, che hanno un eccellente supporto per Dattiloscritto, come Visual Studio Codice, WebStorm, Atom e Sublime.

Rigorosi controlli nulli

Gli errori di Runtime del modulo cannot read property 'x' of undefined o undefined is not a function sono molto comunemente causato da un bug nel codice JavaScript.Out of the box Dattiloscritto già riduce la probabilità di questi tipi di errori che si verificano, perché non si può utilizzare una variabile che non è noto per il Dattiloscritto del compilatore (con l'eccezione di proprietà di any variabili tipizzate).È ancora possibile, anche se per errore utilizzare una variabile impostata a undefined.Tuttavia, con la versione 2.0 del Dattiloscritto è possibile eliminare questi tipi di errori tutti insieme attraverso l'uso di non-tipi nullable.Questo funziona come segue:

Con rigorosi controlli nulli abilitato (--strictNullChecks flag del compilatore) Dattiloscritto compilatore non consentire undefined per essere assegnato ad una variabile a meno che non si dichiara esplicitamente di essere di tipo nullable.Per esempio, let x : number = undefined si tradurrà in un errore di compilazione.Questo si sposa perfettamente con il tipo di teoria dal undefined non è un numero.Si può definire x per essere una somma tipo di number e undefined per correggere questo: let x : number | undefined = undefined.

Una volta che un tipo è noto per essere nullable, il che significa che è di un tipo che può anche essere di valore null o undefined, il Dattiloscritto compilatore è in grado di determinare, mediante il controllo del flusso di base tipo di analisi, se il codice può tranquillamente utilizzare una variabile o non.In altre parole, quando si verifica una variabile è undefined attraverso, ad esempio, un if dichiarazione Dattiloscritto compilatore dedurre che il tipo in quel ramo del codice di controllo del flusso non è più annullabile e quindi possono essere tranquillamente utilizzati.Ecco un semplice esempio:

let x: number | undefined;
if (x !== undefined) x += 1; // this line will compile, because x is checked.
x += 1; // this line will fail compilation, because x might be undefined.

Durante la compilazione, 2016 conferenza di co-progettazione del Dattiloscritto Anders Hejlsberg ha illustrato una dettagliata spiegazione e la dimostrazione di questa funzione: video (dal 44:30 a 56:30).

Compilazione

Per utilizzare la Macchina, è necessario un processo di compilazione per la compilazione del codice JavaScript.Il processo di costruzione in genere richiede solo un paio di secondi, a seconda, naturalmente, la dimensione del tuo progetto.Il Dattiloscritto del compilatore supporta la compilazione incrementale (--watch flag del compilatore) in modo che tutte le modifiche successive possono essere compilati a maggior velocità.

Il Dattiloscritto compilatore è in grado di inline fonte di informazioni mappa generato .js file o creare separato .i file di mappa.Fonte mappa informazioni possono essere utilizzate da debug di programmi come Chrome DevTools e altri IDE, di relazionarsi con le linee in JavaScript per quelli che li hanno generati nel Dattiloscritto.Questo rende possibile per voi per impostare i punti di interruzione e ispezionare le variabili durante l'esecuzione direttamente sul tuo Dattiloscritto codice.Fonte delle informazioni della mappa, funziona piuttosto bene, è stato intorno a lungo prima di Dattiloscritto, ma il debug Dattiloscritto in genere non è così grande come quando si utilizza JavaScript direttamente.Prendere l' this parola chiave per esempio.A causa dei cambiamenti nella semantica del this parola chiave intorno chiusure dal ES2015, this può effettivamente esistente durante la fase di esecuzione, come una variabile chiamata _this (vedere questa risposta).Questo può confondere, durante il debug, ma generalmente non è un problema se si sa su di esso o di ispezionare il codice JavaScript.Va notato che Babel subisce lo stesso tipo di problema.

Ci sono alcuni altri trucchi Dattiloscritto compilatore è in grado di fare, come la generazione di intercettare il codice in base decoratori, la generazione di codice per caricare il modulo per modulo diverso e sistemi di analisi JSX.Tuttavia, è probabile che richiedono un tool di build oltre il Dattiloscritto del compilatore.Per esempio, se si desidera comprimere il vostro codice sarà necessario aggiungere altri strumenti per il processo di generazione per farlo.

Ci sono Dattiloscritto di compilazione del plugin disponibili per Webpack, Gulp, Grunt e praticamente qualsiasi altro codice JavaScript tool di build là fuori.Il Dattiloscritto di documentazione ha una sezione su integrazione con strumenti di costruzione la copertura di tutti loro.Un linter è disponibile anche nel caso in cui si vuole ancora di più i tempi di compilazione di controllo.Ci sono anche un gran numero di semi di progetti che iniziare con Dattiloscritto in combinazione con un sacco di altre tecnologie come Angolare 2, Reagire, Ember, SystemJS, Webpack, Gulp, etc.

JavaScript interoperabilità

Dal Dattiloscritto è così strettamente legato a JavaScript ha una grande capacità di interoperabilità, ma un certo lavoro supplementare è richiesto per lavorare con librerie JavaScript nel Dattiloscritto. Dattiloscritto definizioni sono necessari in modo che il Dattiloscritto del compilatore capisce che le chiamate di funzione come _.groupBy o angular.copy o $.fadeOut non sono in realtà illegali dichiarazioni.Le definizioni di queste funzioni sono messi in .d.ts i file.

La forma più semplice, una definizione che può prendere è quello di consentire un identificatore per essere utilizzato in alcun modo.Per esempio, quando si utilizza Lodash, una singola riga del file di definizione declare var _ : any potrai chiamare in qualsiasi funzione che si desidera sul _, ma poi, naturalmente, si sono ancora in grado di fare errori: _.foobar() sarebbe un legale Dattiloscritto chiamata, ma è, ovviamente, illegale chiamata a run-time.Se si desidera che il corretto tipo di supporto e di completamento del codice, il file di definizione deve essere più precisa (vedi lodash definizioni per un esempio).

Npm moduli che sono pre-confezionati con le loro definizioni di tipo, sono automaticamente capito il Dattiloscritto del compilatore (vedere documentazione).Per qualsiasi altro semi-popolare libreria JavaScript che non dispone di un proprio definizioni fuori ci fosse qualcuno che ha già fatto le definizioni del tipo di disponibile attraverso un altro npm modulo.Questi moduli sono preceduti dal prefisso "@/ tipi" e provengono da un repository Github chiamato DefinitelyTyped.

C'è un avvertimento:le definizioni di tipo deve corrispondere alla versione della libreria che si sta utilizzando al momento dell'esecuzione.Se non, Dattiloscritto potrebbe non consentire che si chiama una funzione o di risoluzione del riferimento a una variabile che esiste o consentono di chiamare una funzione o un riferimento a una variabile che non esiste, semplicemente perché il tipo non corrisponde il run-time (a tempo di compilazione.Quindi, assicurarsi di caricare la versione giusta del tipo di definizioni per la giusta versione della libreria che si sta utilizzando.

Per essere onesti, c'è un leggero fastidio per questo e potrebbe essere uno dei motivi per non scegliere Dattiloscritto, ma invece andare per qualcosa come Babel, che non soffre di dover ottenere le definizioni di tipo a tutti.D'altra parte, se si sa cosa si sta facendo si può superare facilmente qualsiasi tipo di problemi causati da errata o mancante file di definizione.

La conversione da JavaScript a Dattiloscritto

Qualsiasi .js il file può essere rinominato per un .ts file e corse attraverso il Dattiloscritto del compilatore per ottenere sintatticamente stesso codice JavaScript di uscita (se è sintatticamente corretta, in primo luogo).Anche quando il Dattiloscritto del compilatore viene errori di compilazione sarà ancora produrre un .js file.Si può anche accettare .js come input i file con l' --allowJs la bandiera.Questo ti permette di iniziare con Dattiloscritto subito.Purtroppo, gli errori di compilazione sono suscettibili di verificarsi all'inizio.Bisogna ricordare che questi non sono la show-stopping errori può essere utilizzato con altri compilatori.

Gli errori di compilazione, si ottiene all'inizio, quando la conversione di un progetto JavaScript per un Dattiloscritto progetto sono inevitabili da Dattiloscritto della natura.Dattiloscritto controlli tutti codice per la validità e quindi ha bisogno di conoscere tutte le funzioni e le variabili utilizzate.Pertanto le definizioni del tipo di bisogno di essere a posto per tutti, altrimenti gli errori di compilazione sono tenuti a verificarsi.Come accennato nel precedente capitolo, per praticamente qualsiasi framework JavaScript ci sono .d.ts i file che possono essere facilmente acquistati con l'installazione di DefinitelyTyped pacchetti.Tuttavia, potrebbe essere che hai utilizzato qualche oscuro biblioteca per i quali non Dattiloscritto definizioni sono disponibili o che hai polyfilled un po ' di JavaScript primitive.In questo caso, è necessario fornire le definizioni di tipo di questi bit per gli errori di compilazione, a scomparire.Basta creare un .d.ts file in tsconfig.json è files matrice, in modo che si è sempre considerato il Dattiloscritto del compilatore.In esso dichiarare tali bit Dattiloscritto che non conosci, tipo any.Una volta che hai eliminato tutti gli errori che si possono introdurre gradualmente a digitare per quelle parti in base alle vostre esigenze.

Un lavoro di (ri)configurazione costruire pipeline sarà anche necessaria per ottenere un Dattiloscritto nel costruire la pipeline.Come accennato nel capitolo sulla compilation ci sono un sacco di risorse là fuori e vi incoraggio a cercare di semi di progetti che utilizzano la combinazione di strumenti che si desidera lavorare con.

Il più grande ostacolo è la curva di apprendimento.Vi incoraggio a giocare con un piccolo progetto in un primo momento.Guarda come funziona, come si costruisce, quali file si utilizza, come è configurato, come funziona nel vostro IDE, come è strutturato, quali strumenti usa, etc.La conversione di un grande JavaScript codebase per Dattiloscritto è fattibile quando si sa cosa si sta facendo.Leggere questo blog, per esempio, sul la conversione di 600k linee dattiloscritto in 72 ore).Basta assicurarsi di che avere una buona padronanza della lingua prima di fare il salto.

Adozione

Dattiloscritto è open-source (Apache 2 con licenza, vedere GitHub) e supportato da Microsoft. Anders Hejlsberg, il lead architect di C# è alla guida del progetto.È un progetto attivo;il Dattiloscritto di squadra è stato il rilascio di un sacco di nuove funzionalità, negli ultimi anni, e un sacco di quelli che sono ancora in programma di venire (vedi il tabella di marcia).

Alcuni fatti circa l'adozione e la popolarità di:

  • Nel 2017 StackOverflow sviluppatore sondaggio Dattiloscritto è stato il più popolare JavaScript transpiler (9 ° posto assoluto) e ha conquistato il terzo posto in più amati linguaggio di programmazione di categoria.
  • Nel 2018 stato di js sondaggio Dattiloscritto è stato dichiarato come uno dei due grandi vincitori in JavaScript e sapori di categoria (con ES6 è l'altro).
  • Nel 2019 StackOverlow deverloper sondaggio Dattiloscritto di rose per il 9 ° posto di lingue più popolari tra gli sviluppatori professionali, superando sia in C e C++.Prese nuovamente il terzo posto tra i più amati lingue.

Discusct fa qualcosa di simile a ciò che meno o sass fa per CSS.Sono super insertosi, il che significa che ogni codice JS che scrivi è valido codice dattiloscritto.Inoltre è possibile utilizzare gli altri Goodies che aggiunge alla lingua e il codice traspirato sarà valido JS.Puoi anche impostare la versione JS che vuoi il tuo codice risultante.

Attualmente Dypescript è un Super Set di ES2015, quindi potrebbe essere una buona scelta per iniziare a imparare le nuove funzionalità JS e traspilare allo standard necessario per il tuo progetto.

" dattiloscritto fondamentali " - Un videogioco plurialsight di Dan wahlin e John Papa è davvero buono, attualmente (25 marzo 2016) aggiornato per riflettere dattilografo 1.8, introduzione a dattiloscritto.

Per me le caratteristiche davvero buone, accanto alle belle possibilità per IntelliSense, sono le lezioni , interfacce , moduli , la facilità di implementazioneAMD, e la possibilità di utilizzare il DEBUGGER DI VISUAL STUDIO DEBUGCRICT quando è stato invocato con IE.

per riassumere : Se utilizzato come previsto, dattiloscritto può rendere la programmazione JavaScript più affidabile e più facile.Può aumentare significativamente la produttività del programmatore JavaScript sopra l'intero SDLC.

Script ECMA 5 (ES5) che tutto il supporto del browser e precompilato.ES6 / ES2015 ed ES / 2016 è arrivato quest'anno con un sacco di modifiche per far apparire questi cambiamenti, c'è qualcosa nel quale dovrebbe prendere cura di così dattire.

• Destinatari è tipi -> significa definire il tipo di dati di ciascuna proprietà e metodi.Se sai C #, allora i tuoi dattiloscritti è facile da capire.

• Big vantaggio del dattiloscritto è il tipo di identità I problemi relativi prima di andare alla produzione.Ciò consente ai test dell'unità di fallire se c'è qualche disallineamento di tipo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top