Angolare e dattiloscritto: impossibile trovare i nomi


221

Sto usando Angular (versione 2) con TypeScript (versione 1.6) e quando compilo il codice ottengo questi errori:

Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/change_detection/parser/locals.d.ts(4,42): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(1,25): Error TS2304: Cannot find name 'MapConstructor'.
    node_modules/angular2/src/core/facade/collection.d.ts(2,25): Error TS2304: Cannot find name 'SetConstructor'.
    node_modules/angular2/src/core/facade/collection.d.ts(4,27): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(4,39): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(7,9): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(8,30): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(11,43): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(12,27): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(14,23): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(15,25): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/collection.d.ts(94,41): Error TS2304: Cannot find name 'Set'.
    node_modules/angular2/src/core/facade/collection.d.ts(95,22): Error TS2304: Cannot find name 'Set'.
    node_modules/angular2/src/core/facade/collection.d.ts(96,25): Error TS2304: Cannot find name 'Set'.
    node_modules/angular2/src/core/facade/lang.d.ts(1,22): Error TS2304: Cannot find name 'BrowserNodeGlobal'.
    node_modules/angular2/src/core/facade/lang.d.ts(33,59): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/facade/promise.d.ts(1,10): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(3,14): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(8,32): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(9,38): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(10,35): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(10,93): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(11,34): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(12,32): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(12,149): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/facade/promise.d.ts(13,43): Error TS2304: Cannot find name 'Promise'.
    node_modules/angular2/src/core/linker/element_injector.d.ts(72,32): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/element_injector.d.ts(74,17): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/element_injector.d.ts(78,184): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/element_injector.d.ts(83,182): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/element_injector.d.ts(107,37): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/proto_view_factory.d.ts(27,146): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(52,144): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(76,79): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(77,73): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(94,31): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(97,18): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(100,24): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(103,142): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/linker/view.d.ts(104,160): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/render/api.d.ts(281,74): Error TS2304: Cannot find name 'Map'.
    node_modules/angular2/src/core/zone/ng_zone.d.ts(1,37): Error TS2304: Cannot find name 'Zone'.

Questo è il codice:

import 'reflect-metadata';
import {bootstrap, Component, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/core';
@Component({
  selector: 'my-app',
  template: '<input type="text" [(ng-model)]="title" /><h1>{{title}}</h1>',
  directives: [ CORE_DIRECTIVES ]
})
class AppComponent {
  title :string;

  constructor() {
    this.title = 'hello angular 2';
  }
}
bootstrap(AppComponent);

sembra che ci sia un problema qui github.com/angular/angular/issues/4902
rob

Prova ad aggiungere la seguente importazione import {ROUTER_PROVIDERS} from 'angular2/router';sto ricevendo lo stesso problema e per qualche motivo questo risolve il problema per me ...?!?
ruba il

Risposte:


52

Un problema noto: https://github.com/angular/angular/issues/4902

Motivo principale: il .d.tsfile incluso implicitamente da TypeScript varia in base al target di compilazione, quindi è necessario disporre di più dichiarazioni ambientali durante il targeting es5anche se le cose sono effettivamente presenti nei runtime (ad es. Chrome). Più sulib.d.ts


446
Quindi qual è la soluzione?
user233232

3
2.0.0-alpha.45 è buono, usa le digitazioni da node_modules / angular2 / bundles / typings / ** / *. D.ts
Are Butuv,

2
"angular2": "2.0.0-beta.3" funziona, ma beta.4 e beta.5 sembrano avere nuovamente questo problema, almeno quando si configura il progetto come nell'esercitazione
CorayThan

3
@Roj Lo sto ancora vedendo in beta 6 ma funziona quando si utilizza il riferimento a browser.d.ts
inki

3
evviva! rc1 si è unito a questo.
RoninCoder,

105

Esiste una soluzione alternativa menzionata nel registro delle modifiche per 2.0.0-beta.6 (11-02-2016) (elencata sotto le ultime modifiche):

Se usi --target = es5, dovrai aggiungere una linea da qualche parte nella tua applicazione (ad esempio, nella parte superiore del file .ts dove chiami bootstrap):

///<reference path="node_modules/angular2/typings/browser.d.ts"/>

(Nota che se il tuo file non si trova nella stessa directory di node_modules, dovrai aggiungere uno o più ../ all'inizio di quel percorso.)

assicurati di avere il percorso di riferimento corretto, avevo bisogno di aggiungere ../ all'inizio per farlo funzionare.


3
Ciò ha risolto molti errori per me, ma ho ancora errori come TS2304: Cannot find name 'module'e TS2339: Property 'find' does not exist on type 'MyThing[]'.... Qualche idea?
mwijnands,

1
Cosa succede se si utilizza angolare in un pacchetto destinato al riutilizzo? Qualsiasi applicazione provo ad usare un pacchetto con un file con questo riferimento si lamenta al momento della compilazione di tsc di non riuscire a trovare questo riferimento.
Hans

5
Esiste una soluzione per la nuova struttura del pacchetto in Angular, non riesco a trovare un browser.d.ts nella nuova struttura @angular / ....
I.devries

2
@ I.devries Corretto, hanno rimosso browser.d.ts. I file ora sono index.d.ts e ne hai bisogno per ogni componente angolare, poiché ciascuno è installato separatamente in rc.0 e versioni successive. Devi anche installare "digitazioni" - vedi le risposte di Khaled Al-Ansari e theUltraSide sopra.
Vern Jensen,

1
Ho risolto aggiungendo: /// <reference path = "../ typings / index.d.ts" />
Sako73

80

Le funzionalità di ES6 come le promesse non sono definite quando si sceglie ES5. Esistono altre librerie, ma core-js è la libreria javascript utilizzata dal team Angular. Contiene polifilloli per ES6.

Angular 2 è cambiato molto da quando è stata posta questa domanda. Le dichiarazioni di tipo sono molto più facili da usare in Typescript 2.0.

npm install -g typescript

Per le funzionalità ES6 in Angular 2, non è necessario digitare. Basta usare typescript 2.0 o versioni successive e installare @ types / core-js con npm:

npm install --save-dev @types/core-js

Quindi, aggiungi gli attributi TypeRoots e Tipi a tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "typeRoots": [
      "../node_modules/@types"
    ],
    "types" : [
      "core-js"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}

Questo è molto più semplice rispetto all'uso di Digitazioni, come spiegato in altre risposte. Vedere il post sul blog di Microsoft per ulteriori informazioni: Typescript: The Future of Declaration Files


1
Penso che anche l'array "types" appartenga all'oggetto "compilerOptions". Ma a parte questo, grazie mille, ho lottato con questo per tutto il giorno.
plesso,

@plexus Grazie! Hai ragione su compilerOptions. Ho risolto la risposta.
David Rinck,

Grazie per l'ottimo post, ma secondo l'URL che hai fornito non è nemmeno necessario aumentare tsconfig.json, funziona davvero comunque comunque :) Almeno lo ha fatto per me. Quindi l'unica cosa che devi fare è installare il pacchetto richiesto
Ilya Chernomordik,

Puoi anche rimuovere typeRootsse l'unica voce che hai è node_modules/@types.
Morgan Touverey Quilling,

A meraviglia. Come aveva detto @ ilya-chernomordik, questo ha funzionato anche per me senza l'aggiunta di TypeRootse Typessu tsconfig.json. Nel mio caso ho anche dovuto aggiornare il mio plug-in Gulp gulp-typescript 2.x che stava eseguendo la transpiling usando e la versione incorporata di TypeScript 1, ma una volta che ho aggiornato così stavo usando TypeScript 2 e ho aggiunto il polyfill @ types / core-js impostato. Grazie molto.
Scritto il

49

Per coloro che seguono il tutorial di Angular2 su angular.io solo per essere espliciti, ecco un'espansione della risposta di mvdluit di dove esattamente mettere il codice:

Il tuo main.tsdovrebbe assomigliare a questo:

/// <reference path="../node_modules/angular2/typings/browser.d.ts" />

import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'
// Add all operators to Observable
import 'rxjs/Rx'

bootstrap(AppComponent);

Si noti che si lasciano le ///barre in avanti, non rimuoverle.

rif: https://github.com/ericmdantas/angular2-typescript-todo/blob/master/index.ts#L1


Uso VS2015 MVC6 e Angular2 beta.14, se si inserisce la linea di riferimento in _references.jsessa non funzionerà. Deve essere all'interno del componente come suggerisce questa risposta. Inoltre, utilizzare ../../anziché ../per il percorso.
RoninCoder,

@Hani hai trovato un modo per evitarlo? Proverò l'aggiornamento a rc1 e lo proverò
Rots

Quindi le digitazioni sono sparite. Suppongo che dovrai installarlo separatamente e quando lo faccio, ottengo anche molti pacchetti inutili aggiunti. Comunque, anche dopo aver fatto tutto ciò, non c'è più browser.d.tssotto la cartella delle tipizzazioni. Solo .jsfile sotto dist. C'è un file chiamato typings.d.tscosì ho pensato che fosse quello nuovo, ma non ha risolto il problema. Costruire per 'es6' funziona, ma IE si lamenta. Così bloccato con la build 'es5' e senza digitare! : /
RoninCoder

@Hani C'è una nuova risposta. Forse funzionerà? npm install -g typings typings install
Rott

Eseguito il downgrade a beta.15 e utilizzato lo stesso .d.tsdal pacchetto di digitazioni. Anche per soddisfare i requisiti IE9 +, ho dovuto costruire per es3.
RoninCoder,

48

Sono stato in grado di risolvere questo problema con il seguente comando

typings install es6-promise es6-collections --ambient

Si noti che è necessario typingsfar funzionare il comando sopra, se non lo si esegue eseguire il comando seguente per installarlo

npm install -g typings

AGGIORNARE

l'aggiornamento delle digitazioni non legge --ambientè diventato --globalanche per alcune persone è necessario installare le definizioni delle librerie sopra, basta usare il seguente comando

typings install dt~es6-promise dt~es6-collections --global --save

Grazie a @bgerth per averlo segnalato.


9
Per me è statotypings install dt~es6-promise dt~es6-collections --global --save
bgerth il

1
@bgerth Suppongo sia cambiato a causa typingsdell'aggiornamento, aggiungerò la tua soluzione alla risposta
Khaled Al-Ansari

digitando install dt ~ es6-promise dt ~ es6-collections --global --save ha funzionato per me. Questo problema è ricorrente e intermittente ... grazie per questa correzione lascia sperare che funzioni più a lungo di un giorno.
Sam

typing install dt ~ es6-promise dt ~ es6-collections --global --save ha funzionato anche per me
Rikku121

33

Quando hai Typescript> = 2 l'opzione "lib" in tsconfig.json farà il lavoro. Non c'è bisogno di digitare. https://www.typescriptlang.org/docs/handbook/compiler-options.html

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["es2016", "dom"] //or es6 instead of es2016(es7)
    }
}

Sì ... aggiungendo "lib": ["es2016", "dom"] al mio file tsconfig.json è stato corretto
Marvel Moe

Questo è corretto. Basta usare cautela perché alcuni dei tipi ivi dichiarati potrebbero non essere presenti.
Aluan Haddad,

@Niels Steenbeek ha ragione qui. Ho riscontrato gli stessi errori durante gli esercizi per i corsi Angular 2 e 4. Tuttavia, i miei contenuti di lib erano leggermente diversi: "lib": ["es2015", "es2015.iterable", "dom"]
BoiseBaked

15

Per l' Angular 2.0.0-rc.0aggiunta node_modules/angular2/typings/browser.d.tsnon funzionerà. Per prima cosa aggiungi il file typings.json alla tua soluzione, con questo contenuto:

{
    "ambientDependencies": {
        "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd"
    }
}

E quindi aggiorna il package.jsonfile per includerlo postinstall:

"scripts": {
    "postinstall": "typings install"
},

Adesso corri npm install

Inoltre ora dovresti ignorare anche la typingscartella nel tuo tsconfig.jsonfile:

 "exclude": [
        "node_modules",
        "typings/main",
        "typings/main.d.ts"
    ]

Aggiornare

Ora AngularJS 2.0 sta usando core-jsal posto di es6-shim. Segui il suo file typings.json di avvio rapido per maggiori informazioni.


Si è verificato un problema con questo errore in rc0 github.com/angular/angular/issues/4902#issuecomment-216495769
ssuperczynski

15

puoi aggiungere il codice all'inizio dei file .ts.

/// <reference path="../typings/index.d.ts" />

Questo ha funzionato per me. Non è necessario installare digitazioni a livello globale. Provato su angolare stabile 2.
Gopinath Shiva,

Ha funzionato anche per me, usando Angular 2.0.0 (versione)
JoshuaDavid,

10

Lo stavo ottenendo su Angular 2 rc1. Risulta che alcuni nomi sono stati modificati con le digitazioni v1 rispetto al vecchio 0.x. I browser.d.tsfile sono diventatiindex.d.ts .

Dopo aver eseguito, typings installindividuare il file di avvio (dove si avvia bootstrap) e aggiungere:

/// <reference path="../typings/index.d.ts" /> (o senza il ../ se il file di avvio si trova nella stessa cartella della cartella delle tipizzazioni)

Aggiunta index.d.tsall'elenco dei file intsconfig.json non ha funzionato per qualche motivo.

Inoltre, il es6-shimpacchetto non era necessario.


7

Sono stato in grado di risolvere questo problema installando il typingsmodulo.

npm install -g typings
typings install

(Utilizzando ng 2.0.0-rc.1)


1
"File" typyings.json "mancante. - (Nessuna dipendenza)". Restituisce questo errore quando eseguo il comando nella stessa cartella del file app.ts. Dove dovrei trovare questo file typings.json e quando dovrei eseguire il comando?
Ulisse Alves,

7

Ho avuto lo stesso problema e l'ho risolto usando l' libopzione in tsconfig.json. Come detto da basarat nella sua risposta , un tipo di .d.tsfile è implicitamente incluso in TypeScript a seconda targetdell'opzione di compilazione , ma questo comportamento può essere modificato conlib opzione.

È possibile specificare ulteriori file di definizione da includere senza modificare la versione JS di destinazione. Ad esempio, questo fa parte del mio attuale compilerOptionsper Typescript@2.1 e aggiunge il supporto per le es2015funzionalità senza installare nient'altro:

"compilerOptions": {
    "experimentalDecorators": true,
    "lib": ["es5", "dom", "es6", "dom.iterable", "scripthost"],
    "module": "commonjs",
    "moduleResolution": "node",
    "noLib": false,
    "target": "es5",
    "types": ["node"]
}

Per l'elenco completo delle opzioni disponibili, consultare il documento ufficiale .

Nota anche che ho aggiunto "types": ["node"]e installato npm install @types/nodeper supportare il require('some-module')mio codice.


5
 typings install dt~es6-shim --save --global

e aggiungi il percorso corretto a index.d.ts

///<reference path="../typings/index.d.ts"/>

Ho provato @ angular-2.0.0-rc3


Questa soluzione funziona perfettamente quando abbiamo bisogno del file .d.ts in un progetto di libreria.
Robin Ding,

4

Se il problema persistenpm install -g typings typings install , eliminare le cartelle node_modules e typing prima di eseguire questo comando.


4

Questo è quello che pensa come tutti stanno cercando di fare qualcosa di diverso. Credo che questi sistemi siano ancora lontani dalla versione finale.

Nel mio caso, ho aggiornato da rc.0 a rc.5 questo errore è apparso.

Il mio problema era cambiare tsconfig.json.

{
    "compilerOptions": {
        "target": "es6", <-- It was es5
        "module": "system",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false,
        "outDir": "../wwwroot/app"
    },
    "compileOnSave": true,
    "exclude": [
        "../node_modules",
        "../typings/main"
    ]
}

1
Ciò ha risolto anche i miei problemi. Sembra che le versioni RC siano destinate a es6.
Inari,

Ora non stai più prendendo di mira ES5. Semmai, cambia "lib", no "target".
Aluan Haddad,

4

aggiungi typing.d.ts nella cartella principale dell'applicazione e lì dichiara la variabile che vuoi usare ogni volta

declare var System: any;
declare var require: any;

dopo averlo dichiarato in typing.d.ts, nell'applicazione non verrà visualizzato l'errore per request.


4

Sono nuovo di Angular ma per me la soluzione è stata trovata semplicemente importando Input. Non posso prendermi il merito per questo, l'ho trovato su un'altra scheda. Questa è una soluzione semplice se stai riscontrando lo stesso problema, ma se i tuoi problemi sono più complessi leggerei le cose sopra.

Mukesh :

devi importare input in questo modo nella parte superiore del componente figlio

import { Directive, Component, OnInit, Input } from '@angular/core';

3

Ho trovato questo documento molto utile sul sito Web di Angular 2. Finalmente mi ha permesso di far funzionare le cose correttamente, mentre le altre risposte qui, per installare le digitazioni, mi hanno fallito con vari errori. (Ma mi ha aiutato a guidarmi nella giusta direzione.)

Invece di includere es6-promise ed es6-collection, include core-js, che ha fatto il trucco per me ... nessun conflitto con le definizioni di core ts di Angular2. Inoltre, il documento ha spiegato come impostare tutto ciò in modo che accada automaticamente durante l'installazione di NPM e come modificare il file typings.json.


2

Angular 2 RC1 ha rinominato la node_modules/angular2directory innode_modules/angular .

Se stai usando un gulpfile per copiare i file in una directory di output probabilmente hai ancora node_modules/angular seduto lì che potrebbe essere raccolto dal compilatore e confondere l'inferno da solo.

Quindi (accuratamente) cancella ciò che hai in node_modulesquella è per le versioni beta, ed elimina anche tutte le vecchie digitazioni ed esegui nuovamente typings install.


o in alternativa ... lavora su altre cose per 4 mesi e attendi che la versione finale ricomincia da capo (che è quello che sto facendo)
Simon_Weaver

2

Bella telefonata, @VahidN, ho scoperto di aver bisogno

    "exclude": [
        "node_modules",
        "typings/main",
        "typings/main.d.ts"
    ]

Anche nel mio tsconfig, per fermare gli errori da es6-shimse stesso


2

Importa la seguente istruzione nel tuo file JS.

import 'rxjs/add/operator/map';

Sto rimandando l'aggiornamento di un progetto all'ultima versione, quindi aggiunto import './rxjs-extensions';al mio app.component.tscon il file rxjs-extensions dal tutorial angular2 (inclusa la tua linea suggerita) e sembra aver rimosso quegli errori.
James,

Potresti per favore essere più specifico. Quale file JS? quello compilato da Typescript? principale?
mm_

2

La risposta accettata non fornisce una soluzione praticabile, e la maggior parte delle altre suggerisce la soluzione "triple-slash" che non è più praticabile, poiché browser.d.tsè stata rimossa dagli ultimi RC di Angular2 e quindi non è più disponibile.

Consiglio vivamente di installare il typingsmodulo come suggerito da un paio di soluzioni qui, ma non è necessario farlo manualmente o globalmente - c'è un modo efficace per farlo solo per il tuo progetto e all'interno dell'interfaccia VS2015. Ecco cosa devi fare:

  • aggiungi typingsnel file package.json del progetto.
  • aggiungere un scriptblocco nel package.jsonfile per eseguire / aggiornaretypings dopo ogni azione NPM.
  • aggiungere un typings.jsonfile nella cartella principale del progetto contenente un riferimento a core-js(complessivamente meglio di es6-shimatm).

Questo è tutto.

Puoi anche dare un'occhiata a quest'altro thread SO e / o leggere questo post sul mio blog per ulteriori dettagli.


2

Stavo ricevendo questo errore dopo aver unito il mio ramo dev al mio ramo attuale. Ho impiegato un po 'di tempo per risolvere il problema. Come puoi vedere nell'immagine qui sotto, non c'è nessun problema nei codici.

inserisci qui la descrizione dell'immagine

Quindi l'unica soluzione che ha funzionato per me è che il riavvio del VSCode


0

Ora devi importarli manualmente.

import 'rxjs/add/operator/retry';
import 'rxjs/add/operator/timeout';
import 'rxjs/add/operator/delay';
import 'rxjs/add/operator/map';




this.http.post(url, JSON.stringify(json), {headers: headers, timeout: 1000})

         .retry(2)

         .timeout(10000, new Error('Time out.'))

         .delay(10)

         .map((res) => res.json())
        .subscribe(
          (data) => resolve(data.json()),
          (err) => reject(err)
        );

-3

Aggiorna tsconfig.json, cambia

"target": "es5"

per

"target": "es6"

Ciò potrebbe rendere l'output JavaScript incompatibile con i browser precedenti.
Tom Robinson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.