Giter VIP home page Giter VIP logo

zoonavigator's Introduction

ZooNavigator

ZooNavigator is a web-based ZooKeeper UI and editor/browser with many features.

ZooKeeper versions 3.4.x and 3.5.x are currently supported.

📘 Read official docs for more info, screenshots 📷 and instructions how to use ZooNavigator. 🔥

Quick start

You can run ZooNavigator from:

Docker

Start Docker container:

docker run \
  -d \
  -p 9000:9000 \
  -e HTTP_PORT=9000 \
  --name zoonavigator \
  --restart unless-stopped \
  elkozmon/zoonavigator:latest

Go to http://localhost:9000.

Note:

If wanting to access ZooKeeper running locally on host machine (not in Docker container):

  • Linux users may use --net host instead of exposing the port
  • Windows and Mac users should follow this advice

Snap

Install ZooNavigator from Snap store:

sudo snap install zoonavigator

Go to http://localhost:9000.

License

The project is licensed under Affero General Public License version 3.0 (AGPLv3).

zoonavigator's People

Contributors

elkozmon avatar simplesteph avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

zoonavigator's Issues

Error: Unable to establish connection with ZooKeeper

I'm running zookeeper on the host machine on port 2181, and I'm using your docker-compose file to start the zoonavigator.

But I'm getting the following problem:
Error: Unable to establish connection with ZooKeeper

I've tried to use my hostname (on the host machine), and also:
localhost:2181
127.0.0.1:2181

But nothing has worked so far.

Connection to remove Zookeeper?

Can you provide some details about how to connect with a Zookeeper instance running on a different machine? Typically this should take a Zookeeper hostname or IP and zookeeper port (2181?) as arguments. But I couldn't find any way of specifying that.

I'm trying to run this on Kubernetes. I can contribute some documentation about how I was able to do it if the above is possible.

Custom base path doesn't work

@elkozmon Thanks for the quick answer!

A couple more things:

  • The instructions for the submodule(s) fail as the default is to get the via ssh. I was able to get past git submodule update --init --recursive by changing the urls in my .gitmodules to the http ones of your 2 submodules, followed by git submodule sync. Maybe it's worth adding these prior to the first instruction.

  • I was able to build the custom docker image. Then I try to run it with the same command I was using before:

docker run -d --network host -e HTTP_PORT=9000 --name rev-zoonavigator --restart unless-stopped my-zoonavigator

it starts, I'm able to reach it at <host>:9000/zoonavigator (but not at <host>:9000/zoonavigator/ with a / at the end), but then it's stuck loading the page. I only see the loading logo.

If I check the network in the browser console I see that it tries to make a request to http://93.90.193.89:9000/api/config.

Am I getting something wrong when trying to start it up or the basepath is missing somewhere (when /api/config is called)?

Originally posted by @mujina93 in #27 (comment)

unable to login

Hi,

I am new to this zookeeper as part of research i started zookeeper server using docker-compose and zoonavigator too. but while connecting thru my nodejs script, i havent provided any username and password in my local linux instance.

this is my zookeeper server

zookeeper:
container_name: zookeeper
image: "zookeeper"
ports:
- "2181:2181"

and for web, i used this zookeeper docker. What are the details to enter ? can you please guide me.

docker-compose start failed

D:\Program\ZookeeperNavigator>docker-compose start
Starting api ... done
Starting web ... failed

D:\Program\ZookeeperNavigator>docker-compose logs
Attaching to zoonavigator-api
zoonavigator-api | [info] application - Starting ZooNavigator API 0.6.2
zoonavigator-api | [info] play.api.Play - Application started (Prod)
zoonavigator-api | [info] p.c.s.AkkaHttpServer - Listening for HTTP on /0.0.0.0:9000
zoonavigator-api | [warn] a.a.ActorSystemImpl - Illegal request, responding with status '400 Bad Request': Unsupported HTTP method: HTTP method too long (started with '↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑'). Increase akka.http.server.parsing.max-method-len gth to support HTTP methods with more characters.

[Feature Request] Multi-cluster support ?

Hi @elkozmon,

I just came across your project while looking for a potential replacement of our existing Zookeeper UI solution. First of all good job on all of that. I really appreciated reading the clean documentation / instructions you put together to run Zoo-navigator good job 👏 .

I wanted to know if you have any plan on supporting multiple zookeeper clusters from a single instance of ZooNavigator. There could be some sort of drop down allowing us to choose which cluster to connect to making it easy to switch from one to an other.

We run dozens of zookeeper clusters and that would make your project even more valuable to us.

Keep up the good work !
Thanks

Make connection string / cluster name more visible on the UI

Right now in order to know what ZK cluster ZooNavigator is connected to, we have to go to ... > Session details. That will be great to have it part of the top header banner.

The reason why I am suggesting this improvement is because we have a lot of ZK clusters running and it can be confusing for users when they land on the UI.

Let me know what you think about it @elkozmon

Thanks !

Refresh ZNode listing

It would be nice to have a refresh button for refreshing the left-hand ZNode listing. Current workaround is to go up a directory and back in to be able to refresh the listing when ZNodes are added/removed.

Resource not found by Assets controller

I am able to successfully build the image with the Dockerfile provided on Mac OS. On running that image with the following command:

docker run -p 9000:9000 --name zoonavigator --restart unless-stopped zoonavigator

and then going to 0.0.0.0:9000 I get the following 404 http error:

{"success":false,"message":"Resource not found by Assets controller"}

Please help about how to fix it.

Feature request: Nginx location for health checks

Hi. I'm using the elkozmon/zoonavigator-web:0.5.0 docker image to deploy Zoonavigator in a Kubernetes Cluster, configuring health checks for my container:

livenessProbe:
  httpGet:
    path: /
    port: {{ .Values.service.internalPort.web }}
  initialDelaySeconds: 15
  timeoutSeconds: 5
readinessProbe:
  httpGet:
    path: /
    port: {{ .Values.service.internalPort.web }}
  initialDelaySeconds: 10
  timeoutSeconds: 5

This works fine, but the log output register every health check request, which create a bunch of unnecessary log lines:

2018-06-11T18:29:08.059154013Z 10.0.2.106 - - [11/Jun/2018:18:29:08 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9"
2018-06-11T18:29:17.778473602Z 10.0.2.106 - - [11/Jun/2018:18:29:17 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9"
2018-06-11T18:29:18.059005116Z 10.0.2.106 - - [11/Jun/2018:18:29:18 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9"
2018-06-11T18:29:27.778463035Z 10.0.2.106 - - [11/Jun/2018:18:29:27 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9"
2018-06-11T18:29:28.059161984Z 10.0.2.106 - - [11/Jun/2018:18:29:28 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9"
2018-06-11T18:29:37.778500371Z 10.0.2.106 - - [11/Jun/2018:18:29:37 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9"
2018-06-11T18:29:38.059143613Z 10.0.2.106 - - [11/Jun/2018:18:29:38 +0000] "GET / HTTP/1.1" 200 974 "-" "kube-probe/1.9
....

Including a /health location with disabled logs in the nginx.conf.template would be a nice feature!
Something like this:

# health check endpoint
location /health {
    access_log off;
    return 200 'OK';
    add_header Content-Type text/plain;
}

Zoonavigator is an awesome project. Congrats!

Support reading GZipped data

Similar to #24 :) It would be great if Zoonavigator supported reading and writing GZipped data. This should be fairly easy to do since it already supports JSON. Ex (in Scala, but you get the idea, using Jackson to deserialize Gzipped data):

def readGzippedOrCreateObjectNode(data: Array[Byte]): ObjectNode = {
  // See https://tools.ietf.org/html/rfc1952
  val isGzip: Boolean = data != null && data.length > 3 && data(0) == 31 && data(1) == -117 && data(2) == 8

  if (data == null) {
    mapper.createObjectNode()
  } else if (isGzip) {
    Try(mapper.readValue(new GZIPInputStream(new ByteArrayInputStream(data)), classOf[ObjectNode])).getOrElse(mapper.createObjectNode())
  } else {
    readOrCreateObjectNode(data)
  }
}

def compress(data: Array[Byte]): Array[Byte] = {
  val bytes: ByteArrayOutputStream = new ByteArrayOutputStream
  val out: GZIPOutputStream = new GZIPOutputStream(bytes)

  try {
    out.write(data)
  } finally {
    out.close()
  }

  bytes.toByteArray
}

ACL issue with sasl

Some of my nodes are configured with sasl access. It seems that the API isn't configured to work with those:

zoonavigator-api | [debug] c.e.z.c.c.b.DefaultBackgroundPromiseFactory - GET_ACL event completed with result code 0
zoonavigator-api | [error] o.a.c.f.i.CuratorFrameworkImpl - Background operation result handling threw exception
zoonavigator-api | scala.MatchError: sasl (of class java.lang.String)
zoonavigator-api | 	at com.elkozmon.zoonavigator.core.zookeeper.acl.Scheme$.fromZookeeperScheme(Scheme.scala:40)
zoonavigator-api | 	at com.elkozmon.zoonavigator.core.query.queries.GetZNodeAclQueryHandler$$anonfun$2$$anonfun$3.apply(GetZNodeAclQueryHandler.scala:51)
zoonavigator-api | 	at com.elkozmon.zoonavigator.core.query.queries.GetZNodeAclQueryHandler$$anonfun$2$$anonfun$3.apply(GetZNodeAclQueryHandler.scala:48)
zoonavigator-api | 	at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
zoonavigator-api | 	at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
zoonavigator-api | 	at scala.collection.Iterator$class.foreach(Iterator.scala:893)
zoonavigator-api | 	at scala.collection.AbstractIterator.foreach(Iterator.scala:1336)
zoonavigator-api | 	at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
zoonavigator-api | 	at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
zoonavigator-api | 	at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
zoonavigator-api | [warn] application - Background operation result handling threw exception
zoonavigator-api | scala.MatchError: sasl (of class java.lang.String)
zoonavigator-api | 	at com.elkozmon.zoonavigator.core.zookeeper.acl.Scheme$.fromZookeeperScheme(Scheme.scala:40)
zoonavigator-api | 	at com.elkozmon.zoonavigator.core.query.queries.GetZNodeAclQueryHandler$$anonfun$2$$anonfun$3.apply(GetZNodeAclQueryHandler.scala:51)
zoonavigator-api | 	at com.elkozmon.zoonavigator.core.query.queries.GetZNodeAclQueryHandler$$anonfun$2$$anonfun$3.apply(GetZNodeAclQueryHandler.scala:48)
zoonavigator-api | 	at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
zoonavigator-api | 	at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
zoonavigator-api | 	at scala.collection.Iterator$class.foreach(Iterator.scala:893)
zoonavigator-api | 	at scala.collection.AbstractIterator.foreach(Iterator.scala:1336)
zoonavigator-api | 	at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
zoonavigator-api | 	at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
zoonavigator-api | 	at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
zoonavigator-api | [debug] application - Closing connection to zookeeper-1.zk.dev.analytics.in.cld:2181. Cause: EXPIRED

Saving a node again issues a bad version error

Trying to save a node again after it has already been saved issue a bad version warning. It should either be masked or disabled instead, or the version should be fetched/updated in the UI after a save event.

Also, once such error has occurred, the user can no longer save a document until the browser/page is refreshed in its entirety.

Error: Unable to establish connection with ZooKeeper

Connecting with the docker-compose name does not work here but connecting with the network IP does. In my sample application, I had the name as simply 'zookeeper' instead of 'compliance-message-queue-zookeeper' and connected with 'zookeeper:2181' and it worked. Is there a name length issue somewhere?

image

image

Copy/rename a node

The ability to copy or rename a node in ZooNavigator would be really nice.
At the moment, i would have to do this via creating a new node, copying the content and deleting the old node.

Zoonavigator-api can not be run as a non-root user

There are Kubernetes environments that provide a Pod Security Policy (PSP). One of the options in a PSP is to force all containers in a Pod to run as a non-root user (some UID/GID grater than 0).

In such an environment zoonavigator-api can not be deployed, because the docker image has everything under the /app folder owned by root:root as such the following error is encountered.

Oops, cannot start the server.
java.nio.file.AccessDeniedException: /app/RUNNING_PID
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
        at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
        at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
        at java.nio.file.Files.newOutputStream(Files.java:216)
        at play.core.server.ProdServerStart$.createPidFile(ProdServerStart.scala:136)
        at play.core.server.ProdServerStart$.start(ProdServerStart.scala:43)
        at play.core.server.ProdServerStart$.main(ProdServerStart.scala:25)
        at play.core.server.ProdServerStart.main(ProdServerStart.scala)

The design of zoonavigator-api does not require privilege or root in any way. A simple and transparent solution to this problem would be to:

  • cause the Dockerfile to create a zoonavigator-api user and group in the image
  • use a RUN directive to chown the /app folder to the new user
  • use the USER directive to cause the CMD to be executed as the new user

There was a similar issue with zoonavigator-web where the nginx proxy required to be run with privilege (see #35) which was solved by pull request (see elkozmon/zoonavigator-web#9). Making this change will allow both zoonavigator-web and zoonavigator-api to be run in environments with restrictive security policies.

Setting HTTP_PORT=disabled makes docker healthcheck fail

While running the container with HTTPS only (and using the env vars described at https://www.elkozmon.com/zoonavigator/docker/configuration/) I encountered the docker container reporting a bad healthcheck.

Compose file:
version: '2'
services:
zoonavigator:
image: elkozmon/zoonavigator:latest
restart: always
network_mode: bridge
hostname: zoonavigator
ports:
- 9001:9001
environment:
- HTTP_PORT=disabled
- HTTPS_PORT=9001

Portainer shows the following error: curl: (3) Port number ended with 'd'

It appears the issue lies in the healthcheck.sh file (https://github.com/elkozmon/zoonavigator/blob/master/build/docker/files/zoonavigator-api/healthcheck.sh.template)
since it assumes that the HTTP_PORT will always be defined.

Feature request: retrieve binary data in base64

Would be nice to be able to visualize znodes containing binary data in base64 on the web UI, so that I can decode base64 myself if I need to.

Currently it seems zoonavigator is returning a string representation of binary data we can't really work with:

�P?���S.���l�{

Default connection string

Hey,
Is there any way to default the connection string to a given value on the connection page? Or have the app jump straight into a given server.

Basically there is no "option" in the environment we run in, it's always going to a specific server so that page isn't required

Using external ZooKeeper instance (in OS other than Linux)

If wanting to connect to a local ZooKeeper on 2181 outside of the docker container, we cannot use network: host mode. Here is how I was able to get around this, remove net=host mode and open 9000 on the host machine:

docker run \
  -d -p 9000:9000 \
  --name zoonavigator \
  --restart unless-stopped \
  elkozmon/zoonavigator:latest

And use the connection string docker.for.mac.host.internal:2181 (varies by operating system, see this answer: https://stackoverflow.com/a/43541732/7983959

Wanted to share here in case others experience this issue, it was not straightforward to determine the issue

Standalone service

Is it possible to run ZooNavigator as standalone service on dedicated platform (without docker)?

Host not allowed: zoonavigator:9000

Hi,

I am starting the container as documentations asks:

docker run \

-d --network host
-e HTTP_PORT=9000
--name zoonavigator
--restart unless-stopped
elkozmon/zoonavigator:latest

I can access the zoonavigator using the address localhost:9000

However, I am not able to access zoonavigator externally by hostname. I am receiving the following error:

{"success":false,"message":"Host not allowed: zoonavigator:9000"}

How to easily reproduce:

edit /etc/hosts and add zoonavigator to the line that begins with 127.0.0.1

Start the container with

docker run \

-d --network host
-e HTTP_PORT=9000
--name zoonavigator
--restart unless-stopped
elkozmon/zoonavigator:latest

Try to access the web application using a web browser.

I could not find any setting to allow a different host.

Thanks

Docker image for zoonavigator-web 0.6.0 results in Permission Denied

I have a Kubernetes based deployment of the prebuilt docker image
elkozmon/zoonavigator-web:0.6.0

When I deploy this image I get the following in the Pod logs:

2019/04/08 20:26:29 [emerg] 14#14: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

The container then exits with a non-zero exit status and Kubernetes redeploys it. We end up in an infinite loop :-)

Have I missed some instructions about needing to create some kind of volume mount?

Provide ZooKeeper host and auth via Docker

Since I log into various ZooKeeper servers numerous times a day in dev and test environments, it would be nice if I could provide connection and auth information via Docker environment variables, and if zoonavogator-web could use that to establish a connection rather than prompting me to manually enter this info.

JSON / YAML auto-formatting

I really like the JSON / YAML modes and was wondering if it would make sense to offer an auto-formatting option based on the mode where text is formatted to be more readable according to the mode.

ZNode data line wrapping

I have a lot of ZNodes with very long single line values. It would be cool if there were an option to have ZNode data wrap instead of scroll horizontally.

need website safety

can you provide a basic authentication just like rockmongo? our zk is no-password so everybody can modify via this website. only a user/password needed, for log in the website

Docker state stuck in "health: starting"

Hey! I recently added Zoonavigator to a Docker Compose project and I can access the web ui without any problems. However, I've noticed that the containers never seem to get past the "starting" stage. If I run docker-compose ps I get the following output:

             Name                           Command                       State                                      Ports
------------------------------------------------------------------------------------------------------------------------------------------------------
zookeeper                        /docker-entrypoint.sh zkSe ...   Up                      0.0.0.0:2181->2181/tcp, 2888/tcp, 3888/tcp
zoonavigator-api                 ./run.sh                         Up (health: starting)   9000/tcp
zoonavigator-web                 ./run.sh                         Up (health: starting)   80/tcp, 0.0.0.0:32771->8000/tcp

This wasn't a problem until I started using Traefik, which doesn't register services until the starting stage has completed. Is there anything I can do here? Or is this a bug?

Btw, great project!

ssl connection

Caused by: java.io.IOException: Couldn't instantiate org.apache.zookeeper.ClientCnxnSocketNetty
at org.apache.zookeeper.ZooKeeper.getClientCnxnSocket(ZooKeeper.java:1845)
at org.apache.zookeeper.ZooKeeper.(ZooKeeper.java:452)
at org.apache.curator.utils.DefaultZookeeperFactory.newZooKeeper(DefaultZookeeperFactory.java:29)
at org.apache.curator.framework.imps.CuratorFrameworkImpl$2.newZooKeeper(CuratorFrameworkImpl.java:191)
at org.apache.curator.HandleHolder$1.getZooKeeper(HandleHolder.java:101)
at org.apache.curator.HandleHolder.internalClose(HandleHolder.java:147)
at org.apache.curator.HandleHolder.closeAndClear(HandleHolder.java:78)
at org.apache.curator.ConnectionState.close(ConnectionState.java:122)
at org.apache.curator.CuratorZookeeperClient.close(CuratorZookeeperClient.java:227)
at org.apache.curator.framework.imps.CuratorFrameworkImpl.close(CuratorFrameworkImpl.java:381)
Caused by: java.lang.ClassNotFoundException: org.apache.zookeeper.ClientCnxnSocketNetty
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.apache.zookeeper.ZooKeeper.getClientCnxnSocket(ZooKeeper.java:1842)
at org.apache.zookeeper.ZooKeeper.(ZooKeeper.java:452)
at org.apache.curator.utils.DefaultZookeeperFactory.newZooKeeper(DefaultZookeeperFactory.java:29)
at org.apache.curator.framework.imps.CuratorFrameworkImpl$2.newZooKeeper(CuratorFrameworkImpl.java:191)

ZNode sorting

Would be nice if the ZNode listing on the left-hand window could be sorted alphabetically, either way.

add url prefix to hosting multiple instances

Hi,

I have only one host to server multiple web project, such that to access http://myhost/app_prefix/ to reverse proxy to different web ui.

I found this: https://www.elkozmon.com/zoonavigator/get-started/usage/ the environment section that does not have prefix or path varible.

so, I cannot access let nginx do the proxy:
such as:

 location ~ ^/zoonavigator/(.*)$ {
                proxy_pass              http://localhost:8000;
                rewrite /zoonavigator/(.*) /$1  break;
                proxy_set_header        Host $host;
                proxy_set_header        Referer "";
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_http_version      1.1;
                proxy_connect_timeout   150;
                proxy_send_timeout      100;
                proxy_read_timeout      100;
                proxy_buffers           16 64k;
                proxy_busy_buffers_size 64k;
                client_max_body_size    256M;
                client_body_buffer_size 128k;
 }

and the screen shot:

screen shot 2018-09-28 at 3 16 45 pm

those resources are all point to root of my domain.

Can add one more env variable?

Single distribution?

Hi,

Any chance considering a "single distribution"? I.e. to have a single JAR containing the JS resouces too? since the application is an SPA? (SBT could copy the JS resouces at build/package time).

It would greatly simplify the deployment for users (and also the required documentation).

Thank you.

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.