Code Monkey home page Code Monkey logo

Comments (46)

marcoscaceres avatar marcoscaceres commented on July 21, 2024

I wonder if we would even need to expose the bandwidthCeiling as this is very regional (hence, it might require look-up tables on a per country or per state-level or per city-level).

For instance, my carrier here in Canada claims it is 3G, but I rarely, if ever, get anything close to 3G speeds. It also doesn't work outside any of the main cities and gets bounced to different carriers - where I get charged "away rates" (see below).

If this is the situation in a "developed" country like Canada, I don't want to imagine how sad the state of affairs is in other countries. My worry is that UAs will have to always report the lowest possible speed to avoid abuse of this feature (if we introduce the fine-grained types).

screenshot 2014-08-21 17 44 48

WIND NETWORK BEST
PHONE DISPLAYS: WIND Home, WIND Zone, WIND, or 302490
Good indoor and outdoor coverage where you can use your unlimited features.

VARIABLE NETWORK & COVERAGE
PHONE DISPLAYS: Either WIND OR AWAY
Good outdoor and satisfactory indoor coverage depending on location factors. In this area it is possible to get WIND or our Partner network so check display to ensure you know if you will be using WIND service or charged Away pay per use rates.

PARTNER NETWORK (AWAY COVERAGE)
PHONE DISPLAYS: AWAY (Canada) or Partner Name (i.e. TMobile in USA)
Signal strength and network coverage will vary. See WIND plan details for Away pay per use rates.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

We don't need to get into carrier/region based ceiling discussions - these values change on a minute to minute basis based on network load, location, device in use, etc. However, regardless of all of these variables, the maximum bandwidth for a particular generation of network stays the same - e.g. EDGE will max out at 384kbps. In other words, regardless of how good or bad the current network weather is for any carrier or location, if you're on EDGE, I know you'll never go faster than 384kbps.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

Not particularly representative, but here are my results sitting right in the middle of Toronto on 3G:

Download: 1.52 Mbps
Upload: 0.22 Mbps
Ping: 73 ms

http://www.speedtest.net/my-result/i/938818231

I'm also reading on Wikipedia that:

ITU has not provided a clear[citation needed][vague] definition of the data rate that users can expect from 3G equipment or providers. Thus users sold 3G service may not be able to point to a standard and say that the rates it specifies are not being met. While stating in commentary that "it is expected that IMT-2000 will provide higher transmission rates: a minimum data rate of 2 Mbit/s for stationary or walking users, and 384 kbit/s in a moving vehicle,"[25] the ITU does not actually clearly specify minimum required rates, nor required average rates, nor what modes[clarification needed] of the interfaces qualify as 3G, so various[vague] data rates are sold as '3G' in the market.

I'm worried that carriers might be annoyed if we start stating that things should be at some speed, but they are not.

Note from the above that my own carried in Canada doesn't even get to 2 Mbits/s on 3G.

It is also noted in Wikipedia that, at least, "In India, 3G is defined by telecom service providers as minimum 2 Mbit/s to maximum 28 Mbit/s".

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

Right, there are no minimums (I wish), but that's not what we're after with 'ceiling'. There are well-defined maximums, which are based on the underlying technology: coding algorithm, number of channels, etc. Hence the reason why I'm stressing that this should be "ceiling" to indicate that this is max possible throughput of last hop - e.g. Gigabit ethernet would return 1000Mbps.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

@igrigorik where would we get the max speed list from? Let's build it up.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

Original FF implementation is a good starting point: http://hg.mozilla.org/mozilla-central/rev/e652d673382f#l2.68. I'm not sure where @mounirlamouri got those numbers from, but on first pass, they are in the right ballpark.

/cc @dougsillars

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

As the theoretical bandwidth can change independently of type, we might need an event. Over on public-script-coord, they currently discussing adding [Observable] to WebIDL. If we had that, we could make both bandwidthCeiling and type observable instead of requiring the event. However, it's looking like it's going to take ages, we can add a change event for bandwidthCeiling.

from netinfo.

dougsillars avatar dougsillars commented on July 21, 2024

The numbers seem ballpark correct.

Any thoughts on providing a "latency minimum" along with the "Bandwidth Max"? This might be helpful for interactive sites, notifying the site to prefetch more data earlier?

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@dougsillars which set of numbers? The ones in original FF implementation?

For latency, even if we don't include it in the spec, since we're deriving BW based on last hop type, it would be pretty easy to build a lookup map on your own. In other words, seems like a library?

from netinfo.

dougsillars avatar dougsillars commented on July 21, 2024

The firefox numbers are close, but I think they tend to be a bit slower than your references and those in android docs. Here are the Android emulator speeds for various GSM networks.
Value Description Comments
gsm GSM/CSD (Up: 14.4, down: 14.4)
hscsd HSCSD (Up: 14.4, down: 43.2)
gprs GPRS (Up: 40.0, down: 80.0)
edge EDGE/EGPRS (Up: 118.4, down: 236.8)
umts UMTS/3G (Up: 128.0, down: 1920.0)
hsdpa HSDPA (Up: 348.0, down: 14400.0)
full no limit (Up: 0.0, down: 0.0)
http://developer.android.com/tools/devices/emulator.html#netspeed

For HSPA+ and LTE we can look at your book :)
HSPA+ (22 Mbit/s up 168 Mbit/s down
LTE (75 300

i love the idea of a library to help devs create latency measurements. For browsers (and native!)

from netinfo.

mounirlamouri avatar mounirlamouri commented on July 21, 2024

I'm not sure where @mounirlamouri got those numbers from, but on first pass, they are in the right ballpark.

Just did a bit of research.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

Relevant references for Android:

int NETWORK_TYPE_1xRTT  Current network is 1xRTT
int NETWORK_TYPE_CDMA   Current network is CDMA: Either IS95A or IS95B
int NETWORK_TYPE_EDGE   Current network is EDGE
int NETWORK_TYPE_EHRPD  Current network is eHRPD
int NETWORK_TYPE_EVDO_0 Current network is EVDO revision 0
int NETWORK_TYPE_EVDO_A Current network is EVDO revision A
int NETWORK_TYPE_EVDO_B Current network is EVDO revision B
int NETWORK_TYPE_GPRS   Current network is GPRS
int NETWORK_TYPE_HSDPA  Current network is HSDPA
int NETWORK_TYPE_HSPA   Current network is HSPA
int NETWORK_TYPE_HSPAP  Current network is HSPA+
int NETWORK_TYPE_HSUPA  Current network is HSUPA
int NETWORK_TYPE_IDEN   Current network is iDen
int NETWORK_TYPE_LTE    Current network is LTE
int NETWORK_TYPE_UMTS   Current network is UMTS

For iOS 7+:

The Core Telephony framework (CoreTelephony.framework) lets you get information about the type of radio technology in use by the device. Apps developed in conjunction with a carrier can also authenticate against a particular subscriber for that carrier... source, example

Added CTTelephonyNetworkInfo.currentRadioAccessTechnology
Added CTRadioAccessTechnologyCDMA1x
Added CTRadioAccessTechnologyCDMAEVDORev0
Added CTRadioAccessTechnologyCDMAEVDORevA
Added CTRadioAccessTechnologyCDMAEVDORevB
Added CTRadioAccessTechnologyDidChangeNotification
Added CTRadioAccessTechnologyEdge
Added CTRadioAccessTechnologyGPRS
Added CTRadioAccessTechnologyHSDPA
Added CTRadioAccessTechnologyHSUPA
Added CTRadioAccessTechnologyLTE
Added CTRadioAccessTechnologyWCDMA
Added CTRadioAccessTechnologyeHRPD

Other references:

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

First run at intersecting the Android and iOS network types:
https://gist.github.com/igrigorik/cb94f9b83f5afb3f722a

Now we just need to fill in the downlink speeds.. easier to iterate in a gist. :)

from netinfo.

paulirish avatar paulirish commented on July 21, 2024

The network presets in DevTools emulation:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/devtools/front_end/toolbox/OverridesUI.js&q=WebInspector.OverridesUI._networkConditionsPresets&sq=package:chromium&type=cs&l=366

I believe eustas did some research on these. I spoke to a few folks that indicate they may not be too accurate, but we haven't had any definitive data that disproves them.

I mentioned this to @bluesmoon as SOASTA might have some data here. Philip, do you have anything that could help?

from netinfo.

bluesmoon avatar bluesmoon commented on July 21, 2024

Let me have a look at my data.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@paulirish @bluesmoon note that we're not looking for estimated BW data based on current carriers, etc. The ceiling value is meant to indicate the maximum theoretical throughput of the connection type, regardless of carrier and all other factors.

from netinfo.

paulirish avatar paulirish commented on July 21, 2024

Well, I'm pretty interested in average/expected BW per connection type.
Would help me as a dev to set expectations for what each of the ceiling
values will map to.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@paulirish as an FYI, sure... I'm just saying that the intent of bandwidthCeiling is to expose the theoretical maximum, not some expected average - these values are highly variable and change with time. If / once / when we get to surfacing bandwidthEstimate, or some such, then these averages and end-to-end BW estimates start to become more relevant.

from netinfo.

paulirish avatar paulirish commented on July 21, 2024

​Sure, but I guess I'm saying I don't know how useful the bandwidthCeiling
metric is to me if, say for instance, the Estimate values are actually
80-90% smaller.

This API is going to expose decision points for developers on what sort of
assets to send down, so I want to use the Ceiling metric to pick something
reasonable. And the gulf between Ceiling and Estimate is the difference
between unreasonable and reasonable. :)

from netinfo.

bluesmoon avatar bluesmoon commented on July 21, 2024

I'd have to agree with @paulirish, the ceiling is rather useless from a web dev's point of view, just as useless as knowing the connection type.

from netinfo.

paulirish avatar paulirish commented on July 21, 2024

I definitely want the granularity in this API that Ilya has proposed. And I'm OK with ceiling being how we get there. (Definitely seems to be the best route to shipping this)

But when that API ships, I would be doing this estimate research work on my own understand how to use it. :)

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@bluesmoon it's not useless, it's a cap - e.g. knowing that your cap is 384kbps (EDGE) can be incredibly useful. First, we know you won't ever exceed that limit, and second, it also allows you to estimate the RTT range... Once you get into higher G's, the BW range gets wider, and last mile latency range gets narrower. Yes, these are coarse signals, but they are still important, especially for delivering a better user experience for users on older generation networks, of which there are many... Something we often forget because most of us are walking around with latest generation devices that are connected to relatively fast networks (3.75G+).

@paulirish I do hope that, one day, we'll also expose bandwidthEstimate attribute, or some such, that would provide a situational end-to-end BW estimate.. However, that's a tricky area, and having the ceiling value does not conflict with this goal. If anything, if you want to rely on averages, you can map the ceiling values to some values that you determine are (more) reasonable for your location, etc.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

I've started adding bandwidthCeiling based on what we've discussed so far (see bandwidthCeiling branch). I've tied it to "Mbps". I've defined a "underlying connection type" concept - which I will link to the table of maximums once we have it.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

(we should bikeshed the bandwidthCeiling name later ... making people type addEventListener("bandwidthceilingchange") will not make us any friends 😄 )

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@marcoscaceres ceil is a common API name... Perhaps bandwidthceil, bwceil? The latter is nice and short, but kinda cryptic.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

@igrigorik, agree. Let's stick with bandwidthCeiling at least for now.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@marcoscaceres took a run at mapping different technologies to BW numbers... In the process, realized that some of the previous numbers in FF implementation were off: some types were mapped to wrong generations and some generations had wrong bitrates - bits vs bytes mixups, woops...

In w3c/netinfo@19ec1af#commitcomment-7498128, would it make sense to reference the suggested numbers? I want to make sure we end up reporting the same values across different UAs.

/cc @dougsillars can you do another quick sanity check on above spreadsheet?

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

@igrigorik looking good! thanks for doing the research. I'll start putting in the infrastructure into the spec to capture this once we triple check it.

I'll let Moz people know that their values are off. We should expect that we will make similar mistakes, so we should think of some system to reduce that risk. The citations you have are great - and most seem fairly authoritative.

In the spec, your ok for us to use kbits/s?

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

We need to decide what we are going to do for the other connection types.

If we add this data for "cellular", we probably need to do something for "wifi", "bluetooth", "ethernet", etc.

"other" is left to the implementation, with +Infinity as the default. Note that other + bw ceiling might form a fingerprint, so need to make a note there.

"unknown" will probably just return +Infinity.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

I'm sure there is a lot of room to bikeshed the exact ceiling numbers. That said, the more important part to me is that I can map a particular value to a type, and given the type I can then add a layer of additional smarts - e.g. combine some Geo + carrier knowledge to get a localized expected peak, or some average value (as @paulirish wanted). On that note, one thing that bugs me a bit at the moment is that HSUPA/HSDPA return same BW values -- which is true for download, but HSUPA offers a significant bump in uplink speed, which may be useful to know. Wondering if we could/should offset those a bit to make the distinction clear.

In terms of getting feedback, fixing errors, and adding new values in the future: what if we convert it into a standalone JSON struct, place it in the same repo, and reference it in the spec? That would make it easy to consume by external parties, with revision history, and so on. WDYT?

We need to decide what we are going to do for the other connection types.

In the spec, your ok for us to use kbits/s?

I can be convinced either way, but 1000Mbps for Ethernet would result in a lot of trailing zeros. Perhaps Mbps is better? As a crazy thought, even though link speeds are typically reported in bits.. My experience shows that most developers (myself included) often miss this and think its bytes - e.g. 384kbps for EDGE is 48kB/s! What if we reported in MBps?

from netinfo.

dougsillars avatar dougsillars commented on July 21, 2024

@igrigorik Are you proposing a a BandwidthUploadCeiling? :)

The numbers in the spreadsheet look accurate, and have great references (saving the link for future use).

from netinfo.

bmaurer avatar bmaurer commented on July 21, 2024

Just wanted to chime in here and say that at Facebook, we already use this type of data in our native clients. http://techcrunch.com/2014/08/27/facebook-turns-on-bandwidth-targeting-to-match-mobile-ads-to-network-quality/ is an example of how this can be useful to help serve ads to the right audience -- you wouldn't want to serve a video ad to a 2G user.

To be honest, I'm not sure how we'd use the bandwidth ceiling information. I assume that the enumeration of possible connection types would not change much over time, so I think we might end up having our own map of connection type -> quality. That said, I think it's a good thing to make sure that browsers can add new connection types and clients that don't know about that connection type can parse them in some reasonable way.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@dougsillars I really hope we can avoid that :)

@bmaurer thanks, great use case, and from what I understand the current announcement does not apply to web, just native - right? It'd be great to enable this for the web.

Re, how to use: all browsers should report same ceiling values for each underlying type (e.g. 384kbps for 2G EDGE), which you can then use to do a reverse-map to a type, or use the value directly (e.g. if BW ceiling > 1mbps, run a video ad). The benefit of reporting a numeric value, instead of an enum, is that the API continues to work in the future when/if we add new connection types, and also across different technologies... Also, if you have additional data, like Geo-specific info on how a certain connection type behaves in a particular geo region, or some such, you can easily add that on top of this API.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

@igrigorik so, we can do the JSON thing and keep the spec and JSON synchronized (i.e., we generate the table in the spec from the JSON file).

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

So, for the JSON, going with the following (hopefully calling it max-megabytes will help remind people to use MiB/s). We can, of course, bikeshed later - Any obvious problems with this structure?

{
  "cellular": [
    {"version": "", "max-megabytes":  0 }
  ],
  "bluetooth": [
    {"version": "", "max-megabytes":  0}
  ],
  "ethernet": [
    {"version": "", "max-megabytes":  0}
  ],
  "wifi": [
    {"version": "", "max-megabytes":  0}
  ]
}

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@marcoscaceres on first pass, LGTM. I'll put together a pull request with the right data.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

Ok, started adding stuff:
w3c/netinfo@8994703

  • fixed mixed content issue
  • added task source
  • started adding dependencies
  • switched to using megabytes
  • switched megabytes to unrestricted double (for +Infinity)
  • defined bandwidthCeiling and event
  • added "steps for getting the bandwidth ceiling"
  • defined more clearly "Underlying connection types"
  • added empty "Table of maximum theoretical bandwidths"
  • added "maxbws.json" file

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

GitHub didn't pick up the update, manual ping: see pull https://github.com/w3c/netinfo/pull/16.

There are a few nomenclature changes from what was discussed above (e.g. bandwidthCeiling is now downlinkMax) but the general idea and approach is the same. Please take a look!

from netinfo.

sicking avatar sicking commented on July 21, 2024

I'd prefer to only expose the "bandwidth" for cellular connections. On for example wifi and ethernet connections the actual connection bandwidth is usually irrelevant. Back when the spec contained just .metered and .bandwidth this lead to endless rathole discussions about the evilness of the .bandwidth property.

So I'd prefer to call this new property something like .cellDownlinkMax or .cellBandwidth or something to that effect. And make it return null except when .type === 'cellular.

The only use case that I could see lost there would be getting the bandwidth of a current bluetooth connection. But this seems like a pretty rare edge case.

from netinfo.

jkarlin avatar jkarlin commented on July 21, 2024

I'm in favor of this as an implementer as it's difficult information to
obtain for each connection type. Restricting to cellular is much easier.

On Wed, Nov 12, 2014, 3:54 PM Jonas Sicking [email protected]
wrote:

I'd prefer to only expose the "bandwidth" for cellular connections. On for
example wifi and ethernet connections the actual connection bandwidth is
usually irrelevant. Back when the spec contained just .metered and
.bandwidth this lead to endless rathole discussions about the evilness of
the .bandwidth property.

So I'd prefer to call this new property something like .cellDownlinkMax
or .cellBandwidth or something to that effect. And make it return null
except when .type === 'cellular.

The only use case that I could see lost there would be getting the
bandwidth of a current bluetooth connection. But this seems like a pretty
rare edge case.


Reply to this email directly or view it on GitHub
https://github.com/w3c/netinfo/issues/13#issuecomment-62791501.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

@sicking playing devil's advocate... I want to build an application that does some really intensive transfers (e.g. streaming high resolution 4K video), and try as I might, I can't jam the stream over 802.1b... it would sure be nice to know that upfront, such that I can adapt my logic. Similarly, WiFi has its bad network weather periods also, just because you're on 802.11g doesn't mean you'll get the full pipe.

I don't think we should special case cellular in the spec. We should keep the door open for UAs to improve their estimates and reporting in the future - e.g. if someone plumbs through WiFi signal strength and interface speeds, instead of just mapping to family, then that's great and we should allow for that.

from netinfo.

sicking avatar sicking commented on July 21, 2024

Exposing the bandwidth of the local connection is generally only useful if that local connection is the limiting factor.

If the user is on a wifi network, then it's almost certain that that wifi network is not the limiting factor. The cost of upgrading your wifi router is small enough compared to paying for a high quality internet connection that in practice people that pay for a faster internet connection will also ensure that they are on a wifi router that enables them to use that connection.

If 802.11b isn't fast enough for you, then netinfo likely won't provide you the data that you need. I.e. there's a high degree of risk that even if netinfo indicates that the user is on a fast ethernet or a fast wifi, that the actual internet connection on the other side of the local router will be the limiting factor.

The other situation when the wifi connection is the limiting factor is if you're on a crowded wifi network. But that too is not something that the current proposal will help with since it

I agree that it would be cool if the UA could estimate your actual internet connection speed. Back when the spec had a .bandwidth property we had a bunch of discussions at both W3C and mozilla about this. I think it's a good idea, but requires more research.

So my proposal is that we in the meantime just expose the local link speed. The simplest way to do that seems to be to just expose the cellular bandwidth. And explicitly define it as such rather than create a best-effort UA estimate that may or may not just look ad the connection type. I worry that anything beyond that will go the way of the previous netinfo spec, i.e. getting bogged down by allowing perfect to stand in the way of good.

Once we have experiments that show that we can provide useful bandwidth estimates then I'd be all for exposing that as well.

from netinfo.

igrigorik avatar igrigorik commented on July 21, 2024

Exposing the bandwidth of the local connection is generally only useful if that local connection is the limiting factor.

Give me any link speed, and I'll give you a case where I can saturate it. downlinkMax is relevant regardless of interface. Introducing cellDownlinkMax would only break APIs down the road.

For example, say we add wifiDownlinkMax, applications would then need to update their code to check for different XDownlinkMax variables based connection type... that's broken. If all I care about is speed, I shouldn't have to check for interface type. As specced, I can simply use downlinkMax and:

  • check for +Infinity as a signal that UA has no reasonable estimate - i.e. I'm on my own.
  • check for interface type if I have conditional logic - e.g. only fetch large files over WiFi, or some such.

In short, I think we should keep downlinkMax as a consistent attribute, regardless of interface. We don't win anything by adding more specific attributes.

from netinfo.

jkarlin avatar jkarlin commented on July 21, 2024

Ignore my previous comment, it's just implementer griping. I agree with Ilya that we should have a unified attribute for ease of coding. The more information the merrier.

That said, I think getting at the underlying connection technology for bluetooth/wifi will be challenging on a number of platforms, so expect a lot of +Infinitys.

from netinfo.

marcoscaceres avatar marcoscaceres commented on July 21, 2024

I agree with @igrigorik. We should keep downlinkMax as a consistent attribute.

@jkarlin, I think lots of +Infinitys are fine. We can always keep updating implementations and the spec to best serve the people who make use of this information.

from netinfo.

fahadbaig123 avatar fahadbaig123 commented on July 21, 2024

why not allow the data usage ceiling as a device level setting that the end user can setup.. I believe bandwidth is just one side of the coin the real issue lies in the data plan that the consumer has bought.. the control should be with the consumer in deciding how much data plan does he or she want the brands to use..

from netinfo.

Related Issues (20)

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.