Giter Site home page Giter Site logo

start's Introduction

Hey, I'm Yehor! ๐Ÿ‘‹

start's People

Contributors

almstrand avatar chrisjlee avatar enyo avatar fedott avatar hoylen avatar kevmoo avatar kjelly avatar lucipacurar avatar lvivski avatar markbennett avatar nfrancois avatar patrickjs avatar piif avatar rhydiant avatar sethladd avatar tomaszkubacki 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

start's Issues

Concept of View is under-documented

A View is totally optional, from what I can tell. It's under-documented in the README. Could you either explain what it's used for, and why someone would care, or split the README into the concepts that don't require a View and those that do?

I'm hoping to make Start even easier to learn and use.

Thanks!

No way to know what websocket is being close.

With a normal HttpServer you can transform a request into a websocket like this.

WebSocketTransformer.upgrade(request).then((WebSocket websocket) {
    onWebSocketConnected(websocket);
    websocket.listen((data){
      onWebSocketDataReceived(websocket,data);
    },onDone:(){
      onWebSocketClosed(websocket);
    });
  });

Notice that I can still access the websocket during the closing. This allows for handling of temp data (session-ish things) to be cleared once the socket closes. I would really like to use start for its clean semantics and want to know how to get this information properly within start's framework.

Production ready?

I am thinking about start for use in my next simple project. Is it ready for production?

Request.cookies crashes (if non valid cookies are set)

If non valid cookies are set for example like that:

req.response.cookie("name", "for example something with a whitespace");

a call on

req.cookies

will fail like that.

Uncaught Error: HttpException: Failed to parse header value [name=nane; first name=test; last name=nane]
Unhandled exception:
HttpException: Failed to parse header value [name=nane; first name=test; last name=nane]
#0      _rootHandleUncaughtError.<anonymous closure>.<anonymous closure> (dart:async/zone.dart:677)
#1      _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#2      _asyncRunCallback (dart:async/schedule_microtask.dart:21)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)
Stack Trace: 
#0      _HttpHeaders._parseCookies.parseCookieString.expect (http_headers.dart:470)
#1      _HttpHeaders._parseCookies.parseCookieString (http_headers.dart:480)
#2      _HttpHeaders._parseCookies.<anonymous closure> (http_headers.dart:491)
#3      List.forEach (dart:core-patch/growable_array.dart:240)
#4      _HttpHeaders._parseCookies (http_headers.dart:491)
#5      _HttpInboundMessage.cookies (http_impl.dart:74)
#6      Request.cookies (package:start/src/request.dart:22:40)
#7      main.<anonymous closure>.<anonymous closure> (file:///Users/nane/dart/httpserver/bin/start_cookie_handling.dart:13:15)
#8      _rootRunUnary (dart:async/zone.dart:695)
#9      _RootZone.runUnary (dart:async/zone.dart:834)
#10     _BaseZone.runUnaryGuarded (dart:async/zone.dart:546)
#11     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:333)
#12     _DelayedData.perform (dart:async/stream_impl.dart:585)
#13     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:701)
#14     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:661)
#15     _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#16     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)

I propose to provide a Uri.encodeQueryComponent in the following method of class Response:

Response cookie(String name, String val, [Map options]) {
    var cookie = new Cookie(
             Uri.encodeQueryComponent(name),
             Uri.encodeQueryComponent(value),
     );

     final cookieMirror = reflect(cookie);

    if (options != null) {
      options.forEach((option, value) {
        cookieMirror.setField(new Symbol(option), value);
      });
    }

    _response.cookies.add(cookie);
    return this;
  }

Also a Uri.decodeQueryComponent should be made in the cookies getter of HttpRequest.

For example like this:

  List<Cookie> get cookies {
      return _request.cookies.map((Cookie c) {
        c.name = Uri.decodeQueryComponent(c.name);
        c.value = Uri.decodeQueryComponent(c.value);
        return c;
     });
  }

Is the comment about routing incorrect?

It gives an example of route "/hello/:firstname.:lastname?" and claims it will match "/hello/john" and "/hello/john.doe". While it does match the latter, it is accepting all of 'john.doe' as firstname which is either incorrect or very confusing.

Add support for HTTPS

I think the title is obvious, as is the importance :)

I recently proposed an implementation of HTTPS for the Vane dart web framework, so perhaps if I find some time, I can take a look at start as well. But you guys probably know the code better.

The Vane proposal is here: Scorpiion/vane#19

Response.send with error: 'String contains invalid characters.'

I just loaded all my files info in Google Drive and send them out.
And I got the error 'String contains invalid characters.';

Uncaught Error: Illegal argument(s): String contains invalid characters.
Stack Trace:
#0      _UnicodeSubsetEncoder.convert (dart:convert/ascii.dart:83)
#1      Codec.encode (dart:convert/codec.dart:22)
#2      _IOSinkImpl.write (dart:io/io_sink.dart:288)
#3      _HttpOutboundMessage.write (dart:io/http_impl.dart:484)
#4      Response.send (package:start/src/response.dart:65:20)

Memory leak?

I cloned start, and run the example "start / example / app.dart".

I can see it uses 24M memory from activity monitor (from ios)

Then I visit http://localhost:3000, where I can see the "Start is awesome"

I refreshed the browser quickly, and found the memory it used growing fast, soon became "51M+"

Then I run "purge" from command line, it became "50M"

I'm worried if start/dart has memory leak? Or do I misunderstand something?

Start experimental version for WebSocket #73 (API changed)

I've already commented on WebSocket v0.4.0 at #73.
But, I've changed the onMessage() into onMessage (stream object).


app.ws('/socket').listen((socket) {

  socket.onMessage.listen((data) {
    print('data: $data');
    socket.send(data);
  });

  socket.onOpen.listen((ws) {
    print('new socket opened');
  });

  socket.onClose.listen((ws) {
    print('socket has been closed');
  });

});

Thus, I've made expremental start v0.5.0 on github.
https://github.com/bsjung/start.

And I've made start web frame examples.
https://github.com/bsjung/start_examples.

Benjamin Jung ([email protected])

Start provides only indirect access to session data

Request class of start does not provide direct access to session data. Therefore accessing session data is unnecessary verbose due to the fact that we have to use input property of Request.

req.input.session['key'] = 'value';

It would be more efficient to do it this way:

req.session['key'] = 'value';

Therefore I propose to introduce the following getter to Request class to overcome unnecessary verbosity.

HttpSession get session => _request.session;

How to use async operations with Start?

Could you please provide an example how to use async operations with Start?

I tried this, but it didn't work:

app.get('/:name', (req, res) {
  new File(req.param('name')).readAsString().then((content) {
    res.render('view', {'content': content});
  });
});

It seems, the response stream is closed before the Future's function is called.

Why not using `part of`to include all classes?

I've noticed that you first import server which then imports all other parts of start, like response.dart.

This means that I can't just use the types in my app. Why don't you include all the assets with part "src/response.dart";?

How to get the posted data?

I mean a form in HTML:

<form method="post">
<input type="text" name="title" />
<input type="submit" />
</form>

How to get the value of posted title?

websockets do not appear to be working with latest dartlang version

tried example from main project page and after evaluating this

var ws = new WebSocket("ws://localhost:3000/socket");

in Chrome console i've got following on the server side:

0 Socket.on (package:start/src/socket.dart:30:45)
1 main.. (file:///home/tomek/projects/moohub/bin/moohub.dart:33:16)
2 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:191:14)
3 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:141:16)
4 _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:57:15)
5 _MapStream._handleData (dart:async/stream_pipe.dart:122:14)
6 _ForwardingStreamSubscription._handleData._handleData (dart:async/stream_pipe.dart:79:24)
7 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:191:14)
8 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:141:16)
9 _SyncStreamController._sendData (dart:async/stream_controller.dart:107:23)
10 _StreamController.add (dart:async/stream_controller.dart:48:16)
11 _WebSocketTransformerImpl.bind.. (websocket_impl.dart:294:70)
12 _ThenFuture._sendValue (dart:async/future_impl.dart:265:24)
13 _FutureImpl._setValue (dart:async/future_impl.dart:149:26)
14 _FutureImpl._setOrChainValue (dart:async/future_impl.dart:239:16)
15 _ThenFuture._sendValue (dart:async/future_impl.dart:271:21)
16 _FutureImpl._setValue (dart:async/future_impl.dart:149:26)
17 _FutureImpl._setOrChainValue (dart:async/future_impl.dart:239:16)
18 _ThenFuture._sendValue (dart:async/future_impl.dart:271:21)
19 _FutureImpl._setValue (dart:async/future_impl.dart:149:26)
20 _CatchErrorFuture._sendValue (dart:async/future_impl.dart:283:14)
21 _FutureImpl._setValue (dart:async/future_impl.dart:149:26)
22 _FutureImpl._setOrChainValue (dart:async/future_impl.dart:239:16)
23 _ThenFuture._sendValue (dart:async/future_impl.dart:271:21)
24 _FutureImpl._setValue (dart:async/future_impl.dart:149:26)
25 _AsyncCompleter._setFutureValue. (dart:async/future_impl.dart:29:23)
26 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:9:15)
27 Timer.Timer. (dart:async-patch/timer_patch.dart:9:15)

Unhandled exception:
type '() => dynamic' is not a subtype of type 'MsgHandler' of 'action'.
0 _throwDelayed. (dart:async/stream_impl.dart:7:5)
1 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:9:15)
2 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:13:7)
3 Timer.Timer. (dart:async-patch/timer_patch.dart:9:15)
4 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:99:28)
5 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:107:7)
6 _Timer._createTimerHandler. (timer_impl.dart:115:23)
7 _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

get Cookie problem

Hi
Iam getting an Error when calling request.cookies in 'package:start/src/request.dart'

Error:
Unhandled exception:
type 'MappedListIterable' is not a subtype of type 'List<Cookie' of 'function result'.

Refactor WebSocket Message parsing into an external pub

Clients can't include the Start library as it uses parts of the Dart stdlib not accessable in the web browser. That said, it would be good if there was some common code which allowed WebSocket messages to be consistently serialized and de-serialized between the client and server.

I'm going to work on building this external pub, then including it in the list of Start's dependencies but obviously wanted to hear your thoughts before I started work.

WebSocket error

I'm new to start web-framework but, I think it is great framework for me because I like the express framework from node.js.

I've tried to use websocket server example in
https://github.com/lvivski/start/blob/master/example/app.dart.

I've tested with my node.js websocket client.

=====================================
#!/bin/env node
const WebSocket = require('ws');
const ip = 'localhost';
const port = 3000;
const url = ws://${ip}:${port}/socket;
const connection = new WebSocket(url)

// Send message when the connection with the websocket is established
connection.onopen = () => {
let data = {'type' : 'login', 'userName': 'bsjung', 'password' : 'xxxx' };
let msg = JSON.stringify(data);
connection.send(msg);
}

// Print messages from other clients in the client terminal
connection.onmessage = (event) => {
let msg = JSON.parse(event.data);
console.log(msg);
}

// Print Websocket error in the client terminal
connection.onerror = (error) => {
console.log('Error:', error);
}

=====================================

The error is as following.

FINE: 2020-01-27 16:13:10.797449: Server started, listening on 127.0.0.1:3000
Unhandled exception:
type '_HttpRequest' is not a subtype of type 'Request' in type cast
#0 Route.handle (package:start/src/route.dart:34:34)
#1 Server.listen.handle. (package:start/src/server.dart:27:17)
#2 _RootZone.runUnaryGuarded (dart:async/zone.dart:1316:10)
#3 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:338:11)
#4 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:265:7)
#5 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:766:19)
#6 _StreamController._add (dart:async/stream_controller.dart:642:7)
#7 _StreamController.add (dart:async/stream_controller.dart:588:5)
#8 _HttpServer._handleRequest (dart:_http/http_impl.dart:2828:19)
#9 new _HttpConnection. (dart:_http/http_impl.dart:2586:19)
#10 _RootZone.runUnaryGuarded (dart:async/zone.dart:1316:10)
#11 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:338:11)
#12 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:265:7)
#13 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:766:19)
#14 _StreamController._add (dart:async/stream_controller.dart:642:7)
#15 _StreamController.add (dart:async/stream_controller.dart:588:5)
#16 _HttpParser._headersEnd (dart:_http/http_parser.dart:366:19)
#17 _HttpParser._doParse (dart:_http/http_parser.dart:703:15)
#18 _HttpParser._parse (dart:_http/http_parser.dart:320:7)
#19 _HttpParser._onData (dart:_http/http_parser.dart:812:5)
#20 _RootZone.runUnaryGuarded (dart:async/zone.dart:1316:10)
#21 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:338:11)
#22 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:265:7)
#23 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:766:19)
#24 _StreamController._add (dart:async/stream_controller.dart:642:7)
#25 _StreamController.add (dart:async/stream_controller.dart:588:5)
#26 _Socket._onData (dart:io-patch/socket_patch.dart:1831:41)
#27 _RootZone.runUnaryGuarded (dart:async/zone.dart:1316:10)
#28 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:338:11)
#29 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:265:7)
#30 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:766:19)
#31 _StreamController._add (dart:async/stream_controller.dart:642:7)
#32 _StreamController.add (dart:async/stream_controller.dart:588:5)
#33 new _RawSocket. (dart:io-patch/socket_patch.dart:1379:33)
#34 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:899:14)
#35 _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
#36 _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
#37 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
#38 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:175:5)

gzip

Would be great to be able to gzip all responses.

Start provides no pragmatic post parameter handling

Start provides no pragmatic parameter handling of post request. Therefore I propose the following method for class Request.

/**
 * Method to get post parameters from a [Request] object.
 */
Future<Map<String, String>> getPostParams({ Encoding enc: UTF8 }) {
  Completer c = new Completer();
  this.input.transform(const AsciiDecoder()).listen((content) {
    final postParams = new Map.fromIterable(
        content.split("&").map((kvs) => kvs.split("=")),
        key: (kv) => Uri.decodeQueryComponent(kv[0], encoding: enc),
        value: (kv) => Uri.decodeQueryComponent(kv[1], encoding: enc)
    );
    c.complete(postParams);
  });
  return c.future;
}

This would enable to do a pragmatic post parameter handling in start. Like this ...

    app.post("/formular").listen((Request req) {
      final name = req.getPostParams().then((params) {
        final fn = params['first name'];
        final ln = params['last name'];
        req.response.send(renderForm("$fn $ln"));
      });
    });

CORS integration

I needed CORS support for my project.
Thus I've made an experimental Start web framework.

All code is at https://github.com/bsjung/start_examples/blob/master/jwt/server/server.dart.

At first, I've added "cors" option at start().


void main() {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((rec) {
print('${rec.level.name}: ${rec.time}: ${rec.message}');
});

start(port: 3000, cors: true).then((Server app) {


And, I've add addCorsHeaders with options from start().


void addCorsHeaders(HttpResponse response) {
response.headers.add('Access-Control-Allow-Origin', '*');
response.headers.add('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE');
response.headers.add('Access-Control-Allow-Headers',
'access-control-allow-origin,content-type,x-access-token');
}


Experimental Start web framework is at https://github.com/bsjung/start.
JWT example using CORS options is at https://github.com/bsjung/start_examples/blob/master/jwt/server.

Benjamin Jung ( [email protected] )

Throwing "No such HTTP method" is confusing

I think it'd be better to replace noSuchMethod with explicit method declarations of get,post, etc.. But even if there is reason to keep it, the error is super confusing. For instance:

get('/lala', (req, res){
   Hello
});

Will raise "No such HTTP method", because "Hello" isn't in the list of http methods.

The "type 'View' is not loaded" error.

Hi, I am starting to work with Dart.

I try to run the sample from README and get the following message:

i:\project\test>dart server.dart
Unhandled exception:
'file:///i:/project/test/server.dart': Error: line 5 pos 19: type 'View' is not loaded
  start(view: new View(), public: 'example/public', port: 3000).then((app) {
                  ^
malformed type used.
#0      main (file:///i:/project/test/server.dart:5:19)

I have found the instruction about compilation of the views:

Don't forget to compile views with bin/compiler.dart (views are precompiled in example).

But it is not clear how to do that. Can you describe the full process of compilation and installation? What should be done to fix this error.

The pub install start also does not work in windows, it shows the following message:

Could not find a file named "pubspec.yaml" in the directory ....

So I have created the following pubspec.yaml file to make it work:

name: my_app
dependencies:
    start: any 

and then I run the following command:

pub install

Cookie method can not set more than one cookie per request

Cookie method of Response is not able to set more than one cookie per response.

I think header method is buggy.

  header(String name, [value]) {
    if (value == null) {
      return _response.headers[name];
    }
    _response.headers.set(name, value);
    return this;
  }

should be:

  header(String name, [value]) {
    if (value == null) {
      return _response.headers[name];
    }
    _response.headers.__add__(name, value);
    return this;
  }

Class '_HttpResponse' has no instance method 'write'.

A clean install of the example application crashes upon first GET request with an error. No response is returned from the Start HTTP server.

Full error message can be found in this gist.

Dart Editor also reports:
"HttpResponse" has no method named "write" - response.dart [Line 60]
`"HttpResponse" has no method named "write" - response.dart [Line 64]``

As such the example application is broken.

Route placeholders fail to match all valid URL path segment characters

The following code fails to match a URL ccontaining path '/hello/file.txt', e.g. http://localhost/hello/file.txt:

server.get('/hello/:filename').listen((request) {
  print('match!');
});

Only when removing the period (.) from the URL does the placeholder (:filename) match the path segment; despite periods being valid characters in URL path segments.

It would be great if the start placeholders can match all valid path segment character.

Cookie method causes an exception when called with no options

Cookie method causes an exeception when called with no options.

app.get("/formular").listen((Request req) {
      req.response.cookie('test', 'example');
      req.response.send("something");
});

Above causes exception. The following works:

app.get("/formular").listen((Request req) {
      req.response.cookie('test', 'example', {});
      req.response.send("something");
});

Socket messages with data not being received

In the two socket classes the message controller is added with the message name and data (stringified) together instead of just the message name. This needs to change to so that it only enters the message from:

_ws.onMessage.listen((e) {
    var msg = new Message(e.data);
    _messageController.add(msg);
});

To:

_ws.onMessage.listen((e) {
    var msg = new Message.fromPacket(e.data);
    _messageController.add(msg.name);
});

I think that would work, but you should get what I'm on about. I don't know how I would add a unit test to test this however.

Support the passing of data via websockets

Though being able to "route" Socket messages with the data seems useful, by using the entire contents of the data to do the routing it makes passing data associated with the message impossible.

Some refactorings to address this include:

a) Change the routing to work with JSON data, and look for a specific "msg" and "data" attributes of the parsed hash which would be used for routing and message data respectively.
b) Removing "routing" from the Socket and instead expose the raw data for the application to handle?

Thoughts? I can do a PR.

request.params empty

Just FYI, request.params is empty until request.param(url) is specified first..

There is no access to request payload

The Request object doesn't provide any access to the request payload. It should provide access to HttpRequest#inputStream, so it's possible to get data from a POST.

application/json format.

I've tested the JSON request for my project.

This is my dart client is at
https://github.com/bsjung/start_examples/blob/master/jwt/server/client.dart.

The header is set to {'Content-Type': "application/json"}.
But, the most client software appends to UTF encoding into HTTP header : [application/json; charset=utf-8].

The isMime() loose default is false.
Thus I think the loose default option should be set the true for client software.


16 bool isMime(String type, {loose: false}) =>
17 _request.headers[HttpHeaders.contentTypeHeader]
18 .where((value) => loose ? value.contains(type) : value == type)
19 .isNotEmpty;


Benjamin Jung ( [email protected] )

Static serve of packages

Hello. I have a link to the packages folder in my web folder. I am not sure where pub get actually stores packages, but I don't think a static web serve actually serves these packages. TLDR Packages aren't getting served correctly.

Pub

Hi,

Could you please update the pub package with the latest version? There are breaking changes which are already fixed in the repo but aren't present in pub.

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.