jsPsych/7.2/plugins/sketchpad/index.html

2305 lines
58 KiB
HTML
Executable File

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://www.jspsych.org/7.2/plugins/sketchpad/">
<link rel="icon" href="../../img/jspsych-favicon.png">
<meta name="generator" content="mkdocs-1.2.3, mkdocs-material-8.2.5">
<title>sketchpad - jsPsych</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.2d9f7617.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.e6a45f82.min.css">
<meta name="theme-color" content="#4cae4f">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("../..",location),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-50563838-1","auto"),ga("set","anonymizeIp",!0),ga("send","pageview"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){var e;this.value&&(e=document.location.pathname,ga("send","pageview",e+"?q="+this.value))}),"undefined"!=typeof location$&&location$.subscribe(function(e){ga("send","pageview",e.pathname)})})</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
</head>
<body dir="ltr" data-md-color-scheme="" data-md-color-primary="green" data-md-color-accent="orange">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#sketchpad-plugin" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-component="outdated" hidden>
<aside class="md-banner md-banner--warning">
</aside>
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="jsPsych" class="md-header__button md-logo" aria-label="jsPsych" data-md-component="logo">
<img src="../../img/jspsych-logo-no-text-mono.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
jsPsych
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
sketchpad
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/jspsych/jsPsych/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
jspsych/jspsych
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="jsPsych" class="md-nav__button md-logo" aria-label="jsPsych" data-md-component="logo">
<img src="../../img/jspsych-logo-no-text-mono.svg" alt="logo">
</a>
jsPsych
</label>
<div class="md-nav__source">
<a href="https://github.com/jspsych/jsPsych/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
jspsych/jspsych
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
Introduction
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2" type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2">
Tutorials
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Tutorials" data-md-level="1">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Tutorials
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../tutorials/hello-world/" class="md-nav__link">
The Basics: Hello World
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorials/rt-task/" class="md-nav__link">
Demo Experiment: Simple Reaction Time Task
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorials/video-tutorials/" class="md-nav__link">
Video Tutorials
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3">
Overview
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Overview" data-md-level="1">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Overview
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../overview/timeline/" class="md-nav__link">
Creating an Experiment: The Timeline
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/plugins/" class="md-nav__link">
Plugins
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/extensions/" class="md-nav__link">
Extensions
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/dynamic-parameters/" class="md-nav__link">
Dynamic Parameters
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/style/" class="md-nav__link">
Controlling Visual Appearance
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/data/" class="md-nav__link">
Data Storage, Aggregation, and Manipulation
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/simulation/" class="md-nav__link">
Simulation Modes
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/running-experiments/" class="md-nav__link">
Running Experiments
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/experiment-options/" class="md-nav__link">
Experiment Settings
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/events/" class="md-nav__link">
Events
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/record-browser-interactions/" class="md-nav__link">
Record Browser Interactions
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/media-preloading/" class="md-nav__link">
Media Preloading
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/fullscreen/" class="md-nav__link">
Fullscreen Experiments
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/eye-tracking/" class="md-nav__link">
Eye Tracking
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/exclude-browser/" class="md-nav__link">
Exclude Participants Based on Browser Features
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/progress-bar/" class="md-nav__link">
Automatic Progress Bar
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/prolific/" class="md-nav__link">
Integrating with Prolific
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/mturk/" class="md-nav__link">
Integrating with Mechanical Turk
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/browser-device-support/" class="md-nav__link">
Browser and Device Support
</a>
</li>
<li class="md-nav__item">
<a href="../../overview/timing-accuracy/" class="md-nav__link">
Timing Accuracy
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4" type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4">
Reference
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Reference" data-md-level="1">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/jspsych/" class="md-nav__link">
jsPsych
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/jspsych-data/" class="md-nav__link">
jsPsych.data
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/jspsych-randomization/" class="md-nav__link">
jsPsych.randomization
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/jspsych-turk/" class="md-nav__link">
jsPsych.turk
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/jspsych-pluginAPI/" class="md-nav__link">
jsPsych.pluginAPI
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" checked>
<label class="md-nav__link" for="__nav_5">
Plugins
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Plugins" data-md-level="1">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Plugins
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../list-of-plugins/" class="md-nav__link">
List of Plugins
</a>
</li>
<li class="md-nav__item">
<a href="../animation/" class="md-nav__link">
animation
</a>
</li>
<li class="md-nav__item">
<a href="../audio-button-response/" class="md-nav__link">
audio-button-response
</a>
</li>
<li class="md-nav__item">
<a href="../audio-keyboard-response/" class="md-nav__link">
audio-keyboard-response
</a>
</li>
<li class="md-nav__item">
<a href="../audio-slider-response/" class="md-nav__link">
audio-slider-response
</a>
</li>
<li class="md-nav__item">
<a href="../browser-check/" class="md-nav__link">
browser-check
</a>
</li>
<li class="md-nav__item">
<a href="../call-function/" class="md-nav__link">
call-function
</a>
</li>
<li class="md-nav__item">
<a href="../canvas-button-response/" class="md-nav__link">
canvas-button-response
</a>
</li>
<li class="md-nav__item">
<a href="../canvas-keyboard-response/" class="md-nav__link">
canvas-keyboard-response
</a>
</li>
<li class="md-nav__item">
<a href="../canvas-slider-response/" class="md-nav__link">
canvas-slider-response
</a>
</li>
<li class="md-nav__item">
<a href="../categorize-animation/" class="md-nav__link">
categorize-animation
</a>
</li>
<li class="md-nav__item">
<a href="../categorize-html/" class="md-nav__link">
categorize-html
</a>
</li>
<li class="md-nav__item">
<a href="../categorize-image/" class="md-nav__link">
categorize-image
</a>
</li>
<li class="md-nav__item">
<a href="../cloze/" class="md-nav__link">
cloze
</a>
</li>
<li class="md-nav__item">
<a href="../external-html/" class="md-nav__link">
external-html
</a>
</li>
<li class="md-nav__item">
<a href="../free-sort/" class="md-nav__link">
free-sort
</a>
</li>
<li class="md-nav__item">
<a href="../fullscreen/" class="md-nav__link">
fullscreen
</a>
</li>
<li class="md-nav__item">
<a href="../html-audio-response/" class="md-nav__link">
html-audio-response
</a>
</li>
<li class="md-nav__item">
<a href="../html-button-response/" class="md-nav__link">
html-button-response
</a>
</li>
<li class="md-nav__item">
<a href="../html-keyboard-response/" class="md-nav__link">
html-keyboard-response
</a>
</li>
<li class="md-nav__item">
<a href="../html-slider-response/" class="md-nav__link">
html-slider-response
</a>
</li>
<li class="md-nav__item">
<a href="../iat-html/" class="md-nav__link">
iat-html
</a>
</li>
<li class="md-nav__item">
<a href="../iat-image/" class="md-nav__link">
iat-image
</a>
</li>
<li class="md-nav__item">
<a href="../image-button-response/" class="md-nav__link">
image-button-response
</a>
</li>
<li class="md-nav__item">
<a href="../image-keyboard-response/" class="md-nav__link">
image-keyboard-response
</a>
</li>
<li class="md-nav__item">
<a href="../image-slider-response/" class="md-nav__link">
image-slider-response
</a>
</li>
<li class="md-nav__item">
<a href="../initialize-microphone/" class="md-nav__link">
initialize-microphone
</a>
</li>
<li class="md-nav__item">
<a href="../instructions/" class="md-nav__link">
instructions
</a>
</li>
<li class="md-nav__item">
<a href="../maxdiff/" class="md-nav__link">
maxdiff
</a>
</li>
<li class="md-nav__item">
<a href="../preload/" class="md-nav__link">
preload
</a>
</li>
<li class="md-nav__item">
<a href="../reconstruction/" class="md-nav__link">
reconstruction
</a>
</li>
<li class="md-nav__item">
<a href="../resize/" class="md-nav__link">
resize
</a>
</li>
<li class="md-nav__item">
<a href="../same-different-html/" class="md-nav__link">
same-different-html
</a>
</li>
<li class="md-nav__item">
<a href="../same-different-image/" class="md-nav__link">
same-different-image
</a>
</li>
<li class="md-nav__item">
<a href="../serial-reaction-time/" class="md-nav__link">
serial-reaction-time
</a>
</li>
<li class="md-nav__item">
<a href="../serial-reaction-time-mouse/" class="md-nav__link">
serial-reaction-time-mouse
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
sketchpad
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
sketchpad
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#parameters" class="md-nav__link">
Parameters
</a>
</li>
<li class="md-nav__item">
<a href="#data-generated" class="md-nav__link">
Data Generated
</a>
</li>
<li class="md-nav__item">
<a href="#simulation-mode" class="md-nav__link">
Simulation Mode
</a>
</li>
<li class="md-nav__item">
<a href="#examples" class="md-nav__link">
Examples
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../survey/" class="md-nav__link">
survey
</a>
</li>
<li class="md-nav__item">
<a href="../survey-html-form/" class="md-nav__link">
survey-html-form
</a>
</li>
<li class="md-nav__item">
<a href="../survey-likert/" class="md-nav__link">
survey-likert
</a>
</li>
<li class="md-nav__item">
<a href="../survey-multi-choice/" class="md-nav__link">
survey-multi-choice
</a>
</li>
<li class="md-nav__item">
<a href="../survey-multi-select/" class="md-nav__link">
survey-multi-select
</a>
</li>
<li class="md-nav__item">
<a href="../survey-text/" class="md-nav__link">
survey-text
</a>
</li>
<li class="md-nav__item">
<a href="../video-button-response/" class="md-nav__link">
video-button-response
</a>
</li>
<li class="md-nav__item">
<a href="../video-keyboard-response/" class="md-nav__link">
video-keyboard-response
</a>
</li>
<li class="md-nav__item">
<a href="../video-slider-response/" class="md-nav__link">
video-slider-response
</a>
</li>
<li class="md-nav__item">
<a href="../virtual-chinrest/" class="md-nav__link">
virtual-chinrest
</a>
</li>
<li class="md-nav__item">
<a href="../visual-search-circle/" class="md-nav__link">
visual-search-circle
</a>
</li>
<li class="md-nav__item">
<a href="../webgazer-calibrate/" class="md-nav__link">
webgazer-calibrate
</a>
</li>
<li class="md-nav__item">
<a href="../webgazer-init-camera/" class="md-nav__link">
webgazer-init-camera
</a>
</li>
<li class="md-nav__item">
<a href="../webgazer-validate/" class="md-nav__link">
webgazer-validate
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6">
Extensions
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Extensions" data-md-level="1">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Extensions
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../extensions/list-of-extensions/" class="md-nav__link">
List of Extensions
</a>
</li>
<li class="md-nav__item">
<a href="../../extensions/mouse-tracking/" class="md-nav__link">
mouse-tracking
</a>
</li>
<li class="md-nav__item">
<a href="../../extensions/webgazer/" class="md-nav__link">
webgazer
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7">
Developers
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Developers" data-md-level="1">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Developers
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../developers/configuration/" class="md-nav__link">
Configuration
</a>
</li>
<li class="md-nav__item">
<a href="../../developers/contributing/" class="md-nav__link">
Contributing to jsPsych
</a>
</li>
<li class="md-nav__item">
<a href="../../developers/plugin-development/" class="md-nav__link">
Plugin Development
</a>
</li>
<li class="md-nav__item">
<a href="../../developers/extension-development/" class="md-nav__link">
Extension Development
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_8" type="checkbox" id="__nav_8" >
<label class="md-nav__link" for="__nav_8">
Support
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Support" data-md-level="1">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
Support
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../support/support/" class="md-nav__link">
Getting Help
</a>
</li>
<li class="md-nav__item">
<a href="../../support/migration-v7/" class="md-nav__link">
Migrating from 6.x to 7.x
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_9" type="checkbox" id="__nav_9" >
<label class="md-nav__link" for="__nav_9">
About
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="About" data-md-level="1">
<label class="md-nav__title" for="__nav_9">
<span class="md-nav__icon md-icon"></span>
About
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../about/about/" class="md-nav__link">
About jsPsych
</a>
</li>
<li class="md-nav__item">
<a href="../../about/license/" class="md-nav__link">
License
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#parameters" class="md-nav__link">
Parameters
</a>
</li>
<li class="md-nav__item">
<a href="#data-generated" class="md-nav__link">
Data Generated
</a>
</li>
<li class="md-nav__item">
<a href="#simulation-mode" class="md-nav__link">
Simulation Mode
</a>
</li>
<li class="md-nav__item">
<a href="#examples" class="md-nav__link">
Examples
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/jspsych/jsPsych/edit/master/docs/plugins/sketchpad.md" title="Edit this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
</a>
<h1 id="sketchpad-plugin">sketchpad plugin<a class="headerlink" href="#sketchpad-plugin" title="Permanent link">&para;</a></h1>
<p>This plugin creates an interactive canvas that the participant can draw on using their mouse or touchscreen.
It can be used for sketching tasks, like asking the participant to draw a particular object.
It can also be used for some image segmentation or annotation tasks by setting the <code>background_image</code> parameter to render an image on the canvas.</p>
<p>The plugin stores a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs">base 64 data URL representation</a> of the final image.
This can be converted to an image file using <a href="https://www.google.com/search?q=base64+image+decoder">online tools</a> or short programs in <a href="https://stackoverflow.com/q/58604195/3726673">R</a>, <a href="https://stackoverflow.com/q/2323128/3726673">python</a>, or another language of your choice.
It also records all of the individual strokes that the participant made during the trial.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>This plugin generates <strong>a lot</strong> of data. Each trial can easily add 500kb+ of data to a final JSON output.
You can reduce the amount of data generated by turning off storage of the individual stroke data (<code>save_strokes: false</code>) or storage of the final image (<code>save_final_image: false</code>) if your use case doesn't require that information.
If you are going to be collecting a lot of data with this plugin you may want to save your data to your server after each trial and not wait until the end of the experiment to perform a single bulk upload.
You can do this by putting data saving code inside the <a href="../../overview/events/#on_data_update"><code>on_data_update</code> event handler</a>.</p>
</div>
<h2 id="parameters">Parameters<a class="headerlink" href="#parameters" title="Permanent link">&para;</a></h2>
<p>In addition to the <a href="../../overview/plugins/#parameters-available-in-all-plugins">parameters available in all plugins</a>, this plugin accepts the following parameters. </p>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Default Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>canvas_shape</td>
<td><code>"rectangle"</code> or <code>"circle"</code></td>
<td><code>"rectangle"</code></td>
<td>The shape of the canvas element.</td>
</tr>
<tr>
<td>canvas_width</td>
<td>int</td>
<td>500</td>
<td>Width of the canvas in pixels when <code>canvas_shape</code> is <code>"rectangle"</code></td>
</tr>
<tr>
<td>canvas_height</td>
<td>int</td>
<td>500</td>
<td>Height of the canvas in pixels when <code>canvas_shape</code> is <code>"rectangle"</code></td>
</tr>
<tr>
<td>canvas_diameter</td>
<td>int</td>
<td>500</td>
<td>Diameter of the canvas in pixels when <code>canvas_shape</code> is <code>"circle"</code></td>
</tr>
<tr>
<td>canvas_border_width</td>
<td>int</td>
<td>0</td>
<td>Width of the canvas border</td>
</tr>
<tr>
<td>canvas_border_color</td>
<td>string</td>
<td><code>"#000"</code></td>
<td>Color of the canvas border</td>
</tr>
<tr>
<td>background_image</td>
<td>image path</td>
<td><code>null</code></td>
<td>Path to an image to render as the background of the canvas</td>
</tr>
<tr>
<td>background_color</td>
<td>string</td>
<td><code>"#fff"</code></td>
<td>Color of the canvas background. Note that a <code>background_image</code> will render on top of the color.</td>
</tr>
<tr>
<td>stroke_width</td>
<td>int</td>
<td>2</td>
<td>Width of the stroke on the canvas</td>
</tr>
<tr>
<td>stroke_color</td>
<td>string</td>
<td><code>"#000"</code></td>
<td>Color of the stroke on the canvas</td>
</tr>
<tr>
<td>stroke_color_palette</td>
<td>array of strings</td>
<td><code>[]</code></td>
<td>Array of colors to render as a palette of choices for stroke color. Clicking on the corresponding color button will change the stroke color.</td>
</tr>
<tr>
<td>prompt</td>
<td>string</td>
<td>null</td>
<td>HTML content to render on the screen.</td>
</tr>
<tr>
<td>prompt_location</td>
<td><code>"abovecanvas"</code> or <code>"belowcanvas"</code> or <code>"belowbutton"</code></td>
<td><code>"abovecanvas"</code></td>
<td>The location to render the prompt content.</td>
</tr>
<tr>
<td>save_final_image</td>
<td>bool</td>
<td>true</td>
<td>Whether to save the final image in the data as a base64 encoded data URL.</td>
</tr>
<tr>
<td>save_strokes</td>
<td>bool</td>
<td>true</td>
<td>Whether to save the individual stroke data that generated the final image.</td>
</tr>
<tr>
<td>key_to_draw</td>
<td>key string</td>
<td>null</td>
<td>If this key is held down then it is like the mouse button being held down. The "ink" will flow when the button is held and stop when it is lifted. Pass in the string representation of the key, e.g., <code>'a'</code> for the A key or <code>' '</code> for the spacebar.</td>
</tr>
<tr>
<td>show_finished_button</td>
<td>bool</td>
<td>true</td>
<td>Whether to show the button that ends the trial.</td>
</tr>
<tr>
<td>finished_button_label</td>
<td>string</td>
<td><code>"Finished"</code></td>
<td>The label for the button that ends the trial.</td>
</tr>
<tr>
<td>show_clear_button</td>
<td>bool</td>
<td>true</td>
<td>Whether to show the button that clears the entire drawing.</td>
</tr>
<tr>
<td>clear_button_label</td>
<td>string</td>
<td><code>"Clear"</code></td>
<td>The label for the button that clears the entire drawing.</td>
</tr>
<tr>
<td>show_undo_button</td>
<td>bool</td>
<td>true</td>
<td>Whether to show the button that enables an undo action.</td>
</tr>
<tr>
<td>undo_button_label</td>
<td>string</td>
<td><code>"Undo"</code></td>
<td>The label for the button that enables an undo action.</td>
</tr>
<tr>
<td>show_redo_button</td>
<td>bool</td>
<td>true</td>
<td>Whether to show the button that enables a redo action. Note that <code>show_undo_button</code> must be <code>true</code> for the redo button to show up.</td>
</tr>
<tr>
<td>redo_button_label</td>
<td>string</td>
<td><code>"Redo"</code></td>
<td>The label for the button that enables a redo action.</td>
</tr>
<tr>
<td>choices</td>
<td>array of keys</td>
<td><code>"NO_KEYS"</code></td>
<td>This array contains the key(s) that the subject is allowed to press in order to end the trial. Keys should be specified as characters (e.g., <code>'a'</code>, <code>'q'</code>, <code>' '</code>, <code>'Enter'</code>, <code>'ArrowDown'</code>) - see <a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values">this page</a> and <a href="https://www.freecodecamp.org/news/javascript-keycode-list-keypress-event-key-codes/">this page (event.key column)</a> for more examples. Any key presses that are not listed in the array will be ignored. The default value of <code>"NO_KEYS"</code> means that no keys will be accepted as valid responses. Specifying <code>"ALL_KEYS"</code> will mean that all responses are allowed.</td>
</tr>
<tr>
<td>trial_duration</td>
<td>int</td>
<td>null</td>
<td>Length of time before the trial ends. If <code>null</code> the trial will continue indefinitely (until another way of ending the trial occurs).</td>
</tr>
<tr>
<td>show_countdown_trial_duration</td>
<td>bool</td>
<td>false</td>
<td>Whether to show a timer that counts down until the end of the trial when <code>trial_duration</code> is not <code>null</code>.</td>
</tr>
<tr>
<td>countdown_timer_html</td>
<td>string</td>
<td><code>'&lt;span id="sketchpad-timer"&gt;&lt;/span&gt; remaining'</code></td>
<td>The HTML to use for rendering the countdown timer. The element with <code>id="sketchpad-timer"</code> will have its content replaced by a countdown timer in the format <code>MM:SS</code>.</td>
</tr>
</tbody>
</table>
<h2 id="data-generated">Data Generated<a class="headerlink" href="#data-generated" title="Permanent link">&para;</a></h2>
<p>In addition to the <a href="../../overview/plugins/#data-collected-by-all-plugins">default data collected by all plugins</a>, this plugin collects the following data for each trial.</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>rt</td>
<td>int</td>
<td>The length of time from the start of the trial to the end of the trial.</td>
</tr>
<tr>
<td>response</td>
<td>string</td>
<td>If the trial was ended by clicking the finished button, then <code>"button"</code>. If the trial was ended by pressing a key, then the key that was pressed. If the trial timed out, then <code>null</code>.</td>
</tr>
<tr>
<td>png</td>
<td>base64 data URL string</td>
<td>If <code>save_image</code> is true, then this will contain the base64 encoded data URL for the image, in png format.</td>
</tr>
<tr>
<td>strokes</td>
<td>array of stroke objects</td>
<td>If <code>save_strokes</code> is true, then this will contain an array of stroke objects. Objects have an <code>action</code> property that is either <code>"start"</code>, <code>"move"</code>, or <code>"end"</code>. If <code>action</code> is <code>"start"</code> or <code>"move"</code> it will have an <code>x</code> and <code>y</code> property that report the coordinates of the action relative to the upper-left corner of the canvas. If <code>action</code> is <code>"start"</code> then the object will also have a <code>t</code> and <code>color</code> property, specifying the time of the action relative to the onset of the trial (ms) and the color of the stroke. If <code>action</code> is <code>"end"</code> then it will only have a <code>t</code> property.</td>
</tr>
</tbody>
</table>
<h2 id="simulation-mode">Simulation Mode<a class="headerlink" href="#simulation-mode" title="Permanent link">&para;</a></h2>
<p>This plugin does not yet support <a href="../../overview/simulation/">simulation mode</a>.</p>
<h2 id="examples">Examples<a class="headerlink" href="#examples" title="Permanent link">&para;</a></h2>
<details class="example" open="open">
<summary>Basic sketchpad with a prompt</summary>
<div class="tabbed-set" data-tabs="1:2"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><label for="__tabbed_1_1">Code</label><div class="tabbed-content">
<div class="highlight"><pre><span></span><code><span class="kd">var</span> <span class="nx">trial</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">type</span><span class="o">:</span> <span class="nx">jsPsychSketchpad</span><span class="p">,</span>
<span class="nx">prompt</span><span class="o">:</span> <span class="s1">&#39;&lt;p&gt;Draw an apple!&lt;/p&gt;&#39;</span><span class="p">,</span>
<span class="nx">prompt_location</span><span class="o">:</span> <span class="s1">&#39;abovecanvas&#39;</span><span class="p">,</span>
<span class="nx">canvas_width</span><span class="o">:</span> <span class="mf">300</span><span class="p">,</span>
<span class="nx">canvas_height</span><span class="o">:</span> <span class="mf">300</span><span class="p">,</span>
<span class="nx">canvas_border_width</span><span class="o">:</span> <span class="mf">2</span>
<span class="p">}</span>
</code></pre></div>
</div>
<input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><label for="__tabbed_1_2">Demo</label><div class="tabbed-content">
<p><div style="text-align:center;">
<iframe src="../../demos/jspsych-sketchpad-demo1.html" width="90%;" height="500px;" frameBorder="0"></iframe>
</div></p>
</div>
</div>
<p><a target="_blank" rel="noopener noreferrer" href="../../demos/jspsych-sketchpad-demo1.html">Open demo in new tab</a></p>
</details>
<details class="example" open="open">
<summary>Image segmentation with different colors</summary>
<div class="tabbed-set" data-tabs="2:2"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><label for="__tabbed_2_1">Code</label><div class="tabbed-content">
<div class="highlight"><pre><span></span><code><span class="kd">var</span> <span class="nx">trial</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">type</span><span class="o">:</span> <span class="nx">jsPsychSketchpad</span><span class="p">,</span>
<span class="nx">prompt</span><span class="o">:</span> <span class="s1">&#39;&lt;p style=&quot;width:380px&quot;&gt;Circle the mouth using red. Circle the eyes using blue.&lt;/p&gt;&#39;</span><span class="p">,</span>
<span class="nx">prompt_location</span><span class="o">:</span> <span class="s1">&#39;abovecanvas&#39;</span><span class="p">,</span>
<span class="nx">stroke_color_palette</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="s1">&#39;blue&#39;</span><span class="p">],</span>
<span class="nx">stroke_color</span><span class="o">:</span> <span class="s1">&#39;red&#39;</span><span class="p">,</span>
<span class="nx">background_image</span><span class="o">:</span> <span class="s1">&#39;img/sad_face_4.jpg&#39;</span><span class="p">,</span>
<span class="nx">canvas_width</span><span class="o">:</span> <span class="mf">380</span><span class="p">,</span>
<span class="nx">canvas_height</span><span class="o">:</span> <span class="mf">252</span>
<span class="p">}</span>
</code></pre></div>
</div>
<input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><label for="__tabbed_2_2">Demo</label><div class="tabbed-content">
<p><div style="text-align:center;">
<iframe src="../../demos/jspsych-sketchpad-demo2.html" width="90%;" height="500px;" frameBorder="0"></iframe>
</div></p>
</div>
</div>
<p><a target="_blank" rel="noopener noreferrer" href="../../demos/jspsych-sketchpad-demo2.html">Open demo in new tab</a></p>
</details>
<details class="example" open="open">
<summary>Draw an image in a time limit, then display the image and ask for a label.</summary>
<div class="tabbed-set" data-tabs="3:2"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><label for="__tabbed_3_1">Code</label><div class="tabbed-content">
<div class="highlight"><pre><span></span><code><span class="kd">var</span> <span class="nx">draw</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">type</span><span class="o">:</span> <span class="nx">jsPsychSketchpad</span><span class="p">,</span>
<span class="nx">prompt</span><span class="o">:</span> <span class="s1">&#39;&lt;p&gt;Draw the first animal that comes to mind. You have 30 seconds!&lt;/p&gt;&#39;</span><span class="p">,</span>
<span class="nx">prompt_location</span><span class="o">:</span> <span class="s1">&#39;belowcanvas&#39;</span><span class="p">,</span>
<span class="nx">trial_duration</span><span class="o">:</span> <span class="mf">30000</span><span class="p">,</span>
<span class="nx">show_countdown_trial_duration</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">label</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">type</span><span class="o">:</span> <span class="nx">jsPsychSurveyText</span><span class="p">,</span>
<span class="nx">preamble</span><span class="o">:</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">imageData</span> <span class="o">=</span> <span class="nx">jsPsych</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">get</span><span class="p">().</span><span class="nx">last</span><span class="p">(</span><span class="mf">1</span><span class="p">).</span><span class="nx">values</span><span class="p">()[</span><span class="mf">0</span><span class="p">].</span><span class="nx">png</span><span class="p">;</span>
<span class="k">return</span> <span class="sb">`&lt;img src=&quot;</span><span class="si">${</span><span class="nx">imageData</span><span class="si">}</span><span class="sb">&quot;&gt;&lt;/img&gt;`</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">questions</span><span class="o">:</span> <span class="p">[</span>
<span class="p">{</span><span class="nx">prompt</span><span class="o">:</span> <span class="s1">&#39;What animal did you draw?&#39;</span><span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
</div>
<input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><label for="__tabbed_3_2">Demo</label><div class="tabbed-content">
<p><div style="text-align:center;">
<iframe src="../../demos/jspsych-sketchpad-demo3.html" width="90%;" height="500px;" frameBorder="0"></iframe>
</div></p>
</div>
</div>
<p><a target="_blank" rel="noopener noreferrer" href="../../demos/jspsych-sketchpad-demo3.html">Open demo in new tab</a></p>
</details>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer">
<a href="../serial-reaction-time-mouse/" class="md-footer__link md-footer__link--prev" aria-label="Previous: serial-reaction-time-mouse" rel="prev">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</div>
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
Previous
</span>
serial-reaction-time-mouse
</div>
</div>
</a>
<a href="../survey/" class="md-footer__link md-footer__link--next" aria-label="Next: survey" rel="next">
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
Next
</span>
survey
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2012-2021 Josh de Leeuw
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-social">
<a href="https://github.com/jspsych" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</a>
<a href="https://twitter.com/joshdeleeuw" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing", "select.version.title": "Select version"}, "search": "../../assets/javascripts/workers/search.bd0b6b67.min.js", "version": {"provider": "mike"}}</script>
<script src="../../assets/javascripts/bundle.467223ff.min.js"></script>
</body>
</html>