SlideShare a Scribd company logo
1 of 251
Download to read offline
EtherCalc
Multiplayer
Spreadsheet
 ethercalc.tw
Personal Opinions
Personal Opinions




(With Infotisements)
Time Limited
 Just Stories
  No Coding
Time Limited
 Just Stories
       Ideas
  No Coding
ethercalc.org

ā€£ npm install -g ethercalc

ā€£ ethercalc
 Please connect to: http://0:8000/


              nodejs.org/#download
A.O.S.A., 2011


aosabook.org


 aosa.tw
History
VisiCalc, 1979




Dan Bricklin
Harvard, 1977
Harvard, 1977
Harvard, 1977
Harvard, 1977
Harvard, 1977
Original Vision
Original Vision




       Alto
    Workstation
Original Vision




                 Alto
Calculator-   Workstation
  Mouse
Original Vision




                 Alto
Calculator-   Workstation   Head-mounted
  Mouse                        Display
Original Vision




                 Alto
Calculator-   Workstation   Head-mounted
  Mouse                        Display
=SUM( )   0
10

     =SUM( )   10
                0
10       20

     =SUM( )   30
               10
                0
10       20    30

     =SUM( )        60
                    30
                    10
                     0
10       20    30

     =SUM( )        60
                    30
                    10
                     0
1977 ā†’ 1978
1977 ā†’ 1978
1977 ā†’ 1978



       +



  Integer BASIC
1978 ā†’ 1979
1978 ā†’ 1979
  10      20   30
  =SUM(        )    60
1978 ā†’ 1979
    A       B    C    D
1   10      20   30

2   =SUM(        )    60
1978 ā†’ 1979
    A     B     C    D
1   10    20    30

2   =SUM(A1,B1,C1)   60
1978 ā†’ 1979
    A     B     C    D
1   10    20    30

2   =SUM(A1,B1,C1)   60




                     Bob & Dan
1978 ā†’ 1979
           A     B     C    D
      1    10    20    30

      2    =SUM(A1,B1,C1)   60
ā€£ Dan prototypes in BASIC



                            Bob & Dan
1978 ā†’ 1979
           A     B     C    D
      1    10    20    30

      2    =SUM(A1,B1,C1)   60
ā€£ Dan prototypes in BASIC
ā€£ Bob codes in 6502 ASM


                            Bob & Dan
1978 ā†’ 1979
            A     B     C     D
       1   10     20    30

       2    =SUM(A1,B1,C1)    60
ā€£ Dan prototypes in BASIC
ā€£ Bob codes in 6502 ASM
ā€£ 700,000 copies in 6 years
                              Bob & Dan
1978 ā†’ 1979
            A     B     C     D
       1   10     20    30

       2    =SUM(A1,B1,C1)    60
ā€£ Dan prototypes in BASIC
ā€£ Bob codes in 6502 ASM
ā€£ 700,000 copies in 6 years
ā€£ The !rst ā€œKiller Appā€       Bob & Dan
1981
20 years passed
20 years passed
20 years passed
20 years passed
20 years passed



Nothing changed
ā€œCanā€™t openā€
ā€œCanā€™t openā€

ā€œGarbledā€
ā€œCanā€™t openā€

ā€œGarbledā€

ā€œVirus!ā€
Wikipedia, 2001
Wikipedia, 2001
Wikipedia, 2001
wikiCalc, 2005
wikiCalc, 2005
āœ“ Plain text, HTML & Wiki syntax
wikiCalc, 2005
āœ“ Plain text, HTML & Wiki syntax
āœ“ References cells on other servers
wikiCalc, 2005
āœ“ Plain text, HTML & Wiki syntax
āœ“ References cells on other servers
āœ“ Keeps all operations for auditing
wikiCalc, 2005
āœ“ Plain text, HTML & Wiki syntax
āœ“ References cells on other servers
āœ“ Keeps all operations for auditing
āœ“ Revert to any revision
wikiCalc, 2005
āœ“ Plain text, HTML & Wiki syntax
āœ“ References cells on other servers
āœ“ Keeps all operations for auditing
āœ“ Revert to any revision
āœ“ Open Source! (GPLv2)
wikiCalc.pl
wikiCalc.pl
      ē¶²ē«™
      Sites
./wkcdata/sites/Foo
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz
wikiCalc.pl
      ē¶²ē«™
      Sites             頁面
                        Pages
./wkcdata/sites/Foo
                         XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz    YYY
                         ZZZ
wikiCalc.pl
      ē¶²ē«™
      Sites             頁面
                        Pages
./wkcdata/sites/Foo
                         XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz    YYY
                         ZZZ


               Cells
               å„²å­˜ę ¼
wikiCalc.pl
      ē¶²ē«™
      Sites             頁面
                        Pages
./wkcdata/sites/Foo
                         XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz    YYY
                         ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100
wikiCalc.pl
      ē¶²ē«™
      Sites             頁面
                        Pages
./wkcdata/sites/Foo
                         XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz    YYY
                         ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100
    A2: =A1*2
wikiCalc.pl
      ē¶²ē«™
      Sites               頁面
                          Pages
./wkcdata/sites/Foo
                           XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz      YYY
                           ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100 B1: =XXX!C1
    A2: =A1*2
wikiCalc.pl
      ē¶²ē«™
      Sites               頁面
                          Pages
./wkcdata/sites/Foo
                           XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz      YYY
                           ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100 B1: =XXX!C1
    A2: =A1*2
wikiCalc.pl
      ē¶²ē«™
      Sites                 頁面
                            Pages
./wkcdata/sites/Foo
                             XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz        YYY
                             ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100 B1: =XXX!C1
    A2: =A1*2 B2: =YYY!D2
wikiCalc.pl
      ē¶²ē«™
      Sites                 頁面
                            Pages
./wkcdata/sites/Foo
                             XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz        YYY
                             ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100 B1: =XXX!C1
    A2: =A1*2 B2: =YYY!D2
wikiCalc.pl
      ē¶²ē«™
      Sites                 頁面
                            Pages
./wkcdata/sites/Foo
                             XXX
 ./wkcdata/sites/Bar
  ./wkcdata/sites/Baz        YYY
                             ZZZ


               Cells
               å„²å­˜ę ¼
    A1: 100 B1: =XXX!C1
    A2: =A1*2 B2: =YYY!D2
                             Cross-page
                             Reference
wikiCalc Edit Flow
wikiCalc Edit Flow
     A1: 100
     A2: =A1*2
wikiCalc Edit Flow
     A1: 100
     A2: =A1*2
wikiCalc Edit Flow
       A1: 100
       A2: =A1*2


    POST /
    ajaxsetcell=host:page:A1:300
                                   wikicalc.pl
wikiCalc Edit Flow
       A1: 100
       A2: =A1*2


    POST /
    ajaxsetcell=host:page:A1:300
                                      wikicalc.pl
          200 OK
          <?xml version="1.0"?>
          <root><![CDATA[
          A1:v:300:300:right:1:1::
          A2:f:600:A1*2:right:1:1::
          ]]></root>
ā€œLoadingā€¦ā€
ā€œLoadingā€¦ā€
ā€œLoadingā€¦ā€




ā€œC100kā€ Problem
ā€œLoadingā€¦ā€




ā€œC100kā€ Problem
Undo
Undo
Redo
SocialCalc, 2006



Dan Bricklin   Ross Mayļ¬eld
Design Goals
Design Goals
ā€£ Rewrite calc engine in JS
Design Goals
ā€£ Rewrite calc engine in JS
ā€£ Real-time responsive editor
Design Goals
ā€£ Rewrite calc engine in JS
ā€£ Real-time responsive editor
ā€£ Supports 100,000+ cells
Design Goals
ā€£ Rewrite calc engine in JS
ā€£ Real-time responsive editor
ā€£ Supports 100,000+ cells
ā€£ Works on all browsers (IE6+)
Design Goals
ā€£ Rewrite calc engine in JS
ā€£ Real-time responsive editor
ā€£ Supports 100,000+ cells
ā€£ Works on all browsers (IE6+)
ā€£ Client-side log & undo/redo
Architecture
Architecture
SocialCalc.js




HTTP Server
Architecture
      SocialCalc.js


GET



      HTTP Server
Architecture
      SocialCalc.js


GET



      HTTP Server
Architecture
   SocialCalc.js


GET GET



   HTTP Server
Architecture
   SocialCalc.js


GET GET
    ($)



   HTTP Server
Architecture
   SocialCalc.js

               PUT
GET GET
    ($)



   HTTP Server
Architecture
   SocialCalc.js

               PUT
GET GET
    ($)



   HTTP Server
Command Pattern
Command Pattern
set A1 value n 42
Command Pattern
set A1 value n 42
set A2 formula A1*2
Command Pattern
set A1 value n 42
set A2 formula A1*2
merge A1:B2
cut A3
paste A4
sort A1:B9 A up B down
set sheet defaultcolor blue
...
Command Pattern
 set A1 value n 42
 set A2 formula A1*2
ā€£ Async recalc loop
Command Pattern
 set A1 value n 42
 set A2 formula A1*2
ā€£ Async recalc loop
ā€£ Visible-only redraw
Command Pattern
 set A1 value n 42
 set A2 formula A1*2
ā€£ Async recalc loop
ā€£ Visible-only redraw
ā€£ Unlimited undo/redo
Command Pattern
 set A1 value n 42
 set A2 formula A1*2
ā€£ Async recalc loop
ā€£ Visible-only redraw
ā€£ Unlimited undo/redo
ā€£ UI stays responsive
Command Pattern
 set A1 value n 42
 set A2 formula A1*2
ā€£ Async recalc loop
ā€£ Visible-only redraw
ā€£ Unlimited undo/redo
ā€£ UI stays responsive
ā€œSocialā€Calc
ā€œSocialā€Calc
ā€œSocialā€Calc




 Comment, Like,
   Tag, Share, Embed...
Objects   Relations
Objects   Relations
Objects   Relations
Good !rst
Pro!ts later
Common Public
Attribution License
Common Public
      Attribution License
  ā“
BSD, MIT
Common Public
      Attribution License
              Ā©
  ā“
BSD, MIT   LGPL, MPL
Common Public
      Attribution License
              Ā©        ++Ā©
  ā“
BSD, MIT   LGPL, MPL    GPL
Common Public
      Attribution License
              Ā©                                  ++Ā©
  ā“
BSD, MIT   LGPL, MPL                                  GPL
               ā€œASP
Ā loopholeā€
Common Public
      Attribution License
              Ā©                                  ++Ā©
  ā“
BSD, MIT   LGPL, MPL                                  GPL
               ā€œASP
Ā loopholeā€

                                             Affero GPL
Common Public
      Attribution License
              Ā©                                  ++Ā©
  ā“
BSD, MIT   LGPL, MPL                                  GPL
               ā€œASP
Ā loopholeā€

             CPAL                            Affero GPL
Common Public
      Attribution License
              Ā©                                  ++Ā©
  ā“
BSD, MIT   LGPL, MPL                                  GPL
               ā€œASP
Ā loopholeā€

             CPAL                            Affero GPL
Common Public
      Attribution License
              Ā©                                  ++Ā©
  ā“
BSD, MIT   LGPL, MPL                                  GPL
               ā€œASP
Ā loopholeā€

             CPAL                            Affero GPL
Common Public
      Attribution License
              Ā©                                  ++Ā©
  ā“
BSD, MIT   LGPL, MPL                                  GPL
               ā€œASP
Ā loopholeā€

             CPAL                            Affero GPL
Sheetnode, 2008




Karim Ratib
Sheetnode, 2008
              Views + Fields + CCK




Karim Ratib
Sheetnode, 2008
              Views + Fields + CCK



                  SocialCalc.js


Karim Ratib
Sheetnode, 2008
              Views + Fields + CCK



                  SocialCalc.js


Karim Ratib
Sheetnode, 2008
              Views + Fields + CCK



                  SocialCalc.js


Karim Ratib
Sheetnode, 2008
              Views + Fields + CCK



                  SocialCalc.js


Karim Ratib
OLPC, 2008
OLPC, 2008




Luke Closs  Dan
Mesh
P2P
Manusheel
  Gupta




Vijit Singh
SocialCalcActivity.py
                  Gecko/XPCOM
                 SocialCalc.js
                    XoCom.js

                    XoCom.py



Manusheel
  Gupta




Vijit Singh
SocialCalcActivity.py
                                      Gecko/XPCOM
                                     SocialCalc.js
                                        XoCom.js

              set A1 value n 42         XoCom.py



Manusheel
  Gupta




Vijit Singh
SocialCalcActivity.py
                                      Gecko/XPCOM
                                     SocialCalc.js
                                        XoCom.js

              set A1 value n 42         XoCom.py

                                      D-Bus + Telepathy

Manusheel
  Gupta




Vijit Singh
SocialCalcActivity.py
                                      Gecko/XPCOM
                                     SocialCalc.js
                                        XoCom.js

              set A1 value n 42         XoCom.py

                                      D-Bus + Telepathy
                            OLPC Mesh
Manusheel
  Gupta                     Broadcast
                             ē¶²ēµ”å»£ę’­




Vijit Singh
SocialCalcActivity.py
                                            Gecko/XPCOM
                                           SocialCalc.js
                                              XoCom.js

              set A1 value n 42               XoCom.py

                                            D-Bus + Telepathy
                               OLPC Mesh
Manusheel
  Gupta                        Broadcast
                                ē¶²ēµ”å»£ę’­
                    D-Bus + Telepathy


                       Gecko/XPCOM
                      SocialCalc.js
                         XoCom.js

                         XoCom.py
Vijit Singh        SocialCalcActivity.py
SocialCalcActivity.py
                                            Gecko/XPCOM
                                           SocialCalc.js
                                              XoCom.js

              set A1 value n 42               XoCom.py

                                            D-Bus + Telepathy
                               OLPC Mesh
Manusheel
  Gupta                        Broadcast
                                ē¶²ēµ”å»£ę’­
                    D-Bus + Telepathy


                       Gecko/XPCOM
                                              set A1 value n 42
                      SocialCalc.js
                         XoCom.js

                         XoCom.py
Vijit Singh        SocialCalcActivity.py
Great, but...
Great, but...
ā€£ Must log on same time
Great, but...
ā€£ Must log on same time
ā€£ Canā€™t replay missed logs
Great, but...
ā€£ Must log on same time
ā€£ Canā€™t replay missed logs
ā€£ Race condition on cells
Great, but...
ā€£ Must log on same time
ā€£ Canā€™t replay missed logs
ā€£ Race condition on cells
ā€£ OLPC-speciļ¬c code!
YAPC::Tiny, 2009


     č·³ę ¼
  Multiplayer
  SocialCalc
           äŗŒé›¶é›¶ä¹ć€€å”é³³
                字
           äø­č‹±é›™å®‡ęœ‰å­—ē‰ˆ
EV/AnyEvent
Tatsumaki EV/AnyEvent




 @miyagawa
Tatsumaki EV/AnyEvent
        Web::Hippie




 @miyagawa   @clkao
Tatsumaki EV/AnyEvent
        Web::Hippie
                Feersum


 @miyagawa   @clkao   @stash
WebSocket Channels
      multiserver.pl

       Web::Hippie
          Plack
         Feersum
         EV/libev
WebSocket Channels
  SpreadsheetControl
                        multiserver.pl

                         Web::Hippie
ScheduleScheetCommand
 set A1 value n 2046        Plack
   RenderSheet
                           Feersum
                           EV/libev
WebSocket Channels
  SpreadsheetControl
                              multiserver.pl

                               Web::Hippie
ScheduleScheetCommand
 set A1 value n 2046              Plack
   RenderSheet
                       Send      Feersum
                                 EV/libev
WebSocket Channels
  SpreadsheetControl
                              multiserver.pl


ScheduleScheetCommand
                               Web::Hippie     Relay
 set A1 value n 2046              Plack
   RenderSheet
                       Send      Feersum
                                 EV/libev
WebSocket Channels
  SpreadsheetControl
                              multiserver.pl


ScheduleScheetCommand
                               Web::Hippie     Relay
 set A1 value n 2046              Plack
                                               ScheduleScheetCommand
   RenderSheet
                       Send      Feersum         set A1 value n 2046
                                                   (isRemote = true)
                                 EV/libev
                                                     RenderSheet
New Features
New Features
āœ“ Fetch logs on join
New Features
āœ“ Fetch logs on join
āœ“ Reconnection recovery
New Features
āœ“ Fetch logs on join
āœ“ Reconnection recovery
āœ“ Show peer cursors
New Features
āœ“ Fetch logs on join
āœ“ Reconnection recovery
āœ“ Show peer cursors
āœ“ Cross-browser support!
New Features
āœ“ Fetch logs on join
āœ“ Reconnection recovery
āœ“ Show peer cursors
āœ“ Cross-browser support!
Much better, but...
Much better, but...
ā€£ Which peerā€™s log to take?
Much better, but...
ā€£ Which peerā€™s log to take?
ā€£ What if everyone leaves?
Much better, but...
ā€£ Which peerā€™s log to take?
ā€£ What if everyone leaves?
ā€£ Who would keep the logs?
Much better, but...
ā€£ Which peerā€™s log to take?
ā€£ What if everyone leaves?
ā€£ Who would keep the logs?
ā€£ Replay 1,000+ commands?
Much better, but...
ā€£ Which peerā€™s log to take?
ā€£ What if everyone leaves?
ā€£ Who would keep the logs?
ā€£ Replay 1,000+ commands?
Undo
Undo
Redo?
YAPC::NA, 2006
YAPC::NA, 2006
ā€œI think, but I cannot prove, that by
the next year JavaScript 2.0 will
bootstrap itself, complete self
hosting, compile back to JavaScript,
and replace Ruby as the Next Big
Thing in all environments. ā€
YAPC::NA, 2006
YAPC::NA, 2006
ā€œJavaScript will become the common
backend for all dynamic languages,
and so you can write Perl to run in the
browser, on the server, and inside
databases, all with the same set of
development tools. ā€
YAPC::NA, 2006
YAPC::NA, 2006
ā€œBecause, as we all know,
worse is better, so the worst
scripting language is doomed
to become the best.ā€
YAPC::NA, 2006
ā€œBecause, as we all know,
worse is better, so the worst
scripting language is doomed
to become the best.ā€

        劣=å¤Æ
JavaScript: Good Part Only
CoeeScript: HalfPart Noise
 JavaScript: Good the Only

  cs = (js) = js/2


 Jeremy
Ashkenas
CoeeScript: HalfPart Noise
 JavaScript: Good the Only

  cs = (js) = js/2


 Jeremy
Ashkenas
CoeeScript: HalfPart Noise
 JavaScript: Good the Only

  cs = (js) = js/2

           ā€œOriginal JavaScript: 22k LOC.
           怀Ported to Coļ¬€eeScript: 5k LOC.
           怀{async, jsdom, zappa, optimist etc}++ā€
 Jeremy
Ashkenas
{x,y} = @offset
{x,y} = @offset
var _ref = this.offset;
{x,y} = @offset
var _ref = this.offset;
var x = _ref.x;
{x,y} = @offset
var _ref = this.offset;
var x = _ref.x;
var y = _ref.y;
{x,y} = @offset
var _ref = this.offset;
var x = _ref.x;
var y = _ref.y;

          js2coffee.org
Function::įµ’ = (fun) -
Function::įµ’ = (fun) -
  (arg) = @ fun arg
Function::įµ’ = (fun) -
  (arg) = @ fun arg

f = (x) = x * 2
Function::įµ’ = (fun) -
  (arg) = @ fun arg

f = (x) = x * 2
g = (x) = x * 3
Function::įµ’ = (fun) -
  (arg) = @ fun arg

f = (x) = x * 2
g = (x) = x * 3
h = f .įµ’ g
Function::įµ’ = (fun) -
  (arg) = @ fun arg

f = (x) = x * 2
g = (x) = x * 3
h = f .įµ’ g

h 100 # 600
Function::įµ’ = (fun) -
  (arg) = @ fun arg

f = (x) = x * 2
g = (x) = x * 3
h = f .įµ’ g

h 100 # 600
Zappa: Lazy Node.js




          zappajs.org
Zappa: Lazy Node.js



Maurice
Machado

           zappajs.org
Zappa: Lazy Node.js
          ā€œIf you can describe it
          in 495 characters,
          why on earth should
Maurice
          it take 879?ā€
Machado

                 zappajs.org
require('zappa') -
  @view layout: -
    html = body = @body

  @get '/': - @render 'index'

  @view index: - for name, value of {
    wiki: Wiki to HTML
    html: HTML to Wiki
  }
    form method: 'post', =
      p = textarea {name}
      p = input {type: 'submit', value}
require('zappa') -
  @view layout: -
    html = body = @body

  @get '/': - @render 'index'

  @view index: - for name, value of {
    wiki: Wiki to HTML
    html: HTML to Wiki
  }
    form method: 'post', =
      p = textarea {name}
      p = input {type: 'submit', value}
require('zappa') -
@post '/': - -
  @view layout:
  if @data.wiki? @body
    html = body =
    @send w2h @data.wiki
 @get '/': - @render 'index'
 else if @data.html?
    @send h2w @data.html
 @view index: - for name, value of {
 else redirect '/'
   wiki: Wiki to HTML
     html: HTML to Wiki
 }
     form method: 'post', =
       p = textarea {name}
       p = input {type: 'submit', value}
COSCUP, 2011
COSCUP, 2011
COSCUP, 2011




hack
Ā hack
Ā hack
Ā ...
COSCUP, 2011




hack
Ā hack
Ā hack
Ā ...
EtherCalc Edit Flow
EtherCalc Edit Flow
      main.coļ¬€ee
 sc.coļ¬€ee
                Socket.io
SocialCalc.js
                Express
                Node.js
 db.coļ¬€ee       EV/libuv
  redis.js       Zappa
EtherCalc Edit Flow
      main.coļ¬€ee
 sc.coļ¬€ee
                Socket.io
SocialCalc.js
                Express
                Node.js
 db.coļ¬€ee       EV/libuv
  redis.js       Zappa



  Redis
(optional)
EtherCalc Edit Flow
      main.coļ¬€ee
 sc.coļ¬€ee
                Socket.io
SocialCalc.js
                Express
                Node.js
 db.coļ¬€ee       EV/libuv    player.coļ¬€ee
  redis.js       Zappa       SocialCalc.js




  Redis
(optional)
EtherCalc Edit Flow
      main.coļ¬€ee            MULTI
 sc.coļ¬€ee
                              GET snapshot
                Socket.io     LRANGE log
SocialCalc.js               EXEC
                Express
                Node.js
 db.coļ¬€ee       EV/libuv     player.coļ¬€ee
  redis.js       Zappa        SocialCalc.js




  Redis
(optional)
EtherCalc Edit Flow
      main.coļ¬€ee            MULTI
 sc.coļ¬€ee
                              GET snapshot
                Socket.io     LRANGE log
SocialCalc.js               EXEC
                Express
                Node.js
 db.coļ¬€ee       EV/libuv     player.coļ¬€ee
  redis.js       Zappa        SocialCalc.js



                            RPUSH log cmd
  Redis
(optional)
EtherCalc Edit Flow
      main.coļ¬€ee            MULTI
 sc.coļ¬€ee
                              GET snapshot
                Socket.io     LRANGE log
SocialCalc.js               EXEC
                Express
                Node.js
 db.coļ¬€ee       EV/libuv     player.coļ¬€ee
  redis.js       Zappa        SocialCalc.js



                            RPUSH log cmd
  Redis
(optional)
EtherCalc Edit Flow
      main.coļ¬€ee            MULTI
 sc.coļ¬€ee
                              GET snapshot
                Socket.io     LRANGE log
SocialCalc.js               EXEC
                Express
                Node.js
 db.coļ¬€ee       EV/libuv     player.coļ¬€ee
  redis.js       Zappa        SocialCalc.js



                            RPUSH log cmd
  Redis
(optional)
EtherCalc Edit Flow
      main.coļ¬€ee            MULTI
 sc.coļ¬€ee
                              GET snapshot
                Socket.io     LRANGE log
SocialCalc.js               EXEC
                Express
                Node.js
 db.coļ¬€ee       EV/libuv     player.coļ¬€ee
  redis.js       Zappa        SocialCalc.js


                 MULTI     RPUSH log cmd
  Redis            DEL log
(optional)         SET snapshot snapshot
                 EXEC
Recalc Subscription
Recalc Subscription
Recalc Subscription
Recalc Subscription
         ask.log: Foo
Recalc Subscription
              ask.log: Foo

   log: Foo,snapshot,log
Recalc Subscription
              ask.log: Foo

   log: Foo,snapshot,log

           execute: set A1
            formula Bar!B2
Recalc Subscription
              ask.log: Foo

   log: Foo,snapshot,log

           execute: set A1
            formula Bar!B2
           ask.recalc: Bar
Recalc Subscription
              ask.log: Foo

   log: Foo,snapshot,log

           execute: set A1
            formula Bar!B2
           ask.recalc: Bar

   recalc: Bar,snapshot
Recalc Subscription
              ask.log: Foo

   log: Foo,snapshot,log

           execute: set A1
            formula Bar!B2
           ask.recalc: Bar

   recalc: Bar,snapshot

   recalc: Bar,snapshot
PaaS Deployment
PaaS Deployment
          stackato.yml
          app.js
PaaS Deployment
          stackato.yml
          app.js

          dotcloud.yml
          server.js
PaaS Deployment
          stackato.yml
          app.js

          dotcloud.yml
          server.js

          server.js

More Related Content

Similar to EtherCalc: Multiplayer Spreadsheet

Understanding git
Understanding gitUnderstanding git
Understanding git
Avik Das
Ā 
11-PLDs.pdf
11-PLDs.pdf11-PLDs.pdf
11-PLDs.pdf
KoayFT
Ā 
Boston Spark Meetup May 24, 2016
Boston Spark Meetup May 24, 2016Boston Spark Meetup May 24, 2016
Boston Spark Meetup May 24, 2016
Chris Fregly
Ā 
Tecnicas avanzadas con CSS3
Tecnicas avanzadas con CSS3Tecnicas avanzadas con CSS3
Tecnicas avanzadas con CSS3
Marta Armada
Ā 
Windows kernel debugging workshop in florida
Windows kernel debugging   workshop in floridaWindows kernel debugging   workshop in florida
Windows kernel debugging workshop in florida
Sisimon Soman
Ā 
čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向
čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向
čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向
Fumihiro Kato
Ā 

Similar to EtherCalc: Multiplayer Spreadsheet (17)

Understanding git
Understanding gitUnderstanding git
Understanding git
Ā 
IPv6恮闇ćØPHP
IPv6恮闇ćØPHPIPv6恮闇ćØPHP
IPv6恮闇ćØPHP
Ā 
Operationalizing yara
Operationalizing yaraOperationalizing yara
Operationalizing yara
Ā 
11-PLDs.pdf
11-PLDs.pdf11-PLDs.pdf
11-PLDs.pdf
Ā 
Real time, streaming advanced analytics, approximations, and recommendations ...
Real time, streaming advanced analytics, approximations, and recommendations ...Real time, streaming advanced analytics, approximations, and recommendations ...
Real time, streaming advanced analytics, approximations, and recommendations ...
Ā 
20200812 Cbject Detection with OpenCV and CNN
20200812 Cbject Detection with OpenCV and CNN20200812 Cbject Detection with OpenCV and CNN
20200812 Cbject Detection with OpenCV and CNN
Ā 
Boston Spark Meetup May 24, 2016
Boston Spark Meetup May 24, 2016Boston Spark Meetup May 24, 2016
Boston Spark Meetup May 24, 2016
Ā 
unit 5.ppt
unit 5.pptunit 5.ppt
unit 5.ppt
Ā 
Tecnicas avanzadas con CSS3
Tecnicas avanzadas con CSS3Tecnicas avanzadas con CSS3
Tecnicas avanzadas con CSS3
Ā 
20201029 ćƒ¢ćƒ†ć‚™ćƒ«ćƒ˜ć‚™ćƒ¼ć‚¹é–‹ē™ŗćƒ¢ćƒ¼ć‚æćƒ¼åˆ¶å¾”ē·Øļ½žCč؀čŖžćØSimulinkć®ę–‡ę³•čؘčæ°ć‚’ęÆ”č¼ƒć™ć‚‹ļ½ž
20201029 ćƒ¢ćƒ†ć‚™ćƒ«ćƒ˜ć‚™ćƒ¼ć‚¹é–‹ē™ŗćƒ¢ćƒ¼ć‚æćƒ¼åˆ¶å¾”ē·Øļ½žCč؀čŖžćØSimulinkć®ę–‡ę³•čؘčæ°ć‚’ęÆ”č¼ƒć™ć‚‹ļ½ž20201029 ćƒ¢ćƒ†ć‚™ćƒ«ćƒ˜ć‚™ćƒ¼ć‚¹é–‹ē™ŗćƒ¢ćƒ¼ć‚æćƒ¼åˆ¶å¾”ē·Øļ½žCč؀čŖžćØSimulinkć®ę–‡ę³•čؘčæ°ć‚’ęÆ”č¼ƒć™ć‚‹ļ½ž
20201029 ćƒ¢ćƒ†ć‚™ćƒ«ćƒ˜ć‚™ćƒ¼ć‚¹é–‹ē™ŗćƒ¢ćƒ¼ć‚æćƒ¼åˆ¶å¾”ē·Øļ½žCč؀čŖžćØSimulinkć®ę–‡ę³•čؘčæ°ć‚’ęÆ”č¼ƒć™ć‚‹ļ½ž
Ā 
Speeding Up Distributed Machine Learning Using Codes
Speeding Up Distributed Machine Learning Using CodesSpeeding Up Distributed Machine Learning Using Codes
Speeding Up Distributed Machine Learning Using Codes
Ā 
Windows kernel debugging workshop in florida
Windows kernel debugging   workshop in floridaWindows kernel debugging   workshop in florida
Windows kernel debugging workshop in florida
Ā 
Bucketing 2.0: Improve Spark SQL Performance by Removing Shuffle
Bucketing 2.0: Improve Spark SQL Performance by Removing ShuffleBucketing 2.0: Improve Spark SQL Performance by Removing Shuffle
Bucketing 2.0: Improve Spark SQL Performance by Removing Shuffle
Ā 
EWD 3 Training Course Part 21: Persistent JavaScript Objects
EWD 3 Training Course Part 21: Persistent JavaScript ObjectsEWD 3 Training Course Part 21: Persistent JavaScript Objects
EWD 3 Training Course Part 21: Persistent JavaScript Objects
Ā 
PAL
PALPAL
PAL
Ā 
Android RenderScript on LLVM
Android RenderScript on LLVMAndroid RenderScript on LLVM
Android RenderScript on LLVM
Ā 
čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向
čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向
čŠøč”“ćƒ»åœ°åŸŸęƒ…å ±LOD動向
Ā 

More from Audrey Tang

TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­
TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­
TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­
Audrey Tang
Ā 
唐鳳ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Š
唐鳳ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Šå”é³³ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Š
唐鳳ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Š
Audrey Tang
Ā 
å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēƄ
å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēÆ„å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēƄ
å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēƄ
Audrey Tang
Ā 

More from Audrey Tang (20)

Social Innovation & Digital Transformation
Social Innovation & Digital TransformationSocial Innovation & Digital Transformation
Social Innovation & Digital Transformation
Ā 
Stories from the Future of Democracy
Stories from the Future of DemocracyStories from the Future of Democracy
Stories from the Future of Democracy
Ā 
TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­
TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­
TEDxTaipei 2017: ē¤¾ęœƒä¼ę„­
Ā 
唐鳳ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Š
唐鳳ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Šå”é³³ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Š
唐鳳ę”æå‹™å§”å“”ę„­å‹™å·„ä½œå ±å‘Š
Ā 
č³‡čØŠęœå‹™ęŽ”č³¼å„‘ē“„ēÆ„ęœ¬ äæ®ę­£ę˜Žē“°å°ē…§ 1060713
č³‡čØŠęœå‹™ęŽ”č³¼å„‘ē“„ēÆ„ęœ¬ äæ®ę­£ę˜Žē“°å°ē…§ 1060713č³‡čØŠęœå‹™ęŽ”č³¼å„‘ē“„ēÆ„ęœ¬ äæ®ę­£ę˜Žē“°å°ē…§ 1060713
č³‡čØŠęœå‹™ęŽ”č³¼å„‘ē“„ēÆ„ęœ¬ äæ®ę­£ę˜Žē“°å°ē…§ 1060713
Ā 
ęœå‹™åž‹ę™ŗꅧę”æåŗœęŽØ動č؈ē•« v9
ęœå‹™åž‹ę™ŗꅧę”æåŗœęŽØ動č؈ē•« v9ęœå‹™åž‹ę™ŗꅧę”æåŗœęŽØ動č؈ē•« v9
ęœå‹™åž‹ę™ŗꅧę”æåŗœęŽØ動č؈ē•« v9
Ā 
å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēƄ
å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēÆ„å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēƄ
å…±é€šę€§ę‡‰ē”ØēØ‹å¼ä»‹é¢č¦ēƄ
Ā 
ꉓ造äø€ē«™å¼ēš„é˜²ę•‘ē½č³‡čØŠę•“åˆå¹³č‡ŗ
ꉓ造äø€ē«™å¼ēš„é˜²ę•‘ē½č³‡čØŠę•“åˆå¹³č‡ŗꉓ造äø€ē«™å¼ēš„é˜²ę•‘ē½č³‡čØŠę•“åˆå¹³č‡ŗ
ꉓ造äø€ē«™å¼ēš„é˜²ę•‘ē½č³‡čØŠę•“åˆå¹³č‡ŗ
Ā 
é–‹ę”¾ę”æåŗœčÆēµ”äŗŗē¬¬11ę¬”å”ä½œęœƒč­°ē°”å ±
é–‹ę”¾ę”æåŗœčÆēµ”äŗŗē¬¬11ę¬”å”ä½œęœƒč­°ē°”å ±é–‹ę”¾ę”æåŗœčÆēµ”äŗŗē¬¬11ę¬”å”ä½œęœƒč­°ē°”å ±
é–‹ę”¾ę”æåŗœčÆēµ”äŗŗē¬¬11ę¬”å”ä½œęœƒč­°ē°”å ±
Ā 
ē¬¬7ę¬”å”ä½œęœƒč­°ęœƒå¾Œęœƒē°”å ±v6.0
ē¬¬7ę¬”å”ä½œęœƒč­°ęœƒå¾Œęœƒē°”å ±v6.0ē¬¬7ę¬”å”ä½œęœƒč­°ęœƒå¾Œęœƒē°”å ±v6.0
ē¬¬7ę¬”å”ä½œęœƒč­°ęœƒå¾Œęœƒē°”å ±v6.0
Ā 
č‡Øę™‚å‹•č­°ļ¼šē¤¾ęœƒä¼ę„­é€£ē¹«ęœƒč­°åˆ†ēµ„
č‡Øę™‚å‹•č­°ļ¼šē¤¾ęœƒä¼ę„­é€£ē¹«ęœƒč­°åˆ†ēµ„č‡Øę™‚å‹•č­°ļ¼šē¤¾ęœƒä¼ę„­é€£ē¹«ęœƒč­°åˆ†ēµ„
č‡Øę™‚å‹•č­°ļ¼šē¤¾ęœƒä¼ę„­é€£ē¹«ęœƒč­°åˆ†ēµ„
Ā 
č­°ēØ‹åŠę­·ę¬”åˆ—ē®”č”Ø
č­°ēØ‹åŠę­·ę¬”åˆ—ē®”č”Øč­°ēØ‹åŠę­·ę¬”åˆ—ē®”č”Ø
č­°ēØ‹åŠę­·ę¬”åˆ—ē®”č”Ø
Ā 
čØŽč«–ę”ˆäø€ļ¼šäø­ć€å—ć€ę±éƒØåœØ地ē¤¾ä¼ęœƒč«‡č¦åŠƒęƒ…å½¢
čØŽč«–ę”ˆäø€ļ¼šäø­ć€å—ć€ę±éƒØåœØ地ē¤¾ä¼ęœƒč«‡č¦åŠƒęƒ…å½¢čØŽč«–ę”ˆäø€ļ¼šäø­ć€å—ć€ę±éƒØåœØ地ē¤¾ä¼ęœƒč«‡č¦åŠƒęƒ…å½¢
čØŽč«–ę”ˆäø€ļ¼šäø­ć€å—ć€ę±éƒØåœØ地ē¤¾ä¼ęœƒč«‡č¦åŠƒęƒ…å½¢
Ā 
å ±å‘Šę”ˆå››ä¹‹äø€ļ¼šå‰µę«ƒęæ協助ē¤¾ęœƒä¼ę„­ē±Œč³‡ä¹‹ęŽØ動ē¾ę³
å ±å‘Šę”ˆå››ä¹‹äø€ļ¼šå‰µę«ƒęæ協助ē¤¾ęœƒä¼ę„­ē±Œč³‡ä¹‹ęŽØ動ē¾ę³å ±å‘Šę”ˆå››ä¹‹äø€ļ¼šå‰µę«ƒęæ協助ē¤¾ęœƒä¼ę„­ē±Œč³‡ä¹‹ęŽØ動ē¾ę³
å ±å‘Šę”ˆå››ä¹‹äø€ļ¼šå‰µę«ƒęæ協助ē¤¾ęœƒä¼ę„­ē±Œč³‡ä¹‹ęŽØ動ē¾ę³
Ā 
å ±å‘Šę”ˆå››ä¹‹äŗŒļ¼šåœ‹ē™¼åŸŗ金運ē”Øč³‡é‡‘å”åŠ©ē¤¾ęœƒē™¼å±•č¾¦ē†ę–¹å¼
å ±å‘Šę”ˆå››ä¹‹äŗŒļ¼šåœ‹ē™¼åŸŗ金運ē”Øč³‡é‡‘å”åŠ©ē¤¾ęœƒē™¼å±•č¾¦ē†ę–¹å¼å ±å‘Šę”ˆå››ä¹‹äŗŒļ¼šåœ‹ē™¼åŸŗ金運ē”Øč³‡é‡‘å”åŠ©ē¤¾ęœƒē™¼å±•č¾¦ē†ę–¹å¼
å ±å‘Šę”ˆå››ä¹‹äŗŒļ¼šåœ‹ē™¼åŸŗ金運ē”Øč³‡é‡‘å”åŠ©ē¤¾ęœƒē™¼å±•č¾¦ē†ę–¹å¼
Ā 
å ±å‘Šę”ˆäŗŒļ¼šēµ„團參加2017幓ē¤¾ęœƒä¼ę„­äø–ē•Œč«–å£‡č¾¦ē†é€²åŗ¦å ±å‘Š
å ±å‘Šę”ˆäŗŒļ¼šēµ„團參加2017幓ē¤¾ęœƒä¼ę„­äø–ē•Œč«–å£‡č¾¦ē†é€²åŗ¦å ±å‘Šå ±å‘Šę”ˆäŗŒļ¼šēµ„團參加2017幓ē¤¾ęœƒä¼ę„­äø–ē•Œč«–å£‡č¾¦ē†é€²åŗ¦å ±å‘Š
å ±å‘Šę”ˆäŗŒļ¼šēµ„團參加2017幓ē¤¾ęœƒä¼ę„­äø–ē•Œč«–å£‡č¾¦ē†é€²åŗ¦å ±å‘Š
Ā 
å ±å‘Šę”ˆäø‰ ļ¼šSEWFē”³č¾¦2019進åŗ¦čŖŖ꘎
å ±å‘Šę”ˆäø‰ ļ¼šSEWFē”³č¾¦2019進åŗ¦čŖŖę˜Žå ±å‘Šę”ˆäø‰ ļ¼šSEWFē”³č¾¦2019進åŗ¦čŖŖ꘎
å ±å‘Šę”ˆäø‰ ļ¼šSEWFē”³č¾¦2019進åŗ¦čŖŖ꘎
Ā 
2017-06-17 č‡ŗē£ē¶²č·Æę²»ē†č«–壇
2017-06-17 č‡ŗē£ē¶²č·Æę²»ē†č«–壇2017-06-17 č‡ŗē£ē¶²č·Æę²»ē†č«–壇
2017-06-17 č‡ŗē£ē¶²č·Æę²»ē†č«–壇
Ā 
č”Œę”æ院ę•øä½åœ‹å®¶å‰µę–°ē¶“ęæŸęŽØ動小ēµ„čØ­ē½®č¦é»ž
č”Œę”æ院ę•øä½åœ‹å®¶å‰µę–°ē¶“ęæŸęŽØ動小ēµ„čØ­ē½®č¦é»žč”Œę”æ院ę•øä½åœ‹å®¶å‰µę–°ē¶“ęæŸęŽØ動小ēµ„čØ­ē½®č¦é»ž
č”Œę”æ院ę•øä½åœ‹å®¶å‰µę–°ē¶“ęæŸęŽØ動小ēµ„čØ­ē½®č¦é»ž
Ā 
DIGIāŗ ę•ø位ę”æåŗœ
DIGIāŗ ę•ø位ę”æåŗœDIGIāŗ ę•ø位ę”æåŗœ
DIGIāŗ ę•ø位ę”æåŗœ
Ā 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
Ā 

Recently uploaded (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
Ā 
Scaling API-first ā€“ The story of a global engineering organization
Scaling API-first ā€“ The story of a global engineering organizationScaling API-first ā€“ The story of a global engineering organization
Scaling API-first ā€“ The story of a global engineering organization
Ā 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Ā 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
Ā 
šŸ¬ The future of MySQL is Postgres šŸ˜
šŸ¬  The future of MySQL is Postgres   šŸ˜šŸ¬  The future of MySQL is Postgres   šŸ˜
šŸ¬ The future of MySQL is Postgres šŸ˜
Ā 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
Ā 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Ā 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
Ā 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
Ā 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Ā 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Ā 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
Ā 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Ā 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
Ā 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
Ā 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
Ā 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
Ā 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
Ā 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
Ā 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Ā 

EtherCalc: Multiplayer Spreadsheet