+
+## 1. End User Code
+
+The End User Code is written in JavaScript with added syntax sugar. The [eval package](https://github.com/tidalcycles/strudel/tree/main/packages/eval#strudelcycleseval) evaluates the user code
+after a transpilation step, which resolves the syntax sugar. If you don't want the syntax sugar, you can omit the eval package and call the native javascript `eval` instead.
+
+### 🍭 Syntax Sugar
+
+JavaScript Transpilation = converting valid JavaScript to valid JavaScript:
+
+```js
+"c3 [e3 g3]".fast(2)
+```
+
+becomes
+
+```js
+mini('c3 [e3 g3]')
+ .withMiniLocation([1, 0, 0], [1, 11, 11]) // source location
+ .fast(2);
+```
+
+- double quoted strings and backtick strings are turned into `mini` calls (single quoted strings are left as is)
+- The source location is added by chaining `withMiniLocation`, which enables the real time highlighting later
+- (psuedo) variable names that look like notes (like `c4`, `bb2` or `fs3`) are turned into strings
+- support for top level await
+- operator overloading could be implemented in the future
+
+This is how it works:
+
+
+
+- The user code is parsed with a [shift parser](https://github.com/shapesecurity/shift-parser-js), generating an AST
+- The AST is transformed to resolve the syntax sugar
+- The AST is used to generate code again (shift-codegen)
+
+Shift will most likely be replaced with acorn in the future, see https://github.com/tidalcycles/strudel/issues/174
+
+### Mini Notation
+
+Another important part of the user code is the mini notation, which allows to express rhythms in a short manner.
+
+- the mini notation is [implemented as a PEG grammar](https://github.com/tidalcycles/strudel/blob/main/packages/mini/krill.pegjs), living in the [mini package](https://github.com/tidalcycles/strudel/tree/main/packages/mini)
+- it is based on [krill](https://github.com/Mdashdotdashn/krill) by Mdashdotdashn
+- the peg grammar is used to generate a parser with [peggyjs](https://peggyjs.org/)
+- the generated parser takes a mini notation string and outputs an AST
+- the AST can then be used to construct a pattern using the regular Strudel API
+
+Here's an example AST:
+
+```json
+{
+ "type_": "pattern",
+ "arguments_": { "alignment": "h" },
+ "source_": [
+ {
+ "type_": "element", "source_": "c3",
+ "location_": { "start": { "offset": 1, "line": 1, "column": 2 }, "end": { "offset": 4, "line": 1, "column": 5 } }
+ },
+ {
+ "type_": "element",
+ "location_": { "start": { "offset": 4, "line": 1, "column": 5 }, "end": { "offset": 11, "line": 1, "column": 12 } }
+ "source_": {
+ "type_": "pattern", "arguments_": { "alignment": "h" },
+ "source_": [
+ {
+ "type_": "element", "source_": "e3",
+ "location_": { "start": { "offset": 5, "line": 1, "column": 6 }, "end": { "offset": 8, "line": 1, "column": 9 } }
+ },
+ {
+ "type_": "element", "source_": "g3",
+ "location_": { "start": { "offset": 8, "line": 1, "column": 9 }, "end": { "offset": 10, "line": 1, "column": 11 } }
+ }
+ ]
+ },
+ }
+ ]
+}
+```
+
+which translates to `seq(c3, seq(e3, g3))`
+
+## 2. Querying & Scheduling
+
+When the user code has been evaluated, we hopefully get a Pattern instance, which we can use to query events from.
+These events can then be used to trigger side effects in the real world. On that note, Events are mostly called Hap(s) in the codebase, because JS already has a built in `Event` class.
+
+### Querying
+
+> Querying = Asking a Pattern for Events within a certain time span
+
+```js
+seq('c3', ['e3', 'g3']) // <--- Pattern
+ .queryArc(0, 2) // query events within 0 and 2 cycles
+ .map((hap) => hap.showWhole()); // make readable
+```
+
+yields
+
+```js
+[
+ '0/1 -> 1/2: c3', // cycle 0
+ '1/2 -> 3/4: e3',
+ '3/4 -> 1/1: g3',
+ '1/1 -> 3/2: c3', // cycle 1
+ '3/2 -> 7/4: e3',
+ '7/4 -> 2/1: g3',
+];
+```
+
+### 🗓️ Scheduling
+
+The scheduler will query events repeatedly, creating a possibly endless loop of time slices.
+Here is a simplified example of how it works
+
+```js
+let step = 0.5; // query interval in seconds
+let tick = 0; // how many intervals have passed
+let pattern = seq('c3', ['e3', 'g3']); // pattern from user
+setInterval(() => {
+ const events = pattern.queryArc(tick * step, ++tick * step);
+ events.forEach((event) => {
+ console.log(event.showWhole());
+ const o = getAudioContext().createOscillator();
+ o.frequency.value = getFreq(event.value);
+ o.start(event.whole.begin);
+ o.stop(event.whole.begin + event.duration);
+ o.connect(getAudioContext().destination);
+ });
+}, step * 1000); // query each "step" seconds
+```
+
+## 3. Sound Output
+
+The third and last step is to use the scheduled events to make sound.
+Patterns are wrapped with param functions to compose different properties of the sound.
+
+```js
+note("[c2(3,8) [
+
+