Giter Site home page Giter Site logo

incr_dom's Introduction

Incr_dom: a library for writing dynamic web-apps

A library for building dynamic webapps, using Js_of_ocaml.

The library is designed roughly on a model/view/controller model. Your application is built out of:

  • A functional model type that tracks the state of your application.
  • An incremental view function for computing an HTML-like representation of how your application should render on the browser. The is based on the virtual-dom javascript library.
  • An action type that is used to schedule events that update the model.

Combined with the ability to use Async, and in particular to send out network requests using websockets, this should allow the easy construction of rich web applications in a fairly comprehensible style.

If you want a more concrete sense of how this works, look in the examples directory.

incr_dom's People

Contributors

aalekseyev avatar d-kalinichenko avatar joelburget avatar public-release avatar staronj avatar trefis avatar xclerc avatar

Stargazers

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

Watchers

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

incr_dom's Issues

Define recipe for a server-side render

Problem

examples/ have excellent content for defining client side applications. I am interested in the classico isomorphic SSR + hydrate/re-render in browser paradigm (e.g. next.js), and it seems like a well defined set of function calls in the incr_dom world could enable this.

  • server: (psuedo code), on GET /my-sweet-page => MyServerImpl.html @@ H.show (App.render model)
  • browser => Start_app.start (module App) ...

There's clearly more involved here, but OCaml community I don't think has a killer solve for this yet, even though all of the capabilities are there. Additionally, I do see that there's some work going into bonsai ATM by incr_dom contributors. Aside, should incr_dom users continue to expect development here, or really only be expecting new work (maintenance, features, etc) to be flowing from that project?

Thanks!

Building examples from README.md fails

Assuming that jbuilder is actually dune now, the README at

https://github.com/janestreet/incr_dom/blob/master/example/README.org

jbuilder build example/incr_decr/{main.bc.js,index.html}

fails.

When I run:

dune build example/incr_decr/{main.bc.js,index.html}
Error: Don't know how to build example/incr_decr/main.bc.js

Information about incr_dom/opam/ocaml installation:

❯ opam list | grep incr_dom
incr_dom                      v0.13.0          A library for building dynamic webapps, using Js_of_ocaml

❯ opam --version
2.0.5

❯ ocaml --version
The OCaml toplevel, version 4.10.0

Unable to build examples

Tried to follow the instructions here: https://github.com/janestreet/incr_dom/tree/master/example

Emacs is not my usual editor and I am unfamiliar with the ocaml build ecosystem so bear with me...

I tried to install omake via opam and invoke build commands via spacemacs+ocaml layer with little success. Also explored the traditional OCaml build processes I found on google and ran into more issues. For example:

kverrier at Kyles-MBP in ~/repos/incr_dom/example/big_table (master●)
$ ocamlbuild -use-ocamlfind -pkg core,async_kernel,incr_dom main.byte
+ ocamlfind ocamlc -c -no-alias-deps -thread -w -40 -package core,async_kernel,incr_dom -o table.cmo table.ml
findlib: [WARNING] Interface js_of_ocaml.cmi occurs in several directories: /Users/kverrier/.opam/4.03.0/lib/incr_dom, /Users/kverrier/.opam/4.03.0/lib/virtual_dom
File "table.ml", line 56, characters 54-72:
Error: Unbound value Row.focused_column
Command exited with code 2.
Compilation unsuccessful after building 3 targets (1 cached) in 00:00:00.

@yminsky @diml any assistance would be sincerely appreciated. Thanks! 😄

Installing incr_dom requires downgrade of js_of_ocaml

@hhugo: any idea why this is?

~ $ opam install incr_dom
The following actions will be performed:
  ∗  install   ppx_inline_test    v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_pipebang       v0.9.114.41+37  [required by ppx_jane]
  ∗  install   ppx_here           v0.9.114.41+37  [required by ppx_assert, ppx_jane]
  ∗  install   ppx_enumerate      v0.9.114.41+37  [required by ppx_base]
  ↘  downgrade js_of_ocaml        3.0.0 to 2.8.4  [required by incr_dom]
  ∗  install   ppx_let            v0.9.114.41+37  [required by ppx_jane]
  ∗  install   ppx_js_style       v0.9.114.41+37  [required by ppx_base]
  ∗  install   typerep            v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_traverse       v0.9.114.41+37  [required by ppx_custom_printf, ppx_expect]
  ∗  install   ppx_compare        v0.9.114.41+37  [required by bin_prot, ppx_assert]
  ∗  install   ppx_optional       v0.9.114.41+37  [required by ppx_jane]
  ∗  install   variantslib        v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_bench          v0.9.114.41+37  [required by ppx_jane]
  ∗  install   ppx_sexp_value     v0.9.114.41+37  [required by ppx_jane]
  ∗  install   ppx_sexp_message   v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_fail           v0.9.114.41+37  [required by ppx_jane]
  ↻  recompile ptime              0.8.3           [uses js_of_ocaml]
  ↻  recompile mtime              0.8.4           [uses js_of_ocaml]
  ↻  recompile logs               0.6.2           [uses js_of_ocaml]
  ↻  recompile js_of_ocaml-ppx    3.0.0           [uses js_of_ocaml]
  ∗  install   ppx_typerep_conv   v0.9.114.41+37  [required by ppx_jane]
  ∗  install   ppx_custom_printf  v0.9.114.41+37  [required by bin_prot, ppx_jane]
  ∗  install   ppx_hash           v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_assert         v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_variants_conv  v0.9.114.41+37  [required by bin_prot, ppx_jane]
  ↻  recompile tls                0.8.0           [uses ptime]
  ∗  install   ppx_base           v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_expect         v0.9.114.41+37  [required by ppx_jane]
  ∗  install   bin_prot           v0.9.114.41+37  [required by core_kernel]
  ↻  recompile conduit            0.15.0          [uses logs]
  ∗  install   configurator       v0.9.114.41+37  [required by core_kernel]
  ∗  install   ppx_bin_prot       v0.9.114.41+37  [required by ppx_jane]
  ↻  recompile cohttp             0.22.0          [uses js_of_ocaml]
  ∗  install   ppx_jane           v0.9.114.41+37  [required by incr_dom]
  ∗  install   github             2.3.0
  ∗  install   core_kernel        v0.9.114.41+37  [required by incr_dom]
  ∗  install   incremental_kernel v0.9.114.41+37  [required by incr_dom]
  ∗  install   async_kernel       v0.9.114.41+37  [required by incr_dom]
  ∗  install   incr_map           v0.9.114.41+37  [required by incr_dom]
  ∗  install   async_rpc_kernel   v0.9.114.41+37  [required by async_js]
  ∗  install   async_js           v0.9.114.41+37  [required by incr_dom]
  ∗  install   virtual_dom        v0.9.114.41+37  [required by incr_dom]
  ∗  install   incr_select        v0.9.114.41+37  [required by incr_dom]
  ∗  install   incr_dom           v0.9.114.41+37
===== ∗  36   ↻  7   ↘  1 =====

Examples require +weak.js

I can't run examples because some stuff about weaks and ephemerons are not available (the html file doesn't load and raises exceptions). Where should I put +weak.js?

➜  incr_dom git:(master) evalopam 
4.06.0
/home/kakadu/.opam/4.06.0+fp+flambda/lib/ocaml
➜  incr_dom git:(master) jbuilder build example/text_input/{main.bc.js,index.html}
         ppx example/text_input/main.pp.ml
         ppx example/text_input/app.pp.ml
    ocamldep example/text_input/main.depends.ocamldep-output
      ocamlc example/text_input/app.{cmi,cmo,cmt}
      ocamlc example/text_input/main.{cmi,cmo,cmt}
      ocamlc example/text_input/main.bc
 js_of_ocaml example/text_input/main.bc.js
There are some missing primitives
Dummy implementations (raising 'Failure' exception) will be used if they are not available at runtime.
You can prevent the generation of dummy implementations with the commandline option '--disable genprim'
Missing primitives provided by +weak.js:
  caml_ephe_create
  caml_ephe_get_data
  caml_ephe_set_data
  caml_ephe_set_key
  caml_weak_create
  caml_weak_get
  caml_weak_set

Some examples are missing

Those examples are mentioned in the readme but their directories are missing.

  • Incr_decr_rpc
  • Todo_mvc
  • todo_mvc_rpc

Install from source into 4.10.0 switch fails with Unbound value Attr.Expert.contains_name

Problem

incr_dom on  master via 🐪 default
❯ opam install ./incr_dom.opam
incr_dom is now pinned to git+file:///Users/cdaringe/src/incr_dom#master (version v0.14.0)
The following actions will be performed:
  ∗ install incr_dom v0.14.0*

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
[incr_dom.v0.14.0] synchronised from git+file:///Users/cdaringe/src/incr_dom#master

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
[ERROR] The compilation of incr_dom failed at "/Users/cdaringe/.opam/opam-init/hooks/sandbox.sh build dune build -p incr_dom -j
        3".

#=== ERROR while compiling incr_dom.v0.14.0 ===================================#
# context     2.0.7 | macos/x86_64 | ocaml-system.4.10.0 | pinned(git+file:///Users/cdaringe/src/incr_dom#master#f4a8f6a7)
# path        ~/.opam/default/.opam-switch/build/incr_dom.v0.14.0
# command     ~/.opam/opam-init/hooks/sandbox.sh build dune build -p incr_dom -j 3
# exit-code   1
# env-file    ~/.opam/log/incr_dom-5395-0a5907.env
# output-file ~/.opam/log/incr_dom-5395-0a5907.out
### output ###
# [...]
#       ocamlc src/.incr_dom.objs/byte/incr_dom__Start_app.{cmo,cmt} (exit 2)
# (cd _build/default && /usr/local/bin/ocamlc.opt -w -40 -g -bin-annot -I src/.incr_dom.objs/byte -I /Users/cdaringe/.opam/default/lib/angstrom -I /Users/cdaringe/.opam/default/lib/async_js -I /Users/cdaringe/.opam/default/lib/async_kernel -I /Users/cdaringe/.opam/default/lib/async_kernel/persistent_connection_kernel -I /Users/cdaringe/.opam/default/lib/async_rpc_kernel -I /Users/cdaringe/.opam[...]
# File "src/start_app.ml", line 185, characters 23-48:
# 185 |     |> List.exists ~f:(Attr.Expert.contains_name "disable_tab_index")
#                              ^^^^^^^^^^^^^^^^^^^^^^^^^
# Error: Unbound value Attr.Expert.contains_name
#     ocamlopt src/.incr_dom.objs/native/incr_dom__Start_app.{cmx,o} (exit 2)
# (cd _build/default && /usr/local/bin/ocamlopt.opt -w -40 -g -I src/.incr_dom.objs/byte -I src/.incr_dom.objs/native -I /Users/cdaringe/.opam/default/lib/angstrom -I /Users/cdaringe/.opam/default/lib/async_js -I /Users/cdaringe/.opam/default/lib/async_kernel -I /Users/cdaringe/.opam/default/lib/async_kernel/persistent_connection_kernel -I /Users/cdaringe/.opam/default/lib/async_rpc_kernel -I /[...]
# File "src/start_app.ml", line 185, characters 23-48:
# 185 |     |> List.exists ~f:(Attr.Expert.contains_name "disable_tab_index")
#                              ^^^^^^^^^^^^^^^^^^^^^^^^^
# Error: Unbound value Attr.Expert.contains_name



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
┌─ The following actions failed
│ λ build incr_dom v0.14.0
└─
╶─ No changes have been performed

Examples won't build due to `Scheduler.t`

I'm a total noob when it comes to OCaml but I was trying to build and got this:

λ ~/sandbox/incr_dom/ master dune build example/hello_world/{index.html,main.bc.js}
File "src/start_app.ml", line 22, characters 60-62:
Error: This expression has type unit but an expression was expected of type
         Scheduler.t

OCaml version:

λ ~/sandbox/incr_dom/ master ocamlc --version
4.07.1

Incr* versions:

incr_dom                v0.12.0     A library for building dynamic webapps, using Js_of_ocaml
incr_map                v0.12.0     Helpers for incremental operations on map like data structures
incr_select             v0.12.0     Handling of large set of incremental outputs from a single input
incremental             v0.12.0     Library for incremental computations

All versions of packages installed:

async                   v0.12.0     Monadic concurrency library
async_extra             v0.12.0     Monadic concurrency library
async_js                v0.12.0     A small library that provide Async support for JavaScript platforms
async_kernel            v0.12.0     Monadic concurrency library
async_rpc_kernel        v0.12.0     Platform-independent core of Async RPC library
async_unix              v0.12.0     Monadic concurrency library
base                    v0.12.2     Full standard library replacement for OCaml
base-bigarray           base
base-bytes              base        Bytes library distributed with the OCaml compiler
base-threads            base
base-unix               base
base_bigstring          v0.12.0     String type based on [Bigarray], for use in I/O and C-bindings
base_quickcheck         v0.12.0     Randomized testing framework, designed for compatibility with Base
bin_prot                v0.12.0     A binary protocol generator
biniou                  1.2.0       Binary data format designed for speed, safety, ease of use and backward compatibility as protocols evolve
camomile                1.0.1       A Unicode library
charInfo_width          1.1.0       Determine column width for a character
cmdliner                1.0.4       Declarative definition of command line interfaces for OCaml
conf-m4                 1           Virtual package relying on m4
conf-which              1           Virtual package relying on which
core                    v0.12.3     Industrial strength alternative to OCaml's standard library
core_kernel             v0.12.2     Industrial strength alternative to OCaml's standard library
cppo                    1.6.6       Code preprocessor like cpp for OCaml
dune                    1.10.0      Fast, portable and opinionated build system
easy-format             1.3.1       High-level and functional interface to the Format module of the OCaml standard library
fieldslib               v0.12.0     Syntax extension to define first class values representing record fields, to get and set record fields, iterate and fold over all fields of a record and create new re
incr_dom                v0.12.0     A library for building dynamic webapps, using Js_of_ocaml
incr_map                v0.12.0     Helpers for incremental operations on map like data structures
incr_select             v0.12.0     Handling of large set of incremental outputs from a single input
incremental             v0.12.0     Library for incremental computations
jane-street-headers     v0.12.0     Jane Street C header files
jbuilder                transition  This is a transition package, jbuilder is now named dune. Use the dune
js_of_ocaml             3.4.0       Compiler from OCaml bytecode to Javascript
js_of_ocaml-compiler    3.4.0       Compiler from OCaml bytecode to Javascript
js_of_ocaml-ppx         3.4.0       Compiler from OCaml bytecode to Javascript
jst-config              v0.12.0     Compile-time configuration for Jane Street libraries
lambda-term             2.0.1       Terminal manipulation library for OCaml
lwt                     4.2.1       Promises and event-driven I/O
lwt_log                 1.1.0       Lwt logging library (deprecated)
lwt_react               1.1.2       Helpers for using React with Lwt
merlin                  3.3.1       Editor helper, provides completion, typing and source browsing in Vim and Emacs
mmap                    1.1.0       File mapping functionality
num                     1.2         The legacy Num library for arbitrary-precision integer and rational arithmetic
ocaml                   4.07.1      The OCaml compiler (virtual package)
ocaml-base-compiler     4.07.1      Official release 4.07.1
ocaml-compiler-libs     v0.12.0     OCaml compiler libraries repackaged
ocaml-config            1           OCaml Switch Configuration
ocaml-migrate-parsetree 1.3.1       Convert OCaml parsetrees between different versions
ocamlbuild              0.14.0      OCamlbuild is a build system with builtin rules to easily build most OCaml projects.
ocamlfind               1.8.0       A library manager for OCaml
ocp-indent              1.7.0       A simple tool to indent OCaml programs
octavius                1.2.1       Ocamldoc comment syntax parser
parsexp                 v0.12.0     S-expression parsing library
ppx_assert              v0.12.0     Assert-like extension nodes that raise useful errors on failure
ppx_base                v0.12.0     Base set of ppx rewriters
ppx_bench               v0.12.0     Syntax extension for writing in-line benchmarks in ocaml code
ppx_bin_prot            v0.12.1     Generation of bin_prot readers and writers from types
ppx_compare             v0.12.0     Generation of comparison functions from types
ppx_custom_printf       v0.12.1     Printf-style format-strings for user-defined string conversion
ppx_derivers            1.2.1       Shared [@@deriving] plugin registry
ppx_enumerate           v0.12.0     Generate a list containing all values of a finite type
ppx_expect              v0.12.0     Cram like framework for OCaml
ppx_fail                v0.12.0     Add location to calls to failwiths
ppx_fields_conv         v0.12.0     Generation of accessor and iteration functions for ocaml records
ppx_hash                v0.12.0     A ppx rewriter that generates hash functions from type expressions and definitions
ppx_here                v0.12.0     Expands [%here] into its location
ppx_inline_test         v0.12.0     Syntax extension for writing in-line tests in ocaml code
ppx_jane                v0.12.0     Standard Jane Street ppx rewriters
ppx_js_style            v0.12.0     Code style checker for Jane Street Packages
ppx_let                 v0.12.0     Monadic let-bindings
ppx_module_timer        v0.12.0     Ppx rewriter that records top-level module startup times
ppx_optcomp             v0.12.0     Optional compilation for OCaml
ppx_optional            v0.12.0     Pattern matching on flat options
ppx_pipebang            v0.12.0     A ppx rewriter that inlines reverse application operators `|>` and `|!`
ppx_sexp_conv           v0.12.0     [@@deriving] plugin to generate S-expression conversion functions
ppx_sexp_message        v0.12.0     A ppx rewriter for easy construction of s-expressions
ppx_sexp_value          v0.12.0     A ppx rewriter that simplifies building s-expressions from ocaml values
ppx_stable              v0.12.0     Stable types conversions generator
ppx_tools_versioned     5.2.2       A variant of ppx_tools based on ocaml-migrate-parsetree
ppx_typerep_conv        v0.12.0     Generation of runtime types from type declarations
ppx_variants_conv       v0.12.0     Generation of accessor and iteration functions for ocaml variant types
ppxlib                  0.8.0       Base library and tools for ppx rewriters
protocol_version_header v0.12.0     Protocol versioning
re                      1.9.0       RE is a regular expression library for OCaml
react                   1.2.1       Declarative events and signals for OCaml
result                  1.4         Compatibility Result module
seq                     base        Compatibility package for OCaml's standard iterator type starting from 4.07.
sexplib                 v0.12.0     Library for serializing OCaml values to and from S-expressions
sexplib0                v0.12.0     Library containing the definition of S-expressions and some base converters
spawn                   v0.13.0     Spawning sub-processes
splittable_random       v0.12.0     PRNG that can be split into independent streams
stdio                   v0.12.0     Standard IO library for OCaml
stringext               1.6.0       Extra string functions for OCaml
textutils               v0.12.0     Text output utilities
time_now                v0.12.0     Reports the current time
topkg                   1.0.0       The transitory OCaml software packager
typerep                 v0.12.0     Typerep is a library for runtime types
tyxml                   4.3.0       TyXML is a library for building correct HTML and SVG documents
uchar                   0.0.2       Compatibility library for OCaml's Uchar module
uri                     2.2.1       An RFC3986 URI/URL parsing library
utop                    2.4.0       Universal toplevel for OCaml
uutf                    1.0.2       Non-blocking streaming Unicode codec for OCaml
variantslib             v0.12.0     Part of Jane Street's Core library
virtual_dom             v0.12.0     OCaml bindings for the virtual-dom library
yojson                  1.7.0       Yojson is an optimized parsing and printing library for the JSON format
zed                     2.0.2       Abstract engine for text edition in OCaml

New release?

Examples like counter use S_component which isn't present in the opam latest version v0.11.0. Is there an ongoing release?

The Example instructions only work for one of the examples

Thank you for making an awesome project, I found that the instructions for testing out the examples seems to be little out of date.

The example instructions:

opam install incr_dom
dune build example/incr_decr/bin/{main.bc.js,index.html}
Open _build/default/example/incr_decr/index.html in a web browser

are misleading, the generated code is not in _build/default/example/incr_decr but in _build/default/example/incr_decr/bin

The steps do not work for building any of the other examples provided in the repo :(

Question: Only update when a change has happened

Hi!

I've been using the Bonsai library for a side project and it's fantastic! The app runs on mobile as a single-page-application (SPA) and works well for the most part, except battery life. I've noticed that the battery drains fairly fast when using the SPA and after a bit of investigation I noticed a constant call to request_animation_frame.

It seems the source of this is that Incr_dom doesn't know when the computation graph is dirty, so it constantly tries to perform updates and stabilize the computation graph. I was wondering if there was a way to instead only call perform update when there are pending updates to the incremental graph?

I hacked it together for now here:
wlitwin/incremental@e545438
wlitwin@c489f81

But I imagine there's a better way. I tried using Observer.on_update_exn on the top-level app, but it seems that will only fire during a stabilize.

Thank you!

ts_gui example build error

$ dune build example/ts_gui/{main.bc.js,index.html}
File "src/arg_spec.ml", line 55, characters 15-21: Assertion failed
Backtrace:
Raised at file "src/dep_path.ml" (inlined), line 45, characters 24-55
Called from file "src/build_system.ml", line 186, characters 6-48
Called from file "src/fiber/fiber.ml", line 243, characters 6-18
Error: Conflict between the following libraries:
- "incr_dom" in _build/default/src
- "incr_dom" in /Users/boris/.opam/ocsigen/lib/incr_dom
    -> required by library "incr_dom_widgets" in /Users/boris/.opam/ocsigen/lib/incr_dom_widgets
This is not allowed.

Here are the lib versions I have installed:

incr_dom                            v0.11.0  A library for building dynamic weba
incr_dom_widgets                    v0.11.0  A library of libraries and widgets 
incr_map                            v0.11.0  Helpers for incremental operations 
incr_select                         v0.11.0  Handling of large set of incrementa
incremental                         v0.11.0  Library for incremental computation
incremental_kernel                  v0.11.1  Library for incremental computation

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.