In Node.js, come posso "includere" le funzioni dagli altri miei file?


969

Diciamo che ho un file chiamato app.js. Abbastanza semplice:

var express = require('express');
var app = express.createServer();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.get('/', function(req, res){
  res.render('index', {locals: {
    title: 'NowJS + Express Example'
  }});
});

app.listen(8080);

E se avessi una funzione all'interno di "tools.js". Come li importerei da usare in apps.js?

O ... dovrei trasformare "strumenti" in un modulo e quindi richiederlo? << sembra difficile, preferisco fare l'importazione di base del file tools.js.


4
Ciò che mi ha sconcertato qui è stata la requirecreazione di una cartella nella stessa directory su Windows. Devi usare l'indirizzamento in stile unix: al ./mydirposto del semplice vecchio mydir.
Ben

1
Ho creato un modulo per importare script, esportare su file e includere il modulo dalla node_modulescartella esterna . npmjs.com/package/node-import Spero che possa aiutarti. Grazie!
Nanang Mahdaen El-Agung,

Risposte:


1416

Puoi richiedere qualsiasi file js, devi solo dichiarare ciò che vuoi esporre.

// tools.js
// ========
module.exports = {
  foo: function () {
    // whatever
  },
  bar: function () {
    // whatever
  }
};

var zemba = function () {
}

E nel tuo file dell'app:

// app.js
// ======
var tools = require('./tools');
console.log(typeof tools.foo); // => 'function'
console.log(typeof tools.bar); // => 'function'
console.log(typeof tools.zemba); // => undefined

101
+1 Ben fatto, limita anche il codice importato al suo spazio dei nomi. Dovrò prenderne nota per dopo.
Evan Plaice,

8
Mi chiedo se sia possibile importare script esterni. require("http://javascript-modules.googlecode.com/svn/functionChecker.js")non sembra importare correttamente il modulo. Esiste un altro modo per importare script esterni?
Anderson Green,

6
E se dovessi passare la variabile in funzione Come, bar: function (a, b) {// some code}
Nishutosh Sharma

5
Dato che stai esponendo le proprietà, userei export invece di module.exports. Per le esportazioni vs module.exports: stackoverflow.com/questions/5311334/...
Farm

4
come chiamare la funzione bar (), all'interno della funzione foo (), significa come accedere a una funzione con un'altra
pitu

303

Se, nonostante tutte le altre risposte, vuoi comunque includere tradizionalmente un file in un file sorgente node.js, puoi usare questo:

var fs = require('fs');

// file is included here:
eval(fs.readFileSync('tools.js')+'');
  • La concatenazione di stringhe vuota +''è necessaria per ottenere il contenuto del file come stringa e non come oggetto (è possibile utilizzare anche .toString()se si preferisce).
  • Eval () non può essere utilizzato all'interno di una funzione e deve essere chiamato all'interno dell'ambito globale, altrimenti nessuna funzione o variabile sarà accessibile (ovvero non è possibile creare una include()funzione di utilità o qualcosa del genere).

Si noti che nella maggior parte dei casi questa è una cattiva pratica e si dovrebbe invece scrivere un modulo . Tuttavia, ci sono rare situazioni in cui l'inquinamento del tuo contesto / spazio dei nomi locale è ciò che desideri davvero.

Aggiornamento 06-08-2015

Si noti inoltre che non funzionerà con "use strict";(quando ci si trova in "modalità rigorosa" ) perché le funzioni e le variabili definite nel file "importato" non sono accessibili dal codice che esegue l'importazione. La modalità rigorosa applica alcune regole definite dalle versioni più recenti dello standard linguistico. Questo potrebbe essere un altro motivo per evitare la soluzione qui descritta.


41
Fantastico, questo è utile per mettere velocemente libs JS progettate per il lato client in un'app node.js senza la necessità di mantenere un fork in stile Node.
Kos,

18
Ho appena risposto alla domanda originale, che riguarda l'inclusione del codice, non la scrittura di moduli. Il primo può avere vantaggi in determinate situazioni. Inoltre, la tua supposizione su un requisito è sbagliata: il codice è certamente valutato, ma rimane nel suo spazio dei nomi e non ha modo di "inquinare" lo spazio dei nomi del contesto chiamante, quindi è necessario valutarlo () da solo. Nella maggior parte dei casi l'uso del metodo descritto nella mia risposta è una cattiva pratica, ma non sono io che dovrei decidere se è per TIMEX.
Udo G,

14
@EvanPlaice: hai un suggerimento migliore che risponde effettivamente alla domanda ? Se devi includere un file che non è un modulo , hai un approccio migliore di questo?
jalf

8
A volte ci sono quando è necessario includere, e talvolta richiedono, sono due concetti fondamentalmente diversi nella maggior parte dei linguaggi di programmazione, anche Node JS. La capacità di includere js sul posto dovrebbe essere una parte di Node per essere onesti, ma valutare è essenzialmente una soluzione decente. Upvoted.
J. Martin,

4
Si noti che è incompatibile con use strict - in quanto use strict limiterà l'uso di eval bloccando l'introduzione di nuove variabili tramite eval, ecc.
timbo,

189

Non sono necessarie nuove funzioni né nuovi moduli. Devi semplicemente eseguire il modulo che stai chiamando se non vuoi usare lo spazio dei nomi.

in tools.js

module.exports = function() { 
    this.sum = function(a,b) { return a+b };
    this.multiply = function(a,b) { return a*b };
    //etc
}

in app.js

o in qualsiasi altro .js come myController.js:

invece di

var tools = require('tools.js') che ci costringe a usare uno spazio dei nomi e a chiamare strumenti come tools.sum(1,2);

possiamo semplicemente chiamare

require('tools.js')();

e poi

sum(1,2);

nel mio caso ho un file con controller ctrls.js

module.exports = function() {
    this.Categories = require('categories.js');
}

e posso usare Categoriesin ogni contesto come classe pubblica doporequire('ctrls.js')()


12
In che modo questo non ha più +1? Questa è una vera soluzione a ciò che pone la domanda (anche se non quella "ufficiale"). È anche un milione di volte più facile da eseguire il debug di eval () perché il nodo può fornire un utile stack di chiamate invece che punta al file effettivo anziché non definito.
user3413723,

5
Si noti che non è possibile "utilizzare la modalità 'rigorosa" nel modulo importato.
David,

1
@Nick Panov: geniale! Vale la pena notare che questo funziona perché thisin una funzione è l' ambito globale quando la funzione viene chiamata direttamente (non associata in alcun modo).
Udo G

3
questo mi ha appena cambiato la vita, non è uno scherzo - aveva un file di 1000+ righe che non potevo separare perché le variabili di metodi diversi sono tutte interconnesse e avrebbero bisogno che i requisiti siano tutti nello stesso ambito ... require('blah.js')();dovrebbe mi permetta di importarli tutti nello stesso ambito !!! Grazie!!!
Sam Johnson,

2
Questo è un ottimo consiglio! Avvertenza: se si dichiara la funzione module.exports utilizzando la sintassi di scelta rapida () => {} anziché la dichiarazione di funzione standard () {}, ha esito negativo. Mi ci è voluta un'ora per capire dov'era il problema! (Le funzioni Arrow non hanno la loro proprietà 'this': developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Ryan Griggs,

117

Crea due file js

// File cal.js
module.exports = {
    sum: function(a,b) {
        return a+b
    },
    multiply: function(a,b) {
        return a*b
    }
};

File js principale

// File app.js
var tools = require("./cal.js");
var value = tools.sum(10,20);
console.log("Value: "+value);

Uscita console

Value: 30

Quale versione di js funziona?
Mirv - Matt

39

Ecco una spiegazione semplice e chiara:

Contenuto Server.js:

// Include the public functions from 'helpers.js'
var helpers = require('./helpers');

// Let's assume this is the data which comes from the database or somewhere else
var databaseName = 'Walter';
var databaseSurname = 'Heisenberg';

// Use the function from 'helpers.js' in the main file, which is server.js
var fullname = helpers.concatenateNames(databaseName, databaseSurname);

Contenuto di Helpers.js:

// 'module.exports' is a node.JS specific feature, it does not work with regular JavaScript
module.exports = 
{
  // This is the function which will be called in the main file, which is server.js
  // The parameters 'name' and 'surname' will be provided inside the function
  // when the function is called in the main file.
  // Example: concatenameNames('John,'Doe');
  concatenateNames: function (name, surname) 
  {
     var wholeName = name + " " + surname;

     return wholeName;
  },

  sampleFunctionTwo: function () 
  {

  }
};

// Private variables and functions which will not be accessible outside this file
var privateFunction = function () 
{
};

34

Stavo anche cercando una funzione 'include' di NodeJS e ho verificato la soluzione proposta da Udo G - vedi messaggio https://stackoverflow.com/a/8744519/2979590 . Il suo codice non funziona con i miei file JS inclusi. Alla fine ho risolto il problema in questo modo:

var fs = require("fs");

function read(f) {
  return fs.readFileSync(f).toString();
}
function include(f) {
  eval.apply(global, [read(f)]);
}

include('somefile_with_some_declarations.js');

Certo, questo aiuta.


2
Capisco quanto sia brutto questo hack, ma sicuramente mi ha aiutato.
Lindhe

30

creare due file ad es. app.jsetools.js

app.js

const tools= require("./tools.js")


var x = tools.add(4,2) ;

var y = tools.subtract(4,2);


console.log(x);
console.log(y);

tools.js

 const add = function(x, y){
        return x+y;
    }
 const subtract = function(x, y){
            return x-y;
    }

    module.exports ={
        add,subtract
    }

produzione

6
2

26

dire che vuole chiamare la funzione ping () e aggiungi (30,20) , che è in lib.js file da main.js

main.js

lib = require("./lib.js")

output = lib.ping();
console.log(output);

//Passing Parameters
console.log("Sum of A and B = " + lib.add(20,30))

lib.js

this.ping=function ()
{
    return  "Ping Success"
}
//Functions with parameters
this.add=function(a,b)
    {
        return a+b
    }

1
Funziona, ma non dovremmo usare la sintassi dei moduli quando includiamo gli script?
Kokodoko,

25

Il modulo vm in Node.js offre la possibilità di eseguire il codice JavaScript nel contesto corrente (incluso l'oggetto globale). Vedi http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

Si noti che, ad oggi, c'è un bug nel modulo vm che impedisce a runInThisContext di fare il giusto quando viene invocato da un nuovo contesto. Ciò importa solo se il tuo programma principale esegue il codice in un nuovo contesto e quindi quel codice chiama runInThisContext. Vedi https://github.com/joyent/node/issues/898

Purtroppo, l'approccio with (globale) che Fernando ha suggerito non funziona per funzioni con nome come "function foo () {}"

In breve, ecco una funzione include () che funziona per me:

function include(path) {
    var code = fs.readFileSync(path, 'utf-8');
    vm.runInThisContext(code, path);
}

Ho trovato vm.runInThisContext in un'altra risposta SO e l'avevo usato per includere file di codice Javascript "vanilla". Quindi, tuttavia, ho provato ad usarlo per includere il codice che dipendeva dalla funzionalità del nodo (ad esempio "var fs = require ('fs')"), e non avrebbe funzionato. In tal caso, tuttavia, le soluzioni "eval" indicate in un paio di risposte funzionano davvero.
Dexygen,

Ripensandoci un po 'di più, quando inizi a includere il codice che dipende dalla funzionalità del nodo, è probabilmente il momento di scrivere un modulo, anche se la soluzione eval potrebbe essere il primo passo in questo processo
Dexygen

Solo uno che ha funzionato in node.js nel 2019
meesern

13

Udo G. ha detto:

  • Eval () non può essere utilizzato all'interno di una funzione e deve essere chiamato all'interno dell'ambito globale, altrimenti nessuna funzione o variabile sarà accessibile (ovvero non è possibile creare una funzione di utilità include () o qualcosa del genere).

Ha ragione, ma c'è un modo per influenzare l'ambito globale da una funzione. Migliorare il suo esempio:

function include(file_) {
    with (global) {
        eval(fs.readFileSync(file_) + '');
    };
};

include('somefile_with_some_declarations.js');

// the declarations are now accessible here.

Spero che aiuti.


12

Ha funzionato con me come il seguente ...

Lib1.js

//Any other private code here 

// Code you want to export
exports.function1 = function(params) {.......};
exports.function2 = function(params) {.......};

// Again any private code

ora nel file Main.js devi includere Lib1.js

var mylib = requires('lib1.js');
mylib.function1(params);
mylib.function2(params);

Ricordarsi di inserire Lib1.js nella cartella node_modules .


11

Puoi mettere le tue funzioni in variabili globali, ma è meglio trasformare il tuo script di strumenti in un modulo. Non è davvero troppo difficile: basta collegare l'API pubblica exportsall'oggetto. Dai un'occhiata al modulo sulle esportazioni di Node.js per ulteriori dettagli.


1
Un esempio è migliore di un collegamento
tno2007,

11

Un altro modo di fare questo secondo me, è quello di eseguire tutto nel file lib quando chiamate la funzione request () usando (function (/ * things here * /) {}) (); fare questo renderà tutte queste funzioni portata globale, esattamente come la soluzione eval ()

src / lib.js

(function () {
    funcOne = function() {
            console.log('mlt funcOne here');
    }

    funcThree = function(firstName) {
            console.log(firstName, 'calls funcThree here');
    }

    name = "Mulatinho";
    myobject = {
            title: 'Node.JS is cool',
            funcFour: function() {
                    return console.log('internal funcFour() called here');
            }
    }
})();

E poi nel tuo codice principale puoi chiamare le tue funzioni per nome come:

main.js

require('./src/lib')
funcOne();
funcThree('Alex');
console.log(name);
console.log(myobject);
console.log(myobject.funcFour());

Produrrà questo output

bash-3.2$ node -v
v7.2.1
bash-3.2$ node main.js 
mlt funcOne here
Alex calls funcThree here
Mulatinho
{ title: 'Node.JS is cool', funcFour: [Function: funcFour] }
internal funcFour() called here
undefined

Fai attenzione a undefined quando chiami my object.funcFour () , sarà lo stesso se carichi con eval () . Spero che sia d'aiuto :)


10

Voglio solo aggiungere, nel caso in cui siano necessarie solo alcune funzioni importate da tools.js , quindi è possibile utilizzare un compito di destrutturazione supportato in node.js dalla versione 6.4 - vedere node.green .


Esempio : (entrambi i file si trovano nella stessa cartella)

tools.js

module.exports = {
    sum: function(a,b) {
        return a + b;
    },
    isEven: function(a) {
        return a % 2 == 0;
    }
};

main.js

const { isEven } = require('./tools.js');

console.log(isEven(10));

produzione: true


Questo evita anche di assegnare quelle funzioni come proprietà di un altro oggetto come nel caso nella seguente assegnazione (comune):

const tools = require('./tools.js');

dove devi chiamare tools.isEven(10).


NOTA:

Non dimenticare di aggiungere il prefisso al nome del file con il percorso corretto, anche se entrambi i file si trovano nella stessa cartella, devi aggiungere il prefisso con ./

Dai documenti Node.js :

Senza un '/', './' iniziale o '../' per indicare un file, il modulo deve essere un modulo principale o essere caricato da una cartella node_modules.


10

app.js

let { func_name } = require('path_to_tools.js');
func_name();    //function calling

tools.js

let func_name = function() {
    ...
    //function body
    ...
};

module.exports = { func_name };

3

Includi il file ed eseguilo in un determinato contesto (non globale)

fileToInclude.js

define({
    "data": "XYZ"
});

main.js

var fs = require("fs");
var vm = require("vm");

function include(path, context) {
    var code = fs.readFileSync(path, 'utf-8');
    vm.runInContext(code, vm.createContext(context));
}


// Include file

var customContext = {
    "define": function (data) {
        console.log(data);
    }
};
include('./fileToInclude.js', customContext);

2

Questo è il modo migliore che ho creato finora.

var fs = require('fs'),
    includedFiles_ = {};

global.include = function (fileName) {
  var sys = require('sys');
  sys.puts('Loading file: ' + fileName);
  var ev = require(fileName);
  for (var prop in ev) {
    global[prop] = ev[prop];
  }
  includedFiles_[fileName] = true;
};

global.includeOnce = function (fileName) {
  if (!includedFiles_[fileName]) {
    include(fileName);
  }
};

global.includeFolderOnce = function (folder) {
  var file, fileName,
      sys = require('sys'),
      files = fs.readdirSync(folder);

  var getFileName = function(str) {
        var splited = str.split('.');
        splited.pop();
        return splited.join('.');
      },
      getExtension = function(str) {
        var splited = str.split('.');
        return splited[splited.length - 1];
      };

  for (var i = 0; i < files.length; i++) {
    file = files[i];
    if (getExtension(file) === 'js') {
      fileName = getFileName(file);
      try {
        includeOnce(folder + '/' + file);
      } catch (err) {
        // if (ext.vars) {
        //   console.log(ext.vars.dump(err));
        // } else {
        sys.puts(err);
        // }
      }
    }
  }
};

includeFolderOnce('./extensions');
includeOnce('./bin/Lara.js');

var lara = new Lara();

Hai ancora bisogno di informare cosa vuoi esportare

includeOnce('./bin/WebServer.js');

function Lara() {
  this.webServer = new WebServer();
  this.webServer.start();
}

Lara.prototype.webServer = null;

module.exports.Lara = Lara;

2

Come se avessi un file abc.txte molti altri?

Crea 2 file: fileread.jse fetchingfile.jspoi fileread.jsscrivi questo codice:

function fileread(filename) {
    var contents= fs.readFileSync(filename);
        return contents;
    }

    var fs = require("fs");  // file system

    //var data = fileread("abc.txt");
    module.exports.fileread = fileread;
    //data.say();
    //console.log(data.toString());
}

In fetchingfile.jsscrivere questo codice:

function myerror(){
    console.log("Hey need some help");
    console.log("type file=abc.txt");
}

var ags = require("minimist")(process.argv.slice(2), { string: "file" });
if(ags.help || !ags.file) {
    myerror();
    process.exit(1);
}
var hello = require("./fileread.js");
var data = hello.fileread(ags.file);  // importing module here 
console.log(data.toString());

Ora, in un terminale: $ node fetchingfile.js --file = abc.txt

Stai passando il nome del file come argomento, inoltre includi tutti i file readfile.jsinvece di passarlo.

Grazie


2

Puoi semplicemente require('./filename').

Per esempio.

// file: index.js
var express = require('express');
var app = express();
var child = require('./child');
app.use('/child', child);
app.get('/', function (req, res) {
  res.send('parent');
});
app.listen(process.env.PORT, function () {
  console.log('Example app listening on port '+process.env.PORT+'!');
});
// file: child.js
var express = require('express'),
child = express.Router();
console.log('child');
child.get('/child', function(req, res){
  res.send('Child2');
});
child.get('/', function(req, res){
  res.send('Child');
});

module.exports = child;

Si prega di notare che:

  1. non è possibile ascoltare PORT sul file figlio, solo il modulo express parent ha listener PORT
  2. Il bambino sta usando 'Router', non il genitore Express moudle.

1

Stavo anche cercando un'opzione per includere il codice senza scrivere moduli, resp. usare le stesse fonti autonome testate da un progetto diverso per un servizio Node.js e la risposta di jmparatte l'ha fatto per me.

Il vantaggio è che non inquini lo spazio dei nomi, non ho problemi con "use strict";e funziona bene.

Ecco un esempio completo :

Script da caricare - /lib/foo.js

"use strict";

(function(){

    var Foo = function(e){
        this.foo = e;
    }

    Foo.prototype.x = 1;

    return Foo;

}())

SampleModule - index.js

"use strict";

const fs = require('fs');
const path = require('path');

var SampleModule = module.exports = {

    instAFoo: function(){
        var Foo = eval.apply(
            this, [fs.readFileSync(path.join(__dirname, '/lib/foo.js')).toString()]
        );
        var instance = new Foo('bar');
        console.log(instance.foo); // 'bar'
        console.log(instance.x); // '1'
    }

}

Spero che questo sia stato utile in qualche modo.


1

Un altro metodo quando si utilizza il framework node.js e express.js

var f1 = function(){
   console.log("f1");
}
var f2 = function(){
   console.log("f2");
}

module.exports = {
   f1 : f1,
   f2 : f2
}

memorizzalo in un file js chiamato s e nella statica della cartella

Ora per usare la funzione

var s = require('../statics/s');
s.f1();
s.f2();

1

Ho escogitato un metodo piuttosto rozzo per gestirlo per il modello HTML. Analogamente a PHP<?php include("navigation.html"); ?>

server.js

var fs = require('fs');

String.prototype.filter = function(search,replace){
    var regex = new RegExp("{{" + search.toUpperCase() + "}}","ig");
    return this.replace(regex,replace);
}

var navigation = fs.readFileSync(__dirname + "/parts/navigation.html");

function preProcessPage(html){
    return html.filter("nav",navigation);
}

var express = require('express');
var app = express();
// Keep your server directory safe.
app.use(express.static(__dirname + '/public/'));
// Sorta a server-side .htaccess call I suppose.
app.get("/page_name/",function(req,res){
    var html = fs.readFileSync(__dirname + "/pages/page_name.html");
    res.send(preProcessPage(html));
});

page_name.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>NodeJS Templated Page</title>
    <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css">
    <!-- Scripts Load After Page -->
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/tether.min.js"></script>
    <script type="text/javascript" src="/js/bootstrap.min.js"></script>
</head>
<body>
    {{NAV}}
    <!-- Page Specific Content Below Here-->
</body>
</html>

navigation.html

<nav></nav>

Risultato della pagina caricata

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>NodeJS Templated Page</title>
    <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css">
    <!-- Scripts Load After Page -->
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/tether.min.js"></script>
    <script type="text/javascript" src="/js/bootstrap.min.js"></script>
</head>
<body>
    <nav></nav>
    <!-- Page Specific Content Below Here-->
</body>
</html>

0

Se desideri sfruttare più CPU e architettura Microservice, per velocizzare le cose ... Usa RPC su processi a forcella.

Sembra complesso, ma è semplice se si utilizza il polpo .

Ecco un esempio:

su tools.js aggiungi:

const octopus = require('octopus');
var rpc = new octopus('tools:tool1');

rpc.over(process, 'processRemote');

var sum = rpc.command('sum'); // This is the example tool.js function to make available in app.js

sum.provide(function (data) { // This is the function body
    return data.a + data.b;
});

su app.js, aggiungi:

const { fork } = require('child_process');
const octopus = require('octopus');
const toolprocess = fork('tools.js');

var rpc = new octopus('parent:parent1');
rpc.over(toolprocess, 'processRemote');

var sum = rpc.command('sum');

// Calling the tool.js sum function from app.js
sum.call('tools:*', {
    a:2, 
    b:3
})
.then((res)=>console.log('response : ',rpc.parseResponses(res)[0].response));

divulgazione - Sono l'autore di polpo, e costruito per un mio caso simile, dal momento che non sono riuscito a trovare librerie leggere.


0

Per trasformare "strumenti" in un modulo, non vedo affatto difficile. Nonostante tutte le altre risposte, consiglierei comunque l'uso di module.exports:

//util.js
module.exports = {
   myFunction: function () {
   // your logic in here
   let message = "I am message from myFunction";
   return message; 
  }
}

Ora dobbiamo assegnare queste esportazioni all'ambito globale (nella tua app | index | server.js)

var util = require('./util');

Ora puoi fare riferimento e chiamare la funzione come:

//util.myFunction();
console.log(util.myFunction()); // prints in console :I am message from myFunction 

-3

Uso:

var mymodule = require("./tools.js")

app.js:

module.exports.<your function> = function () {
    <what should the function do>
}

1
Non dovresti quasi mai usare una directory completa. Dovresti considerare l'utilizzo di percorsi relativi come:./tools.js
Matthew D Auld
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.