Giter Site home page Giter Site logo

node-irc's People

Contributors

eirikb avatar ellisgl avatar esamattis avatar excedrin avatar fent avatar itsrachelfish avatar jakobwesthoff avatar jirwin avatar joeshaw avatar jonrohan avatar katanacrimson avatar linuxmercedes avatar lloyd avatar martynsmith avatar mortal avatar ota42y avatar pnwebster avatar pumpuli avatar quentinxs avatar revmischa avatar rsms avatar schwuk avatar stigi avatar tarlepp avatar thejh avatar timer avatar tom-- avatar trinitas avatar vbm avatar wraithan 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

node-irc's Issues

Should sending messages also emit a 'message' signal?

This is more of a question to see what other people thought rather than an issue.

I am working on a "client" of sorts that is using node-irc to handle all the back-end IRC stuff. In my code, I listen for a 'message' signal to capture all new PRIVMSG's sent to the channel the user is currently in. The problem-- this was only emitted when someone else sends a PRIVMSG to the channel. Not when the user who is logged in sends one.

To work around this, I just update my client when a message is sent w/out waiting for a signal from node-irc. The danger in doing this is there could have been a communication issue between the client and the server and me updating the client w/out waiting for a signal saying the message was actually sent could give the client a false sense of what's actually visible in the IRC channel.

My solution would be to to change

    this.send('PRIVMSG', target, text);
} // }}}

to

    this.send('PRIVMSG', target, text);
    this.emit('message' + target, this.nick, text);
} // }}}

Thoughts?

whois + host with IPv6 leads to info.host = '0'

when i send a whois for myself, i get back these arguments:

{ '0':
   {
     nick: 'cc',
     user: 'username',
     host: '0',
     realname: undefined,
     channels: ['#debug' ],
     server: '--redacted--',
     serverinfo: 'inspircd',
     idle: '1' 
  }
}

If i'm doing the same whois from my regular Chat-Client, my info looks like this:

Nick: cc (identified)
User: username@0::ffff:192.168.1.104
Server: --redacted-- (inspircd)
Im Moment in: #debug 
Idle for: 1 minute

apparently, our inspircd is ipv6-aware and maps all our ipv4-addresses into ipv6-space. This is standard-Behaviour for inspircd 1.2 (debian package default setup), so i guess it might come in handy as a general fix. Is there any other way to retrieve this info in the meantime (or as a permanent workaround)?

Emit channels for "kill" like for "quit"

If I have to use the library via RPC, I have to do my own nicklists based on irc events, and I'd like to be able to correctly remove people from my nicklist when a kill event comes in.

[Feature request] Automatic flood protection

Instead of queuing commands to be sent, monitor conn.bufferSize and automatically enable flood protection based on that. (Possibly using conn.pause() and conn.resume() instead of queuing commands.)

See node/.../doc/api/net.markdown

Event on successful pm

When sending a PRIVATEMSG to someone, it would be helpful if node-irc emitted an event indicating that the message went through.

As designed now, if you want to open a new window when I send a pm (as opposed to receiving one), I have to special-case it (other windows are opened only after event is emitted from node-irc). And if the nick doesn't exist, you've just opened a window that shouldn't be there.

opping and kicking on freenode.net

All I'm trying to do is get my bot to kick a nick from a channel

To do that I need +o, which according to the docs I should bot.send('MODE', channel, '+o', bot.nick)

When I do that it throws:

./node_modules/irc/lib/irc.js:548
                    throw err;
                          ^
Error: Uncaught, unspecified 'error' event.
    at Client.EventEmitter.emit (events.js:70:15)
    at Client.<anonymous> (./node_modules/irc/lib/irc.js:432:26)
    at Client.EventEmitter.emit (events.js:93:17)
    at Client.connect (./node_modules/irc/lib/irc.js:545:22)
    at Array.forEach (native)
    at Socket.Client.connect (./node_modules/irc/lib/irc.js:542:15)
    at Socket.EventEmitter.emit (events.js:93:17)
    at TCP.onread (net.js:391:31)

and I have no idea how to kick.

messaging chanserv for ops works, but I cant find an equivalent way to kick.

Thanks. I am an IRC-bot n00b

refactor node-irc to emit only one 'event' object

Hi

I've started playing around node-irc, creating my own bot based on it, etc (here) and I've been wondering, wouldn't it be better to refactor node-irc to only emit the event name itself and an event object with all the info, i.e. event.from, event.to, event.message etc. (idea from the DOM event system itself: http://en.wikipedia.org/wiki/DOM_events#Event_object)

I'd be willing to refactor it, of course, but I guess we'd need to establish some sort of convetion. one major advantage would be that I could pass the bot object itself on in the event in an easier manner (like I'm doing it now).

I do understand this'd be a major change, though.

Handle erroneous commands gracefully

Sent this through client.send()

/leave #pocoo

Oops, should have been /part. Rather than gracefully handling the error though, I get this:

/Users/akavlie/node_modules/irc/lib/irc.js:907
                    throw err;
                    ^
Error: Uncaught, unspecified 'error' event.
    at Client.emit (events.js:47:15)
    at Client.<anonymous> (/Users/akavlie/node_modules/irc/lib/irc.js:818:26)
    at Client.emit (events.js:64:17)
    at /Users/akavlie/node_modules/irc/lib/irc.js:904:22
    at Array.forEach (native)
    at Socket.<anonymous> (/Users/akavlie/node_modules/irc/lib/irc.js:901:15)
    at Socket.emit (events.js:64:17)
    at Socket._onReadable (net.js:673:31)
    at IOWatcher.onReadable [as callback] (net.js:177:10)

running on 0.2.1 via npm

MODE messages don't appear to work correctly with JustinTV/TwitchTV chat.

Hey there!

I came across an issue where I'm trying to capture the operators. The event gets fired correctly, but here is what I get:

RAW line:
:jtv MODE #crapbot +o beauwest

MESSAGE response:
{ prefix: 'jtv',
nick: 'jtv',
user: undefined,
host: undefined,
command: 'MODE',
rawCommand: 'MODE',
commandType: 'normal',
args: [ '#crapbot', '+o' ] }

The problem is that I have no way of telling which user is modded or unmodded. It may be that JTV IRC sends those messages differently than other IRC servers. One thought I had was passing, along with "message", the raw line so I could do my own parsing if it's different.

Anyway, if you need more info let me know!

Issue with Non-ASCII Nick

When using non-ASCII nick and join a any channel, error happend like this:
/Volumes/Data HD/Projects/Test-Project/node_modules/irc/lib/irc.js:548
throw err;
^
TypeError: Cannot read property 'users' of undefined
at Client. (/Volumes/Data HD/Dropbox/Projects/noru/node_modules/irc/lib/irc.js:324:28)
at Client.EventEmitter.emit (events.js:88:17)
at Client.connect (/Volumes/Data HD/Dropbox/Projects/noru/node_modules/irc/lib/irc.js:545:22)
at Array.forEach (native)
at Socket.Client.connect (/Volumes/Data HD/Dropbox/Projects/noru/node_modules/irc/lib/irc.js:542:15)
at Socket.EventEmitter.emit (events.js:88:17)
at TCP.onread (net.js:392:31)

Traceback after joining network in 0.3.1

Got this right after joining the network:

/Users/akavlie/node_modules/irc/lib/irc.js:510
                    throw err;
                    ^
TypeError: Cannot read property 'mode' of undefined
    at /Users/akavlie/node_modules/irc/lib/irc.js:157:41
    at Array.forEach (native)
    at Client.<anonymous> (/Users/akavlie/node_modules/irc/lib/irc.js:136:26)
    at Client.emit (events.js:64:17)
    at /Users/akavlie/node_modules/irc/lib/irc.js:507:22
    at Array.forEach (native)
    at Socket.<anonymous> (/Users/akavlie/node_modules/irc/lib/irc.js:504:15)
    at Socket.emit (events.js:64:17)
    at Socket._onReadable (net.js:673:31)
    at IOWatcher.onReadable [as callback] (net.js:177:10)

new npm release?

it's been 8 months since 0.3.4, and the code hasn't been completely idle

Handle server connection failures gracefully

When an invalid server name is passed to node-irc, my app crashes as follows:

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: ETIMEDOUT, Operation timed out
    at Socket._onConnect (net.js:601:18)
    at IOWatcher.onWritable [as callback] (net.js:186:12)

Race condition, mode+- before mode= seems to cause crash

> var irc=require('irc')
undefined
> var client = new irc.Client('irc.freenode.net', 'test378546', {channels:['#node.ks']})
undefined
> 
/home/jann/tmp/node_modules/irc/lib/irc.js:511
                    throw err;
                          ^
TypeError: Cannot call method 'indexOf' of undefined
    at /home/jann/tmp/node_modules/irc/lib/irc.js:158:47
    at Array.forEach (native)
    at Client.<anonymous> (/home/jann/tmp/node_modules/irc/lib/irc.js:137:26)
    at Client.emit (events.js:67:17)
    at /home/jann/tmp/node_modules/irc/lib/irc.js:508:22
    at Array.forEach (native)
    at Socket.<anonymous> (/home/jann/tmp/node_modules/irc/lib/irc.js:505:15)
    at Socket.emit (events.js:67:17)
    at TCP.onread (net.js:322:31)

Wiresharks logs:

JOIN :#node.ks
:[email protected] JOIN #node.ks
:sendak.freenode.net MODE #node.ks +ns
:sendak.freenode.net 353 test378546 @ #node.ks :@test378546
:sendak.freenode.net 366 test378546 #node.ks :End of /NAMES list.
[node crashed]

Code looks like the mode change handler expects the mode to be set, but node-irc requests the mode explicitely after joining so that automatic network-caused mode changes happen before the absolute mode is known. Just ignoring might cause node-irc to see a wrong channelmodes, so maybe it should just rerequest the absolute mode when such things happen? E.g. have a "relative changes happened" flag, set it to false on requesting absolute mode, set it to true when changes happen. When an absolute mode comes in and "relative changes happened" is true, rerequest.

'invite' not emitted

Not sure why, but the 'invite' event isn't getting emitted, in fact it doesn't seem to be diving into the 'INVITE' case at all (adding a console.log call to that case in the switch doesn't do anything).

Digging a bit, but filing first in case anyone else has ideas, or has seen this before.

Sending PASS to password protected irc server prepends :

Seeing an issue using node-irc with a password protected IRC server.

When sending the PASS in this section:
https://github.com/martynsmith/node-irc/blob/master/lib/irc.js#L510

It prepends : to the password (and thus the password fails)

It looks like from this line:
https://github.com/martynsmith/node-irc/blob/master/lib/irc.js#L603

Here is what we saw when we enabled extra logging on our IRC server:
INFO | server.commands | #<NioAcceptedSocketChannel [id: 0x00b15b0c, /10.9.1.11:45366 => /10.194.154.5:6667]> sent PASS-> :blah
INFO | server.commands | #<NioAcceptedSocketChannel [id: 0x01b3358f, /10.9.1.11:45467 => /10.194.154.5:6667]> sent PASS-> :blah
INFO | server.commands | #<NioAcceptedSocketChannel [id: 0x00165861, /10.1.1.17:37850 => /10.194.154.5:6667]> sent PASS-> blah

The first 2 lines were using node-irc - the last one used a generic IRC client.

Any ideas?

TOPIC command doesn't play nicely with send function

Client.prototype.send automatically inserts a colon before the last argument in a command. However, for the TOPIC command the colon changes the command from checking the topic to setting/erasing the topic.

A colon should only be inserted in this command's line if there is a second argument and the second argument doesn't already begin with a colon.

For more information, see RFC 2812-3.2.4.

Detect ping timeout

I think there's no ping timeout detection in the library right now. I waited for around 5 minutes to see if something happens but nothing did.

Steps to reproduce:

  1. Connect to a server.
  2. Disconnect from the internet (disconnect button on router webui for example).
  3. Reconnect to internet.
  4. The library doesn't detect that you got ping timeouted from the server, therefore it doesn't even try to reconnect.

I'm gonna temporarily fix this issue by manually pinging the server every few minutes but this puts (a minimal amount from my single bot) extra stress on the server so you might want to find something more elegant.
15 Dec 21:59:39 - SEND: PING :PONG
15 Dec 21:59:39 - Connection got "close" event
15 Dec 21:59:39 - Disconnected: reconnecting
15 Dec 21:59:39 - Waiting 2000ms before retrying

mode emit event

Does anyone think it's worth emitting a standard mode event when a MODE is recieved, in addition to the +mode and -mode.

I'm thinking an event that just emits the nick setting the mode, the channel and the message object. My reasoning for this is because I'm doing some advanced mode parsing and keeping track of channels modes/banlists outside of node-irc and to be honest the +mode and -mode events just don't really make it any easier. I'd rather work with the original string in a one time event.

Emit mode change events

Would be good to have mode change notifications, like

.on('+mode', function(userOrChan, flags) {})
.on('-mode', function(userOrChan, flags) {})

NAMES command crashes client on InspIRCd-2.0 servers

The problem can be observed by just joining the client to any channel on an inspircd server (e.g., irc.alphachat.net). The problem is that InspIRCd is leaving a trailing space in the names reply, like so:

"353 somenick = #channel : nick1 somenick "

You're splitting on spaces, so you wind up with a blank nickname which you then attempt to parse as though it isn't -- match[1] bombs because it's null.

The solution is to just trim the list of nicknames. Here's the patch:

--- irc.js 2011-11-04 01:39:43.138346320 -0400
+++ irc.js.fixed 2011-11-04 01:41:10.478005694 -0400
@@ -196,7 +196,7 @@
break;
case "rpl_namreply":
var channel = self.chanData(message.args[2]);

  •            var users = message.args[3].split(/ +/);
    
  •            var users = message.args[3].trim().split(/ +/);
             if ( channel ) {
                 users.forEach(function (user) {
                     var match = user.match(/^(.)(.*)$/);
    

provide a way to access the current nick

Given that during join the client library might change the nick (by appending self.nickMod when err_nicknameinuse is received), there should be a way to attain the current nick. This could perhaps be a parameter to the registered event?

Handle errors when parsing message

I'm getting this error sporadically with irc 0.3.2:

2011-11-14T07:32:37+00:00 app[app.1]: /app/node_modules/hubot/node_modules/irc/lib/irc.js:715
2011-11-14T07:32:37+00:00 app[app.1]:     message.command = match[1];
2011-11-14T07:32:37+00:00 app[app.1]:                            ^
2011-11-14T07:32:37+00:00 app[app.1]: TypeError: Cannot read property '1' of null
2011-11-14T07:32:37+00:00 app[app.1]:     at parseMessage (/app/node_modules/hubot/node_modules/irc/lib/irc.js:715:28)
2011-11-14T07:32:37+00:00 app[app.1]:     at /app/node_modules/hubot/node_modules/irc/lib/irc.js:506:27
2011-11-14T07:32:37+00:00 app[app.1]:     at Array.forEach (native)
2011-11-14T07:32:37+00:00 app[app.1]:     at Socket.<anonymous> (/app/node_modules/hubot/node_modules/irc/lib/irc.js:505:15)
2011-11-14T07:32:37+00:00 app[app.1]:     at Socket.emit (events.js:64:17)
2011-11-14T07:32:37+00:00 app[app.1]:     at Socket._onReadable (net.js:671:31)
2011-11-14T07:32:37+00:00 app[app.1]:     at IOWatcher.onReadable [as callback] (net.js:177:10)

And the problem is that match can be null under some circumstances (which I haven't pinned down yet).

// Parse command
match = line.match(/^([^ ]+) +/);
message.command = match[1];

Maybe wrapping https://github.com/martynsmith/node-irc/blob/master/lib/irc.js#L506-513 with an if ( line.trim() != '' ) could fix it?

Automatic NickServ /IDENTIFYcation?

Also, join channels only after NickServ acknowledges identification; many networks use cloaks which are only enabled after NickServ is identified to.

QUIT, KILL removes users from user list before processing event hooks

The default 'raw' event hook is executed before anything else, which removes. It emits a 'quit' event which lists the removed users, however other commands (KILL, NICK) have no way of knowing what the affected channels are. Additionally with the current 'quit' event there is no way to get the raw parsed packet AND the list of channels the user was in. Perhaps the data structures should not be modified until all event hooks have been fully processed.

Add an 'action' event

Currently only sending actions is supported, like "/me is coding" via

client.action(channel, 'is coding');

There should therefore also be an 'action' event to be able to register a listener for action messages. As a workaround you can add a listener to the 'raw' event like this:

client.addListener('raw', function (message) {
    if (message.args[1]) {
        var match = message.args[1].match(/^\u0001ACTION (.+)\u0001$/);
        if (match) {
            socket.emit('action', { nick: message.nick, to: message.args[0], timestamp: getTime(),message: match[1] });
        }
    }
});

Colons in user messages cause issues

Causes thedjpetersen/subway#174

Problem code seems to be here: https://github.com/martynsmith/node-irc/blob/master/lib/irc.js#L875-882

The regex is apparently not robust enough to fully handle colon characters in a multi-word message. Emoticons in particular are a problem.

A message like:

What's up? :)

is sent to node-irc Client listeners as:

:What's

I'd attempt to provide a corrected regex, but I'm not that knowledgeable on the IRC protocol and would probably break this logic for input that is currently handled correctly.

chat server connection errors

I created a bot and am running a chat server locally to test it. When I shutdown my chat server and run the bot I don't get any errors . Is this the expected behavior? I'd like to know when the bot can't connect.

uncaught error on data listener

Sometimes lines is empty and the forEach crashes:

self.conn.addListener("data", function (chunk) {
buffer += chunk;
var lines = buffer.split("\r\n");
buffer = lines.pop();
lines.forEach(function (line) {

the crash:
/home/sha0/soft/node-irc/lib/irc.js:534
throw err;
^
Error: Uncaught, unspecified 'error' event.
at Client.emit (events.js:50:15)
at Client. (/home/sha0/soft/node-irc/lib/irc.js:422:26)
at Client.emit (events.js:67:17)
at /home/sha0/soft/node-irc/lib/irc.js:531:22
at Array.forEach (native)
at Socket. (/home/sha0/soft/node-irc/lib/irc.js:528:15)
at Socket.emit (events.js:67:17)
at TCP.onread (net.js:372:31)

Issuing NICK during session breaks JOIN

When I issue a NICK command and later issue a JOIN command, the following exception is thrown:

node_modules/irc/lib/irc.js:549
                    throw err;
                          ^
TypeError: Cannot read property 'users' of undefined
    at Client.<anonymous> (/Users/atul/Documents/explorations/irc-fun/node_modules/irc/lib/irc.js:325:28)
    at Client.emit (events.js:88:20)
    at /Users/atul/Documents/explorations/irc-fun/node_modules/irc/lib/irc.js:546:22
    at Array.forEach (native)
    at Socket.<anonymous> (/Users/atul/Documents/explorations/irc-fun/node_modules/irc/lib/irc.js:543:15)
    at Socket.emit (events.js:67:17)
    at TCP.onread (net.js:362:31)

It looks like that's right here. The exception is being thrown because self.nick wasn't updated when the NICK command was issued.

SSL Failed to connect

I'm trying to connect to my own irc server using SSL and I got this message:

8 Nov 20:06:00 - UNABLE_TO_VERIFY_LEAF_SIGNATURE
8 Nov 20:06:11 - Unhandled message: { command: 'ERROR',
rawCommand: 'ERROR',
commandType: 'normal',
args: [ 'Closing link: (unknown@ip_address_here) [Registration timeout]' ] }
8 Nov 20:06:11 - Connection got "close" event
8 Nov 20:06:11 - Disconnected: reconnecting
8 Nov 20:06:11 - Waiting 2000ms before retrying

The server is: irc.kernelpanic.com.ar:6697 (SSL) if you wanna try. I don't know what's going on with the link, but maybe it could be an incompatibility with the ircd I'm running.

The server is an Inspircd 2.0.5, hope this can help you.

Channel letter-case crashes client

Commit 549d62f introduced a bug where channels with uppercase letters will crash the client because the channel name is, for example, #Node.js as returned by Freenode, but stored as #node.js. While JOIN, PART, and KICK operations don't trigger a crash, any other command that looksup the channel by name does, like in this case a channel mode:

node_modules/irc/lib/irc.js:913
                     throw err;
                           ^
TypeError: Cannot read property 'users' of undefined
     at Client.<anonymous> (node_modules/irc/lib/irc.js:611:40)
     at Client.emit (events.js:88:20)
     at node_modules/irc/lib/irc.js:910:22
     at Array.forEach (native)
     at Socket.<anonymous> (node_modules/irc/lib/irc.js:907:15)
     at Socket.emit (events.js:67:17)
     at TCP.onread (net.js:302:31)

Reverting the above commit fixes any crashing (which I don't fully understand, since it says it was supposed to fix such crashes).

The client should assume that the particular case the IRC server uses is meaningful, so if it changes the case on us we should adopt that case instead.

'LOAD' event issue?

var irc = require('irc');
var client = new irc.Client('irc.freenode.net', 'myNick', {
    channels: ['#hmh'],
});
client.addListener('JOIN', function (msg) {client.send('hemanth',msg.nick)});

This does not send msg to hemanth when the users on 'JOIN'! missing something?

Also the below did not work

client.on('JOIN', function (data) {
  var message = 'Welcome to ' + data.receiver + ', ' + data.sender;
  client.say(data.receiver, message);
  console.log(data.receiver);
});

"kill" emits no event

            var nick = message.args[0];
            for ( var channel in self.chans ) {
                delete self.chans[channel].users[nick];
            }
            break;

Would be nice to have an event for that as for quit.

Make Client writable/readable stream?

I think streams are Node's great feature to handle data flow and IRC certainly is one. I can always implement my own stream interface on top of node-irc, but it might be a nice feature in this library, so what do you think?

Add command for listing channels

RFC-1459:

4.2.6 List message

     Command: LIST
 Parameters: [<channel>{,<channel>} [<server>]]

 The list message is used to list channels and their topics.  If  the
 <channel>  parameter  is  used,  only  the  status  of  that  channel
 is displayed.  Private  channels  are  listed  (without  their
 topics)  as channel "Prv" unless the client generating the query is
 actually on that channel.  Likewise, secret channels are not listed

Also, most IRC clients show a user count for all users in the channel list. I don't see explicit support for that, but I suspect that it's done by running /names on every channel in the list, and counting the results.

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.