diff --git a/.gitignore b/.gitignore
index 70b6503..9e1ed2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@ archive/
server/
**.log
**.aux
+kicad/
diff --git a/docs/diagrams/fern-v3-concept-diagram.drawio b/docs/diagrams/fern-v3-concept-diagram.drawio
deleted file mode 100644
index 6d46b66..0000000
--- a/docs/diagrams/fern-v3-concept-diagram.drawio
+++ /dev/null
@@ -1 +0,0 @@
-7Vpbb6M4FP41eUxkc7HhkW2buW1X1VSrkeZl5ASHoCE4C06bzq9fE2zCxSFUApJWzUvgAAf4vu8c+xwzMW82+08J2a7vmU+jiQH8/cS8nRgGNCxD/GWWl9yCkJUbgiT05UlHw2P4h0ojkNZd6NO0ciJnLOLhtmpcsjimS16xkSRhz9XTViyq3nVLAtowPC5J1LT+CH2+zq2ODY72zzQM1urOEMgjG6JOloZ0TXz2XDKZdxPzJmGM51ub/Q2NMvAULvl18xNHiwdLaMy7XODu/vl+v3Ppz8ff5Db+Enp/fi6mULLxRKKdfGP5tPxFQUBj38uQFHsxi4XxrzXfRGIPis2E7WKfZrcAYm/FYi45NLL9lCfsN71hEUsOvkxw+BVHFKT4YCEJr92o+Y7ytVO2S5by+b4u/51+Xcx/ebHnW3eJZ337vJgi+R7Ur/AroflE2Yby5EWc8HxkVZG6LhGqbAmNCA+fqqogUlxB4a64wwMLxSMbQAYCMqUfFQZK38pF/kLyqjKLNUe2VXVkOjVHAsWA8oYjsVF67aPpIJLXCAa8fcHoX0xllwN+bcqyrkpZhQBOCaKrsrBddWQZ4yoLdRBWFIm8n/H8vA45fdySA6XPYuipioyk23wwWIX7TGvndTaf37oINXTmZteGUaTOPCezJ5pwum+VhcoINbhNFdgl2Tga2dTpLSukQkkL/lpdW2aPBJQxE+j6DgDY1OHu2QBYKhOU7KvDrx+oDVCF2rbtBtSWBmprMKjt4aBGFkYO1kFtQsu0rRaoE8ZFJmJxpnswDPQY2jMAxCxJjGNIhAC6MBF9Jp0aEXBBIDX0Yxq68+bjah6ZF9a8rUsvKOIShgrm6L8dUwem6SFte+IEAcn+eFBsBdm/Fy/XAkHpa5Eou7KIp81voMw1fgWgvEpklTCZ8jWjAInCIAuWiK4yDxk5oagcPGnehL4fndJNdRrUB+HofJIrapFxGHcGzHKAuFCb5YxbjMDIAwp2Lx1c7kDBdc/4R2w1YkvH97ixhXRlWB+EzxNKswfeh6n4Y6usQFHTgg8ZNCYzl5YBHEgGD/SD7jrduinUyHR36da9yREV4Vo1jJrV8FAjqrYbYfSI9BvoRtRnNA4eb0ajxX+oauHH4eEFCwb4HsbBR5JD54kfLMlpme9QNSjI/iYLGj2wNJRdiwXjnG00mHJWC8l0TbaZs80+yNatZguShssZSZYT1VeOg8PdwMxxRSllWYaLIMAuzqIya3AXxw27S0Sf6GOjwSIaAbtCrKGZs0KsIbYw9s6srkipR1USkhzZs8NXv4gP0PvCtdAqOvMlBtSUokyAORT+UDdbfJdtR9toTCcu1HbUE9FldjHOItpJsM8vmMkhurxg1iq7K1kwg+aJsHztghlC7swtfg42290OvTA74PLNZVvZ9QXOEUuD1k8L3t9CWb0Kw+aFqzDYZX3myr82aNXQ+eTpXFXyxLWB1bG063mvTaUurLl17HGTJ+4xpN9AuY9rxYGjaW0N9fFBq8zfX2cLGzWoR/z4QN/Z6lAFBCJvbqtTc/S6qXnxRSZZKKegFSfUWGNpjj3QwTNNwTRcxQo7lKzvvhlxXgTtOuscKlZFAFPc5H/cfoUa6669YQHtQWmBoFrZQKuZwXrqY4jd4wfR+eB+/KzcvPsf
\ No newline at end of file
diff --git a/docs/diagrams/fern-v3-concept-diagram.png b/docs/diagrams/fern-v3-concept-diagram.png
deleted file mode 100644
index 7e408f4..0000000
Binary files a/docs/diagrams/fern-v3-concept-diagram.png and /dev/null differ
diff --git a/docs/diagrams/fern-v3-single-arm-angles-diagram.drawio b/docs/diagrams/fern-v3-single-arm-angles-diagram.drawio
deleted file mode 100644
index 800cca4..0000000
--- a/docs/diagrams/fern-v3-single-arm-angles-diagram.drawio
+++ /dev/null
@@ -1 +0,0 @@
-5VpdU+I8FP41XMI0X/24dGHdfWddh9WdWfXGCW2gnS0NUwKCv/5N26Q0bdGqiLpyY89JOGnO8+R8RHpoON98S+ki/MkDFvegFWx6aNSDELgEyj+ZZltobBsXilkaBWrSTnEZ3TOltJR2FQVsaUwUnMciWphKnycJ84Who2nK78xpUx6bqy7ojDUUlz6Nm9o/USDCQusSa6f/zqJZqFcGlhqZUz1ZmViGNOB3hSqfg7720DDlXBRP882QxZnztF8KQ6d7RssXS1kiunzBW51f/Fx57ObyLx0l/0Un9zeTvnbzmsYrtWP1tmKrXcCS4CTzpJQSnkjll1DMYykB+ZjyVRKwbAlLSlOeCIUhzOSlSPlfNuQxT3NbyMo/5Yh2Kck1NBW1hQK6DHPjQAljKgRLk1wDrUzbdIP2N1+lPnto72oiCwwKKO99Y3zORLqVE+52wGvcwwrmWpeymIpobRKHKv7NSnPlCmMeyVeGljorfUfZUScFaVmbKDakvlUFumbIRo8Yko6eMdEwJB8q296pch49gVN2B0rFsTzAGcJ3YSTY5YLmSN3JGGLSiy4XxameRpuMCC9i2DSKYz3zAARbs1SwzYPMUaPYMhEByBmQQlPhFsKkSa5S2UYkA7mnwqTpfxCcqq5tglAZQQAjghWQFf00/+QBRchTxDMEPOsw7ndr54G0+L7lXCPr5Z4PT3+fnFN6/uvi9ge7n52fXfuTPmlxvMyKOLgFxUMDB7lRYTrcdKxicwvBaRzNMl/60n1M6r9kbotkfjtRA/MoCOJ9CD8c3XNZvSQ8AE4IeSZQLm4AZR8TKG8PUBcfDKgOUe7QWJL6odOVxhGw/H5qT0bDq/SS/0EXV+Op8yu67cODFjrSMen2KhMGlutpxXWukDzWitGmOn+0rUpjlkZyaxnWo/Z8Jd/nNMp2OeoI4l7cioz/eM5+J6XQoxVM11II12oq6L1aKdRKOvQk0vkxXS4j/+kFtkmaHTMdu8ZMiJ/DzL206lxifzD+lTTR/LOfyT+E90TBI/EPvwH/NpEwAqOUNfu0vCNfJmwrQmfqvROmYIgHnkcs/QFmuAHewILYKz/uM8OYJ1dxDNOgnihfmUltNasdZ7VOEK3l40zkaOVFERmumd9zvqQ9Z6TrpGKuXNqY/iGqp0OXRmXdo1kC37g0amvYDSDXFSA/JWQYdGngjwqa83ho1w49oxMWj/kyUn31hAvB5y0eF7zW1i9DusiMzTez7Hp3MKEyPwxo6pf3dcksX80aOAQBF9oOJsTCrl0UGsFu3MW2g7DtQWBBmzhOp2RyAOgajUjLaSsvbavIlcqDQ+e+M+iAa8lcLbMMcZHXAA4ShFzi2JhgaCGAjwVcHxIzTJImcBC3AFcqDw5c6225ipQ0XoT0UwdJ6LjmSUPO24ZI0NbzK7hEyMTnhovUm+wjwoWCq9/8+ob7N9OxA07oD34263e5j37eDY3t1PpgDN/0hqbWvLQA+Vb9jFsrdGQHY5ro3LJANAAA1zuf0qwr2ybT8uEamFZ2dWiFj5p0IXYhAraLCQAQQELqeVcWSwDarmMTJIsW7yl5txEEOjFM31k4Zt4Fdlut+3olUyt6+/5l8q9E8hchhusNJXq1hlKKu18sFEdz97sP9PV/
\ No newline at end of file
diff --git a/docs/diagrams/fern-v3-single-arm-angles-diagram.png b/docs/diagrams/fern-v3-single-arm-angles-diagram.png
deleted file mode 100644
index 265abbb..0000000
Binary files a/docs/diagrams/fern-v3-single-arm-angles-diagram.png and /dev/null differ
diff --git a/docs/diagrams/fern-v3-single-arm-diagram.drawio b/docs/diagrams/fern-v3-single-arm-diagram.drawio
deleted file mode 100644
index b22f457..0000000
--- a/docs/diagrams/fern-v3-single-arm-diagram.drawio
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/diagrams/fern-v3-single-arm-diagram.png b/docs/diagrams/fern-v3-single-arm-diagram.png
deleted file mode 100644
index ab172d4..0000000
Binary files a/docs/diagrams/fern-v3-single-arm-diagram.png and /dev/null differ
diff --git a/docs/diagrams/fern-v3-single-arm-integral-diagram.drawio b/docs/diagrams/fern-v3-single-arm-integral-diagram.drawio
deleted file mode 100644
index 1d08d53..0000000
--- a/docs/diagrams/fern-v3-single-arm-integral-diagram.drawio
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/diagrams/fern-v3-single-arm-integral-diagram.png b/docs/diagrams/fern-v3-single-arm-integral-diagram.png
deleted file mode 100644
index 9e37d7a..0000000
Binary files a/docs/diagrams/fern-v3-single-arm-integral-diagram.png and /dev/null differ
diff --git a/docs/latex/gyro-fern.tex b/docs/latex/gyro-fern.tex
deleted file mode 100644
index be3cc9e..0000000
--- a/docs/latex/gyro-fern.tex
+++ /dev/null
@@ -1,129 +0,0 @@
-\documentclass{article}
-\usepackage{graphicx}
-\usepackage{amsmath}
-\usepackage{parskip}
-\usepackage[margin=1.5in]{geometry}
-\title{Supporting Documentation for a Gyroscopic Fern}
-\author{ijbd}
-\begin{document}
-
- \section{Introduction}
-
- The goal of this iteration is to replace the stacked linear axes with a pair of rotating arms (figure \ref{fig:high-level-concept}).
- This document serves as theoretical foundation and proof-of-concept for this idea.
-
- \begin{figure}[h!]
- \includegraphics[width=\linewidth]{../diagrams/fern-v3-concept-diagram.png}
- \caption{Birds-eye concept drawing of a gyroscopic fern.}
- \label{fig:high-level-concept}
- \end{figure}
-
- \section{Setup}
-
- To start, consider a single arm (figure \ref{fig:high-level-one-arm}). It has a motor on one end and an ambiguous mass on the other
- (e.g. a pen or another arm).
-
- \begin{figure}[h!]
- \includegraphics[width=\linewidth]{../diagrams/fern-v3-single-arm-diagram.png}
- \caption{Body diagram for one arm.}
- \label{fig:high-level-one-arm}
- \end{figure}
-
- Assume the motor and supporting rod are massless.
- With the system at rest, the angular momentum is zero.
- Suppose the motor begins to spin such that the angular rotation about the rotor axis is $\omega$.
- We want to predict the resulting arm motion.
- The conservation of angular momentum says that the change in angular momentum of a system (lacking an external torques)
- is zero.
- To express the rotational velocity of the arm as a function of motor speed,
- we can equate the angular momentum of the motor with the angular momentum of the arm.
-
-
- \section{Calculation}
- \subsection{Angular Momentum from the Spinning Ring}
-
- By definition...
- \begin{align}
- L &= \vec{r} \times\vec{p}
- &= \vec{r} \times m \vec{v} \\
- &= \int_m\vec{r}\times\vec{v} dm \\
- &= \int_{\theta}\vec{r}\times\rho\vec{v} d\theta
- \end{align}
-
- Where...
- \begin{align}
- \rho &= \frac{m_1}{2\pi}
- \end{align}
-
- The components of this integral are shown in figure \ref{fig:one-arm-integral}
-
- \begin{figure}[h!]
- \includegraphics[width=\linewidth]{../diagrams/fern-v3-single-arm-integral-diagram.png}
- \caption{Components of angular momentum integration.}
- \label{fig:one-arm-integral}
- \end{figure}
-
- Continuing...
- \begin{align}
- L &= \rho\int_0^{2\pi}|\vec{r}(\theta)||\vec{v}|sin(\phi(\theta))d\theta
- \end{align}
-
- Where..
- \begin{align}
- \phi &= \angle\vec{v} - \angle\vec{r}
- \end{align}
-
- Solving for the needed quanitities (figure \ref{fig:one-arm-integral-angles})
- \begin{align}
- |\vec{r}(\theta)| &= \sqrt{R_1^2 + d_1^2 -2R_1d_1cos(\theta)} \\
- |\vec{v}| &= \omega r\\
- \phi(\theta) &= \frac{\pi}{2}-\theta-\alpha(\theta)
- \end{align}
-
- Where...
- \begin{align}
- \alpha &= \angle\vec{r}\\
- &= sin^{-1}(\frac{R_1sin(\theta)}{|\vec{r}(\theta)|})
- \end{align}
-
- \begin{figure}[h!]
- \includegraphics[width=\linewidth]{../diagrams/fern-v3-single-arm-angles-diagram.png}
- \caption{Components of angular momentum integration.}
- \label{fig:one-arm-integral-angles}
- \end{figure}
-
- Continuing...
- \begin{align}
- sin(\phi(\theta)) &= sin(\frac{\pi}{2}-(\theta+\alpha(\theta)))
- \end{align}
-
- To simplify...
- \begin{align}
- sin(\phi(\theta)) &= cos(\theta + \alpha(\theta)) \\
- &= cos(\theta)cos(\alpha(\theta)) - sin(\theta)sin(\alpha(\theta)) \\
- &= cos(\theta)cos(sin^{-1}(\frac{R_1sin(\theta)}{|\vec{r}(\theta)|})) - sin(\theta)sin(sin^{-1}(\frac{R_1sin(\theta)}{|\vec{r}(\theta)|})) \\
- &= cos(\theta)\sqrt{1-\frac{R_1^2sin^2(\theta)}{|\vec{r}(\theta)|^2}} - \frac{R_1}{|\vec{r}(\theta)|}sin^2(\theta) \\
- &= cos(\theta)\sqrt{\frac{|\vec{r}(\theta)|^2 - R_1^2sin^2(\theta)}{|\vec{r}(\theta)|^2}} - \frac{R_1}{|\vec{r}(\theta)|}sin^2(\theta) \\
- &= cos(\theta)\sqrt{\frac{R_1^2+d_1^2-2R_1d_1cos(\theta)- R_1^2sin^2(\theta)}{|\vec{r}(\theta)|^2}} - \frac{R_1}{|\vec{r}(\theta)|}sin^2(\theta) \\
- &= cos(\theta)\sqrt{\frac{R_1^2(1-sin^2(\theta))+d_1^2-2R_1d_1cos(\theta)}{|\vec{r}(\theta)|^2}} - \frac{R_1}{|\vec{r}(\theta)|}sin^2(\theta) \\
- &= cos(\theta)\sqrt{\frac{R_1^2cos^2(\theta)+d_1^2-2R_1d_1cos(\theta)}{|\vec{r}(\theta)|^2}} - \frac{R_1}{|\vec{r}(\theta)|}sin^2(\theta) \\
- &= cos(\theta)\sqrt{\frac{(R_1cos(\theta) - d_1)^2}{|\vec{r}(\theta)|^2}} - \frac{R_1}{|\vec{r}(\theta)|}sin^2(\theta) \\
- &= \frac{d_1cos(\theta) - R_1cos^2(\theta) - R_1sin^2(\theta)}{|\vec{r}(\theta)|} \\
- &= \frac{d_1cos(\theta) - R_1(cos^2(\theta) + sin^2(\theta))}{|\vec{r}(\theta)|} \\
- &= \frac{d_1cos(\theta) - R_1}{|\vec{r}(\theta)|}
- \end{align}
- Recall...
- \begin{align}
- L &= \rho\int_0^{2\pi}|\vec{r}(\theta)||\vec{v}|sin(\phi(\theta))d\theta
- \end{align}
-
- Finally...
- \begin{align}
- L &=\rho\omega R_1\int_0^{2\pi}|\vec{r}(\theta)|\frac{d_1cos(\theta) - R_1}{|\vec{r}(\theta)|}d\theta \\
- &= \rho\omega R_1\int_0^{2\pi}d_1cos(\theta) - R_1 d\theta \\
- &= \rho\omega R_1^2 2\pi \\
- &= \frac{m}{2\pi} \omega R_1^2 2\pi \\
- &= m \omega R_1^2
- \end{align}
-
-\end{document}
diff --git a/docs/pdf/gyro-fern.pdf b/docs/pdf/gyro-fern.pdf
deleted file mode 100644
index 6826023..0000000
Binary files a/docs/pdf/gyro-fern.pdf and /dev/null differ
diff --git a/kicad/fern-mcu/fern-mcu-backups/fern-mcu-2022-08-03_225632.zip b/kicad/fern-mcu/fern-mcu-backups/fern-mcu-2022-08-03_225632.zip
deleted file mode 100644
index fd690a0..0000000
Binary files a/kicad/fern-mcu/fern-mcu-backups/fern-mcu-2022-08-03_225632.zip and /dev/null differ
diff --git a/kicad/fern-mcu/fern-mcu.kicad_pcb b/kicad/fern-mcu/fern-mcu.kicad_pcb
deleted file mode 100644
index 28b47a1..0000000
--- a/kicad/fern-mcu/fern-mcu.kicad_pcb
+++ /dev/null
@@ -1,2 +0,0 @@
-(kicad_pcb (version 20211014) (generator pcbnew)
-)
\ No newline at end of file
diff --git a/kicad/fern-mcu/fern-mcu.kicad_prl b/kicad/fern-mcu/fern-mcu.kicad_prl
deleted file mode 100644
index 83acdaa..0000000
--- a/kicad/fern-mcu/fern-mcu.kicad_prl
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "board": {
- "active_layer": 0,
- "active_layer_preset": "",
- "auto_track_width": true,
- "hidden_nets": [],
- "high_contrast_mode": 0,
- "net_color_mode": 1,
- "opacity": {
- "pads": 1.0,
- "tracks": 1.0,
- "vias": 1.0,
- "zones": 0.6
- },
- "ratsnest_display_mode": 0,
- "selection_filter": {
- "dimensions": true,
- "footprints": true,
- "graphics": true,
- "keepouts": true,
- "lockedItems": true,
- "otherItems": true,
- "pads": true,
- "text": true,
- "tracks": true,
- "vias": true,
- "zones": true
- },
- "visible_items": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 20,
- 21,
- 22,
- 23,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 30,
- 32,
- 33,
- 34,
- 35,
- 36
- ],
- "visible_layers": "fffffff_ffffffff",
- "zone_display_mode": 0
- },
- "meta": {
- "filename": "fern-mcu.kicad_prl",
- "version": 3
- },
- "project": {
- "files": []
- }
-}
diff --git a/kicad/fern-mcu/fern-mcu.kicad_pro b/kicad/fern-mcu/fern-mcu.kicad_pro
deleted file mode 100644
index ccaeff9..0000000
--- a/kicad/fern-mcu/fern-mcu.kicad_pro
+++ /dev/null
@@ -1,82 +0,0 @@
-{
- "board": {
- "design_settings": {
- "defaults": {
- "board_outline_line_width": 0.1,
- "copper_line_width": 0.2,
- "copper_text_size_h": 1.5,
- "copper_text_size_v": 1.5,
- "copper_text_thickness": 0.3,
- "other_line_width": 0.15,
- "silk_line_width": 0.15,
- "silk_text_size_h": 1.0,
- "silk_text_size_v": 1.0,
- "silk_text_thickness": 0.15
- },
- "diff_pair_dimensions": [],
- "drc_exclusions": [],
- "rules": {
- "min_copper_edge_clearance": 0.0,
- "solder_mask_clearance": 0.0,
- "solder_mask_min_width": 0.0
- },
- "track_widths": [],
- "via_dimensions": []
- },
- "layer_presets": []
- },
- "boards": [],
- "cvpcb": {
- "equivalence_files": []
- },
- "libraries": {
- "pinned_footprint_libs": [],
- "pinned_symbol_libs": []
- },
- "meta": {
- "filename": "fern-mcu.kicad_pro",
- "version": 1
- },
- "net_settings": {
- "classes": [
- {
- "bus_width": 12.0,
- "clearance": 0.2,
- "diff_pair_gap": 0.25,
- "diff_pair_via_gap": 0.25,
- "diff_pair_width": 0.2,
- "line_style": 0,
- "microvia_diameter": 0.3,
- "microvia_drill": 0.1,
- "name": "Default",
- "pcb_color": "rgba(0, 0, 0, 0.000)",
- "schematic_color": "rgba(0, 0, 0, 0.000)",
- "track_width": 0.25,
- "via_diameter": 0.8,
- "via_drill": 0.4,
- "wire_width": 6.0
- }
- ],
- "meta": {
- "version": 2
- },
- "net_colors": null
- },
- "pcbnew": {
- "last_paths": {
- "gencad": "",
- "idf": "",
- "netlist": "",
- "specctra_dsn": "",
- "step": "",
- "vrml": ""
- },
- "page_layout_descr_file": ""
- },
- "schematic": {
- "legacy_lib_dir": "",
- "legacy_lib_list": []
- },
- "sheets": [],
- "text_variables": {}
-}
diff --git a/kicad/fern-mcu/fern-mcu.kicad_sch b/kicad/fern-mcu/fern-mcu.kicad_sch
deleted file mode 100644
index 3cfeed7..0000000
--- a/kicad/fern-mcu/fern-mcu.kicad_sch
+++ /dev/null
@@ -1,5 +0,0 @@
-(kicad_sch (version 20211123) (generator eeschema)
- (paper "A4")
- (lib_symbols)
- (symbol_instances)
-)
diff --git a/server/assets/stylesheets/main.css b/server/assets/stylesheets/main.css
deleted file mode 100644
index e69de29..0000000
diff --git a/server/index.html b/server/index.html
deleted file mode 100644
index 09ca124..0000000
--- a/server/index.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- Fern
-
-
-
-
-
-
\ No newline at end of file
diff --git a/server/src/fern_server.py b/server/src/fern_server.py
deleted file mode 100644
index 5874ede..0000000
--- a/server/src/fern_server.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from flask import Flask, render_doc
-
-app = Flask()
-
-@route('/')
-def index(self):
- return render_doc('index.html')
-
-
-
-if __name__ == "__main__":
- app.run()
\ No newline at end of file
diff --git a/src/fern.py b/src/fern.py
new file mode 100644
index 0000000..ece7807
--- /dev/null
+++ b/src/fern.py
@@ -0,0 +1,59 @@
+'''
+what is true of ferns?
+
+a fern is made of leaves, branches, and smaller ferns.
+all ferns are related in space.
+relations describe perceived position, orientation, and scale.
+'''
+from __future__ import annotations
+from collections import namedtuple
+
+Leaf = namedtuple(
+ typename="Leaf",
+ field_names=["x", "y"]
+)
+
+Branch = namedtuple(
+ typename="Branch",
+ field_names=["x", "y"]
+)
+
+Relation = namedtuple(
+ typename="Relation",
+ field_names=[
+ "x",
+ "y",
+ "xs",
+ "ys",
+ "theta"
+ ]
+)
+
+def relate_leaf(leaf, relation):
+ pass
+
+def relate_leaf(branch, relation):
+ pass
+
+
+class Fern:
+ def __init__(self):
+ self.ferns = []
+ self.relations = []
+
+ def plant(self, fern: Fern, relation: Relation):
+ """plant a new fern"""
+ self.ferns.append(fern)
+ self.relations.append(relation)
+
+ def resolve(self) -> list[Leaf | Branch]:
+ """return a list of perceived leaves and branches"""
+ perspective = []
+ for fern, relation in zip(self.ferns, self.relations):
+ # base case
+ if isinstance(fern, [Leaf, Branch]):
+ perspective += self.apply(relation, fern)
+ # recurse
+ perspective += fern.resolve()
+
+ return perspective
\ No newline at end of file