Giter VIP home page Giter VIP logo

dalek-services's Introduction

DalekIRC Services

Version Version Maintained Unreal WP Validation by irctest

DalekIRC Services with UnrealIRCd & WordPress integration tailored to you.

Why do I need Dalek?

With WordPress + Dalek + UnrealIRCd, you have more creative control over things such as:

  • How your users register and manage their profile:
    • Works with Ultimate Member, customise how your profiles look
    • Create your own registration options like Date of Birth, Gender ID, Location etc. in WordPress, and these will be reflected in chat.
    • Profile pictures are shown on IRC to clients who support METADATA
  • Confirmation emails, account deletion, bans and suspensions are all do-able from your WordPress dashboard.
  • Add and remove Services staff via website, simply by adding or revoking their permission in the WordPress Users tab. You can oper them from the WordPress dashboard.
  • With our WordPress plugin, you have an overview of all the users, channels, network bans, servers. Additionally, you can oper staff on IRC from the website, rehash servers, remove bans, WHOIS users, WHOIS IPs, and more.

Planned Services

  • NickServ
  • ChanServ
  • OperServ
  • BotServ
  • Global
  • MetaServ (HostServ replacement with extra features)
  • bbServ (Optional: bbForums notification bot)

Although DalekIRC currently uses bots (NickServ, ChanServ etc), the ball is rolling to move things to a more "server-side command" environment, eliminating need to message a bot to ask what you need.

To find out more about how DalekIRC compliments UnrealIRCd, check out the Add-On for UnrealIRCd

Knows how to talk with

  • WordPress
  • JSON-RPC (remote procedure calls)
  • UnrealIRCd
  • SQL Databases
  • You!

IRCv3

DalekIRC has a keen interest in the advancement of IRC specifically, and so aims to add as many IRCv3 features as is workable from a services point of view, as well as suggest a few things in return.

To learn more about IRCv3, what it means, and how it's used, check out their website.

To learn more about how DalekIRC uses IRCv3, check out the support table

How to run

  1. Install dependencies: sudo apt install php-cli php-mysql php-mbstring mariadb-server-core on Debian/Ubuntu
  2. Configure MySQL
  3. Install and configure Wordpress 6.0 or later
  4. Install and configure UnrealIRCd 6.0 or later
  5. Copy conf/example.dalek.conf to conf/dalek.conf and edit the latter
  6. Run php src/dalek

dalek-services's People

Contributors

7dsmeliodas avatar modmenager avatar muskirc avatar omerati avatar progval avatar valwareirc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

dalek-services's Issues

Crash when using SASL plain with password over 400 characters

Client traffic and services log (interleaved):

1662797615.506 1: connects to server.
1662797615.506 1 -> S: CAP LS 302
[SEND] @msgid=avct7WwIOXh/D/AS/7e+R/cP+aZnXQRT;time=2022-09-10T08:13:35.518Z :00AFFC916 PRIVMSG #services :chkNS (~chk@localhost) [127.0.0.1] disconnected from the network. (Quit: chkNS) (001)
1662797616.019 S -> 1: :My.Little.Server CAP * LS :unrealircd.org/link-security=2 unrealircd.org/plaintext-policy=user=allow,oper=deny,server=deny unrealircd.org/history-storage=memory away-notify invite-notify extended-join userhost-in-names multi-prefix cap-notify sasl=PLAIN,EXTERNAL setname tls chghost account-notify message-tags batch server-time account-tag echo-message labeled-response draft/chathistory draft/extended-monitor unrealircd.org/json-log
1662797616.020 1 -> S: CAP REQ :sasl
1662797616.020 S -> 1: :My.Little.Server CAP * ACK :sasl 
1662797616.020 1 -> S: AUTHENTICATE PLAIN
[RECV] :My.Little.Server SASL services.example.org 001Y35N04 H 127.0.0.1 127.0.0.1
[RECV] :My.Little.Server SASL services.example.org 001Y35N04 S PLAIN
[SEND] @msgid=aTfX50Ra9V24C75e0QoeXeUy7rqoJAK2;time=2022-09-10T08:13:36.03Z SASL My.Little.Server 001Y35N04 C +
1662797616.030 S -> 1: AUTHENTICATE +
1662797616.031 1 -> S: AUTHENTICATE Zm9vAGZvbwBiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJi
1662797616.031 1 -> S: AUTHENTICATE YXJiYXJiYXI=
[RECV] :My.Little.Server SASL services.example.org 001Y35N04 C Zm9vAGZvbwBiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJiYXJi
PHP Fatal error:  Uncaught Error: Call to a member function bind_param() on bool in /home/oragono/Dalek-Services/src/misc.php:429
Stack trace:
#0 /home/oragono/Dalek-Services/src/modules/sasl.php(347): is_invite()
#1 /home/oragono/Dalek-Services/src/modules/sasl.php(241): IRC_SASL->check_pass()
#2 /home/oragono/Dalek-Services/src/modules/sasl.php(163): IRC_SASL->__construct()
#3 /home/oragono/Dalek-Services/src/cmd.php(31): SASL::cmd_sasl()
#4 /home/oragono/Dalek-Services/src/cmd.php(108): cmd::run()
#5 /home/oragono/Dalek-Services/src/hook.php(78): {closure}()
#6 /home/oragono/Dalek-Services/src/main.php(197): hook::run()
#7 /home/oragono/Dalek-Services/src/dalek(2): include('/home/oragono/D...')
#8 {main}
  thrown in /home/oragono/Dalek-Services/src/misc.php on line 429

Adding print_r($conn->error); before the offending line shows the error is: Table 'pifpaf.dalek_invite' doesn't exist

Space in network name causes config file to be mis-parsed

This config file:

info {
    SID "00A";
    network-name "testnetwork";
    services-name "services.example.org";
}

link {
    hostname "0.0.0.0";
    port "50939";
    password "password";
}

sql {
    port "3306";
    user "pifpaf";
    password "pifpaf";
    sockfile "/tmp/tmp8jkbphz2/mysql.socket";
    prefix "dlk5bff38242512_";
}

wordpress {
    prefix "wp5bff38242512_";
}

is correctly rewritten as:

info::SID::00A
info::network-name::testnetwork
info::services-name::services.example.org
link::hostname::0.0.0.0
link::port::50939
link::password::password
sql::port::3306
sql::user::pifpaf
sql::password::pifpaf
sql::sockfile::/tmp/tmp8jkbphz2/mysql.socket
sql::prefix::dlk5bff38242512_
wordpress::prefix::wp5bff38242512_

which is then parsed as:

Array
(
    [info] => Array
        (
            [SID] => 00A
            [network-name] => testnetwork
            [services-name] => services.example.org
        )

    [link] => Array
        (
            [hostname] => 0.0.0.0
            [port] => 50939
            [password] => password
        )

    [sql] => Array
        (
            [port] => 3306
            [user] => pifpaf
            [password] => pifpaf
            [sockfile] => /tmp/tmp8jkbphz2/mysql.socket
            [prefix] => dlk5bff38242512_
        )

    [wordpress] => Array
        (
            [prefix] => wp5bff38242512_
        )

)

However, when replacing testnetwork with test network in the config file, it gets rewritten as:

info::SID::00A
info::network-name test network
services-name::services.example.org
link::hostname::0.0.0.0
link::port::38449
link::password::password
sql::port::3306
sql::user::pifpaf
sql::password::pifpaf
sql::sockfile::/tmp/tmpf2bqbfj1/mysql.socket
sql::prefix::dlk74b63dab1e07_
wordpress::prefix::wp74b63dab1e07_

which is then incorrectly parsed as:

Array
(
    [info] => Array
        (
            [SID] => 00A
            [0] => network-name test network
        )

    [services-name] => Array
        (
            [0] => services.example.org
        )

    [link] => Array
        (
            [hostname] => 0.0.0.0
            [port] => 38449
            [password] => password
        )

    [sql] => Array
        (
            [port] => 3306
            [user] => pifpaf
            [password] => pifpaf
            [sockfile] => /tmp/tmpf2bqbfj1/mysql.socket
            [prefix] => dlk74b63dab1e07_
        )

    [wordpress] => Array
        (
            [prefix] => wp74b63dab1e07_
        )

)

causing this error:

Configuration test failed. Dalek encountered the following error(s):
'info::network-name' not found.
'info::services-name' not found.

IRC Channel - Libera

Hi, I'd like to transfer the Dalek IRC nick on the Libera Network to assist in demoing Dalek-Services.

Client sending CAP END between receiving 900 and 903 may cause temporary auth failure

So I have this code in irctest that connects a client with SASL, and sends NICK+USER+CAP END as soon as it gets the 900 (RPL_LOGGEDIN) reply.

This works fine on my main computer, but it often fails in the GitHub CI. Here is an excerpt from a successful test:

1663177132.182 1: connects to server.
[SEND] @msgid=+5Cx7SaIkHxW+4lKW+FcKuLfJcCljxGM;time=2022-09-14T17:38:52.202Z :00AFFC916 PRIVMSG #services :chkNS (~chk@localhost) [127.0.0.1] disconnected from the network. (Quit: chkNS) (001)
Success: Created user 2.
1663177132.995 1 -> S: CAP REQ :sasl
1663177132.995 S -> 1: :My.Little.Server CAP * ACK :sasl 
1663177132.996 1 -> S: AUTHENTICATE PLAIN
[RECV] :My.Little.Server SASL services.example.org 0019ULV04 H 127.0.0.1 127.0.0.1
[RECV] :My.Little.Server SASL services.example.org 0019ULV04 S PLAIN
[SEND] @msgid=ihCe8sZ28DG89j+XRum0GHyQkA4jZGVZ;time=2022-09-14T17:38:53.005Z SASL My.Little.Server 0019ULV04 C +
1663177133.006 S -> 1: AUTHENTICATE +
1663177133.006 1 -> S: AUTHENTICATE Y29vbEFjY3QAY29vbEFjY3QAc2VzYW1l
[RECV] :My.Little.Server SASL services.example.org 0019ULV04 C Y29vbEFjY3QAY29vbEFjY3QAc2VzYW1l
[SEND] @msgid=4x8EkHkuaaA3Td8ug6hksWKWlpk8HaaK;time=2022-09-14T17:38:53.023Z :00AFFC916 PRIVMSG #services :[127.0.0.1|127.0.0.1] 0019ULV04 identified using SASL for account: coolAcct (PLAIN)
[SEND] @msgid=lHgz1ZsNpSMeCd9slzqAJeR7Mo/64gJJ;time=2022-09-14T17:38:53.023Z :00A SVSLOGIN * 0019ULV04 coolAcct
[SEND] @msgid=4OfIjF6kcKr1ib0Rl5nhccG9ZZvWPuT2;time=2022-09-14T17:38:53.024Z SASL My.Little.Server 0019ULV04 D S
1663177133.064 S -> 1: :My.Little.Server 900 * *!*@127.0.0.1 coolAcct :You are now logged in as coolAcct.
1663177133.064 S -> 1: :My.Little.Server 903 * :SASL authentication successful
1663177133.064 1 -> S: NICK coolNick
1663177133.065 1 -> S: USER myusernam 0 * :My UniqueReal Name
1663177133.065 1 -> S: CAP END
1663177133.065 S -> 1: PING :33A62238
1663177133.065 1 -> S: PONG :33A62238
[info] Client connecting: coolNick (~myusernam@localhost) [127.0.0.1] [vhost: Clk-4D552FD5] [class: clients] [account: coolAcct] [reputation: 0] [security-groups: known-users,tls-and-known-users] 
[RECV] :001 REPUTATION 127.0.0.1 0
[RECV] :001 UID coolNick 0 1663177132 ~myusernam localhost 0019ULV04 coolAcct +ix * Clk-4D552FD5 fwAAAQ== :My UniqueReal Name
[SEND] @msgid=CSU0pZMDNQemAq5d/hJNpAgPTJjwU19J;time=2022-09-14T17:38:53.087Z :00AFFC916 PRIVMSG #services :coolNick (~myusernam@localhost) [127.0.0.1] connected to the network (001)
1663177133.108 S -> 1: :My.Little.Server 001 coolNick :Welcome to the ExampleNET IRC Network coolNick!~myusernam@localhost
1663177133.108 S -> 1: :My.Little.Server 002 coolNick :Your host is My.Little.Server, running version UnrealIRCd-6.0.3-git
1663177133.108 S -> 1: :My.Little.Server 003 coolNick :This server was created Mon Mar 28 2022 at 18:43:13 UTC
1663177133.108 S -> 1: :My.Little.Server 004 coolNick My.Little.Server UnrealIRCd-6.0.3-git diopqrstwxzBDGHIRSTWZ beIacdfhiklmnopqrstvzCDGHKLMNOPQRSTVZ
1663177133.108 S -> 1: :My.Little.Server 005 coolNick AWAYLEN=307 BOT=B CASEMAPPING=ascii CHANLIMIT=#:10 CHANMODES=beI,fkL,lH,cdimnprstzCDGKMNOPQRSTVZ CHANNELLEN=32 CHANTYPES=# CHATHISTORY=50 CLIENTTAGDENY=*,-draft/typing,-typing,-draft/reply DEAF=d ELIST=MNUCT EXCEPTS :are supported by this server
1663177133.108 S -> 1: :My.Little.Server 005 coolNick EXTBAN=~,acfjmnpqrtCGOST INVEX KICKLEN=307 KNOCK MAP MAXCHANNELS=10 MAXLIST=b:60,e:60,I:60 MAXNICKLEN=30 MINNICKLEN=0 MODES=12 MONITOR=128 NAMELEN=50 :are supported by this server
1663177133.108 S -> 1: :My.Little.Server 005 coolNick NAMESX NETWORK=ExampleNET NICKLEN=30 PREFIX=(qaohv)~&@%+ QUITLEN=307 SAFELIST SILENCE=15 STATUSMSG=~&@%+ TARGMAX=DCCALLOW:,ISON:,JOIN:,KICK:4,KILL:,LIST:,NAMES:1,NOTICE:1,PART:,PRIVMSG:4,SAJOIN:,SAPART:,TAGMSG:1,USERHOST:,USERIP:,WATCH:,WHOIS:1,WHOWAS:1 TOPICLEN=360 UHNAMES USERIP :are supported by this server
1663177133.109 S -> 1: :My.Little.Server 005 coolNick WALLCHOPS WATCH=128 WATCHOPTS=A WHOX :are supported by this server
1663177133.109 S -> 1: :My.Little.Server 396 coolNick Clk-4D552FD5 :is now your displayed host
1663177133.109 S -> 1: :My.Little.Server 251 coolNick :There are 1 users and 6 invisible on 2 servers
1663177133.109 S -> 1: :My.Little.Server 252 coolNick 6 :operator(s) online
1663177133.109 S -> 1: :My.Little.Server 254 coolNick 3 :channels formed
1663177133.109 S -> 1: :My.Little.Server 255 coolNick :I have 1 clients and 1 servers
1663177133.109 S -> 1: :My.Little.Server 265 coolNick 1 1 :Current local users 1, max 1
1663177133.109 S -> 1: :My.Little.Server 266 coolNick 7 7 :Current global users 7, max 7
1663177133.109 S -> 1: :My.Little.Server 375 coolNick :- My.Little.Server Message of the Day - 
1663177133.109 S -> 1: :My.Little.Server 372 coolNick :- 14/9/2022 17:38
1663177133.109 S -> 1: :My.Little.Server 372 coolNick :- 
1663177133.109 S -> 1: :My.Little.Server 376 coolNick :End of /MOTD command.
1663177133.109 S -> 1: :coolNick MODE coolNick :+ix

And here is an example of a failure on GitHub:

1663176737.810 1: connects to server.
1663176738.425 1 -> S: CAP REQ :sasl
1663176738.425 S -> 1: :My.Little.Server CAP * ACK :sasl 
1663176738.425 1 -> S: AUTHENTICATE PLAIN
1663176738.433 S -> 1: AUTHENTICATE +
1663176738.433 1 -> S: AUTHENTICATE Y29vbEFjY3QAY29vbEFjY3QAc2VzYW1l
1663176738.452 S -> 1: :My.Little.Server 900 * *!*@127.0.0.1 coolAcct :You are now logged in as coolAcct.
1663176738.452 1 -> S: NICK coolNick
1663176738.452 1 -> S: USER myusernam 0 * :My UniqueReal Name
1663176738.452 1 -> S: CAP END
1663176738.452 S -> 1: PING :FCE8B74A
1663176738.452 1 -> S: PONG :FCE8B74A
1663176738.453 S -> 1: :My.Little.Server 001 coolNick :Welcome to the ExampleNET IRC Network coolNick!~myusernam@localhost
1663176738.453 S -> 1: :My.Little.Server 002 coolNick :Your host is My.Little.Server, running version UnrealIRCd-6.0.3
1663176738.453 S -> 1: :My.Little.Server 003 coolNick :This server was created Wed Sep 14 2022 at 17:20:10 UTC
1663176738.453 S -> 1: :My.Little.Server 004 coolNick My.Little.Server UnrealIRCd-6.0.3 diopqrstwxzBDGHIRSTWZ beIacdfhiklmnopqrstvzCDGHKLMNOPQRSTVZ
1663176738.453 S -> 1: :My.Little.Server 005 coolNick AWAYLEN=307 BOT=B CASEMAPPING=ascii CHANLIMIT=#:10 CHANMODES=beI,fkL,lH,cdimnprstzCDGKMNOPQRSTVZ CHANNELLEN=32 CHANTYPES=# CHATHISTORY=50 CLIENTTAGDENY=*,-draft/typing,-typing,-draft/reply DEAF=d ELIST=MNUCT EXCEPTS :are supported by this server
1663176738.453 S -> 1: :My.Little.Server 005 coolNick EXTBAN=~,acfjmnpqrtCGOST INVEX KICKLEN=307 KNOCK MAP MAXCHANNELS=10 MAXLIST=b:60,e:60,I:60 MAXNICKLEN=30 MINNICKLEN=0 MODES=12 MONITOR=128 NAMELEN=50 :are supported by this server
1663176738.453 S -> 1: :My.Little.Server 005 coolNick NAMESX NETWORK=ExampleNET NICKLEN=30 PREFIX=(qaohv)~&@%+ QUITLEN=307 SAFELIST SILENCE=15 STATUSMSG=~&@%+ TARGMAX=DCCALLOW:,ISON:,JOIN:,KICK:4,KILL:,LIST:,NAMES:1,NOTICE:1,PART:,PRIVMSG:4,SAJOIN:,SAPART:,TAGMSG:1,USERHOST:,USERIP:,WATCH:,WHOIS:1,WHOWAS:1 TOPICLEN=360 UHNAMES USERIP :are supported by this server
1663176738.453 S -> 1: :My.Little.Server 005 coolNick WALLCHOPS WATCH=128 WATCHOPTS=A WHOX :are supported by this server
1663176738.453 S -> 1: :My.Little.Server 396 coolNick Clk-4D552FD5 :is now your displayed host
1663176738.453 S -> 1: :My.Little.Server 251 coolNick :There are 1 users and 6 invisible on 2 servers
1663176738.453 S -> 1: :My.Little.Server 252 coolNick 6 :operator(s) online
1663176738.453 S -> 1: :My.Little.Server 254 coolNick 3 :channels formed
1663176738.453 S -> 1: :My.Little.Server 255 coolNick :I have 1 clients and 1 servers
1663176738.453 S -> 1: :My.Little.Server 265 coolNick 1 1 :Current local users 1, max 1
1663176738.453 S -> 1: :My.Little.Server 266 coolNick 7 7 :Current global users 7, max 7
1663176738.453 S -> 1: :My.Little.Server 375 coolNick :- My.Little.Server Message of the Day - 
1663176738.453 S -> 1: :My.Little.Server 372 coolNick :- 14/9/2022 17:32
1663176738.453 S -> 1: :My.Little.Server 372 coolNick :- 
1663176738.453 S -> 1: :My.Little.Server 376 coolNick :End of /MOTD command.
1663176738.453 S -> 1: :My.Little.Server 906 coolNick :SASL authentication aborted
1663176738.453 S -> 1: :coolNick MODE coolNick :+ix
1663176738.454 S -> 1: :My.Little.Server 903 coolNick :SASL authentication successful

As you can see, 906 (ERR_SASLABORTED) is sent after the MOTD; then 903 (RPL_SASLSUCCESS) is sent shortly after

Both are running on commit 8868473

PHP Notice: Undefined property: Channel::$modes in src/client.php on line 141

This happens on startup, just before sending each SJOIN to service channels.

PHP Warning:  Undefined property: Channel::$modes in /home/runner/work/irctest/irctest/Dlk-Services/src/client.php on line 141
PHP Stack trace:
PHP   1. {main}() /home/runner/work/irctest/irctest/Dlk-Services/src/dalek:0
PHP   2. include() /home/runner/work/irctest/irctest/Dlk-Services/src/dalek:2
PHP   3. hook::run($hook = 'connect', $args = []) /home/runner/work/irctest/irctest/Dlk-Services/src/main.php:178
PHP   4. nickserv::spawn_client([]) /home/runner/work/irctest/irctest/Dlk-Services/src/hook.php:79
PHP   5. Client->__construct($nick = 'NickServ', $ident = 'services', $hostmask = 'services.host', $uid = NULL, $gecos = 'Nickname Registration Service', $modinfo = 'nickserv') /home/runner/work/irctest/irctest/Dlk-Services/src/modules/NickServ/nickserv.php:131
PHP   6. Client->join(...$dests = variadic('#services')) /home/runner/work/irctest/irctest/Dlk-Services/src/client.php:56

PHP Notice: Undefined offset: 0 in src/modules/fakelag.php on line 76

This happens on startup, just before Dalek sends PASS

PHP Warning:  Undefined array key 0 in /home/runner/work/irctest/irctest/Dlk-Services/src/modules/fakelag.php on line 76
PHP Stack trace:
PHP   1. {main}() /home/runner/work/irctest/irctest/Dlk-Services/src/dalek:0
PHP   2. include() /home/runner/work/irctest/irctest/Dlk-Services/src/dalek:2
PHP   3. include() /home/runner/work/irctest/irctest/Dlk-Services/src/main.php:79
PHP   4. loadmodule($mod = 'fakelag') /home/runner/work/irctest/irctest/Dlk-Services/conf/modules.conf:39
PHP   5. Module->__construct($mod = 'fakelag') /home/runner/work/irctest/irctest/Dlk-Services/src/module.php:194
PHP   6. Module->load_module($mod = 'fakelag') /home/runner/work/irctest/irctest/Dlk-Services/src/module.php:31
PHP   7. fakelag->__init() /home/runner/work/irctest/irctest/Dlk-Services/src/module.php:109
PHP   8. __FakeLag::config_check() /home/runner/work/irctest/irctest/Dlk-Services/src/modules/fakelag.php:59

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.