Giter VIP home page Giter VIP logo

gulp-accessibility's Introduction

Gulp Accessibility

Build Status Build status

Uses AccessSniff and HTML Codesniffer to grade your sites accessibility using different levels of the WCAG guidelines

Gulp Accessibility example

Getting Started

Install this gulp plugin next to your project's gulpfile with: npm install gulp-accessibility --save-dev

Then add this line to your project's gulpfile.js gulpfile:

var access = require('gulp-accessibility');

Documentation

Place this in your gulp file.

gulp.task('test', function() {
  return gulp.src('./example/**/*.html')
    .pipe(access({
      force: true
    }))
    .on('error', console.log)
    .pipe(access.report({reportType: 'txt'}))
    .pipe(rename({
      extname: '.txt'
    }))
    .pipe(gulp.dest('reports/txt'));
});

Report Generation

You can link to the files you wish to lint using the gulp api

You'll need to add the below to convert into other formats

.pipe(access.report({reportType: 'txt'}))

Options

View AccessSniff options for all available options.

License

Copyright (c) 2015 Steven Miller Licensed under the MIT license.

gulp-accessibility's People

Contributors

adam-l avatar benweizhu avatar prantlf avatar yargalot 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

Watchers

 avatar  avatar  avatar

gulp-accessibility's Issues

Server side code throwing false positives

Managing a theme for Drupal written in PHP, and the PHP syntax is throwing false positives for accessibility errors. For instance:
<?php print $title; ?>

Throws a "Heading tag found with no content" error like this:
<h2 class="title" id="page-title"><!--?php print $title; ?--></h2>

Does an option exist that marks this code syntax as content, or will we have to wade through hundreds of false positives?

Get error even after correcting it

TL;DR

I get errors from this plugin, even though the HTML file already has these problems fixed. I use a templating engine, but I do not think it is relevant since this plugin is used once the files are converted into HTML.

Problem

I am using Nunjucks as a templating engine. These are the files that I have:

~/test/gulpfile.js

var gulp = require('gulp');
var nunjucksRender = require('gulp-nunjucks-render');
var access = require('gulp-accessibility');

gulp.task('build', function() {
    return gulp.src('app/templates/*.njk')
    .pipe(nunjucksRender({
        path: ['app/templates/']
    }))
    .pipe(access()).on('error', console.log)
    .pipe(gulp.dest('dist'))
});

~/test/app/templates/layout.njk

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>{% block title %}Test Page{% endblock %}</title>
        <link rel="stylesheet" href="/styles/main.css" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    </head>
    <body>
        {% block content %} {% endblock %}
    </body>
</html>

~/test/app/templates/index.njk

{% extends "layout.njk" %}

{% block content %}
    <h1>Test Page</h1>
{% endblock %}

If I run gulp build in ~/test/, I get the following error:

Tested ~/test/app/templates/index.html

ERROR WCAG2A.Principle2.Guideline2_4.2_4_2.H25.1.NoTitleEl
A title should be provided for the document, using a non-empty title element in the head section.
--------------------
<head></head>

ERROR WCAG2A.Principle3.Guideline3_1.3_1_1.H57.2
The html element should have a lang or xml:lang attribute which describes the language of the document.
--------------------
<html><head></head><body></body></html>

There was 2 errors

As you can see from the Nunjucks templates, I have those two rules fulfilled. We can even check the output of this build process:

~/test/dist/index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Test Page</title>
        <link rel="stylesheet" href="/styles/main.css" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    </head>
    <body>

    <h1>Test Page</h1>

    </body>
</html>

The output of the Nunjucks render does have a title in its head tag and there is a lang attribute in the html tag, but the error still appears. I do not think it has to do with Nunjucks since by the time that this plugin is used, its input is an HTML file. Do you know why this is happening?

Doesn't work on Windows properly

Problem:

Using this plugin under Windows, the linting fails because PhantomJS just returns

<html><head></head><body></body></html>

As it seems, PhantomJS doesn't handle full Windows paths like C:\foo\bar\index.html which gets returned from the file.path

Possible Solution:

I could make it work by hacking https://github.com/yargalot/gulp-accessibility/blob/master/index.js#L33

if (file.isBuffer()) {
      return accessSniff
        .default(fileUrl(file.path), gulpOptions) // using file-url to convert Windows path to classic file URI
        .then(function(response) {
          file.contents = new Buffer(JSON.stringify(response));

          return callback(null, file);
        })
        .catch(function(error) {
          var error = new Error(error);

          return callback(error, file);
        });
    }

You could use https://github.com/sindresorhus/file-url

The file path gets converted to something like

file:///C:/foo/bar/index.html

which is fine for PhantomJS.

I haven't tested this conversion on OS X/Linux, but it shouldn't do no harm.

Maybe there a other solutions, it was the easiest way to fix it for me.

Error: stdout maxBuffer exceeded

I assume it's because the Project has grown beyond what was imagined, but it starts to break for more and more files with the same error:

Testing /home/some/path/to/file.html failed
Error: stdout maxBuffer exceeded

Heres a simple word count:

$ wc /home/some/path/to/file.html
  8410  28860 679426 /home/some/path/to/file.html

8410 lines
679426 bytes (679371 characters)

These aren't out in the wild pages, but huge collections of components in a style guide, with massive inline svg sprites. (Just telling you to prevent, you shouldn't do so huge pages anways answers).

Is there maybe a way to pass a desired buffer size to the actual exec call?

Test against URL's

Since the plugin is working now (although it throws an error when you don't specify the "force: true" object), would it be possible to test against URL's?

Right now it's not much use to static site builds, so that would be great!

Fetch failed with 404

Can't install gulp-accessibility via CLI. See below. Not sure if NPM (npm/npm#8440) or this package.

Error output

npm i gulp-accessibility --save-dev
npm ERR! fetch failed https://registry.npmjs.org/gulp-accessibility/-/gulp-accessibility-1.1.1.tgz
npm WARN retry will retry, error on last attempt: Error: fetch failed with status code 404
npm ERR! fetch failed https://registry.npmjs.org/gulp-accessibility/-/gulp-accessibility-1.1.1.tgz
npm WARN retry will retry, error on last attempt: Error: fetch failed with status code 404
npm ERR! fetch failed https://registry.npmjs.org/gulp-accessibility/-/gulp-accessibility-1.1.1.tgz
npm ERR! Darwin 13.4.0
npm ERR! argv "node" "/usr/local/bin/npm" "i" "gulp-accessibility" "--save-dev"
npm ERR! node v0.12.4
npm ERR! npm  v2.10.1

npm ERR! fetch failed with status code 404

Duplicate Names

If two html files in the same project have the same name the report for the files will be [](or possibly the last file).

Solution: You should construct a tree structure in the report folder or build one JSON

https

[Error: Protocol:https: not supported.]

Why is https not supported?

cb and not callback

On lines 57 and 24 of index.js you should change cb( to callback( to match the name of the callback method.

force attribute not working

Hi,

I expected when I set force to false, if there is any error like:
ERROR WCAG2AAA.Principle1.Guideline1_3.1_3_1_AAA.G141

The gulp task should failed with exit -1.

But the result is Finished 'accessibility'

Output to CSV columns don't appear to align with column headers

Output looks like this

heading, issue, element, line, column, description
NOTICE,"WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.2",<title>Angular Materialize Base Project</title>,,,6,4,Check that the title element describes the documen....

The extra commas between the element and line columns causes there to be alignment problem. This might be a problem with AccessSniff and not the gulp implementation but I haven't gotten a chance to test out AccessSniff by itself

This {range|color} input element does not have a name available...

<label for="ic">Color input</label>
<input type="color" id="ic" name="ic" value="#000000">

<label for="ir">Range input</label>
<input type="range" id="ir" name="ir" value="10">

gives

ERROR WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.InputColor.Name
Line:441 Col:10
This color input element does not have a name available to an accessibility API. Valid names are: element content.
--------------------
<input type="color" id="ic" name="ic" value="#000000">

ERROR WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.InputRange.Name
Line:445 Col:10
This range input element does not have a name available to an accessibility API. Valid names are: element content.
--------------------
<input type="range" id="ir" name="ir" value="10">

Similar issues:
squizlabs/HTML_CodeSniffer#210
squizlabs/HTML_CodeSniffer#160
pa11y/pa11y#378

Can't stop output to CLI

I was attempting to make this task only report to a file and not output to the CLI, but it seems to ignore the verbose option. It properly makes the report file but I was trying to find a way to stop the CLI output.

gulp.task('wcag_report', function() {
  gulp.src(html_paths)
  .pipe(access({
    force: true,
    verbose: false,
  }))
  .pipe(access.report({reportType: 'txt'}))
  .pipe(rename({
    prefix: 'wcag',
    basename: '-report',
    extname: '.txt'
  }))
  .pipe(gulp.dest('reports/'));
});

Module not Found

When I install the plugin and try to run it. I get module not found 100% of the time. I can verify the plugin is in the package, it is installed in the directory of the correct name, it is being called with the correct name, and it is being used the correct way. I am only assume it is a issue with the current version.

Thanks.

Options to sniff bunch of urls

Hello. In WordPress there's no html files and checking **/*.php causes bunch of errors just because of the PHP code. I would rather use URL sniffs like with php-uncss/gulp-sitemap-generator.

Currently I have my gulp tas set up like this:

/*

ACCESSIBILITY
=============
*/

gulp.task('a11y', function() {

  // Use https://github.com/digitoimistodude/gulp-sitemap-generator
  // Go to http://airdev.test/?show_sitemap to get list and paste here
  var files = ["http:\/\/airdev.test\/2013\/01\/07\/sticky\/","http:\/\/airdev.test\/2012\/01\/07\/template-sticky\/","http:\/\/airdev.test\/test-english-front-page\/","http:\/\/airdev.test\/2016\/08\/12\/uusi-podcast\/","http:\/\/airdev.test\/about\/page-with-a-title-so-long-you-havent-seen-a-title-this-long-before\/","http:\/\/airdev.test\/kauppa\/","http:\/\/airdev.test\/ostoskori\/","http:\/\/airdev.test\/kassa\/","http:\/\/airdev.test\/oma-tili\/","http:\/\/airdev.test\/2015\/12\/06\/moikka-maailma\/","http:\/\/airdev.test\/about-2\/","http:\/\/airdev.test\/about\/page-markup-and-formatting\/","http:\/\/airdev.test\/about\/page-image-alignment\/","http:\/\/airdev.test\/2013\/03\/15\/twitter-embeds\/","http:\/\/airdev.test\/2013\/03\/15\/featured-image-vertical\/","http:\/\/airdev.test\/2013\/03\/15\/featured-image-horizontal\/","http:\/\/airdev.test\/2013\/03\/15\/nested-and-mixed-lists\/","http:\/\/airdev.test\/2013\/03\/15\/more-tag\/","http:\/\/airdev.test\/2013\/03\/15\/excerpt\/","http:\/\/airdev.test\/2013\/01\/11\/markup-and-formatting\/","http:\/\/airdev.test\/2013\/01\/11\/markup-html-tags-and-formatting\/","http:\/\/airdev.test\/2013\/01\/10\/image-alignment\/","http:\/\/airdev.test\/2013\/01\/10\/markup-image-alignment\/","http:\/\/airdev.test\/2013\/01\/09\/text-alignment\/","http:\/\/airdev.test\/2013\/01\/09\/markup-text-alignment\/","http:\/\/airdev.test\/2013\/01\/08\/paginated\/","http:\/\/airdev.test\/2013\/01\/06\/no-content\/","http:\/\/airdev.test\/2013\/01\/05\/non-breaking-text\/","http:\/\/airdev.test\/2013\/01\/05\/title-with-special-characters-2\/","http:\/\/airdev.test\/2013\/01\/05\/title-with-special-characters\/","http:\/\/airdev.test\/2013\/01\/05\/title-with-markup\/","http:\/\/airdev.test\/2013\/01\/05\/markup-title-with-markup\/","http:\/\/airdev.test\/2013\/01\/05\/no-title\/","http:\/\/airdev.test\/2013\/01\/04\/password-protected\/","http:\/\/airdev.test\/2013\/01\/03\/comments\/","http:\/\/airdev.test\/2013\/01\/02\/comments-disabled\/","http:\/\/airdev.test\/2013\/01\/01\/pingbacks-an-trackbacks\/","http:\/\/airdev.test\/2012\/12\/11\/post-format-standard-2\/","http:\/\/airdev.test\/2012\/12\/10\/post-format-gallery-2\/","http:\/\/airdev.test\/2012\/12\/09\/post-format-aside-2\/","http:\/\/airdev.test\/2012\/12\/08\/post-format-chat-2\/","http:\/\/airdev.test\/2012\/12\/07\/post-format-link-2\/","http:\/\/airdev.test\/2012\/12\/06\/post-format-image-caption-2\/","http:\/\/airdev.test\/2012\/12\/05\/post-format-image-2\/","http:\/\/airdev.test\/2012\/12\/04\/post-format-quote-2\/","http:\/\/airdev.test\/2012\/12\/03\/post-format-status-2\/","http:\/\/airdev.test\/2012\/12\/02\/post-format-video-videopress-2\/","http:\/\/airdev.test\/2012\/12\/02\/post-format-video\/","http:\/\/airdev.test\/2012\/12\/01\/post-format-audio-2\/","http:\/\/airdev.test\/2012\/11\/02\/many-categories\/","http:\/\/airdev.test\/2012\/11\/01\/many-tags\/","http:\/\/airdev.test\/2012\/03\/15\/template-featured-image-vertical\/","http:\/\/airdev.test\/2012\/03\/15\/template-featured-image-horizontal\/","http:\/\/airdev.test\/2012\/03\/15\/template-more-tag\/","http:\/\/airdev.test\/2012\/03\/15\/template-excerpt-defined\/","http:\/\/airdev.test\/2012\/03\/14\/template-excerpt-generated\/","http:\/\/airdev.test\/2012\/01\/08\/template-paginated\/","http:\/\/airdev.test\/2012\/01\/04\/template-password-protected\/","http:\/\/airdev.test\/2012\/01\/03\/template-comments\/","http:\/\/airdev.test\/2012\/01\/02\/template-comments-disabled\/","http:\/\/airdev.test\/2012\/01\/01\/template-pingbacks-an-trackbacks\/","http:\/\/airdev.test\/level-1\/level-2\/level-3b\/","http:\/\/airdev.test\/level-1\/level-2\/level-3a\/","http:\/\/airdev.test\/level-1\/level-2b\/","http:\/\/airdev.test\/level-1\/level-2a\/","http:\/\/airdev.test\/page-b\/","http:\/\/airdev.test\/page-a\/","http:\/\/airdev.test\/blog\/","http:\/\/airdev.test\/","http:\/\/airdev.test\/2011\/03\/15\/media-twitter-embeds\/","http:\/\/airdev.test\/2010\/10\/05\/post-format-standard\/","http:\/\/airdev.test\/2010\/09\/10\/post-format-gallery\/","http:\/\/airdev.test\/2010\/09\/09\/post-format-gallery-tiled\/","http:\/\/airdev.test\/2010\/08\/08\/post-format-image\/","http:\/\/airdev.test\/2010\/08\/07\/post-format-image-caption\/","http:\/\/airdev.test\/2010\/08\/06\/post-format-image-linked\/","http:\/\/airdev.test\/about\/clearing-floats\/","http:\/\/airdev.test\/about\/","http:\/\/airdev.test\/2010\/07\/02\/post-format-audio\/","http:\/\/airdev.test\/2010\/06\/03\/post-format-video-wordpresstv\/","http:\/\/airdev.test\/2010\/06\/02\/post-format-video-videopress\/","http:\/\/airdev.test\/2010\/06\/02\/post-format-video-youtube\/","http:\/\/airdev.test\/2010\/05\/09\/post-format-aside\/","http:\/\/airdev.test\/2010\/04\/04\/post-format-status\/","http:\/\/airdev.test\/2010\/03\/07\/post-format-link\/","http:\/\/airdev.test\/2010\/02\/05\/post-format-quote\/","http:\/\/airdev.test\/2010\/01\/08\/post-format-chat\/","http:\/\/airdev.test\/2009\/10\/05\/title-should-not-overflow-the-content-area\/","http:\/\/airdev.test\/2009\/09\/05\/edge-case-no-title\/","http:\/\/airdev.test\/2009\/08\/06\/edge-case-no-content\/","http:\/\/airdev.test\/2009\/07\/02\/edge-case-many-categories\/","http:\/\/airdev.test\/2009\/06\/01\/edge-case-many-tags\/","http:\/\/airdev.test\/2009\/05\/15\/edge-case-nested-and-mixed-lists\/","http:\/\/airdev.test\/level-1\/","http:\/\/airdev.test\/level-1\/level-2\/","http:\/\/airdev.test\/level-1\/level-2\/level-3\/","http:\/\/airdev.test\/about\/page-with-comments-disabled\/","http:\/\/airdev.test\/about\/page-with-comments\/","http:\/\/airdev.test\/lorem-ipsum\/"]

  return gulp.src(files)
    .pipe(access({ 
      accessibilityLevel: 'WCAG2AA',
      browser: true,
      reportType: 'json',
      reportLevels: {
        notice: false,
        warning: false,
        error: true
      }
    }))
    .on('error', console.log)
});

This doesn't work, obviously. Any way to sniff urls instead of files?

HTML_CodeSniffer is installed via git@ protocol instead of https

This happens when installing:

"gulp-accessibility": "2.0.1",
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99: Initialized empty Git repository in /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99/
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99:
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99: Permission denied (publickey).
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99: fatal: The remote end hung up unexpectedly

How do I change that (protocol from where it's installed)? So https instead of ssh.

Full log:

[vagrant@npm]$ npm install gulp-accessibility
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99: Initialized empty Git repository in /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99/
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99:
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99: Permission denied (publickey).
npm ERR! git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99: fatal: The remote end hung up unexpectedly
npm ERR! Linux 2.6.32-642.1.1.el6.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "gulp-accessibility"
npm ERR! node v4.5.0
npm ERR! npm  v2.15.9
npm ERR! code 128

npm ERR! Command failed: git clone --template=/home/vagrant/.npm/_git-remotes/_templates --mirror [email protected]:squizlabs/HTML_CodeSniffer.git /home/vagrant/.npm/_git-remotes/git-github-com-squizlabs-HTML-CodeSniffer-git-65c00b99
npm ERR! Permission denied (publickey).
npm ERR! fatal: The remote end hung up unexpectedly
npm ERR!
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /home/vagrant/npm-debug.log

This happens in VM which doesn't have any ssh keys setup, so I would expect it to work.

So I guess cloning via SSH should be changed to HTTPS, e.g. git@ to https://.

Section508 - Unknown Provider

For some reason the Phantom.js file that comes with the gulp plugin is missing the proper switch statement to support Section508

Here is the relevant portion of code in the phantom.js file in accesssniff included with the gulp plugin

  switch (options) {
    case 'WCAG2A':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('WCAG2A');
      });
      break;
    case 'WCAG2AA':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('WCAG2AA');
      });
      break;
    case 'WCAG2AAA':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('WCAG2AAA');
      });
      break;
    default:
      console.log('Unknown standard.');
  }

and here is the switch statement from the accesssniff project

  switch (options) {
    case 'WCAG2A':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('WCAG2A');
      });
      break;
    case 'WCAG2AA':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('WCAG2AA');
      });
      break;
    case 'WCAG2AAA':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('WCAG2AAA');
      });
      break;
    case 'Section508':
      page.evaluate(function () {
        return HTMLCS_RUNNER.run('Section508');
      });
      break;
    default:
      console.log('Unknown standard.');
  }

The version number in the accesssniff files pulled into the gulp plugin seem to indicate it is the latest version so I am not quite sure what is happening here.

Output to cli

Hey, can I instead of report to a file, just report to the cli? Did I miss this option?

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.