Giter Site home page Giter Site logo

libjass's People

Contributors

arnavion avatar dador avatar doomtay 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

libjass's Issues

Rotation

  • Partial implementation in this branch - diff
  • Rotation is always applied in the order Y-X-Z
  • Rotations apply from the point where they're defined till the end of the line or till they're redefined. However, a redefined rotation is always measured from the zero of the screen. For example, the line M{\fry60}N{\fry60}O will cause O to be rotated a total of 60 degrees, not 120.
  • When individual angles of rotation are thus overridden, the other angles remain unmodified. For example, in the line M{\frz45\fry60}N{\fry0}O, M will be rotated by 0-0-0, N will be rotated by 60-0-45 and O by 0-0-45
  • However, this cannot be rendered as completely separate rotations. In the previous example, the N will be slightly into the screen due to the 60 degrees Y-angle, and the O will be also into the screen (but parallel to the X-Y plane). Effectively the O will be in a plane closer to the viewer than the M, and so will appear larger.

All these facts combined mean that rotations must nest. The line M{\frz45\fry60}N{\fry0}O{\frx90\frz30}P must be rendered as follows:

<span id="1">M<span id="2">N<span id="3">O<span id="4">P</span></span></span></span>

with the following transforms on each:

#1: .transform = "";
#2: .transform = "rotateY(60deg) rotateX(0deg) rotateZ(-45deg)";
#3: .transform = "rotateZ(45deg) rotateX(-0deg) rotateY(-60deg) " + // undo existing rotation to reset back to 0
                 "rotateY(0deg) rotateX(0deg) rotateZ(-45deg)"; // apply new rotation
#4: .transform = "rotateZ(45deg) rotateX(-0deg) rotateY(-0deg) " + // undo existing rotation to reset back to 0
                 "rotateY(0deg) rotateX(90deg) rotateZ(-30deg)"; // apply new rotation

The only thing that should start a top-level span with no reversed rotation applied first is a \N


Unfortunately browsers implement rotation in a retarded manner. All rotations are done from scratch, i.e., if the parent element is rotated, the child element's rotation is not applied on top of the parent's rotation. Instead, it's applied as if the way the child is visible right now is the 0-0-0 state. Thus there is no way to undo a parent's rotation on a child and apply a new rotation.

<style type="text/css">div { display: inline-block; }</style>
<div><div>ABCD</div></div>
<div style="-webkit-transform: rotateY(60deg); transform: rotateY(60deg);"><div>ABCD</div></div>
<div style="-webkit-transform: rotateY(60deg); transform: rotateY(60deg);"><div style="-webkit-transform: rotateY(-60deg); transform: rotateY(-60deg);">ABCD</div></div>

Notice how the third div doesn't look like the first. The child doesn't have the parent's 60deg rotation reversed, instead it has a -60deg rotation applied to its appearance due to the parent rotation (second div).

Another example: http://jsfiddle.net/ag5dQ/4/ Notice how .child_b1 is the same size as .child_b, but .child_b2 isn't.

Font scale (\fscx, \fscy) is wrong (bigger than should be)

Seems like proportion is right but whole text becomes much bigger than should be.

In libjass:
libjass-1

In Aegisub (libass):
libass

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:10:00.00,Default,,0,0,0,,{\fscx50}xxxxxxxxxxxxxxxxx
Dialogue: 0,0:00:00.50,0:10:00.00,Default,,0,0,0,,{\fscy50}yyyyyyyyyyyyyyyyy

SVG outlines are blocky and don't touch the text

The fix for #52 introduced multiplying the SourceAlpha by 1e6 to try to get the equivalent of SourceAlpha but with value 1 at all points instead of the actual source value. This has the downside that the result is blocky and slightly larger than the source, so not only are the outer edges of the outline blocky, but excluding the multipled alpha from the outlines leaves a noticeable clear gap around the source.

Wrong order of dialogues

In libjass:
2015-08-01_21-28-50

In Aegisub (libass):
25_001_0

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on bottom 1
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on top 1
Dialogue: 0,0:00:04.00,0:10:00.00,Default,,0,0,0,,Should be on bottom 2
Dialogue: 0,0:00:05.00,0:10:00.00,Default,,0,0,0,,Should be on top 2

P.S. Test almost the same as #48 but this issue about different thing so I decided to put it in separate issue.

Manual clock behavior weird

Calling this.disable() first sets this._enabled to false, then calls this.pause() which does nothing because this._enabled is false, then calls this.stop(), which works as expected and makes WebRenderer hide the subtitle container by dispatching ClockEvent.Stop.

Then calling this.enable(), sets this._enabled but subsequent this.tick() calls call this.play() which doesn't send the ClockEvent.Play event, because it isn't this._paused is false (the this.pause() call during this.disable() did nothing). Since no ClockEvent.Play is received WebRenderer doesn't restore the visibility of the subtitle container.

What I would expect to work:

webRenderer.disable();
webRenderer.enable();

What's actually needed:

webRenderer.disable();
webRenderer.enable();
manualClock.pause();
manualClock.play();

Support some form of automatic line breaking

  • Not accurate, but text width can be estimated based on font size and number of characters in the span.
  • A more accurate method is using the 2-D context of a canvas but doing that for each sub might be overkill.
  • How to take rotations / dynamic font sizes into account? Dynamic font sizes are especially important for borderline cases like the default style font or first few characters of the line being in a super-huge font while the rest of the line is in tiny font.

Renderer tests

  • A renderer decoupled from <video> - WebRenderer
  • A clock decoupled from <video> - ManualClock
  • A test framework that can load a minimal page with libjass.js, a single div, and the test JS, then take screenshots.

Font name should not be quoted when it's a CSS keyword

For example, Style defaults fontName to sans-serif if the ASS doesn't specify one. Such a keyword is supposed to be used without quotes for the CSS font-family property, otherwise it's interpreted as a real font name instead of a keyword.

Support .srt

Either:

  • Same way as VSFilter - pretend it's an ASS.
    • Add a type parameter to ASS.fromString to select between ASS and SRT.
    • Implement via default script properties and style.
    • SRT doesn't specify resolution, it uses video resolution.
    • Map SRT formatting to ASS parts.
    • Partial implementation in this branch - diff

or

  • Don't do anything. Browsers support / will support WebVTT natively and it is trivial to convert SRT to WebVTT (prepend "WEBVTT\n\n" and serve as text/vtt).

Margins should be shared between multiple subs in same alignment group

In libjass:
2015-08-01_21-28-50

In Aegisub (libass):
25_001_0

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on bottom 1
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on top 1

P.S. Test almost the same as #49 but this issue about different thing so I decided to put it in separate issue.

Fix some names

Style.OutlineWidth -> OutlineThickness
{parts, SpanStyles}.OutlineWidthX -> OutlineWidth
{parts, SpanStyles}.OutlineWidthY -> OutlineHeight

Fix fscx-clipping

fscx scaling via transform: scaleX(...) causes the scaled text to clip its neighbors. One alternative is to do the following transformation:

Given:

fontSize = f
fontScaleX = x
fontScaleY = y

Transform to:

fontSize = f * x
fontScaleX = 1
fontScaleY = y / x

and drop the scaleX(...)

The problem is that lines like {\fs12\fscx1000\fscy100} (f = 12, x = 10, y = 1 => f = 120, x = 1, y = 0.1) will end up having a line height of 120px; the 0.1 vertical scaling will not allow the line height to be set to 12px. This does not happen.

Wrong font color when using opacity

libjass with enableSvg = true:
2015-08-02_19-18-06

libjass with enableSvg = false: (notice that it darken than previous, it more noticeable on colored text)
2015-08-02_19-16-20

Aegisub (libass):
test5_001_12

Script:

[Script Info]
Title:
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 1,0:00:00.00,0:00:36.95,Default,,0,0,0,,{\alpha&7E&}test

Maybe just remove rgba from "color" and "text-shadow" and add "opacity". I tried it via debugger and seems like everything is okay.

For example replace:

color: rgba(255, 255, 255, 0.686275);
text-shadow: rgba(19, 7, 2, 0.686275) 0px 0px 0px, ...many shadows...;

to:

opacity: 0.686275;
color: rgb(255, 255, 255);
text-shadow: rgb(19, 7, 2) 0px 0px 0px, ...many shadows...;

Or is there some kind of pitfall?

Possible to render ASS before ASS.fromURL promise is fully resolved?

My use case is I use torrent-stream, which creates readable streams of torrent files. You can start watching video files, before they are fully transferred. I can also feed a mkv video file stream into ffmpeg to create a ASS file stream. It would be neat if libjass could support rendering the currently parsed dialogue.

I looked around and it seems like I could create my own versions of ASS.fromURL & ASS.fromStream to return the minimalAss promise instead. I didn't see if using that would work yet and the renderer was too complex to figure out for me for now.

Anyways, if libjass could support this use case that would be super. If modified ASS.fromURL & ASS.fromStream is all that's needed for it to work, I'll send a pull request.

Support `catch` in `Promise` shim

For compatibility with the official API (and browsers' native implementations). I think this should be a couple extra prototypes in the interface section and a 1-line wrapper function.

Support kfx

  • \k should be trivial to implement with animation-timing-function: step-end Done.
  • \ko is harder - there's no CSS property to animate.
  • \K's sweeping behavior may be impossible to do with just CSS - might require two overlapping spans and an animated width. Also see [https://stackoverflow.com/questions/23569441/is-it-possible-to-apply-css-to-half-of-a-character](this SO question.)

Clock ticks don't update animations when paused

With a paused clock, animations are paused. WebRenderer.draw is a no-op because the dialogue is already drawn. As a result, the sub animation remains paused at the frame it was first drawn at instead of updating with the ticks.

Timing out of sync after network lag or heavy animation

Happens often when playing video with heavy animation (heavy for libjass, fine in native player). Also that happens on regural subtitles on mobile devices (such as Chrome on Android tablet). In case of network lag (html5 player waiting for video to load) that happens too.

These delays started after implementing new AutoClock. AutoClock take value of currentTime from html5 video only once. So difference between time in AutoClock and currentTime in html5 video growing and growing. Re-sync of timing happens only if seek to other part of video. It doesn't happens on play & pause.

Maybe sync time each "onupdatetime" event? (but there may be noticeable gaps, not sure)
BTW, why you decided to switch from "onupdatetime" to manual clock only?

Don't always invalidate pre-rendered dialogues on resize / ratechanged

  • Store two more pieces of metadata with each pre-rendered sub - whether it has size-related values, and whether it has time-related values. This includes animations.
  • On resize, only clear those pre-rendered subs (and their associated animations) that have size-related values.
  • On ratechange, only clear those pre-rendered subs (and their associated animations) that have time-related values.

Animated \alpha start animation from 0% opacity

Animated \alpha start animation from 0% opacity while should start it from 100% opacity.

Test script:

[Script Info]
Title:
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 1,0:00:00.00,0:00:36.95,Default,,0,0,0,,{\t(2000,5000,\alpha&7E&)}test

Font scale + rotation leads to wrong rotation degree

In libjass:
2015-08-01_21-14-36

In Aegisub (libass):
libass

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:10:00.00,Default,,0,0,0,,{\fs50\frz22.962\fscx180\pos(812.95,394)}1111111111111111111111111111111111
Dialogue: 0,0:00:00.00,0:10:00.00,Default,,0,0,0,,{\fs50\frz22.962\pos(812.95,394)}2222222222222222222222222222222222222

font size changed in libjass

hello
i have two problem after using libjass on website
the first is about support fonts
i think the pre-loading not work properly
i have all the font in my pc and also i have attached font to the script
but here photo of what appears

in libass
http://im49.gulfup.com/8NvrgU.png
23_001_2779

in libjass
http://im49.gulfup.com/Bp3V1O.png
23_003_2779

the second problem with font size... sometimes become smaller and sometime bigger

here in libass
http://im49.gulfup.com/8NvrgU.png
23_001_2779

and here in libjass
http://im49.gulfup.com/Yn5u5K.png
23_002_2779

[Script Info]
; Script generated by Aegisub 2.1.8
; http://www.aegisub.org/
Title: العربية
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
YCbCr Matrix: TV.601
Last Style Storage: rapu
Video File: ?dummy:23.976000:40000:1280:720:47:163:254:c
Video Aspect Ratio: 0
Video Zoom: 3
Video Position: 33204

[Aegisub Project Garbage]
Audio File: ../../274 [720p].mkv
Video File: ../../274 [720p].mkv
Video AR Mode: 4
Video AR Value: 1.777778
Video Zoom Percent: 0.250000
Scroll Position: 146
Active Line: 152
Video Position: 830

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Adobe Arabic,63,&H00FFFFFF,&H00FFFFFF,&H00020203,&H00000000,-1,0,0,0,104.274,100,0,0,1,1.7,0.74,2,21,21,30,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:01:55.90,0:01:58.19,Default,,0000,0000,0000,,!عليّ أن أسأل أحد شينوبي السحاب حول طريقة استعمالها

Better Example

Hi, i'm relatively new to Javascript, i've seen the ''online demo'', it works fine, but the script is too complex to understand and edit, is it possible a simple ''hello world script''?
Something like:
-script-
var video = VIDEO_URL
var sub = ASS_URL
//SOME CODE TO RUN LIBJASS on idvideo
-/script-
-video id='idvideo'- -/video-

Thanks for attention

dist and bower

Any chance that you'll create a bower package or check in the compiled libjass.js and libjass.css?

libjass is more front-end centric and having a compiled version of the essential files will simplify dependency management of other front-end projects using libjass.

Checking in the compiled files for every new tag/release would be great.

Thanks

Newlines don't work depending on… something

This works:

[Script Info]
; Script generated by FFmpeg/Lavc56.12.100
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:02.96,0:00:06.40,Default,,0,0,0,,That's my vehicle\Nand I want it back!

This does not:

[Script Info]
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,1,1,0,2,10,10,10,0,0

[Events]
Format: Layer, Start, End, Style, Text
Dialogue: 0,0:00:02.88,0:00:06.32,Default,That's my vehicle\Nand I want it back!

It produces output like this:
It looks like a number of style attributes don't output.

"Outline" style issue in Chrome

Outline looks pretty wrong/ugly after Chrome update. Probably that caused by new way of rendering fonts in Chrome (now chrome uses Direct Write as I understand).

Screenshot (in Chrome):
chrome test
Screenshot (in Firefox):
firefox test
Screenshot (in Aegisub):
aegisub test

Test script:

[Script Info]
Title: Test
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.601
Last Style Storage: Default
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Main,Arial,42,&H00FFFFFF,&H000000FF,&H00331B2F,&H00000000,-1,0,0,0,100,100,0,0,1,1.8,0,2,20,20,35,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:10:00.00,Main,,0,0,0,,Lorem ipsum dolor sit amet

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.