Coder Social home page Coder Social logo

cyrillef / extract.autodesk.io Goto Github PK

View Code? Open in Web Editor NEW
117.0 17.0 74.0 1.65 MB

A sample showing how to extract viewables from the Autodesk OSS storage to your local machine

License: MIT License

Shell 0.38% JavaScript 47.90% HTML 19.94% CSS 31.79%
autodesk forge lmv bubble offline translation

extract.autodesk.io's Introduction

extract.autodesk.io sample

build status Node.js npm Platforms License

Forge API: oAuth2 Data-Management OSS Model-Derivative Viewer

Important: What is demonstrated here, is not officially supported by Autodesk, and may break in future. This is why this sample is posted on my private github repo. You should be using this 'offline' approach only when you are developing an applicationile in development, for backup reasons, or when your application does not have access to the internet.

Note: For using this sample, you need a valid oAuth credential for the translation / extraction portion. Visit this page for instructions to get on-board.

Live demo from the 'service' branch at

http://extract.autodesk.io/

Description

The extract.autodesk.io server exercises and demonstrates the Autodesk Forge API authorization, translation, viewing processes mentioned in the Quick Start guide. It also demonstrates how to extract the 'bubbles' files from the Autodesk server for storing and viewing them locally.

In order to make use of this sample, you need to register your consumer and secret keys:

This provides the credentials to supply to the http requests to the Autodesk server endpoints.

Dependencies

This sample is dependent on the server part on Node.js and couple of Node.js extensions which would update/install automatically via 'npm':

This sample is dependent of Node.js and few Node.js extensions which would update/install automatically via 'npm'.

  1. Node.js - built on Chrome's JavaScript runtime for easily building fast, scalable network applications. You can get Node.js from here

This sample is also dependent on the client side on couple of javascript library which would update/install automatically via 'bower':

  1. flow.js - A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.

  2. Bootstrap - Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.

  3. jQuery.

Setup/Usage Instructions

Deploy on Heroku

Deploy

Setup

  1. Download and install Node.js (that will install npm as well)

  2. Download this repo anywhere you want (the server will need to write files, so make sure you install in a location where you have write permission, at least the 'tmp', 'data' and '/www/extracted' folders)

  3. Execute 'npm install', this command will download and install the required node modules automatically for you.

    npm install
    
  4. Install your credential keys:
    Use system environment variables (This is actually the option you need to use for the tests suite which runs on Travis-CI). Replace keys placeholder xxx with your own keys.

       * Windows<br />
         ```
         set FORGE_CLIENT_ID=xxx
    
         set FORGE_CLIENT_SECRET=xxx
    
         [set PORT=<port>]
    
     	node start.js
         ```
       * OSX/Linux<br />
         ```
         [sudo] [PORT=<port>] FORGE_CLIENT_ID=xxx FORGE_CLIENT_SECRET=xxx node start.js
         ```
    

    Note: the port argument can be omitted and default to port 80. If port 80 is already in use by another application (like Skype, or IIS, or Apache, ...), you can use any other free port such as 8000, 3000, etc... But in the next section you would need to specify the port to use, i.e. http://localhost[:port]/
  5. Recapcha setup
    Add your own site key and secret key respectively in /www/index.html#L257 and /server/config.js#L41.

Use of the sample

Translating files / Extracting 'bubbles'

  1. Start your favorite browser supporting HTML5 and WEBGL and browse to http://localhost/.
    Note: In case you use a different port above do not forget to include it in the URL. I.e. http://localhost:3000/.
  2. Drag'n Drop your files into the 'Drop area' or browse for individual files or grab files for your dropbox, box or google drive account. Tips: start with the main file in your file has dependencies.
  3. Select the master file. The master is the file that Forge will load to trigger translation.
  4. Once all files are uploaded on your local server, press the 'Submit my project' button to translate your file(s).
  5. After the translation completed successfully, move your mouse over the project thumbnail at the bottom of the page ('View submitted Projects' tab) and press the 'Explore' button.
  6. On the new page, you should review your model and if you're happy with what you see, you can request to download the 'bubbles' from the server. Sometimes the process can take a long time, so you can register to be notified by email when the process completed and get a direct link on the resulting zip file.

Viewing 'bubbles' offline using Node.js

  1. This step needs to be done only once per machine. Setup Node.js http-server server.
    npm install http-server -g
    
  2. Unzip the project zip file into a folder.
  3. Execute the index.bat or ./index depending of your OS, or follow instructions below a. Start your local node http-server server.
    [sudo] http-server <myfolder>
    
    b. Start your favorite browser supporting HTML5 and WEBGL and browse to http://localhost:8080/

Viewing 'bubbles' offline using PHP 5.4.x+

  1. This step needs to be done only once per machine. Download and install PHP 5.4+ on your computer.
  2. Unzip the project zip file into a folder.
  3. Start your local PHP http server.
    cd <myfolder>
    
    php -S localhost:8000
    
  4. Start your favorite browser supporting HTML5 and WEBGL and browse to http://localhost:8000/

Viewing 'bubbles' offline using Python

  1. This step needs to be done only once per machine. Download and install Python on your computer.
  2. Unzip the project zip file into a folder.
  3. Start your local Python http server.
    cd <myfolder>
    
    # with Python 2.x
    
    python -m SimpleHTTPServer
    
    # with Python 3.x+
    
    python -m http-server
    
  4. Start your favorite browser supporting HTML5 and WEBGL and browse to http://localhost:8000/

Viewing 'bubbles' offline using Ruby

  1. This step needs to be done only once per machine. Download and install Ruby on your computer.
  2. Unzip the project zip file into a folder.
  3. Start your local Ruby http server.
    cd <myfolder>
    
    ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start"
    
  4. Start your favorite browser supporting HTML5 and WEBGL and browse to http://localhost:8000/

Package an offline viewing solutions

Package with Python

On Windows only: simply copy the Python directory on your CD, and launch the server via a script when your application wants to show a LMV result. Make sure to set the PATH to point to your CD Python location to avoid errors. On OSX, Linux: Python is already installed, so you can use the default Python on these OS.

Usage:

cd <my sample directory>
python -m SimpleHTTPServer [port]

Package with Node/http-server

On all platform you may install the http-server utility. http-server is a simple, zero-configuration command-line http server. It is powerful enough for production usage, but it's simple and hackable enough to be used for testing, local development, and learning.

To install http-server, go on your node.js console and enter the following command:

npm install http-server -g

Usage:

cd <my sample directory>
http-server [path] [options]

[path] defaults to ./public if the folder exists, and ./ otherwise.


License

This sample is licensed under the terms of the MIT License. Please see the LICENSE file for full details.

While the sample is licensed under the terms of the MIT license, the content people post on this site and the bubbles you can extract remain the property of their owner. For a good customer experience the resulting ZIP file includes the current version of the viewer, but the intellectual property of this component remains Autodesk's. You can freely use it for offline viewing on your device, and/or use it on you website, but you cannot claim it to be yours.

Written by

Cyrille Fauvel
Forge Partner Development
http://developer.autodesk.com/
http://around-the-corner.typepad.com

extract.autodesk.io's People

Contributors

autodesk-adn avatar cyrillef avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

extract.autodesk.io's Issues

cannot GET /extracted/<x-x>.zip

Hi,

Not everything works as expected. I have two questions:

(1) I somehow I get the following error message when I try to extract a translated model:
image

The contents of the directory /data/ gets cleaned up during the download of the viewer files at this point:
image

After that, this happens again for a few more times. What is causing this?

(2) The model I upload is a model with another model as dependency. But in the viewer I only see one of the models. Why doesn't it show both of the models?

I used the following models: testing models.zip

Thanks in advance!
Gerard

Forge Viewer Error

Customers are complaining that the users are not able to upload the models in this viewer.
image

Thumbnails not working

The downloaded thumbnails don't appear to be valid PNG files. I think the first problem is that they are being saved as UTF-8, with a BOM before the start of the file. But looking at result.js downloadThumbnail, the first character in the thumbnail body appears to be 0xfffd (unicode replacement character), not 0x89. So there is another conversion to unicode before the response body is being saved as a file.

Models not loading in the viewer

Hi,
I finally got the extractor working by changing some lines in the config file and extend the timeout for my larger models.
however trying to load models in the offline mode I receive this errors:

viewer3D.min.js:1 THREE.DDSLoader.parse: Unsupported FourCC code
viewer3D.min.js:1 THREE.DDSLoader.parse: Unsupported FourCC code A
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost/0/0.pf

I checked the contents of the '0' folder and 0.pf is not there for neither of the models converted.

I'm not confident the output file is containing all files?
any ideas?

Regards,
Afshin

Fail to create your project

got "Fail to create your project" after deploy this repo to heroku and upload models in samples folder, check the server-side shown "POST done Au.zip 51914-Auzip", have no clue what to do.

Problem testing this github

Hi everybody!

I clone this github and load it.

I set credentials.js.

I try to upload a file and it doesn't do anything.

extract_001

Is this a old review? I need to use other branch?

Could you help me?

errors when submitting project

hi,
with the new build I get this error when submitting the project:

C:\Temp...>node start.js
Server listening on port 8083
Token: 4zKnRKJzYLFzLYNNNEndtdhmv2QR
Token RO: Px84bQovzVjQMgCsb3zOg1lMy4hm
POST done beam.nwc 632486-beamnwc
{ statusCode: 403, statusMessage: 'Forbidden' }

and with another model:
**POST done KLE_DomGasPart.NWD 113114670-KLE_DomGasPartNWD
POST done KLE_DomGasPart.NWD 113114670-KLE_DomGasPartNWD
Unexpected end of JSON input 113114670-KLE_DomGasPartNWD
Unexpected end of JSON input 113114670-KLE_DomGasPartNWD
{ Error: ETIMEDOUT
at Timeout._onTimeout (C:\Temp\extract.autodesk.io-master\node_modules\reque
st\request.js:759:15)
at tryOnTimeout (timers.js:224:11)
at Timer.listOnTimeout (timers.js:198:5) code: 'ETIMEDOUT', connect: false }

Unexpected end of JSON input 113114670-KLE_DomGasPartNWD
Unexpected end of JSON input 113114670-KLE_DomGasPartNWD**

and stops uploading the model, nothing will happen next and cannot browse the model.
any ideas?

Different Bubble when calling derivativeservice/v2/manifest/:urn

Hi,

Sometimes the downloaded zips do not have all files in them, only the xref/designDescription.json file is in the zip, not the 0 folder with the scene.

I believe it is happening because of different results returned from the /derivativeservice/v2/manifest/:urn api. For example, I call /derivativeservice/v2/manifest/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ and get:

{ guid: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ',
  owner: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ=',
  type: 'design',
  hasThumbnail: 'false',
  startedAt: 'Mon Dec 19 00:11:05 UTC 2016',
  urn: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ',
  region: 'US',
  status: 'success',
  progress: 'complete',
  success: '100%',
  children: 
   [ { guid: 'aa85aad6-c480-4a35-9cbf-4cf5994a25ba',
       name: 'd2uddpvm9os908ie0k34k7qfr.ipt',
       success: '100%',
       hasThumbnail: 'false',
       role: 'viewable',
       version: '2.0',
       urn: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ',
       status: 'success',
       assetCount: 29,
       type: 'folder',
       progress: 'complete',
       children: 
        [ { guid: '3b81724e-5543-4ff8-aeb7-9d74588f38a9',
            type: 'resource',
            role: 'Autodesk.CloudPlatform.DesignDescription',
            urn: 'urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ/output/xref/designDescription.json',
            mime: 'application/json' } ] } ] }

This shows all translations have completed with result success. My application then proceeds to download the files listed in the manifest on the basis that all nodes in the manifest show successful translation. However, calling /derivativeservice/v2/manifest/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ again 10 seconds later returns a different result with more information. I get:

{ guid: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ',
  owner: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ=',
  type: 'design',
  hasThumbnail: 'true',
  startedAt: 'Mon Dec 19 00:11:05 UTC 2016',
  urn: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ',
  region: 'US',
  status: 'success',
  progress: 'complete',
  success: '100%',
  children: 
   [ { guid: 'aa85aad6-c480-4a35-9cbf-4cf5994a25ba',
       name: 'd2uddpvm9os908ie0k34k7qfr.ipt',
       success: '100%',
       hasThumbnail: 'true',
       role: 'viewable',
       version: '2.0',
       urn: 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ',
       status: 'success',
       assetCount: 29,
       type: 'folder',
       progress: 'complete',
       children: 
        [ { guid: '3b81724e-5543-4ff8-aeb7-9d74588f38a9',
            type: 'resource',
            role: 'Autodesk.CloudPlatform.DesignDescription',
            urn: 'urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ/output/xref/designDescription.json',
            mime: 'application/json' },
          { guid: '8615e0f8-2ff4-4f94-9baa-cb2541744b02',
            type: 'folder',
            name: 'Scenes',
            status: 'success',
            progress: 'complete',
            success: '100%',
            hasThumbnail: 'true',
            children: 
             [ { guid: '9d76bf67-0622-4df7-a960-20ba448ab5e6',
                 type: 'geometry',
                 role: '3d',
                 name: 'Scene',
                 status: 'success',
                 progress: 'complete',
                 size: 201544,
                 success: '100%',
                 hasThumbnail: 'true',
                 children: 
                  [ { guid: 'bb1388e5-3961-4b5b-980a-0d4f13c31d11',
                      type: 'resource',
                      urn: 'urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ/output/1/d2uddpvm9os908ie0k34k7qfr.svf',
                      role: 'graphics',
                      mime: 'application/autodesk-svf',
                      size: 119274 } ] },
               { guid: '31bd9eff-10b0-4763-9e78-f8bc2bdb6b12',
                 type: 'resource',
                 urn: 'urn:adsk.viewing:fs.file:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlbW4vZDJ1ZGRwdm05b3M5MDhpZTBrMzRrN3Fmci5pcHQ/output/1/properties.db',
                 role: 'Autodesk.CloudPlatform.PropertyDatabase',
                 mime: 'application/autodesk-db',
                 status: 'success',
                 size: 24576 } ] } ] } ] }

This response contains the information required to download the scene. Can you advise a way of getting a consistent response from the /derivativeservice/v2/manifest/:urn api so that my application does not download incomplete zips?

Failed to upload model file!

Hi,
Thank you for providing the code.
Following your instructions I installed this and set the parameters.
however when I try to upload a model I get these messages on the server side:

**Server listening on port 80
Token: {"access_token":"tNZaebzZ7hACve7PbwgeYmrHYJC6","token_type":"Bearer","exp
ires_in":86399}

POST partly_done 球面垫.SLDPRT 72422-SLDPRT
master: 72422-SLDPRT
Bucket created (or did exist already)!
async uploading(s)
async uploading 72422-SLDPRT
Failed to upload 72422-SLDPRT
Something wrong happened during upload**

any help will be appreciated.

Failed to create bucket!

Hi,
Thank you for providing the code.
Following your instructions I installed this and set the parameters.
however when I try to upload a model I get these messages on the server side:

Token: {"access_token":"XbnQtu7LnWgJGvNnEVcZy6IrdMDH","token_type":"Bearer","expires_in":86399}

POST done test.nwc 3239-testnwc
master: 3239-testnwc
Failed to create bucket!undefined
async uploading(s)
async uploading 3239-testnwc
Failed to upload 3239-testnwc
Something wrong happened during upload

any help will be appreciated.

From viewer3.3, there are not many res files and CSS files, such as bimwork

hi
When I download the offline version from the transformation model site, I find that the res file and CSS file are missing under the bimwork folder. The version in it is viewer3.3, and now the viewer version has reached 4.2.4. Whether the transformation of the official network will fill and update the missing files to the latest version,By the way , my English is very poor.
thank you

miss /bower_components/

<script src="/bower_components/jquery/dist/jquery.js"></script>
<link href="/bower_components/jquery-ui/themes/smoothness/jquery-ui.css" rel="stylesheet">
<script src="/bower_components/jquery-ui/jquery-ui.js"></script>

Where does the actual file upload happens?

In submitProject(): https://github.com/cyrillef/extract.autodesk.io/blob/master/www/js/app.js#L129
I see that it just sends with an ajax request, an object with the file name and unique identifier but not the actual binary file.

In here: https://github.com/cyrillef/extract.autodesk.io/blob/master/www/js/upload-flow.js#L34
there's r.upload(), is this the actual upload of the model?

Does it start to upload the file right as you press ok in the file chooser?

Is there a way to give it a file path to upload instead of uploading with the form and file chooser?

(If some of those questions are irrelevant here, I posted them on SO)

why name illegal file name

i download all zip file after upload my bim file on the website:https://extract.autodesk.io/.
in the folder:Resource____3D 155844\3\mats,there are three photo files,
their name are
one:woods & plastics.finish carpentry.wood.red birch.png
two:woods & plastics.finish carpentry.wood.teak.png
three:woods & plastics.finish carpentry.wood.white oak.png
why their name have the illegal character “&” and blank space.it will rasie an error in a web site application.
i can't show them on my ipad.

How does the usage disclaimer in v4 of Forge Viewer affect this project and/or offline forge viewer support?

I am developing an application which needs the ability to run the Autodesk Forge Viewer in an offline capacity. As of the Autodesk Forge Viewer 4.0.0 release, an "Autodesk Forge Viewer Usage Limitations Disclaimer" has been added which states:

The Autodesk Forge viewer can only be used to view files generated by Autodesk Forge services. The Autodesk Forge Viewer JavaScript must be delivered from an Autodesk hosted URL.

Where does this leave this project? Does this put offline Forge Viewer support in a grey area? Please consider making an exception for offline cases.

Configuring Extract sample locally

I configured the project. when i browse the file for upload it gives me erro "POST /api/file" Error
(404): "Not found" and it list the file in red color. i did all npm install properly.

Some times it say's /api/file and /api/projects/undefined/progress not found. please guide me in this issue

Interactive Parametrics?

WOW!! This tool creates an amazing web presentation of models exported from Fusion

Are there plans to support a palette of user parameters that can be interacted with?

What the difference between “.dependencies.json” and “.json” in ./data?

Hi cyrillef
I am trying to make this project work in my localhost to learn the forge service.
there is a problem when I uploading files.
In 'lmv-porject.js' line 311~316

            function (err) { //- All tasks are done
                    if (err !== undefined && err !== null) {
                        console.log(err)  // I add one line here to see the err message
                        console.log ('Something wrong happened during upload') ;
                        callbacks2 (err, 3) ;
                        return ; `

the output windows shows

 async uploading(s)
async uploading 5681152-rst_basic_sample_projectrvt
5681152-rst_basic_sample_projectrvt
Failed to upload 5681152-rst_basic_sample_projectrvt
{ Error: ENOENT: no such file or directory, open 'D:\DB\coding\forgeweb\data\5681152-rst_basic_sample_projectrvt.json'
    at Error (native)
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\DB\\coding\\forgeweb\\data\\5681152-rst_basic_sample_projectrvt.json' }
Something wrong happened during upload

I didn't know the difference between “.dependencies.json” and “.json” in ./data,
I am freshman in coding. Hope you can help.
Otherwise, is this project updated the live demo in http://extract.autodesk.io/?

Chunk assembly is failing on Windows

fs.rename (files [$.fileParameterName].path, chunkFilename, function () {
if your tmp folder is not on the same device as your installs, it will fail on Windows

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.