Code Monkey home page Code Monkey logo

django-livereload-server's Introduction

django-livereload-server

This django app adds a management command that starts a livereload server watching all your static files and templates as well as a custom runserver command that issues livereload requests when the development server is ready after a restart.

Installation

Install package:

$ pip install django-livereload-server

Add 'livereload' to the INSTALLED_APPS, before 'django.contrib.staticfiles' if this is used:

INSTALLED_APPS = (
    ...
    'livereload',
    ...
)

Next you need to inject the loading of the livereload javascript. You can do this in one of two ways:

  • Through middleware by adding 'livereload.middleware.LiveReloadScript' to MIDDLEWARE (probably at the end):

    MIDDLEWARE = (
        ...
        'livereload.middleware.LiveReloadScript',
    )
    
  • Through a templatetag in your base.html (or similar) template:

    {% load livereload_tags %}
    ...
    {% livereload_script %}
    </head>
    

Either of these options will inject the livereload.js script into your webpages if DEBUG setting is on.

Configuration

If you need the livereload server to use a different host and port than the default 127.0.0.1 and 35729, specify them by setting LIVERELOAD_HOST and LIVERELOAD_PORT in settings.py.

Usage

Start the livereload server:

$ python manage.py livereload

keep the livereload server running.

Start the django development server as usual (in another console):

$ python manage.py runserver

In the browser's address bar access your web app by doing:

127.0.0.1:8000 or localhost:8000

now every time you hit save in your editor, the django-development-server/livereload-server automatically updates the staticfiles

Customization

By default both template and staticfiles directories are watched.

You can ignore template directories using:

$ ./manage.py livereload --ignore-template-dirs

Or staticfiles directories using:

$ ./manage.py livereload --ignore-static-dirs

You can ignore file extensions:

$ ./manage.py livereload --ignore-file-extensions=.less,.scss

Extra files and/or paths to watch for changes can be added as positional arguments. By default livereload server watches the files that are found by your staticfiles finders and your template loaders.

$ python manage.py livereload path/to/my-extra-directory/

This will be excluded from the paths ignored by --ignore-template-dirs and --ignore-static-dirs.

Host and port can be overridden with --host and --port options.

$ python manage.py livereload --host=myhost.com --port=9090

the runserver command python manage.py runserver also accepts three additional options:

* ``--nolivereload`` to disable livereload functionality
* ``--livereload-host`` to override both default and settings file specified host address
* ``--livereload-port`` to override both default and settings file specified port

Background

This project is based on a merge of python-livereload and django-livereload, excellent projects both and even better for smooth django development when combined.

django-livereload-server's People

Contributors

calumy avatar demeralde avatar fennecinspace avatar gilmrjc avatar gnud avatar kalekseev avatar kbuilds avatar mcteo avatar michjnich avatar nilshellerhoff avatar palewire avatar rtpg avatar tjwalch avatar valian avatar ypcrumble 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

django-livereload-server's Issues

404 Not Found

i get 404 Not Found when accessing the localhost from the port using python manage.py livereload

Django 1.10 compatibility

WARNINGS:
?: (1_10.W001) The MIDDLEWARE_CLASSES setting is deprecated in Django 1.10 and the MIDDLEWARE setting takes precedence. Since you've set MIDDLEWARE, the value of MIDDLEWARE_CLASSES is ignored.

if the middleware 'livereload.middleware.LiveReloadScript', is on the new MIDDLEWARE settings then django trows: Unhandled exception in thread started by <function wrapper at 0x7fa9c7fbe050>

livereload server not start without "--ignore-file-extensions" option

Hi, thanks to good app.
I found a little bug as below. (with this master branch)

when you do this command, it's ok.
python manage.py livereload --ignore-file-extensions=.less,.scss

but do this, error occur.
python manage.py livereload

i think this is cause from this code in livereload.py.
options.get('ignore_file_extensions', '').split(',')

error message

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.7/site-packages/livereload/management/commands/livereload.py", line 62, in handle
    ignore_file_extensions = options.get('ignore_file_extensions', '').split(',')
AttributeError: 'NoneType' object has no attribute 'split'

404 is being thrown for all routes

I've installed and configured this plugin. Whenever I access any route, it throws a 404. I've tested the same routes using runserver instead of livereload and they work fine.

I'm running Django 2.0.1 and Python 3.6.1.

Here's my redacted settings.py:

INSTALLED_APPS = [
    'livereload',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize',
    'django.contrib.postgres',
    'main.apps.MainConfig',
    'webpack_loader',
    'compressor',
]

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'livereload.middleware.LiveReloadScript',
]

Let me know if you need anything else. Cheers

Page is reloaded before template is updated

When I update a Django template, a reload happens as expected, but often, the reloaded page doesn't show the changes I just saved. To see them, I need to save the template a second time (with no new changes).

It feels like the reload might be happening before Django has picked up the template changes?

Have not setup any template caching in my dev env.

Using the Channels runserver in case that matters.

how to change the port exactly?

I want to change the ports used. What do I run exactly?

I tried

python manage.py livereload --port 9090
python manage.py runserver 9000 --livereload-port=9090

the second complains manage.py runserver: error: unrecognized arguments: --livereload-port 9090

TypeError: unhashable type: 'list'

livereload is crashing for me with the new release (0.3.0):

Traceback (most recent call last):
   File "manage.py", line 12, in <module>
     execute_from_command_line(sys.argv)
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
     utility.execute()
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
     output = self.handle(*args, **options)
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/livereload/management/commands/livereload.py", line 59, in handle
     server.watch(dir)
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/livereload/server.py", line 120, in watch
     self.watcher.watch(filepath, func, delay)
   File "/Users/Browning/Documents/memecomplete/.venv/lib/python3.6/site-packages/livereload/watcher.py", line 53, in watch
     'ignore': ignore,
 TypeError: unhashable type: 'list'

I do not experience this issue with 0.2.3.

304 error

Currently getting 304 errors

  • when saving scss files
  • reload does not detect changes unless

Unless,I trigger a save on a python file.

Python version 3.7.4
Django Version 2.2

Stop ignoring changed CSS files

Thank you for work on this tool, sorry if I'm overlooking something completely obvious. It works and reloads as expected at first, and then as I'm working and changing my css, I get this last output and have to manually refresh the browser:

[I 190423 13:11:29 handlers:92] Reload 1 waiters: /Users/shimadar/Projects/human_resources/human_resources/static/sass/project.scss
[I 190423 13:11:29 handlers:132] Browser Connected: http://127.0.0.1:8000/
[I 190423 13:11:29 handlers:79] Ignore: /Users/shimadar/Projects/human_resources/human_resources/static/css/project.css

I tried running with ./manage.py livereload human_resources/static/css to make sure it's watching that static folder but the same thing happens. (also tried with the full path)

The entire reason I'm running livereload is to reload when my static files change... I'm not sure how to tell it to stop ignoring them?

Livereload on OSX hangs with ERR_CONTENT_LENGTH_MISMATCH

Same code on a Windows system executes without issue and livereload works like a charm. On OSX visiting a page with livereload running results in the browser hanging on loading the page with the error "ERR_CONTENT_LENGTH_MISMATCH"

This FileResponse instance has no `content` attribute. Use `streaming_content` instead.

Code:

def inspect(request, path=None):
  folder = os.path.abspath(os.path.join(__file__, ".."))
  directory = os.path.join(folder, path)
  from django.views.static import serve
  return serve(request, os.path.basename(directory), os.path.dirname(directory))

Django Doc: Serving files in development

Environment:

Request Method: GET
Request URL: http://localhost:8000/inspect/somedir/testfile.html

Django Version: 1.10
Python Version: 3.5.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'livereload',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'livereload.middleware.LiveReloadScript']

Traceback:

File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  131.                 response = middleware_method(request, response)

File "/usr/local/lib/python3.5/site-packages/livereload/middleware.py" in process_response
  22.             smart_str(response.content),

File "/usr/local/lib/python3.5/site-packages/django/http/response.py" in content
  371.             "`streaming_content` instead." % self.__class__.__name__

Exception Type: AttributeError at /inspect/somedir/testfile.html
Exception Value: This FileResponse instance has no `content` attribute. Use `streaming_content` instead.

When multiple static files are changed in a short time it goes into a reload loop.

I have some build scripts for my JavaScript and SCSS. These build a hundred or so files at once and place them into static/
Livereload works well until I run these scripts, and then it seem to cue up one reload for every single changed file so whenever the build script runs I get a reload loop. The page just reloads over and over.

If I manually change a single static or template file one at a time, there's no problem, it's only when the build script updates multiple files at once that the loop happens.

No changes detected

I installed as instructed, but changes made to html files in templates directory don't seem to be caught by livereload server. Is there a way I can debug this?

ImportError: No module named apps

I tried to use it with Django 1.6.4 but raise this error
File "/Users/wxttt/.virtualenvs/fitness/lib/python2.7/site-packages/livereload/management/commands/livereload.py", line 4, in <module> from django.apps import apps ImportError: No module named apps

ImportError: No module named server

This is what I get when I try to run python manage.py livereload:

File "/home/myname/myproject/venv/lib/python2.7/site-packages/livereload/management/commands/livereload.py", line 6, in <module> from livereload.server import Server ImportError: No module named server

Release new version

Version 0.4.0 was released almost two years ago in December 2021, and multiple issues have been fixed since then. Would you be able to make a new release and publish it to PyPI?

livereload doesn't work in https environment

I use django-sslserver to make a https django develop environment. django-liveload-server works well in http environment, but when in https it still monitors http://127.0.0.1:8000, and doesn't reflect any file change.
Is there any way to make live-reload on https environment?

Needs to have a --delay or --wait flag

A common problem I've found across livereload implementations is that reloading happens once for every file changed.

For example, I'm using Django as a front end to serve static files generated with Hugo.
When I make a change in Hugo, it regenerates around 100 files, and livereload then reloads once for each.

I need to be able to throttle livereloading to prevent this.

Error when DIRS does not exist

Hi there!
I was using your very useful package, but encountered an error. When the setting TEMPLATES = [ ... ] does not contain DIRS, the following error is thrown:

  File "/usr/local/lib/python3.6/site-packages/livereload/management/commands/livereload.py", line 47, in handle
    watch_dirs.extend(template['DIRS'])
KeyError: 'DIRS

It can be circumvented from my side by making an empty 'DIRS': '' variable in my settings, but it would be nicer if it were fixed in:

django-livereload-server/livereload/management/commands/livereload.py, line 47

Thanks! Keep up the good work :)

Disable reload on specific pages

Hi, and many thanks for maintaining this plugin, this boosted my productivity :)

I usually have plenty of pages open for my project (CMS, admin, etc) unrelated to the page I'm currently working on (frontend css), and livereload keeps reloading all of the pages on each modification, which puts a lot of stress on the CPU.
Could we have a shortcut to disable reload on the page? or a small ui settings tooltip to configure that? A no-brainer for the user would be to only reload the page currently active, but that's probably not trivial to implement.

Thanks for considering this feature!

name collision with other livereload package => ImportError: cannot import name 'livereload_port' from 'livereload'

No help needed, I resolved my issue, but just wanted to leave a note about it.

https://gist.github.com/hangtwenty/f53b3867db1e33780505ccafd8d2eef0

Error:

ImportError: cannot import name 'livereload_port' from 'livereload'

Cause:

You have both livereload and django-livereload-server installed. Most likely, one was installed before the other,
and having both is an accident.

Fix:

Assuming it's OK to just consolidate on django-livereload-server, get rid of your code that imports or uses livereload directly.
Then:

pip uninstall -y livereload
pip install django-livereload-server

Or equivalent with your preferred package manager.


It's a simple issue really, but easy to miss.
(I initially assumed django-livereload-server wrapped livereload, but rather it's "inspired by"
and they have a namespace collision if you install both. Easy fix though.

HTTPS

Hi

I'm using runsslserver for development that requires SSL, it runs on port 8000 just as the standard dev server.

The django-reload-server does not seem to communicate with it, works fine on plain runserver

Is there an undocumented setting where that could be addressed?

Does not work without HEAD tag.

Understanding that including the tag is best practice, it would nevertheless be good to throw an error/warning if the template does not have a tag into which to inject the livereload.js script. I spent some time with some very basic HTML file trying to get this to work, only to realize that it was not loading because I did not have a element.

Add option to only live reload certain file types

I'm using django-livereload-server only for live reloading my templates. I use webpack-dev-server to hot reload my static assets (SCSS, JS etc).

It'd be great to have an option to only live reload certain assets (which in my case is templates).

Reload after a change in django view

Hi, great library!

Live reload works well when I change a template. I'd like the same happen whenever change in django view occurs. So I run livereload server with command ("core" being the app folder where views.py lies, name):
$python manage.py livereload core/.

Then if i run, in another terminal:
$python manage.py runserver
and try to change a value that is passed to the template in the view, both django-livereload-server gets in action as expected but at the same time the django development webserver restarts itself as well. It results in, in random manner, one of the following outcomes:

  • browser displays "This site can't be reached" for 4 seconds, then restarts again, and value is updated.
  • browser displays 'This site can't be reached' takes only 500ms and change happens.
  • restart happens properly, but value in template is not changed.

If, instead, in another terminal I run:
$python manage.py runserver --noreload

  • reloads after a template change still works fine.
  • reloads after view change produce the same results as with templates, i.e. django livereload prints:
[I 180706 16:57:48 handlers:92] Reload 1 waiters: core/views.py
[I 180706 16:57:48 handlers:132] Browser Connected: http://127.0.0.1:8000/

and django runserver prints:
[06/Jul/2018 16:57:48] "GET / HTTP/1.1" 200 274

and refresh in browser happen, except... still the old value from the view that was passed to template is shown.

What would be(if any) a way to get the reloads after view changes functionality working?

Thank you a lot in advance for taking a time to look into this issue as well as, once again, for developing this library.

picking up sass changes

I was just about to ask but found the solution myself .. in order for the file to be watched, it needs to be inside a template or static files folder .. maybe you could add that tiny detail to the readme?

love that app!

All 404?

Tried installing the app on the django tutorial project. All pages go to a 404. When the middleware is commented out and runserver is used, the 404's disappear and obviously the livereload doesn't function. This is on Windows 7, python 3.6, django 1.10.5

Exception in callback - TypeError: expected string or bytes-like object

[E 210824 12:02:32 ioloop:907] Exception in callback <bound method LiveReloadHandler.poll_tasks of <class 'livereload.handlers.LiveReloadHandler'>>
    Traceback (most recent call last):
      File "...\lib\site-packages\tornado\ioloop.py", line 905, in _run
        return self.callback()
      File "...\lib\site-packages\livereload\handlers.py", line 66, in poll_tasks
        filepath, delay = cls.watcher.examine()
      File "...\lib\site-packages\livereload\watcher.py", line 71, in examine
        if self.is_changed(path, item['ignore']):
      File "...\lib\site-packages\livereload\watcher.py", line 91, in is_changed
        return self.is_glob_changed(path, ignore)
      File "...\lib\site-packages\livereload\watcher.py", line 135, in is_glob_changed
        for f in glob.glob(path):
      File "...\lib\glob.py", line 22, in glob
        return list(iglob(pathname, recursive=recursive))
      File "...\lib\glob.py", line 44, in _iglob
        if not has_magic(pathname):
      File "...\lib\glob.py", line 156, in has_magic
        match = magic_check.search(s)
    TypeError: expected string or bytes-like object

New Path class isn't supported

When using the new Path class in latest Django versions, static files aren't reloaded on save (they aren't watched) :

BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_DIR = BASE_DIR / 'static'

Doing this on the other hand works :

BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_DIR = os.path.join(BASE_DIR, 'static')

`livereload_script` should use "protocol-relative URL"

Description

def livereload_script():
if settings.DEBUG:
return format_html(
"""<script src="{}:{}/livereload.js"></script>""",

When this loads in my browser, the src populated with a relative URL path. The browser interprets this with the expectation that the path should be appended to the pages current URL.

The result is http://localhost:8000/127.0.0.1:35729/livereload.js which isn't going to work.

Proposal

By adding the relative protocol syntax, the browser can interpret the script src as a complete URI with an empty scheme. The scheme is inherited from the pages scheme.

 """<script src="//{}:{}/livereload.js"></script>""", 

Links

Protocol Relative URL

Error 404 with Django 1.11.4

Hello, I installed livereload-server on Django 1.11.4, but after running manage.py livereload, the server returned a 404 for a route that works OK, if I use runserver.
What could be the problem?

Error with changing LIVERELOAD_HOST

Trying to change LIVERELOAD_HOST to `10.10.10.10´ gives me error.

[I 181031 13:51:11 server:141] Serving on http://10.10.10.20:35729
Traceback (most recent call last):
  File "/app/website/manage.py", line 12, in <module>
    execute_from_command_line(sys.argv)
  File "/app/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/app/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/app/env/lib/python3.4/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/app/env/lib/python3.4/site-packages/django/core/management/base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "/app/env/lib/python3.4/site-packages/livereload/management/commands/livereload.py", line 62, in handle
    liveport=options['port'],
  File "/app/env/lib/python3.4/site-packages/livereload/server.py", line 143, in serve
    self.application('10.10.10.20', liveport=liveport)
  File "/app/env/lib/python3.4/site-packages/livereload/server.py", line 130, in application
    live.listen(liveport, address=host)
  File "/app/env/lib/python3.4/site-packages/tornado/web.py", line 2042, in listen
    server.listen(port, address)
  File "/app/env/lib/python3.4/site-packages/tornado/tcpserver.py", line 143, in listen
    sockets = bind_sockets(port, address=address)
  File "/app/env/lib/python3.4/site-packages/tornado/netutil.py", line 168, in bind_sockets
    sock.bind(sockaddr)
OSError: [Errno 99] Cannot assign requested address

However I was able to set the REMOTE_HOST to 0.0.0.0 but then the middleware include fails of course.

do a new release

some issues seem to have been fixed, for example the app not working with channels issue.
but these features only work if i use a cloned version of the repository, not when using the pypi version
please do a new release, so that people can have access to the latest features when installing with pip

middleware messes up link and meta elements in head

Hi,
I found out that if link and meta elements in head are not closed (like this ), using the LiveReloadScript middleware will close them for me ().

What is worse, if some of them are already closed, then the rest are not closed by the / before the end > (), but a closing tag is created somewhere further down the head element, which messes things up completely. I suppose that the HTML is mangled by beautifulsoup when the script is injected.

Cheers
Beda

CSRF_Token

whenever i modify the html and save i get

Forbidden (403)
CSRF verification failed. Request aborted.

setting `LIVERELOAD_HOST` in container/VM/similar

Hey,
just wanted to report this:
If you set the LIVERELOAD_HOST in settings.py this host is also used in the javascript to conntect to the livereload backend, this breaks functionality in case of (dev-)container/VMs/similar setups because the backend needs to f.e. start with 0.0.0.0 but the script still needs a specific host like f.e. 127.0.0.1 in case of docker containers.
this might be not needed on a "real" docker environment like a Linux OS as the base - but there are still use cases left (besides Windows and macOS).

So, solution would be "just" to have two settings I guess ... something like LIVERELOAD_HOST and maybe LIVERELOAD_BACKENDHOST or _TARGET_HOST or something else :) - naming is a bitch :)

cheers

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.