CINXE.COM
Sign In
<!DOCTYPE html> <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> <!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> <!--[if gt IE 9]><!--><html class="no-js" lang="en"><!--<![endif]--><head> <meta content='IE=edge' http-equiv='X-UA-Compatible'> <meta charset='utf-8'> <meta content='width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no' name='viewport'> <meta content='en' name='Content-Language'> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-57x57-3dc48b9be1873ac9bf6d580e7836e3e5.png" sizes="57x57" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-60x60-06b95deca3f378372b051ca8ea42cfbd.png" sizes="60x60" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-72x72-935ba702f9d3da9b4404aa2b797920e5.png" sizes="72x72" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-76x76-937dbc8b688db389b5b872c5ffdffe2d.png" sizes="76x76" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-114x114-9db66ed49dfe9c3ed799923955da36e2.png" sizes="114x114" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-120x120-3fd2359930103db35eb499036b81ba90.png" sizes="120x120" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-144x144-5bee791d2b53cc426eb14e7f6e40a024.png" sizes="144x144" /> <link rel="apple-touch-icon-precomposed" type="image/png" href="https://leanpub.com/assets/favicons/apple-touch-icon-152x152-af69d0ec0fe11cf82324b06ff9a56e3b.png" sizes="152x152" /> <link rel="icon" type="image/png" href="https://leanpub.com/assets/favicons/favicon-16x16-19545df363d1089bccdc59d17ee5b781.png" sizes="16x16" /> <link rel="icon" type="image/png" href="https://leanpub.com/assets/favicons/favicon-32x32-9a0898109481d6450269c966cdf6a2d7.png" sizes="32x32" /> <link rel="icon" type="image/png" href="https://leanpub.com/assets/favicons/favicon-96x96-98f4372a68f5617fc907b7bde8d94e05.png" sizes="96x96" /> <link rel="icon" type="image/png" href="https://leanpub.com/assets/favicons/favicon-128x128-bf73acc329429fbf555afe3b067aa2d6.png" sizes="128x128" /> <link rel="icon" type="image/png" href="https://leanpub.com/assets/favicons/favicon-196x196-24a71f1b4fb02600f635b59a116daf05.png" sizes="196x196" /> <meta content='Leanpub' name='application-name'> <meta content='#ffffff' name='msapplication-TileColor'> <meta content='favicons/mstile-144x144.png' name='msapplication-TileImage'> <meta content='favicons/mstile-150x150.png' name='msapplication-square150x150logo'> <meta content='favicons/mstile-310x150.png' name='msapplication-wide310x150logo'> <meta content='favicons/mstile-310x310.png' name='msapplication-square310x310logo'> <meta content='favicons/mstile-70x70.png' name='msapplication-square70x70logo'> <title>Sign In</title> <link href='//fonts.googleapis.com/' rel='dns-prefetch'> <script src='https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js'></script> <script> if (typeof WebFont !== 'undefined') { WebFont.load({ google: { families: [ 'Noto+Sans:ital,wght@0,400;0,700;1,400;1,700', 'Noto+Serif:ital,wght@0,400;0,700;1,400;1,700', 'Inter:wght@400;700', ] } }); } </script> <link rel="stylesheet" media="screen" href="https://leanpub.com/assets/font_awesome-bbab983f4954a5c7dd952efdd403ebe8.css" /> <link rel="stylesheet" media="all" href="https://leanpub.com/assets/application-48c8d5aa3156e22d7b7c0b588642be6d.css" /> <meta name="csrf-param" content="authenticity_token" /> <meta name="csrf-token" content="C3d5znOHJwDbb8AzPseQamk/Y2wPfj/ddZqFp5g2lt7pRvVqXtr09IpnJXxiyjRFW+xBnr4M5dAG5d7G5IHmnQ==" /> <script> var _rollbarConfig = { accessToken: "3d279f41d3804636adbbba833c2c0d2d", captureUncaught: true, captureUnhandledRejections: true, code_version: "37ccd27f", payload: { environment: "production" } }; // Rollbar Snippet !function(r){function o(n){if(e[n])return e[n].exports;var t=e[n]={exports:{},id:n,loaded:!1};return r[n].call(t.exports,t,t.exports,o),t.loaded=!0,t.exports}var e={};return o.m=r,o.c=e,o.p="",o(0)}([function(r,o,e){"use strict";var n=e(1),t=e(4);_rollbarConfig=_rollbarConfig||{},_rollbarConfig.rollbarJsUrl=_rollbarConfig.rollbarJsUrl||"https://cdnjs.cloudflare.com/ajax/libs/rollbar.js/2.5.2/rollbar.min.js",_rollbarConfig.async=void 0===_rollbarConfig.async||_rollbarConfig.async;var a=n.setupShim(window,_rollbarConfig),l=t(_rollbarConfig);window.rollbar=n.Rollbar,a.loadFull(window,document,!_rollbarConfig.async,_rollbarConfig,l)},function(r,o,e){"use strict";function n(r){return function(){try{return r.apply(this,arguments)}catch(r){try{console.error("[Rollbar]: Internal error",r)}catch(r){}}}}function t(r,o){this.options=r,this._rollbarOldOnError=null;var e=s++;this.shimId=function(){return e},"undefined"!=typeof window&&window._rollbarShims&&(window._rollbarShims[e]={handler:o,messages:[]})}function a(r,o){if(r){var e=o.globalAlias||"Rollbar";if("object"==typeof r[e])return r[e];r._rollbarShims={},r._rollbarWrappedError=null;var t=new p(o);return n(function(){o.captureUncaught&&(t._rollbarOldOnError=r.onerror,i.captureUncaughtExceptions(r,t,!0),i.wrapGlobals(r,t,!0)),o.captureUnhandledRejections&&i.captureUnhandledRejections(r,t,!0);var n=o.autoInstrument;return o.enabled!==!1&&(void 0===n||n===!0||"object"==typeof n&&n.network)&&r.addEventListener&&(r.addEventListener("load",t.captureLoad.bind(t)),r.addEventListener("DOMContentLoaded",t.captureDomContentLoaded.bind(t))),r[e]=t,t})()}}function l(r){return n(function(){var o=this,e=Array.prototype.slice.call(arguments,0),n={shim:o,method:r,args:e,ts:new Date};window._rollbarShims[this.shimId()].messages.push(n)})}var i=e(2),s=0,d=e(3),c=function(r,o){return new t(r,o)},p=function(r){return new d(c,r)};t.prototype.loadFull=function(r,o,e,t,a){var l=function(){var o;if(void 0===r._rollbarDidLoad){o=new Error("rollbar.js did not load");for(var e,n,t,l,i=0;e=r._rollbarShims[i++];)for(e=e.messages||[];n=e.shift();)for(t=n.args||[],i=0;i<t.length;++i)if(l=t[i],"function"==typeof l){l(o);break}}"function"==typeof a&&a(o)},i=!1,s=o.createElement("script"),d=o.getElementsByTagName("script")[0],c=d.parentNode;s.crossOrigin="",s.src=t.rollbarJsUrl,e||(s.async=!0),s.onload=s.onreadystatechange=n(function(){if(!(i||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){s.onload=s.onreadystatechange=null;try{c.removeChild(s)}catch(r){}i=!0,l()}}),c.insertBefore(s,d)},t.prototype.wrap=function(r,o,e){try{var n;if(n="function"==typeof o?o:function(){return o||{}},"function"!=typeof r)return r;if(r._isWrap)return r;if(!r._rollbar_wrapped&&(r._rollbar_wrapped=function(){e&&"function"==typeof e&&e.apply(this,arguments);try{return r.apply(this,arguments)}catch(e){var o=e;throw o&&("string"==typeof o&&(o=new String(o)),o._rollbarContext=n()||{},o._rollbarContext._wrappedSource=r.toString(),window._rollbarWrappedError=o),o}},r._rollbar_wrapped._isWrap=!0,r.hasOwnProperty))for(var t in r)r.hasOwnProperty(t)&&(r._rollbar_wrapped[t]=r[t]);return r._rollbar_wrapped}catch(o){return r}};for(var u="log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleUnhandledRejection,captureEvent,captureDomContentLoaded,captureLoad".split(","),f=0;f<u.length;++f)t.prototype[u[f]]=l(u[f]);r.exports={setupShim:a,Rollbar:p}},function(r,o){"use strict";function e(r,o,e){if(r){var t;if("function"==typeof o._rollbarOldOnError)t=o._rollbarOldOnError;else if(r.onerror){for(t=r.onerror;t._rollbarOldOnError;)t=t._rollbarOldOnError;o._rollbarOldOnError=t}var a=function(){var e=Array.prototype.slice.call(arguments,0);n(r,o,t,e)};e&&(a._rollbarOldOnError=t),r.onerror=a}}function n(r,o,e,n){r._rollbarWrappedError&&(n[4]||(n[4]=r._rollbarWrappedError),n[5]||(n[5]=r._rollbarWrappedError._rollbarContext),r._rollbarWrappedError=null),o.handleUncaughtException.apply(o,n),e&&e.apply(r,n)}function t(r,o,e){if(r){"function"==typeof r._rollbarURH&&r._rollbarURH.belongsToShim&&r.removeEventListener("unhandledrejection",r._rollbarURH);var n=function(r){var e,n,t;try{e=r.reason}catch(r){e=void 0}try{n=r.promise}catch(r){n="[unhandledrejection] error getting `promise` from event"}try{t=r.detail,!e&&t&&(e=t.reason,n=t.promise)}catch(r){}e||(e="[unhandledrejection] error getting `reason` from event"),o&&o.handleUnhandledRejection&&o.handleUnhandledRejection(e,n)};n.belongsToShim=e,r._rollbarURH=n,r.addEventListener("unhandledrejection",n)}}function a(r,o,e){if(r){var n,t,a="EventTarget,Window,Node,ApplicationCache,AudioTrackList,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload".split(",");for(n=0;n<a.length;++n)t=a[n],r[t]&&r[t].prototype&&l(o,r[t].prototype,e)}}function l(r,o,e){if(o.hasOwnProperty&&o.hasOwnProperty("addEventListener")){for(var n=o.addEventListener;n._rollbarOldAdd&&n.belongsToShim;)n=n._rollbarOldAdd;var t=function(o,e,t){n.call(this,o,r.wrap(e),t)};t._rollbarOldAdd=n,t.belongsToShim=e,o.addEventListener=t;for(var a=o.removeEventListener;a._rollbarOldRemove&&a.belongsToShim;)a=a._rollbarOldRemove;var l=function(r,o,e){a.call(this,r,o&&o._rollbar_wrapped||o,e)};l._rollbarOldRemove=a,l.belongsToShim=e,o.removeEventListener=l}}r.exports={captureUncaughtExceptions:e,captureUnhandledRejections:t,wrapGlobals:a}},function(r,o){"use strict";function e(r,o){this.impl=r(o,this),this.options=o,n(e.prototype)}function n(r){for(var o=function(r){return function(){var o=Array.prototype.slice.call(arguments,0);if(this.impl[r])return this.impl[r].apply(this.impl,o)}},e="log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleUnhandledRejection,_createItem,wrap,loadFull,shimId,captureEvent,captureDomContentLoaded,captureLoad".split(","),n=0;n<e.length;n++)r[e[n]]=o(e[n])}e.prototype._swapAndProcessMessages=function(r,o){this.impl=r(this.options);for(var e,n,t;e=o.shift();)n=e.method,t=e.args,this[n]&&"function"==typeof this[n]&&("captureDomContentLoaded"===n||"captureLoad"===n?this[n].apply(this,[t[0],e.ts]):this[n].apply(this,t));return this},r.exports=e},function(r,o){"use strict";r.exports=function(r){return function(o){if(!o&&!window._rollbarInitialized){r=r||{};for(var e,n,t=r.globalAlias||"Rollbar",a=window.rollbar,l=function(r){return new a(r)},i=0;e=window._rollbarShims[i++];)n||(n=e.handler),e.handler._swapAndProcessMessages(l,e.messages);window[t]=n,window._rollbarInitialized=!0}}}}]); // End Rollbar Snippet </script> <script src="https://www.google.com/recaptcha/api.js?render=6LdDCakUAAAAAEFI0Kyx_gg9t-G4r1mOWrIwFLd0"></script> <script src="https://leanpub.com/assets/modernizr-a38b94cc0625ba4488942166ee4d23a4.js"></script> <script src="//www.google.com/jsapi"></script> <script src="https://leanpub.com/assets/chartkick-ecf78465738cad825935037ff8bba32a.js"></script> <link rel="stylesheet" media="screen" href="https://leanpub.com/assets/stylesheets/header-bundle-fb6d3e1d0d42d8298f3a.css" /> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'G-XQK3X47PGQ', 'auto'); // Replace with your property ID. ga('require', 'ec'); // Visitor type parameters (only settable from non cached) ga('send', 'pageview'); </script> </head> <body id='sessions-login'> <div class='flash' id='js-flash-prototype'> <div class='flash__progress-bar'></div> <div class='container--large'> <div class='flash__message'></div> <div class='flash__close-icon'> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="25px" id="Layer_1" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" width="25px" xml:space="preserve"><path d="M437.5,386.6L306.9,256l130.6-130.6c14.1-14.1,14.1-36.8,0-50.9c-14.1-14.1-36.8-14.1-50.9,0L256,205.1L125.4,74.5 c-14.1-14.1-36.8-14.1-50.9,0c-14.1,14.1-14.1,36.8,0,50.9L205.1,256L74.5,386.6c-14.1,14.1-14.1,36.8,0,50.9 c14.1,14.1,36.8,14.1,50.9,0L256,306.9l130.6,130.6c14.1,14.1,36.8,14.1,50.9,0C451.5,423.4,451.5,400.6,437.5,386.6z"></path></svg> </div> </div> </div> <script type='text/javascript'> window.__menu_data__ = null window.__menuPath__ = null window.__hidesStoreContent__ = true </script> <div id='react-header-root'></div> <script> window.__BASE_URL__ = "https://leanpub.com/" </script> <script src="https://leanpub.com/assets/polyfill-bundle-f2bf261e3f0b57d19161.js"></script> <script src="https://leanpub.com/assets/header-bundle-fb6d3e1d0d42d8298f3a.js"></script> <div class='scroll-wrapper' id='scroll-wrapper'> <div class='main ruby-main'> <div class='container--very-small'> <form class="simple_form form--session" novalidate="novalidate" action="/session" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="zuNyjdKuKiS6S7bZUH/xS/PcqdsQqQHKzWjfaDlGxdcs0v4p//P50OtDU5YMclVkwQ+LKaHb28e+F4QJRfG1lA==" /><fieldset> <legend>Sign In</legend> <div class="control-group email optional session_email"><label class="email optional control-group__label" for="session_email">Email or Username</label><div class="control-group__control"><input class="string email optional control-group__input" placeholder="you@domain.com" type="email" name="session[email]" id="session_email" /></div></div> <div class="control-group password optional session_password"><label class="password optional control-group__label" for="session_password">Password</label><div class="control-group__control"><input class="password optional control-group__input" placeholder="********" type="password" name="session[password]" id="session_password" /></div></div> <div> <p class='hint'> This site is protected by reCAPTCHA and the Google <a rel='noopener noreferrer' target='_blank' href="https://policies.google.com/privacy">Privacy Policy</a> and <a rel='noopener noreferrer' href="https://policies.google.com/terms">Terms of Service</a> apply. </p> <script src="https://www.recaptcha.net/recaptcha/api.js?render=6LdDCakUAAAAAEFI0Kyx_gg9t-G4r1mOWrIwFLd0" ></script> <script> // Define function so that we can call it again later if we need to reset it // This executes reCAPTCHA and then calls our callback. function executeRecaptchaForSession() { grecaptcha.ready(function() { grecaptcha.execute('6LdDCakUAAAAAEFI0Kyx_gg9t-G4r1mOWrIwFLd0', {action: 'session'}).then(function(token) { setInputWithRecaptchaResponseTokenForSession('g-recaptcha-response-data-session', token) }); }); }; // Invoke immediately executeRecaptchaForSession() // Async variant so you can await this function from another async function (no need for // an explicit callback function then!) // Returns a Promise that resolves with the response token. async function executeRecaptchaForSessionAsync() { return new Promise((resolve, reject) => { grecaptcha.ready(async function() { resolve(await grecaptcha.execute('6LdDCakUAAAAAEFI0Kyx_gg9t-G4r1mOWrIwFLd0', {action: 'session'})) }); }) }; var setInputWithRecaptchaResponseTokenForSession = function(id, token) { var element = document.getElementById(id); element.value = token; } </script> <input type="hidden" name="g-recaptcha-response-data[session]" id="g-recaptcha-response-data-session" data-sitekey="6LdDCakUAAAAAEFI0Kyx_gg9t-G4r1mOWrIwFLd0" class="g-recaptcha g-recaptcha-response "/> </div> <input type="submit" name="commit" value="Sign In" class="btn--solid button--full-width" data-disable-with="Please wait…" /> </fieldset> <div class='form__footer'> <p> Don't like passwords? <a class="link--blue" href="/magic_sign_in">Send me a Magic Sign In Link</a> </p> <p> Trouble signing in? <a class="link--blue" href="/password_reset">Reset Your Password</a> </p> <p> No Leanpub account? <a class="link--blue" href="/sign_up">Create an Account</a> </p> <p class='hint'> By the way, you don't need to create an account ahead of time. We also create an account for you if you buy something or if you create a book or course, so please feel free to do that instead! </p> <p> <a class="link--blue" href="/">Browse Leanpub</a> </p> <p> <a class="link--blue" href="/bookstore?type=all">Search the Leanpub Store</a> </p> <p> <a class="link--blue" href="/create">Create a Book or Course</a> </p> </div> </form> </div> </div> <footer class='footer'> <div class='container--small'> <h1 class='footer-logo'> <a href="https://leanpub.com/"><img src="https://leanpub.com/assets/logos/logo-white-96-67-2x-cbf54f68046da93161c6375a4d74259d.png" alt="Logo white 96 67 2x" /> </a></h1> <h3 class='footer-slogan'>Publish Early, Publish Often</h3> <ul class='footer-list-break'> <li> <h5 class='footer-headings'>Path</h5> </li> <li class='footer-descriptions-top'>There are many paths, but the one you're on right now on Leanpub is:</li> <li class='path'> Login </li> </ul> <div class='footer-links'> <ul class='footer-list'> <ul class='footer-columns'> <li> <h5 class='footer-headings'>READERS</h5> </li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Newsletters</h5> </li> <li><a href="/newsletters">Weekly Sale</a></li> <li><a href="/newsletters">Monthly Sale</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Store</h5> </li> <li><a href="/">Home</a></li> <li><a href="/redeem">Redeem a Token</a></li> <li><a href="/bookstore/book?search">Search</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Support</h5> </li> <li><a href="https://help.leanpub.com/en/articles/3788293-the-leanpub-faq">Leanpub FAQ</a></li> <li><a href="https://help.leanpub.com/en/articles/4405350-leanpub-author-faq">Leanpub Author FAQ</a></li> <li><a href="https://help.leanpub.com/en/">Search our Help Center</a></li> <li><a href="https://help.leanpub.com/en/articles/110768-if-i-can-t-find-an-answer-to-my-question-in-this-help-center-what-should-i-do">How to Contact Us</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-headings'>FRONTMATTER PODCAST</h5> </li> <li><a href="/podcasts/featured">Featured Episode</a></li> <li><a href="/podcasts/frontmatter">Episode List</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-headings'>MEMBERSHIPS</h5> </li> <li><a href="/reader_memberships">Reader Memberships</a></li> <li><a href="/departmentmemberships">Department Reader Memberships</a></li> <li><a href="/author_memberships">Author Memberships</a></li> <li><a href="/membership">Your Membership</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-headings'>COMPANY</h5> </li> <li> <h5 class='footer-list-title'>About</h5> </li> <li><a href="/about">About Leanpub</a></li> <li><a href="/blog">Blog</a></li> <li><a href="/contact">Contact</a></li> <li><a href="/press">Press</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Essays</h5> </li> <li><a href="/ai_services">AI Services</a></li> <li><a href="/imagine_a_world">Imagine a world...</a></li> <li><a href="/manifesto">Manifesto</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>More</h5> </li> <li><a href="/partner_program">Partner Program</a></li> <li><a href="/causes">Causes</a></li> <li><a href="/accessibility">Accessibility</a></li> </ul> </ul> <ul class='footer-list'> <ul class='footer-columns'> <li> <h5 class='footer-headings'>AUTHORS</h5> </li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Write and Publish on Leanpub</h5> </li> <li><a href="/create/book">Create a Book</a></li> <li><a href="/author_dashboard/new_bundle">Create a Bundle</a></li> <li><a href="/create/course">Create a Course</a></li> <li><a href="/course_set_admin/leanpub/course_sets/new">Create a Track</a></li> <li><a href="/testimonials">Testimonials</a></li> <li><a href="/authors">Why Leanpub</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Services</h5> </li> <li><a href="/course_ai/buy">CourseAI</a></li> <li><a href="/translate_ai/buy">TranslateAI</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Author Newsletter</h5> </li> <li><a href="/newsletters">The Leanpub Author Update</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Author Support</h5> </li> <li><a href="https://help.leanpub.com/author-help">Author Help Center</a></li> <li><a href="https://community.leanpub.com/c/authors">Leanpub Authors Forum</a></li> <li><a href="https://leanpub.com/manual/read">The Leanpub Manual</a></li> <li><a href="/help/supported_languages">Supported Languages</a></li> <li><a href="https://leanpub.com/lfm/read">The LFM Manual</a></li> <li><a href="https://leanpub.com/markua/read">Markua Manual</a></li> <li><a href="/help/api">API Docs</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-list-title'>Organizations</h5> </li> <li><a href="/organizations">Learn More</a></li> <li><a href="/p/register">Sign Up</a></li> </ul> <ul class='footer-list-break'> <li> <h5 class='footer-headings'>LEGAL</h5> </li> <li><a href="/terms">Terms of Service</a></li> <li><a href="/takedown">Copyright Policy</a></li> <li><a href="/privacy">Privacy Policy</a></li> <li><a href="/refunds">Refund Policy</a></li> </ul> </ul> </div> <p class='footer-copyright'> * * * </p> <p class='footer-copyright'> Leanpub is copyright © 2010-2024 <a href="http://ruboss.com">Ruboss Technology Corp.</a><br/> All rights reserved. </p> <p class='footer-copyright'> This site is protected by reCAPTCHA<br/> and the Google <a rel='noopener noreferrer' target='_blank' href="https://policies.google.com/privacy">Privacy Policy</a> and <a rel='noopener noreferrer' target='_blank' href="https://policies.google.com/terms">Terms of Service</a> apply. </p> </div> </footer> <div id='react-modal'></div> </div> <div class='cookies-banner alert alert--info' style='display: none'> Leanpub requires cookies in order to provide you the best experience. <a class='dismiss link'>Dismiss</a> </div> <script type='text/javascript'> window.addEventListener('load', function() { var shouldShowCookies = document.cookie.indexOf('should_show_cookies') !== -1 if (shouldShowCookies) { var banner = document.querySelector('.cookies-banner') // IE < 9 check if (banner.style.removeProperty) { banner.style.removeProperty('display'); } else { banner.style.removeAttribute('display'); } document.querySelector('.cookies-banner').classList.add('shown') // Note that we have to use vanilla JS here because ujs (remote links) code doesn't live in the react app, and i don't // want to have to write this shit twice. document.querySelector('.cookies-banner .dismiss').addEventListener('click', function() { document.querySelector('.cookies-banner').remove() var xhr = new XMLHttpRequest() xhr.open("POST", "/api/v1/accepted_terms/dismiss_cookies", true); xhr.send() }) } }) </script> <script src="https://leanpub.com/assets/application-88e446d6bb15c5682db3fb765baa70b6.js"></script> <!-- Twitter universal website tag code --> <script> !function(e,t,n,s,u,a){e.twq||(s=e.twq=function(){s.exe?s.exe.apply(s,arguments):s.queue.push(arguments); },s.version='1.1',s.queue=[],u=t.createElement(n),u.async=!0,u.src='//static.ads-twitter.com/uwt.js', a=t.getElementsByTagName(n)[0],a.parentNode.insertBefore(u,a))}(window,document,'script'); // Insert Twitter Pixel ID and Standard Event data below twq('init','nw0pa'); twq('track','PageView'); </script> <!-- End Twitter universal website tag code --> </body></html>