Giter Site home page Giter Site logo

aragon-react-kit-boilerplate's Introduction

Aragon React Kit Boilerplate

๐Ÿ•ต๏ธ Find more boilerplates using GitHub | โœจ Official boilerplates

React boilerplate for Aragon applications.

This boilerplate also includes a fully working example app, complete with a background worker and a front-end in React (with Aragon UI).

Usage

Kit support requires using the Aragon CLI with a version greater than 4.1.0.

npm install -g @aragon/cli
aragon init app react-kit

Make the kit work with your app

  • In order for the kit to work properly, it needs to know what the name of your app is. Replace app in this line with the name of your app in the arapp.json file (e.g. myapp for myapp.aragonpm.eth)

  • Edit the roles defined in the kit to configure your DAO as you want!

Run the kit

aragon run --kit Kit --kit-init @ARAGON_ENS

Running your app

Using HTTP

Running your app using HTTP will allow for a faster development process of your app's front-end, as it can be hot-reloaded without the need to execute aragon run every time a change is made.

  • First start your app's development server running npm run start:app, and keep that process running. By default it will rebuild the app and reload the server when changes to the source are made.

  • After that, you can run npm run start:aragon:http or npm run start:aragon:http:kit which will compile your app's contracts, publish the app locally and create a DAO. You will need to stop it and run it again after making changes to your smart contracts.

Changes to the app's background script (app/script.js) cannot be hot-reloaded, after making changes to the script, you will need to either restart the development server (npm run start:app) or rebuild the script npm run build:script.

Using IPFS

Running your app using IPFS will mimic the production environment that will be used for running your app. npm run start:aragon:ipfs will run your app using IPFS. Whenever a change is made to any file in your front-end, a new version of the app needs to be published, so the command needs to be restarted.

What's in the box?

npm Scripts

  • start or start:aragon:ipfs: Runs your app inside a DAO served from IPFS
  • start:aragon:http: Runs your app inside a DAO served with HTTP (hot reloading)
  • start:aragon:ipfs:kit: Creates a DAO with the Kit and serves the app from IPFS
  • start:aragon:http:kit: Creates a DAO with the Kit and serves the app with HTTP (hot reloading)
  • start:app: Starts a development server for your app
  • compile: Compile the smart contracts
  • build: Builds the front-end and background script
  • build:app: Builds the front-end
  • build:script: Builds the background script
  • test: Runs tests for the contracts
  • publish:patch: Release a patch version to aragonPM (only frontend/content changes allowed)
  • publish:minor: Release a minor version to aragonPM (only frontend/content changes allowed)
  • publish:major: Release a major version to aragonPM (frontend and contract changes)
  • versions: Check the currently installed versions of the app

Libraries

Publish

This app has 3 environments defined in arapp.json:

Environment Network
default localhost
staging rinkeby
production mainnet

Prerequisites:

  • ENS Registry address

Note: the default environment which points to localhost does not have an ENS Registry address specified because the @aragon/cli will default the value to 0xB9462EF3441346dBc6E49236Edbb0dF207db09B7 (the ENS Registry pre-deployed on the local development chain).

Introduction to environments

Environments are defined in arapp.json, for example staging points to:

  • an ENS registry (0x314159265dd8dbb310642f98f50c066173c1259b)
  • an APM registry (open.aragonpm.eth)
  • an APM repository (app)
  • an Ethereum network (rinkeby)
  • an Ethereum websockets provider (wss://rinkeby.eth.aragon.network/ws - to read from the blockchain)

The rinkeby network is further defined in truffle.js, and has:

  • an Ethereum provider (to write to the blockchain):
    • an address (https://rinkeby.infura.io)
    • an Ethereum Account (0xb4124cEB3451635DAcedd11767f004d8a28c6eE7) (which is the first account generated from the DEFAULT_MNEMONIC variable, to use a different account see here)

Major version: content + contract

Command:

npm run publish:major -- --environment staging

This will:

  1. build the app's frontend (the output lives in dist)
  2. compile the app's contract (the output lives in build)
  3. publish the app to the staging environment.

Sample output:

 > aragon apm publish major "--environment" "staging"

 โœ” Successfully published app.open.aragonpm.eth v1.0.0:
 โ„น Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
 โ„น Content (ipfs): QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
 โ„น Transaction hash: 0x3d752db29cc106e9ff98b260a90615921eb32471425a29ead8cbb830fb224d8

Note: the contract location is defined in arapp.json under path. Note: you can also deploy a major version with only frontend changes by passing --only-content.

Minor/patch version: content only

Command:

npm run publish:patch -- --environment staging

This will:

  1. build the app's frontend (which lives in dist)
  2. publish the app to the staging environment.

Sample output:

 โœ” Successfully published app.open.aragonpm.eth v1.1.1:
 โ„น Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
 โ„น Content (ipfs): QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
 โ„น Transaction hash: 0x57864d8efd8d439008621b494b19a3e8f876a8a46b38475f9626802f0a1403c2

Check published versions

Command:

npm run versions -- --environment staging

Sample output:

 โ„น app.open.aragonpm.eth has 4 published versions
 โœ” 1.0.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
 โœ” 1.1.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmSwjUZFpv2c2e9fLoxtgFrAsAmBN4DyQGJp4RcqQcW3z3
 โœ” 1.1.1: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
 โœ” 2.0.0: 0x74CBbbC932d7C344FCd789Eba24BfD40e52980c9 ipfs:Qmadb3hzwLDKtb93fF367Vg1epkdsLZF4dhpapNYynjgZF

Using a different Ethereum account

To deploy from a different account, you can:

  • define a ~/.aragon/mnemonic.json file
    {
        "mnemonic": "explain tackle mirror kit ..."
    }
    
    or
  • define a ~/.aragon/${network_name}_key.json file, for example: ~/.aragon/rinkeby_key.json
    {
        "keys": [
            "a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563"
        ]
    }
    

Licensing

Note that the Kit contract has a special requirement on licensing because it includes contract dependencies that are licensed as GPL-3.0-or-later. This is the only file in your project that is required to be licensed this way, and you are free to choose a different license for the rest of the project.

aragon-react-kit-boilerplate's People

Contributors

0xgabi avatar bingen avatar bpierre avatar izqui avatar kernelwhisperer avatar onbjerg avatar ottodevs avatar sohkai avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

aragon-react-kit-boilerplate's Issues

Error when trying to run a fresh react-kit

 ~/code/aragon/app $ node -v
v10.14.1

 ~/code/aragon/app $ aragon -v
5.2.1

 ~/code/aragon $ aragon init app react-kit
 โœ” Preparing initialization
 โœ” Cloning app template
 โœ” Preparing template
 โœ” Installing package dependencies
 โœ” Created new application app.aragonpm.eth in app

 ~/code/aragon $ cd app
 ~/code/aragon/app $ aragon run --kit Kit --kit-init @ARAGON_ENS
 โœ” Start a local Ethereum network
 โœ” Check IPFS
 โœ” Publish app to APM
 โœ” Deploy Kit
 โฏ Create DAO
   โœ– Create new DAO from kit
     โ†’ Returned error: VM Exception while processing transaction: revert
     Checking DAO
   Open DAO
 โœ– Returned error: VM Exception while processing transaction: revert

The default counter example is not working. (script not found error)

I tried to reproduce the boilerplate counter example but is not working at all...

The script.js is not correctly being deployed to IPFS, so just trying to run:
aragon run --kit Kit --kit-init @ARAGON_ENS

Everything seems to work, but when I try to load the app in my browser, here is what the console tells me:
image

In the browser network requests tab I get this 404 response for that request:
ipfs resolve -r /ipfs/QmWFFAned4EaYR21RkTVB9HqDqWJaQS3fA6Kwnp3utNJ1g/dist/script.js: no link named "script.js" under QmNyzJuVxDurtypeveaFuzg4cEkndV4tWexokgS4E6UhgL

I tried to go into my local ipfs instance to look for the file, the dist file/folder exists but seems to be only the index.html nothing inside (so I am not sure if it is a folder or only a file)

Even the increment counter button raises a metamask transaction the counter never gets updated

npm run start:local 'scripts' is not recognized as an internal or external command

Im installing a fresh kit with the following (Im on win10)

rmdir /Q /S C:\Users\goran.aragon

node --version
v8.11.3

npm --version
6.4.1

npm i -g @aragon/cli
...

npm list -g @aragon/cli
C:\Users\goran\AppData\Roaming\npm
`-- @aragon/[email protected]

aragon --version
5.2.2

aragon init app react-kit
โˆš Preparing initialization
โˆš Cloning app template
โˆš Preparing template
โˆš Installing package dependencies
โˆš Created new application app.aragonpm.eth in app

cd app

aragon run --kit Kit --kit-init @ARAGON_ENS
โˆš Start a local Ethereum network
โˆš Check IPFS
โˆš Publish app to APM
โˆš Deploy Kit
โˆš Create DAO
โˆš Open DAO
i You are now ready to open your app in Aragon.
i Here are some Ethereum accounts you can use.
The first one will be used for all the actions the CLI performs.
You can use your favorite Ethereum provider or wallet to import their private keys.

Address #1: 0xb4124cEB3451635DAcedd11767f004d8a28c6eE7 (this account is used to deploy DAOs, it has more permissions)
Private key: a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563
Address #2: 0x8401Eb5ff34cc943f096A32EF3d5113FEbE8D4Eb
Private key: ce8e3bda3b44269c147747a373646393b1504bfcbb73fc9564f5d753d8116608
i The accounts were generated from the following mnemonic phrase:
explain tackle mirror kit van hammer degree position ginger unfair soup bonus

i This is the configuration for your development deployment:
Ethereum Node: ws://localhost:8545
ENS registry: 0x5f6f7e8cc7346a11ca2def8f827b7a0b612c56a1
APM registry: aragonpm.eth
DAO address: 0x5b6a3301a67A4bfda9D3a528CaD34cac6e7F8070

Opening http://localhost:3000/#/0x5b6a3301a67A4bfda9D3a528CaD34cac6e7F8070 to view your DAO

(node:13984) UnhandledPromiseRejectionWarning: Error: Error: Command failed: npm run start:local
'scripts' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start:local: scripts/launch-local.sh
npm ERR! Exit status 1

I attached the complete log
2019-01-07T11_34_30_014Z-debug.log

App.sol should be named properly to CounterApp.sol or the correct contract name in the default deploy_contracts migration

var App = artifacts.require('./App.sol')

Rename at least App.sol occurrences to CounterApp:

var App = artifacts.require('./CounterApp.sol')

module.exports = function (deployer) {
  deployer.deploy(App)
}

To reproduce the error just follow the Readme.MD instructions to init a new project and try to run:
npm run test
An error message about App.sol not found will raise without fixing the contract name.

Error trying to run: npm run start:aragon:http

I forked and downloaded the aragon-boilerplate repo.

did an npm install and then followed the instructions in the readme file.

$ npm run start:app | works fine
$ npm run start:aragon:http | fails

Error

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start:aragon:http: `aragon run --http localhost:8001 --http-served-from ./dist`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start:aragon:http script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/lismore/.npm/_logs/2018-11-11T12_39_53_249Z-debug.log

The full output of the complete log file is here

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/11.1.0/bin/node',
1 verbose cli   '/usr/local/bin/npm',
1 verbose cli   'run',
1 verbose cli   'start:aragon:http' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart:aragon:http',
4 verbose run-script   'start:aragon:http',
4 verbose run-script   'poststart:aragon:http' ]
5 info lifecycle [email protected]~prestart:aragon:http: [email protected]
6 info lifecycle [email protected]~start:aragon:http: [email protected]
7 verbose lifecycle [email protected]~start:aragon:http: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]~start:aragon:http: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/.bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/share/dotnet:~/.dotnet/tools
9 verbose lifecycle [email protected]~start:aragon:http: CWD: /Users/lismore/Documents/GitHub/aragon-fundraising-application
10 silly lifecycle [email protected]~start:aragon:http: Args: [ '-c',
10 silly lifecycle   'aragon run --http localhost:8001 --http-served-from ./dist' ]
11 silly lifecycle [email protected]~start:aragon:http: Returned: code: 1  signal: null
12 info lifecycle [email protected]~start:aragon:http: Failed to exec start:aragon:http script
13 verbose stack Error: [email protected] start:aragon:http: `aragon run --http localhost:8001 --http-served-from ./dist`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
13 verbose stack     at EventEmitter.emit (events.js:182:13)
13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:182:13)
13 verbose stack     at maybeClose (internal/child_process.js:970:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:257:5)
14 verbose pkgid [email protected]
15 verbose cwd /Users/lismore/Documents/GitHub/aragon-fundraising-application
16 verbose Darwin 18.2.0
17 verbose argv "/usr/local/Cellar/node/11.1.0/bin/node" "/usr/local/bin/npm" "run" "start:aragon:http"
18 verbose node v11.1.0
19 verbose npm  v6.4.1
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] start:aragon:http: `aragon run --http localhost:8001 --http-served-from ./dist`
22 error Exit status 1
23 error Failed at the [email protected] start:aragon:http script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

Also relevant I notice lots of warnings

screenshot 2018-11-11 at 12 46 20

some additional info to help troubleshoot this,

macOS Mojave
node v11.1.0
npm 6.4.1
[email protected]

additional output

Compilation warnings encountered:

/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:20:48: Warning: "throw" is deprecated in favour of "revert()", "require()" and "assert()".
        if (records[node].owner != msg.sender) throw;
                                               ^---^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:27:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function ENS() public {
    ^ (Relevant source part starts here and spans across multiple lines).
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:71:9: Warning: Use of the "var" keyword is deprecated.
        var subnode = keccak256(node, label);
        ^---------^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/PublicResolver.sol:43:44:Warning: "throw" is deprecated in favour of "revert()", "require()" and "assert()".
        if (ens.owner(node) != msg.sender) throw;
                                           ^---^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/PublicResolver.sol:51:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function PublicResolver(AbstractENS ensAddr) public {
    ^ (Relevant source part starts here and spans across multiple lines).
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/PublicResolver.sol:144:9:Warning: Use of the "var" keyword is deprecated.
        var record = records[node];
        ^--------^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/PublicResolver.sol:164:53: Warning: "throw" is deprecated in favour of "revert()", "require()" and "assert()".
        if (((contentType - 1) & contentType) != 0) throw;
                                                    ^---^
,@aragon/apps-shared-minime/contracts/MiniMeToken.sol:37:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function Controlled()  public { controller = msg.sender;}
    ^-------------------------------------------------------^
,@aragon/apps-shared-minime/contracts/MiniMeToken.sol:123:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function MiniMeToken(
    ^ (Relevant source part starts here and spans across multiple lines).
,@aragon/apps-shared-minime/contracts/MiniMeToken.sol:195:9: Warning: Use of the "var" keyword is deprecated.
        var previousBalanceFrom = balanceOfAt(_from, block.number);
        ^---------------------^
,@aragon/apps-shared-minime/contracts/MiniMeToken.sol:209:9: Warning: Use of the "var" keyword is deprecated.
        var previousBalanceTo = balanceOfAt(_to, block.number);
        ^-------------------^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/apps-shared-minime/contracts/MiniMeToken.sol:37:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function Controlled()  public { controller = msg.sender;}
    ^-------------------------------------------------------^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/apps-shared-minime/contracts/MiniMeToken.sol:123:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function MiniMeToken(
    ^ (Relevant source part starts here and spans across multiple lines).
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/apps-shared-minime/contracts/MiniMeToken.sol:195:9: Warning: Use of the "var" keyword is deprecated.
        var previousBalanceFrom = balanceOfAt(_from, block.number);
        ^---------------------^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/apps-shared-minime/contracts/MiniMeToken.sol:209:9: Warning: Use of the "var" keyword is deprecated.
        var previousBalanceTo = balanceOfAt(_to, block.number);
        ^-------------------^
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/contracts/Kit.sol:22:5: Warning: Defining constructors as functionswith the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function KitBase(DAOFactory _fac, ENS _ens) public {
    ^ (Relevant source part starts here and spans across multiple lines).
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/contracts/Kit.sol:48:5: Warning: Defining constructors as functionswith the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
    function Kit(ENS ens) KitBase(DAOFactory(0), ens) public{
    ^ (Relevant source part starts here and spans across multiple lines).
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/contracts/misc/Migrations.sol:11:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead.
  function Migrations() {
  ^ (Relevant source part starts here and spans across multiple lines).
,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:58:37: Warning: This declaration shadows an existing declaration.
    function setOwner(bytes32 node, address owner) only_owner(node) public {
                                    ^-----------^
/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:34:5: The shadoweddeclaration is here:
    function owner(bytes32 node) public constant returns (address) {
    ^ (Relevant source part starts here and spans across multiple lines).

,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:70:59: Warning: This declaration shadows an existing declaration.
    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) only_owner(node) public {
                                                          ^-----------^
/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:34:5: The shadoweddeclaration is here:
    function owner(bytes32 node) public constant returns (address) {
    ^ (Relevant source part starts here and spans across multiple lines).

,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:81:40: Warning: This declaration shadows an existing declaration.
    function setResolver(bytes32 node, address resolver) only_owner(node) public {
                                       ^--------------^
/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:41:5: The shadoweddeclaration is here:
    function resolver(bytes32 node) public constant returns (address) {
    ^ (Relevant source part starts here and spans across multiple lines).

,/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:91:35: Warning: This declaration shadows an existing declaration.
    function setTTL(bytes32 node, uint64 ttl) only_owner(node) public {
                                  ^--------^
/Users/lismore/Documents/GitHub/aragon-fundraising-application/node_modules/@aragon/os/contracts/lib/ens/ENS.sol:48:5: The shadoweddeclaration is here:
    function ttl(bytes32 node) public constant returns (uint64) {
    ^ (Relevant source part starts here and spans across multiple lines)

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.