Giter VIP home page Giter VIP logo

grammatech / sel Goto Github PK

View Code? Open in Web Editor NEW
162.0 21.0 21.0 21.02 MB

Programmatic modification and evaluation of software

Home Page: https://grammatech.github.io/sel/#Top

License: Other

Common Lisp 79.32% Makefile 0.19% C 11.30% Shell 0.74% C++ 0.73% Assembly 0.14% Coq 0.14% Emacs Lisp 0.08% Io 5.17% JavaScript 0.16% Dockerfile 0.14% Python 1.85% Java 0.01% TypeScript 0.03% NewLisp 0.01% Rust 0.01%
software-engineering source-code evolutionary-computation program-synthesis

sel's Introduction

SOFTWARE-EVOLUTION-LIBRARY

The SOFTWARE-EVOLUTION-LIBRARY enables the programmatic modification and evaluation of software.

A common interface abstracts over multiple types of software objects including source code abstract syntax trees (primarily using tree-sitter), compiled assembler code, and binary software objects. Software transformation, analysis, and evaluation techniques are implemented on top of this interface supporting automation of common software engineering tasks.

See the manual, available at https://grammatech.github.io/sel.

SEL has been used to support many projects including:

To cite SEL please use the following reference:

@manual{sel2018manual,
  title        = {Software Evolution Library},
  author       = {Eric Schulte and Contributors},
  organization = {GrammaTech},
  address      = {eschulte@grammatech.com},
  month        = 1,
  year         = 2018,
  note         = {https://grammatech.github.io/sel/}
}

sel's People

Contributors

amygale avatar berchn avatar bfairservice-gt avatar eschulte avatar jaruchti avatar jranieri-grammatech avatar menoonan avatar nikodemus avatar pfdietz avatar probinso avatar rgcorman avatar riswords avatar ruricolist avatar stharding avatar tchangalov avatar zakpfry 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  avatar  avatar  avatar  avatar

sel's Issues

Some systems failed to build for Quicklisp dist

Building with SBCL 2.2.7.28-02bc916fd / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id 556deca

software-evolution-library/run-tree-sitter-py-generator fails to build with the following error:

Unhandled SB-PCL::NO-APPLICABLE-METHOD-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {10016D0003}>: There is no applicable method for the generic function #<COMMON-LISP:STANDARD-GENERIC-FUNCTION FSET:CONVERT (99)> when called with arguments (PYTHON-AST "from typing import Any, List

Full log here

a weird problem when performing transformation

Hi there,

It is a great project, which makes up the transformation ability that the original tree-sitter haven't had yet.

Here I would like to perform a transformation that removing the type descriptor of the cast expression.
For example, given the input snippet as follows (which has two nested cast expressions in the corresponding AST):

void foo(byte *param)
{
  sVar = (char *)xmalloc((int)param + 8);
}

, the expected output should be

void foo(byte *param)
{
  sVar = xmalloc(param + 8);
}

To this end, I write the code as follows:

import asts


code = \
"""
void foo(byte *param)
{
  sVar = (char *)xmalloc((int)param + 8);
}
"""


def remove_cast(ast: asts.AST):
    if isinstance(ast, asts.CCastExpression):
        print('TRANS:', ast.source_text, '->', ast.value.source_text)
        return ast.value


def main():
    root = asts.AST.from_string(code, asts.ASTLanguage.C, deepest=True)
    new_root = asts.AST.transform(root, remove_cast)
    print('New Code:\n', new_root.source_text)


if __name__ == '__main__':
    main()

But the output is

TRANS: (char *)xmalloc((int)param + 8) -> xmalloc((int)param + 8)
TRANS: (int)param -> param
New Code:
 param

, there is only an identifier in the generated code, which is unexpected.

After some trials, I found it can work well under the situation that a cast expression doesn't contain other cast expressions.
For example, if the input is

void foo(byte *param)
{
  sVar = (char *)xmalloc(param + 8);
}

the output is

void foo(byte *param)
{
  sVar = xmalloc(param + 8);
}

, which is expected.

Now I have no idea about how to deal with this problem... Can you help me please?

Thanks!

Some systems failed to build for Quicklisp dist

Building with SBCL 2.1.10.195-bca540cd6 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id e5b4a22

software-evolution-library/deploy-tree-sitter-interface fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (MATCH2*+ (JSON) (T) ...). Use *BREAK-ON-SIGNALS* to intercept.
;    Symbol JSON-DOCUMENT is unbound in namespace PATTERN
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BFC103}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/javascript-project" "file-type">

software-evolution-library/run-dump-store fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (MATCH2*+ (JSON) (T) ...). Use *BREAK-ON-SIGNALS* to intercept.
;    Symbol JSON-DOCUMENT is unbound in namespace PATTERN
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {10418EC4A3}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/javascript-project" "file-type">

software-evolution-library/run-rest-server fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (MATCH2*+ (JSON) (T) ...). Use *BREAK-ON-SIGNALS* to intercept.
;    Symbol JSON-DOCUMENT is unbound in namespace PATTERN
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BFC103}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/javascript-project" "file-type">

software-evolution-library/run-test-parse fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (MATCH2*+ (JSON) (T) ...). Use *BREAK-ON-SIGNALS* to intercept.
;    Symbol JSON-DOCUMENT is unbound in namespace PATTERN
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BFC103}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/javascript-project" "file-type">

software-evolution-library/run-tree-sitter-interface fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (MATCH2*+ (JSON) (T) ...). Use *BREAK-ON-SIGNALS* to intercept.
;    Symbol JSON-DOCUMENT is unbound in namespace PATTERN
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BFC103}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/javascript-project" "file-type">

software-evolution-library/run-tree-sitter-py-generator fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (MATCH2*+ (JSON) (T) ...). Use *BREAK-ON-SIGNALS* to intercept.
;    Symbol JSON-DOCUMENT is unbound in namespace PATTERN
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BFC103}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/javascript-project" "file-type">

Full log here

Some systems failed to build for Quicklisp dist

Building with SBCL 2.0.5 / ASDF 3.3.1 for quicklisp dist creation.

Trying to build commit id e7a6ae7

software-evolution-library/run-dump-store fails to build with the following error:

Unhandled ASDF/FIND-COMPONENT:MISSING-DEPENDENCY in thread #<SB-THREAD:THREAD "main thread" RUNNING {10008D8083}>: Component "cl-tree-sitter" not found, required by #<PACKAGE-INFERRED-SYSTEM "software-evolution-library/software/tree-sitter">

software-evolution-library/run-rest-server fails to build with the following error:

Unhandled ASDF/FIND-COMPONENT:MISSING-DEPENDENCY in thread #<SB-THREAD:THREAD "main thread" RUNNING {10008D8083}>: Component "cl-tree-sitter" not found, required by #<PACKAGE-INFERRED-SYSTEM "software-evolution-library/software/tree-sitter">

Full log here

Loading test/template.lisp fails on macro-expansion of a match clause

Specifically I get the following error in my slime REPL. Commenting out the test-match-derive test allows the file to load. This is with the versions of all tree-sitter libraries listed in tools/tree-sitter-install.sh.

Error Backtrace:

; file: /Users/eschulte/quicklisp/local-projects/sel/test/template.lisp
; in: DEFTEST TEST-MATCH-DERIVE
;     (TRIVIA.LEVEL2:EMATCH (SOFTWARE-EVOLUTION-LIBRARY/TEST/TEMPLATE::MAKE-DERIVE
;                            '("PartialEq" "PartialOrd"))
;       ((SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER:RUST "#[derive(@ARGS)]"
;                                                              :ARGS
;                                                              SOFTWARE-EVOLUTION-LIBRARY/TEST/TEMPLATE::ARGS)
;        (STEFIL:IS
;         (FSET::EVERY #'SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/PARSEABLE:SOURCE-TEXT=
;                      SOFTWARE-EVOLUTION-LIBRARY/TEST/TEMPLATE::ARGS
;                      '("PartialEq" "PartialOrd")))))
; --> TRIVIA.LEVEL2:MATCH2+ 
; ==>
;   (TRIVIA.LEVEL2:MATCH2*+ ((SOFTWARE-EVOLUTION-LIBRARY/TEST/TEMPLATE::MAKE-DERIVE
;                             '("PartialEq" "PartialOrd")))
;       (T)
;     (((SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER:RUST "#[derive(@ARGS)]"
;                                                             :ARGS
;                                                             SOFTWARE-EVOLUTION-LIBRARY/TEST/TEMPLATE::ARGS))
;      (STEFIL:IS
;       (FSET::EVERY #'SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/PARSEABLE:SOURCE-TEXT=
;                    SOFTWARE-EVOLUTION-LIBRARY/TEST/TEMPLATE::ARGS
;                    '("PartialEq" "PartialOrd"))))
;     ((#:OTHERWISE1674)
;      (ERROR 'TRIVIA.LEVEL2:MATCH-ERROR :PATTERN '((# #)) :VALUES
;             (LIST #:OTHERWISE1674))))
; 
; caught ERROR:
;   during macroexpansion of
;   (MATCH2*+ (#)
;       (T)
;     ...).
;   Use *BREAK-ON-SIGNALS* to intercept.
;   
;    Unknown &KEY argument: :NAME-GENERATOR

Some systems failed to build for Quicklisp dist

Building with SBCL 2.0.5 / ASDF 3.3.1 for quicklisp dist creation.

Trying to build commit id e56fcf5

software-evolution-library/deploy-tree-sitter-interface fails to build with the following error:

Unhandled SB-PCL:CLASS-NOT-FOUND-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1000A18083}>: There is no class named SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER::C-FUNCTION-DEFINITION.

software-evolution-library/run-dump-store fails to build with the following error:

Unhandled SB-PCL:CLASS-NOT-FOUND-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1000A18083}>: There is no class named SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER::C-FUNCTION-DEFINITION.

software-evolution-library/run-rest-server fails to build with the following error:

Unhandled SB-PCL:CLASS-NOT-FOUND-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1000A18083}>: There is no class named SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER::C-FUNCTION-DEFINITION.

software-evolution-library/run-test-parse fails to build with the following error:

Unhandled SB-PCL:CLASS-NOT-FOUND-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1000A18083}>: There is no class named SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER::C-FUNCTION-DEFINITION.

software-evolution-library/run-tree-sitter-interface fails to build with the following error:

Unhandled SB-PCL:CLASS-NOT-FOUND-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1000A18083}>: There is no class named SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER::C-FUNCTION-DEFINITION.

Full log here

Request to add example code / information from Evolving Exact Decompilation (BED)

As someone in the decompilation community, I'm very interested in doing my own research and exploration into this field. I was hoping some more specific information could be shared here (or elsewhere) about how sel and any other tools were leveraged in your research project.

Particularly, I am interested in performing a similar experiment but with MIPS-compiled c programs. If it makes more sense for me to reach out to someone privately and discuss elsewhere, happy to do that as well. Thanks in advance for your consideration.

Failed to load "tree-sitter"

Hi, I'm having some trouble trying to run the examples.

Specifically, when I try to load the 003-neutral.lisp example, the lisp interpreter throws No package named "SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/TREE-SITTER.
So I manually load (ql:quickload :software-evolution-library/software/tree-sitter), but the interpreter says

> Error: The value :LOCAL-NICKNAMES is not of the expected type (MEMBER :USE :MIX :REEXPORT :USE-REEXPORT :MIX-REEXPORT :IMPORT-FROM :SHADOWING-IMPORT-FROM :NICKNAMES :DOCUMENTATION :SHADOW :EXPORT :INTERN :UNINTERN :RECYCLE).
> While executing: ASDF/PACKAGE-INFERRED-SYSTEM::PACKAGE-DEPENDENCIES, in process listener(1).

Also, the same error occurs when loading "(ql:quickload:software-evolution-library/software/clang)".

I've been haunted for a long time, so I decided to ask you for help.

Thanks.
Bo.

`asts.ASTLanguage.Python`: invalid resulting indentation for class' docstring

Have "test.py" python file:

class TestIndent:
    """\\ 
    """

Parse it:

import asts

with open("test.py") as f:
    text = f.read()

ast = asts.AST.from_string(text, language=asts.ASTLanguage.Python)
with open("test.parsed.py", "w") as f:
    f.write(ast.source_text)

The resulting "test.parsed.py" will have invalid indentation:

class TestIndent:
"""\\ 
    """

Fork CFFI

To load CFFI (and thus SEL) on a Mac M1 the latest changes from the main CFFI branch are required. Unfortunately death doesn't want to merge those into their fork of CFFI used by SEL. They suggest (see death/cffi#2 (comment)) maintaining a fork of CFFI with these changes and any others needed by SEL. You're welcome to use the fork I've started for this purpose (https://github.com/eschulte/cffi) or maybe you'd rather host one under GrammaTech on GitHub.

Some systems failed to build for Quicklisp dist

Building with SBCL 2.2.1 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id a8e0ef7

software-evolution-library/deploy-tree-sitter-interface fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (ITER (FOR AST IN-TREE ...) (MATCH AST #)). Use *BREAK-ON-SIGNALS* to intercept.
;    Failed to deduce the way to access the slot C/CPP-PATH
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001B98003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/cpp" "file-type">

software-evolution-library/run-dump-store fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (ITER (FOR AST IN-TREE ...) (MATCH AST #)). Use *BREAK-ON-SIGNALS* to intercept.
;    Failed to deduce the way to access the slot C/CPP-PATH
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {10418AC073}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/cpp" "file-type">

software-evolution-library/run-rest-server fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (ITER (FOR AST IN-TREE ...) (MATCH AST #)). Use *BREAK-ON-SIGNALS* to intercept.
;    Failed to deduce the way to access the slot C/CPP-PATH
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001B98003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/cpp" "file-type">

software-evolution-library/run-test-parse fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (ITER (FOR AST IN-TREE ...) (MATCH AST #)). Use *BREAK-ON-SIGNALS* to intercept.
;    Failed to deduce the way to access the slot C/CPP-PATH
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001B98003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/cpp" "file-type">

software-evolution-library/run-tree-sitter-interface fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (ITER (FOR AST IN-TREE ...) (MATCH AST #)). Use *BREAK-ON-SIGNALS* to intercept.
;    Failed to deduce the way to access the slot C/CPP-PATH
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001B98003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/cpp" "file-type">

software-evolution-library/run-tree-sitter-py-generator fails to build with the following error:

; caught ERROR:
;   during macroexpansion of (ITER (FOR AST IN-TREE ...) (MATCH AST #)). Use *BREAK-ON-SIGNALS* to intercept.
;    Failed to deduce the way to access the slot C/CPP-PATH
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001B98003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "software-evolution-library/software/cpp" "file-type">

Full log here

Updates to eclector break some systems

If you use the latest eclector, the following systems no longer build:

  • software-evolution-library/run-new-clang-round-trip
  • software-evolution-library/run-dump-store
  • software-evolution-library/run-clang-diff-test

I get this:
USE-PACKAGE #<PACKAGE "ECLECTOR.PARSE-RESULT"> causes name-conflicts in #<PACKAGE "SOFTWARE-EVOLUTION-LIBRARY/SOFTWARE/LISP"> between the following symbols: ECLECTOR.PARSE-RESULT:READ-PRESERVING-WHITESPACE, COMMON-LISP:READ-PRESERVING-WHITESPACE

Unable to parse sqlite3.c

Unable to parse the single-file sqlite3.c "amalgamation." The file is attached sqlite3.c.txt. The result is a single error AST.

SEL/SW/C-CPP> (defparameter sqlite (from-file (make-instance 'c) "~/Projects/sqlite-bld/sqlite3.c"))
SQLITE
SEL/SW/C-CPP> (describe (@ sqlite 0))
#<C-ERROR 1217039 :TEXT "/*******************...">
  [standard-object]

Slots with :CLASS allocation:
  CHILD-SLOTS                    = ((CHILDREN . 0))
  CHILD-SLOT-SPECIFIERS          = (#<FUNCTIONAL-TREES::SLOT-SPECIFIER CHILDREN 0>)
Slots with :INSTANCE allocation:
  STORED-HASH                    = NIL
  OID                            = 1219463
  DESCENDANT-MAP                 = #<unbound slot>
  SERIAL-NUMBER                  = 1217039
  SIZE                           = #<unbound slot>
  ANNOTATIONS                    = NIL
  BEFORE-TEXT                    = ""
  TEXT                           = "/********************************************************************..
  AFTER-TEXT                     = ""
  BEFORE-ASTS                    = NIL
  AFTER-ASTS                     = NIL
  ORDERED-CHILDREN               = NIL
  INDENT-CHILDREN                = NIL
  INDENT-ADJUSTMENT              = NIL
  CHILDREN                       = NIL
; No value

Outdated Installation instruction

I follow the installation instruction in this [https://grammatech.github.io/sel/Installation.html#Installation(https://grammatech.github.io/sel/Installation.html#Installation) to install the SEL library.

However, the instruction stated that cl-arrows recommends downloading from: https://github.com/eschulte/cl-arrows but it seems that the SEL library expects the cl-arrowz that can be downloaded from https://github.com/eschulte/cl-arrowz, which is a replacement of the cl-arrows library.

There are two possible ways to resolve this issue:

  1. Update the installation instruction to use https://github.com/eschulte/cl-arrowz
  2. Update the dependency to be cl-arrows instead of cl-arrowz

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.