Code Monkey home page Code Monkey logo

adbkit's People

Contributors

bennlich avatar codeskyblue avatar fiws avatar gunta avatar hamanaka-styly avatar koral-- avatar nwalters512 avatar pretyk avatar redgell avatar sorccu 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adbkit's Issues

Process fails to quit due to issue in opening and ending logcat

Switching over from adbkit-logcat to adbkit, and my Node.js process fails to quit because something in logcat must still be in the stack. Previously this wasn't an issue in adbkit-logcat as it's recommended you kill the stream process upon exit, but I don't see a way to access the logcat process using the mechanisms provided by adbkit. The stream end method does not let the process end. Using the following reduced test case:

var adb = require('adbkit');
var client = adb.createClient();

client.listDevices()
  .then(function(devices) {
    var deviceId = devices[0].id;

    client.openLogcat(deviceId)
      .then(function(logcat) {
        setTimeout(function() {
          console.log('ending logcat');
          logcat.end();
        }, 5000);
      });
  });

How can I exec commands as `root` user with this toolkit?

Thank you for your work first!

Now I have rooted android devices, if I use adb shell under command-line and switched to su, I could access app data directories under /data/data/com.xxx.xxx, I want to know how I could switch to root user with this toolkit? For the moment I could only find the client.shell(serial, command[, callback]) API, could you provide me some suggestions? Thank you!

Support destination directory for client.pull

The adb pull command supports both source and destination so use can pull files to the desired directory like this: adb pull sdcard/AndroidAutomation/TestResults/ C:/tmp

Looking into client.js: Client.prototype.pull = function(serial, path, callback)
I can see it supports only source path.

How to use screenshot?

So I have this code:

      return client.screencap(device.id)
        .then(function(stream) {
           // Well, what now?
        });

What can I do with the object I get after calling screencap?

Error: spawn ENOENT

I've got this error when trying to track the device:

Error: spawn ENOENT
    at errnoException (child_process.js:1011:11)
    at Process.ChildProcess._handle.onexit (child_process.js:802:34)

I've tested on another Maverics Macbook and it was fine.
I'm using MacBook Pro OSX Yosemite 10.10.5

implement backup & reboot functionality

these features would be nice. A possible API:

Backup

client.backup(serial, options, callback)
where the options could look like this:

{
  out: "backup.ab",
  apk: true,
  all: false,
  shared: false,
  system: true,
  packages: []
}
adb backup -f backup.ab -all (...)

Reboot

client.rebootRecovery(serial, callback)
client.rebootBootloader(serial, callback)

adb reboot [bootloader|recovery]

I would like to contribute, but I can't get my head around coffescript.

framebuffer not work

my code, follow....
when use png format, file is empty.
when use raw format, file has invalid data.

                    client.framebuffer(device.id, "png", function(err, info, fb_data) {
                        if(err) {
                            console.log("screencapture failed @", device.id, ":", err);
                            return;
                        }
                        console.log(info);
                        var pngname = device.id+"-"+index+'.png';
                        index += 1;
                        var stream = fs.createWriteStream(pngname);
                        fb_data.pipe(stream);
                    });

Output from client.shell returns [object Object] when toString() is called on it

Hi guys, I run into a strange issue:

client.shell(serial, 'ifconfig wlan0', function adbCommandCb(err, output) {
    console.log(output.toString('utf-8'));
}

The console.log produces [object Object].
I have already tried using just plain .toString(), but the result is the same.

I will try Promise version any (it fits in the code better than the callback one).

Version of adbkit: 2.3.1
Node: 0.10.40
System: Windows Server 2012 R2

Thanks!

proc stat never emitting with my nexus 5

I'm playing with a nexus 5 device and trying out the client.openProcStat code:

      return client.openProcStat(device.id)
      .then(function(stat) {
        stat.on('load', function (data) {
          debugger;
        });
        stat.on('error', function (err) {
          console.log(err);
          debugger;
        });
      });

For me the load event is never emitted, and after setting some debug statements it seems the ProcStat.prototype.parse is never called on (update is though)

I know that other things are working, like the checking for nfc example works fine.

I feel like this ins't enough info to go on, so let me know what else might help with debugging.

TypeError: Object #<Object> has no method 'transport' in client.openMonkey

find below the code snippet,

The code fails with the reason transport method not available and gets catched the exception by Promise.

socket.on('screenevent', function (event) {
   client.openMonkey(device_id)
        .then(function(err,monkey) {
            if (err === null) {

                var clientEvents = {
                    touchDown: monkey.touchDown,
                    touchUp: monkey.touchUp,
                    touchMove: monkey.touchMove,
                    tap: monkey.tap,
                    keyUp: monkey.keyUp,
                    keyDown: monkey.keyDown
                };

                console.log('--',event);
                console.log('I received a message ------------ ', event.name,'array--', clientEvents,' method-- ', clientEvents[event.name]);
                if(typeof clientEvents[event.name] === "function"){
                    clientEvents[event.name].call(monkey,event.x,event.y,callback(arguments));
                }
            } else {
                callback(err);
            }
        })
        .catch(function (err){
          console.error('Something went wrong:',err.stack);
        });
}

Any information or help is much appreciated.

Option to only retrieve 3rd party packages and their filenames

currently client.getPackages is equivalent to adb shell pm list packages

need a way to get only 3rd party packages and their package filename on the given device. In other words: adb shell pm list packages -f -3

the full set of options available for list packages is

  • -f: See their associated file.
  • -d: Filter to only show disabled packages.
  • -e: Filter to only show enabled packages.
  • -s: Filter to only show system packages.
  • -3: Filter to only show third party packages.
  • -i: See the installer for the packages.
  • -u: Also include uninstalled packages.
  • --user <USER_ID>: The user space to query.

possible solution:

  • modify client.getPackages to take an options object
options = {
    retrieve_filename: [true | false*],
    filter: [disabled, enabled, system, thirdparty, null*],
    retrieve_installer: [true | false*],
    include_uninstalled_packages: [ true | false*],
    user_id: [<user_id> | null*]
}
  • then need to modify the return value(s) to include the additional filenames

Can adbkit openlogcat add param events/main/sytem/radio?

I have modify the file (/src/adb/command/host-transport/logcat.coffee) where like this:
cmd = 'logcat -B -b events -b main *:I 2>/dev/null'.

But event log is Garbled and main log is ok.

Can adbkit logcat add params with events/main/sytem/radio?

Support reverse command

Although not in the official adb documentation, adb has a reverse command that functions similarly to forward; you can see the usage of the command with adb --help. It would be great to see adbkit support this feature.

client.install() doesn`t work

I tried installing an APK and i get strange error, in the document it was mentioned client.install() was analog to adb install -r but seems like you're doing adb seems like you are doing adb shell pm install

Below is code snippet

    var tmp_file_path = 'data/' + filename[filename.length - 1] + '.apk';
    console.log('temp file path ' + tmp_file_path);

    require("request")
        .get(req.body.url)
        .on('response', function(response) {
            if (response.statusCode == 200)
                shellProvider.install_apk(tmp_file_path, function(results) {
                    res.writeHead(200, {
                        'Content-Type': 'application/json'
                    });
                    res.end(results);
                });
        })
        .on('error', function(err) {
            console.log('Something unexpected happened ' + err)
        })
        .pipe(fs.createWriteStream(tmp_file_path));




    var outputResult = {
        status: "",
        apk: "",
        error: ""
    };

    client.listDevices()
        .then(function(devices) {
            return Promise.map(devices, function(device) {
                return client.install(device.id, apk)
            })
        })
        .then(function() {
            outputResult.status = "success";
            outputResult.apk = apk;
            callback(JSON.stringify(outputResult));
            fs.unlink(apk);
            console.log('Installed %s on all connected devices', apk)
        })
        .catch(function(err) {
            outputResult.status = "failure";
            outputResult.error = err.stack;
            callback(JSON.stringify(outputResult));
            console.error('Something went wrong:', err.stack)
        });

client.screencap() fails on some 2.3 devices

Some 2.3 devices print "screencap: permission denied" to stdout when the binary is missing. The current ScreencapCommand doesn't account for that, expecting the output to go to stderr.

how to activate tcp wireless mode?

ADB over TCP:

//configure a phone to use tcp mode. With USB plugged.
adb tcpip 5555 
//then connect to phone using tcp. Without USB plugged.
adb connect 192.168.0.101:5555

Can this process be done with adbkit? I have not found any related API yet.

Failed to get png file from screencap command

I use adbkit on Android 7.1.1 (Nexus 5X), and call client.screencap() api, when I pipe the stream to fs.createWriteStream("/tmp/a.png").
I got an invalid png format file.
But when I remove "LineTransform" Module in screencap command, it works fine..

So, I don't know if the linetransform should be deprecated ?

client.install() fails on apk downgrade

When I install apk which version is lesser or older than the one currently then the APK will not be installed you need to modify command to take adb install -d -r <apk> to make it work.

I created a PR for this minor change.

shell command not finishing before next command is executed using await

A little background, I am using your library to push a firmware update file to a custom android device. In order for the device to detect the update file, it has to be in a particular block device at a particular mount point. If I execute these shell commands in order, the push goes through, the file ends up where it is supposed to be, and the device picks up the firmware no problem. When I execute the same commands using your library, the commands execute properly, however the file ends up in the mount target folder and not the actual mounted device.

Working adb commands in ubuntu terminal:

adb shell mount /dev/block/mmcblk1p5 /mntpnt
adb push tmpUpdate.zip /mntpnt
adb shell mv /mntpnt/tmpUpdate.zip /mntpnt/update.zip
adb umount /mntpnt

When I do the same commands using your library (using Electron/babel await if that makes a difference):

 await client.shell(device.id, 'mount -t vfat /dev/block/mmcblk1p5 /mntpnt');
 await client.shell(device.id, 'sync');
 const pushFile = await client.push(device.id, updateFilePath, '/mntpnt/tmpFirmware.zip');
 pushFile.on('progress', (stats) => {
   store.dispatch(DEVICE_FIRMWARE_UPDATE_PROGRESS(device.id, { status: 'copyingFirmwareFile', progress: (stats.bytesTransferred / updateFiles.get(updateFile.fileName).get('total')) * 100 }));
 });
 pushFile.on('end', async () => {
   store.dispatch(DEVICE_FIRMWARE_UPDATE_PROGRESS(device.id, { status: 'finishedCopyingFirmwareFile' }));
   await client.shell(device.id, 'sync');
   await client.shell(device.id, 'mv /mntpnt/tmpFirmware.zip /mntpnt/update.zip');
   await client.shell(device.id, 'sync');
   await client.shell(device.id, 'umount /mntpnt');
   await client.shell(device.id, 'sync');
   store.dispatch(DEVICE_FIRMWARE_UPDATE_PROGRESS(device.id, { status: 'waitingForReboot' }));
 });

When I run the commands using adbkit, the device doesn't detect the update, so I shell in, I can see the file in the /mntpnt directory, however the block device is not mounted. However, if I shell in during the transfer, I can see in mount that the device is mounted. Once I mount the block device manually, the files disappear (due to the mount location changing for the dir), and then once I unmount again, the files are back. Any idea or direction would be greatly appreciated.

Notes:
shell sync commands added based on previous comments, does not work with or without although does seem to improve the reliability of the mv command (to rename the file) when sync is called after each shell command

I have also added console logs to the shell commands and the output seems to be what I expect, it just seems like the client.push is what is not performing the way I expect it to.

Error thrown when disconnecting succesfully

adb returns "disconnected 10.2.6.97:5555" when disconnecting successfully.
However, the code expects empty string if successful "" (adbkit/src/adb/command/host/disconnect.coffee)
Therefore a Promise.reject is returned when it was actually successful.

Module not found: Error: Cannot resolve 'file' or 'directory' ./src/adb

I'm developing a tool with electron and react. i use webpack for react, es6 syntax

While creating bundle.js with webpack, i found errors. i installed adbkit with npm

ERROR in .//adbkit/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./src/adb in /Users/LCH/WebstormProjects/electron/node_modules/adbkit
@ ./
/adbkit/index.js 9:15-35

ERROR in .//adbkit//adbkit-monkey/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./src/monkey in /Users/LCH/WebstormProjects/electron/node_modules/adbkit/node_modules/adbkit-monkey
@ .//adbkit//adbkit-monkey/index.js 9:15-38

ERROR in .//adbkit//adbkit-logcat/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./src/logcat in /Users/LCH/WebstormProjects/electron/node_modules/adbkit/node_modules/adbkit-logcat
@ .//adbkit//adbkit-logcat/index.js 9:15-38

What are 'numeric flags'?

In the client.startActivity' method, it is written that the flags are to be passed as a numeric value.
Could this be explicited through an example?

In my case I to launch the following adb shell am start -n com.package.name/.ActivityName but don't know how to fill the config.

Seems like there a bug in the MonkeyCommand

If i do a adb forward and then a monkey.connect(xxxx) then it works fine, seems like the command.write doesn't work when we are connecting to a stream.

wrong: TypeError: Object #<Client> has no method 'write'
    at MonkeyCommand.Command._send (node_modules/adbkit/lib/adb/command.js:29:23)
    at MonkeyCommand.execute (node_modules/adbkit/lib/adb/command/host-transport/monkey.js:20:12)
    at /node_modules/adbkit/lib/adb/client.js:300:45

Capture screenshot from Android emulator

Hello,
I was wondering if you could give me some advice on how to capture a screenshot from the android emulator.
I am working with protractor and appium for connecting to the emulator. Here is the code which I have so far:

var fs = require('fs'),
    adbClient = require('adbkit').createClient();

function writeScreenShot(data, filename) {
    var stream = fs.createWriteStream(filename);
    stream.write(new Buffer(data, 'base64'));
    stream.end();
}

describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('http://www.angularjs.org');

    browser.findElement(by.id('add-some-control'))
        .then(function (el) {
            return el.getLocation();
        }).then(function (loc) {
            return browser.executeScript('window.scroll(0,' + loc.y + ')');
        }).then(function () {
            return adbClient.listDevices();
        }).then(function (devices) {
            console.log(devices[0].id);
            return adbClient.screencap(devices[0].id);
        }).then(function (png) {
            writeScreenShot(png, 'screen.png');
        });

    var todoList = element.all(by.repeater('todo in todos'));
    expect(todoList.count()).toEqual(2);
  });
});

How to detect "No such file or directory" error?

Hi, could you tell me how to catch the "No such file or directory" error?

var base64 = require('base64-stream');

client.pull(device.id, '/sdcard/mydata.txt')
  .then(function(transfer) {
     transfer.pipe(base64.decode()).pipe(process.stdout)
  })
  .catch(function(error) {
    console.log('-----> error');  // <-- This does not work.
  });

About adbkit-logcat's version

adbkit-logcat was updated to v1.1.0, that version fixed the issue: 'Error parsing log stream for Android 5.0.2'. But the version has been sitll "~1.0.3" in adbkit's package.json file. Will it should be updated to "~1.1.0" ? Thanks.

unplugin mobile cause crash

some times when I unplug a mobile from Usb cable, stf is crashed. Here is log:
device:support:push 21886 [13a1a8cf] Sending output to "tcp://127.0.0.1:7116"
device 21886 [13a1a8cf] Preparing device
device:support:sub 21886 [13a1a8cf] Receiving input from "tcp://127.0.0.1:7114"
device:support:sub 21886 [13a1a8cf] Subscribing to permanent channel "*ALL"
device 21886 [13a1a8cf] Setup had an error FailError: Failure: 'device not found'
at /stf/node_modules/adbkit/lib/adb/parser.js:226:31
From previous event:
at Parser.readError (/stf/node_modules/adbkit/lib/adb/parser.js:225:31)
at /stf/node_modules/adbkit/lib/adb/command/host/transport.js:25:35
From previous event:
at HostTransportCommand.execute (/stf/node_modules/adbkit/lib/adb/command/host/transport.js:19:39)
at /stf/node_modules/adbkit/lib/adb/client.js:257:47
at processImmediate as _immediateCallback
From previous event:
at Client.transport (/stf/node_modules/adbkit/lib/adb/client.js:256:32)
at Client.waitBootComplete (/stf/node_modules/adbkit/lib/adb/client.js:531:19)
at ensureBootComplete (/stf/lib/units/device/support/adb.js:19:15)
at /stf/lib/units/device/support/adb.js:28:12
at SerialSyrup.ParallelSyrup.invoke (/stf/node_modules/stf-syrup/lib/parallel.js:54:24)
at /stf/node_modules/stf-syrup/lib/serial.js:43:33
at process._tickCallback (node.js:355:11)

Hi,

I find this tool inspiring.
Do you guys have or need something similar for iOS?

Stuck after track command

I'm trying to use ADBKit inside an Electron app. I call trackClient and the tracker seems to work, BUT, none of the next command called on the same ADBClient object fail to work.

The only way I managed to get it working was by adding a timeout() call on one of the methods I'm trying to call. The error is caught and then suddenly the other methods run.

Here is what (doesn't) happen without the timeout:

adb:command Send '0012host:track-devices' +0ms
Tracker detected ADDED device: 094c9a99
Adding tracker item
Tracker detected ONLINE device: 094c9a99

Here is the logging with a timeout inserted:

adb:command Send '0012host:track-devices' +0ms
Tracker detected ADDED device: 094c9a99
Adding tracker item
Tracker detected ONLINE device: 094c9a99
Error receiving informations
failed to fetch info on 094c9a99
Not sure what to do here
adb:command Send '0017host:transport:094c9a99' +147ms
adb:command Send '0017host:transport:094c9a99' +3ms
adb:command Send '0022shell:pm list features 2>/dev/null' +1ms
adb:command Send '000Dshell:getprop' +1ms

I must say that this worked well with NW.js although I'm not sure it's related.

Convert to plain JavaScript (or perhaps ES6 with Babel)

This is a tracking issue for converting the codebase to plain JavaScript. Many potential contributors have expressed their feelings that they're unable to work with a CoffeeScript codebase, plus CoffeeScript is being left behind in features anyway. It has outlived its usefulness.

Steps:

  • Combine lib and src so that we can start writing plain JS files that work from both CS and JS.
  • Make the linters and hinters to look at the JS codebase while also keeping them looking at the CS codebase.
  • Replace files one by one over a longer period of time.
  • Get rid of CS hinters and linters.
  • Get rid of the prepublish build script (unless converted to Babel).
  • Remove CoffeeScript.
  • Be happy.

Help is most welcome.

client.shell returns inconsistent output

Last time I asked my question about [object Object] being returned by client.shell:
#34

The provided answer helped to correct my assumption, and fix the code.

However it seems that client.shell will returns either Buffer or Stream at it's convenience.
This causes code from the example (https://github.com/openstf/adbkit#example) to fail.
Please have a look at the excerpt from my code:

Unhandled rejection TypeError: undefined is not a function
    at Parser.readAll (c:\dev\playground\Reporter\node_modules\adbkit\lib\adb\parser.js:113:19)
    at module.exports.readAll (c:\dev\playground\Reporter\node_modules\adbkit\lib\adb\util.js:9:31)
    at tryCatcher (c:\dev\playground\Reporter\node_modules\bluebird\js\main\util.js:26:23)
    at Promise._settlePromiseFromHandler (c:\dev\playground\Reporter\node_modules\bluebird\js\main\promise.js:503:31)
    at Promise._settlePromiseAt (c:\dev\playground\Reporter\node_modules\bluebird\js\main\promise.js:577:18)
    at Promise._settlePromises (c:\dev\playground\Reporter\node_modules\bluebird\js\main\promise.js:693:14)
    at Async._drainQueue (c:\dev\playground\Reporter\node_modules\bluebird\js\main\async.js:123:16)
    at Async._drainQueues (c:\dev\playground\Reporter\node_modules\bluebird\js\main\async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] (c:\dev\playground\Reporter\node_modules\bluebird\js\main\async.js:15:14)
    at processImmediate [as _immediateCallback] (timers.js:367:17)

As I already mentioned in the previous issue I reported. The documentation suggests that a Buffer is returned by client.shell. However the code example later suggests that a Stream is returned. In fact both objects can be returned, and a developer need to cater for both of these scenarios.

I don't say it's a HARD BUG, but the behavior doesn't go well with the documentation. I already added an additional step in my code to work with Buffer/Stream output, but either fixing code (yeah sure) or documentation (more likely) will save people a lot of time :)

Thanks

Browserify with adbkit: Cannot find module './src/adb'

My Node script:
var adb = require("adbkit");

upon running in terminal:
browserify script.js -o bundle.js

is resulting:

Error: Cannot find module './src/adb' from '/home/[user]/app/node_modules/adbkit'
at /usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:55:21
at load (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:69:43)
at onex (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:92:31)
at /usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:22:47
at Object.oncomplete (fs.js:107:15)

I have 'adbkit' installed globally and locally in my Express app, as demonstrated by my dependencies:

#"dependencies": {
"adbkit": "^2.4.1",
...
}

What is going wrong? - Why is it supposedly looking for './src/adb' from '/home/[user]/app/node_modules/adbkit' when './src/adb' doesn't even exist?

Calling sync.pull() after sync.readdir() fails

I'm getting the following error when calling sync.pull after sync.readdir:

pull failed: { name: 'UnexpectedDataError',
  message: 'Unexpected \'\u0000\u0000\u0000\u0000\', was expecting DATA, DONE or FAIL',
  unexpected: '\u0000\u0000\u0000\u0000',
  expected: 'DATA, DONE or FAIL' }

This fails:

client.syncService()
  sync.readdir()
    sync.pull()

This works:

client.syncService()
  client.readdir()
    sync.pull()

This is using adbkit v2.0.12 connected to Android 4.4.2.
See my sample code here: http://pastie.org/9364879

remote debug device

I have gone through the readme and most parts of the source codes, but even then I am not very clearly about how to realize the remote debug. Could you give some advice? Now, I plug a real device on my test computer A (192.168.1.2), and want to use android studio of computer B (192.168.1.3), to debug the device.

"Error: getaddrinfo ENOENT" when haven't any connection network?

I use this code to get list android device connected in windows. But when I turn off all my network card or my network down it will catch exeption "getaddrinfo ENOENT". It will work when I have any network card connected even this is network card to virtual machine. How can I get listdevice when my network down?

const adb = require('adbkit');
const client = adb.createClient();

client.listDevices()
  .then(function(devices) {
    console.log(devices);
    //Set link button if detect device
  })
  .catch(function(err) {
    console.error('Something went wrong: ' + err);
  });

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.