This commit is contained in:
Felix Roos 2022-02-22 00:48:00 +01:00
parent f6be175af0
commit 413d401567
14 changed files with 873 additions and 471 deletions

View File

@ -107,7 +107,7 @@ class TimeSpan {
} }
return result; return result;
} }
get midpoint() { midpoint() {
return this.begin.add(this.end.sub(this.begin).div(Fraction(2))); return this.begin.add(this.end.sub(this.begin).div(Fraction(2)));
} }
equals(other) { equals(other) {
@ -436,6 +436,9 @@ class Pattern {
edit(...funcs) { edit(...funcs) {
return stack(...funcs.map((func) => func(this))); return stack(...funcs.map((func) => func(this)));
} }
pipe(func) {
return func(this);
}
_bypass(on2) { _bypass(on2) {
on2 = Boolean(parseInt(on2)); on2 = Boolean(parseInt(on2));
return on2 ? silence : this; return on2 ? silence : this;
@ -456,6 +459,24 @@ function pure(value) {
function steady(value) { function steady(value) {
return new Pattern((span) => Hap(void 0, span, value)); return new Pattern((span) => Hap(void 0, span, value));
} }
export const signal = (func) => {
const query = (span) => [new Hap(void 0, span, func(span.midpoint()))];
return new Pattern(query);
};
const _toBipolar = (pat) => pat.fmap((x) => x * 2 - 1);
const _fromBipolar = (pat) => pat.fmap((x) => (x + 1) / 2);
export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t));
export const sine = _fromBipolar(sine2);
export const cosine2 = sine2._early(0.25);
export const cosine = sine._early(0.25);
export const saw = signal((t) => t % 1);
export const saw2 = _toBipolar(saw);
export const isaw = signal((t) => 1 - t % 1);
export const isaw2 = _toBipolar(isaw);
export const tri2 = fastcat(isaw2, saw2);
export const tri = fastcat(isaw, saw);
export const square = signal((t) => Math.floor(t * 2 % 2));
export const square2 = _toBipolar(square);
function reify(thing) { function reify(thing) {
if (thing?.constructor?.name == "Pattern") { if (thing?.constructor?.name == "Pattern") {
return thing; return thing;

19
docs/dist/App.js vendored
View File

@ -1,6 +1,6 @@
import React, {useCallback, useLayoutEffect, useMemo, useRef, useState} from "../_snowpack/pkg/react.js"; import React, {useCallback, useLayoutEffect, useRef, useState} from "../_snowpack/pkg/react.js";
import * as Tone from "../_snowpack/pkg/tone.js"; import * as Tone from "../_snowpack/pkg/tone.js";
import CodeMirror from "./CodeMirror.js"; import CodeMirror, {markEvent} from "./CodeMirror.js";
import cx from "./cx.js"; import cx from "./cx.js";
import {evaluate} from "./evaluate.js"; import {evaluate} from "./evaluate.js";
import logo from "./logo.svg.proxy.js"; import logo from "./logo.svg.proxy.js";
@ -29,20 +29,10 @@ function getRandomTune() {
const randomTune = getRandomTune(); const randomTune = getRandomTune();
function App() { function App() {
const [editor, setEditor] = useState(); const [editor, setEditor] = useState();
const doc = useMemo(() => editor?.getDoc(), [editor]);
const {setCode, setPattern, error, code, cycle, dirty, log, togglePlay, activateCode, pattern, pushLog} = useRepl({ const {setCode, setPattern, error, code, cycle, dirty, log, togglePlay, activateCode, pattern, pushLog} = useRepl({
tune: decoded || randomTune, tune: decoded || randomTune,
defaultSynth, defaultSynth,
onEvent: useCallback((event) => { onEvent: useCallback(markEvent(editor), [editor])
const locs = event.value.locations;
if (!locs) {
return;
}
const marks = locs.map(({start, end}) => doc.markText({line: start.line - 1, ch: start.column}, {line: end.line - 1, ch: end.column}, {css: "background-color: gray;"}));
setTimeout(() => {
marks.forEach((mark) => mark.clear());
}, event.duration * 0.9 * 1e3);
}, [doc])
}); });
const logBox = useRef(); const logBox = useRef();
useLayoutEffect(() => { useLayoutEffect(() => {
@ -112,7 +102,8 @@ function App() {
mode: "javascript", mode: "javascript",
theme: "material", theme: "material",
lineNumbers: true, lineNumbers: true,
styleSelectedText: true styleSelectedText: true,
cursorBlinkRate: 0
}, },
onChange: (_2, __, value) => setCode(value) onChange: (_2, __, value) => setCode(value)
}), /* @__PURE__ */ React.createElement("span", { }), /* @__PURE__ */ React.createElement("span", {

View File

@ -2,14 +2,15 @@ import React from "../_snowpack/pkg/react.js";
import {Controlled as CodeMirror2} from "../_snowpack/pkg/react-codemirror2.js"; import {Controlled as CodeMirror2} from "../_snowpack/pkg/react-codemirror2.js";
import "../_snowpack/pkg/codemirror/mode/javascript/javascript.js"; import "../_snowpack/pkg/codemirror/mode/javascript/javascript.js";
import "../_snowpack/pkg/codemirror/mode/pegjs/pegjs.js"; import "../_snowpack/pkg/codemirror/mode/pegjs/pegjs.js";
import "../_snowpack/pkg/codemirror/theme/material.css.proxy.js";
import "../_snowpack/pkg/codemirror/lib/codemirror.css.proxy.js"; import "../_snowpack/pkg/codemirror/lib/codemirror.css.proxy.js";
import "../_snowpack/pkg/codemirror/theme/material.css.proxy.js";
export default function CodeMirror({value, onChange, options, editorDidMount}) { export default function CodeMirror({value, onChange, options, editorDidMount}) {
options = options || { options = options || {
mode: "javascript", mode: "javascript",
theme: "material", theme: "material",
lineNumbers: true, lineNumbers: true,
styleSelectedText: true styleSelectedText: true,
cursorBlinkRate: 500
}; };
return /* @__PURE__ */ React.createElement(CodeMirror2, { return /* @__PURE__ */ React.createElement(CodeMirror2, {
value, value,
@ -18,3 +19,13 @@ export default function CodeMirror({value, onChange, options, editorDidMount}) {
editorDidMount editorDidMount
}); });
} }
export const markEvent = (editor) => (event) => {
const locs = event.value.locations;
if (!locs || !editor) {
return;
}
const marks = locs.map(({start, end}) => editor.getDoc().markText({line: start.line - 1, ch: start.column}, {line: end.line - 1, ch: end.column}, {css: "background-color: #FFCA28; color: black"}));
setTimeout(() => {
marks.forEach((mark) => mark.clear());
}, event.duration * 0.9 * 1e3);
};

12
docs/dist/evaluate.js vendored
View File

@ -27,10 +27,12 @@ export const evaluate = (code) => {
if (typeof evaluated === "function") { if (typeof evaluated === "function") {
evaluated = evaluated(); evaluated = evaluated();
} }
const pattern = minify(evaluated); if (typeof evaluated === "string") {
if (pattern?.constructor?.name !== "Pattern") { evaluated = strudel.withLocationOffset(minify(evaluated), {start: {line: 1, column: -1}});
const message = `got "${typeof pattern}" instead of pattern`;
throw new Error(message + (typeof pattern === "function" ? ", did you forget to call a function?" : "."));
} }
return {mode: "javascript", pattern}; if (evaluated?.constructor?.name !== "Pattern") {
const message = `got "${typeof evaluated}" instead of pattern`;
throw new Error(message + (typeof evaluated === "function" ? ", did you forget to call a function?" : "."));
}
return {mode: "javascript", pattern: evaluated};
}; };

View File

@ -1,7 +1,13 @@
import { parseScriptWithLocation } from './shift-parser/index.js'; // npm module does not work in the browser import { parseScriptWithLocation } from './shift-parser/index.js'; // npm module does not work in the browser
import traverser from './shift-traverser/index.js'; // npm module does not work in the browser import traverser from './shift-traverser/index.js'; // npm module does not work in the browser
const { replace } = traverser; const { replace } = traverser;
import { LiteralStringExpression, IdentifierExpression, CallExpression, StaticMemberExpression } from '../_snowpack/pkg/shift-ast.js'; import {
LiteralStringExpression,
IdentifierExpression,
CallExpression,
StaticMemberExpression,
Script,
} from '../_snowpack/pkg/shift-ast.js';
import codegen from '../_snowpack/pkg/shift-codegen.js'; import codegen from '../_snowpack/pkg/shift-codegen.js';
import * as strudel from '../_snowpack/link/strudel.js'; import * as strudel from '../_snowpack/link/strudel.js';
@ -12,20 +18,50 @@ const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name);
const addLocations = true; const addLocations = true;
export const addMiniLocations = true; export const addMiniLocations = true;
/*
not supported for highlighting:
- 'b3'.p
- mini('b3') / m('b3')
- 'b3'.m / 'b3'.mini
*/
export default (code) => { export default (code) => {
const ast = parseScriptWithLocation(code); const ast = parseScriptWithLocation(code);
const nodesWithLocation = []; const artificialNodes = [];
const parents = []; const parents = [];
const shifted = replace(ast.tree, { const shifted = replace(ast.tree, {
enter(node, parent) { enter(node, parent) {
parents.push(parent); parents.push(parent);
const isSynthetic = parents.some((p) => nodesWithLocation.includes(p)); const isSynthetic = parents.some((p) => artificialNodes.includes(p));
if (isSynthetic) { if (isSynthetic) {
return node; return node;
} }
const grandparent = parents[parents.length - 2];
const isTimeCat = parent?.type === 'ArrayExpression' && isPatternFactory(grandparent); // replace template string `xxx` with 'xxx'.m
const isMarkable = isPatternFactory(parent) || isTimeCat; if (isBackTickString(node)) {
const minified = getMinified(node.elements[0].rawValue);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// allows to use top level strings, which are normally directives... but we don't need directives
if (node.type === 'Script' && node.directives.length === 1 && !node.statements.length) {
const minified = getMinified(node.directives[0].rawValue);
const wrapped = wrapLocationOffset(minified, node.directives[0], ast.locations, artificialNodes);
return new Script({ directives: [], statements: [wrapped] });
}
// replace double quote string "xxx" with 'xxx'.m
if (isStringWithDoubleQuotes(node, ast.locations, code)) {
const minified = getMinified(node.value);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// replace double quote string "xxx" with 'xxx'.m
if (isStringWithDoubleQuotes(node, ast.locations, code)) {
const minified = getMinified(node.value);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// operator overloading => still not done // operator overloading => still not done
const operators = { const operators = {
'*': 'fast', '*': 'fast',
@ -41,22 +77,28 @@ export default (code) => {
) { ) {
let arg = node.left; let arg = node.left;
if (node.left.type === 'IdentifierExpression') { if (node.left.type === 'IdentifierExpression') {
arg = wrapReify(node.left); arg = wrapFunction('reify', node.left);
} }
return new CallExpression({ return new CallExpression({
callee: new StaticMemberExpression({ callee: new StaticMemberExpression({
property: operators[node.operator], property: operators[node.operator],
object: wrapReify(arg), object: wrapFunction('reify', arg),
}), }),
arguments: [node.right], arguments: [node.right],
}); });
} }
const isMarkable = isPatternArg(parents) || hasModifierCall(parent);
// add to location to pure(x) calls
if (node.type === 'CallExpression' && node.callee.name === 'pure') {
return reifyWithLocation(node.arguments[0].name, node.arguments[0], ast.locations, artificialNodes);
}
// replace pseudo note variables // replace pseudo note variables
if (node.type === 'IdentifierExpression') { if (node.type === 'IdentifierExpression') {
if (isNote(node.name)) { if (isNote(node.name)) {
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name; const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
if (addLocations && isMarkable) { if (addLocations && isMarkable) {
return reifyWithLocation(value, node, ast.locations, nodesWithLocation); return reifyWithLocation(value, node, ast.locations, artificialNodes);
} }
return new LiteralStringExpression({ value }); return new LiteralStringExpression({ value });
} }
@ -66,10 +108,10 @@ export default (code) => {
} }
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) { if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) {
// console.log('add', node); // console.log('add', node);
return reifyWithLocation(node.value, node, ast.locations, nodesWithLocation); return reifyWithLocation(node.value, node, ast.locations, artificialNodes);
} }
if (!addMiniLocations) { if (!addMiniLocations) {
return node; return wrapFunction('reify', node);
} }
// mini notation location handling // mini notation location handling
const miniFunctions = ['mini', 'm']; const miniFunctions = ['mini', 'm'];
@ -81,11 +123,11 @@ export default (code) => {
console.warn('multi arg mini locations not supported yet...'); console.warn('multi arg mini locations not supported yet...');
return node; return node;
} }
return wrapLocationOffset(node, node.arguments, ast.locations, nodesWithLocation); return wrapLocationOffset(node, node.arguments, ast.locations, artificialNodes);
} }
if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) { if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) {
// 'c3'.mini or 'c3'.m // 'c3'.mini or 'c3'.m
return wrapLocationOffset(node, node.object, ast.locations, nodesWithLocation); return wrapLocationOffset(node, node.object, ast.locations, artificialNodes);
} }
return node; return node;
}, },
@ -96,15 +138,58 @@ export default (code) => {
return codegen(shifted); return codegen(shifted);
}; };
function wrapReify(node) { function wrapFunction(name, ...args) {
return new CallExpression({ return new CallExpression({
callee: new IdentifierExpression({ callee: new IdentifierExpression({ name }),
name: 'reify', arguments: args,
}),
arguments: [node],
}); });
} }
function getMinified(value) {
return new StaticMemberExpression({
object: new LiteralStringExpression({ value }),
property: 'm',
});
}
function isBackTickString(node) {
return node.type === 'TemplateExpression' && node.elements.length === 1;
}
function isStringWithDoubleQuotes(node, locations, code) {
if (node.type !== 'LiteralStringExpression') {
return false;
}
const loc = locations.get(node);
const snippet = code.slice(loc.start.offset, loc.end.offset);
return snippet[0] === '"'; // we can trust the end is also ", as the parsing did not fail
}
// returns true if the given parents belong to a pattern argument node
// this is used to check if a node should receive a location for highlighting
function isPatternArg(parents) {
if (!parents.length) {
return false;
}
const ancestors = parents.slice(0, -1);
const parent = parents[parents.length - 1];
if (isPatternFactory(parent)) {
return true;
}
if (parent?.type === 'ArrayExpression') {
return isPatternArg(ancestors);
}
return false;
}
function hasModifierCall(parent) {
// TODO: modifiers are more than composables, for example every is not composable but should be seen as modifier..
// need all prototypes of Pattern
return (
parent?.type === 'StaticMemberExpression' && Object.keys(Pattern.prototype.composable).includes(parent.property)
);
}
function isPatternFactory(node) { function isPatternFactory(node) {
return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name); return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name);
} }
@ -115,7 +200,7 @@ function canBeOverloaded(node) {
} }
// turn node into withLocationOffset(node, location) // turn node into withLocationOffset(node, location)
function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) { function wrapLocationOffset(node, stringNode, locations, artificialNodes) {
// console.log('wrapppp', stringNode); // console.log('wrapppp', stringNode);
const expression = { const expression = {
type: 'CallExpression', type: 'CallExpression',
@ -125,28 +210,22 @@ function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) {
}, },
arguments: [node, getLocationObject(stringNode, locations)], arguments: [node, getLocationObject(stringNode, locations)],
}; };
nodesWithLocation.push(expression); artificialNodes.push(expression);
// console.log('wrapped', codegen(expression)); // console.log('wrapped', codegen(expression));
return expression; return expression;
} }
// turns node in reify(value).withLocation(location), where location is the node's location in the source code // turns node in reify(value).withLocation(location), where location is the node's location in the source code
// with this, the reified pattern can pass its location to the event, to know where to highlight when it's active // with this, the reified pattern can pass its location to the event, to know where to highlight when it's active
function reifyWithLocation(value, node, locations, nodesWithLocation) { function reifyWithLocation(value, node, locations, artificialNodes) {
// console.log('reifyWithLocation', value, node);
const withLocation = new CallExpression({ const withLocation = new CallExpression({
callee: new StaticMemberExpression({ callee: new StaticMemberExpression({
object: new CallExpression({ object: wrapFunction('reify', new LiteralStringExpression({ value })),
callee: new IdentifierExpression({
name: 'reify',
}),
arguments: [new LiteralStringExpression({ value })],
}),
property: 'withLocation', property: 'withLocation',
}), }),
arguments: [getLocationObject(node, locations)], arguments: [getLocationObject(node, locations)],
}); });
nodesWithLocation.push(withLocation); artificialNodes.push(withLocation);
return withLocation; return withLocation;
} }

326
docs/dist/tunes.js vendored
View File

@ -1,7 +1,7 @@
export const timeCatMini = `stack( export const timeCatMini = `stack(
'c3@3 [eb3, g3, [c4 d4]/2]'.mini, "c3@3 [eb3, g3, [c4 d4]/2]",
'c2 g2'.mini, "c2 g2",
'[eb4@5 [f4 eb4 d4]@3] [eb4 c4]/2'.mini.slow(8) "[eb4@5 [f4 eb4 d4]@3] [eb4 c4]/2".slow(8)
)`; )`;
export const timeCat = `stack( export const timeCat = `stack(
timeCat([3, c3], [1, stack(eb3, g3, cat(c4, d4).slow(2))]), timeCat([3, c3], [1, stack(eb3, g3, cat(c4, d4).slow(2))]),
@ -54,47 +54,47 @@ export const tetrisWithFunctions = `stack(sequence(
) )
).slow(16)`; ).slow(16)`;
export const tetris = `stack( export const tetris = `stack(
mini( cat(
'e5 [b4 c5] d5 [c5 b4]', "e5 [b4 c5] d5 [c5 b4]",
'a4 [a4 c5] e5 [d5 c5]', "a4 [a4 c5] e5 [d5 c5]",
'b4 [~ c5] d5 e5', "b4 [~ c5] d5 e5",
'c5 a4 a4 ~', "c5 a4 a4 ~",
'[~ d5] [~ f5] a5 [g5 f5]', "[~ d5] [~ f5] a5 [g5 f5]",
'e5 [~ c5] e5 [d5 c5]', "e5 [~ c5] e5 [d5 c5]",
'b4 [b4 c5] d5 e5', "b4 [b4 c5] d5 e5",
'c5 a4 a4 ~' "c5 a4 a4 ~"
), ),
mini( cat(
'e2 e3 e2 e3 e2 e3 e2 e3', "e2 e3 e2 e3 e2 e3 e2 e3",
'a2 a3 a2 a3 a2 a3 a2 a3', "a2 a3 a2 a3 a2 a3 a2 a3",
'g#2 g#3 g#2 g#3 e2 e3 e2 e3', "g#2 g#3 g#2 g#3 e2 e3 e2 e3",
'a2 a3 a2 a3 a2 a3 b1 c2', "a2 a3 a2 a3 a2 a3 b1 c2",
'd2 d3 d2 d3 d2 d3 d2 d3', "d2 d3 d2 d3 d2 d3 d2 d3",
'c2 c3 c2 c3 c2 c3 c2 c3', "c2 c3 c2 c3 c2 c3 c2 c3",
'b1 b2 b1 b2 e2 e3 e2 e3', "b1 b2 b1 b2 e2 e3 e2 e3",
'a1 a2 a1 a2 a1 a2 a1 a2' "a1 a2 a1 a2 a1 a2 a1 a2",
) )
).slow(16)`; ).slow(16)`;
export const tetrisRev = `stack( export const tetrisRev = `stack(
mini( cat(
'e5 [b4 c5] d5 [c5 b4]', "e5 [b4 c5] d5 [c5 b4]",
'a4 [a4 c5] e5 [d5 c5]', "a4 [a4 c5] e5 [d5 c5]",
'b4 [~ c5] d5 e5', "b4 [~ c5] d5 e5",
'c5 a4 a4 ~', "c5 a4 a4 ~",
'[~ d5] [~ f5] a5 [g5 f5]', "[~ d5] [~ f5] a5 [g5 f5]",
'e5 [~ c5] e5 [d5 c5]', "e5 [~ c5] e5 [d5 c5]",
'b4 [b4 c5] d5 e5', "b4 [b4 c5] d5 e5",
'c5 a4 a4 ~' "c5 a4 a4 ~",
).rev(), ).rev(),
mini( cat(
'e2 e3 e2 e3 e2 e3 e2 e3', "e2 e3 e2 e3 e2 e3 e2 e3",
'a2 a3 a2 a3 a2 a3 a2 a3', "a2 a3 a2 a3 a2 a3 a2 a3",
'g#2 g#3 g#2 g#3 e2 e3 e2 e3', "g#2 g#3 g#2 g#3 e2 e3 e2 e3",
'a2 a3 a2 a3 a2 a3 b1 c2', "a2 a3 a2 a3 a2 a3 b1 c2",
'd2 d3 d2 d3 d2 d3 d2 d3', "d2 d3 d2 d3 d2 d3 d2 d3",
'c2 c3 c2 c3 c2 c3 c2 c3', "c2 c3 c2 c3 c2 c3 c2 c3",
'b1 b2 b1 b2 e2 e3 e2 e3', "b1 b2 b1 b2 e2 e3 e2 e3",
'a1 a2 a1 a2 a1 a2 a1 a2' "a1 a2 a1 a2 a1 a2 a1 a2",
).rev() ).rev()
).slow(16)`; ).slow(16)`;
export const tetrisMini = `\`[[e5 [b4 c5] d5 [c5 b4]] export const tetrisMini = `\`[[e5 [b4 c5] d5 [c5 b4]]
@ -112,7 +112,7 @@ export const tetrisMini = `\`[[e5 [b4 c5] d5 [c5 b4]]
[[d2 d3]*4] [[d2 d3]*4]
[[c2 c3]*4] [[c2 c3]*4]
[[b1 b2]*2 [e2 e3]*2] [[b1 b2]*2 [e2 e3]*2]
[[a1 a2]*4]\`.mini.slow(16) [[a1 a2]*4]\`.slow(16)
`; `;
export const spanish = `slowcat( export const spanish = `slowcat(
stack(c4,eb4,g4), stack(c4,eb4,g4),
@ -126,117 +126,117 @@ export const whirlyStrudel = `sequence(e4, [b2, b3], c4)
.fast(slowcat(1.25, 1, 1.5)) .fast(slowcat(1.25, 1, 1.5))
.every(2, _ => sequence(e4, r, e3, d4, r))`; .every(2, _ => sequence(e4, r, e3, d4, r))`;
export const swimming = `stack( export const swimming = `stack(
mini( cat(
'~', "~",
'~', "~",
'~', "~",
'A5 [F5@2 C5] [D5@2 F5] F5', "A5 [F5@2 C5] [D5@2 F5] F5",
'[C5@2 F5] [F5@2 C6] A5 G5', "[C5@2 F5] [F5@2 C6] A5 G5",
'A5 [F5@2 C5] [D5@2 F5] F5', "A5 [F5@2 C5] [D5@2 F5] F5",
'[C5@2 F5] [Bb5 A5 G5] F5@2', "[C5@2 F5] [Bb5 A5 G5] F5@2",
'A5 [F5@2 C5] [D5@2 F5] F5', "A5 [F5@2 C5] [D5@2 F5] F5",
'[C5@2 F5] [F5@2 C6] A5 G5', "[C5@2 F5] [F5@2 C6] A5 G5",
'A5 [F5@2 C5] [D5@2 F5] F5', "A5 [F5@2 C5] [D5@2 F5] F5",
'[C5@2 F5] [Bb5 A5 G5] F5@2', "[C5@2 F5] [Bb5 A5 G5] F5@2",
'A5 [F5@2 C5] A5 F5', "A5 [F5@2 C5] A5 F5",
'Ab5 [F5@2 Ab5] G5@2', "Ab5 [F5@2 Ab5] G5@2",
'A5 [F5@2 C5] A5 F5', "A5 [F5@2 C5] A5 F5",
'Ab5 [F5@2 C5] C6@2', "Ab5 [F5@2 C5] C6@2",
'A5 [F5@2 C5] [D5@2 F5] F5', "A5 [F5@2 C5] [D5@2 F5] F5",
'[C5@2 F5] [Bb5 A5 G5] F5@2' "[C5@2 F5] [Bb5 A5 G5] F5@2"
), ),
mini( cat(
'[F4,Bb4,D5] [[D4,G4,Bb4]@2 [Bb3,D4,F4]] [[G3,C4,E4]@2 [[Ab3,F4] [A3,Gb4]]] [Bb3,E4,G4]', "[F4,Bb4,D5] [[D4,G4,Bb4]@2 [Bb3,D4,F4]] [[G3,C4,E4]@2 [[Ab3,F4] [A3,Gb4]]] [Bb3,E4,G4]",
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, Bb3, Db3] [F3, Bb3, Db3]]', "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, Bb3, Db3] [F3, Bb3, Db3]]",
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]', "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]', "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
'[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]', "[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]",
'[~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]', "[~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
'[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]', "[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]",
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]', "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
'[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]', "[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]",
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]', "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
'[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]', "[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]",
'[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]', "[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]",
'[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]', "[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]",
'[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]', "[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]",
'[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]', "[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]",
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]', "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
'[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]' "[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]"
), ),
mini( cat(
'[G3 G3 C3 E3]', "[G3 G3 C3 E3]",
'[F2 D2 G2 C2]', "[F2 D2 G2 C2]",
'[F2 D2 G2 C2]', "[F2 D2 G2 C2]",
'[F2 A2 Bb2 B2]', "[F2 A2 Bb2 B2]",
'[A2 Ab2 G2 C2]', "[A2 Ab2 G2 C2]",
'[F2 A2 Bb2 B2]', "[F2 A2 Bb2 B2]",
'[G2 C2 F2 F2]', "[G2 C2 F2 F2]",
'[F2 A2 Bb2 B2]', "[F2 A2 Bb2 B2]",
'[A2 Ab2 G2 C2]', "[A2 Ab2 G2 C2]",
'[F2 A2 Bb2 B2]', "[F2 A2 Bb2 B2]",
'[G2 C2 F2 F2]', "[G2 C2 F2 F2]",
'[Bb2 Bb2 A2 A2]', "[Bb2 Bb2 A2 A2]",
'[Ab2 Ab2 G2 [C2 D2 E2]]', "[Ab2 Ab2 G2 [C2 D2 E2]]",
'[Bb2 Bb2 A2 A2]', "[Bb2 Bb2 A2 A2]",
'[Ab2 Ab2 G2 [C2 D2 E2]]', "[Ab2 Ab2 G2 [C2 D2 E2]]",
'[F2 A2 Bb2 B2]', "[F2 A2 Bb2 B2]",
'[G2 C2 F2 F2]' "[G2 C2 F2 F2]"
) )
).slow(51); ).slow(51);
`; `;
export const giantSteps = `stack( export const giantSteps = `stack(
// melody // melody
mini( cat(
'[F#5 D5] [B4 G4] Bb4 [B4 A4]', "[F#5 D5] [B4 G4] Bb4 [B4 A4]",
'[D5 Bb4] [G4 Eb4] F#4 [G4 F4]', "[D5 Bb4] [G4 Eb4] F#4 [G4 F4]",
'Bb4 [B4 A4] D5 [D#5 C#5]', "Bb4 [B4 A4] D5 [D#5 C#5]",
'F#5 [G5 F5] Bb5 [F#5 F#5]', "F#5 [G5 F5] Bb5 [F#5 F#5]",
), ),
// chords // chords
mini( cat(
'[B^7 D7] [G^7 Bb7] Eb^7 [Am7 D7]', "[B^7 D7] [G^7 Bb7] Eb^7 [Am7 D7]",
'[G^7 Bb7] [Eb^7 F#7] B^7 [Fm7 Bb7]', "[G^7 Bb7] [Eb^7 F#7] B^7 [Fm7 Bb7]",
'Eb^7 [Am7 D7] G^7 [C#m7 F#7]', "Eb^7 [Am7 D7] G^7 [C#m7 F#7]",
'B^7 [Fm7 Bb7] Eb^7 [C#m7 F#7]' "B^7 [Fm7 Bb7] Eb^7 [C#m7 F#7]"
).voicings(['E3', 'G4']), ).voicings(['E3', 'G4']),
// bass // bass
mini( cat(
'[B2 D2] [G2 Bb2] [Eb2 Bb3] [A2 D2]', "[B2 D2] [G2 Bb2] [Eb2 Bb3] [A2 D2]",
'[G2 Bb2] [Eb2 F#2] [B2 F#2] [F2 Bb2]', "[G2 Bb2] [Eb2 F#2] [B2 F#2] [F2 Bb2]",
'[Eb2 Bb2] [A2 D2] [G2 D2] [C#2 F#2]', "[Eb2 Bb2] [A2 D2] [G2 D2] [C#2 F#2]",
'[B2 F#2] [F2 Bb2] [Eb2 Bb3] [C#2 F#2]' "[B2 F#2] [F2 Bb2] [Eb2 Bb3] [C#2 F#2]"
) )
).slow(20);`; ).slow(20);`;
export const giantStepsReggae = `stack( export const giantStepsReggae = `stack(
// melody // melody
mini( cat(
'[F#5 D5] [B4 G4] Bb4 [B4 A4]', "[F#5 D5] [B4 G4] Bb4 [B4 A4]",
'[D5 Bb4] [G4 Eb4] F#4 [G4 F4]', "[D5 Bb4] [G4 Eb4] F#4 [G4 F4]",
'Bb4 [B4 A4] D5 [D#5 C#5]', "Bb4 [B4 A4] D5 [D#5 C#5]",
'F#5 [G5 F5] Bb5 [F#5 [F#5 ~@3]]', "F#5 [G5 F5] Bb5 [F#5 [F#5 ~@3]]",
), ),
// chords // chords
mini( cat(
'[B^7 D7] [G^7 Bb7] Eb^7 [Am7 D7]', "[B^7 D7] [G^7 Bb7] Eb^7 [Am7 D7]",
'[G^7 Bb7] [Eb^7 F#7] B^7 [Fm7 Bb7]', "[G^7 Bb7] [Eb^7 F#7] B^7 [Fm7 Bb7]",
'Eb^7 [Am7 D7] G^7 [C#m7 F#7]', "Eb^7 [Am7 D7] G^7 [C#m7 F#7]",
'B^7 [Fm7 Bb7] Eb^7 [C#m7 F#7]' "B^7 [Fm7 Bb7] Eb^7 [C#m7 F#7]"
) )
.groove('~ [x ~]'.m.fast(4*8)) .groove("~ [x ~]".fast(4*8))
.voicings(['E3', 'G4']), .voicings(['E3', 'G4']),
// bass // bass
mini( cat(
'[B2 D2] [G2 D2] [Eb2 Bb2] [A2 D2]', "[B2 D2] [G2 D2] [Eb2 Bb2] [A2 D2]",
'[G2 Bb2] [Eb2 F#2] [B2 F#2] [F2 Bb2]', "[G2 Bb2] [Eb2 F#2] [B2 F#2] [F2 Bb2]",
'[Eb2 Bb2] [A2 D2] [G2 D2] [C#2 F#2]', "[Eb2 Bb2] [A2 D2] [G2 D2] [C#2 F#2]",
'[B2 F#2] [F2 Bb2] [Eb2 Bb2] [C#2 F#2]' "[B2 F#2] [F2 Bb2] [Eb2 Bb2] [C#2 F#2]"
) )
.groove('x ~'.m.fast(4*8)) .groove("x ~".fast(4*8))
).slow(25)`; ).slow(25)`;
export const transposedChordsHacked = `stack( export const transposedChordsHacked = `stack(
'c2 eb2 g2'.mini, "c2 eb2 g2",
'Cm7'.pure.voicings(['g2','c4']).slow(2) "Cm7".voicings(['g2','c4']).slow(2)
).transpose( ).transpose(
slowcat(1, 2, 3, 2).slow(2) slowcat(1, 2, 3, 2).slow(2)
).transpose(5)`; ).transpose(5)`;
@ -245,24 +245,24 @@ export const scaleTranspose = `stack(f2, f3, c4, ab4)
.scaleTranspose(sequence(0, -1, -2, -3).slow(4)) .scaleTranspose(sequence(0, -1, -2, -3).slow(4))
.transpose(sequence(0, 1).slow(16))`; .transpose(sequence(0, 1).slow(16))`;
export const groove = `stack( export const groove = `stack(
'c2 g2 a2 [e2@2 eb2] d2 a2 g2 [d2 ~ db2]'.mini, "c2 g2 a2 [e2@2 eb2] d2 a2 g2 [d2 ~ db2]",
'[C^7 A7] [Dm7 G7]'.mini.groove('[x@2 x] [~@2 x] [~ x@2]@2 [x ~@2] ~ [~@2 x@4]@2'.mini) "[C^7 A7] [Dm7 G7]".groove("[x@2 x] [~@2 x] [~ x@2]@2 [x ~@2] ~ [~@2 x@4]@2")
.voicings(['G3','A4']) .voicings(['G3','A4'])
).slow(4)`; ).slow(4)`;
export const magicSofa = `stack( export const magicSofa = `stack(
'<C^7 F^7 ~> <Dm7 G7 A7 ~>'.m "<C^7 F^7 ~> <Dm7 G7 A7 ~>"
.every(2, fast(2)) .every(2, fast(2))
.voicings(), .voicings(),
'<c2 f2 g2> <d2 g2 a2 e2>'.m "<c2 f2 g2> <d2 g2 a2 e2>"
).slow(1).transpose.slowcat(0, 2, 3, 4)`; ).slow(1).transpose.slowcat(0, 2, 3, 4)`;
export const confusedPhoneDynamic = `stack('[g2 ~@1.3] [c3 ~@1.3]'.mini.slow(2)) export const confusedPhoneDynamic = `stack("[g2 ~@1.3] [c3 ~@1.3]".slow(2))
.superimpose( .superimpose(
...[-12,7,10,12,24].slice(0,5).map((t,i,{length}) => x => transpose(t,x).late(i/length)) ...[-12,7,10,12,24].slice(0,5).map((t,i,{length}) => x => transpose(t,x).late(i/length))
) )
.scale(sequence('C dorian', 'C mixolydian').slow(4)) .scale(sequence('C dorian', 'C mixolydian').slow(4))
.scaleTranspose(slowcat(0,1,2,1).slow(2)) .scaleTranspose(slowcat(0,1,2,1).slow(2))
.synth('triangle').gain(0.5).filter(1500)`; .synth('triangle').gain(0.5).filter(1500)`;
export const confusedPhone = `'[g2 ~@1.3] [c3 ~@1.3]'.mini export const confusedPhone = `"[g2 ~@1.3] [c3 ~@1.3]"
.superimpose( .superimpose(
transpose(-12).late(0), transpose(-12).late(0),
transpose(7).late(0.1), transpose(7).late(0.1),
@ -280,14 +280,14 @@ export const zeldasRescue = `stack(
[B3@2 D4] [A3@2 [G3 A3]] [B3@2 D4] [A3] [B3@2 D4] [A3@2 [G3 A3]] [B3@2 D4] [A3]
[B3@2 D4] [A4@2 G4] D5@2 [B3@2 D4] [A4@2 G4] D5@2
[D5@2 [C5 B4]] [[C5 B4] G4@2] [C5@2 [B4 A4]] [[B4 A4] E4@2] [D5@2 [C5 B4]] [[C5 B4] G4@2] [C5@2 [B4 A4]] [[B4 A4] E4@2]
[D5@2 [C5 B4]] [[C5 B4] G4 C5] [G5] [~ ~ B3]\`.mini, [D5@2 [C5 B4]] [[C5 B4] G4 C5] [G5] [~ ~ B3]\`,
// bass // bass
\`[[C2 G2] E3@2] [[C2 G2] F#3@2] [[C2 G2] E3@2] [[C2 G2] F#3@2] \`[[C2 G2] E3@2] [[C2 G2] F#3@2] [[C2 G2] E3@2] [[C2 G2] F#3@2]
[[B1 D3] G3@2] [[Bb1 Db3] G3@2] [[A1 C3] G3@2] [[D2 C3] F#3@2] [[B1 D3] G3@2] [[Bb1 Db3] G3@2] [[A1 C3] G3@2] [[D2 C3] F#3@2]
[[C2 G2] E3@2] [[C2 G2] F#3@2] [[C2 G2] E3@2] [[C2 G2] F#3@2] [[C2 G2] E3@2] [[C2 G2] F#3@2] [[C2 G2] E3@2] [[C2 G2] F#3@2]
[[B1 D3] G3@2] [[Bb1 Db3] G3@2] [[A1 C3] G3@2] [[D2 C3] F#3@2] [[B1 D3] G3@2] [[Bb1 Db3] G3@2] [[A1 C3] G3@2] [[D2 C3] F#3@2]
[[F2 C3] E3@2] [[E2 B2] D3@2] [[D2 A2] C3@2] [[C2 G2] B2@2] [[F2 C3] E3@2] [[E2 B2] D3@2] [[D2 A2] C3@2] [[C2 G2] B2@2]
[[F2 C3] E3@2] [[E2 B2] D3@2] [[Eb2 Bb2] Db3@2] [[D2 A2] C3 [F3,G2]]\`.mini [[F2 C3] E3@2] [[E2 B2] D3@2] [[Eb2 Bb2] Db3@2] [[D2 A2] C3 [F3,G2]]\`
).transpose(12).slow(48).tone( ).transpose(12).slow(48).tone(
new PolySynth().chain( new PolySynth().chain(
new Gain(0.3), new Gain(0.3),
@ -296,9 +296,9 @@ export const zeldasRescue = `stack(
Destination) Destination)
)`; )`;
export const technoDrums = `stack( export const technoDrums = `stack(
'c1*2'.m.tone(new Tone.MembraneSynth().toDestination()), "c1*2".tone(new Tone.MembraneSynth().toDestination()),
'~ x'.m.tone(new Tone.NoiseSynth().toDestination()), "~ x".tone(new Tone.NoiseSynth().toDestination()),
'[~ c4]*2'.m.tone(new Tone.MetalSynth().set({envelope:{decay:0.06,sustain:0}}).chain(new Gain(0.5),Destination)) "[~ c4]*2".tone(new Tone.MetalSynth().set({envelope:{decay:0.06,sustain:0}}).chain(new Gain(0.5),Destination))
)`; )`;
export const loungerave = `() => { export const loungerave = `() => {
const delay = new FeedbackDelay(1/8, .2).chain(vol(0.5), out); const delay = new FeedbackDelay(1/8, .2).chain(vol(0.5), out);
@ -309,22 +309,22 @@ export const loungerave = `() => {
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out); const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
const drums = stack( const drums = stack(
'c1*2'.m.tone(kick).bypass('<0@7 1>/8'.m), "c1*2".tone(kick).bypass("<0@7 1>/8"),
'~ <x!7 [x@3 x]>'.m.tone(snare).bypass('<0@7 1>/4'.m), "~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
'[~ c4]*2'.m.tone(hihat) "[~ c4]*2".tone(hihat)
); );
const thru = (x) => x.transpose('<0 1>/8'.m).transpose(1); const thru = (x) => x.transpose("<0 1>/8").transpose(1);
const synths = stack( const synths = stack(
'<C2 Bb1 Ab1 [G1 [G2 G1]]>/2'.m.groove('[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2'.m).edit(thru).tone(bass), "<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".groove("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2").edit(thru).tone(bass),
'<Cm7 Bb7 Fm7 G7b9>/2'.m.groove('~ [x@0.1 ~]'.m).voicings().edit(thru).every(2, early(1/4)).tone(keys).bypass('<0@7 1>/8'.m.early(1/4)) "<Cm7 Bb7 Fm7 G7b9>/2".groove("~ [x@0.1 ~]").voicings().edit(thru).every(2, early(1/4)).tone(keys).bypass("<0@7 1>/8".early(1/4))
) )
return stack( return stack(
drums, drums,
synths synths
) )
//.bypass('<0 1>*4'.m) //.bypass("<0 1>*4")
//.early('0.25 0'.m); //.early("0.25 0");
}`; }`;
export const caverave = `() => { export const caverave = `() => {
const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out); const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out);
@ -335,25 +335,41 @@ export const caverave = `() => {
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out); const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
const drums = stack( const drums = stack(
'c1*2'.m.tone(kick).bypass('<0@7 1>/8'.m), "c1*2".tone(kick).bypass("<0@7 1>/8"),
'~ <x!7 [x@3 x]>'.m.tone(snare).bypass('<0@7 1>/4'.m), "~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
'[~ c4]*2'.m.tone(hihat) "[~ c4]*2".tone(hihat)
); );
const thru = (x) => x.transpose('<0 1>/8'.m).transpose(-1); const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
const synths = stack( const synths = stack(
'<eb4 d4 c4 b3>/2'.m.scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove('[~ x]*2'.m) "<eb4 d4 c4 b3>/2".scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove("[~ x]*2")
.edit( .edit(
scaleTranspose(0).early(0), scaleTranspose(0).early(0),
scaleTranspose(2).early(1/8), scaleTranspose(2).early(1/8),
scaleTranspose(7).early(1/4), scaleTranspose(7).early(1/4),
scaleTranspose(8).early(3/8) scaleTranspose(8).early(3/8)
).edit(thru).tone(keys).bypass('<1 0>/16'.m), ).edit(thru).tone(keys).bypass("<1 0>/16"),
'<C2 Bb1 Ab1 [G1 [G2 G1]]>/2'.m.groove('[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2'.m.fast(2)).edit(thru).tone(bass), "<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".groove("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2".fast(2)).edit(thru).tone(bass),
'<Cm7 Bb7 Fm7 G7b13>/2'.m.groove('~ [x@0.1 ~]'.m.fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass('<0@7 1>/8'.m.early(1/4)) "<Cm7 Bb7 Fm7 G7b13>/2".groove("~ [x@0.1 ~]".fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass("<0@7 1>/8".early(1/4))
) )
return stack( return stack(
drums.fast(2), drums.fast(2),
synths synths
).slow(2); ).slow(2);
}`; }`;
export const callcenterhero = `()=>{
const bpm = 90;
const lead = polysynth().set({...osc('sine4'),...adsr(.004)}).chain(vol(0.15),out)
const bass = fmsynth({...osc('sawtooth6'),...adsr(0.05,.6,0.8,0.1)}).chain(vol(0.6), out);
const s = scale(slowcat('F3 minor', 'Ab3 major', 'Bb3 dorian', 'C4 phrygian dominant').slow(4));
return stack(
"0 2".groove("<x ~> [x ~]").edit(s).scaleTranspose(stack(0,2)).tone(lead),
"<6 7 9 7>".groove("[~ [x ~]*2]*2").edit(s).scaleTranspose("[0,2] [2,4]".fast(2).every(4,rev)).tone(lead),
"-14".groove("[~ x@0.8]*2".early(0.01)).edit(s).tone(bass),
"c2*2".tone(membrane().chain(vol(0.6), out)),
"~ c2".tone(noise().chain(vol(0.2), out)),
"c4*4".tone(metal(adsr(0,.05,0)).chain(vol(0.03), out))
)
.slow(120 / bpm)
}
`;

View File

@ -12,8 +12,10 @@ function useRepl({tune, defaultSynth, autolink = true, onEvent}) {
const [activeCode, setActiveCode] = useState(); const [activeCode, setActiveCode] = useState();
const [log, setLog] = useState(""); const [log, setLog] = useState("");
const [error, setError] = useState(); const [error, setError] = useState();
const [hash, setHash] = useState("");
const [pattern, setPattern] = useState(); const [pattern, setPattern] = useState();
const dirty = code !== activeCode; const dirty = code !== activeCode || error;
const generateHash = () => encodeURIComponent(btoa(code));
const activateCode = (_code = code) => { const activateCode = (_code = code) => {
!cycle.started && cycle.start(); !cycle.started && cycle.start();
broadcast({type: "start", from: id}); broadcast({type: "start", from: id});
@ -27,6 +29,7 @@ function useRepl({tune, defaultSynth, autolink = true, onEvent}) {
if (autolink) { if (autolink) {
window.location.hash = "#" + encodeURIComponent(btoa(code)); window.location.hash = "#" + encodeURIComponent(btoa(code));
} }
setHash(generateHash());
setError(void 0); setError(void 0);
setActiveCode(_code); setActiveCode(_code);
} catch (err) { } catch (err) {
@ -103,7 +106,8 @@ function useRepl({tune, defaultSynth, autolink = true, onEvent}) {
togglePlay, togglePlay,
activateCode, activateCode,
activeCode, activeCode,
pushLog pushLog,
hash
}; };
} }
export default useRepl; export default useRepl;

View File

@ -958,6 +958,9 @@ select {
.flex { .flex {
display: flex; display: flex;
} }
.inline-flex {
display: inline-flex;
}
.contents { .contents {
display: contents; display: contents;
} }
@ -967,6 +970,9 @@ select {
.h-full { .h-full {
height: 100%; height: 100%;
} }
.h-5 {
height: 1.25rem;
}
.min-h-screen { .min-h-screen {
min-height: 100vh; min-height: 100vh;
} }
@ -979,6 +985,9 @@ select {
.w-16 { .w-16 {
width: 4rem; width: 4rem;
} }
.w-5 {
width: 1.25rem;
}
.max-w-3xl { .max-w-3xl {
max-width: 48rem; max-width: 48rem;
} }
@ -991,6 +1000,22 @@ select {
.transform { .transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
} }
@-webkit-keyframes pulse {
50% {
opacity: .5;
}
}
@keyframes pulse {
50% {
opacity: .5;
}
}
.animate-pulse {
-webkit-animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.cursor-not-allowed { .cursor-not-allowed {
cursor: not-allowed; cursor: not-allowed;
} }
@ -1024,9 +1049,15 @@ select {
.overflow-auto { .overflow-auto {
overflow: auto; overflow: auto;
} }
.overflow-hidden {
overflow: hidden;
}
.whitespace-pre { .whitespace-pre {
white-space: pre; white-space: pre;
} }
.rounded-md {
border-radius: 0.375rem;
}
.border { .border {
border-width: 1px; border-width: 1px;
} }
@ -1036,6 +1067,12 @@ select {
.border-b { .border-b {
border-bottom-width: 1px; border-bottom-width: 1px;
} }
.border-t {
border-top-width: 1px;
}
.border-r {
border-right-width: 1px;
}
.border-gray-200 { .border-gray-200 {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity)); border-color: rgb(229 231 235 / var(--tw-border-opacity));
@ -1074,10 +1111,16 @@ select {
.p-2 { .p-2 {
padding: 0.5rem; padding: 0.5rem;
} }
.p-1 {
padding: 0.25rem;
}
.px-2 { .px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
} }
.pr-2 {
padding-right: 0.5rem;
}
.text-right { .text-right {
text-align: right; text-align: right;
} }
@ -1089,6 +1132,10 @@ select {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 1rem; line-height: 1rem;
} }
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
.text-gray-100 { .text-gray-100 {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(243 244 246 / var(--tw-text-opacity)); color: rgb(243 244 246 / var(--tw-text-opacity));
@ -1105,6 +1152,10 @@ select {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity)); color: rgb(148 163 184 / var(--tw-text-opacity));
} }
.text-red-200 {
--tw-text-opacity: 1;
color: rgb(254 202 202 / var(--tw-text-opacity));
}
.filter { .filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
} }

File diff suppressed because one or more lines are too long

View File

@ -7338,29 +7338,28 @@ It aims to be `, /*#__PURE__*/ _react1.mdx("a", {
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out); const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
const drums = stack( const drums = stack(
'c1*2'.m.tone(kick).bypass('<0@7 1>/8'.m), "c1*2".tone(kick).bypass("<0@7 1>/8"),
'~ <x!7 [x@3 x]>'.m.tone(snare).bypass('<0@7 1>/4'.m), "~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
'[~ c4]*2'.m.tone(hihat) "[~ c4]*2".tone(hihat)
); );
const thru = (x) => x.transpose('<0 1>/8'.m).transpose(-1); const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
const synths = stack( const synths = stack(
'<eb4 d4 c4 b3>/2'.m.scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove('[~ x]*2'.m) "<eb4 d4 c4 b3>/2".scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove("[~ x]*2")
.edit( .edit(
scaleTranspose(0).early(0), scaleTranspose(0).early(0),
scaleTranspose(2).early(1/8), scaleTranspose(2).early(1/8),
scaleTranspose(7).early(1/4), scaleTranspose(7).early(1/4),
scaleTranspose(8).early(3/8) scaleTranspose(8).early(3/8)
).edit(thru).tone(keys).bypass('<1 0>/16'.m), ).edit(thru).tone(keys).bypass("<1 0>/16"),
'<C2 Bb1 Ab1 [G1 [G2 G1]]>/2'.m.groove('[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2'.m.fast(2)).edit(thru).tone(bass), "<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".groove("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2".fast(2)).edit(thru).tone(bass),
'<Cm7 Bb7 Fm7 G7b13>/2'.m.groove('~ [x@0.1 ~]'.m.fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass('<0@7 1>/8'.m.early(1/4)) "<Cm7 Bb7 Fm7 G7b13>/2".groove("~ [x@0.1 ~]".fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass("<0@7 1>/8".early(1/4))
) )
return stack( return stack(
drums.fast(2), drums.fast(2),
synths synths
).slow(2); ).slow(2);
}`, }`,
height: 400,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, /*#__PURE__*/ _react1.mdx("a", { }), /*#__PURE__*/ _react1.mdx("p", null, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p", parentName: "p",
@ -7392,7 +7391,6 @@ Before diving deeper into the details, here is a flavor of how the mini language
[[a1 a2]*4] [[a1 a2]*4]
] ]
]/16\``, ]/16\``,
height: 600,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `The snippet above is enclosed in backticks (\`), which allows you to write multi-line strings. }), /*#__PURE__*/ _react1.mdx("p", null, `The snippet above is enclosed in backticks (\`), which allows you to write multi-line strings.
You can also use double quotes (") for single line mini notation.`), /*#__PURE__*/ _react1.mdx("h2", null, `Notes`), /*#__PURE__*/ _react1.mdx("p", null, `Notes are notated with the note letter, followed by the octave number. You can notate flats with `, /*#__PURE__*/ _react1.mdx("inlineCode", { You can also use double quotes (") for single line mini notation.`), /*#__PURE__*/ _react1.mdx("h2", null, `Notes`), /*#__PURE__*/ _react1.mdx("p", null, `Notes are notated with the note letter, followed by the octave number. You can notate flats with `, /*#__PURE__*/ _react1.mdx("inlineCode", {
@ -7496,7 +7494,6 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
stack(b3,d3,fs4), stack(b3,d3,fs4),
stack(b3,e4,g4) stack(b3,e4,g4)
)`, )`,
height: 200,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `The above is equivalent to`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `The above is equivalent to`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>"`, tune: `"<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>"`,
@ -7541,7 +7538,7 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
}, `early`), `.`), /*#__PURE__*/ _react1.mdx("p", null, `There is the shorthand `, /*#__PURE__*/ _react1.mdx("strong", { }, `early`), `.`), /*#__PURE__*/ _react1.mdx("p", null, `There is the shorthand `, /*#__PURE__*/ _react1.mdx("strong", {
parentName: "p" parentName: "p"
}, `p`), ` for this:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }, `p`), ` for this:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.late(0.5))`, tune: `cat(e5, b4.late(0.5))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `late(cycles)`), /*#__PURE__*/ _react1.mdx("p", null, `Like early, but in the other direction:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `late(cycles)`), /*#__PURE__*/ _react1.mdx("p", null, `Like early, but in the other direction:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.late(0.5))`, tune: `cat(e5, b4.p.late(0.5))`,
@ -7550,10 +7547,10 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
tune: `cat(c3,d3,e3,f3).rev()`, tune: `cat(c3,d3,e3,f3).rev()`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `every(n, func)`), /*#__PURE__*/ _react1.mdx("p", null, `Will apply the given function every n cycles:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `every(n, func)`), /*#__PURE__*/ _react1.mdx("p", null, `Will apply the given function every n cycles:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.every(4, late(0.5)))`, tune: `cat(e5, pure(b4).every(4, late(0.5)))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Note that late is called directly. This is a shortcut for:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `Note that late is called directly. This is a shortcut for:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `cat(e5, b4.p.every(4, x => x.late(0.5)))`, tune: `cat(e5, pure(b4).every(4, x => x.late(0.5)))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: should the function really run the first cycle?`), /*#__PURE__*/ _react1.mdx("h3", null, `Functions not documented yet`), /*#__PURE__*/ _react1.mdx("ul", null, /*#__PURE__*/ _react1.mdx("li", { }), /*#__PURE__*/ _react1.mdx("p", null, `TODO: should the function really run the first cycle?`), /*#__PURE__*/ _react1.mdx("h3", null, `Functions not documented yet`), /*#__PURE__*/ _react1.mdx("ul", null, /*#__PURE__*/ _react1.mdx("li", {
parentName: "ul" parentName: "ul"
@ -7591,21 +7588,20 @@ For sharp notes, the letter "s" is used instead of "#", because JavaScript does
"href": "https://github.com/tidalcycles/strudel/blob/main/repl/src/tone.ts" "href": "https://github.com/tidalcycles/strudel/blob/main/repl/src/tone.ts"
}, `Show Source on Github`)), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }, `Show Source on Github`)), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `stack( tune: `stack(
"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~".m "[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~"
.tone(synth(adsr(0,.1,0,0)).chain(out)), .tone(synth(adsr(0,.1,0,0)).chain(out)),
"[c2 c3]*8".m "[c2 c3]*8"
.tone(synth({ .tone(synth({
...osc('sawtooth'), ...osc('sawtooth'),
...adsr(0,.1,0.4,0) ...adsr(0,.1,0.4,0)
}).chain(lowpass(300), out)) }).chain(lowpass(300), out))
).slow(4)`, ).slow(4)`,
height: 300,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `tone(instrument)`), /*#__PURE__*/ _react1.mdx("p", null, `To change the instrument of a pattern, you can pass any `, /*#__PURE__*/ _react1.mdx("a", { }), /*#__PURE__*/ _react1.mdx("h3", null, `tone(instrument)`), /*#__PURE__*/ _react1.mdx("p", null, `To change the instrument of a pattern, you can pass any `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p", parentName: "p",
"href": "https://tonejs.github.io/docs/14.7.77/index.html" "href": "https://tonejs.github.io/docs/14.7.77/index.html"
}, `Tone.js Source`), ` to .tone:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }, `Tone.js Source`), ` to .tone:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(new FMSynth().toDestination())`, .tone(new FMSynth().toDestination())`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `While this works, it is a little bit verbose. To simplify things, all Tone Synths have a shortcut:`), /*#__PURE__*/ _react1.mdx("pre", null, /*#__PURE__*/ _react1.mdx("code", { }), /*#__PURE__*/ _react1.mdx("p", null, `While this works, it is a little bit verbose. To simplify things, all Tone Synths have a shortcut:`), /*#__PURE__*/ _react1.mdx("pre", null, /*#__PURE__*/ _react1.mdx("code", {
@ -7623,15 +7619,15 @@ const polysynth = (options) => new PolySynth(options);
const sampler = (options) => new Sampler(options); const sampler = (options) => new Sampler(options);
const synth = (options) => new Synth(options); const synth = (options) => new Synth(options);
`)), /*#__PURE__*/ _react1.mdx("h3", null, `out`), /*#__PURE__*/ _react1.mdx("p", null, `Shortcut for Tone.Destination. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { `)), /*#__PURE__*/ _react1.mdx("h3", null, `out`), /*#__PURE__*/ _react1.mdx("p", null, `Shortcut for Tone.Destination. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(membrane().chain(out))`, .tone(membrane().chain(out))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `This alone is not really useful, so read on..`), /*#__PURE__*/ _react1.mdx("h3", null, `vol(volume)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Gain Node with the given volume. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `This alone is not really useful, so read on..`), /*#__PURE__*/ _react1.mdx("h3", null, `vol(volume)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Gain Node with the given volume. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(noise().chain(vol(0.5), out))`, .tone(noise().chain(vol(0.5), out))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `osc(type)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper to set the waveform of a synth, monosynth or polysynth:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `osc(type)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper to set the waveform of a synth, monosynth or polysynth:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(osc('sawtooth4')).chain(out))`, .tone(synth(osc('sawtooth4')).chain(out))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `The base types are `, /*#__PURE__*/ _react1.mdx("inlineCode", { }), /*#__PURE__*/ _react1.mdx("p", null, `The base types are `, /*#__PURE__*/ _react1.mdx("inlineCode", {
@ -7643,72 +7639,71 @@ const synth = (options) => new Synth(options);
}, `sawtooth`), `, `, /*#__PURE__*/ _react1.mdx("inlineCode", { }, `sawtooth`), `, `, /*#__PURE__*/ _react1.mdx("inlineCode", {
parentName: "p" parentName: "p"
}, `triangle`), `. You can also append a number between 1 and 32 to reduce the harmonic partials.`), /*#__PURE__*/ _react1.mdx("h3", null, `lowpass(cutoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Filter Node of type lowpass with the given cutoff. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }, `triangle`), `. You can also append a number between 1 and 32 to reduce the harmonic partials.`), /*#__PURE__*/ _react1.mdx("h3", null, `lowpass(cutoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Filter Node of type lowpass with the given cutoff. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(osc('sawtooth')).chain(lowpass(800), out))`, .tone(synth(osc('sawtooth')).chain(lowpass(800), out))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `highpass(cutoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Filter Node of type highpass with the given cutoff. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `highpass(cutoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper that returns a Filter Node of type highpass with the given cutoff. Intended to be used with Tone's .chain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(osc('sawtooth')).chain(highpass(2000), out))`, .tone(synth(osc('sawtooth')).chain(highpass(2000), out))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `adsr(attack, decay?, sustain?, release?)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper to set the envelope of a Tone.js instrument. Intended to be used with Tone's .set:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `adsr(attack, decay?, sustain?, release?)`), /*#__PURE__*/ _react1.mdx("p", null, `Helper to set the envelope of a Tone.js instrument. Intended to be used with Tone's .set:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m.slow(4) tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
.tone(synth(adsr(0,.1,0,0)).chain(out))`, .tone(synth(adsr(0,.1,0,0)).chain(out))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `Experimental: Patternification`), /*#__PURE__*/ _react1.mdx("p", null, `While the above methods work for static sounds, there is also the option to patternify tone methods. }), /*#__PURE__*/ _react1.mdx("h3", null, `Experimental: Patternification`), /*#__PURE__*/ _react1.mdx("p", null, `While the above methods work for static sounds, there is also the option to patternify tone methods.
This is currently experimental, because the performance is not stable, and audio glitches will appear after some time. This is currently experimental, because the performance is not stable, and audio glitches will appear after some time.
It would be great to get this to work without glitches though, because it is fun!`), /*#__PURE__*/ _react1.mdx("h4", null, `synth(type)`), /*#__PURE__*/ _react1.mdx("p", null, `With .synth, you can create a synth with a variable wave type:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { It would be great to get this to work without glitches though, because it is fun!`), /*#__PURE__*/ _react1.mdx("h4", null, `synth(type)`), /*#__PURE__*/ _react1.mdx("p", null, `With .synth, you can create a synth with a variable wave type:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m. tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~"
synth('<sawtooth8 square8>'.m).slow(4)`, .synth("<sawtooth8 square8>").slow(4)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h4", null, `adsr(attack, decay?, sustain?, release?)`), /*#__PURE__*/ _react1.mdx("p", null, `Chainable Envelope helper:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h4", null, `adsr(attack, decay?, sustain?, release?)`), /*#__PURE__*/ _react1.mdx("p", null, `Chainable Envelope helper:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~".m.slow(4). tune: `"[c5 c5 bb4 c5] [~ g4 ~ g4] [c5 f5 e5 c5] ~".slow(4)
synth('sawtooth16').adsr(0,.1,0,0)`, .synth('sawtooth16').adsr(0,.1,0,0)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Due to having more than one argument, this method is not patternified.`), /*#__PURE__*/ _react1.mdx("h4", null, `filter(cuttoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified filter:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `Due to having more than one argument, this method is not patternified.`), /*#__PURE__*/ _react1.mdx("h4", null, `filter(cuttoff)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified filter:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m. tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~"
synth('sawtooth16').filter('[500 2000]*8'.m).slow(4)`, .synth('sawtooth16').filter("[500 2000]*8").slow(4)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h4", null, `gain(value)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified gain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h4", null, `gain(value)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified gain:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".m. tune: `"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~"
synth('sawtooth16').gain('[.2 .8]*8'.m).slow(4)`, .synth('sawtooth16').gain("[.2 .8]*8").slow(4)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h4", null, `autofilter(value)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified autofilter:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h4", null, `autofilter(value)`), /*#__PURE__*/ _react1.mdx("p", null, `Patternified autofilter:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m. tune: `"c2 c3"
synth('sawtooth16').autofilter('<1 4 8>'.m)`, .synth('sawtooth16').autofilter("<1 4 8>"")`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h2", null, `Tonal API`), /*#__PURE__*/ _react1.mdx("p", null, `The Tonal API, uses `, /*#__PURE__*/ _react1.mdx("a", { }), /*#__PURE__*/ _react1.mdx("h2", null, `Tonal API`), /*#__PURE__*/ _react1.mdx("p", null, `The Tonal API, uses `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p", parentName: "p",
"href": "https://github.com/tonaljs/tonal" "href": "https://github.com/tonaljs/tonal"
}, `tonaljs`), ` to provide helpers for musical operations.`), /*#__PURE__*/ _react1.mdx("h3", null, `transpose(semitones)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes all notes to the given number of semitones:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }, `tonaljs`), ` to provide helpers for musical operations.`), /*#__PURE__*/ _react1.mdx("h3", null, `transpose(semitones)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes all notes to the given number of semitones:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.fast(2).transpose('<0 -2 5 3>'.m.slow(2)).transpose(0)`, tune: `"c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).transpose(0)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `This method gets really exciting when we use it with a pattern as above.`), /*#__PURE__*/ _react1.mdx("p", null, `Instead of numbers, scientific interval notation can be used as well:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `This method gets really exciting when we use it with a pattern as above.`), /*#__PURE__*/ _react1.mdx("p", null, `Instead of numbers, scientific interval notation can be used as well:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.fast(2).transpose('<1P -2M 4P 3m>'.m.slow(2)).transpose(1)`, tune: `"c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).transpose(1)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `scale(name)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like scaleTranpose.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `scale(name)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like scaleTranpose.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"0 2 4 6 4 2".m tune: `"0 2 4 6 4 2"
.scale(slowcat('C2 major', 'C2 minor').slow(2))`, .scale(slowcat('C2 major', 'C2 minor').slow(2))`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.`), /*#__PURE__*/ _react1.mdx("p", null, `All the available scale names can be found `, /*#__PURE__*/ _react1.mdx("a", { }), /*#__PURE__*/ _react1.mdx("p", null, `Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.`), /*#__PURE__*/ _react1.mdx("p", null, `All the available scale names can be found `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p", parentName: "p",
"href": "https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts" "href": "https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts"
}, `here`), `.`), /*#__PURE__*/ _react1.mdx("h3", null, `scaleTranspose(steps)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes notes inside the scale by the number of steps:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }, `here`), `.`), /*#__PURE__*/ _react1.mdx("h3", null, `scaleTranspose(steps)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes notes inside the scale by the number of steps:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"-8 [2,4,6]".m tune: `"-8 [2,4,6]"
.scale('C4 bebop major') .scale('C4 bebop major')
.scaleTranspose('<0 -1 -2 -3 -4 -5 -6 -4>'.m)`, .scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `voicings(range?)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into voicings, using the smoothest voice leading possible:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("h3", null, `voicings(range?)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into voicings, using the smoothest voice leading possible:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `stack("<C^7 A7 Dm7 G7>".m.voicings(), '<C3 A2 D3 G2>'.m)`, tune: `stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use voicing collection as first param + patternify.`), /*#__PURE__*/ _react1.mdx("h3", null, `rootNotes(octave = 2)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into root notes of chords in given octave.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use voicing collection as first param + patternify.`), /*#__PURE__*/ _react1.mdx("h3", null, `rootNotes(octave = 2)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into root notes of chords in given octave.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<C^7 A7b13 Dm7 G7>".m.rootNotes(3)`, tune: `"<C^7 A7b13 Dm7 G7>".rootNotes(3)`,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Together with edit, groove and voicings, this can be used to create a basic backing track:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, { }), /*#__PURE__*/ _react1.mdx("p", null, `Together with edit, groove and voicings, this can be used to create a basic backing track:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<C^7 A7b13 Dm7 G7>".m.edit( tune: `"<C^7 A7b13 Dm7 G7>".edit(
x => x.voicings(['d3','g4']).groove('~ x'.m), x => x.voicings(['d3','g4']).groove("~ x"),
x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out)) x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out))
)`, )`,
height: 150,
mdxType: "MiniRepl" mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use range instead of octave. }), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use range instead of octave.
TODO: find out why composition does not work`), /*#__PURE__*/ _react1.mdx("h2", null, `MIDI API`), /*#__PURE__*/ _react1.mdx("p", null, `Strudel also supports midi via `, /*#__PURE__*/ _react1.mdx("a", { TODO: find out why composition does not work`), /*#__PURE__*/ _react1.mdx("h2", null, `MIDI API`), /*#__PURE__*/ _react1.mdx("p", null, `Strudel also supports midi via `, /*#__PURE__*/ _react1.mdx("a", {
@ -7963,44 +7958,97 @@ const defaultSynth = new _tone.PolySynth().chain(new _tone.Gain(0.5), _tone.Dest
release: 0.01 release: 0.01
} }
}); });
function MiniRepl({ tune , height =100 }) { function MiniRepl({ tune , maxHeight =500 }) {
const { code , setCode , activateCode , activeCode , setPattern , error , cycle , dirty , log , togglePlay } = _useReplDefault.default({ const [editor, setEditor] = _react.useState();
const { code , setCode , activateCode , activeCode , setPattern , error , cycle , dirty , log , togglePlay , hash } = _useReplDefault.default({
tune, tune,
defaultSynth, defaultSynth,
autolink: false autolink: false,
onEvent: _react.useCallback(_codeMirror.markEvent(editor), [
editor
])
}); });
const lines = code.split('\n').length;
const height = Math.min(lines * 30 + 30, maxHeight);
return(/*#__PURE__*/ _jsxRuntime.jsxs("div", { return(/*#__PURE__*/ _jsxRuntime.jsxs("div", {
className: "flex space-y-0 overflow-auto", className: "rounded-md overflow-hidden",
style: {
height
},
children: [ children: [
/*#__PURE__*/ _jsxRuntime.jsxs("div", { /*#__PURE__*/ _jsxRuntime.jsxs("div", {
className: "w-16 flex flex-col", className: "flex justify-between bg-slate-700 border-t border-slate-500",
children: [ children: [
/*#__PURE__*/ _jsxRuntime.jsx("button", { /*#__PURE__*/ _jsxRuntime.jsxs("div", {
className: "grow bg-slate-700 border-b border-slate-500 text-white hover:bg-slate-600 ", className: "flex",
onClick: ()=>togglePlay() children: [
, /*#__PURE__*/ _jsxRuntime.jsx("button", {
children: cycle.started ? 'pause' : 'play' className: _cxDefault.default('w-16 flex items-center justify-center p-1 bg-slate-700 border-r border-slate-500 text-white hover:bg-slate-600', cycle.started ? 'animate-pulse' : ''),
onClick: ()=>togglePlay()
,
children: !cycle.started ? /*#__PURE__*/ _jsxRuntime.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "h-5 w-5",
viewBox: "0 0 20 20",
fill: "currentColor",
children: /*#__PURE__*/ _jsxRuntime.jsx("path", {
fillRule: "evenodd",
d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z",
clipRule: "evenodd"
})
}) : /*#__PURE__*/ _jsxRuntime.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "h-5 w-5",
viewBox: "0 0 20 20",
fill: "currentColor",
children: /*#__PURE__*/ _jsxRuntime.jsx("path", {
fillRule: "evenodd",
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z",
clipRule: "evenodd"
})
})
}),
/*#__PURE__*/ _jsxRuntime.jsx("button", {
className: _cxDefault.default('w-16 flex items-center justify-center p-1 border-slate-500 hover:bg-slate-600', dirty ? 'bg-slate-700 border-r border-slate-500 text-white' : 'bg-slate-600 text-slate-400 cursor-not-allowed'),
onClick: ()=>activateCode()
,
children: /*#__PURE__*/ _jsxRuntime.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
className: "h-5 w-5",
viewBox: "0 0 20 20",
fill: "currentColor",
children: /*#__PURE__*/ _jsxRuntime.jsx("path", {
fillRule: "evenodd",
d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z",
clipRule: "evenodd"
})
})
})
]
}), }),
/*#__PURE__*/ _jsxRuntime.jsx("button", { /*#__PURE__*/ _jsxRuntime.jsx("div", {
className: _cxDefault.default('grow border-slate-500 hover:bg-slate-600', activeCode && dirty ? 'bg-slate-700 text-white' : 'bg-slate-600 text-slate-400 cursor-not-allowed'), className: "text-right p-1 text-sm",
onClick: ()=>activateCode() children: error && /*#__PURE__*/ _jsxRuntime.jsx("span", {
, className: "text-red-200",
children: "update" children: error.message
}) })
}),
' '
] ]
}), }),
/*#__PURE__*/ _jsxRuntime.jsx(_codeMirrorDefault.default, { /*#__PURE__*/ _jsxRuntime.jsx("div", {
className: "w-full", className: "flex space-y-0 overflow-auto",
value: code, style: {
options: { height
mode: 'javascript',
theme: 'material',
lineNumbers: true
}, },
onChange: (_, __, value)=>setCode(value) children: /*#__PURE__*/ _jsxRuntime.jsx(_codeMirrorDefault.default, {
className: "w-full",
value: code,
editorDidMount: setEditor,
options: {
mode: 'javascript',
theme: 'material',
lineNumbers: true
},
onChange: (_, __, value)=>setCode(value)
})
}) })
] ]
})); }));
@ -41626,8 +41674,11 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
const [activeCode, setActiveCode] = _react.useState(); const [activeCode, setActiveCode] = _react.useState();
const [log1, setLog] = _react.useState(''); const [log1, setLog] = _react.useState('');
const [error, setError] = _react.useState(); const [error, setError] = _react.useState();
const [hash, setHash] = _react.useState('');
const [pattern, setPattern] = _react.useState(); const [pattern, setPattern] = _react.useState();
const dirty = code !== activeCode; const dirty = code !== activeCode || error;
const generateHash = ()=>encodeURIComponent(btoa(code))
;
const activateCode = (_code = code)=>{ const activateCode = (_code = code)=>{
!cycle1.started && cycle1.start(); !cycle1.started && cycle1.start();
broadcast({ broadcast({
@ -41643,6 +41694,7 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
setPattern(()=>parsed.pattern setPattern(()=>parsed.pattern
); );
if (autolink) window.location.hash = '#' + encodeURIComponent(btoa(code)); if (autolink) window.location.hash = '#' + encodeURIComponent(btoa(code));
setHash(generateHash());
setError(undefined); setError(undefined);
setActiveCode(_code); setActiveCode(_code);
} catch (err) { } catch (err) {
@ -41749,7 +41801,8 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
togglePlay, togglePlay,
activateCode, activateCode,
activeCode, activeCode,
pushLog pushLog,
hash
}; };
} }
exports.default = useRepl; exports.default = useRepl;
@ -41800,14 +41853,19 @@ const evaluate = (code)=>{
// console.log('shapeshifted', shapeshifted); // console.log('shapeshifted', shapeshifted);
let evaluated = eval(shapeshifted); let evaluated = eval(shapeshifted);
if (typeof evaluated === 'function') evaluated = evaluated(); if (typeof evaluated === 'function') evaluated = evaluated();
const pattern = _parse.minify(evaluated); // eval and minify (if user entered a string) if (typeof evaluated === 'string') evaluated = _strudelMjs.withLocationOffset(_parse.minify(evaluated), {
if (pattern?.constructor?.name !== 'Pattern') { start: {
const message = `got "${typeof pattern}" instead of pattern`; line: 1,
throw new Error(message + (typeof pattern === 'function' ? ', did you forget to call a function?' : '.')); column: -1
}
});
if (evaluated?.constructor?.name !== 'Pattern') {
const message = `got "${typeof evaluated}" instead of pattern`;
throw new Error(message + (typeof evaluated === 'function' ? ', did you forget to call a function?' : '.'));
} }
return { return {
mode: 'javascript', mode: 'javascript',
pattern: pattern pattern: evaluated
}; };
}; };
@ -41816,6 +41874,32 @@ var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports); parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "curry", ()=>curry parcelHelpers.export(exports, "curry", ()=>curry
); );
parcelHelpers.export(exports, "signal", ()=>signal
);
parcelHelpers.export(exports, "sine2", ()=>sine2
);
parcelHelpers.export(exports, "sine", ()=>sine
);
parcelHelpers.export(exports, "cosine2", ()=>cosine2
);
parcelHelpers.export(exports, "cosine", ()=>cosine
);
parcelHelpers.export(exports, "saw", ()=>saw
);
parcelHelpers.export(exports, "saw2", ()=>saw2
);
parcelHelpers.export(exports, "isaw", ()=>isaw
);
parcelHelpers.export(exports, "isaw2", ()=>isaw2
);
parcelHelpers.export(exports, "tri2", ()=>tri2
);
parcelHelpers.export(exports, "tri", ()=>tri
);
parcelHelpers.export(exports, "square", ()=>square
);
parcelHelpers.export(exports, "square2", ()=>square2
);
// adds Pattern.prototype.composable to given function as child functions // adds Pattern.prototype.composable to given function as child functions
// then you can do transpose(2).late(0.2) instead of x => x.transpose(2).late(0.2) // then you can do transpose(2).late(0.2) instead of x => x.transpose(2).late(0.2)
parcelHelpers.export(exports, "makeComposable", ()=>makeComposable parcelHelpers.export(exports, "makeComposable", ()=>makeComposable
@ -42010,7 +42094,7 @@ class TimeSpan {
const result = this.intersection(other); const result = this.intersection(other);
return result; return result;
} }
get midpoint() { midpoint() {
return this.begin.add(this.end.sub(this.begin).div(_fractionJsDefault.default(2))); return this.begin.add(this.end.sub(this.begin).div(_fractionJsDefault.default(2)));
} }
equals(other) { equals(other) {
@ -42461,6 +42545,9 @@ class Pattern {
return stack(...funcs.map((func)=>func(this) return stack(...funcs.map((func)=>func(this)
)); ));
} }
pipe(func) {
return func(this);
}
_bypass(on) { _bypass(on) {
on = Boolean(parseInt(on)); on = Boolean(parseInt(on));
return on ? silence : this; return on ? silence : this;
@ -42508,6 +42595,35 @@ function steady(value) {
return new Pattern((span)=>Hap(undefined, span, value) return new Pattern((span)=>Hap(undefined, span, value)
); );
} }
const signal = (func)=>{
const query = (span)=>[
new Hap(undefined, span, func(span.midpoint()))
]
;
return new Pattern(query);
};
const _toBipolar = (pat)=>pat.fmap((x)=>x * 2 - 1
)
;
const _fromBipolar = (pat)=>pat.fmap((x)=>(x + 1) / 2
)
;
const sine2 = signal((t)=>Math.sin(Math.PI * 2 * t)
);
const sine = _fromBipolar(sine2);
const cosine2 = sine2._early(0.25);
const cosine = sine._early(0.25);
const saw = signal((t)=>t % 1
);
const saw2 = _toBipolar(saw);
const isaw = signal((t)=>1 - t % 1
);
const isaw2 = _toBipolar(isaw);
const tri2 = fastcat(isaw2, saw2);
const tri = fastcat(isaw, saw);
const square = signal((t)=>Math.floor(t * 2 % 2)
);
const square2 = _toBipolar(square);
function reify(thing) { function reify(thing) {
// Tunrs something into a pattern, unless it's already a pattern // Tunrs something into a pattern, unless it's already a pattern
if (thing?.constructor?.name == "Pattern") return thing; if (thing?.constructor?.name == "Pattern") return thing;
@ -62614,17 +62730,40 @@ const addLocations = true;
const addMiniLocations = true; const addMiniLocations = true;
exports.default = (code)=>{ exports.default = (code)=>{
const ast = _indexJs.parseScriptWithLocation(code); const ast = _indexJs.parseScriptWithLocation(code);
const nodesWithLocation = []; const artificialNodes = [];
const parents = []; const parents = [];
const shifted = replace(ast.tree, { const shifted = replace(ast.tree, {
enter (node, parent) { enter (node, parent) {
parents.push(parent); parents.push(parent);
const isSynthetic = parents.some((p)=>nodesWithLocation.includes(p) const isSynthetic = parents.some((p)=>artificialNodes.includes(p)
); );
if (isSynthetic) return node; if (isSynthetic) return node;
const grandparent = parents[parents.length - 2]; // replace template string `xxx` with 'xxx'.m
const isTimeCat = parent?.type === 'ArrayExpression' && isPatternFactory(grandparent); if (isBackTickString(node)) {
const isMarkable = isPatternFactory(parent) || isTimeCat; const minified = getMinified(node.elements[0].rawValue);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// allows to use top level strings, which are normally directives... but we don't need directives
if (node.type === 'Script' && node.directives.length === 1 && !node.statements.length) {
const minified = getMinified(node.directives[0].rawValue);
const wrapped = wrapLocationOffset(minified, node.directives[0], ast.locations, artificialNodes);
return new _shiftAst.Script({
directives: [],
statements: [
wrapped
]
});
}
// replace double quote string "xxx" with 'xxx'.m
if (isStringWithDoubleQuotes(node, ast.locations, code)) {
const minified = getMinified(node.value);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// replace double quote string "xxx" with 'xxx'.m
if (isStringWithDoubleQuotes(node, ast.locations, code)) {
const minified = getMinified(node.value);
return wrapLocationOffset(minified, node, ast.locations, artificialNodes);
}
// operator overloading => still not done // operator overloading => still not done
const operators = { const operators = {
'*': 'fast', '*': 'fast',
@ -62638,22 +62777,25 @@ exports.default = (code)=>{
'IdentifierExpression' 'IdentifierExpression'
].includes(node.right?.type) && canBeOverloaded(node.left)) { ].includes(node.right?.type) && canBeOverloaded(node.left)) {
let arg = node.left; let arg = node.left;
if (node.left.type === 'IdentifierExpression') arg = wrapReify(node.left); if (node.left.type === 'IdentifierExpression') arg = wrapFunction('reify', node.left);
return new _shiftAst.CallExpression({ return new _shiftAst.CallExpression({
callee: new _shiftAst.StaticMemberExpression({ callee: new _shiftAst.StaticMemberExpression({
property: operators[node.operator], property: operators[node.operator],
object: wrapReify(arg) object: wrapFunction('reify', arg)
}), }),
arguments: [ arguments: [
node.right node.right
] ]
}); });
} }
const isMarkable = isPatternArg(parents) || hasModifierCall(parent);
// add to location to pure(x) calls
if (node.type === 'CallExpression' && node.callee.name === 'pure') return reifyWithLocation(node.arguments[0].name, node.arguments[0], ast.locations, artificialNodes);
// replace pseudo note variables // replace pseudo note variables
if (node.type === 'IdentifierExpression') { if (node.type === 'IdentifierExpression') {
if (isNote(node.name)) { if (isNote(node.name)) {
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name; const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
if (addLocations && isMarkable) return reifyWithLocation(value, node, ast.locations, nodesWithLocation); if (addLocations && isMarkable) return reifyWithLocation(value, node, ast.locations, artificialNodes);
return new _shiftAst.LiteralStringExpression({ return new _shiftAst.LiteralStringExpression({
value value
}); });
@ -62663,8 +62805,8 @@ exports.default = (code)=>{
}); });
} }
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) // console.log('add', node); if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) // console.log('add', node);
return reifyWithLocation(node.value, node, ast.locations, nodesWithLocation); return reifyWithLocation(node.value, node, ast.locations, artificialNodes);
if (!addMiniLocations) return node; if (!addMiniLocations) return wrapFunction('reify', node);
// mini notation location handling // mini notation location handling
const miniFunctions = [ const miniFunctions = [
'mini', 'mini',
@ -62678,10 +62820,10 @@ exports.default = (code)=>{
console.warn('multi arg mini locations not supported yet...'); console.warn('multi arg mini locations not supported yet...');
return node; return node;
} }
return wrapLocationOffset(node, node.arguments, ast.locations, nodesWithLocation); return wrapLocationOffset(node, node.arguments, ast.locations, artificialNodes);
} }
if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) // 'c3'.mini or 'c3'.m if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) // 'c3'.mini or 'c3'.m
return wrapLocationOffset(node, node.object, ast.locations, nodesWithLocation); return wrapLocationOffset(node, node.object, ast.locations, artificialNodes);
return node; return node;
}, },
leave () { leave () {
@ -62690,16 +62832,46 @@ exports.default = (code)=>{
}); });
return _shiftCodegenDefault.default(shifted); return _shiftCodegenDefault.default(shifted);
}; };
function wrapReify(node) { function wrapFunction(name, ...args) {
return new _shiftAst.CallExpression({ return new _shiftAst.CallExpression({
callee: new _shiftAst.IdentifierExpression({ callee: new _shiftAst.IdentifierExpression({
name: 'reify' name
}), }),
arguments: [ arguments: args
node
]
}); });
} }
function getMinified(value) {
return new _shiftAst.StaticMemberExpression({
object: new _shiftAst.LiteralStringExpression({
value
}),
property: 'm'
});
}
function isBackTickString(node) {
return node.type === 'TemplateExpression' && node.elements.length === 1;
}
function isStringWithDoubleQuotes(node, locations, code) {
if (node.type !== 'LiteralStringExpression') return false;
const loc = locations.get(node);
const snippet = code.slice(loc.start.offset, loc.end.offset);
return snippet[0] === '"'; // we can trust the end is also ", as the parsing did not fail
}
// returns true if the given parents belong to a pattern argument node
// this is used to check if a node should receive a location for highlighting
function isPatternArg(parents) {
if (!parents.length) return false;
const ancestors = parents.slice(0, -1);
const parent = parents[parents.length - 1];
if (isPatternFactory(parent)) return true;
if (parent?.type === 'ArrayExpression') return isPatternArg(ancestors);
return false;
}
function hasModifierCall(parent) {
// TODO: modifiers are more than composables, for example every is not composable but should be seen as modifier..
// need all prototypes of Pattern
return parent?.type === 'StaticMemberExpression' && Object.keys(Pattern.prototype.composable).includes(parent.property);
}
function isPatternFactory(node) { function isPatternFactory(node) {
return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name); return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name);
} }
@ -62708,7 +62880,7 @@ function canBeOverloaded(node) {
// TODO: support sequence(c3).transpose(3).x.y.z // TODO: support sequence(c3).transpose(3).x.y.z
} }
// turn node into withLocationOffset(node, location) // turn node into withLocationOffset(node, location)
function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) { function wrapLocationOffset(node, stringNode, locations, artificialNodes) {
// console.log('wrapppp', stringNode); // console.log('wrapppp', stringNode);
const expression = { const expression = {
type: 'CallExpression', type: 'CallExpression',
@ -62721,33 +62893,25 @@ function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) {
getLocationObject(stringNode, locations) getLocationObject(stringNode, locations)
] ]
}; };
nodesWithLocation.push(expression); artificialNodes.push(expression);
// console.log('wrapped', codegen(expression)); // console.log('wrapped', codegen(expression));
return expression; return expression;
} }
// turns node in reify(value).withLocation(location), where location is the node's location in the source code // turns node in reify(value).withLocation(location), where location is the node's location in the source code
// with this, the reified pattern can pass its location to the event, to know where to highlight when it's active // with this, the reified pattern can pass its location to the event, to know where to highlight when it's active
function reifyWithLocation(value, node, locations, nodesWithLocation) { function reifyWithLocation(value, node, locations, artificialNodes) {
// console.log('reifyWithLocation', value, node);
const withLocation = new _shiftAst.CallExpression({ const withLocation = new _shiftAst.CallExpression({
callee: new _shiftAst.StaticMemberExpression({ callee: new _shiftAst.StaticMemberExpression({
object: new _shiftAst.CallExpression({ object: wrapFunction('reify', new _shiftAst.LiteralStringExpression({
callee: new _shiftAst.IdentifierExpression({ value
name: 'reify' })),
}),
arguments: [
new _shiftAst.LiteralStringExpression({
value
})
]
}),
property: 'withLocation' property: 'withLocation'
}), }),
arguments: [ arguments: [
getLocationObject(node, locations) getLocationObject(node, locations)
] ]
}); });
nodesWithLocation.push(withLocation); artificialNodes.push(withLocation);
return withLocation; return withLocation;
} }
// returns ast for source location object // returns ast for source location object
@ -98032,20 +98196,24 @@ exports.default = usePostMessage;
},{"react":"21dqq","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"f5BgG":[function(require,module,exports) { },{"react":"21dqq","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"f5BgG":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports); parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "markEvent", ()=>markEvent
);
var _jsxRuntime = require("react/jsx-runtime"); var _jsxRuntime = require("react/jsx-runtime");
var _react = require("react"); var _react = require("react");
var _reactDefault = parcelHelpers.interopDefault(_react); var _reactDefault = parcelHelpers.interopDefault(_react);
var _reactCodemirror2 = require("react-codemirror2"); var _reactCodemirror2 = require("react-codemirror2");
var _javascriptJs = require("codemirror/mode/javascript/javascript.js"); var _javascriptJs = require("codemirror/mode/javascript/javascript.js");
var _pegjsJs = require("codemirror/mode/pegjs/pegjs.js"); var _pegjsJs = require("codemirror/mode/pegjs/pegjs.js");
var _materialCss = require("codemirror/theme/material.css"); // import 'codemirror/theme/material.css';
var _codemirrorCss = require("codemirror/lib/codemirror.css"); var _codemirrorCss = require("codemirror/lib/codemirror.css");
var _materialCss = require("codemirror/theme/material.css");
function CodeMirror({ value , onChange , options , editorDidMount }) { function CodeMirror({ value , onChange , options , editorDidMount }) {
options = options || { options = options || {
mode: 'javascript', mode: 'javascript',
theme: 'material', theme: 'material',
lineNumbers: true, lineNumbers: true,
styleSelectedText: true styleSelectedText: true,
cursorBlinkRate: 500
}; };
return(/*#__PURE__*/ _jsxRuntime.jsx(_reactCodemirror2.Controlled, { return(/*#__PURE__*/ _jsxRuntime.jsx(_reactCodemirror2.Controlled, {
value: value, value: value,
@ -98055,8 +98223,30 @@ function CodeMirror({ value , onChange , options , editorDidMount }) {
})); }));
} }
exports.default = CodeMirror; exports.default = CodeMirror;
const markEvent = (editor)=>(event)=>{
const locs = event.value.locations;
if (!locs || !editor) return;
// mark active event
const marks = locs.map(({ start , end })=>editor.getDoc().markText({
line: start.line - 1,
ch: start.column
}, {
line: end.line - 1,
ch: end.column
}, {
css: 'background-color: #FFCA28; color: black'
})
);
//Tone.Transport.schedule(() => { // problem: this can be cleared by scheduler...
setTimeout(()=>{
marks.forEach((mark)=>mark.clear()
);
// }, '+' + event.duration * 0.5);
}, event.duration * 900);
}
;
},{"react/jsx-runtime":"6AEwr","react":"21dqq","react-codemirror2":"l8gGc","codemirror/mode/javascript/javascript.js":"6YWC8","codemirror/mode/pegjs/pegjs.js":"ishmS","codemirror/theme/material.css":"5kHRb","codemirror/lib/codemirror.css":"4uIDj","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l8gGc":[function(require,module,exports) { },{"react/jsx-runtime":"6AEwr","react":"21dqq","react-codemirror2":"l8gGc","codemirror/mode/javascript/javascript.js":"6YWC8","codemirror/mode/pegjs/pegjs.js":"ishmS","codemirror/lib/codemirror.css":"4uIDj","codemirror/theme/material.css":"5kHRb","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l8gGc":[function(require,module,exports) {
'use strict'; 'use strict';
var global = arguments[3]; var global = arguments[3];
function _extends() { function _extends() {
@ -109263,7 +109453,7 @@ exports.UnControlled = UnControlled;
}, "javascript"); }, "javascript");
}); });
},{"../../lib/codemirror":"2Peje","../javascript/javascript":"6YWC8"}],"5kHRb":[function() {},{}],"4uIDj":[function() {},{}],"aTay5":[function(require,module,exports) { },{"../../lib/codemirror":"2Peje","../javascript/javascript":"6YWC8"}],"4uIDj":[function() {},{}],"5kHRb":[function() {},{}],"aTay5":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports); parcelHelpers.defineInteropFlag(exports);
function cx(...classes) { function cx(...classes) {
@ -109273,4 +109463,4 @@ exports.default = cx;
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2") },{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
//# sourceMappingURL=index.a96519ca.js.map //# sourceMappingURL=index.fbb1ad94.js.map

File diff suppressed because one or more lines are too long

View File

@ -695,12 +695,16 @@ Ensure the default browser behavior of the `hidden` attribute.
display: block; display: block;
}.flex { }.flex {
display: flex; display: flex;
}.inline-flex {
display: inline-flex;
}.contents { }.contents {
display: contents; display: contents;
}.h-16 { }.h-16 {
height: 4rem; height: 4rem;
}.h-full { }.h-full {
height: 100%; height: 100%;
}.h-5 {
height: 1.25rem;
}.min-h-screen { }.min-h-screen {
min-height: 100vh; min-height: 100vh;
}.min-h-\[200px\] { }.min-h-\[200px\] {
@ -709,6 +713,8 @@ Ensure the default browser behavior of the `hidden` attribute.
width: 100%; width: 100%;
}.w-16 { }.w-16 {
width: 4rem; width: 4rem;
}.w-5 {
width: 1.25rem;
}.max-w-3xl { }.max-w-3xl {
max-width: 48rem; max-width: 48rem;
}.flex-none { }.flex-none {
@ -717,6 +723,19 @@ Ensure the default browser behavior of the `hidden` attribute.
flex-grow: 1; flex-grow: 1;
}.transform { }.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}@-webkit-keyframes pulse {
50% {
opacity: .5;
}
}@keyframes pulse {
50% {
opacity: .5;
}
}.animate-pulse {
-webkit-animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}.cursor-not-allowed { }.cursor-not-allowed {
cursor: not-allowed; cursor: not-allowed;
}.flex-col { }.flex-col {
@ -741,14 +760,22 @@ Ensure the default browser behavior of the `hidden` attribute.
margin-bottom: calc(0px * var(--tw-space-y-reverse)); margin-bottom: calc(0px * var(--tw-space-y-reverse));
}.overflow-auto { }.overflow-auto {
overflow: auto; overflow: auto;
}.overflow-hidden {
overflow: hidden;
}.whitespace-pre { }.whitespace-pre {
white-space: pre; white-space: pre;
}.rounded-md {
border-radius: 0.375rem;
}.border { }.border {
border-width: 1px; border-width: 1px;
}.border-0 { }.border-0 {
border-width: 0px; border-width: 0px;
}.border-b { }.border-b {
border-bottom-width: 1px; border-bottom-width: 1px;
}.border-t {
border-top-width: 1px;
}.border-r {
border-right-width: 1px;
}.border-gray-200 { }.border-gray-200 {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity)); border-color: rgb(229 231 235 / var(--tw-border-opacity));
@ -777,9 +804,13 @@ Ensure the default browser behavior of the `hidden` attribute.
padding: 1rem; padding: 1rem;
}.p-2 { }.p-2 {
padding: 0.5rem; padding: 0.5rem;
}.p-1 {
padding: 0.25rem;
}.px-2 { }.px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
}.pr-2 {
padding-right: 0.5rem;
}.text-right { }.text-right {
text-align: right; text-align: right;
}.text-2xl { }.text-2xl {
@ -788,6 +819,9 @@ Ensure the default browser behavior of the `hidden` attribute.
}.text-xs { }.text-xs {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 1rem; line-height: 1rem;
}.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}.text-gray-100 { }.text-gray-100 {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(243 244 246 / var(--tw-text-opacity)); color: rgb(243 244 246 / var(--tw-text-opacity));
@ -800,6 +834,9 @@ Ensure the default browser behavior of the `hidden` attribute.
}.text-slate-400 { }.text-slate-400 {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity)); color: rgb(148 163 184 / var(--tw-text-opacity));
}.text-red-200 {
--tw-text-opacity: 1;
color: rgb(254 202 202 / var(--tw-text-opacity));
}.filter { }.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}.react-codemirror2, }.react-codemirror2,
@ -822,148 +859,6 @@ Ensure the default browser behavior of the `hidden` attribute.
--tw-ring-color: rgb(30 41 59 / var(--tw-ring-opacity)); --tw-ring-color: rgb(30 41 59 / var(--tw-ring-opacity));
} }
/*
Name: material
Author: Mattia Astorino (http://github.com/equinusocio)
Website: https://material-theme.site/
*/
.cm-s-material.CodeMirror {
background-color: #263238;
color: #EEFFFF;
}
.cm-s-material .CodeMirror-gutters {
background: #263238;
color: #546E7A;
border: none;
}
.cm-s-material .CodeMirror-guttermarker,
.cm-s-material .CodeMirror-guttermarker-subtle,
.cm-s-material .CodeMirror-linenumber {
color: #546E7A;
}
.cm-s-material .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
.cm-s-material.cm-fat-cursor .CodeMirror-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material .cm-animate-fat-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material.CodeMirror-focused div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::selection,
.cm-s-material .CodeMirror-line>span::selection,
.cm-s-material .CodeMirror-line>span>span::selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::-moz-selection,
.cm-s-material .CodeMirror-line>span::-moz-selection,
.cm-s-material .CodeMirror-line>span>span::-moz-selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.5);
}
.cm-s-material .cm-keyword {
color: #C792EA;
}
.cm-s-material .cm-operator {
color: #89DDFF;
}
.cm-s-material .cm-variable-2 {
color: #EEFFFF;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #f07178;
}
.cm-s-material .cm-builtin {
color: #FFCB6B;
}
.cm-s-material .cm-atom {
color: #F78C6C;
}
.cm-s-material .cm-number {
color: #FF5370;
}
.cm-s-material .cm-def {
color: #82AAFF;
}
.cm-s-material .cm-string {
color: #C3E88D;
}
.cm-s-material .cm-string-2 {
color: #f07178;
}
.cm-s-material .cm-comment {
color: #546E7A;
}
.cm-s-material .cm-variable {
color: #f07178;
}
.cm-s-material .cm-tag {
color: #FF5370;
}
.cm-s-material .cm-meta {
color: #FFCB6B;
}
.cm-s-material .cm-attribute {
color: #C792EA;
}
.cm-s-material .cm-property {
color: #C792EA;
}
.cm-s-material .cm-qualifier {
color: #DECB6B;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #DECB6B;
}
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #FF5370;
}
.cm-s-material .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}
/* BASICS */ /* BASICS */
.CodeMirror { .CodeMirror {
@ -1309,4 +1204,146 @@ div.CodeMirror-dragcursors {
/* Help users use markselection to safely style text background */ /* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; } span.CodeMirror-selectedtext { background: none; }
/*# sourceMappingURL=index.1e09ac22.css.map */ /*
Name: material
Author: Mattia Astorino (http://github.com/equinusocio)
Website: https://material-theme.site/
*/
.cm-s-material.CodeMirror {
background-color: #263238;
color: #EEFFFF;
}
.cm-s-material .CodeMirror-gutters {
background: #263238;
color: #546E7A;
border: none;
}
.cm-s-material .CodeMirror-guttermarker,
.cm-s-material .CodeMirror-guttermarker-subtle,
.cm-s-material .CodeMirror-linenumber {
color: #546E7A;
}
.cm-s-material .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
.cm-s-material.cm-fat-cursor .CodeMirror-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material .cm-animate-fat-cursor {
background-color: #5d6d5c80 !important;
}
.cm-s-material div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material.CodeMirror-focused div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::selection,
.cm-s-material .CodeMirror-line>span::selection,
.cm-s-material .CodeMirror-line>span>span::selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-line::-moz-selection,
.cm-s-material .CodeMirror-line>span::-moz-selection,
.cm-s-material .CodeMirror-line>span>span::-moz-selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.5);
}
.cm-s-material .cm-keyword {
color: #C792EA;
}
.cm-s-material .cm-operator {
color: #89DDFF;
}
.cm-s-material .cm-variable-2 {
color: #EEFFFF;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #f07178;
}
.cm-s-material .cm-builtin {
color: #FFCB6B;
}
.cm-s-material .cm-atom {
color: #F78C6C;
}
.cm-s-material .cm-number {
color: #FF5370;
}
.cm-s-material .cm-def {
color: #82AAFF;
}
.cm-s-material .cm-string {
color: #C3E88D;
}
.cm-s-material .cm-string-2 {
color: #f07178;
}
.cm-s-material .cm-comment {
color: #546E7A;
}
.cm-s-material .cm-variable {
color: #f07178;
}
.cm-s-material .cm-tag {
color: #FF5370;
}
.cm-s-material .cm-meta {
color: #FFCB6B;
}
.cm-s-material .cm-attribute {
color: #C792EA;
}
.cm-s-material .cm-property {
color: #C792EA;
}
.cm-s-material .cm-qualifier {
color: #DECB6B;
}
.cm-s-material .cm-variable-3,
.cm-s-material .cm-type {
color: #DECB6B;
}
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #FF5370;
}
.cm-s-material .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}
/*# sourceMappingURL=index.fd7d9b66.css.map */

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico"> <link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico">
<link rel="stylesheet" type="text/css" href="/tutorial/index.1e09ac22.css"> <link rel="stylesheet" type="text/css" href="/tutorial/index.fd7d9b66.css">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Strudel REPL"> <meta name="description" content="Strudel REPL">
<title>Strudel Tutorial</title> <title>Strudel Tutorial</title>
@ -11,6 +11,6 @@
<body> <body>
<div id="root"></div> <div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/tutorial/index.a96519ca.js" defer=""></script> <script src="/tutorial/index.fbb1ad94.js" defer=""></script>
</body> </body>
</html> </html>