cooklang / cookcli Goto Github PK
View Code? Open in Web Editor NEWCommand line program which provides a suite of tools to create shopping lists and maintain recipes.
Home Page: https://cooklang.org
License: MIT License
Command line program which provides a suite of tools to create shopping lists and maintain recipes.
Home Page: https://cooklang.org
License: MIT License
If you run cook server
, the program starts but nothing is logged to stdout. When visiting http://127.0.0.1:9080/, I can clearly see the server is running. This is confusing because unless you know that the server is going to run on port 9080, it seems like the program just hangs.
Looking at the code, I see that tracing
is the logging library. If I remember correctly, it is necessary to register subscribers to collect the logging info. tracing-subscriber
is a common one for logging too stdouot.
I absolutely L-L-LOVE cooklang! Recently discovered it and just jumped in head-first. I did notice, however, that there already exists a Recipe schema for structured data: https://schema.org/Recipe
Wondering if it's possible to enhance the CLI to output a json-formatted structured data for inclusion on the web for enhanced SEO by google, and other search engine crawlers? Perhaps through including metadata fields that map to specific schema Properties like >> servings
would map to recipeYield
during output, and a validator can tell you what schema properties are missing for the output to be valid? Just thinking out loud.... as this would be a great way to bridge these two technologies.
Edit: I just noticed that cook recipe read recipe.cook --output-format json
spits out json, would be great if there's an output format that will allow to map to the Recipe schema, like --output-format recipe-json
or something like that.....
When making some cooklang recipes, I have noticed that there is not a good way to represent certain ingredients. In the real world, you would be given an ingredient list that may include "Campbell's Condensed Cream of Chicken Soup (10.75oz can)," while in the recipe it references this item only as "the soup." Cooklang only supports one name for each ingredient, so in the recipe, this item would be referred to by its full name (rather encumbering).
I suggest a "nickname" definition, perhaps like so:
Add the @Campbell's Condensed Cream of Chicken Soup(soup){1%can}
or perhaps:
Add the @Campbell's Condensed Cream of Chicken Soup{(soup)1%can}
or maybe with [brackets], who knows?
Either way, I highly recommend these changes to improve the "natural" language of recipes.
As an aside, this would also allow for much more information to be placed within the actual ingredients section that may not be necessary in the directions.
Running Pop_OS! 21.04 and invoking cook shopping-list <some cook file>
segfaults every time.
Running on Linux I've tried running cook fetch
with no other arguments and left it for several hours. Also, if you run cook fetch .
the application has a fatal error, causing a an illegal hardware instruction
.
Version: v0.0.9 – in food we trust
When following the installation instructions for Linux, running cook
results in the following errors:
Error relocating /usr/local/bin/cook: fts_open: symbol not found
Error relocating /usr/local/bin/cook: fts_read: symbol not found
Error relocating /usr/local/bin/cook: fts_close: symbol not found
Error relocating /usr/local/bin/cook: fts_set: symbol not found
I have installed the musl-fts
and musl-fts-devel
packages in an effort to circumvent this issue, but to no avail.
On big screens, being able to see ingredients and steps side-by-side would save a couple of clicks back and forth. Have you thought about this before?
Hi, thank you for making Cooklang!
I have created some CSS adjustments for the Recipe page which makes it easier to print the page.
Since I don't know anything about Stelve or Swift, I cannot make a real PR, but I feel like it would be a waste to not share it. So if you ever want to incorporate something like this, I invite you to take this as an example.
And that is the code behind it:
@media print {
nav.navbar, .btn {
display: none;
}
ol.breadcrumb li:not(:last-of-type) {
display: none;
}
li.breadcrumb-item {
font-size: 2em;
}
.breadcrumb-item+.breadcrumb-item::before {
content: '';
}
ul.nav {
display: none;
}
.tab-content>.tab-pane {
display: block;
}
.tab-content>.tab-pane:first-of-type {
width: 20rem;
border: 1px solid black;
border-radius: 0px;
padding: 1.5rem 1rem;
float: left;
margin-right: 2rem;
margin-left: 1rem;
}
.tab-content>.tab-pane:nth-of-type(2) {
display: none;
}
}
Hi,
I'm trying to prepare an arch linux package for this but the build documentation is kinda lacking. Right now I got it boiled down to this:
make prepare
(this fails on linux because of different sed implementations and I guess you need node and something called rollup.js
too?)swift build --configuration release -Xswiftc -static-stdlib
.build/x86_64-unknown-linux-gnu/release/cook
To get their recipes in search engine's rich recipe search results, many recipe sites describe their recipes with a JSON schema in a special HTML tag. Some recipe apps can interpret this schema in order to import recipes. CookCLI could parse this schema and generate a cook file that could be reviewed by a human.
More information about structured data and recipe schemas is available at Google developers.
Started server on http://127.0.0.1:9080, serving cook files from /Users/azlekov/Workspace/cookbook.
[1] 24627 segmentation fault cook server
Steps to reproduce:
cook seed
cook server
Steps to reproduce 2:
cook seed
cook server
OS: macOS X 12.2.1
Version of the CLI: 0.1.3
The cook server
is great, but it's not practical to use without a computer to serve it on. It would be really nice to be able to generate a static website from a recipe book that could be deployed to (say) GitHub Pages, and then used the same way as the existing server (keeping all the shopping list state client-side, if it isn't already).
When using the cook recipe read
method with the --output-format
option, it would be great if you could output the metadata for the recipe, along with the cookware, ingredients and method.
p.s. love the library!
When running on M1 Macs the only way to use the CLI is to do a local compilation, requiring the full installation of XCode. It would be prefereable to create binaries for ARM-arch as well as the AMD ones in the future
Reproduction steps:
brew tap cooklang/tap
brew install cooklang/tap/cook
cook version
# v0.1.2 – in food we trust
mkdir recipes
cook seed ./recipes
cook server ./recipes
# Started server on http://127.0.0.1:9080, serving cook files from ./recipes.
# Navigate to http://localhost:9080/
# Navigate to http://localhost:9080/shopping-list
# zsh: segmentation fault cook server ./recipes
I tried to build from source on Arch Linux using the instructions provided in the README, but got this error:
> [email protected] build
> rollup -c
[!] RollupError: Node tried to load your configuration file as CommonJS even
though it is likely an ES module. To resolve this, change the extension of yo
ur configuration to ".mjs", set "type": "module" in your package.json file or
pass the "--bundleConfigAsCjs" flag.
Original error: Cannot use import statement outside a module
https://rollupjs.org/command-line-interface/#bundleconfigascjs
/home/user/custom-pkgs/cookcli-git/src/cookcli-0.4.0/ui/rollup.
config.js:1
import svelte from 'rollup-plugin-svelte';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at internalCompileFunction (node:internal/vm:77:18)
at wrapSafe (node:internal/modules/cjs/loader:1288:20)
at Module._compile (node:internal/modules/cjs/loader:1340:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12)
at cjsLoader (node:internal/modules/esm/translators:345:17)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:294:7)
at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
Then, as suggested in the output, I changed the filename of rollup.config.js
to rollup.config.mjs
, which resulted in this error:
> [email protected] build
> rollup -c
[!] Error: Cannot find package 'rollup-plugin-svelte' imported from /home/user/custom-pkgs/cookcli-git/src/cookcli-0.4.0/ui/rollup.config.mj
s
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'rollup-plugin-svelte' impo
rted from /home/user/custom-pkgs/cookcli-git/src/cookcli-0.4.0/
ui/rollup.config.mjs
at packageResolve (node:internal/modules/esm/resolve:844:9)
at moduleResolve (node:internal/modules/esm/resolve:901:20)
at defaultResolve (node:internal/modules/esm/resolve:1121:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:396:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:365:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:240:38)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
at link (node:internal/modules/esm/module_job:84:36)
I am trying to build on Arch Linux using makepkg
. I doubt that it has any effect on the behavior observed, but here is the PKGBUILD
for completeness:
pkgname='cookcli-git'
_pkgname="${pkgname%-git}"
arch=('x86_64')
pkgver=0.4.0
pkgrel=1
pkgdesc='CookCLI is provided as a command-line tool to make Cook recipe management easier, and enable automation and scripting workflows for the CookLang ecosystem. Build from source.'
provides=("${_pkgname}")
conflicts=("${_pkgname}" "${_pkgname}-bin")
url='https://github.com/cooklang/cookcli'
license=('MIT')
makedepends=('rust' 'npm' 'rollup')
source=("cookcli_${pkgver}.tar.gz::https://github.com/cooklang/CookCLI/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('b66b7256074e85dee717855ffb149afde66591c14c2da47229a27b8c2fce222d')
build() {
cd "${srcdir}/cookcli-${pkgver}"
cd ui && npm run build
cd ../src
cargo build --release
}
I am not familiar with the Javascript ecosystem and I did not want to try this outside of makepkg
to avoid npm
downloading packages on to my host, so this is where I stopped.
Can someone please help me with this? :)
I was surprised by 125 g of flour being rendered as 120 g, but when digging deeper, I found that ingredients without a unit somehow get rounded too when using cook cli (yes, that is an unreasonable amount of eggs, but you get the idea 😄):
bug.cook
:
@flour{125%g} @egg{125}
Actual output:
$ cook recipe read bug.cook
Ingredients:
egg 120
flour 120 g
Steps:
1. flour egg
[egg: 120; flour: 120 g]
Expected output:
$ cook recipe read bug.cook
Ingredients:
egg 125
flour 125 g
Steps:
1. flour egg
[egg: 125; flour: 125 g]
The numbers are incorrect in the server too.
... as I would like to use it on this platform.
Thanks a lot.
First off - love this idea and the effort put into it so far!
This is more of a question / suggestion than an issue, but would it be possible to generate .md
files using the cookcli? Essentially converting the .cook
file to an .md
so I could put it on github or gitlab and have it auto-formatted?
It would be nice to have some integration with LSP-compatible text editors for syntax highlighting, autocompletion of ingredients, syntax validation, etc. It would be more universal than addons for Sublime and VSCode.
Hey,
It would be awesome to be able to parse an argument to the .cook file to let it know how many servings I would like to make and then automatically adapt the amount I need to buy accordingly. I, unfortunately, do not have that much time to make a pull request myself, but if no one has picked up the idea until I find time, I probably will make a pull request.
Anyways, I love the idea, the simplicity and all that!
I have a set of recipes ordered into folders. The web page served by cook server
shows them in an undefined order (or is there an order?). Is it possible to sort alphabetically?
Hello,
I was wondering if there was a way to make this work with web browsers, so that a Javascript function can process the parsed results of cooklang.
Thanks,
Nakul
Right now a recipe picture will be displayed only in the recipe list:
We should also display it on a recipe screen here:
And display step images too
Seems like one of the big benefits of cooklang is that you could programmatically adjust a recipe for a different serving size, convert imperial to metric units, or vice versa.
Any plans for this? Are PRs welcome? Should I just write my own tool?
Running on arch linux I get a segmentation fault on v0.1.3:
> cook server
Started server on http://127.0.0.1:9080, serving cook files from /home/ludwig/Documents/cook.
zsh: segmentation fault (core dumped) cook server
but only after I open the webpage in my browser. I tried it both with the provided binary and with a self compiled binary.
Furthermore, with v0.1.2 I get an instant segmentation fault and with v0.0.13 it works.
I hope somebody can help me, or that this bug report will be of some help.
Awesome project!
I apologize in advance if I am not using cooklang in the intended manner, but I think I have discovered a use case that is not included in the specification or example recipes.
In most recipes, physical preparation instructions for ingredients (like dicing, chopping, mincing, cutting on bias, etc.) are specified with the ingredient quantities. For example, a recipe calling for 2 cups of finely chopped carrots would have the following entry for carrots in the Ingredients list:
Ingredients:
- 2 cups carrot, finely chopped
When I'm writing this recipe in cooklang, I want the preparation instructions for carrots to appear in the Ingredients section of the output of $ cook recipe read
. I could include the preparation instructions in a comment, but that wouldn't show up in the output. In order to have the preperation instructions appear in the Ingredients section, I included them inside the curly braces {}
after the unit when defining the ingredient. Here's an example:
Add @carrots{2%cup, finely chopped}
The desired output of $ cook recipe read
would be:
Ingredients:
carrots 2 cups, finely chopped
Steps:
1. Add carrots
[carrots: 2 cups]
However, the actual output of $ cook recipe read
is:
Ingredients:
carrots 2 cup, finely choppeds
Steps:
1. Add carrots
[carrots: 2 cup, finely choppeds]
In this example, cooklang thinks that the entire string following the %
character inside {}
is the unit. When cooklang attempts to use the plural form of the unit (since the recipe requires 2 cups plural of carrots), cooklang appends an "s" to the last word in the string (chopped) instead of the actual unit (cup).
I think I've accidentally uncovered two issues here:
$ cook recipe read
?One option would be to have cooklang consider only the word immediately after the %
character to be the unit, and ignore everything else.
Love the tool so far. Some ideas from using it that would make it easier while cooking
Option to sort ingredient list by step.
Typical recipes will have ingredients sorted by the order that they are added to the recipe. This can make it easier to know where you are, what other ingredients you'll need soon, and make it less likely to miss an ingredient
Recipe grouping
Many recipes have some sort of sub-recipe with its own group of ingredients. Think a sauce/glaze/some other step that wouldn't function as a stand-alone recipe. Handy like the above option. Also useful when the same ingredient can appear in both groups. I've accidentally added too much of an ingredient in the moment in recipes where it is not clearly split apart
I'm having an issue with the cook server
; here is the error (Ubuntu 20.04) :
cook: dl-call-libc-early-init.c:37: _dl_call_libc_early_init: Assertion `sym != NULL' failed.
[1] 15474 abort (core dumped) cook server
It seems to be a compatibility problem old/mordern Linux distribution maybe more here.
-> but it only happen on v0.1.3 ; v0.1.2 works fine
I just tried to write down this recipe from Glen and Friend's Cooking in cooklang when I discovered that there is no way of escaping the % character for ingredient units.
The recipe in the description of the video calls for 100% chicken bones
.
I tried @chicken bones{100%%}
and got 100 chicken bones
😆
Tested it in the playground.
I'm running cookcli on Pop!_OS 22.04 LTS. When I run it, I get the following error:
cannot execute binary file: Exec format error
I'm running 0.7.1.
Hey - in case I haven't mentioned it, I'm absolutely IN LOVE with this project! I've already started converting many of my own recipes into this format, and it's been so immeasurably helpful.
I often use Termux on my android device, and tried to run the arm64 binary on it, but when I do, I get the error:
29950 invalid system call cook
Am I doing something wrong?
When running cook recipe file.cook
, cookware and ingredients are output in a random order. It would be nicer for readers if they were presented in a consistent fashion.
For cookware, I'd argue "in the order listed in the recipe" is the most consistent.
For ingredients, there's a few options (I favour the latter):
Regardless of order chosen, it should be consistent for all output formats.
Sometimes, a recipe isn't exact and would require a range of quantities like 1-2 tablespoons, or 12-15 minutes. There doesn't appear to be an elegant way to accommodate something like this. While there are some "workarounds" in the instructions section, such as:
~bake{12%minutes} - 13 minutes
What renders in the "Timers" section is just "bake (12 minutes)". Similarly, if a dough needs 1-2 tablespoons of water, adding as needed to adjust for environmental factors (altitude, humidity, etc) the steps will only allow to define a single quantity such as @water{1%tablespoon}
. Would be great to see this implemented. Unless there's something I'm missing?
Right now we only build binaries for macOS and Linux. Swift is officially supported on Windows now, so we can explore options to build CLI to work natively on Windows.
It would be amazing, if the tool would be available over HomeBrew.
Ressources:
I'm not comfortable downloading and running unsigned binaries, and would greatly appreciate build instructions or a signature with the binary!
The default output generated from:
cook recipe read <recipe-file>
Generates a structure with four headers: Metadata, Ingredients, Cookware, Steps.
Is it possible to change these headings for specific cases where alternate headings are preferred?
For example, files being shared within a small food manufacturer could be given the corresponding headers: Product, Materials, Equipment, Operations.
Hello! Love this tool so far.
It looks like a recipe's steps are required to be on a single line. When reading the recipe via the cli-tool (eg: cook recipe read Baked\ Potato\ Soup.cook
) each step is rendered on a line which takes the full length of the terminal window (see screenshot below).
Feature request: can this output be wrapped to 80 characters or made configurable what the line width should be?
IMO, this would make for more readable recipe cards.
I think adding a Dockerfile would really benefit this project! Here is the one I currently use for a Raspberry Pi, based on Alpine Linux.
from alpine:3.18
ARG DOWNLOAD_URL="https://github.com/cooklang/cookcli/releases/latest/download/cook-aarch64-unknown-linux-musl.tar.gz"
# Set workdir to /app
WORKDIR /app
# Download CookCLI file
ADD ${DOWNLOAD_URL} .
# Untar binary
RUN tar -xvf cook-*
# Remove tar
RUN rm *.tar.gz
# Expose default port (9080)
EXPOSE 9080
# Run Server
ENTRYPOINT ["./cook", "server", "--host", "./recipes"]
You could overwrite the download URL with --build-arg
, currently it points to the latest build of the aarch64 version. Also, I'm not sure if logs would be redirected to docker logs
output, since it seems like the cook
binary doesn't output anything anyway?
Also, I spent hours realising that the --host
argument is missing. Maybe add that to the docs?
From #2 (comment):
were you able to use images in the web view? According to the docs, I just need to place an image with the same name as the recipe in the directory of the recipe, but nothing is showing.
@juliangaal From my testing, it somewhat works. This is my directory layout; if I understand the docs correctly, the bottom image (without .2
) should be displayed as the recipe cover and the other should be displayed somewhere around step 3.
The cover image works fine but the one that's supposed to accompany step 3 does not show up. I assume it's just not implemented in CookCLI yet.
That's all with the local server though. The one on my VPS doesn't show images at all, because it's requesting them from a hardcoded localhost
URI instead of a relative path.
I imagine the fix is simple enough that I could open a PR without knowing Swift at all; I can take a look at it in a bit if @dubadub is alright with that 😄
The cooklang spec states that quantity for cookware is supported. However, when running it, the output shows a warning.
Actual Output
$ cook recipe read << EOF
#test{1}
EOF
Warning: expected '}' but got 1
Ingredients:
Cookware:
test
Steps:
1. test1}
[–]
Expected Output
$ cook recipe read << EOF
#test{1}
EOF
Cookware:
test 1
Steps:
1. test
[–]
...
cookware = one word cookware | multiword cookware ;
+one word cookware = "#", ( word, [ "{", [ quantity ], "}" ] ) ;
multiword cookware = "#", ( word, { text item - "{" }-, "{", [ quantity ], "}" ) ;
...
$ cook version
v0.1.4 – in food we trust
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04 LTS
Release: 22.04
Codename: jammy
I'm trying to run the binary on my Raspberry Pi 4, but get the following error: cannot execute binary file: Exec format error
(when running ./cook
).
lsb_release -a
gives the following output:
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal
uname -a
gives the following output:
Linux <NAME> 5.4.0-1095-raspi #106-Ubuntu SMP PREEMPT Fri Sep 15 09:09:18 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
dpkg-architecture --list
gives the following output:
DEB_BUILD_ARCH=arm64
DEB_BUILD_ARCH_ABI=base
DEB_BUILD_ARCH_BITS=64
DEB_BUILD_ARCH_CPU=arm64
DEB_BUILD_ARCH_ENDIAN=little
DEB_BUILD_ARCH_LIBC=gnu
DEB_BUILD_ARCH_OS=linux
DEB_BUILD_GNU_CPU=aarch64
DEB_BUILD_GNU_SYSTEM=linux-gnu
DEB_BUILD_GNU_TYPE=aarch64-linux-gnu
DEB_BUILD_MULTIARCH=aarch64-linux-gnu
DEB_HOST_ARCH=arm64
DEB_HOST_ARCH_ABI=base
DEB_HOST_ARCH_BITS=64
DEB_HOST_ARCH_CPU=arm64
DEB_HOST_ARCH_ENDIAN=little
DEB_HOST_ARCH_LIBC=gnu
DEB_HOST_ARCH_OS=linux
DEB_HOST_GNU_CPU=aarch64
DEB_HOST_GNU_SYSTEM=linux-gnu
DEB_HOST_GNU_TYPE=aarch64-linux-gnu
DEB_HOST_MULTIARCH=aarch64-linux-gnu
DEB_TARGET_ARCH=arm64
DEB_TARGET_ARCH_ABI=base
DEB_TARGET_ARCH_BITS=64
DEB_TARGET_ARCH_CPU=arm64
DEB_TARGET_ARCH_ENDIAN=little
DEB_TARGET_ARCH_LIBC=gnu
DEB_TARGET_ARCH_OS=linux
DEB_TARGET_GNU_CPU=aarch64
DEB_TARGET_GNU_SYSTEM=linux-gnu
DEB_TARGET_GNU_TYPE=aarch64-linux-gnu
DEB_TARGET_MULTIARCH=aarch64-linux-gnu
So I'm pretty certain I'm running an arm64 compatible system. What am I missing? I've tried all possible versions for v0.1.6
and v0.1.5
.
I was able to find photos from the iOS app, but not the webserver. Did I miss them?
Update: tried getting it to run myself and am running into issues with server
My tree after running ./cook seed
to generate recipes.
.
├── Baked Potato Soup.cook
├── Borsch.cook
├── Breakfasts
│ ├── French Breakfast.cook
│ ├── Irish Breakfast.cook
│ ├── Irish Breakfast.jpg
│ ├── Jamie
│ │ ├── Easy Pancakes.cook
│ │ └── Mexican Style Burrito.cook
│ └── Oats.cook
├── cook (binary)
├── Lazy Tomato and Cuke Salad.cook
├── Neapolitan Pizza.cook
├── Olivier Salad.cook
├── Potstickers.cook
├── README.md
├── Root Vegetable Tray Bake.cook
├── Salads
│ ├── Beetroot, feta & grain salad.cook
│ └── Caprese Salad.cook
├── Sicilian-style Scottadito Lamb Chops.cook
├── Snack Basket I.cook
├── Snack Basket II.cook
└── Zharkoe.cook
OS: Ubuntu 20.04
Browser: FF 93.00
When serving with ./cook server
and browsing to 127.0.0.1:9080, I am greeted with this
Thanks for your help, this looks like a really cool project!
It doesn't have the output like the help page.
Access on another Android device:
~ $ curl -vvl http://192.168.1.10:9080/
* Trying 192.168.1.10:9080...
* connect to 192.168.1.10 port 9080 failed: Connection refused
* Failed to connect to 192.168.1.10 port 9080 after 6 ms: Couldn't connect to server
* Closing connection
curl: (7) Failed to connect to 192.168.1.10 port 9080 after 6 ms: Couldn't connect to server
~ $ nmap -P0 -sV -p9080 192.168.1.10
Starting Nmap 7.94 ( https://nmap.org/ ) at 2023-11-25 12:20 CST
Nmap scan report for 192.168.1.10
Host is up (0.0048s latency).
PORT STATE SERVICE VERSION
9080/tcp closed glrpc
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.80 seconds
~ $
Chrome prompts ERR_CONNECTION_REFUSED
.
Noticed the new release, but not seeing the linux executable in the releases....possible to compile locally for arm64 arch following the docs in the readme?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.