From a0dfa41328eb274bdc71760e2c95ef5b9e787afa Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Tue, 24 Sep 2024 18:09:33 +0000
Subject: [PATCH] chore: Updating docs for .

---
 edoc-info                 |   4 +
 erlang.png                | Bin 0 -> 2109 bytes
 index.html                |  17 ++
 ldclient.html             | 250 +++++++++++++++++++++++
 ldclient_config.html      | 158 ++++++++++++++
 ldclient_context.html     | 420 ++++++++++++++++++++++++++++++++++++++
 ldclient_flagbuilder.html | 382 ++++++++++++++++++++++++++++++++++
 ldclient_testdata.html    | 152 ++++++++++++++
 ldclient_user.html        | 115 +++++++++++
 modules-frame.html        |  17 ++
 overview-summary.html     |  18 ++
 overview.edoc             |   4 +
 stylesheet.css            |  55 +++++
 13 files changed, 1592 insertions(+)
 create mode 100644 edoc-info
 create mode 100644 erlang.png
 create mode 100644 index.html
 create mode 100644 ldclient.html
 create mode 100644 ldclient_config.html
 create mode 100644 ldclient_context.html
 create mode 100644 ldclient_flagbuilder.html
 create mode 100644 ldclient_testdata.html
 create mode 100644 ldclient_user.html
 create mode 100644 modules-frame.html
 create mode 100644 overview-summary.html
 create mode 100644 overview.edoc
 create mode 100644 stylesheet.css

diff --git a/edoc-info b/edoc-info
new file mode 100644
index 0000000..d6de0d8
--- /dev/null
+++ b/edoc-info
@@ -0,0 +1,4 @@
+%% encoding: UTF-8
+{application,ldclient}.
+{modules,[ldclient,ldclient_config,ldclient_context,ldclient_flagbuilder,
+          ldclient_testdata,ldclient_user]}.
diff --git a/erlang.png b/erlang.png
new file mode 100644
index 0000000000000000000000000000000000000000..987a618e2403af895bfaf8c2f929e3a4f3746659
GIT binary patch
literal 2109
zcmV-D2*US?P)<h;3K|Lk000e1NJLTq001%o001fo0ssI2e%PN700009a7bBm000XU
z000XU0RWnu7ytkO2XskIMF-Xg1Pd$@^DOJq000NvNkl<ZSi{YjeNa<Z7QpX&`FIH-
zd5;KzkPwIoB9NA1_^_<IqKmp~`H&*JR$cAvC|bv1s?w1UyUGg1X?Jk9)2=HOnF#Ju
zN5FL%izAGVl<fiz2!bCF*knlsLO=-l;6ZqA|44y^4|#E__WbqcynE04y>rez_nr%N
ze)-p~%6|a|LA_bA=l=$|3jjqS$tjbGG?@TN0w$Azq7Z{YeQxKcpLO55<EWEu{v{ph
z*68c>vno1^u23DP&V=i9-KAAsU*ECy^#OtaDC!lVSo!+|-%T+LhTHP<AxNCE{XtQ!
zv3F!v=Pl6F=M4+k6C-<fD@CTUwzm4+Sx+D9fo(=LIyS0p(0tS6|GU_q7iKct&}EIF
zGHGbqJKyD$g6TOW>^Oqwx8m)b4<R~2g~_V!zWLjao_07e&B&Bxs^_cPrjvgGHX9X(
z1@21WiB>r3V28JmV&6M#iG)&0;P`j>XGfomEIEK6wPkhI{{K?3#uAGq$!`N_F)TNX
zAvuspF?^;c9h%CPWyTDc_03%r4N8+Yzzo_VSfa!zo_7F6D?<+-+KkHwXiWQ<qCxNQ
za4yQ6TY0ljfjg<X3IO1>R=Mr(9|K@{{xEjfDvAbS9uNCP&{)NNCoC?XA$aRe>R8->
z5N<#S_)$d|EYpJfPC?{`$Y~f4yjH<NWb<>&dxHXIGG8wiaLBD6usC87c<sVL=3{vX
z(bta!CY-T2fWiAIV6mMG1PmN2EQMX4)K>g+dd&3WLJd4_TcmEeAOz8R>ikgW(9821
z{34Se09Y?KoG<_Y;DDSoyTk>fUN0YO5)3^Za{&s1JbidC9}56{px+f|K_0;YuL5h}
z_9J3y%7ucwM)E4K#=Cn7tCjjRkKjnQuiFcM6{17Jt#5F}7z8~RYqW24xV?kAU6xQN
zh+h4|SmO1;TdsVOaOeD*kKf}6I7=6ZNig_rtqV?Ov1HrU(P%Hi#6npSe>%qGaNK1w
zW$v+r`r<Xmwz>0>#p~AN^8b)#7Yesu(ys(>3SCYb4sF9%A9=kMHrLmzk}E&WPG~Jx
z9!r{qo5M184t;<7I`t1AsNjv912EeKkHKtOSl%wbcjFh7L6|G?Q+{?radOvuEW$>1
zoc+c&F+u$^0f}1_2dN&lS#I#p3e&<rH~^N2y?J1;>+|YGHlMzRC)%&8TnGt+p*;Oz
z`0=D=n|qcN+f@07;QjB@ktLhZ`+qz;(xYDli^Pex&&wwU2V4N-a3b@veqHg2cvCRb
zoi=ZerLk!4t5!s3?|ARuWx_4-VCgl|TY2qa@$Dr~5QdiT8?$oPpZhaF5UOZ&x=+I9
zt((`6wBPM((BS{;2lmSB;o%z{>=mg*1k2oLjI=+zcf5$4BIZmkOr<BK&AyTU2>jrE
z*VY(<@FO?zBVDc+Q~Lh;LnlYodZ$J3tmWJBN4j~wVOWelzexhft2nY6A3PZAcm!q}
z931CL#1Ki6;HM{agTbKF>3(R-yuF1&Apn3Nh@PGvv)K$mkVqu*^z@vaFgQ3kFfg!s
z^=f26@{Ny=_w@7x1qHF$bEk5X$)wR}0s{l><E>V!TCGM=R5Ei1Ll8u7Z*N0G1CPgB
zyLPP|0H{<d?u=w+W|AaHlH}y%WI{rMUFq-dfAi)|az^s<@-Ph3>-FRUDJv`Ea=9fX
zC63D4+FBlumz$eAJv~j5q*|@^_xC?_>XiL0K@bH61$;i=&CLx(QGb8`8#iu{BnjJW
zHUvSgUcK7T&~W(h;koN8t5vB~Ha0dgnane1&RA#87dVcaOpEMM)6>)E&YiPZEXBpe
zlarHk89g;+G#U#E3hL_W002xT6UTApOeR%UR_5g7q^73!_4PG2Hi|@|ii(Pfi3vIY
z0ES^?Mx1IOizO0?e0_a!9483k`PtCk-rm~Unwpw=?b@~O?(WdgP^bMMAYlLg{dIM9
zOy}OcxVTs%k(@q#n$PF+`TXkYYA%;cr_*5ofWcr$PEL-Ai772Db)3`L*|~G)&eqn}
zq@*OrbXim`UAiO`3XdK=%H#1=D%HHV>FMbqAtCAM=@!e}C6Cc))ai5zg~H3rYjkup
zD=RBMKR+`wv!kN}1^{3fR#a3}RaLcP#}20|H!^bT)~%G3lp{xu!0_{Wr2hW?>({UQ
z`T1F`)|D$)*3{IP&1UDKhLn_)sMYHH{QRkzV=$M?#W2idGFh!wf*`b7ZGC-xVPT=c
zV1Vs&!otFoN~M>VQ$G_G6}5No-m0pqwzjr;?W@INu~;m#k*%qz(P%VUt#;3zJ^lUt
zU0q%G?%kVzvF7cqQmLw|tA~e&XIqun*x2Ug=9-!s48ty7ycil9Di(|7aybkD7#<!@
zOH13nefxzA7v}w9Mn(pWM$695cKmySAQBT3<Kp7%xE710yu3UpD5$Basi~>y?%lgQ
z9`Ewy%eDpgxlvJ3Cr+GTFc>(F+cg;(8TPc>y?b|jeEgLwR}LLIBoqp1+1c4_HrvO?
z$J5g@G&D3gIC$2ITrQ7`iwh4AfA;K|OePZu1oriTVVG1Zl}e@S)~)mK@UU1cI-Ty|
z!Gj8gg2UmUD2ibif*{e+(R4bU#bU|j@{Joe^7(uSf+8X!q*7@_M1;L=AqbM3oXp{H
nT3T9A6wS=c+_!HZolgHhw9g$%O4Wbp00000NkvXXu0mjf3HKBY

literal 0
HcmV?d00001

diff --git a/index.html b/index.html
new file mode 100644
index 0000000..a371530
--- /dev/null
+++ b/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The ldclient application</title>
+</head>
+<frameset cols="20%,80%">
+<frame src="modules-frame.html" name="modulesFrame" title="">
+
+<frame src="overview-summary.html" name="overviewFrame" title="">
+<noframes>
+<h2>This page uses frames</h2>
+<p>Your browser does not accept frames.
+<br>You should go to the <a href="overview-summary.html">non-frame version</a> instead.
+</p>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
diff --git a/ldclient.html b/ldclient.html
new file mode 100644
index 0000000..3dc979a
--- /dev/null
+++ b/ldclient.html
@@ -0,0 +1,250 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Module ldclient</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module ldclient</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul><code>ldclient</code> module.
+
+
+<h2><a name="description">Description</a></h2><p><code>ldclient</code> module</p>
+ 
+  <p>Acts as an interface to most common SDK functions: starting and stopping  
+client instances, and evaluating feature flags for contexts.</p>
+ 
+  Most use cases only need a single client instance for the lifetime of
+  their application. Consider using multiple instances only if you need to
+  simultaneously access more than one environment. Do not start an instance
+  every time you need to make a variation or other SDK call.
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#all_flags_state-1">all_flags_state/1</a></td><td>Evaluate all flags for a given context and return their values.</td></tr>
+<tr><td valign="top"><a href="#all_flags_state-2">all_flags_state/2</a></td><td>Evaluate all flags for a given context and given client instance.</td></tr>
+<tr><td valign="top"><a href="#all_flags_state-3">all_flags_state/3</a></td><td>Returns an object that encapsulates the state of all feature flags for a given context.</td></tr>
+<tr><td valign="top"><a href="#identify-1">identify/1</a></td><td>Identify reports details about a context.</td></tr>
+<tr><td valign="top"><a href="#identify-2">identify/2</a></td><td>Identify reports details about a context.</td></tr>
+<tr><td valign="top"><a href="#initialized-1">initialized/1</a></td><td>Returns whether the LaunchDarkly client has initialized.</td></tr>
+<tr><td valign="top"><a href="#is_offline-1">is_offline/1</a></td><td>Returns whether the LaunchDarkly client is in offline mode.</td></tr>
+<tr><td valign="top"><a href="#start_instance-1">start_instance/1</a></td><td>Start client with default options.</td></tr>
+<tr><td valign="top"><a href="#start_instance-2">start_instance/2</a></td><td>Start client with custom name or options.</td></tr>
+<tr><td valign="top"><a href="#start_instance-3">start_instance/3</a></td><td>Start client with custom name and options.</td></tr>
+<tr><td valign="top"><a href="#stop_all_instances-0">stop_all_instances/0</a></td><td>Stop all client instances.</td></tr>
+<tr><td valign="top"><a href="#stop_instance-0">stop_instance/0</a></td><td>Stop client instance.</td></tr>
+<tr><td valign="top"><a href="#stop_instance-1">stop_instance/1</a></td><td>Stop client with the custom name.</td></tr>
+<tr><td valign="top"><a href="#track-3">track/3</a></td><td>Track reports that a context has performed an event.</td></tr>
+<tr><td valign="top"><a href="#track-4">track/4</a></td><td>Track reports that a context has performed an event.</td></tr>
+<tr><td valign="top"><a href="#track_metric-4">track_metric/4</a></td><td>Reports that a context has performed an event, and associates it with a numeric value.</td></tr>
+<tr><td valign="top"><a href="#track_metric-5">track_metric/5</a></td><td>Reports that a context has performed an event, and associates it with a numeric value.</td></tr>
+<tr><td valign="top"><a href="#variation-3">variation/3</a></td><td>Evaluate given flag key for given context.</td></tr>
+<tr><td valign="top"><a href="#variation-4">variation/4</a></td><td>Evaluate given flag key for given context and given client instance.</td></tr>
+<tr><td valign="top"><a href="#variation_detail-3">variation_detail/3</a></td><td>Evaluate given flag key for given context.</td></tr>
+<tr><td valign="top"><a href="#variation_detail-4">variation_detail/4</a></td><td>Evaluate given flag key for given context and given client instance.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="all_flags_state-1">all_flags_state/1</a></h3>
+<div class="spec">
+<p><tt>all_flags_state(Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-feature_flags_state">ldclient_eval:feature_flags_state()</a></tt><br></p>
+<p> </p>
+</div><p><p>Evaluate all flags for a given context and return their values</p>
+ 
+  Evaluates all existing flags, but does not create any events as a side
+  effect of the evaluation. It returns a map of flag keys to evaluated values.</p>
+
+<h3 class="function"><a name="all_flags_state-2">all_flags_state/2</a></h3>
+<div class="spec">
+<p><tt>all_flags_state(Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Tag::atom()) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-feature_flags_state">ldclient_eval:feature_flags_state()</a></tt><br></p>
+<p> </p>
+</div><p><p>Evaluate all flags for a given context and given client instance</p>
+ 
+  Evaluates all existing flags, but does not create any events as a side
+  effect of the evaluation. It returns a map of flag keys to evaluated values.</p>
+
+<h3 class="function"><a name="all_flags_state-3">all_flags_state/3</a></h3>
+<div class="spec">
+<p><tt>all_flags_state(Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Options::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-all_flags_state_options">ldclient_eval:all_flags_state_options()</a>, Tag::atom()) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-feature_flags_state">ldclient_eval:feature_flags_state()</a></tt><br></p>
+<p> </p>
+</div><p><p>Returns an object that encapsulates the state of all feature flags for a given context.</p>
+ 
+  <p>This includes the flag values, and also metadata that can be used on the front end.  
+The most common use case for this method is to bootstrap a set of client-side feature flags from a  
+back-end service.</p>
+ 
+  If you are not using this to boostrap a client, then you likely want all_flags_state/1 or all_flags_state/2.</p>
+
+<h3 class="function"><a name="identify-1">identify/1</a></h3>
+<div class="spec">
+<p><tt>identify(Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Identify reports details about a context</p>
+ 
+  This function uses the default client instance.</p>
+
+<h3 class="function"><a name="identify-2">identify/2</a></h3>
+<div class="spec">
+<p><tt>identify(Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Tag::atom()) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Identify reports details about a context</p>
+ 
+  This is useful to report context to a specific client instance.</p>
+
+<h3 class="function"><a name="initialized-1">initialized/1</a></h3>
+<div class="spec">
+<p><tt>initialized(Tag::atom()) -&gt; boolean()</tt><br></p>
+<p> </p>
+</div><p><p>Returns whether the LaunchDarkly client has initialized.</p>
+ 
+  <p>If this value is true, it means the client has succeeded at some point in connecting to LaunchDarkly and  
+has received feature flag data. It could still have encountered a connection problem after that point, so  
+this does not guarantee that the flags are up to date. Alternatively, it could also mean that the client  
+is in offline mode.</p>
+ 
+  If this value is false, it means the client has not yet connected to LaunchDarkly, or has permanently
+  failed. In this state, feature flag evaluations will always return default values.</p>
+
+<h3 class="function"><a name="is_offline-1">is_offline/1</a></h3>
+<div class="spec">
+<p><tt>is_offline(Tag::atom()) -&gt; boolean()</tt><br></p>
+<p> </p>
+</div><p><p>Returns whether the LaunchDarkly client is in offline mode.</p>
+ 
+  In some situations, you might want to stop making remote calls to LaunchDarkly and
+  fall back to default values for your feature flags, this tells you whether only default
+  values will be returned.</p>
+
+<h3 class="function"><a name="start_instance-1">start_instance/1</a></h3>
+<div class="spec">
+<p><tt>start_instance(SdkKey::string()) -&gt; ok | {error, atom(), term()}</tt><br></p>
+<p> </p>
+</div><p><p>Start client with default options</p>
+ 
+  The SDK key is required to connect. Default streamer URL, storage backend
+  and instance name <code>default</code> will be used.</p>
+
+<h3 class="function"><a name="start_instance-2">start_instance/2</a></h3>
+<div class="spec">
+<p><tt>start_instance(SdkKey::string(), TagOrOptions::atom() | map()) -&gt; ok | {error, atom(), term()}</tt><br></p>
+<p> </p>
+</div><p><p>Start client with custom name or options</p>
+ 
+  When <code>TagOrOptions</code> is an atom, the instance is started with that name. When
+  it's a map, it can be used to start with custom options.</p>
+
+<h3 class="function"><a name="start_instance-3">start_instance/3</a></h3>
+<div class="spec">
+<p><tt>start_instance(SdkKey::string(), Tag::atom(), Options::map()) -&gt; ok | {error, atom(), term()}</tt><br></p>
+<p> </p>
+</div><p><p>Start client with custom name and options</p>
+ 
+  Specify both custom client name and options when starting the client.</p>
+
+<h3 class="function"><a name="stop_all_instances-0">stop_all_instances/0</a></h3>
+<div class="spec">
+<p><tt>stop_all_instances() -&gt; ok</tt><br></p>
+<p> </p>
+</div><p>Stop all client instances
+ </p>
+
+<h3 class="function"><a name="stop_instance-0">stop_instance/0</a></h3>
+<div class="spec">
+<p><tt>stop_instance() -&gt; ok | {error, not_found, term()}</tt><br></p>
+<p> </p>
+</div><p><p>Stop client instance</p>
+ 
+  Stops the default client instance.</p>
+
+<h3 class="function"><a name="stop_instance-1">stop_instance/1</a></h3>
+<div class="spec">
+<p><tt>stop_instance(Tag::atom()) -&gt; ok | {error, not_found, term()}</tt><br></p>
+<p> </p>
+</div><p><p>Stop client with the custom name</p>
+ 
+  This is useful if a client instance was started with a custom name.</p>
+
+<h3 class="function"><a name="track-3">track/3</a></h3>
+<div class="spec">
+<p><tt>track(Key::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Data::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_event.html#type-event_data">ldclient_event:event_data()</a>) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Track reports that a context has performed an event</p>
+ 
+  Custom data can be attached to the event.</p>
+
+<h3 class="function"><a name="track-4">track/4</a></h3>
+<div class="spec">
+<p><tt>track(Key::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Data::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_event.html#type-event_data">ldclient_event:event_data()</a>, Tag::atom()) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Track reports that a context has performed an event</p>
+ 
+  This is useful for specifying a specific client instance.</p>
+
+<h3 class="function"><a name="track_metric-4">track_metric/4</a></h3>
+<div class="spec">
+<p><tt>track_metric(Key::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Data::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_event.html#type-event_data">ldclient_event:event_data()</a>, Metric::number()) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Reports that a context has performed an event, and associates it with a numeric value.</p>
+ 
+  <p>This value is used by the LaunchDarkly experimentation feature in numeric custom metrics, and will also  
+be returned as part of the custom event for Data Export.</p>
+ 
+  Custom data can also be attached to the event.</p>
+
+<h3 class="function"><a name="track_metric-5">track_metric/5</a></h3>
+<div class="spec">
+<p><tt>track_metric(Key::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, Data::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_event.html#type-event_data">ldclient_event:event_data()</a>, Metric::number(), Tag::atom()) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Reports that a context has performed an event, and associates it with a numeric value.</p>
+ 
+  <p>This value is used by the LaunchDarkly experimentation feature in numeric custom metrics, and will also  
+be returned as part of the custom event for Data Export.</p>
+ 
+  Custom data can also be attached to the event.</p>
+
+<h3 class="function"><a name="variation-3">variation/3</a></h3>
+<div class="spec">
+<p><tt>variation(FlagKey::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, DefaultValue::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-result_value">ldclient_eval:result_value()</a>) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-result_value">ldclient_eval:result_value()</a></tt><br></p>
+<p> </p>
+</div><p><p>Evaluate given flag key for given context</p>
+ 
+  Evaluates the flag and returns the resulting variation value. The default
+  value will be returned in case of any errors.</p>
+
+<h3 class="function"><a name="variation-4">variation/4</a></h3>
+<div class="spec">
+<p><tt>variation(FlagKey::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, DefaultValue::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-result_value">ldclient_eval:result_value()</a>, Tag::atom()) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-result_value">ldclient_eval:result_value()</a></tt><br></p>
+<p> </p>
+</div><p><p>Evaluate given flag key for given context and given client instance</p>
+ 
+  Evaluates the flag and returns the resulting variation value. The default
+  value will be returned in case of any errors.</p>
+
+<h3 class="function"><a name="variation_detail-3">variation_detail/3</a></h3>
+<div class="spec">
+<p><tt>variation_detail(FlagKey::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, DefaultValue::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-result_value">ldclient_eval:result_value()</a>) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-detail">ldclient_eval:detail()</a></tt><br></p>
+<p> </p>
+</div><p><p>Evaluate given flag key for given context</p>
+ 
+  Evaluates the flag and returns the result detail containing the variation
+  index, value, and reason why the specific result was chosen. The default
+  value will be returned in case of any errors.</p>
+
+<h3 class="function"><a name="variation_detail-4">variation_detail/4</a></h3>
+<div class="spec">
+<p><tt>variation_detail(FlagKey::binary(), Context::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a> | <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-context">ldclient_context:context()</a>, DefaultValue::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-result_value">ldclient_eval:result_value()</a>, Tag::atom()) -&gt; <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_eval.html#type-detail">ldclient_eval:detail()</a></tt><br></p>
+<p> </p>
+</div><p><p>Evaluate given flag key for given context and given client instance</p>
+ 
+  Evaluates the flag and returns the result detail containing the variation
+  index, value, and reason why the specific result was chosen. The default
+  value will be returned in case of any errors.</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/ldclient_config.html b/ldclient_config.html
new file mode 100644
index 0000000..c8f1638
--- /dev/null
+++ b/ldclient_config.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Module ldclient_config</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module ldclient_config</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul><code>ldclient_config</code> module.
+
+
+<h2><a name="description">Description</a></h2><p><code>ldclient_config</code> module</p>
+ 
+  Acts as a storage interface for SDK client instance settings.
+<h2><a name="types">Data Types</a></h2>
+
+<h3 class="typedecl"><a name="type-app_info">app_info()</a></h3>
+<p><tt>app_info() = #{id =&gt; binary(), version =&gt; binary()}</tt></p>
+
+
+<h3 class="typedecl"><a name="type-http_options">http_options()</a></h3>
+<p><tt>http_options() = #{tls_options =&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>] | undefined, connect_timeout =&gt; pos_integer() | undefined, custom_headers =&gt; [{Key::string(), Value::string()}] | undefined}</tt></p>
+
+
+<h3 class="typedecl"><a name="type-instance">instance()</a></h3>
+<p><tt>instance() = #{sdk_key =&gt; string(), base_uri =&gt; string(), events_uri =&gt; string(), stream_uri =&gt; string(), feature_store =&gt; atom(), events_capacity =&gt; pos_integer(), events_flush_interval =&gt; pos_integer(), events_dispatcher =&gt; atom(), context_keys_capacity =&gt; pos_integer(), private_attributes =&gt; <a href="#type-private_attributes">private_attributes()</a>, stream =&gt; boolean(), polling_interval =&gt; pos_integer(), polling_update_requestor =&gt; atom(), offline =&gt; boolean(), redis_host =&gt; string(), redis_port =&gt; pos_integer(), redis_database =&gt; integer(), redis_password =&gt; string(), redis_prefix =&gt; string(), redis_tls =&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_option">ssl:tls_option()</a>] | undefined, cache_ttl =&gt; integer(), use_ldd =&gt; boolean(), send_events =&gt; boolean(), file_datasource =&gt; boolean(), file_paths =&gt; [string() | binary()], file_auto_update =&gt; boolean(), file_poll_interval =&gt; pos_integer(), file_allow_duplicate_keys =&gt; boolean(), testdata_tag =&gt; atom(), datasource =&gt; poll | stream | file | testdata | undefined, http_options =&gt; <a href="#type-http_options">http_options()</a>, stream_initial_retry_delay_ms =&gt; non_neg_integer(), application =&gt; <a href="#type-app_info">app_info()</a>}</tt></p>
+
+
+<h3 class="typedecl"><a name="type-private_attributes">private_attributes()</a></h3>
+<p><tt>private_attributes() = all | [<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_attribute_reference.html#type-attribute_reference">ldclient_attribute_reference:attribute_reference()</a>]</tt></p>
+
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#get_event_schema-0">get_event_schema/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#get_registered_tags-0">get_registered_tags/0</a></td><td>Get all registered tags.</td></tr>
+<tr><td valign="top"><a href="#get_user_agent-0">get_user_agent/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#get_value-2">get_value/2</a></td><td>Gets application environment variable value.</td></tr>
+<tr><td valign="top"><a href="#get_version-0">get_version/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#init-0">init/0</a></td><td>Initialize settings environment map.</td></tr>
+<tr><td valign="top"><a href="#register-2">register/2</a></td><td>Register settings for a new client instance.</td></tr>
+<tr><td valign="top"><a href="#tls_basic_certifi_options-0">tls_basic_certifi_options/0</a></td><td>Provide basic TLS options using the bundled certifi store.</td></tr>
+<tr><td valign="top"><a href="#tls_basic_linux_options-0">tls_basic_linux_options/0</a></td><td>Provide basic options for using TLS with the default linux store.</td></tr>
+<tr><td valign="top"><a href="#tls_basic_options-0">tls_basic_options/0</a></td><td>Provide basic options for using TLS.</td></tr>
+<tr><td valign="top"><a href="#tls_ca_certfile_options-1">tls_ca_certfile_options/1</a></td><td>Provide basic options for using TLS with the given store.</td></tr>
+<tr><td valign="top"><a href="#unregister-1">unregister/1</a></td><td>Unregister settings for a client instance.</td></tr>
+<tr><td valign="top"><a href="#with_tls_revocation-1">with_tls_revocation/1</a></td><td>Append the specified TLS options with certificate revocation.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="get_event_schema-0">get_event_schema/0</a></h3>
+<div class="spec">
+<p><tt>get_event_schema() -&gt; string()</tt><br></p>
+<p> </p>
+</div>
+
+<h3 class="function"><a name="get_registered_tags-0">get_registered_tags/0</a></h3>
+<div class="spec">
+<p><tt>get_registered_tags() -&gt; [atom()]</tt><br></p>
+<p> </p>
+</div><p>Get all registered tags
+ </p>
+
+<h3 class="function"><a name="get_user_agent-0">get_user_agent/0</a></h3>
+<div class="spec">
+<p><tt>get_user_agent() -&gt; string()</tt><br></p>
+<p> </p>
+</div>
+
+<h3 class="function"><a name="get_value-2">get_value/2</a></h3>
+<div class="spec">
+<p><tt>get_value(Tag::atom(), Key::atom()) -&gt; undefined | term()</tt><br></p>
+<p> </p>
+</div><p><p>Gets application environment variable value</p>
+ 
+  This is a convenience function to retrieve application environment variables
+  in one place. <code>Tag</code> is the instance tag. <code>Key</code> is the key of the
+  configuration option.</p>
+
+<h3 class="function"><a name="get_version-0">get_version/0</a></h3>
+<div class="spec">
+<p><tt>get_version() -&gt; string()</tt><br></p>
+<p> </p>
+</div>
+
+<h3 class="function"><a name="init-0">init/0</a></h3>
+<div class="spec">
+<p><tt>init() -&gt; ok</tt><br></p>
+<p> </p>
+</div><p><p>Initialize settings environment map</p>
+ 
+  Initializes an empty map for instance settings in application environment.</p>
+
+<h3 class="function"><a name="register-2">register/2</a></h3>
+<div class="spec">
+<p><tt>register(Tag::atom(), Settings::<a href="#type-instance">instance()</a>) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p>Register settings for a new client instance
+ </p>
+
+<h3 class="function"><a name="tls_basic_certifi_options-0">tls_basic_certifi_options/0</a></h3>
+<div class="spec">
+<p><tt>tls_basic_certifi_options() -&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>]</tt><br></p>
+<p> </p>
+</div><p>Provide basic TLS options using the bundled certifi store.
+ </p>
+
+<h3 class="function"><a name="tls_basic_linux_options-0">tls_basic_linux_options/0</a></h3>
+<div class="spec">
+<p><tt>tls_basic_linux_options() -&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>]</tt><br></p>
+<p> </p>
+</div><p>Provide basic options for using TLS with the default linux store.
+  This will try to use the a certificate store located at
+  /etc/ssl/certs/ca-certificates.crt.
+ </p>
+
+<h3 class="function"><a name="tls_basic_options-0">tls_basic_options/0</a></h3>
+<div class="spec">
+<p><tt>tls_basic_options() -&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>]</tt><br></p>
+<p> </p>
+</div><p>Provide basic options for using TLS.
+  This will try to use the a certificate store located at
+  /etc/ssl/certs/ca-certificates.crt, but if that file
+  does not exist, then it will use the bundled certifi store.
+ </p>
+
+<h3 class="function"><a name="tls_ca_certfile_options-1">tls_ca_certfile_options/1</a></h3>
+<div class="spec">
+<p><tt>tls_ca_certfile_options(CaStorePath::string()) -&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>]</tt><br></p>
+<p> </p>
+</div><p>Provide basic options for using TLS with the given store.
+ </p>
+
+<h3 class="function"><a name="unregister-1">unregister/1</a></h3>
+<div class="spec">
+<p><tt>unregister(Tag::atom()) -&gt; ok</tt><br></p>
+<p> </p>
+</div><p>Unregister settings for a client instance
+ </p>
+
+<h3 class="function"><a name="with_tls_revocation-1">with_tls_revocation/1</a></h3>
+<div class="spec">
+<p><tt>with_tls_revocation(Options::[<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>]) -&gt; [<a href="http://www.erlang.org/edoc/doc/ssl/doc/ssl.html#type-tls_client_option">ssl:tls_client_option()</a>]</tt><br></p>
+<p> </p>
+</div><p>Append the specified TLS options with certificate revocation.
+  The crl_cache does not actually cache at this time, so this will
+  result in an additional request per TLS handshake.
+ </p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/ldclient_context.html b/ldclient_context.html
new file mode 100644
index 0000000..331317b
--- /dev/null
+++ b/ldclient_context.html
@@ -0,0 +1,420 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Module ldclient_context</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module ldclient_context</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Context data type  
+When constructing a context by hand, not using new/1, new/2 or new_from_map,  
+then you must include a kind attribute.
+
+
+<h2><a name="description">Description</a></h2><p>Context data type  
+When constructing a context by hand, not using new/1, new/2 or new_from_map,  
+then you must include a kind attribute.</p>
+ 
+  The kind attribute is used to differentiate between a map representing
+  a ldclient_user and one representing a ldclient_context.
+<h2><a name="types">Data Types</a></h2>
+
+<h3 class="typedecl"><a name="type-attribute_key">attribute_key()</a></h3>
+<p><tt>attribute_key() = binary() | key | kind | anonymous | private_attributes | name</tt></p>
+<p>  Attribute keys must be binary() strings. They should not be empty, and they must not be <code>&lt;&lt;"_meta"&gt;&gt;</code>.</p>
+
+<h3 class="typedecl"><a name="type-attribute_map">attribute_map()</a></h3>
+<p><tt>attribute_map() = #{<a href="#type-attribute_key">attribute_key()</a> =&gt; <a href="#type-attribute_value">attribute_value()</a>}</tt></p>
+
+
+<h3 class="typedecl"><a name="type-attribute_value">attribute_value()</a></h3>
+<p><tt>attribute_value() = binary() | integer() | float() | boolean() | <a href="#type-attribute_map">attribute_map()</a> | [<a href="#type-attribute_value">attribute_value()</a>]</tt></p>
+<p>  Attribute values should all be data types which are compatible with JSON and nested JSON collections.
+  The leaf nodes of these values are what are ultimately used when evaluating flags which are dependent on attributes.</p>
+
+<h3 class="typedecl"><a name="type-context">context()</a></h3>
+<p><tt>context() = <a href="#type-single_context">single_context()</a> | <a href="#type-multi_context">multi_context()</a></tt></p>
+
+
+<h3 class="typedecl"><a name="type-context_part">context_part()</a></h3>
+<p><tt>context_part() = #{key := <a href="#type-key">key()</a>, name := binary(), private_attributes =&gt; [binary()], anonymous =&gt; boolean(), attributes =&gt; <a href="#type-attribute_map">attribute_map()</a>}</tt></p>
+<p>  The content of a multi context. Should be the same as a <a docgen-rel="seemfa" docgen-href="#single_context/0" href="#single_context-0"><code>single_context/0</code></a> aside from missing 'kind'.
+  A multi context is keyed by the 'kind'.</p>
+
+<h3 class="typedecl"><a name="type-key">key()</a></h3>
+<p><tt>key() = binary()</tt></p>
+<p>  Keys may be any non-empty binary() string. <code>&lt;&lt;&gt;&gt;</code> and <code>&lt;&lt;""&gt;&gt;</code> are not valid.
+  Keys must be binaries, and should match those in LaunchDarkly exactly.
+  No casing conversions will be applied <code>&lt;&lt;"my_attribute"&gt;&gt;</code> will only match <code>&lt;&lt;"my_attribute"&gt;&gt;</code>, it would not match
+  <code>&lt;&lt;"myAttribute"&gt;&gt;</code>.</p>
+
+<h3 class="typedecl"><a name="type-kind_value">kind_value()</a></h3>
+<p><tt>kind_value() = binary()</tt></p>
+<p>  May only contain ASCII letters, numbers, ., _ or -.
+  <code>&lt;&lt;"my_kind.0-1"&gt;&gt;</code> would be valid.
+  <code>&lt;&lt;"my:kind.{0}"&gt;&gt;</code> would not, it contains ':' and '{}' which are not allowed.
+  Kinds should be binaries, and should match the context kinds exactly.
+  No casing conversions will be applied <code>&lt;&lt;"my_kind"&gt;&gt;</code> will only match <code>&lt;&lt;"my_kind"&gt;&gt;</code>, it would not match
+  <code>&lt;&lt;"myKind"&gt;&gt;</code>.</p>
+
+<h3 class="typedecl"><a name="type-multi_context">multi_context()</a></h3>
+<p><tt>multi_context() = #{kind := <a href="#type-kind_value">kind_value()</a>, <a href="#type-kind_value">kind_value()</a> := <a href="#type-context_part">context_part()</a>}</tt></p>
+<p><p>  A context which represents multiple kinds. Each kind having its own key and attributes.</p>
+ 
+  <p>A multi-context must contain <code>kind =&gt; &lt;&lt;"multi"&gt;&gt;</code> at the root.</p>
+ 
+  <pre>  MyMultiContext = #{
+    %% Multi-contexts must be of kind &lt;&lt;"multi"&gt;&gt;.
+    kind =&gt; &lt;&lt;"multi"&gt;&gt;,
+    %% The context is namespaced by its kind. This is an 'org' kind context.
+    &lt;&lt;"org"&gt;&gt; =&gt; #{
+      // Each component context has its own key and attributes.
+      key =&gt; &lt;&lt;"my-org-key"&gt;&gt;,
+      attributes =&gt; #{
+          &lt;&lt;"someAttribute"&gt;&gt; =&gt; &lt;&lt;"my-attribute-value"&gt;&gt;,
+      }
+    },
+    &lt;&lt;"user"&gt;&gt; =&gt; #{
+      key =&gt; &lt;&lt;"my-user-key"&gt;&gt;,
+      %% Each component context has its own meta attributes. This will only apply the this
+      %% 'user' context.
+      private_attributes =&gt; [&lt;&lt;"firstName"&gt;&gt;]
+      attributes =&gt; #{
+          &lt;&lt;"firstName"&gt;&gt; =&gt; &lt;&lt;"Bob"&gt;&gt;,
+          &lt;&lt;"lastName"&gt;&gt; =&gt; &lt;&lt;"Bobberson"&gt;&gt;,
+      }
+    }
+  }.</pre>
+ 
+  The above multi-context contains both an 'org' and a 'user'. Each with their own key,
+  attributes, and _meta attributes.</p>
+
+<h3 class="typedecl"><a name="type-single_context">single_context()</a></h3>
+<p><tt>single_context() = #{key := <a href="#type-key">key()</a>, name =&gt; binary(), kind := <a href="#type-kind_value">kind_value()</a>, private_attributes =&gt; [binary()], anonymous =&gt; boolean(), attributes =&gt; <a href="#type-attribute_map">attribute_map()</a>}</tt></p>
+<p><p>  A context which represents a single kind.</p>
+ 
+  <p>For a single kind context the 'kind' may not be <code>&lt;&lt;"multi"&gt;&gt;</code>.</p>
+ 
+  <pre>  MyOrgContext = #{
+      kind =&gt; &lt;&lt;"org"&gt;&gt;,
+      key =&gt; &lt;&lt;"my-org-key"&gt;&gt;,
+      attributes =&gt; #{
+        &lt;&lt;"someAttribute"&gt;&gt; =&gt; &lt;&lt;"my-attribute-value"&gt;&gt;
+      }
+  }.</pre>
+ 
+  The above context would be a single kind context representing an organization. It has a key
+  for that organization, and a single attribute 'someAttribute'.</p>
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#get-3">get/3</a></td><td>Get an attribute value from the specified context kind by the specified attribute reference.</td></tr>
+<tr><td valign="top"><a href="#get_canonical_key-1">get_canonical_key/1</a></td><td>A string that describes the entire Context based on Kind and Key values.</td></tr>
+<tr><td valign="top"><a href="#get_key-2">get_key/2</a></td><td>Get the key for the specified context kind.</td></tr>
+<tr><td valign="top"><a href="#get_kinds-1">get_kinds/1</a></td><td>Get all the kinds in the specified context.</td></tr>
+<tr><td valign="top"><a href="#is_valid-2">is_valid/2</a></td><td>Verify a context is valid.</td></tr>
+<tr><td valign="top"><a href="#new-1">new/1</a></td><td>Create a new 'user' context with the specified key.</td></tr>
+<tr><td valign="top"><a href="#new-2">new/2</a></td><td>Create a new context with the specified key and kind.</td></tr>
+<tr><td valign="top"><a href="#new_from_json-1">new_from_json/1</a></td><td>Parse a map created from the JSON representation of a context into an <a docgen-rel="seetype" docgen-href="ldclient_context#context/0" href="ldclient_context.html#type-context"><code>ldclient_context:context()</code></a>.</td></tr>
+<tr><td valign="top"><a href="#new_from_map-1">new_from_map/1</a></td><td>Create a context from a map.</td></tr>
+<tr><td valign="top"><a href="#new_from_user-1">new_from_user/1</a></td><td>Create a context from an <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a>.</td></tr>
+<tr><td valign="top"><a href="#new_multi_from-1">new_multi_from/1</a></td><td>Create a multi context from several multiple single kind contexts.</td></tr>
+<tr><td valign="top"><a href="#set-3">set/3</a></td><td>Set an attribute value with the specified key in a single kind context.</td></tr>
+<tr><td valign="top"><a href="#set-4">set/4</a></td><td>Set an attribute value in the specified context kind with the specified key.</td></tr>
+<tr><td valign="top"><a href="#set_private_attributes-2">set_private_attributes/2</a></td><td>Set private attributes for a single kind context.</td></tr>
+<tr><td valign="top"><a href="#set_private_attributes-3">set_private_attributes/3</a></td><td>Set private attributes for the specified context kind.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="get-3">get/3</a></h3>
+<div class="spec">
+<p><tt>get(ContextKind::<a href="#type-kind_value">kind_value()</a>, AttributeReference::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_attribute_reference.html#type-attribute_reference">ldclient_attribute_reference:attribute_reference()</a> | binary(), Context::<a href="#type-context">context()</a>) -&gt; <a href="#type-attribute_value">attribute_value()</a> | null</tt><br></p>
+<p> </p>
+</div><p><p>Get an attribute value from the specified context kind by the specified attribute reference</p>
+ 
+  <p>If the context is a single kind context, and the ContextKind matches the context's kind, and the context contains  
+the specified attribute, then that value will be provided.</p>
+ 
+  <p>If the context is a multi-context, and it contains the specified context kind, and that context kind contains  
+the specified attribute, then that value will be provided.</p>
+ 
+  If the attribute value does not exist, then the null atom will be returned.</p>
+
+<h3 class="function"><a name="get_canonical_key-1">get_canonical_key/1</a></h3>
+<div class="spec">
+<p><tt>get_canonical_key(Context::<a href="#type-context">context()</a>) -&gt; binary()</tt><br></p>
+<p> </p>
+</div><p><p>A string that describes the entire Context based on Kind and Key values.</p>
+ 
+  This value is used whenever LaunchDarkly needs a string identifier based on all of the Kind and
+  Key values in the context; the SDK may use this for caching previously seen contexts, for instance.</p>
+
+<h3 class="function"><a name="get_key-2">get_key/2</a></h3>
+<div class="spec">
+<p><tt>get_key(ContextKind::<a href="#type-kind_value">kind_value()</a>, Context::<a href="#type-context">context()</a>) -&gt; binary() | null</tt><br></p>
+<p> </p>
+</div><p><p>Get the key for the specified context kind.</p>
+ 
+  <p>If the context is of a single kind, and it does not match the specified context kind, then null will be returned.</p>
+ 
+  If the context is a multi-context, and does not contain the specified kind, then null will be returned.</p>
+
+<h3 class="function"><a name="get_kinds-1">get_kinds/1</a></h3>
+<div class="spec">
+<p><tt>get_kinds(Context::<a href="#type-context">context()</a>) -&gt; [binary()]</tt><br></p>
+<p> </p>
+</div><p><p>Get all the kinds in the specified context. Can be a single or multi context.</p>
+ 
+  The kind in the context may be an atom or a binary, but this will always return them as binaries for use
+  in comparison against strings from LaunchDarkly.</p>
+
+<h3 class="function"><a name="is_valid-2">is_valid/2</a></h3>
+<div class="spec">
+<p><tt>is_valid(Context::<a href="#type-context">context()</a>, AllowEmptyKey::boolean()) -&gt; boolean()</tt><br></p>
+<p> </p>
+</div><p><p>Verify a context is valid.</p>
+ 
+  <p>This will ensure that the context, or contexts of a multi context, have:</p>
+ 
+  <p>1.) Valid keys. Key must exist, must be a binary, and cannot be empty.
+      An exception is made for contexts created from an <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a>.</p>
+ 
+  <p>2.) Valid kind. Kind must exist, must be a binary, and must be composed of ASCII letters, numbers, as well as
+      '-', '.', and '_'. A context created from a <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a> will have a <code>&lt;&lt;"user"&gt;&gt;</code> kind.</p>
+ 
+  <p>3.) All parts of a multi context meet #1 and #2.</p>
+ 
+  <p>Other aspects of the context may be invalid, and evaluation will proceed, but those invalid  
+parts will not impact the evaluation. For example an attribute with an atom() key will not successfully targeted  
+by rules. Some of these issues can be avoided by using the new_from_map function which will convert keys.</p>
+ 
+  Evaluations which are done against an invalid context will return default values with a reason
+  of user_not_specified.</p>
+
+<h3 class="function"><a name="new-1">new/1</a></h3>
+<div class="spec">
+<p><tt>new(Key::binary()) -&gt; <a href="#type-single_context">single_context()</a></tt><br></p>
+<p> </p>
+</div><p>Create a new 'user' context with the specified key.
+ </p>
+
+<h3 class="function"><a name="new-2">new/2</a></h3>
+<div class="spec">
+<p><tt>new(Key::binary(), Kind::<a href="#type-kind_value">kind_value()</a>) -&gt; <a href="#type-single_context">single_context()</a></tt><br></p>
+<p> </p>
+</div><p>Create a new context with the specified key and kind.
+ </p>
+
+<h3 class="function"><a name="new_from_json-1">new_from_json/1</a></h3>
+<div class="spec">
+<p><tt>new_from_json(JsonMap::map()) -&gt; <a href="#type-context">context()</a> | undefined</tt><br></p>
+<p> </p>
+</div><p><p>Parse a map created from the JSON representation of a context into an <a docgen-rel="seetype" docgen-href="ldclient_context#context/0" href="ldclient_context.html#type-context"><code>ldclient_context:context()</code></a>.</p>
+ 
+  If the map cannot be parsed into a context, then <code>undefined</code> will be returned.</p>
+
+<h3 class="function"><a name="new_from_map-1">new_from_map/1</a></h3>
+<div class="spec">
+<p><tt>new_from_map(MapContext::map()) -&gt; Context::<a href="#type-context">context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Create a context from a map.</p>
+ 
+  <p>Using this method will help to ensure that all your context keys and values are of supported types. For instance  
+converting all atom() keys into binary() (both for attribute keys and kinds). This can be useful for contexts  
+from a serialized source.</p>
+ 
+  <p>If the map contains a 'kind' attribute, then the resulting context will be of that kind.
+  If the map contains a 'kind' attribute, with the value of <code>&lt;&lt;"multi"&gt;&gt;</code>, then a multi context will be created,  
+and each top level field in the map will be a component of that context.</p>
+ 
+  <p>If the input map contains invalid data, such as bad kinds, then the context will still be created.  
+If the context contains invalid data, then evaluations will return default values with a reason of  
+'user_not_specified'.</p>
+ 
+  The same key should not be provided in the map as both an atom and a binary. For instance:
+  <pre>  #{key =&gt; &lt;&lt;"the-key"&gt;&gt;, &lt;&lt;"key"&gt;&gt; =&gt; &lt;&lt;"the-key"&gt;&gt;}</pre>
+ 
+  Create a context without a kind specified:
+  <pre>  ldclient_context:new_from_map(#{
+      key =&gt; &lt;&lt;"my-key"&gt;&gt;,
+      attributes =&gt; #{
+          nested =&gt; #{
+              deeper =&gt; #{
+                  value =&gt; &lt;&lt;"my-value"&gt;&gt;
+              }
+          }
+      }
+  }).
+  Produces the context
+  #{
+      key := &lt;&lt;"my-key"&gt;&gt;,
+      kind := &lt;&lt;"user"&gt;&gt;,
+      attributes := #{
+          &lt;&lt;"nested"&gt;&gt; := #{
+              &lt;&lt;"deeper"&gt;&gt; := #{
+                  &lt;&lt;"value"&gt;&gt; := &lt;&lt;"my-value"&gt;&gt;
+              }
+          }
+      }
+  }.
+  No kind was included, so it was defaulted to a &lt;&lt;"user"&gt;&gt; kind.
+  Notice that all the keys, and nested keys, within attributes have been converted to binaries.</pre>
+ 
+  Creating a context with a specified kind.
+  <pre>     ldclient_context:new_from_map(#{&lt;&lt;"key"&gt;&gt; =&gt; &lt;&lt;"my-key"&gt;&gt;, &lt;&lt;"kind"&gt;&gt; =&gt; &lt;&lt;"the-kind"&gt;&gt;}).
+  Produces the context
+  {key := &lt;&lt;"my-key"&gt;&gt;, kind := &lt;&lt;"the-kind"&gt;&gt;}.
+  Notice here how the built-in keys have been corrected to atoms.</pre>
+ 
+  <pre>  ldclient_context:new_from_map(#{
+      kind =&gt; &lt;&lt;"multi"&gt;&gt;,
+      &lt;&lt;"meal"&gt;&gt; =&gt; #{
+          key =&gt; &lt;&lt;"user-key"&gt;&gt;,
+          &lt;&lt;"name"&gt;&gt; =&gt; &lt;&lt;"the-name"&gt;&gt;, %% Key that will become an atom.
+          attributes =&gt; #{
+              potato =&gt; #{ %% Key that will become a binary.
+                  &lt;&lt;"bacon"&gt;&gt; =&gt; true,
+                  &lt;&lt;"cheese"&gt;&gt; =&gt; true
+              }
+          }
+      },
+      &lt;&lt;"location"&gt;&gt; =&gt; #{
+          key =&gt; &lt;&lt;"location-key"&gt;&gt;
+      }
+  }).
+  Produces the context
+  #{
+     kind := &lt;&lt;"multi"&gt;&gt;,
+     &lt;&lt;"meal"&gt;&gt; := #{
+         key := &lt;&lt;"user-key"&gt;&gt;,
+         name := &lt;&lt;"the-name"&gt;&gt;,
+         attributes := #{
+             &lt;&lt;"potato"&gt;&gt; := #{
+                 &lt;&lt;"bacon"&gt;&gt; := true,
+                 &lt;&lt;"cheese"&gt;&gt; := true
+             }
+         }
+     },
+     &lt;&lt;"location"&gt;&gt; := #{
+         key := &lt;&lt;"location-key"&gt;&gt;
+     }
+  }</pre></p>
+
+<h3 class="function"><a name="new_from_user-1">new_from_user/1</a></h3>
+<div class="spec">
+<p><tt>new_from_user(User::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_user.html#type-user">ldclient_user:user()</a>) -&gt; <a href="#type-context">context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Create a context from an <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a>.</p>
+ 
+  <p>This function is primarily intended for use by the SDK. It will be used when calling variation methods with
+  <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a>. An <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a> is detected by the lack of kind.</p>
+ 
+  <p>Creating contexts directly, using <a docgen-rel="seemfa" docgen-href="ldclient_context#new/1" href="ldclient_context.html#new-1"><code>ldclient_context:new/1</code></a>, <a docgen-rel="seemfa" docgen-href="ldclient_context#new/2" href="ldclient_context.html#new-2"><code>ldclient_context:new/2</code></a>,
+  <a docgen-rel="seemfa" docgen-href="ldclient_context#new_from_map/1" href="ldclient_context.html#new_from_map-1"><code>ldclient_context:new_from_map/1</code></a>, or creating <a docgen-rel="seetype" docgen-href="#context/0" href="#type-context"><code>context()</code></a>, will avoid this conversion.</p>
+ 
+  The user needs to be a valid <a docgen-rel="seetype" docgen-href="ldclient_user#user/0" href="ldclient_user.html#type-user"><code>ldclient_user:user()</code></a>. A map can be converted to a user using
+  <a docgen-rel="seemfa" docgen-href="ldclient_user#new_from_map/1" href="ldclient_user.html#new_from_map-1"><code>ldclient_user:new_from_map/1</code></a>. If the user does not have at least a key, then an empty map
+  is returned and it will not validate. An invalid context will result in default values from variation methods.</p>
+
+<h3 class="function"><a name="new_multi_from-1">new_multi_from/1</a></h3>
+<div class="spec">
+<p><tt>new_multi_from(Contexts::[<a href="#type-single_context">single_context()</a>]) -&gt; <a href="#type-multi_context">multi_context()</a> | <a href="#type-single_context">single_context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Create a multi context from several multiple single kind contexts.</p>
+ 
+  <pre>  MyMultiContext = ldclient_context:new_multi_from([
+      ldclient_context:new(&lt;&lt;"user-key"&gt;&gt;), %% This defaults to a &lt;&lt;"user"&gt;&gt; kind.
+      ldclient_context:new(&lt;&lt;"org-key"&gt;&gt;, &lt;&lt;"org"&gt;&gt;)]).</pre>
+ 
+  <p>Each of the contexts being combined should have unique keys. If more than one context of the same kind is added,  
+then only a single context of the duplicated type will remain.</p>
+ 
+  If <code>new_from_multi</code> is called with a list containing a single context, then the single context will be returned.
+  A multi context should contain more than one kind.</p>
+
+<h3 class="function"><a name="set-3">set/3</a></h3>
+<div class="spec">
+<p><tt>set(AttributeKey::<a href="#type-attribute_key">attribute_key()</a>, AttributeValue::<a href="#type-attribute_value">attribute_value()</a>, Context::<a href="#type-single_context">single_context()</a>) -&gt; <a href="#type-single_context">single_context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Set an attribute value with the specified key in a single kind context.</p>
+ 
+  <p>This method cannot be used to set attributes in nested maps.</p>
+ 
+  <p>Any built-in attributes private_attributes, anonymous, key, kind, will be set at the top level of the context.  
+Any attributes that are not built-ins will be set in an 'attributes' map.</p>
+ 
+  Attempting to set 'attributes' will result in an attribute named <code>&lt;&lt;"attributes"&gt;&gt;</code>.</p>
+
+<h3 class="function"><a name="set-4">set/4</a></h3>
+<div class="spec">
+<p><tt>set(ContextKind::<a href="#type-kind_value">kind_value()</a>, AttributeKey::<a href="#type-attribute_key">attribute_key()</a>, AttributeValue::<a href="#type-attribute_value">attribute_value()</a>, Context::<a href="#type-context">context()</a>) -&gt; <a href="#type-multi_context">multi_context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Set an attribute value in the specified context kind with the specified key.</p>
+ 
+  <p>If the context is a single kind, then it must be of the kind specified.</p>
+ 
+  <p>If it is a multi context, then specified kind must exist in it.</p>
+ 
+  This method cannot be used to set attributes in nested maps.</p>
+
+<h3 class="function"><a name="set_private_attributes-2">set_private_attributes/2</a></h3>
+<div class="spec">
+<p><tt>set_private_attributes(AttributeValues::[binary()], Context::<a href="#type-single_context">single_context()</a>) -&gt; <a href="#type-single_context">single_context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Set private attributes for a single kind context.</p>
+ 
+  <p>Designate any number of Context attributes, or properties within them, as private: that is,  
+their values will not be sent to LaunchDarkly.</p>
+ 
+  <p>Each parameter can be a simple attribute name, such as "email". Or, if the first character is  
+a slash, the parameter is interpreted as a slash-delimited path to a property within a JSON  
+object, where the first path component is a Context attribute name and each following  
+component is a nested property name: for example, suppose the attribute "address" had the  
+following value</p>
+ 
+  <pre>  	#{&lt;&lt;"street"&gt;&gt;: #{&lt;&lt;"line1"&gt;&gt;: &lt;&lt;"abc"&gt;&gt;, &lt;&lt;"line2"&gt;&gt;: &lt;&lt;"def"&gt;&gt;}}</pre>
+ 
+  <p>Using ["/address/street/line1"] in this case would cause the "line1" property to be marked as  
+private. This syntax deliberately resembles JSON Pointer, but other JSON Pointer features  
+such as array indexing are not supported for Private.</p>
+ 
+  <p>This action only affects analytics events that involve this particular Context. To mark some  
+(or all) Context attributes as private for all users, use the overall configuration for the  
+SDK.</p>
+ 
+  <p>The attributes "kind" and "key", and the meta attributes (like private_attribute_names) cannot be made private.</p>
+ 
+  <p>In this example, firstName is marked as private, but lastName is not:</p>
+ 
+  <pre>  Context = #{
+      kind =&gt; &lt;&lt;"org"&gt;&gt;,
+      key =&gt; &lt;&lt;"my-key"&gt;&gt;,
+      private_attributes: [&lt;&lt;"firstName"&gt;&gt;],
+      attributes =&gt; #{
+          &lt;&lt;"firstName"&gt;&gt; =&gt; &lt;&lt;"Pierre"&gt;&gt;,
+          &lt;&lt;"lastName"&gt;&gt; =&gt; &lt;&lt;"Menard"&gt;&gt;
+      }
+  }.</pre>
+ 
+  This is a metadata property, rather than an attribute that can be addressed in evaluations:
+  that is, a rule clause that references the attribute name "private_attributes", will not use
+  this value, but instead will use whatever value (if any) you have set for that name with a
+  method such as set/3 or by including it in the attributes map.</p>
+
+<h3 class="function"><a name="set_private_attributes-3">set_private_attributes/3</a></h3>
+<div class="spec">
+<p><tt>set_private_attributes(ContextKind::<a href="#type-kind_value">kind_value()</a>, AttributeValues::[binary()], Context::<a href="#type-context">context()</a>) -&gt; <a href="#type-context">context()</a></tt><br></p>
+<p> </p>
+</div><p><p>Set private attributes for the specified context kind.</p>
+ 
+  Context can either be a single kind context of the specified kind or a multi context containing the kind.</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/ldclient_flagbuilder.html b/ldclient_flagbuilder.html
new file mode 100644
index 0000000..5f9fbff
--- /dev/null
+++ b/ldclient_flagbuilder.html
@@ -0,0 +1,382 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Module ldclient_flagbuilder</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module ldclient_flagbuilder</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Flagbuilder.
+
+
+<h2><a name="description">Description</a></h2>Flagbuilder
+ 
+<h2><a name="types">Data Types</a></h2>
+
+<h3 class="typedecl"><a name="type-flag_builder">flag_builder()</a></h3>
+<p><b>abstract datatype</b>: <tt>flag_builder()</tt></p>
+<p>  A builder for feature flag configurations to be used with <a docgen-rel="seeerl" docgen-href="ldclient_testdata" href="ldclient_testdata.html"><code>ldclient_testdata</code></a>.</p>
+
+<h3 class="typedecl"><a name="type-flag_rule_builder">flag_rule_builder()</a></h3>
+<p><b>abstract datatype</b>: <tt>flag_rule_builder()</tt></p>
+<p>  A builder for feature flag rules to be used with <a docgen-rel="seetype" docgen-href="#flag_builder/0" href="#type-flag_builder"><code>flag_builder()</code></a>.</p>
+
+<h3 class="typedecl"><a name="type-variation">variation()</a></h3>
+<p><tt>variation() = boolean() | non_neg_integer()</tt></p>
+
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#and_match-3">and_match/3</a></td><td>Adds another clause, using the "is one of" operator.</td></tr>
+<tr><td valign="top"><a href="#and_match-4">and_match/4</a></td><td>Adds another clause, using the "is one of" operator.</td></tr>
+<tr><td valign="top"><a href="#and_not_match-3">and_not_match/3</a></td><td>Adds another clause, using the "is not one of" operator.</td></tr>
+<tr><td valign="top"><a href="#and_not_match-4">and_not_match/4</a></td><td>Adds another clause, using the "is not one of" operator.</td></tr>
+<tr><td valign="top"><a href="#boolean_flag-1">boolean_flag/1</a></td><td>A shortcut for setting the flag to use the standard boolean configuration.</td></tr>
+<tr><td valign="top"><a href="#clear_rules-1">clear_rules/1</a></td><td>Removes any existing rules from the flag.</td></tr>
+<tr><td valign="top"><a href="#clear_targets-1">clear_targets/1</a></td><td>Removes any existing targets from the flag.</td></tr>
+<tr><td valign="top"><a href="#fallthrough_variation-2">fallthrough_variation/2</a></td><td>Specifies the fallthrough variation for a flag.</td></tr>
+<tr><td valign="top"><a href="#if_match-3">if_match/3</a></td><td>Starts defining a flag rule, using the "is one of" operator.</td></tr>
+<tr><td valign="top"><a href="#if_match-4">if_match/4</a></td><td>Starts defining a flag rule, using the "is one of" operator.</td></tr>
+<tr><td valign="top"><a href="#if_not_match-3">if_not_match/3</a></td><td>Starts defining a flag rule, using the "is not one of" operator.</td></tr>
+<tr><td valign="top"><a href="#if_not_match-4">if_not_match/4</a></td><td>Starts defining a flag rule, using the "is not one of" operator.</td></tr>
+<tr><td valign="top"><a href="#off_variation-2">off_variation/2</a></td><td>Specifies the off variation for a flag.</td></tr>
+<tr><td valign="top"><a href="#on-2">on/2</a></td><td>Sets targeting to be on or off for this flag.</td></tr>
+<tr><td valign="top"><a href="#then_return-2">then_return/2</a></td><td>Finishes defining the rule, specifying the result variation.</td></tr>
+<tr><td valign="top"><a href="#value_for_all-2">value_for_all/2</a></td><td>Sets the flag to always return the specified variation value for all contexts.</td></tr>
+<tr><td valign="top"><a href="#variation_for_all-2">variation_for_all/2</a></td><td>Sets the flag to always return the specified variation for all contexts.</td></tr>
+<tr><td valign="top"><a href="#variation_for_context-4">variation_for_context/4</a></td><td>Sets the flag to return the specified variation for a specific context kind and key when  
+targeting is on.</td></tr>
+<tr><td valign="top"><a href="#variations-2">variations/2</a></td><td>Sets the flag to always return the specified variation value for all contexts.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="and_match-3">and_match/3</a></h3>
+<div class="spec">
+<p><tt>and_match(ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], RuleBuilder::<a href="#type-flag_rule_builder">flag_rule_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>RuleBuilder</tt>: the rule builder to modify<br>
+</p>
+<p>returns: the modified rule builder</p>
+</div><p><p>Adds another clause, using the "is one of" operator. The kind of the context is implicitly "user"
+  for non-user contexts use <a docgen-rel="seemfa" docgen-href="#any_match/4" href="#any_match-4"><code>any_match/4</code></a>.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is "Patsy" and the  
+country is "gb":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:and_match(&lt;&lt;"country"&gt;&gt;, [&lt;&lt;"gb"&gt;&gt;],
+                    ldclient_flagbuilder:if_match(&lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Patsy"&gt;&gt;], Flag)),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="and_match-4">and_match/4</a></h3>
+<div class="spec">
+<p><tt>and_match(ContextKind::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-kind_value">ldclient_context:kind_value()</a>, ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], RuleBuilder::<a href="#type-flag_rule_builder">flag_rule_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>RuleBuilder</tt>: the rule builder to modify<br>
+</p>
+<p>returns: the modified rule builder</p>
+</div><p><p>Adds another clause, using the "is one of" operator. The kind of the context is implicitly "user"
+  for non-user contexts use <a docgen-rel="seemfa" docgen-href="#any_match/4" href="#any_match-4"><code>any_match/4</code></a>.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is "Patsy" and the  
+country is "gb":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:and_match(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"country"&gt;&gt;, [&lt;&lt;"gb"&gt;&gt;],
+                    ldclient_flagbuilder:if_match(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Patsy"&gt;&gt;], Flag)),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="and_not_match-3">and_not_match/3</a></h3>
+<div class="spec">
+<p><tt>and_not_match(ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], RuleBuilder::<a href="#type-flag_rule_builder">flag_rule_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>RuleBuilder</tt>: the rule builder to modify<br>
+</p>
+<p>returns: the modified rule builder</p>
+</div><p><p>Adds another clause, using the "is not one of" operator. The kind of the context is implicitly "user"
+  for non-user contexts use <a docgen-rel="seemfa" docgen-href="#any_match/4" href="#any_match-4"><code>any_match/4</code></a>.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is "Patsy" and the  
+country is not "gb":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:and_not_match(&lt;&lt;"country"&gt;&gt;, [&lt;&lt;"gb"&gt;&gt;],
+                    ldclient_flagbuilder:if_match(&lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Patsy"&gt;&gt;], Flag)),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="and_not_match-4">and_not_match/4</a></h3>
+<div class="spec">
+<p><tt>and_not_match(ContextKind::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-kind_value">ldclient_context:kind_value()</a>, ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], RuleBuilder::<a href="#type-flag_rule_builder">flag_rule_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>RuleBuilder</tt>: the rule builder to modify<br>
+</p>
+<p>returns: the modified rule builder</p>
+</div><p><p>Adds another clause, using the "is not one of" operator.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is "Patsy" and the  
+country is not "gb":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:and_not_match(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"country"&gt;&gt;, [&lt;&lt;"gb"&gt;&gt;],
+                    ldclient_flagbuilder:if_match(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Patsy"&gt;&gt;], Flag)),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="boolean_flag-1">boolean_flag/1</a></h3>
+<div class="spec">
+<p><tt>boolean_flag(FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>A shortcut for setting the flag to use the standard boolean configuration.</p>
+ 
+  This is the default for all new flags created with <a docgen-rel="seemfa" docgen-href="ldclient_testdata#flag/2" href="ldclient_testdata.html#flag-2"><code>ldclient_testdata:flag/2</code></a>.
+  The flag will have two variations, <code>true</code> and <code>false</code> (in that order); it will return
+  <code>false</code> whenever targeting is off, and <code>true</code> when targeting is on if no other
+  settings specify otherwise.
+ </p>
+
+<h3 class="function"><a name="clear_rules-1">clear_rules/1</a></h3>
+<div class="spec">
+<p><tt>clear_rules(FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Removes any existing rules from the flag.</p>
+ 
+  This undoes the effect of <a docgen-rel="seemfa" docgen-href="#if_match/3" href="#if_match-3"><code>if_match/3</code></a> and <a docgen-rel="seemfa" docgen-href="#if_not_match/3" href="#if_not_match-3"><code>if_not_match/3</code></a>.
+ </p>
+
+<h3 class="function"><a name="clear_targets-1">clear_targets/1</a></h3>
+<div class="spec">
+<p><tt>clear_targets(FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Removes any existing targets from the flag.</p>
+ 
+  This undoes the effect of <a docgen-rel="seemfa" docgen-href="#variation_for_context/4" href="#variation_for_context-4"><code>variation_for_context/4</code></a>.
+ </p>
+
+<h3 class="function"><a name="fallthrough_variation-2">fallthrough_variation/2</a></h3>
+<div class="spec">
+<p><tt>fallthrough_variation(Variation::<a href="#type-variation">variation()</a>, FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>Variation</tt>: <code>true</code>, <code>false</code>, or the index of the desired variation to return: 0 for the first, 1 for the second, etc.<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Specifies the fallthrough variation for a flag.</p>
+ 
+  <p>The fallthrough is the value that is returned if targeting is on  
+and the user was not matched by a more specific target or rule.</p>
+ 
+  If the flag was previously configured with other variations and a boolean variation is specified,
+  this also changes the flagbuilder to a boolean flag.
+ </p>
+
+<h3 class="function"><a name="if_match-3">if_match/3</a></h3>
+<div class="spec">
+<p><tt>if_match(ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: a <a docgen-rel="seetype" docgen-href="#flag_rule_builder/0" href="#type-flag_rule_builder"><code>flag_rule_builder()</code></a>; call <a docgen-rel="seemfa" docgen-href="#then_return/2" href="#then_return-2"><code>then_return/2</code></a> to finish the rule,
+           or add more tests with <a docgen-rel="seemfa" docgen-href="#and_match/4" href="#and_match-4"><code>and_match/4</code></a> or <a docgen-rel="seemfa" docgen-href="#and_not_match/4" href="#and_not_match-4"><code>and_not_match/4</code></a>.</p>
+</div><p><p>Starts defining a flag rule, using the "is one of" operator. The kind of the context is implicitly "user"
+  for non-user contexts use <a docgen-rel="seemfa" docgen-href="#if_match/4" href="#if_match-4"><code>if_match/4</code></a>.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is "Patsy" or "Edina":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:if_match(&lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Patsy"&gt;&gt;, &lt;&lt;"Edina"&gt;&gt;], Flag),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="if_match-4">if_match/4</a></h3>
+<div class="spec">
+<p><tt>if_match(ContextKind::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-kind_value">ldclient_context:kind_value()</a>, ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: a <a docgen-rel="seetype" docgen-href="#flag_rule_builder/0" href="#type-flag_rule_builder"><code>flag_rule_builder()</code></a>; call <a docgen-rel="seemfa" docgen-href="#then_return/2" href="#then_return-2"><code>then_return/2</code></a> to finish the rule,
+           or add more tests with <a docgen-rel="seemfa" docgen-href="#and_match/4" href="#and_match-4"><code>and_match/4</code></a> or <a docgen-rel="seemfa" docgen-href="#and_not_match/4" href="#and_not_match-4"><code>and_not_match/4</code></a>.</p>
+</div><p><p>Starts defining a flag rule, using the "is one of" operator.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is "Patsy" or "Edina":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:if_match(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Patsy"&gt;&gt;, &lt;&lt;"Edina"&gt;&gt;], Flag),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="if_not_match-3">if_not_match/3</a></h3>
+<div class="spec">
+<p><tt>if_not_match(ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: a <a docgen-rel="seetype" docgen-href="#flag_rule_builder/0" href="#type-flag_rule_builder"><code>flag_rule_builder()</code></a>; call <a docgen-rel="seemfa" docgen-href="#then_return/2" href="#then_return-2"><code>then_return/2</code></a> to finish the rule,
+           or add more tests with <a docgen-rel="seemfa" docgen-href="#and_match/4" href="#and_match-4"><code>and_match/4</code></a> or <a docgen-rel="seemfa" docgen-href="#and_not_match/4" href="#and_not_match-4"><code>and_not_match/4</code></a>.</p>
+</div><p><p>Starts defining a flag rule, using the "is not one of" operator. The kind of the context is implicitly
+  "user" for non-user contexts use <a docgen-rel="seemfa" docgen-href="#if_not_match/4" href="#if_not_match-4"><code>if_not_match/4</code></a>.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is neither "Saffron" nor "Bubble":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:if_not_match(&lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Saffron"&gt;&gt;, &lt;&lt;"Bubble"&gt;&gt;], Flag),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="if_not_match-4">if_not_match/4</a></h3>
+<div class="spec">
+<p><tt>if_not_match(ContextKind::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-kind_value">ldclient_context:kind_value()</a>, ContextAttribute::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-attribute_key">ldclient_context:attribute_key()</a>, Values::[term()], FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_rule_builder">flag_rule_builder()</a></tt><br></p>
+<p><tt>ContextAttribute</tt>: the context attribute to match against<br>
+<tt>Values</tt>: values to compare to<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: a <a docgen-rel="seetype" docgen-href="#flag_rule_builder/0" href="#type-flag_rule_builder"><code>flag_rule_builder()</code></a>; call <a docgen-rel="seemfa" docgen-href="#then_return/2" href="#then_return-2"><code>then_return/2</code></a> to finish the rule,
+           or add more tests with <a docgen-rel="seemfa" docgen-href="#and_match/4" href="#and_match-4"><code>and_match/4</code></a> or <a docgen-rel="seemfa" docgen-href="#and_not_match/4" href="#and_not_match-4"><code>and_not_match/4</code></a>.</p>
+</div><p><p>Starts defining a flag rule, using the "is not one of" operator.</p>
+ 
+  <p>For example, this creates a rule that returns <code>true</code> if the name is neither "Saffron" nor "Bubble":</p>
+ 
+  <pre>      {ok, Flag} = ldclient_testdata:flag(TestData, &lt;&lt;"flag"&gt;&gt;),
+      RuleBuilder = ldclient_flagbuilder:if_not_match(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"name"&gt;&gt;, [&lt;&lt;"Saffron"&gt;&gt;, &lt;&lt;"Bubble"&gt;&gt;], Flag),
+      UpdatedFlag = ldclient_flagbuilder:then_return(true, RuleBuilder),
+      ldclient_testdata:update(TestData, UpdatedFlag).</pre>
+ </p>
+
+<h3 class="function"><a name="off_variation-2">off_variation/2</a></h3>
+<div class="spec">
+<p><tt>off_variation(Variation::<a href="#type-variation">variation()</a>, FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>Variation</tt>: <code>true</code>, <code>false</code>, or the index of the desired variation to return: 0 for the first, 1 for the second, etc.<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Specifies the off variation for a flag.</p>
+ 
+  <p>The off variation is the value that is returned whenever targeting is off</p>
+ 
+  If the flag was previously configured with other variations and a boolean Variation is specified,
+  this also changes the FlagBuilder to a boolean flag.
+ </p>
+
+<h3 class="function"><a name="on-2">on/2</a></h3>
+<div class="spec">
+<p><tt>on(IsOn::boolean(), FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>IsOn</tt>: true if targeting should be on<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder
+ </p>
+</div><p><p>Sets targeting to be on or off for this flag.</p>
+ 
+  The effect of this depends on the rest of the flag configuration, just as it does on the
+  real LaunchDarkly dashboard. In the default configuration that you get from calling
+  <a docgen-rel="seemfa" docgen-href="ldclient_testdata#flag/2" href="ldclient_testdata.html#flag-2"><code>ldclient_testdata:flag/2</code></a> with a new flag key, the flag will return <code>false</code>
+  whenever targeting is off, and <code>true</code> when targeting is on.
+ </p>
+
+<h3 class="function"><a name="then_return-2">then_return/2</a></h3>
+<div class="spec">
+<p><tt>then_return(Variation::<a href="#type-variation">variation()</a>, RuleBuilder::<a href="#type-flag_rule_builder">flag_rule_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>Variation</tt>: <code>true</code>, <code>false</code>, or the index of the desired variation to return: 0 for the first, 1 for the second, etc.<br>
+<tt>RuleBuilder</tt>: the rule builder to use<br>
+</p>
+<p>returns: the modified flag builder that initially created this rule builder</p>
+</div><p><p>Finishes defining the rule, specifying the result variation.</p>
+ 
+  If the flag was previously configured with other variations and a boolean variation is specified,
+  this also changes the FlagBuilder to a boolean flag.
+ </p>
+
+<h3 class="function"><a name="value_for_all-2">value_for_all/2</a></h3>
+<div class="spec">
+<p><tt>value_for_all(Value::term(), FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>Value</tt>: the desired value to be returned for all contexts<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Sets the flag to always return the specified variation value for all contexts.</p>
+ 
+  The value may be of any JSON type, as defined by }. This method changes the
+  flag to have only a single variation, which is this value, and to return the same
+  variation regardless of whether targeting is on or off. Any existing targets or rules
+  are removed.
+ </p>
+
+<h3 class="function"><a name="variation_for_all-2">variation_for_all/2</a></h3>
+<div class="spec">
+<p><tt>variation_for_all(Variation::<a href="#type-variation">variation()</a>, FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>Variation</tt>: <code>true</code>, <code>false</code>, or the index of the desired variation to return: 0 for the first, 1 for the second, etc.<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Sets the flag to always return the specified variation for all contexts.</p>
+ 
+  <p>The variation is set, targeting is switched on, and any existing targets or rules are removed.  
+The fallthrough variation is set to the specified value.  
+The off variation is left unchanged.</p>
+ 
+  If the flag was previously configured with other variations and a boolean variation is specified,
+  this also changes the flagbuilder to a boolean flag.
+ </p>
+
+<h3 class="function"><a name="variation_for_context-4">variation_for_context/4</a></h3>
+<div class="spec">
+<p><tt>variation_for_context(Variation::<a href="#type-variation">variation()</a>, ContextKind::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_context.html#type-kind_value">ldclient_context:kind_value()</a>, ContextKey::binary(), FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>Variation</tt>: <code>true</code>, <code>false</code>, or the index of the desired variation to return: 0 for the first, 1 for the second, etc.<br>
+<tt>ContextKind</tt>: the kind of context to target<br>
+<tt>ContextKey</tt>: the key of the context to target<br>
+<tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Sets the flag to return the specified variation for a specific context kind and key when  
+targeting is on.</p>
+ 
+  <p>This has no effect when targeting is turned off for the flag.</p>
+ 
+  If the flag was previously configured with other variations and a boolean variation is specified,
+  this also changes the flagbuilder to a boolean flag.
+ </p>
+
+<h3 class="function"><a name="variations-2">variations/2</a></h3>
+<div class="spec">
+<p><tt>variations(Values::[<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_flag.html#type-variation_value">ldclient_flag:variation_value()</a>], FlagBuilder::<a href="#type-flag_builder">flag_builder()</a>) -&gt; <a href="#type-flag_builder">flag_builder()</a></tt><br></p>
+<p><tt>FlagBuilder</tt>: the flag builder to modify<br>
+</p>
+<p>returns: the modified builder</p>
+</div><p><p>Sets the flag to always return the specified variation value for all contexts.</p>
+ 
+  The value may be of any JSON type.
+  This method changes the flag to have only a single variation, which is this value,
+  and to return the same variation regardless of whether targeting is on or off.
+  Any existing targets or rules are removed.
+ </p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/ldclient_testdata.html b/ldclient_testdata.html
new file mode 100644
index 0000000..c89e123
--- /dev/null
+++ b/ldclient_testdata.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Module ldclient_testdata</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module ldclient_testdata</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>TestData  server.
+
+<p><b>Behaviours:</b> <a href="gen_server.html"><tt>gen_server</tt></a>.</p>
+
+<h2><a name="description">Description</a></h2><p>TestData  server</p>
+ 
+  <p>A mechanism for providing dynamically updatable feature flag state  
+in a simplified form to an SDK client in test scenarios.</p>
+ 
+  <p>Unlike the file data mechanism, this does not use any external resources.  
+It provides only the data that the application has put into it using  
+the update/2 function.</p>
+ 
+  <pre>     {ok, Flag} = ldclient_testdata:flag("flag-key-1"),
+     ldclient_testdata:update(ldclient_flagbuilder:variation_for_all(true, Flag)),
+ 
+     Options = #{
+         datasource =&gt; testdata,
+         send_events =&gt; false,
+         feature_store =&gt; ldclient_storage_map
+     },
+     ldclient:start_instance(SdkKey, Options),
+ 
+     %% flags can be updated at any time:
+     {ok, Flag2} = ldclient_testdata:flag("flag-key-2"),
+     UpdatedFlag2 = ldclient_flagbuilder:fallthrough_variation(false,
+                    ldclient_flagbuilder:variation_for_context(&lt;&lt;"user"&gt;&gt;, &lt;&lt;"some-user-key"&gt;&gt;, true, Flag2)),</pre>
+ 
+  <p>The above example uses a simple boolean flag, but more complex configurations
+  are possible using the functions in <a docgen-rel="seeerl" docgen-href="ldclient_flagbuilder" href="ldclient_flagbuilder.html"><code>ldclient_flagbuilder</code></a>.</p>
+ 
+  <a docgen-rel="seeerl" docgen-href="ldclient_flagbuilder" href="ldclient_flagbuilder.html"><code>ldclient_flagbuilder</code></a> supports many of the ways a flag can be configured
+  on the LaunchDarkly dashboard, but does not currently support
+  <ol>
+    <li>rule operators other than "in" and "not in", or</li>
+    <li>percentage rollouts.</li>
+  </ol>
+ 
+  If the same <code>ldclient_testdata</code> instance is used to configure multiple <code>ldclient_instance</code> instances, any changes made to the data will propagate to all of the instances
+ 
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#child_spec-2">child_spec/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#flag-1">flag/1</a></td><td>Creates or copies a <a docgen-rel="seetype" docgen-href="ldclient_flagbuilder#flag_builder/0" href="ldclient_flagbuilder.html#type-flag_builder"><code>ldclient_flagbuilder:flag_builder()</code></a>  
+for building a test flag configuration.</td></tr>
+<tr><td valign="top"><a href="#flag-2">flag/2</a></td><td>Creates or copies a <a docgen-rel="seetype" docgen-href="ldclient_flagbuilder#flag_builder/0" href="ldclient_flagbuilder.html#type-flag_builder"><code>ldclient_flagbuilder:flag_builder()</code></a>  
+for building a test flag configuration.</td></tr>
+<tr><td valign="top"><a href="#update-1">update/1</a></td><td>Updates the test data with the specified flag configuration.</td></tr>
+<tr><td valign="top"><a href="#update-2">update/2</a></td><td>Updates the test data with the specified flag configuration.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="child_spec-2">child_spec/2</a></h3>
+<div class="spec">
+<p><tt>child_spec(Tag::atom(), Args::[term()]) -&gt; <a href="http://www.erlang.org/edoc/doc/stdlib/doc/supervisor.html#type-child_spec">supervisor:child_spec()</a></tt><br></p>
+<p> </p>
+</div>
+
+<h3 class="function"><a name="flag-1">flag/1</a></h3>
+<div class="spec">
+<p><tt>flag(FlagKey::binary() | string()) -&gt; {ok, <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_flagbuilder.html#type-flag_builder">ldclient_flagbuilder:flag_builder()</a>}</tt><br></p>
+<p><tt>FlagKey</tt>: the flag key<br>
+</p>
+<p>returns: a flag configuration builder</p>
+</div><p><p>Creates or copies a <a docgen-rel="seetype" docgen-href="ldclient_flagbuilder#flag_builder/0" href="ldclient_flagbuilder.html#type-flag_builder"><code>ldclient_flagbuilder:flag_builder()</code></a>  
+for building a test flag configuration.</p>
+ 
+  <p>If this flag key has already been defined in this <code>ldclient_testdata</code> instance,  
+then the builder starts with the same configuration that was last provided for this flag.</p>
+ 
+  <p>Otherwise, it starts with a new default configuration in which the flag has <code>true</code>
+  and <code>false</code> variations, is <code>true</code> for all contexts when targeting is turned on and
+  <code>false</code> otherwise, and currently has targeting turned on.</p>
+ 
+  <p>You can change any of those properties, and provide more complex behavior,
+  using the functions in <a docgen-rel="seeerl" docgen-href="ldclient_flagbuilder" href="ldclient_flagbuilder.html"><code>ldclient_flagbuilder</code></a>.</p>
+ 
+  Once you have set the desired configuration, pass the builder to <a docgen-rel="seemfa" docgen-href="#update/2" href="#update-2"><code>update/2</code></a>.
+ </p>
+<p><b>See also:</b> <a href="#update-1">update/1</a>.</p>
+
+<h3 class="function"><a name="flag-2">flag/2</a></h3>
+<div class="spec">
+<p><tt>flag(Tag::atom() | pid(), FlagKey::binary()) -&gt; {ok, <a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_flagbuilder.html#type-flag_builder">ldclient_flagbuilder:flag_builder()</a>}</tt><br></p>
+<p><tt>Tag</tt>: the tag or pid of the <code>ldclient_testdata</code> instance<br>
+<tt>FlagKey</tt>: the flag key<br>
+</p>
+<p>returns: a flag configuration builder</p>
+</div><p><p>Creates or copies a <a docgen-rel="seetype" docgen-href="ldclient_flagbuilder#flag_builder/0" href="ldclient_flagbuilder.html#type-flag_builder"><code>ldclient_flagbuilder:flag_builder()</code></a>  
+for building a test flag configuration.</p>
+ 
+  <p>If this flag key has already been defined in this <code>ldclient_testdata</code> instance,  
+then the builder starts with the same configuration that was last provided for this flag.</p>
+ 
+  <p>Otherwise, it starts with a new default configuration in which the flag has <code>true</code>
+  and <code>false</code> variations, is <code>true</code> for all contexts when targeting is turned on and
+  <code>false</code> otherwise, and currently has targeting turned on.</p>
+ 
+  <p>You can change any of those properties, and provide more complex behavior,
+  using the functions in <a docgen-rel="seeerl" docgen-href="ldclient_flagbuilder" href="ldclient_flagbuilder.html"><code>ldclient_flagbuilder</code></a>.</p>
+ 
+  Once you have set the desired configuration, pass the builder to <a docgen-rel="seemfa" docgen-href="#update/2" href="#update-2"><code>update/2</code></a>.
+ </p>
+<p><b>See also:</b> <a href="#update-2">update/2</a>.</p>
+
+<h3 class="function"><a name="update-1">update/1</a></h3>
+<div class="spec">
+<p><tt>update(Flag::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_flagbuilder.html#type-flag_builder">ldclient_flagbuilder:flag_builder()</a>) -&gt; ok</tt><br></p>
+<p><tt>Flag</tt>: a flag configuration builder<br>
+</p>
+</div><p><p>Updates the test data with the specified flag configuration.</p>
+ 
+  This has the same effect as if a flag were added or modified on the LaunchDarkly dashboard.
+  It immediately propagates the flag change to any <code>ldclient_instance(s)</code> that you have
+  already configured to use this <code>ldclient_testdata</code>. If no <code>ldclient_instance</code> has
+  been started yet, it simply adds this flag to the test data which will be provided
+  to any <code>ldclient_instance</code> that you subsequently configure.
+ </p>
+<p><b>See also:</b> <a href="#flag-1">flag/1</a>.</p>
+
+<h3 class="function"><a name="update-2">update/2</a></h3>
+<div class="spec">
+<p><tt>update(Tag::atom() | pid(), Flag::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_flagbuilder.html#type-flag_builder">ldclient_flagbuilder:flag_builder()</a>) -&gt; ok</tt><br></p>
+<p><tt>Flag</tt>: a flag configuration builder<br>
+</p>
+</div><p><p>Updates the test data with the specified flag configuration.</p>
+ 
+  This has the same effect as if a flag were added or modified on the LaunchDarkly dashboard.
+  It immediately propagates the flag change to any <code>ldclient_instance(s)</code> that you have
+  already configured to use this <code>ldclient_testdata</code>. If no <code>ldclient_instance</code> has
+  been started yet, it simply adds this flag to the test data which will be provided
+  to any <code>ldclient_instance</code> that you subsequently configure.
+ </p>
+<p><b>See also:</b> <a href="#flag-2">flag/2</a>.</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/ldclient_user.html b/ldclient_user.html
new file mode 100644
index 0000000..727c972
--- /dev/null
+++ b/ldclient_user.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Module ldclient_user</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module ldclient_user</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>User data type.
+
+
+<h2><a name="description">Description</a></h2>User data type
+ 
+<h2><a name="types">Data Types</a></h2>
+
+<h3 class="typedecl"><a name="type-attribute">attribute()</a></h3>
+<p><tt>attribute() = binary() | atom()</tt></p>
+
+
+<h3 class="typedecl"><a name="type-custom_attributes">custom_attributes()</a></h3>
+<p><tt>custom_attributes() = #{binary() := any()}</tt></p>
+
+
+<h3 class="typedecl"><a name="type-key">key()</a></h3>
+<p><tt>key() = binary() | null</tt></p>
+
+
+<h3 class="typedecl"><a name="type-private_attribute_names">private_attribute_names()</a></h3>
+<p><tt>private_attribute_names() = [binary()]</tt></p>
+
+
+<h3 class="typedecl"><a name="type-user">user()</a></h3>
+<p><tt>user() = #{key := <a href="#type-key">key()</a>, ip =&gt; binary(), country =&gt; binary(), email =&gt; binary(), first_name =&gt; binary(), last_name =&gt; binary(), avatar =&gt; binary(), name =&gt; binary(), anonymous =&gt; boolean(), custom =&gt; <a href="#type-custom_attributes">custom_attributes()</a>, private_attribute_names =&gt; <a href="#type-private_attribute_names">private_attribute_names()</a>}</tt></p>
+
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#event_format-1">event_format/1</a></td><td>Formats a user for use in an event.</td></tr>
+<tr><td valign="top"><a href="#get-2">get/2</a></td><td>Get an attribute value of a user.</td></tr>
+<tr><td valign="top"><a href="#new-1">new/1</a></td><td></td></tr>
+<tr><td valign="top"><a href="#new_from_map-1">new_from_map/1</a></td><td></td></tr>
+<tr><td valign="top"><a href="#scrub-2">scrub/2</a></td><td>Scrub private attributes from user.</td></tr>
+<tr><td valign="top"><a href="#set-3">set/3</a></td><td>Set an attribute value for a user.</td></tr>
+<tr><td valign="top"><a href="#set_private_attribute_names-2">set_private_attribute_names/2</a></td><td>Sets a list of private attribute names for a user.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="event_format-1">event_format/1</a></h3>
+<div class="spec">
+<p><tt>event_format(User::<a href="#type-user">user()</a>) -&gt; <a href="#type-user">user()</a></tt><br></p>
+<p> </p>
+</div><p><p>Formats a user for use in an event.</p>
+ 
+  Returns the user with first_name and last_name attributes changed to firstName and
+  lastName so that LaunchDarkly can properly record user data.</p>
+
+<h3 class="function"><a name="get-2">get/2</a></h3>
+<div class="spec">
+<p><tt>get(Attribute::<a href="#type-attribute">attribute()</a>, User::<a href="#type-user">user()</a>) -&gt; term()</tt><br></p>
+<p> </p>
+</div><p><p>Get an attribute value of a user</p>
+ 
+  Lookup includes custom attributes. Returns <code>null</code> if attribute doesn't exist.</p>
+
+<h3 class="function"><a name="new-1">new/1</a></h3>
+<div class="spec">
+<p><tt>new(Key::<a href="#type-key">key()</a>) -&gt; <a href="#type-user">user()</a></tt><br></p>
+<p> </p>
+</div>
+
+<h3 class="function"><a name="new_from_map-1">new_from_map/1</a></h3>
+<div class="spec">
+<p><tt>new_from_map(Map::map()) -&gt; <a href="#type-user">user()</a></tt><br></p>
+<p> </p>
+</div>
+
+<h3 class="function"><a name="scrub-2">scrub/2</a></h3>
+<div class="spec">
+<p><tt>scrub(User::<a href="#type-user">user()</a>, GlobalPrivateAttributes::<a href="http://www.erlang.org/edoc/doc/ldclient/doc/ldclient_config.html#type-private_attributes">ldclient_config:private_attributes()</a>) -&gt; {<a href="#type-user">user()</a>, <a href="#type-private_attribute_names">private_attribute_names()</a>}</tt><br></p>
+<p> </p>
+</div><p><p>Scrub private attributes from user</p>
+ 
+  Returns the scrubbed user and the list of attributes that were actually
+  scrubbed.</p>
+
+<h3 class="function"><a name="set-3">set/3</a></h3>
+<div class="spec">
+<p><tt>set(Attribute::<a href="#type-attribute">attribute()</a>, Value::any(), User::<a href="#type-user">user()</a>) -&gt; <a href="#type-user">user()</a></tt><br></p>
+<p> </p>
+</div><p><p>Set an attribute value for a user</p>
+ 
+  Sets given attribute to given value and returns the new user. This function
+  can handle both built-in and custom user attributes.</p>
+
+<h3 class="function"><a name="set_private_attribute_names-2">set_private_attribute_names/2</a></h3>
+<div class="spec">
+<p><tt>set_private_attribute_names(AttributeNames::[<a href="#type-attribute">attribute()</a>], User::<a href="#type-user">user()</a>) -&gt; <a href="#type-user">user()</a></tt><br></p>
+<p> </p>
+</div><p><p>Sets a list of private attribute names for a user</p>
+ 
+  Any attributes that are on this list will not be sent to and indexed by
+  LaunchDarkly. However, they are still available for flag evaluations
+  performed by the SDK locally. This handles both built-in and custom
+  attributes. The built-in <code>key</code> attribute cannot be made private - it will
+  always be sent.</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/modules-frame.html b/modules-frame.html
new file mode 100644
index 0000000..2c7794b
--- /dev/null
+++ b/modules-frame.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The ldclient application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<h2 class="indextitle">Modules</h2>
+<table width="100%" border="0" summary="list of modules">
+<tr><td><a href="ldclient.html" target="overviewFrame" class="module">ldclient</a></td></tr>
+<tr><td><a href="ldclient_config.html" target="overviewFrame" class="module">ldclient_config</a></td></tr>
+<tr><td><a href="ldclient_context.html" target="overviewFrame" class="module">ldclient_context</a></td></tr>
+<tr><td><a href="ldclient_flagbuilder.html" target="overviewFrame" class="module">ldclient_flagbuilder</a></td></tr>
+<tr><td><a href="ldclient_testdata.html" target="overviewFrame" class="module">ldclient_testdata</a></td></tr>
+<tr><td><a href="ldclient_user.html" target="overviewFrame" class="module">ldclient_user</a></td></tr></table>
+</body>
+</html>
\ No newline at end of file
diff --git a/overview-summary.html b/overview-summary.html
new file mode 100644
index 0000000..57ca04d
--- /dev/null
+++ b/overview-summary.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>LaunchDarkly Server-Side SDK for Erlang/Elixir</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<h1>LaunchDarkly Server-Side SDK for Erlang/Elixir</h1>
+<p>LaunchDarkly is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster.</p>
+
+This version of the LaunchDarkly SDK is compatible with Erlang/OTP 21 or higher.
+<hr>
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc</i></p>
+</body>
+</html>
diff --git a/overview.edoc b/overview.edoc
new file mode 100644
index 0000000..24832a4
--- /dev/null
+++ b/overview.edoc
@@ -0,0 +1,4 @@
+@title LaunchDarkly Server-Side SDK for Erlang/Elixir
+@doc LaunchDarkly is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster.
+
+This version of the LaunchDarkly SDK is compatible with Erlang/OTP 21 or higher.
\ No newline at end of file
diff --git a/stylesheet.css b/stylesheet.css
new file mode 100644
index 0000000..ab170c0
--- /dev/null
+++ b/stylesheet.css
@@ -0,0 +1,55 @@
+/* standard EDoc style sheet */
+body {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+      	margin-left: .25in;
+       	margin-right: .2in;
+       	margin-top: 0.2in;
+       	margin-bottom: 0.2in;
+       	color: #000000;
+       	background-color: #ffffff;
+}
+h1,h2 {
+ 	margin-left: -0.2in;
+}
+div.navbar {
+	background-color: #add8e6;
+	padding: 0.2em;
+}
+h2.indextitle {
+	padding: 0.4em;
+	background-color: #add8e6;
+}
+h3.function,h3.typedecl {
+	background-color: #add8e6;
+ 	padding-left: 1em;
+}
+div.spec {
+ 	margin-left: 2em;
+	background-color: #eeeeee;
+}
+a.module {
+	text-decoration:none
+}
+a.module:hover {
+	background-color: #eeeeee;
+}
+ul.definitions {
+	list-style-type: none;
+}
+ul.index {
+	list-style-type: none;
+	background-color: #eeeeee;
+}
+
+/*
+ * Minor style tweaks
+ */
+ul {
+	list-style-type: square;
+}
+table {
+	border-collapse: collapse;
+}
+td {
+	padding: 3
+}