Git Product home page Git Product logo

nal-i5k / genomics-workspace Goto Github PK

View Code? Open in Web Editor NEW
14.0 6.0 5.0 454.78 MB

Django website project for common sequence search tools.

Home Page: http://genomics-workspace.readthedocs.io/

License: Other

Shell 0.95% Python 19.67% CSS 12.49% JavaScript 54.00% HTML 10.89% Batchfile 0.42% Makefile 0.43% Dockerfile 0.02% Less 1.13%
django blast hmmer clustal bioinformatics django-application django-blast django-hmmer django-clustal ncbi-blast

genomics-workspace's Introduction

Genomic-Workspace

Build Status codecov codebeat badge Documentation Status

Genomics-Workspace is a bioinformatic website project created by i5k Workspace. It provides common sequence search services including BLAST, HMMER, and Clustal. To see it in action, please visit following live sites:

Features

Backend

  • Implemented in Python with Django.
  • Supports searches for BLAST, HMMER, and Clustal.
  • Task queue with Celery and RabbitMQ.
  • Use PostgreSQL as database backend.
  • BLAST:
    • Generates several BLAST output formats for download: Text, TSV, XML, ASN.1.
    • Converts BLAST output to GFF3 by grouping contiguous HSPs with identical query sequence, subject sequence, strand direction and an overlap length less than 6 between neighbouring HSPs under the same match.
  • Retrieve previous results with a unique URL for every task.
  • Supports both Linux and MacOS.

Frontend

  • Special BLAST visualization powered by D3.js and JQuery.
    • The results page is an interactive data viewer, query and subject coverage graphs on the top are drawn dynamically on the HTML5 canvas for every high scoring pair (HSP), tabular output from BLAST+ is displayed in a sortable and searchable table on the bottom right, pairwise text output is displayed on the bottom left panel.
    • Fullscreen design dynamically scales to any screen size
    • Dynamically draws a unique query coverage graph and a subject coverage graph for every high scoring pair(HSP) on HTML5 canvas.
    • Interactive graph updates the page as the user mouse over each aligned segment.
    • Graph zoom level and line height are first calculated according to the data and screen size, but can be easily adjusted to user's preference using the sliders on the left and right sides of each graph.
    • Interactive results table updates the page as the user:
      • Mouse over each row.
      • Changes the sorting column.
      • Filters the table using the search box.

Screenshots

BLAST Results BLAST Results

Prerequisite

  • Python 2.7
  • npm
  • RabbitMQ
  • PostgreSQL
  • mod_wsgi (optional, only for production)

Documentation

Docs can be found at genomics-workspace.readthedocs.io.

How to contribute

You're highly encouraged to participate in the development of genomics-workspace. Check the CONTRIBUTING.md first and start contributing !

genomics-workspace's People

Contributors

chienyuehlee avatar childers avatar deming7h777 avatar dependabot[bot] avatar g8tor avatar hotdogee avatar hsiaoyi0504 avatar hsiukanghuang avatar ifishlin avatar jsuriol avatar jwlin avatar mpoelchau avatar pyup-bot avatar r06942072 avatar suryasaha avatar vernonchapman-usda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

genomics-workspace's Issues

Adding blast & hmmer database by script

Also make the script for blast and hmmer that can add the database by one command and can be easier to integrate with CWL.

ideal command : python manage.py addblast [Genus] [species] -t [sequence_type] -f [fasta_filename]

Best practice for migrations of Django project

As described in this stackoverflow question:
https://stackoverflow.com/questions/33784362/django-migrations-best-practice

The same question comes to my mind when I first started working on this project.
During the configuration step, we need to makemigrations and migrate, which is different from my previous experience of other django project (although I didn't work on model part of MTV framework). Maybe we should consider to follow this kind of best practice?

Fail to receive the argument from command line

Due to "manage.py" module we can not directly import argparse to get the argument we want from command line.

Need to put our function under "Command" Class which inherit the "BaseCommand" Class
and use its own "add_arguments(self,parser)" to get the argument,

e.g. python manage.py addorganism Anoplophora glabripennis

problem getting FASTA sequences from the search db

Not sure why I'm getting 404 errors. I reran the command to populate the Sequences database. :

06/Aug/2018 15:53:42] "GET /favicon.ico HTTP/1.1" 404 2980
Not Found: /blast/task/api/seq/gnl|Eurytemora_affinis|euraff_Scaffold502/
[06/Aug/2018 15:54:34] "GET /blast/task/api/seq/gnl|Eurytemora_affinis|euraff_Scaffold502/?format=fasta HTTP/1.1" 404 4146
Not Found: /blast/task/api/seq/gnl|Eurytemora_affinis|euraff_Scaffold579/
[06/Aug/2018 15:54:37] "GET /blast/task/api/seq/gnl|Eurytemora_affinis|euraff_Scaffold579/?format=fasta HTTP/1.1" 404 4146

Replace kendo.js with grid-css in the blast-results page

We recently had issues with using our normal header in the Django app, specifically the blast-results page. This was caused by some hard coded assertions in the kendo.js code that lays out the divs for the panels in the page.

I would like to replace the kendo js with grid-css for layout. There are several benefits to using this including the ability to mix absolute and fractional sizes in a layout, and since it is css it is native to the browser and does not require additional code or us to post additional license information.

Some references:

https://christianheilmann.com/2017/06/21/css-vs-javascript-trust-vs-control/

Guides for implementing grid-css

http://cssgridgarden.com/
https://medium.com/flexbox-and-grids/how-to-efficiently-master-the-css-grid-in-a-jiffy-585d0c213577

@hsiaoyi0504 mentioned that this is not universally available, so I checked with caniuse.com. They report that is should be supported in ~87% of browser installations.

https://caniuse.com/#feat=css-grid

Add alt-text to manuals

Split addblastdb to 3 steps

For adding blast db we need to split to 2 step,

  1. Pick the organism from organism table to add to the blast database
  2. Can execute makeblastdb separately
  3. Populate to the sequence table

BLAST redesign

  1. Legacy blast is a very clean and stable interface that also works well on smaller screens. (General display)
  2. Vigilance on simple mouse-overs without clicking seems to be necessary to ensure that I continue to select the intended organism in setting up a blast query. (Submission page)
  3. When working on complicated genes, which require iterative blasting or blasting for specific exons or motifs individually, the back browser functionality of the legacy system recalls the species and the type of blast (e.g., tblastn) automatically, which saves time and worry. (Going from results back to submission and keeping some settings see #119 (closed))
  4. Also, there never seems to be smooth scrolling navigability within the blast search results subwindows, and where results always require up-down and left-right scrolling. (Results page)
  5. I repeatedly struggle to select the results I want to view and to ensure that I'm actually at the top of the blast hits and haven't inadvertently scrolled down without noticing. (results page)

Need to test jquery 3.3.1

The version of jquery we're using now has security issues, and we'll need to update it before any more deployments.

Add debugging feature to the script

To let the user know for the internet connection error , we can add more conditional expression to the script and also check the data extracted from wiki and NCBI are correct or not.

Load-nucletide loads peptide sequence

As shown in following lines:
The ex_nucleotide is a peptide sequence, not a nucleotide sequence. I will fix it later.

var ex_nucleotide = ">CLEC010822-PA:polypeptide ,Heat shock protein 70-2\n\
MILHFLVLLFASALAADEKNKDVGTVVGIDLGTTYSCVGVYKNGRVEIIANDQGNRITPSYVAFTSEGERLIGDAAKNQLTTNPENTVFDAKRLIGREWTDSTVQDDIKFFPFKVLEKNSKPHIQVSTSQGNKMFAPEEISAMVLGKMKETAEAYLGKKVTHAVVTVPAYFNDAQRQATKDAGTISGLNVMRIINEPTAAAIAYGLDKKEGEKNVLVFDLGGGTFDVSLLTIDNGVFEVVSTNGDTHLGGEDFDQRVMDHFIKLYKKKKGKDIRKDNRAVQKLRREVEKAKRALSSSHQVRIEIESFYDGEDFSETLTRAKFEELNMDLFRSTMKPVQKVLEDADMNKKDVDEIVLVGGSTRIPKVQALVKEFFNGKEPSRGINPDEAVAYGAAVQAGVLSGEQDTDSIVLLDVNPLTLGIETVGGVMTKLIPRNTVIPTKKSQIFSTASDNQHTVTIQVYEGERPMTKDNHLLGKFDLTGIPPAPRGVPQIEVTFEIDANGILQVSAEDKGTGNREKIVITNDQNRLTPDDIDRMIKDAEKFADDDKKLKERVEARNELESYAYSLKNQLADKDKFGSKVTDSDKAKMEKAIEEKIKWLDENQDADSEAFKKQKKELEDVVQPIISKLYQGGAPPPPGAGPQSEDDLKDEL*\n\
>OFAS004830-PA:polypeptide ,Heat shock protein 70-2\n\
MAAGGSRPTRPAVGIDLGTTYSCVGYFDKGRVEIIANDQGNRVTPSYVAFTETDRIVGDAARGQAIMNPSNTVYDAKRLIGRKFDDPSVQADRKMWPFKVASKEGKPMIEVTYKGETRQFFPEEISSMVLSKMRETAESYIGKKVSNAVVTVPAYFNDSQRQATKDSGTIAGLNVLRIINEPTAAAVAYGLDKKGSGEINVLIFDLGGGTFDVSVLTIADGLFEVKATAGDTHLGGADFDNRMVQYFLEEFKRKTKKEVNDNKRALRRLQAACERAKRVLSTATQATVEIDSFVDGIDLYSAVSRAKFEEINSDLFRGTLGPVEKAIRDSKIPKNRIDEIVLVGGSTRIPKIQSLLVEYFNGKELNKTINPDEAVAYGAAVQAAIIVGDTSDEVKDVLLLDVTPLSLGIETAGGIMTNLIPRNTTIPVKHSQIFSTYSDNQPGVLIQVYEGERAMTKDNNLLGTFELRGFPPAPRGVPQIEVAFDVDANGILNVTAQEMSTKKTSKITITNDKGRLTKAQIEKMVKEAERYKSEDTAARETAEAKNGLESYCYAMKNSVEEAANLGRVTEDEMKSVVRKCNETIMWIEANRSATKMEFEKKMRETESVCKPIATKILSRGTQQNNAGGGTPTNERGPVIEEAD\n\
>OFAS004738-PA:polypeptide ,Heat shock protein 70-1\n\
MPAIGIDLGTTYSCVGVWQHGKVEIIANDQGNRTTPSYVAFSDTERLIGDAAKNQVAMNPQNTVFDAKRLIGRKYDDPKIQDDLKHWPFRVVDCSSKPKIQVEYKGETKTFAPEEISSMVLVKMKETAEAYLGGTVRDAVITVPAYFNDSQRQATKDAGAIAGLNVLRIINEPTAAALAYGLDKNLKGERNVLIFDLGGGTFDGPREQDHSLKGERNVLIFDLGGGTFDVSILTIDEGSLFEVKSTAGDTHLGGEDFDNRLVNHLAEEFKRKYRKDLKTNPRALRRLRTAAERAKRTLSSSTEASIEIDALFEGVDFYTKITRARFEELCSDLFRSTLQPVEKALQDAKLDKGLIHDVVLVGGSTRIPKIQNLLQNFFNGKSLNMSINPDEAVAYGAAVQAAILSGDQSSKIQDVLLVDVAPLSLGIETAGGVMTKIIERNTRI";
var ex_peptide = ">M.tuberculosis H37Rv|Rv2565|Rv2565\n\
MTTARRRPKRRGTDARTALRNVPILADIDDEQLERLATTVERRHVPANQWLFHAGEPADSIYIVDSGRFVAVAPEGHVFAEMASGDSIGDLGVIAGAARSAGVRALRDGVVWRIAAETFTDMLEATPLLQSAMLRAMARMLRQSRPAKTARRPRVIGVVSNGDTAAAPMVDAIATSLDSHGRTAVIAPPVETTSAVQEYDELVEAFSETLDRAERSNDWVLVVADRGAGDLWRHYVSAQSDRLVVLVDQRYPPDAVDSLATQRPVHLITCLAEPDPSWWDRLAPVSHHPANSDGFGALARRIAGRSLGLVMAGGGARGLAHFGVYQELTEAGVVIDRFGGTSSGAIASAAFALGMDAGDAIAAAREFIAGSDPLGDYTIPISALTRGGRVDRLVQGFFGNTLIEHLPRGFFSVSADMITGDQIIHRRGSVSGAVRASISIPGLIPPVHNGEQLLVDGGLLNNLPANVMCADTDGEVICVDLRRTFVPSKGFGLLPPIVTPPGLLRRLLTGTDNALPPLQETLLRAFDLAASTANLRELPRVAAIIEPDVSKIGVLNFKQIDAALEAGRMAARAALQAQPDLVR\n\
>TCALIF_07877-PA protein Name:'Similar to Actin, muscle (Manduca sexta)' AED:0.01 eAED:0.01 QI:143|1|0.5|1|1|1|2|0|376\n\
MCDEDVAALVVDNGSGMCKAGFAGDDAPRAVFPSIVGRPRHQGVMVGMGQKDAYVGDEAQSKRGILTLKYPVEHGIITNWDDMEKIWHHTFYNELRVAPEEQPVLLTEAPLNPKANREKMTQIMFETFNMPAMYVAIQAVLSLYASGRTTGIVMDSGDGVSHTVPIYEGYALPHAILRLDLAGRELTNYLMKILTERGYSFTTTAEREIVRDIKEKLCYVALDFEQEMATAAASTSLEKSYELPDGQVITIGNERFRAPEALFQPSFLGMESCGIHETTYNSIMKCDVDIRKDLYANTVMSGGTTMYPGIADRMQKEITALAPSTIKIKIIAPPERKYSVWIGGSILASLSTFQQMWISKQEYDECGPSIVHRKCF\n";
$('.load-nucleotide').click(function() {
$('#query-textarea').val(ex_nucleotide);
$('#query-textarea').keyup();
});
$('.load-peptide').click(function() {
$('#query-textarea').val(ex_peptide);
$('#query-textarea').keyup();
});

Figure out the customized part of jquery-ui.css

When I worked on #631 today, I found that jquery-ui.css (used in result page of blast search) is a customized version of jquery-ui.css, although its name looks like without customized. We should figure out customized part and separate that part from library. That will make our future upgrade more easily. To figure out which part is customized, I noticed that the orange background in result page of blast search comes from that file.

Detecting js error in layout.html

On our production, we replace

{% block head-scripts %}{% endblock %} in layout.html

into

<script>window\.jsErrors=[];window\.onerror=function(errorMessage)\{window\.jsErrors[window\.jsErrors\.length]=errorMessage;\}<\/script> \{\% block head-scripts \%\}\{\% endblock \%\}. We should implement this directly on template in debug mode (that is, when `DEBUG = True`).

Deprecated url patterns

An usage of old-styled url pattern I found when I traced the current codebase. As described here. The usage of patterns() is deprecated in 1.8, and will be removed in 1.10. It will not be a issue if we don't upgrade to 1.10. It's just documented here for future reference.

Initial Update

The bot created this issue to inform you that pyup.io has been set up on this repo.
Once you have closed it, the bot will open pull requests for updates as soon as they are available.

All feature under manage.py command

For the ideal result of all the command for handle django database:

addorganism : python manage.py addorganism Aethina tumida

addblast : python manage.py addblast Aethina tumida -t peptide protein -f GCF_001937115.1_Atum_1.0_genomic.fna

makeblastdb : python manage.py blast_utility GCF_001937115.1_Atum_1.0_genomic.fna -m

populatesequence : python manage.py blast_utility GCF_001937115.1_Atum_1.0_genomic.fna -p

addhmmer : python manage.py addhmmer Aethina tumida -f GCF_001937115.1_Atum_1.0_genomic.fna

make blast is_shown:
python manage.py blast_shown GCF_001937115.1_Atum_1.0_genomic.fna --shown true/false
delete feature:
python manage.py delete -o Aethina tumida

python manage.py delete -b GCF_001937115.1_Atum_1.0_genomic.fna

python manage.py delete -h GCF_001937115.1_Atum_1.0_genomic.fna

Remove duplicate requirements.txt

There are two files recording python dependencies, requirements.txt and requirements_new.txt. It seems that requirements_new.txt was accidentally added one year ago. It should be removed because it may cause some confusion. It's a minor change, but I think it can be totally removed from git history.

[BLAST query page] Organism display order

Inspired by #271, we will create a searchBar for quickly search the organism we are interested in.
I want to discuss about the order of organisms?
Should it still be alphabetically?
Or it is nicer to order by popularity, and how do we define popularity?

Improvement of front-end of blast app

Just document things can be improved in front end of blast app.

  1. use prop() rather than attr() for disabled, checked, and selected
    such as

    $('.program').attr('disabled', false).removeClass('disabled-radio');

    $('.blastp').attr('disabled', 'disabled').addClass('disabled-radio');

    It relates to performance and avoid error.

  2. Move css on template to specific css file
    such as

    <style>
    .nav-tabs>li.active>a, .nav-tabs>li.active>a:hover, .nav-tabs>li.active>a:focus {
    box-shadow: inset 0 -2px 0 #317eac;
    color: #317eac;
    border: 0px;
    }
    .txt:hover {
    text-decoration: underline;
    }
    </style>

    <legend>BLAST Databases <a href="https://i5k.nal.usda.gov/content/blast-tutorial" target="_blank"><span style="float:right"><span class="glyphicon glyphicon-book"></span> Tutorial</span></a></legend>

    <span class="load-nucleotide">Or</span> <span class="load-peptide">load</span> it from disk <span style=" cursor: pointer; font-weight:bold; color: blue;" class="load-nucleotide txt"> (load example) </span>

It will make it more easier to maintain css and avoid error.

  1. Use :disabled css selector, rather than add disabled class dynamically.
    https://developer.mozilla.org/zh-TW/docs/Web/CSS/:disabled

Scripting access of django databases

Like we discussed today, perhaps we don't need to have APIs.
Here are some possible options. I would update if I have more information:

1.using python manage.py shell < myscript.py: https://stackoverflow.com/a/16853799/5363040

2.using RunScript of django-extensions.
See an example here: https://github.com/django-extensions/django-extensions/blob/master/docs/runscript.rst.

The underlying mechanism is the same as 1, but based on a python package.

3.use loaddata, dumpdata of django commands: https://www.creativesoftware.com/blog/8-useful-django-dumpdata-and-loaddata-commands. It's the mechanisms used by Han Lin before and there are lots of scripts/command weren't maintained for a long time: https://github.com/NAL-i5K/genomics-workspace/tree/e9d355bc51118d3f7a4b56b94717d740853bf6f6/util.

django customize manage.py command :https://docs.djangoproject.com/en/1.11/howto/custom-management-commands/

Reset button will not reset the options part of blast app

I think I found a bug of blast-app front-end. When you insert some query into query sequence text area. If it disable some options of blast programs, and you click the reset button. All forms will be reset. However, some of options of blast programs will still be disabled, as that shown in following screenshot:
screen shot 2017-09-18 at 11 24 39 am

Re-written [BLAST query page] by React JS library

[BLAST query page(submission page)]
link:
https://github.com/r06942072/frontend_BLASTquery


Naming list of smart UI components

  • 4 blocks:
    • yourQuery
    • ourDb
    • program
    • timeTravel

Functionality list

  • #271, add Searching bar, and remain scrolling bar
  • List all organisms and BLAST databases
  • User can select multiple databases
  • User can enter multiple query sequences
  • Text box for query input
  • Sample sequences for input
  • Support only one type of database at a time (nucleotide or peptide)
  • Disable BLAST programs based on the database and query type (nucleotide or peptide)

Link:

add clean command in npm scripts

The idea of this is to have a npm script that can clean up files copied from node_modules folder to the place we want by webpack. This enhancement have at least following two benefits:

  1. Reduce the complexity of developing front-end javascript/css based on new npm packages
  2. boost the robustness of the deployment through deploy.sh

That is because currently we need to manually clean up files collected by webpack.

High level usage

Run this command: npm run clean.

When we want update (deploy) new genomics-workspace from one version to another version, the procedure will be following:

  1. npm run clean
  2. use git switch to newer version
  3. npm run build
  4. deploy.sh

Low level details

The current implementation in my mind is to have a script would remove files listed in .gitignore, but would not remove media folder.

Document of tests

Just placed some document materials about testing. This will be add to readthedocs later.

To test whole repo-wide settings:
python manage.py test i5k.tests

To test single app, for example, to test blast app:
python manage.py test blast.tests

To test specific test case, for example, TestClickAll test case of blast app:
python manage.py test blast.tests.TestClickAll

save parameters

When working on complicated genes, which require iterative blasting or blasting for specific exons or motifs individually, the back browser functionality of the legacy system recalls the species and the type of blast (e.g., tblastn) automatically, which saves time and worry. (Going from results back to submission and keeping some settings see below)

Adding delete feature to script

ideal command :
python manage.py delete [organism]
python manage.py delete [blastdb]
python manage.py delete [hmmerdb]

advanced :
delete multiple db or species in the same time
python manage.py delete [organism1] [organism2] . . .
python manage.py delete [blastdb1] [blastdb2] . . .

another delete command:
python manage.py delete -org [organism1]
python manage.py delete -b [blastdb1]
python manage.py delete -h [hmmerdb1]

advanced command:
python manage.py delete -org [org1] [org2] . . .
python manage.py delete -b [blastdb1] [blastdb2] . . .
python manage.py delete -h [hmmerdb1] [hmmerdb2] . . .


When the species is deleted, the cascade field and data should be deleted at the same time.
As same as the situation of species, it should deletes the cascading table when blastdb and hmmerdb be deleted but not the species.

Using web scraping to get tax id from NCBI

Do we need the sequences table?

After loading hundreds of BLAST databases, our sequences table is getting really, really big.

I think the only reason the sequences table exists is for doing lookup to get the sequence form the input fasta file.

With BLAST+, the blastdbcmd program can return a sequence from the ID, removing the need for the table, and the extra steps on setting up a new database.

What functions use the sequences table?
Can these functions be refactored to use existing BLAST apps, or simplified?

remove some useless configuration in settings.py

@deming7h777 commented on Thu Oct 11 2018

There are some file have been removed but the configuration is still in settings.py.(ex. jquery-ui.js,...)
It may confuse someone who want to figure out the whole genomics-workspace.


@hsiaoyi0504 commented on Fri Oct 12 2018

@deming7h777 Can you elaborate a little bit ? It seems to me that jquery-ui.js is still useful.


@deming7h777 commented on Fri Oct 12 2018

I can't find the jquery-ui.js in blast/script directory and even all of the repo, can you give me some suggestion


@hsiaoyi0504 commented on Fri Oct 12 2018

It's because it's installed by webpack:

{ from: path.join(nodeModules, '/jquery-ui-dist/jquery-ui.js'), to: blastScripts},
.


@deming7h777 commented on Sat Oct 13 2018

I have seen that, i mean i don't find any script or html import jquery-ui.js


@hsiaoyi0504 commented on Sat Oct 13 2018

It's imported by django-pipeline through

{% javascript 'blast-results' %}

, and in blast_results.js, the jquery-ui widget is called by some syntax like this:
.


@hsiaoyi0504 commented on Sat Oct 13 2018

BTW, this perhaps is a good alternative of django-pipeline: https://django-compressor.readthedocs.io/en/latest/. One important feature attracts me is that

JS/CSS belong in the templates
Every static combiner for Django I’ve seen makes you configure your static files in your settings.py. While that works, it doesn’t make sense. Static files are for display. And it’s not even an option if your settings are in completely different repositories and use different deploy processes from the templates that depend on them. - django-compressor


@deming7h777 commented on Mon Oct 15 2018

thanks for reminding !

Include DAP government code into app-layout.js

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.