freenode / ircd-seven Goto Github PK
View Code? Open in Web Editor NEWfreenode's IRC server daemon
License: Other
freenode's IRC server daemon
License: Other
******************************* IMPORTANT ************************************* *********** Note for those who dont bother reading docs ***************** * - Reading INSTALL is now a must, as the old DPATH is now specified * * when configure is run. * * You now need to ./configure --prefix="/path/to/install/it" * * to specify the path that will be installed with your ircd! * ************************************************************************* ALSO, IF YOU ARE UPGRADING YOUR CURRENT SOURCE TREE, AND YOU TRY TO BUILD IN IT WITHOUT PERFORMING AT LEAST 'make clean', THINGS _WILL_ BREAK. IT IS RECOMMENDED THAT YOU RUN 'make distclean' AND THEN RERUN './configure'! ******************************* REQUIREMENTS ********************************** Necessary Requirements: - A supported platform (look below) - A working dynamic load library. - A working lex. Solaris /usr/ccs/bin/lex appears to be broken, on this system flex should be used. Feature Specific Requirements: - For SSL Clients, SSL Challenge controlled OPER feature, and encrypted server links, a working OpenSSL library or GnuTLS library. CHALLENGE is not supported on GnuTLS yet. - For encrypted oper and (optional) server passwords, a working DES, MD5, or SHA library implementing crypt(). ******************************************************************************* - To report bugs in charybdis, visit us at irc.atheme.org #charybdis - See the INSTALL document for info on configuring and compiling charybdis. - Please read doc/index.txt to get an overview of the current documentation. - The files, /etc/services, /etc/protocols, and /etc/resolv.conf, SHOULD be readable by the user running the server in order for ircd to start with the correct settings. If these files are wrong, charybdis will try to use 127.0.0.1 for a resolver as a last-ditch effort. - FREEBSD USERS: if you are compiling with ipv6 you may experience problems with ipv4 due to the way the socket code is written. To fix this you must: "sysctl net.inet6.ip6.v6only=0" - SOLARIS USERS: this code appears to tickle a bug in older gcc and egcs ONLY on 64-bit Solaris7. gcc-2.95 and SunPro C on 64bit should work fine, and any gcc or SunPro compiled on 32bit. - DARWIN AND MACOS X USERS: You must be using at least the December 2001 Development Tools from Apple to build charybdis with shared modules. Before then you MUST disable shared modules, as we do not have the proper flags for cc(1) prior to that point to produce shared modules. - SUPPORTED PLATFORMS: this code should compile without any warnings on: FreeBSD 6.x/7.x, Gentoo & Gentoo Hardened ~x86/~amd64/~fbsd Fedora 8/9 / CentOS 4/5 / Redhat Enterprise 5 Debian Etch, OpenSuSE 10/11, OpenSolaris 2008.x? Solaris 10 sparc. Please let us know if you find otherwise. It probably does not compile on AIX, IRIX or libc5 Linux. - TESTED PLATFORMS: The code has been tested on the following platforms, and is known to run properly. FreeBSD 6.x/7.x Linux glibc-2.6, glibc-2.7 Solaris 2.6/7/8 OpenBSD 2.8 NetBSD 1.4 - Please read NEWS for information about what is in this release. - Other files recommended for reading: BUGS, INSTALL
Hi, most IRC servers like Gimpnet or OFTC report an error when trying to set /nick Mo~
:
Mo~ :Erroneous Nickname
However Freenode just cuts the nick at ~
, so /nick Mo~jo
results in a nick named Mo.
First of all, is the ~
allowed? I heard different statements about that, but https://tools.ietf.org/html/rfc1459#section-2.3.1 says it is not part of
<special> ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}'
Hi,
I'd like to (safely) authenticate certain Freenode users against a web service by having them provide a token to a bot through Freenode.
I'd only like to authenticate users that are logged into a nickserv account.
Harder way involves activating identify-msg
, extended-join
and account-notify
, then using WHOX
with the a
and n
fields, keeping track of accounts, and only allowing PRIVMSG
from a user that's in a known channel that my bot is also a member of. I'm sure I'm missing a race condition somewhere.
Easy way to do this would be to activate the account-tag
capability in my bot, then have the users PRIVMSG
my bot with the token generated by the web service.
In this case, there would be no need for the bot to join any channels or to keep track of the user's account; if the Freenode message includes both the correct account and the token generated by my web service, the bot can tell the web service authentication has succeeded.
Would it be feasible to complement identify-msg
with account-tag
?
Hello,
I usually use Freenode with Tor, and I notice a problem.
After a few days of connection (maximum 3 days), the IRCD of Freenode disconnects me with the following message :
warning SSL read error: server closed connection unexpectedly.
Why can not I go beyond 3 days of connection?.
Tor version : 0.2.9.16-1.
Irssi version : 1.2.0.
OpenSSL version : 1.1.0j-1~deb9u1.
Thanks you !.
4.4.3 Bot Notices
Command: BOTNOTICE
Parameters: <channel> <nickname,s> :<text>
The BOTNOTICE message is used similarly to NOTICE. As with NOTICE,
automatic replies must never be sent in response to a BOTNOTICE
notice. The difference between NOTICE and BOTNOTICE is the addition
of a target parameter and how the NOTICE is received by the target
client or clients. The first parameter is the channel from which the
NOTICE is to appear to have been sent to, and the second parameter is
the actual target client (or clients) who should receive the NOTICE.
Only clients with channel operator (+o) status may be able to send
a BOTNOTICE command for a given channel.* Whether the issuing client
is a bona fide automaton or just a client user is unimportant to the
function of this command. The purpose is to permit bots and client
scripts to interact with and address users in the context of a
channel. This allows client programs to know where to paint the
notice text so it can appear in the channel window instead of a
status or query window that the user isn't interacting with or
currently paying attention to.
**Many bots do not utilize NOTICE as they should (see: 4.4.2), because
the authors of those bots know that standard NOTICEs tend to go
unnoticed, and missed.**
Examples:
BOTNOTICE #Twilight_zone Angel :Welcome to the channel!
; Message sent to Angel in #Twilight_zone
:Wiz NOTICE #Twilight_zone :Welcome to the channel!
; Message from Wiz to Angel in #Twilight_zone
See PRIVMSG for more details on replies and examples.
* Channel op status is not necessarily necessary, and the command can
ideally be used by any helper bot or client script without being any
more abusable than regular /notices or /msgs. Client /ignore and
/filter commands already silence channel-targeted notices when said
user is placed on ignore.
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Given that #freenode now heavily relies on /stats p and enough bots, scripts and users abuse it:
I suggest removing the limit of /stats p or at least raise it considerably, as the limit is quite often hit and then unvoiced users have no idea who to contact.
It would be great if ops could what messages they are only able to see due to the channelmode +z being set.
How has to be discussed, of course it would be nice if it didn't break clients or protocol and doesn't require much work for clients to understand it.
I got a "there is a way to sneak italics into the topic since ircd doesn't yet know about 0x1D" in #freenode; I believe the same remark might apply to +c channel mode. Haven't tested it though.
Lines 524 to 528 in 51749ef
The configure script gives a choice on whether hyperscan support should be enabled. However, even if --disable-hyperscan
is passed to the configure script, the resulting makefiles will still attempt to build m_filter
and fail if there is no hyperscan on the system.
In my opinion, the autotools files should either be changed to properly build seven without m_filter
if --disable-hyperscan
is passed – or throw an error at configure time when attempting to build without hyperscan.
m_cmessage.c:199:3: error: non-void function 'm_cmessage' should return a value [-Wreturn-type]
return;
^
m_cmessage.c:203:3: error: non-void function 'm_cmessage' should return a value [-Wreturn-type]
return;
^
2 errors generated.
*** Error code 1
Stop.
make[1]: stopped in /usr/home/devirc/ircd-seven/modules
*** Error code 1
Stop.
make: stopped in /usr/home/devirc/ircd-seven
some errors on "autoconf"
$ autoconf
configure.ac:299: warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body
../../lib/autoconf/lang.m4:193: AC_LANG_CONFTEST is expanded from...
../../lib/autoconf/general.m4:2590: _AC_COMPILE_IFELSE is expanded from...
../../lib/autoconf/general.m4:2606: AC_COMPILE_IFELSE is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
configure.ac:299: the top level
configure.ac:489: warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body
../../lib/autoconf/lang.m4:193: AC_LANG_CONFTEST is expanded from...
../../lib/autoconf/general.m4:2729: _AC_RUN_IFELSE is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2748: AC_RUN_IFELSE is expanded from...
configure.ac:489: the top level
configure.ac:964: warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body
../../lib/autoconf/lang.m4:193: AC_LANG_CONFTEST is expanded from...
../../lib/autoconf/general.m4:2661: _AC_LINK_IFELSE is expanded from...
../../lib/autoconf/general.m4:2678: AC_LINK_IFELSE is expanded from...
configure.ac:964: the top level
configure.ac:1037: warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body
../../lib/autoconf/lang.m4:193: AC_LANG_CONFTEST is expanded from...
../../lib/autoconf/general.m4:2661: _AC_LINK_IFELSE is expanded from...
../../lib/autoconf/general.m4:2678: AC_LINK_IFELSE is expanded from...
configure.ac:1037: the top level
configure.ac:1106: warning: AC_CACHE_VAL(symbol_underscores, ...): suspicious cache-id, must contain cv to be cached
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
configure.ac:1106: the top level
What with the recent "freenodegate" spam attack - which is still ongoing I believe - would it be possible to include a channel mode which prevents a user from saying anything in a channel unless they've been in it for more than X seconds?
Using +J as an example (since I'm not sure what letters are already in use): /mode #chan +J 120 - means that they need to be in #chan for 120 seconds before they can speak otherwise the message is discarded.
This would most likely require caching the Unix Epoch of the time the user joined a channel then comparing it against the current epoch.
Hi,
I was facing "fatal error: hs_common.h: No such file or directory" error message when i try to compile ircd-seven on Ubuntu 18.10.
Solution:
You must install libhyperscan-dev and pkg-config to get rid of it!
sudo apt-get install libhyperscan-dev pkg-config
Special Thanks to @mquin for the valuable help. ( staff of freenode )
For servers that are being drainstopped -
15:40:59 <+* spb> or we could have an extension module that sends new clients a message that the server is not currently in use and please use one of the rotations, before disconnecting them
should not kill people who are kline- or limits-exempt
The ircd keeps a number of internal counters and gauges. It would be useful to have these exported in a way that can be easily ingested by prometheus and similar tools, perhaps by extending m_post to provide a simple http service for this.
The message sent with the numeric 435 (ERR_BANNICKCHANGE) is misleading.
It says "banned on channel" but it's sent to quieted clients as well.
it would be nice if we had to explicitly choose to override a user's wishes in this case.
elemental-ircd seems to have a /OACCEPT we could probably port; see https://github.com/Elemental-IRCd/elemental-ircd/blob/0e7f632f4dabbb2b2c13487c22d70eaf48f6c56e/extensions/m_oaccept.c and https://github.com/Elemental-IRCd/elemental-ircd/blob/0e7f632f4dabbb2b2c13487c22d70eaf48f6c56e/modules/core/m_message.c
/invite can be used to allow clients to bypass +r temporarily, but unlike +i there is no way to do this indefinitely for clients that do not identify to NickServ but have predictable hostnames, for example github commit bots.
Steps to Reproduce:
Register a nickname. Do not verify the account. Connect from an auth block with the need_sasl
flag, with SASL properly configured.
Repro:
01:01 -!- SASL authentication succeeded
01:01 !orwell.freenode.net *** Notice -- You need to identify via SASL to use this server
Suspected Root Cause:
The check that throws the error looks for the config to be enabled and a char array to be instantiated.
suser is defined in client.h, for everyone following along at home.
When a user signs-on, it looks like you pass a flag, *, to validate the user is registered and that initiates the copy of the logon name to the suser char array, seen here.
I suspect you have a check for authUsed == authRequired which will also populate the char array if the correct/expected auth mechanism is used but I didn't get too far/deep into the auth negotiation part of it. In principle, that part should still fail the same way (for incorrect auth path) and is, principally, why I suggested a check for verification should be included and tossing a different error (via another path, maybe on login?).
Expected Behaviour:
The client should receive a message that indicates the actual cause of the failure.
Actual Behaviour:
The client connects and, subsequently, the check happens for the char array being populated and only then is the client disconnected by the server (after having already made a successful connection).
(edited reproduction steps – @ilbelkyr)
(edited suspected root cause and expected behaviour - @felsokning)
There are various IRCv3 extensions that would be useful but require message tags, which we currently don't support.
We'll still need to decide on various specifics before working on the implementation, but I'm opening this issue for now to keep track of this and to reference it as dependency from other issues.
I noticed today channel names on freenode don't support unicode characters, specifically things like æ commonly included for use in domain names. Is this a feature which could be implemented?
When a message is dropped due to flood throttling, the client that sent the message is supposed to be notified of that:
Lines 971 to 974 in 7969abf
The correct way for the ircd to behave is to send those messages whenever a PRIVMSG
gets dropped, and drop NOTICE
s silently instead. This used to be the ircd-seven behavior.
At some point in time, a regression was introduced that changed this the wrong way round: Now clients that send dropped NOTICE
s get notified while PRIVMSG
s are dropped silently.
A MODRESTART reloads all modules, including m_encap.so
. However if the MODRESTART command came from a server (in an ENCAP), we will have ms_encap
in the call stack. Unless a lucky coincidence occurs, the modules will be loaded at different addresses, and the call stack will become corrupt, segfaulting the ircd upon return from the command handling code.
I'm attempting to package ircd-seven (charybdis) for NetBSD in pkgsrc.
GitHub ships with old tags.
Upstream (?) site with distfiles is dead.
FreeBSD packages 3.5.3... on GitHub 3.4.2?
The most recent tag is 5 years old.
parse_netmask()
in src/hostmask.c
does not validate that the values that it passes to atoi()
are valid numerical values. This means that an invalid netmask could be passed (such as 192.168.0.1/i
) which would cause atoi()
to return zero. The accidental mass k-lining on freenode on 17th August 2017 in response to a spambot attack was partly due to an invalid netmask being passed to the IRC server which was not sanitised.
I'd like to have my irc bot listen with two connections to the network for redundancy/reliability. It would need to de-duplicate messages and that means a unique ID per message generated at the client ideally, or at the server. If ircd-seven is a fork of charybdis, the NEWS file says charybdis got message tags 2 years ago yet none of that code appears to be in irc-seven. when is the last time ircd-seven merged new code from charybdis?
the notes for charybdis 4, released March 2016, list support for IRCv3 message tags.
https://github.com/charybdis-ircd/charybdis/blob/master/NEWS.md
running /list {something}
where {something}
isn't an ELIST
parameter or a channel results in all of the channels being returned.
For example, these queries, which would be some common typos, return the entire channel list:
/list channel
/list @channel
/list C,60
It would be saner to return an empty list result in these cases, since they technically don't match any channels.
This would allow people to connect from the web browser without any plugins like Java. There are C libraries for this already, but should a re-implementation be needed the protocol is pretty simple.
Currently (as of ircd-seven-1.1.3), it is possible as a user who is banned or quieted (+b
/+q
) from a channel to PRIVMSG
to that channel while not on it, when the channel is set -n
. This is frustrating, as -n
enables less spammy bot integration with e.g. GitHub, but it means that it's impossible to exclude abusive users.
Would be nice if PRIVMSG
would check bans/quiets even when not on the channel. :-)
Hi,
I was told that it may be of use to put in my two cents here. I remember--a while ago--I used to get private messages from newcomers asking why they can't talk in channels that have +q $~a
(which quiets all users who are not logged). I would assume that now that +R
is set by default for everyone on freenode that this might increase the number of confused newcomers trying who can neither talk on such a +q $~a
'd channel nor send a PRIVMSG to any of the participants (since probably most of them will have +R
).
I have no facts nor figures. It is just a thought. Probably most of them will find their way to #freenode
and ask why they're not able to send messages to the channel. Hopefully, they will get the appropriate answers there. I just had this tiny concern about setting +R
to everyone by default. I wouldn't know the proper solution since there are ... other unfortunate issues that require the settings to be the way they are, but I am merely bringing it up here ... well, because I was told to 😃
Long live freenode,
dylnmc
Hi,
When I run ircd with valgrind -f
and a user connects to the daemon, the daemon seems to fork indefinitely, using all the memory of the system.
+b and +q lists are not applied to externally sent messages when target channel is -n
it'd be nice to support certfp+sasl. also saslserv can give more sensible login failure warnings, which seems marginally useful
Hi,
When a user MONITORs a nick, then the nick joins, then the first user unMONITORs the nick, then the the second user quits, ircd segfaults.
Sessions log:
1479632000.046 1: connects to server.
1479632000.046 1 -> S: NICK foo
1479632000.046 1 -> S: USER username * * :Realname
1479632000.046 S -> 1: :My.Little.Server NOTICE * :*** Looking up your hostname...
[...]
1479632000.087 S -> 1: :My.Little.Server 376 foo :End of /MOTD command.
1479632000.087 S -> 1: :foo MODE foo :+i
1479632000.088 1 -> S: MONITOR + bar
1479632000.088 S -> 1: :My.Little.Server 731 foo :bar
1479632000.088 2: connects to server.
1479632000.088 2 -> S: NICK bar
1479632000.088 2 -> S: USER username * * :Realname
1479632000.088 S -> 2: :My.Little.Server NOTICE * :*** Looking up your hostname...
[...]
1479632000.089 S -> 2: :My.Little.Server 376 bar :End of /MOTD command.
1479632000.089 S -> 2: :bar MODE bar :+i
1479632000.089 S -> 2: :My.Little.Server PONG My.Little.Server :foo
1479632000.089 S -> 1: :My.Little.Server 730 * :[email protected]
1479632000.131 1 -> S: MONITOR - bar
1479632000.946 2 -> S: QUIT :bye
1479632000.946 S -> 2: :[email protected] QUIT :Quit: bye
[ircd segfaults]
Config file (in case that's relevant):
serverinfo {
name = "My.Little.Server";
sid = "42X";
description = "test server";
};
listen {
host = "0.0.0.0";
port = 58807;
};
auth {
user = "*";
flags = exceed_limit;
};
channel {
disable_local_channels = no;
no_create_on_split = no;
no_join_on_split = no;
};
ircd's console:
$ ircd -foreground -configfile ~/irctest/server.conf -pidfile /tmp/server.pid
notice: starting ircd-seven-1.1.3 ...
notice: libratbox version: 20081213_1-26296 - Using SSL: OpenSSL 1.0.2j 26 Sep 2016 compiled: 0x100020af, library 0x100020af
-ircd ssld daemon helper: error while loading shared libraries: libratbox.so: cannot open shared object file: No such file or directory
-ircd bandb daemon: error while loading shared libraries: libratbox.so: cannot open shared object file: No such file or directory
notice: now running in foreground mode from /home/dev-irc/.local as pid 23632 ...
[1] 23632 segmentation fault (core dumped) ircd -foreground -configfile ~/irctest/server.conf -pidfile /tmp/server.pid
$ make
[…]
/bin/bash ../libtool --silent --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../include -I. -I../include -g -O2 -Wall -MT sigio.lo -MD -MP -MF .deps/sigio.Tpo -c -o sigio.lo sigio.c
sigio.c: In function ‘rb_select_sigio’:
sigio.c:238:17: error: storage size of ‘si’ isn’t known
struct siginfo si;
^
sigio.c:238:17: warning: unused variable ‘si’ [-Wunused-variable]
sigio.c: In function ‘rb_sigio_sched_event’:
sigio.c:415:23: warning: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to remove the addressof? [-Wsizeof-pointer-memaccess]
memset(&ev, 0, sizeof(&ev));
^
Makefile:380: recipe for target 'sigio.lo' failed
make[3]: *** [sigio.lo] Error 1
make[3]: Leaving directory '/home/progval/irc/ircd-seven/libratbox/src'
Makefile:264: recipe for target 'all' failed
make[2]: *** [all] Error 2
make[2]: Leaving directory '/home/progval/irc/ircd-seven/libratbox/src'
Makefile:356: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/progval/irc/ircd-seven/libratbox'
Makefile:64: recipe for target 'build' failed
make: *** [build] Error 2
gcc version:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --with-arch-32=i586 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Debian 4.9.2-10)
OS version: Debian 8.2
EDIT: less verbosity
It would be helpful to ban spambots without affect some legit unidentified users.
Spambots usually are not registered and don't use gateways, so we can ban all unidentified users that not use a gateway. If we call that new extban $e, so +b $e:*!*@gateway/*
would ban ever unidentified user that not fit *!*@gateway/*
.
And it can be also used when we want to ban unregistered users but we know some IP range or domain that is safe.
It is necessary to complete the documentation of the installation, relating how to use autoconf / automake (and some other if there is one). The instructions start from the use of 'configure' when said file does not exist.
My launchpad id is anitanayak. Though I am able to build and push the changes file to my ppa from command line, the same I am not able to view in my ppa changed files
. hence I am not able to trigger the build. Can anyone help me?
Doesn't this violate protocol to have a space before the colon?
I mean, it does kinda look silly as well to be
86008 87738 Current global users 86008, max 87738
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.