Giter Club home page Giter Club logo

understand_nodejs's Introduction

Node Js Working

image

------Node Js Components -------

  • V8 :
  • We have V8 engine which helps to execute Javascript file , It is present in Chrome browser and is fast
  • V8 is made up of C++ and JS
  • UVlib :
  • This library that implements Event Loops and Thread pool

------Components of Node Process----

  • Main thread : non CPU intensive work is evecuted on this thread
  • Thread pool : consisting of 4 threads by default
  • These threads are used by CPU intensive works
  • CPU intensive works are Hashing , Encryption , Crypto related
  • Number of threads can be controlled by "process.env.UV_THREADPOOL_SIZE"

------Inside Node Process----

  • Top Level code line console.log() , const a = 10 re run
  • Require Modules are then run
  • Event callbacks are registered like SetTimeout , SetImmediate , IO Polling (reading file / writing file)
  • Then Event Loop Starts

------Inside Event Loop----

  • First Expired setTimeouts are run
  • then IO polling runs
  • then setImmediate callbacks run
  • then close callbacks run
  • event loop checks is there any pending function left
  • If yes then it executes them else it exits

Code 1

const fs = require('fs');
setTimeout(()=>console.log("Hi from SetTimeout 1"), 0)
console.log("Hello from Top Level code")

Output

  • First top level funcations run

  • const fs = require('fs');

  • console.log("Hello from Top Level code")

  • Then Callbacks run as event loops start

  • setTimeout(()=>console.log("Hi from SetTimeout 1"), 0)

  • above is an expired timer call back so it will get executed

    image


Code 2

const fs = require('fs');
setImmediate(()=>console.log("Hey setImmediate function here"))
setTimeout(()=>console.log("Hi from SetTimeout 1"), 0)
console.log("Hello from Top Level code")

Output

  • Top level

  • Set Timeout functions

  • Set Immediate functions

    image


Code 3

const fs = require('fs');
setImmediate(()=>console.log("Hey setImmediate function here"))
setTimeout(()=>console.log("Hi from SetTimeout 1"), 0)

Output

  • we removed console.log()
  • so the output is like this

image

  • here setImmediate is run first but it should run after setTimeout acording to the architecture

  • Why ?

  • As setImmediate is not within an IO polling so which code runs is non deterministic as it is bounded by performance of the process

image

Code 3.0

const fs = require('fs');
setTimeout(()=>console.log("Hi from SetTimeout 1"), 0)
setImmediate(()=>console.log("Hey setImmediate function here"))

Output

  • In this case set Timeout is run first and then set immediate
  • So by comparing two codes we can see that it is non deterministic to tell which function will run first
  • Sequence is Non Deterministic

image

Code 4

const fs = require('fs');
const { red, blue, green, yellow } = require('colorette');
setTimeout(()=>console.log(green("Hi from SetTimeout 1") ), 0)
setImmediate(()=>console.log(blue("Hey setImmediate function here")))
fs.readFile('sample.txt','utf-8' , ()=>{
    console.log(yellow("IO Polling Finished"))
})

Output

  • Top level executed first
  • Expired timers will run so setTimeout will run
  • If reading file will take time then
  • Execution will move to set Immediate callbacks
  • But in my case reading file is not extensive so IO polling printed
  • At last set Immediate will run
  • Done

image

Code 5

const fs = require('fs');
const { red, blue, green, yellow ,magenta , cyan} = require('colorette');
setTimeout(()=>console.log(green("Hi from SetTimeout 1") ), 0)
setImmediate(()=>console.log(blue("Hey setImmediate function here")))
fs.readFile('sample.txt','utf-8' , ()=>{
    console.log(yellow("IO Polling Finished"))
    setTimeout(()=> console.log(magenta("Hi from SetTimeout 2 inside Readfile")))
    setTimeout(()=> console.log(cyan("Hi from SetTimeout 3 inside Readfile")),5*1000)
})
console.log(red("Hi Top Level Code"))

Output

  • Top level code first evecutes
  • setTimeout , setImmediate , fs readfile are registered not run
  • Now Event loop runs
  • so first expired timers will run i.e. setTimeOut1
  • then IO polling will run so inside that we have console which will run
  • but it also has setTime outs so event loop will start again
  • but as readFile completion is not done yet and is taking time so immediate function will run
  • then the two setTimeouts are run
  • Done

image

Code 6

const fs = require("fs");
const { red, blue, green, yellow, magenta, cyan } = require("colorette");
setTimeout(() => console.log(green("Hi from SetTimeout 1")), 0);
setImmediate(() => console.log(blue("Hey setImmediate function here")));
setTimeout(() => {
  fs.readFile("sample.txt", "utf-8", () => {
    console.log(yellow("IO Polling Finished"));

    // Set timer for 2 seconds after reading file
    setTimeout(() => {
      console.log(magenta("Hi from SetTimeout 2 inside Readfile"));
    }, 2000);

    // Set timer for 5 seconds after reading file
    setTimeout(() => {
      console.log(cyan("Hi from SetTimeout 3 inside Readfile"));
    }, 5000);
  });
}, 3000);
console.log(red("Hi Top Level Code"));

Output

  • Top level code first evecutes
  • setTimeout , setImmediate ,setTimeout fs readfile are registered not run
  • Now Event loop runs
  • so first expired timers will run i.e. setTimeOut 1
  • Reading of file will be done after 3 sec so
  • execution will go forward and execute setImmediate
  • then file is being read and IO polling is executed first because reading my text file is not taking much time
  • then due to two setTimeouts event loop starts again
  • Done

image

Code 7

const fs = require("fs");
const { red, blue, green, yellow, magenta, cyan, greenBright, yellowBright } = require("colorette");
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate function here")));
setTimeout(() => {
  fs.readFile("sample.txt", "utf-8", () => {
    console.log(yellow("IO Polling Finished"));

    // Set timer for 2 seconds after reading file
    setTimeout(() => {
      console.log(magenta("Hi from SetTimeout 2 inside Readfile 3s"));
    }, 2000);

    // Set timer for 5 seconds after reading file
    setTimeout(() => {
      console.log(cyan("Hi from SetTimeout 3 inside Readfile 5s"));
    }, 5000);
    setTimeout(() => {
        console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
      }, 0);
    setImmediate(()=>console.log(greenBright("Hi from SetImmediate 2 inside Readfile")))
  });
}, 3000);
console.log(red("Hi Top Level Code"));

Output

  • Top level code first evecutes
  • setTimeout , setImmediate ,setTimeout fs readfile are registered not run
  • Now Event loop runs
  • so first expired timers will run i.e. setTimeOut 1
  • setImmediate is run then
  • then after file reading is done then IO polling printed
  • now this has 4 functions setTimeout of 2s , 5s , 0s and an setImmediate function
  • now as we know that setImmediate inside this is bounded by IO polling ok?!
  • so setImmediate runs first
  • then setTimeout of 0s
  • then setTimeout of 2s
  • then setTimeout of 5s
  • Done

image

Code 8

const fs = require("fs");
const { red, blue, green, yellow, magenta, cyan, greenBright, yellowBright } = require("colorette");
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate 1 function here")));
fs.readFile("sample.txt", "utf-8", () => {
    console.log(yellow("IO Polling Finished"));
    setTimeout(() => {
      console.log(magenta("Hi from SetTimeout 2 inside Readfile 3s"));
    }, 3000);
    setTimeout(() => {
      console.log(cyan("Hi from SetTimeout 3 inside Readfile 5s"));
    }, 5000);
    setTimeout(() => {
        console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
      }, 0);
    setImmediate(()=>console.log(greenBright("Hi from SetImmediate 2 inside Readfile")))
  });
console.log(red("Hi Top Level Code"));

Output

  • In this code i have removed setTimeout for readfile
  • so first top level code runs
  • then event loop starts
  • so first expired timers will run that is setTimeoutof 0s
  • then as my compiler is able to read file very fast so console IO Polling is printed
  • but then we have 4 functions 3 setTimeout and 1 setImmediate so this will start event loop
  • as it is sent to different queue so evecution goes to setImmediate which is present at global level
  • now event loop runs
  • setImmediate runs first as it is inside a IO polling so it runs first
  • then setTimeout of 0s run (expired call back)
  • then setTimeout of 2s run
  • then setTimeout of 5s run

image

Code 9

const fs = require("fs");
const crypto = require('crypto')
const { red, blue, green, yellow, magenta, cyan, greenBright, yellowBright, bgYellowBright, bgBlue, bgCyan, bgGreenBright, bgRedBright, bgMagenta } = require("colorette");
const start = Date.now()
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate 1 function here")));
fs.readFile("sample.txt", "utf-8", () => {
    console.log(yellow("IO Polling Finished"));
    setImmediate(()=>console.log(greenBright("Hi from SetImmediate 2 inside Readfile")))
    setTimeout(() => {
      console.log(magenta("Hi from SetTimeout 2 inside Readfile 1s"));
    }, 1000);
    setTimeout(() => {
      console.log(cyan("Hi from SetTimeout 3 inside Readfile 2s"));
    }, 2000);
    setTimeout(() => {
        console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
      }, 0);

      // CPU intensive work to show Threading work 
      // performed in Thread Pool
      crypto.pbkdf2('mypassword1','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgYellowBright(`password 1 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword2','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgBlue(`password 2 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword3','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgMagenta(`password 3 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword4','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgRedBright(`password 4 Done took ${Date.now() - start}s`))
      })
  });
console.log(red("Hi Top Level Code"));

Output

  • In this code I have added CPU intensive work
  • So these functions will not execute in main thread
  • They will be executed in Thread Pool
  • Thread pool has by default 4 threads and we can chnage it to 128
  • Now our code has 4 crypto functions that are cpu intensive to each process will take one thread
  • and all will execute in concurrently
  • so we can see time taken by each is very close to each other

image

  • I ran code once again and now this time output of CPU intensive is different
  • They are running concurrently and the one who gets resources first and completes first is printed image

Code 10

const fs = require("fs");
const crypto = require('crypto')
const { red, blue, green, yellow, magenta, cyan, greenBright, yellowBright, bgYellowBright, bgBlue, bgCyan, bgGreenBright, 
bgRedBright, bgMagenta } = require("colorette");
const start = Date.now()
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate 1 function here")));
fs.readFile("sample.txt", "utf-8", () => {
    console.log(yellow("IO Polling Finished"));
    setImmediate(()=>console.log(greenBright("Hi from SetImmediate 2 inside Readfile")))
    setTimeout(() => {
      console.log(magenta("Hi from SetTimeout 2 inside Readfile 1s"));
    }, 1000);
    setTimeout(() => {
      console.log(cyan("Hi from SetTimeout 3 inside Readfile 2s"));
    }, 2000);
    setTimeout(() => {
        console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
      }, 0);

      // CPU intensive work to show Threading work 
      // performed in Thread Pool
      crypto.pbkdf2('mypassword1','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgYellowBright(`password 1 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword2','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgBlue(`password 2 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword3','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgMagenta(`password 3 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword4','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgRedBright(`password 4 Done took ${Date.now() - start}s`))
      })
    //    Adding one more cpu intensive 
    // Thread pool has 4 threads so lets see what happens with 5th work
    crypto.pbkdf2('mypassword5','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgCyan(`password 5 Done took ${Date.now() - start}s`))
      })
  });
console.log(red("Hi Top Level Code"));

Output

  • In this code I have added 5th CPU intensive work
  • So this 5th crypto function will not get thread
  • it has to wait for thread to get free
  • as a result it will execute afte one of thread is free

image

  • I ran code again and this time also 5th password comes last as it does not get thread
  • It will execute when a thread gets free so you can see its time is way more than above 4 passwords

image

Code 11

const fs = require("fs");
const crypto = require('crypto')
const { red, blue, green, yellow, magenta, cyan, greenBright, yellowBright, bgYellowBright, bgBlue, bgCyan, bgGreenBright, bgRedBright, bgMagenta, bgGreen } = require("colorette");
const start = Date.now()
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate 1 function here")));
fs.readFile("sample.txt", "utf-8", () => {
    console.log(yellow("IO Polling Finished"));
    setImmediate(()=>console.log(greenBright("Hi from SetImmediate 2 inside Readfile")))
    setTimeout(() => {
      console.log(magenta("Hi from SetTimeout 2 inside Readfile 1s"));
    }, 1000);
    setTimeout(() => {
      console.log(cyan("Hi from SetTimeout 3 inside Readfile 2s"));
    }, 2000);
    setTimeout(() => {
        console.log(yellow("Hi from SetTimeout 5 inside Readfile 5s"));
      }, 5000);
    setTimeout(() => {
        console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
      }, 0);

      // CPU intensive work to show Threading work 
      // performed in Thread Pool
      crypto.pbkdf2('mypassword1','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgYellowBright(`password 1 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword2','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgBlue(`password 2 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword3','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgMagenta(`password 3 Done took ${Date.now() - start}s`))
      })

      crypto.pbkdf2('mypassword4','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgRedBright(`password 4 Done took ${Date.now() - start}s`))
      })
    //    Adding one more cpu intensive 
    // Thread pool has 4 threads so lets see what happens with 5th work
    // this has to wait
    crypto.pbkdf2('mypassword5','mysalt1',100000,1024,'sha512',()=>{
        console.log(bgGreen(`password 5 Done took ${Date.now() - start}s`))
      })
  });
console.log(red("Hi Top Level Code"));

Output

  • So first top level code executes
  • Then we have a setTimeout of 0s and setImmediate and readingFile functions
  • So According to Event Loop first expired Timers are run first
  • So SetTimeout 1 runs first
  • then IO polling happens that is reading of file
  • so console.log(IO Polling ) is printed
  • now as readFile has 4 setTimeout 1 setImmediate and 5 CPU intensive work
  • so as we know if setImmediate is bounded inside IO polling that is read file then setImmediate runs first than setTimeout of 0s
  • so after setImmediate setTime of 0s runs
  • then setTimeout of 1s
  • then setTimeout of 2s
  • Now as setTime of 5s has not expired yet so 4 CPU work will execute as they get each thread
  • 5th CPU process does not get Thread as it is not available so it waits
  • till then event loop sees are there any pending expired timers
  • Yes we have setTimeout of 5s as it expires
  • so it gets printed
  • then our 5th CPU work will get thread and executes
  • Done

image

Code 12

// Top Level code
// Modules are required 
// Event callbacks are registered
// Then Event Loop Runs 
// ------Inside Event Loop----
// First Expired setTimeouts are run 
// then IO polling runs 
// then setImmediate callbacks run
// then close callbacks run 
// event loop checks is there any pending function left
// If yes then it executes them else it exits
const fs = require("fs");
const crypto = require("crypto");
const {
  red,
  blue,
  green,
  yellow,
  magenta,
  cyan,
  greenBright,
  yellowBright,
  bgYellowBright,
  bgBlue,
  bgCyan,
  bgGreenBright,
  bgRedBright,
  bgMagenta,
  bgGreen,
} = require("colorette");
const start = Date.now();
// setTimeouts , setImmediate , IO polling are registered into Event Loop 
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate 1 function here")));
fs.readFile("sample.txt", "utf-8", () => {
  console.log(yellow("IO Polling Finished"));
  // this will run after setImmediate because in event loop in IO polling
  // first setImmediate works then setTimeout of 0s works
  setTimeout(() => {
    console.log(magenta("Hi from SetTimeout 2 inside Readfile 1s"));
  }, 1000);
  setTimeout(() => {
    console.log(cyan("Hi from SetTimeout 3 inside Readfile 2s"));
  }, 2000);
  setTimeout(() => {
    console.log(yellow("Hi from SetTimeout 5 inside Readfile 5s"));
  }, 5000);
  setTimeout(() => {
    console.log(magenta("Hi from SetTimeout 6 inside Readfile 10s"));
  }, 10000);
  setTimeout(() => {
    console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
  }, 0);
  // Executed first as it is inside IO polling
  setImmediate(() =>
    console.log(greenBright("Hi from SetImmediate 2 inside Readfile"))
  );

  // CPU intensive work to show Threading work
  // Performed in Thread Pool
  crypto.pbkdf2("mypassword1", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgYellowBright(`password 1 Done took ${Date.now() - start}s`));
  });

  crypto.pbkdf2("mypassword2", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgBlue(`password 2 Done took ${Date.now() - start}s`));
  });

  crypto.pbkdf2("mypassword3", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgMagenta(`password 3 Done took ${Date.now() - start}s`));
  });

  crypto.pbkdf2("mypassword4", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgRedBright(`password 4 Done took ${Date.now() - start}s`));
  });
  // Adding one more cpu intensive
  // Thread pool has 4 threads so lets see what happens with 5th work
  // This process has to wait
  crypto.pbkdf2("mypassword5", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgGreen(`password 5 Done took ${Date.now() - start}s`));
  });
});
// Top Level Code executes first always 
console.log(red("Hi Top Level Code"));

Output

image

Code 13

// Top Level code
// Modules are required 
// Event callbacks are registered
// Then Event Loop Runs 
// ------Inside Event Loop----
// First Expired setTimeouts are run 
// then IO polling runs 
// then setImmediate callbacks run
// then close callbacks run 
// event loop checks is there any pending function left
// If yes then it executes them else it exits
const fs = require("fs");
const crypto = require("crypto");
const {
  red,
  blue,
  green,
  yellow,
  magenta,
  cyan,
  greenBright,
  yellowBright,
  bgYellowBright,
  bgBlue,
  bgCyan,
  bgGreenBright,
  bgRedBright,
  bgMagenta,
  bgGreen,
} = require("colorette");
const start = Date.now();
process.env.UV_THREADPOOL_SIZE = 10
// setTimeouts , setImmediate , IO polling are registered into Event Loop 
setTimeout(() => console.log(green("Hi from SetTimeout 1 0s")), 0);
setImmediate(() => console.log(blue("Hey setImmediate 1 function here")));
fs.readFile("sample.txt", "utf-8", () => {
  console.log(yellow("IO Polling Finished"));
  // this will run after setImmediate because in event loop in IO polling
  // first setImmediate works then setTimeout of 0s works
  setTimeout(() => {
    console.log(magenta("Hi from SetTimeout 2 inside Readfile 1s"));
  }, 1000);
  setTimeout(() => {
    console.log(cyan("Hi from SetTimeout 3 inside Readfile 2s"));
  }, 2000);
  setTimeout(() => {
    console.log(yellow("Hi from SetTimeout 5 inside Readfile 5s"));
  }, 5000);
  setTimeout(() => {
    console.log(magenta("Hi from SetTimeout 6 inside Readfile 10s"));
  }, 10000);
  setTimeout(() => {
    console.log(yellowBright("Hi from SetTimeout 4 inside Readfile 0s"));
  }, 0);
  // Executed first as it is inside IO polling
  setImmediate(() =>
    console.log(greenBright("Hi from SetImmediate 2 inside Readfile"))
  );

  // CPU intensive work to show Threading work
  // Performed in Thread Pool
  crypto.pbkdf2("mypassword1", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgYellowBright(`password 1 Done took ${Date.now() - start}s`));
  });

  crypto.pbkdf2("mypassword2", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgBlue(`password 2 Done took ${Date.now() - start}s`));
  });

  crypto.pbkdf2("mypassword3", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgMagenta(`password 3 Done took ${Date.now() - start}s`));
  });

  crypto.pbkdf2("mypassword4", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgRedBright(`password 4 Done took ${Date.now() - start}s`));
  });
  // Adding one more cpu intensive
  // Thread pool has 4 threads so lets see what happens with 5th work
  // This process has to wait
  crypto.pbkdf2("mypassword5", "mysalt1", 100000, 1024, "sha512", () => {
    console.log(bgGreen(`password 5 Done took ${Date.now() - start}s`));
  });
});
// Top Level Code executes first always 
console.log(red("Hi Top Level Code"));

Output

  • In this code I have increased number of threads by process.env.UV_THREADPOOL_SIZE = 10
  • So we have 10 threads so all 5 processes are executed at same time concurrently
  • and suppose if we make process.env.UV_THREADPOOL_SIZE = 2 then first two CPU intensive will evecute
  • then next two
  • then next tow
  • Done

image

Difference between Nodejs and other Multithreaded Programming Languages

image

understand_nodejs's People

Contributors

aditimahabole avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.