Giter VIP home page Giter VIP logo

dribdat's Introduction

Github Actions build status codecov status FOSSA status

Tooling for time-limited, team-based, open-by-default cooperation

dribdat is an open source web application that assists teams working playfully on projects with data. Designed to support awesome hackathons and promote data expeditions, it is a ๐Ÿ‡จ๐Ÿ‡ญ Swiss Army Knife for civic techs: your events, guidelines, count-downs, challenge board, project log, progress tracker, integrating with prototyping tools, group chat, code repositories, open data APIs, and more!

Dribdat Logo

The philosophy of this project, in a nutshell, is: live and let live (no tech religion, use whatever design / dev / doc tools you want as long as they are accessible to your team), commit sustainably (aggregate outputs in standard web of data formats for optimal search and archiving), create in safe spaces (embedded code of conduct, works offline, minimal privacy footprint).

Install the software, read our Whitepaper, or try dribdat yourself at a community hackathon.

Screenshot of a Dribdat instance
A screenshot of an event page in Dribdat.

For more background and references, see the User Handbook. If you need help or advice in setting up your event, or would like to contribute to the project: please get in touch via Discussions or GitHub Issues. You can follow and support the project on OpenCollective or Codeberg

If you use Dribdat, please add yourself to the Tour de Hack! It only takes a minute, and knowing this helps keep the ๐Ÿ”ฅ alive.

Quickstart

The Dribdat project can be deployed to any server capable of serving Python applications, and is set up for fast deployment using Ansible or Docker. The first user that registers becomes an admin, so don't delay!

If you would like to run dribdat on any other cloud or local machine, there are additional instructions in the Deployment guide. Information on contributing and extending the code can be found in the Contributors guide, which includes API documentation, and other details.

See also backboard: a responsive, modern alternative frontend, and our dridbot chat client. Both demonstrate reuse of the dribdat API.

If you need support with your deployment, please reach out through Discussions.

Credits

This project is currently mantained by @loleg. See Contributors and Forks to find other users of this project.

Special thanks to the Open Data, Open Networking and Open Source communities in Switzerland for the many trials and feedbacks through over one hundred events.

This project is inspired by the work of many wonderful hackathonistas to the East, West, North, and South of here. We are grateful to F. Wieser and M.-C. Gasser at Swisscom for conceptual inputs and financial support at an early stage of this project. This application was based on Steven Loria's cookiecutter-flask, a more modern version of which is cookiecutter-flask-restful - and could be a good basis for your own hackathon projects.

Additional and โ™ฅ-felt thanks for your contributions to: Alexandre Cotting, Anthony Ritz, Chris Mutel, Fabien Schwob, Gonzalo Casas, Jonathan Schnyder, Jonathan Sobel, Philip Shemella, Thomas Amberg, Yusuf Khasbulatov .. and all the participants and organizers sending in bugs and requests! ๐Ÿค—

License

This project is open source under the MIT License.

Due to the use of the boto3 library for S3 support, there is a dependency on OpenSSL via awscrt. If you use these features, please note that the product includes cryptographic software written by Eric Young ([email protected]) and Tim Hudson ([email protected]).

dribdat's People

Contributors

dependabot[bot] avatar dominiwe avatar fossabot avatar gonzalocasas avatar jibaku avatar jonhesso avatar kinlearn avatar loleg avatar pyup-bot avatar ritzanthony avatar tirkarthi 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

Watchers

 avatar  avatar  avatar  avatar

dribdat's Issues

Implement caching on public views

While the Flask-Caching module has been in the app for quite some time, the views are still not actually wrapped. The performance of the home and event page in particular is quite low for larger events.

Custom project fields

Via @Cotting:

it would be great to be able to automatize the creation of a document linked to the project, accessible by all. I personally chose to add links to Google docs as it was very easy to use for the participants and with a version management. But it was a hassle for me to create and configure all those documents.

The previous hackathon platform we used, DokuWiki, had a custom template which teams filled out with infos. It would make sense to make the project fields more flexible, with some additional questions added by the event organiser.

We recently used this approach - via sodabot/API - at the Climathon. Notice how all the projects follow the same text template.

Display project participants

Right now this can be done directly in the project description, using markup to add avatars if desired. Alternatively, we could show the avatars of all people registered on the forum on the event home page. Or just manually entered avatars / names of team members on project page.

Event description breaks OpenGraph support

Event pages which have breaks and HTML codes (like view-source:https://hack.opendata.ch/event/22 ) do not render nicely in OpenGraph compatible sites. Offending tags and line breaks should be automatically trimmed. But also, we should consider adding specific META sections to the event description for tailoring the way this is presented also in #112

Replace ownership with history

Make the project database into a wiki, allowing anyone to edit any project. However, keep a history log in order to blame or revert changes.

Furthermore, admins should be able to edit any project details.

Unable to setup with Python3 under Debian testing

I followed the instruction in the readme. And got the following error

 python3 manage.py db init
Traceback (most recent call last):
  File "manage.py", line 10, in 
    from dribdat.app import init_app
  File "/opt/src/dribdat/dribdat/app.py", line 5, in 
    from dribdat import commands, public, user, admin
  File "/opt/src/dribdat/dribdat/public/__init__.py", line 3, in 
    from . import views, auth, api  # noqa
  File "/opt/src/dribdat/dribdat/public/views.py", line 7, in 
    from dribdat.user.models import User, Event, Project
  File "/opt/src/dribdat/dribdat/user/models.py", line 9, in 
    from dribdat.extensions import hashing
  File "/opt/src/dribdat/dribdat/extensions.py", line 6, in 
    from flask_oauth import OAuth
  File "/home/niklaus/.local/lib/python3.5/site-packages/flask_oauth.py", line 13, in 
    from urlparse import urljoin
ImportError: No module named 'urlparse'

Tested on Librem Laptop, running a debian testing with Python 3.5.4 installed.

Help to orient future development

Two years and 99 issues since this project started, I would like to get some feedback on how to orient, organize and optimise future development. Some background on the project status and mission is in ABOUT.md. Additional discussion is on a related forum thread. Or you can jump straight into the project board to help sort through top issues.


At time of writing there are 217 hackathon projects in the make.opendata.ch wiki, 90 projects published on hack.opendata.ch, 21 at now.makezurich.ch and dozens more on archived sites like IoT 2015 and 1001001. Many, many more are published by the open data community on other platforms (GitHub, OGD portals, university websites, etc.)

On their own, each of these is an interesting and inventive contribution to the community, the beginnings of a grassroots collaboration, a research direction, a startup... As a whole, the projects can be a rich source of information both on the history/evolution of the open data movement, as well as a references to the experience of participants with various data sources and platforms. Our old wiki platform has many downsides - first and foremost the difficulty to aggregate data about projects (status, team members, etc.) - which was one of the motivators for Dribdat, something that has been worked on with contributions and support from several core members the Opendata.ch community.

We have been discussing the idea of running more development sprints on Dribdat: updating it's backend, giving the frontend a refresh, further work on the chatbot interface and adding a better mobile frontend, moving it within the main infrastructure at Opendata.ch (it is currently hosted on the server of Datalets.ch), migrating data from past events on Make.Opendata.ch, integrating it with our community platforms (sites, blogs, forums, social media), and scaling it out to many more events and users using a SaaS model (click a button to start your own hackathon..)

Critically, this all should be done with a view to the wider usefulness of the tool, so it would be great to solicit feedback and collaboration from Open Knowledge and other closely aligned communities.

The sprint goal could sound something like this: develop our framework for bootstrapping and supporting projects from hackathon to startup, with a focus on community building, event support, use of data sources, and documenting progress, with plug-in support for on-prem and on-cloud collaboration. A longer term organisational goal could be: create the go-to platform for discovering, certifying and funding development of open data sources. As a stretch goal, we could: promote the cause of open development and open data, hackathons and civic activism, invite contribution and use by the international community.

The project has so far progressed mostly on contributions of free time, about 2 K CHF allocated towards short sprints out of the budget of events over the past two years. Even a small amount of motivation or support from the user community would help to motivate progress.

Here are some ways I can think of that people could contribute:

With moderate support, we could move to better infrastructure and support a self-service model, and carefully migrate project data to showcase a variety of community initiated open data projects. With good funding, all of the above plus integration with data portals and community tools could be imagined. With significant resources, and greater purpose, we could potentially rewrite the whole project using modern technologies like streaming data, reactive programming, blockchains, etc. But we need to start somewhere: spend at least a little time this summer dusting off the code base and closing some of the issues, and all kinds of contributions and support are welcome.

If you are interested in helping us to move forward with these plans, or think we should stop right here and do something more productive: please leave a note or just click the voting button as a sign of support. Thanks! -- @loleg

User experience and facilitation of data entry

The easiest way to use Dribdat right now is to avoid using it at all: https://github.com/loleg/sodabot has a (admittedly rather fiddly) script which allows participants to update their projects in a Slack channel. Nevertheless, people tend to (mostly uncomplainingly) use the same plain old form to work on their projects that we've had from the beginning. This could be dramatically improved with not too much effort: for instance:

  • by putting into a wizard and better explaining the steps
  • simplifying the vocabulary
  • allowing edits directly on the page
  • have a tutorial or video explanation of the process
  • #92

Though less of a priority, the event forms could be improved in the same fashion. For instance, users like to customize the CSS of their site, but they may not know how to host a CSS file on GitHub (which is recommended in the form) and instead add code directly to the very clunky interface. The event form has many fields, and is disconnected from the process of creating challenges (further discussed in #93).

The goal of this issue is to analyse the problem and propose a strategy to revise or replace the UX of the interface.

Challenges view

In the newer version of Dribdat, there is a challenges toggle button (a Trophy icon) in the event page which currently hides the challenges. But when there are a lot of projects, what we really want to do is hide the projects. Make it do that on a second click, toggling between projects and challenges after the initial state. Also, make sure the button works in list view.

Alternate idea: make the separation of projects and challenges more clear visually.

Improve form entry and validation

A text is shown under each field which explains if its optional. Fields are highlighted in red if they are required. It was also suggested that we could add a star next to required fields. We should improve validation, and re-design the form - potentially as multi-page wizard or Discourse-like editable fields.

Connect project data sources

Data from the projects could be shown on the description of the projects simply by embedding into the Markdown. For supported platforms (e.g. we considered plugging in ThingSpeak API and others), the activity level of this data feed could actually contribute as a factor in the score. Collect other ideas and propose a plug-in strategy.

Externally hosted web resources

Currently custom CSS is edited directly in the Admin interface, which is unsatisfactory for several reasons. Most web designers would probably prefer to host custom styles on an external site or CDN - allow adding custom CSS and JS to the event.

For the time being, for stylesheets this can be solved using the @import instruction in the CSS, scripts using the community tag.

Visualise event analytics

Through activity logs, we have a simple built-in analytics system on Dribdat. This has been visualised by hand from past events like this:


(Source)

Make it possible to see graphs like this directly in the platform, and export data via API. An infographic type display showing how many participants, projects, contributions there are, would be great. For inspiration see https://github.com/features/insights

Self-tracking of projects

Right now scoring is fully automatic, and project status can be written up in the description. Some teams may like to manually enter their status (ideally with a simple interface), like:

  • How far along in their project (non-quantified self assessment)
  • Flag any problems/roadblocks to others, e.g. design support needed, special materials, etc.
  • A bar goes from red to yellow to green based on the assessment

This information can be used by the organisers to optimise the experience for all teams.

Unable to login from Safari (Python 3)

On certain server configurations, a user of Safari browser was unable to login or register for an account. The server logs contain this message:

Exception on /login/ [GET]
Traceback (most recent call last):
  ...
  File "/srv/soda/dribdat/dribdat/public/auth.py", line 32, in login
 line 43, in process
    self.current_token = self.csrf_impl.generate_csrf_token(self)
  File "/srv/soda/dribdat/env/lib/python3.4/site-packages/flask_wtf/csrf.py", li
ne 134, in generate_csrf_token
    token_key=self.meta.csrf_field_name
  File "/srv/soda/dribdat/env/lib/python3.4/site-packages/flask_wtf/csrf.py", li
ne 47, in generate_csrf
    setattr(g, field_name, s.dumps(session[field_name]))
  ...
  File "/usr/lib/python3.4/json/encoder.py", line 173, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: b'daefd4f311284ca5ce9cf4503bfba12c55918eb0' is not JSON serializable
127.0.0.1 - - [23/Jan/2017 17:38:04] "GET /login/ HTTP/1.0" 500 -

This could be related to this issue.

This happens only when running Dribdat on Python 3, and is related to string conversion (Unicode from octet).

Not sure why it only affects a specific browser, though.

Embed event

For external event pages, it would be nice to have the countdown and other details from Dribdat embeddable in an IFRAME.

Negative numbers in countdown

During the hour after the event start-moment, and after the finish-moment, the front page counter is in a strange state, with negative numbers. This may also be due to an incorrectly (or inconveniently) configured end-date. See if the JS component could be improved in this.

Ideation via public repo issues

From @Cotting a request for an ideation board feature:

How could we facilitate the idea creation before the event? Like letting anyone make challenge proposals and let the rest of the community comment those ideas.

Open Data Day Zurich had some JavaScript in place to connect to the GitHub API, and collect the list of challenges - posted in the form of issues in a dedicated repo. It might certainly help some organisers to have this out of the box, with perhaps some alternative engines supported (Sparkboard? Trello?...)

Project distinctions

Add an interface for platform admins to add comments (such as awards or other "microboosters") to project. These should show up in the form of badges on the project profile, and be visible (border colors, pixel icons, ..) in the project list.

Sync replacing "Banner image link" with user's profile

When I sync from the linked Github repo's Readme.md, the project page replaces any existing Banner Image with the user's profile photo from Github.

I think this is not desired behavior, because the user's github profile photo has nothing to do with the project. Possible solutions would be a "banner.png" file in the Github repo, or just removing the sync for "Banner image link" if it has been manually set.

Forking projects

If someone adds a challenge, someone else should be able to start a project based off of it, with a link between the two. To make it simple, the "fork" could just be a link to the GitHub/etc. fork page - the resulting link pasted into a blank new project page.

Document and REST-ify API

While a basic API description is in the README and we already use the API for interesting things like chatbots, the support is currently very basic. Integration with tools like Flask API and Swagger (via Flask RESTplus or Flask Restless) would help make the platform more interesting for other developers. Ideally we would also make the API bi-directional (fully RESTful) through this effort.

Override autosync data

Make it possible to use different titles, images, etc. in autosynced projects.

Using a separate data structure to keep the latest snapshot, the Dribdat fields could act as overrides.

Feature requested by @5igno

Project bootstrapping

To add value for newcomers, we could recommend quick starters for deployment of a web page, sensor dashboard, "hackathon project" etc. This could be just a prominent, user configurable link to a guide located elsewhere.

Integration with community platforms

We already have integrated our platform with several Single Sign-On providers and chatbots. However, we want to be able to support other and potentially multiple community platforms. What do we mean by this? These are the platforms where interaction and exchange takes place between participants. These could be GitHub discussions, Slack channels, Gather spaces. The goal of this ticket is to clarify what "integration" means.

The questions are:

  • Which integrations make the most sense to our users?
  • Do mechanisms are there to provide integration?
  • What barriers are there to implementation?

Additionally it is important to put more weight behind integration with other open source platforms. Adding Mattermost support to dridbot, SSO and full aggregation support for GitLab, easier integration with Discourse.

The task here is to research the options, suggest which route would be most straight forward, and implement the integration. See also #118

Widen Autofill support

Only GitHub is supported right now for autofilling project details. What other platforms do people use to document their projects? Add support for Bitbucket, wikis, etc.

Add support for project presentations

When the time of final presentations arrives at a hackathon, all projects need to submit their slides one way or another. Some teams do it with online tools (e.g. Google Slides, slides.com, etc), others with offline tools (e.g. PowerPoint, Keynote).

Dribdat should have a way for team members to upload or link slides, and ideally, also a way for the administrator to sort the projects in the order in which they will present. The sort order of projects for presentations should be a manual one, since it is usually the result of dealing with external factors -i.e. I need to go first because I need to catch a plane.

Dataset description

Datasets have quite a central role in many hackathons as being part of a challenge. What we are looking for here is the ability to link to Data Packages and open data portals, loading and displaying the metadata directly from an event or projects. The dataset description should follow the event description, as requested by @Cotting - not the other way around. Also the link to the data resources in the navigation needs to be improved. Challenges in the form of a Data Package could be featured as in [this example], while others can be listed as GitHub issues were visualized as project ideas in this Open Data Day event, or as Data Packages are being shown via Datacentral in the Food Open Data events. Integration with CKAN as done in the GLAM event is also of interest.

Experimental support for Data Packages has been available for a while, i.e. by providing a link that ends with datapackage.json the contents are collected into a project similarly to GitHub repositories and other platforms. However, this is currently not working properly due to some legacy issues, and not a very satisfactory implementation to begin with. The current technical support needs to be improved along side with some design thinking about how to make this work well for the user.

See also #208 #212 #222

Validate user account on SSO registration

An error comes up if a non-SSO user with the same email address is present in the system:

2017-01-19T12:51:12.608482+00:00 app[web.1]: IntegrityError: (psycopg2.IntegrityError) duplicate key value violates unique constraint "users_email_key"

As reported by @gonzalocasas - linked to #63

Error saving projects with embeds

When submitting a project edit form that contains remote resources (embedded widgets, iframes, scripts, etc.), the user sees a nasty ugly error - and may rightly assume that something went wrong. This is due to browser security feature. However, on refreshing the project page, the edits are actually saved fine. Address this by detecting embedded resources, flagging them to an admin as a potential security risk, and save the page through an Ajax call or otherwise handle the error.

Related: #123 #91

screen shot 2018-11-19 at 18 16 57

Screenshot by @NikkiJoy

Voting on projects

In the current version the LIKE button has been replaced with JOIN. It could still be nice for people to thumbs up each others projects. However, since this has been abused in the past, make this possible only for logged in users, and implement a CAPTCHA. Alternatively, look into ways of integrating with other platforms (e.g. social media / saythanks).

Then, of course, we need a High Score page (revamped search result?) with the top Boosted / Voted / Completed projects, filterable by event or keyword.

Add Slack as a login provider

Slack provides an SSO feature called "Sign in with Slack". Most of the information on how to integrate it is contained in this one page: https://api.slack.com/docs/sign-in-with-slack

It's basically just an OAuth 2 flow: register dribdat instance as a Slack app, add the Sign in with Slack button (whose html can be generated there), and then handle oauth code/token exchange thing in the app.

One of the cool things is that it seems this integration doesn't count towards the integration limit so it can be used by free trans without problems.

Ability to archive events

Once a hackathon has passed, the event owner should be able to lock the page and all the projects listed on it from editing. In other words a static snapshot should be served instead. Any projects or challenges that are continued in another hackathon could then be re-attached or forked (#92), without changing the contents of the original page.

Currently this is a process clunkily accomplished to some extent with web scraping your own site:

wget -mkEpnp https://my-dribdat-site...

Additionally some web server configuration needs to happen, e.g. for Nginx:

        location /(event/|project/)static {
                alias [path-to-dribdat]/static;
        }

Dynamic (ie. real) dashboard

The live dashboard was hacked together during the hackathon last weekend, and although it showed real data, it was maintained by hand in a static HTML file. It should be converted into a public view, the social feeds need to be added to the event configuration, a link should be provided somewhere for the organisers to see (admin panel?), and live data (e.g. activity) should be shown in a dynamic graph.

Versioning the fields

One of the questions I get asked most is how could teams work on the same project documentation. I tell them that they should use GitHub, Etherpad, etc., but really this should be built into the platform. For example, the default page content could be a blank Etherpad, if a default provider is configured.

The technical issue is overwriting of project data if people tried to edit simultaneously. Building in a wiki with versioning or a multiuser editor would be the way forward. Page locking and allowing team members to edit would be a midway solution.

Single sign-on

Users should only need to make an account on the platform, and be automatically signed on to DRIBDAT using SSO. We already explored but did not finish integration with Discourse (pydiscourse). Consider plugging in popular providers.

Mechanism for hackathon discoverability

In the context of the hackathon-in-a-box idea, a core requirement is to have discoverability of at least two main things related to a hackathon:

  • Event details
  • Hackathon projects

Discoverability implies machine-readable formats and standardized access patterns. Dribdat already tracks projects and a significant part of the event details, so this information needs to be exposed, but in a standard way to allow others to implement it without the need to run dribdat. The two parts (Event details and Hackathon projects) have potentially different implementations, and conceptual differences, so I will describe them separately.

Event details

Conceptually, this would be a mechanism similar to schema.org, robots.txt, or micro-format specification, to describe the hackathon's metadata in a machine-readable way and with a focus on machine discoverability as well.

Schema.org has a format for generic events, and some sub-classing for specific event types, but none of them fits exactly a hackathon: http://schema.org/Event.

On the other hand, the simplicity of a root-level file descriptor (i.e. robots.txt, humans.txt, etc) is extremely appealing.

So the proposal would be to define a root-level hackathon.json file containing the following (tentative) metadata about the hackathon:

  • event name
  • event date(s)
  • event location(s)
  • topics
  • sibling events: list of links to other domains containing hackathon.json descriptors to enable event chaining)
  • projects API: link to a json API to access projects presented at the hackathon (the API would be integral part of dribdat, but at the same time, should be a well-defined standard that other platforms can implement. See next section)

The sibling event link list creates a crawlable graph that connects events to each other, fostering discoverability in general, and also establishing a relations between events.

This root-level file descriptor should be placed at the event's main website's root.

Hackathon projects

A second level of detail in the meta-description of an event is its actual content, i.e. the projects presented during the event. For this, Dribdat already hosts all the information required, and the only additional need to be to expose it over a well-defined JSON end-point and format/spec.

As mentioned in the previous section, this end-point would be linked from the root-level file descriptor through the projects API property.


In combination these two metadata end-points would allow an event/hackathon to self-describe itself in a fully decentralized manner while allowing the creation of a graph of events to keep things tied together (for a multitude or reasons: forked events, friend events, topical events, etc).

On top of it, additional tools and services (also decentralized) could be created by crawling and visualizing the event graph in various ways. For instance, this community event calendar could be generated out of this data.

Detect and correct relative links on sync

When a (for example, GitHub) repository is used for project data, any relative links (most likely, embedded images) stop working correctly on Dribdat. The process should discreetly correct this, converting relative links to absolute by prepending the project's root URL.

Thanks to @IchEssBlumen for pointing it out at #twist2018

Timezone support

When the server time does not match the event location timezone, things get confusing.
Add an environment variable to offset the UTC timezone. Then update the countdown property and other areas where the time should be presented relative to server time.

Update to FlaskForm

Warnings in console:

dribdat/public/views.py:97: FlaskWTFDeprecationWarning: "flask_wtf.Form" 
has been renamed to "FlaskForm" and will be removed in 1.0.
  form = ProjectForm(obj=project, next=request.args.get('next'))

Make trailing slash optional

A minor annoyance, sometimes links are broken when they have a trailing slash, e.g. ../project/123/ instead of ../project/123

It would also be nice if after an edit the user is redirected to a regular (shareable) project link.

And even nicer if the project line was human-readable (had a minified title of the project) as well as the ID (see how Discourse does this).

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.