### A Pluto.jl notebook ### # v0.19.9 #> [frontmatter] #> author_url = "https://github.com/JuliaPluto" #> image = "https://upload.wikimedia.org/wikipedia/commons/9/99/Unofficial_JavaScript_logo_2.svg" #> tags = ["javascript", "web", "classic"] #> author_name = "Pluto.jl" #> description = "Use HTML, CSS and JavaScript to make your own interactive visualizations!" #> license = "Unlicense" using Markdown using InteractiveUtils # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). macro bind(def, element) quote local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end local el = $(esc(element)) global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) el end end # ╔═╡ 571613a1-6b4b-496d-9a68-aac3f6a83a4b using PlutoUI, HypertextLiteral # ╔═╡ 97914842-76d2-11eb-0c48-a7eedca870fb md""" # Using _JavaScript_ inside Pluto You have already seen that Pluto is designed to be _interactive_. You can make fantastic explorable documents using just the basic inputs provided by PlutoUI, together with the wide range of visualization libraries that Julia offers. _However_, if you want to take your interactive document one step further, then Pluto offers a great framework for **combining Julia with HTML, CSS and _JavaScript_**. """ # ╔═╡ 168e13f7-2ff2-4207-be56-e57755041d36 md""" ## Prerequisites This document assumes that you have used HTML, CSS and JavaScript before in another context. If you know Julia, and you want to add these web languages to your skill set, we encourage you to do so! It will be useful knowledge, also outside of Pluto. """ # ╔═╡ 28ae1424-67dc-4b76-a172-1185cc76cb59 @htl("""

Learning HTML and CSS

It is easy to learn HTML and CSS because they are not 'programming languages' like Julia and JavaScript, they are markup languages: there are no loops, functions or arrays, you only declare how your document is structured (HTML) and what that structure looks like on a 2D color display (CSS).

As an example, this is what this cell looks like, written in HTML and CSS:

""") # ╔═╡ ea39c63f-7466-4015-a66c-08bd9c716343 md""" > My personal favourite resource for learning HTML and CSS is the [Mozilla Developer Network (MDN)](https://developer.mozilla.org/en-US/docs/Web/CSS). > > _-fons_ """ # ╔═╡ 8b082f9a-073e-4112-9422-4087850fc89e md""" #### Learning JavaScript After learning HTML and CSS, you can already spice up your Pluto notebooks by creating custom layouts, generated dynamically from Julia data. To take things to the next level, you can learn JavaScript. We recommend using an online resource for this. > My personal favourite is [javascript.info](https://javascript.info/), a high-quality, open source tutorial. I use it too! > > _-fons_ It is hard to say whether it is easy to _learn JavaScript using Pluto_. On one hand, we highly recommend the high-quality public learning material that already exists for JavaScript, which is generally written in the context of writing traditional web apps. On the other hand, if you have a specific Pluto-related project in mind, then this could be a great motivator to continue learning! A third option is to learn JavaScript using [observablehq.com](https://observablehq.com), an online reactive notebook for JavaScript (it's awesome!). Pluto's JavaScript runtime is designed to be very close to the way you write code in observable, so the skills you learn there will be transferable! If you chose to learn JavaScript using Pluto, let me know how it went, and how we can improve! [fons@plutojl.org](mailto:fons@plutojl.org) """ # ╔═╡ d70a3a02-ef3a-450f-bf5a-4a0d7f6262e2 TableOfContents() # ╔═╡ 10cf6ed1-8276-4a4a-ad06-097d10335512 md""" # Essentials ## Using HTML, CSS and JavaScript To use web languages inside Pluto, we recommend the small package [`HypertextLiteral.jl`](https://github.com/MechanicalRabbit/HypertextLiteral.jl), which provides an `@htl` macro. You wrap `@htl` around a string expression to mark it as an *HTML literal*, as we did in the example cell from earlier. When a cell outputs an HTML-showable object, it is rendered directly in your browser. """ # ╔═╡ d967cdf9-3df9-40bb-9b08-09cae95a5ca7 @htl(" Hello! ") # ╔═╡ 858745a9-cd59-43a6-a296-803515518e57 md""" ### CSS and JavaScript You can use CSS and JavaScript by including it inside HTML, just like you do when writing a web page. For example, here we use ` """) # ╔═╡ 4a3398be-ee86-45f3-ac8b-f627a38c00b8 md""" ## Interpolation Julia has a nice feature: _string interpolation_: """ # ╔═╡ 2d5fd611-284b-4428-b6a5-8909203990b9 who = "🌍" # ╔═╡ 82de4674-9ecc-46c4-8a57-0b4453c579c3 "Hello $(who)!" # ╔═╡ 70a415be-881a-4c01-9f8c-635b8b89e1ad md""" With some (frustrating) exceptions, you can also interpolate into Markdown literals: """ # ╔═╡ 730a692f-2bf2-4d5b-86da-6ab861e8b8ac md""" Hello $(who)! """ # ╔═╡ a45fdec4-2d4b-429b-b809-4c256b57fffe md""" **However**, you cannot interpolate into an `html"` string: """ # ╔═╡ c68ebd7b-5fb6-4527-ac34-33f9730e4587 html"""

Hello $(who)!

""" # ╔═╡ 8c03139f-a94b-40cc-859f-0d86f1c72143 md""" 😢 Luckily we can perform these kinds of interpolations (and much more) with the `@htl` macro, as we will see next. ### Interpolating into HTML -- HypertextLiteral.jl """ # ╔═╡ d8dcb044-0ac8-46d1-a043-1073bb6d1ff1 @htl("""

Hello $(who)!

""") # ╔═╡ e7d3db79-8253-4cbd-9832-5afb7dff0abf cool_features = [ md"Interpolate any **HTML-showable object**, such as plots and images, or another `@htl` literal." md"Interpolated lists are expanded _(like in this cell!)_." "Easy syntax for CSS" ] # ╔═╡ bf592202-a9a4-4e9b-8433-fed55e3aa3bc @htl("""

It has a bunch of very cool features! Including:

""") # ╔═╡ 5ac5b984-8c02-4b8d-a342-d0f05f7909ec md""" #### Why not just `HTML(...)`? You might be thinking, why don't we just use the `HTML` function, together with string interpolation? The main problem is correctly handling HTML _escaping rules_. For example: """ # ╔═╡ ef28eb8d-ec98-43e5-9012-3338c3b84f1b cool_elements = "
and " # ╔═╡ 1ba370cc-3631-47ea-9db5-75587e8e4ff3 HTML("""
My favourite HTML elements are $(cool_elements)!
""") # ╔═╡ 7fcf2f3f-d902-4338-adf0-8ef181e79420 @htl("""
My favourite HTML elements are $(cool_elements)!
""") # ╔═╡ 7afbf8ef-e91c-45b9-bf22-24201cbb4828 md""" ### Interpolating into JS -- _HypertextLiteral.jl_ As we see above, using HypertextLiteral.jl, we can interpolate objects (numbers, string, images) into HTML output, great! Next, we want to **interpolate _data_ into _scripts_**. Although you could use `JSON.jl`, HypertextLiteral.jl actually has this ability built-in! > When you **interpolate Julia objects into a ` """) # ╔═╡ 965f3660-6ec4-4a86-a2a2-c167dbe9315f md""" **Let's look at a more exciting example:** """ # ╔═╡ 00d97588-d591-4dad-9f7d-223c237deefd @bind fantastic_x Slider(0:400) # ╔═╡ 01ce31a9-6856-4ee7-8bce-7ce635167457 my_data = [ (name="Cool", coordinate=[100, 100]), (name="Awesome", coordinate=[200, 100]), (name="Fantastic!", coordinate=[fantastic_x, 150]), ] # ╔═╡ 21f57310-9ceb-423c-a9ce-5beb1060a5a3 @htl(""" """) # ╔═╡ 0866afc2-fd42-42b7-a572-9d824cf8b83b md""" ## Custom `@bind` output """ # ╔═╡ 75e1a973-7ef0-4ac5-b3e2-5edb63577927 md""" **You can use JavaScript to write input widgets.** The `input` event can be triggered on any object using ```javascript obj.value = ... obj.dispatchEvent(new CustomEvent("input")) ``` For example, here is a button widget that will send the number of times it has been clicked as the value: """ # ╔═╡ e8d8a60e-489b-467a-b49c-1fa844807751 ClickCounter(text="Click") = @htl(""" """) # ╔═╡ 9346d8e2-9ba0-4475-a21f-11bdd018bc60 @bind num_clicks ClickCounter() # ╔═╡ 7822fdb7-bee6-40cc-a089-56bb32d77fe6 num_clicks # ╔═╡ 701de4b8-42d3-46a3-a399-d7761dccd83d md""" As an exercise to get familiar with these techniques, you can try the following: - 👉 Add a "reset to zero" button to the widget above. - 👉 Make the bound value an array that increases size when you click, instead of a single number. - 👉 Create a "two sliders" widget: combine two sliders (``) into a single widget, where the bound value is the two-element array with both values. - 👉 Create a "click to send" widget: combine a text input and a button, and only send the contents of the text field when the button is clicked, not on every keystroke. Questions? Ask them on our [GitHub Discussions](https://github.com/fonsp/Pluto.jl/discussions)! """ # ╔═╡ 88120468-a43d-4d58-ac04-9cc7c86ca179 md""" ## Debugging The HTML, CSS and JavaScript that you write run in the browser, so you should use the [browser's built-in developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools) to debug your code. """ # ╔═╡ ea4b2da1-4c83-4a1f-8fc3-c71a120e58e1 @htl(""" """) # ╔═╡ 08bdeaff-5bfb-49ab-b4cc-3a3446c63edc @htl("""
Can you find out which CSS class this is?
""") # ╔═╡ 9b6b5da9-8372-4ebf-9c66-ae9fcfc45d47 md""" ## Selecting elements When writing the javascript code for a widget, it is common to **select elements inside the widgets** to manipulate them. In the number-of-clicks example above, we selected the `` and ` ``` """, "Show with syntax highlighting") # ╔═╡ d121e085-c69b-490f-b315-c11a9abd57a6 details(md""" ```htmlmixed ``` """, "Show with syntax highlighting") # ╔═╡ d4bdc4fe-2af8-402f-950f-2afaf77c62de details(md""" ```htmlmixed ``` """, "Show with syntax highlighting") # ╔═╡ e910982c-8508-4729-a75d-8b5b847918b6 details(md""" ```htmlmixed ``` """, "Show with syntax highlighting") # ╔═╡ 05d28aa2-9622-4e62-ab39-ca4c7dde6eb4 details(md""" ```htmlmixed ``` """, "Show with syntax highlighting") # ╔═╡ cc318a19-316f-4fd9-8436-fb1d42f888a3 demo_img = let url = "https://user-images.githubusercontent.com/6933510/116753174-fa40ab80-aa06-11eb-94d7-88f4171970b2.jpeg" data = read(download(url)) PlutoUI.Show(MIME"image/jpg"(), data) end # ╔═╡ 7aacdd8c-1571-4461-ba6e-0fd65dd8d788 demo_html = @htl("Hello!") # ╔═╡ ebec177c-4c33-45a4-bdbd-f16944631aff md""" ## Embeddable output Pluto has a multimedia object viewer, which is used to display the result of a cell's output. Depending on the _type_ of the resulting object, the richest possible viewer is used. This includes: - an interactive structure viewer for arrays, tables, dictionaries and more: $(embed_display([1,2,(a=3, b=4)])) - an `` tag with optimized data transfer for images: $(embed_display(demo_img)) - raw HTML for HTML-showable objects: $(embed_display(demo_html)) Normally, you get this object viewer for the _output_ of a cell. However, as demonstrated in the list above, you can also **embed Pluto's object viewer in your own HTML**. To do so, Pluto provides a function: ```julia embed_display(x) ``` #### Example As an example, here is how you display two arrays side-by-side: ```julia @htl("\""
$(embed_display(rand(4))) $(embed_display(rand(4)))
"\"") ``` You can [learn more](https://github.com/fonsp/Pluto.jl/pull/1126) about how this feature works, or how to use it inside packages. """ # ╔═╡ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ [deps] HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" [compat] HypertextLiteral = "~0.9.3" PlutoUI = "~0.7.34" """ # ╔═╡ 00000000-0000-0000-0000-000000000002 PLUTO_MANIFEST_TOML_CONTENTS = """ # This file is machine-generated - editing it directly is not advised [[AbstractPlutoDingetjes]] deps = ["Pkg"] git-tree-sha1 = "8eaf9f1b4921132a4cff3f36a1d9ba923b14a481" uuid = "6e696c72-6542-2067-7265-42206c756150" version = "1.1.4" [[ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" [[Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[ColorTypes]] deps = ["FixedPointNumbers", "Random"] git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" [[FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[FixedPointNumbers]] deps = ["Statistics"] git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.4" [[Hyperscript]] deps = ["Test"] git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9" uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" version = "0.0.4" [[HypertextLiteral]] deps = ["Tricks"] git-tree-sha1 = "c47c5fa4c5308f27ccaac35504858d8914e102f9" uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" version = "0.9.4" [[IOCapture]] deps = ["Logging", "Random"] git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" version = "0.2.2" [[InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.21.3" [[LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" [[LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" [[LibGit2]] deps = ["Base64", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" [[LinearAlgebra]] deps = ["Libdl", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" [[Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" [[MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" [[NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" [[OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" [[Parsers]] deps = ["Dates"] git-tree-sha1 = "0044b23da09b5608b4ecacb4e5e6c6332f833a7e" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.3.2" [[Pkg]] deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [[PlutoUI]] deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"] git-tree-sha1 = "8d1f54886b9037091edf146b517989fc4a09efec" uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" version = "0.7.39" [[Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" [[REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" [[Random]] deps = ["SHA", "Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "1.2.2" [[SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" [[Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[SparseArrays]] deps = ["LinearAlgebra", "Random"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[Statistics]] deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [[TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" [[Tar]] deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" [[Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[Tricks]] git-tree-sha1 = "6bac775f2d42a611cdfcd1fb217ee719630c4175" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" version = "0.1.6" [[UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" [[Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [[Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" [[libblastrampoline_jll]] deps = ["Artifacts", "Libdl", "OpenBLAS_jll"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" [[nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" [[p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" """ # ╔═╡ Cell order: # ╟─97914842-76d2-11eb-0c48-a7eedca870fb # ╠═571613a1-6b4b-496d-9a68-aac3f6a83a4b # ╟─168e13f7-2ff2-4207-be56-e57755041d36 # ╠═28ae1424-67dc-4b76-a172-1185cc76cb59 # ╟─93abe0dc-f041-475f-9ef7-d8ee4408414b # ╟─ea39c63f-7466-4015-a66c-08bd9c716343 # ╟─8b082f9a-073e-4112-9422-4087850fc89e # ╟─d70a3a02-ef3a-450f-bf5a-4a0d7f6262e2 # ╟─10cf6ed1-8276-4a4a-ad06-097d10335512 # ╠═d967cdf9-3df9-40bb-9b08-09cae95a5ca7 # ╟─858745a9-cd59-43a6-a296-803515518e57 # ╠═21a9e3e6-92f4-475d-9c8e-21e15c09336b # ╟─4a3398be-ee86-45f3-ac8b-f627a38c00b8 # ╠═2d5fd611-284b-4428-b6a5-8909203990b9 # ╠═82de4674-9ecc-46c4-8a57-0b4453c579c3 # ╟─70a415be-881a-4c01-9f8c-635b8b89e1ad # ╠═730a692f-2bf2-4d5b-86da-6ab861e8b8ac # ╟─a45fdec4-2d4b-429b-b809-4c256b57fffe # ╠═c68ebd7b-5fb6-4527-ac34-33f9730e4587 # ╟─8c03139f-a94b-40cc-859f-0d86f1c72143 # ╠═d8dcb044-0ac8-46d1-a043-1073bb6d1ff1 # ╠═bf592202-a9a4-4e9b-8433-fed55e3aa3bc # ╟─e7d3db79-8253-4cbd-9832-5afb7dff0abf # ╟─5ac5b984-8c02-4b8d-a342-d0f05f7909ec # ╠═ef28eb8d-ec98-43e5-9012-3338c3b84f1b # ╠═1ba370cc-3631-47ea-9db5-75587e8e4ff3 # ╠═7fcf2f3f-d902-4338-adf0-8ef181e79420 # ╟─7afbf8ef-e91c-45b9-bf22-24201cbb4828 # ╠═b226da72-9512-4d14-8582-2f7787c25028 # ╠═a6fd1f7b-a8fc-420d-a8bb-9f549842ad3e # ╟─d12b98df-8c3f-4620-ba3c-2f3dadac521b # ╟─965f3660-6ec4-4a86-a2a2-c167dbe9315f # ╠═01ce31a9-6856-4ee7-8bce-7ce635167457 # ╠═00d97588-d591-4dad-9f7d-223c237deefd # ╠═21f57310-9ceb-423c-a9ce-5beb1060a5a3 # ╟─94561cb1-2325-49b6-8b22-943923fdd91b # ╟─0866afc2-fd42-42b7-a572-9d824cf8b83b # ╟─75e1a973-7ef0-4ac5-b3e2-5edb63577927 # ╠═e8d8a60e-489b-467a-b49c-1fa844807751 # ╟─b0c246ed-b871-461b-9541-280e49b49136 # ╠═9346d8e2-9ba0-4475-a21f-11bdd018bc60 # ╠═7822fdb7-bee6-40cc-a089-56bb32d77fe6 # ╟─701de4b8-42d3-46a3-a399-d7761dccd83d # ╟─88120468-a43d-4d58-ac04-9cc7c86ca179 # ╠═ea4b2da1-4c83-4a1f-8fc3-c71a120e58e1 # ╟─08bdeaff-5bfb-49ab-b4cc-3a3446c63edc # ╟─9b6b5da9-8372-4ebf-9c66-ae9fcfc45d47 # ╟─f18b98f7-1e0f-4273-896f-8a667d15605b # ╟─d83d57e2-4787-4b8d-8669-64ed73d79e73 # ╟─077c95cf-2a1b-459f-830e-c29c11a2c5cc # ╟─80511436-e41f-4913-8a30-d9e113cfaf71 # ╟─8388a833-d535-4cbd-a27b-de323cea60e8 # ╟─4cf27df3-6a69-402e-a71c-26538b2a52e7 # ╟─5721ad33-a51a-4a91-adb2-0915ea0efa13 # ╠═c857bb4b-4cf4-426e-b340-592cf7700434 # ╟─d121e085-c69b-490f-b315-c11a9abd57a6 # ╟─fc8984c8-4668-418a-b258-a1718809470c # ╠═846354c8-ba3b-4be7-926c-d3c9cc9add5f # ╟─a33c7d7a-8071-448e-abd6-4e38b5444a3a # ╠═91f3dab8-5521-44a0-9890-8d988a994076 # ╠═dcaae662-4a4f-4dd3-8763-89ea9eab7d43 # ╟─d4bdc4fe-2af8-402f-950f-2afaf77c62de # ╟─e77cfefc-429d-49db-8135-f4604f6a9f0b # ╠═2d5689f5-1d63-4b8b-a103-da35933ad26e # ╠═6dd221d1-7fd8-446e-aced-950512ea34bc # ╠═0a9d6e2d-3a41-4cd5-9a4e-a9b76ed89fa9 # ╟─0962d456-1a76-4b0d-85ff-c9e7dc66621d # ╠═bf9b36e8-14c5-477b-a54b-35ba8e415c77 # ╟─e910982c-8508-4729-a75d-8b5b847918b6 # ╟─781adedc-2da7-4394-b323-e508d614afae # ╟─de789ad1-8197-48ae-81b2-a21ec2340ae0 # ╠═85483b28-341e-4ed6-bb1e-66c33613725e # ╠═9e37c18c-3ebb-443a-9663-bb4064391d6e # ╟─05d28aa2-9622-4e62-ab39-ca4c7dde6eb4 # ╠═3266f9e6-42ad-4103-8db3-b87d2c315290 # ╟─7d9d6c28-131a-4b2a-84f8-5c085f387e85 # ╟─ebec177c-4c33-45a4-bdbd-f16944631aff # ╟─da7091f5-8ba2-498b-aa8d-bbf3b4505b81 # ╠═64cbf19c-a4e3-4cdb-b4ec-1fbe24be55ad # ╟─cc318a19-316f-4fd9-8436-fb1d42f888a3 # ╟─7aacdd8c-1571-4461-ba6e-0fd65dd8d788 # ╟─00000000-0000-0000-0000-000000000001 # ╟─00000000-0000-0000-0000-000000000002