@grame/faust-web-component 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,451 +0,0 @@
1
- import { icon } from "@fortawesome/fontawesome-svg-core"
2
- import { IFaustMonoWebAudioNode } from "@grame/faustwasm"
3
- import { FaustUI } from "@shren/faust-ui"
4
- import faustCSS from "@shren/faust-ui/dist/esm/index.css?inline"
5
- import Split from "split.js"
6
- import { faustPromise, audioCtx, compiler, svgDiagrams, mono_generator, poly_generator, getInputDevices, deviceUpdateCallbacks, accessMIDIDevice, midiInputCallback, extractMidiAndNvoices } from "./common"
7
- import { createEditor, setError, clearError } from "./editor"
8
- import { Scope } from "./scope"
9
- import faustSvg from "./faustText.svg"
10
-
11
- const template = document.createElement("template")
12
- template.innerHTML = `
13
- <div id="root">
14
- <div id="controls">
15
- <button title="Run" class="button" id="run" disabled>${icon({ prefix: "fas", iconName: "play" }).html[0]}</button>
16
- <button title="Stop" class="button" id="stop" disabled>${icon({ prefix: "fas", iconName: "stop" }).html[0]}</button>
17
- <a title="Open in Faust IDE" id="ide" href="https://faustide.grame.fr/" class="button" target="_blank">${icon({ prefix: "fas", iconName: "up-right-from-square" }).html[0]}</a>
18
- <select id="audio-input" class="dropdown" disabled>
19
- <option>Audio input</option>
20
- </select>
21
- <!-- TODO: MIDI input
22
- <select id="midi-input" class="dropdown" disabled>
23
- <option>MIDI input</option>
24
- </select>
25
- -->
26
- <!-- TODO: volume control? <input id="volume" type="range" min="0" max="100"> -->
27
- <a title="Faust website" id="faust" href="https://faust.grame.fr/" target="_blank"><img src="${faustSvg}" height="15px" /></a>
28
- </div>
29
- <div id="content">
30
- <div id="editor"></div>
31
- <div id="sidebar">
32
- <div id="sidebar-buttons">
33
- <button title="Controls" id="tab-ui" class="button tab" disabled>${icon({ prefix: "fas", iconName: "sliders" }).html[0]}</button>
34
- <button title="Block Diagram" id="tab-diagram" class="button tab" disabled>${icon({ prefix: "fas", iconName: "diagram-project" }).html[0]}</button>
35
- <button title="Scope" id="tab-scope" class="button tab" disabled>${icon({ prefix: "fas", iconName: "wave-square" }).html[0]}</button>
36
- <button title="Spectrum" id="tab-spectrum" class="button tab" disabled>${icon({ prefix: "fas", iconName: "chart-line" }).html[0]}</button>
37
- </div>
38
- <div id="sidebar-content">
39
- <div id="faust-ui"></div>
40
- <div id="faust-diagram"></div>
41
- <div id="faust-scope"></div>
42
- <div id="faust-spectrum"></div>
43
- </div>
44
- </div>
45
- </div>
46
- </div>
47
- <style>
48
- #root {
49
- border: 1px solid black;
50
- border-radius: 5px;
51
- box-sizing: border-box;
52
- }
53
-
54
- *, *:before, *:after {
55
- box-sizing: inherit;
56
- }
57
-
58
- #controls {
59
- background-color: #384d64;
60
- border-bottom: 1px solid black;
61
- display: flex;
62
- }
63
-
64
- #faust {
65
- margin-left: auto;
66
- margin-right: 10px;
67
- display: flex;
68
- align-items: center;
69
- }
70
-
71
- #faust-ui {
72
- width: 232px;
73
- max-height: 150px;
74
- }
75
-
76
- #faust-scope, #faust-spectrum {
77
- min-width: 232px;
78
- min-height: 150px;
79
- }
80
-
81
- #faust-diagram {
82
- max-width: 232px;
83
- height: 150px;
84
- }
85
-
86
- #content {
87
- display: flex;
88
- }
89
-
90
- #editor {
91
- flex-grow: 1;
92
- overflow-y: auto;
93
- }
94
-
95
- #editor .cm-editor {
96
- height: 100%;
97
- }
98
-
99
- .cm-diagnostic {
100
- font-family: monospace;
101
- }
102
-
103
- .cm-diagnostic-error {
104
- background-color: #fdf2f5 !important;
105
- color: #a4000f !important;
106
- border-color: #a4000f !important;
107
- }
108
-
109
- #sidebar {
110
- display: flex;
111
- max-width: 100%;
112
- }
113
-
114
- .tab {
115
- flex-grow: 1;
116
- }
117
-
118
- #sidebar-buttons .tab.active {
119
- background-color: #bbb;
120
- }
121
-
122
- #sidebar-buttons {
123
- background-color: #f5f5f5;
124
- display: flex;
125
- flex-direction: column;
126
- }
127
-
128
- #sidebar-buttons .button {
129
- background-color: #f5f5f5;
130
- color: #000;
131
- width: 20px;
132
- height: 20px;
133
- padding: 4px;
134
- }
135
-
136
- #sidebar-buttons .button:hover {
137
- background-color: #ddd;
138
- }
139
-
140
- #sidebar-buttons .button:active {
141
- background-color: #aaa;
142
- }
143
-
144
- #sidebar-content {
145
- background-color: #fff;
146
- border-left: 1px solid #ccc;
147
- overflow: auto;
148
- flex-grow: 1;
149
- max-height: 100%;
150
- }
151
-
152
- #sidebar-content > div {
153
- display: none;
154
- }
155
-
156
- #sidebar-content > div.active {
157
- display: block;
158
- }
159
-
160
- a.button {
161
- appearance: button;
162
- }
163
-
164
- .button {
165
- background-color: #384d64;
166
- border: 0;
167
- padding: 5px;
168
- width: 25px;
169
- height: 25px;
170
- color: #fff;
171
- }
172
-
173
- .button:hover {
174
- background-color: #4b71a1;
175
- }
176
-
177
- .button:active {
178
- background-color: #373736;
179
- }
180
-
181
- .button:disabled {
182
- opacity: 0.65;
183
- cursor: not-allowed;
184
- pointer-events: none;
185
- }
186
-
187
- #controls > .button > svg {
188
- width: 15px;
189
- height: 15px;
190
- vertical-align: top;
191
- }
192
-
193
- .dropdown {
194
- height: 19px;
195
- margin: 3px 0 3px 10px;
196
- border: 0;
197
- background: #fff;
198
- }
199
-
200
- .gutter {
201
- background-color: #f5f5f5;
202
- background-repeat: no-repeat;
203
- background-position: 50%;
204
- }
205
-
206
- .gutter.gutter-horizontal {
207
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
208
- cursor: col-resize;
209
- }
210
-
211
- ${faustCSS}
212
- </style>
213
- `
214
-
215
- export default class FaustEditor extends HTMLElement {
216
- constructor() {
217
- super()
218
- }
219
-
220
- connectedCallback() {
221
- const code = this.innerHTML.replace("<!--", "").replace("-->", "").trim()
222
- this.attachShadow({ mode: "open" }).appendChild(template.content.cloneNode(true))
223
-
224
- const ideLink = this.shadowRoot!.querySelector("#ide") as HTMLAnchorElement
225
- ideLink.onfocus = () => {
226
- // Open current contents of editor in IDE
227
- const urlParams = new URLSearchParams()
228
- urlParams.set("inline", btoa(editor.state.doc.toString()).replace("+", "-").replace("/", "_"))
229
- ideLink.href = `https://faustide.grame.fr/?${urlParams.toString()}`
230
- }
231
-
232
- const editorEl = this.shadowRoot!.querySelector("#editor") as HTMLDivElement
233
- const editor = createEditor(editorEl, code)
234
-
235
- const runButton = this.shadowRoot!.querySelector("#run") as HTMLButtonElement
236
- const stopButton = this.shadowRoot!.querySelector("#stop") as HTMLButtonElement
237
- const faustUIRoot = this.shadowRoot!.querySelector("#faust-ui") as HTMLDivElement
238
- const faustDiagram = this.shadowRoot!.querySelector("#faust-diagram") as HTMLDivElement
239
- const sidebar = this.shadowRoot!.querySelector("#sidebar") as HTMLDivElement
240
- const sidebarContent = this.shadowRoot!.querySelector("#sidebar-content") as HTMLDivElement
241
- const tabButtons = [...this.shadowRoot!.querySelectorAll(".tab")] as HTMLButtonElement[]
242
- const tabContents = [...sidebarContent.querySelectorAll("div")] as HTMLDivElement[]
243
-
244
- const split = Split([editorEl, sidebar], {
245
- sizes: [100, 0],
246
- minSize: [0, 20],
247
- gutterSize: 7,
248
- snapOffset: 150,
249
- onDragEnd: () => { scope?.onResize(); spectrum?.onResize() },
250
- })
251
-
252
- faustPromise.then(() => runButton.disabled = false)
253
-
254
- const defaultSizes = [70, 30]
255
- let sidebarOpen = false
256
- const openSidebar = () => {
257
- if (!sidebarOpen) {
258
- split.setSizes(defaultSizes)
259
- }
260
- sidebarOpen = true
261
- }
262
-
263
- let node: IFaustMonoWebAudioNode | undefined
264
- let input: MediaStreamAudioSourceNode | undefined
265
- let analyser: AnalyserNode | undefined
266
- let scope: Scope | undefined
267
- let spectrum: Scope | undefined
268
- let gmidi = false
269
- let gnvoices = -1
270
-
271
-
272
- runButton.onclick = async () => {
273
- if (audioCtx.state === "suspended") {
274
- await audioCtx.resume()
275
- }
276
- await faustPromise
277
- // Compile Faust code
278
- const code = editor.state.doc.toString()
279
- let generator = null
280
- try {
281
- // Compile Faust code to access JSON metadata
282
- await mono_generator.compile(compiler, "main", code, "")
283
- const json = mono_generator.getMeta()
284
- let { midi, nvoices } = extractMidiAndNvoices(json);
285
- gmidi = midi;
286
- gnvoices = nvoices;
287
-
288
- // Build the generator
289
- generator = nvoices > 0 ? poly_generator : mono_generator;
290
- await generator.compile(compiler, "main", code, "");
291
-
292
- } catch (e: any) {
293
- setError(editor, e)
294
- return
295
- }
296
- // Clear any old errors
297
- clearError(editor)
298
-
299
- // Create an audio node from compiled Faust
300
- if (node !== undefined) node.disconnect()
301
- if (gnvoices > 0) {
302
- node = (await poly_generator.createNode(audioCtx, gnvoices))!
303
- } else {
304
- node = (await mono_generator.createNode(audioCtx))!
305
- }
306
- if (node.numberOfInputs > 0) {
307
- audioInputSelector.disabled = false
308
- updateInputDevices(await getInputDevices())
309
- await connectInput()
310
- } else {
311
- audioInputSelector.disabled = true
312
- audioInputSelector.innerHTML = "<option>Audio input</option>"
313
- }
314
- node.connect(audioCtx.destination)
315
- stopButton.disabled = false
316
- for (const tabButton of tabButtons) {
317
- tabButton.disabled = false
318
- }
319
-
320
- // Access MIDI device
321
- if (gmidi) {
322
- accessMIDIDevice(midiInputCallback(node))
323
- .then(() => {
324
- console.log('Successfully connected to the MIDI device.');
325
- })
326
- .catch((error) => {
327
- console.error('Error accessing MIDI device:', error.message);
328
- });
329
- }
330
-
331
- openSidebar()
332
- // Clear old tab contents
333
- for (const tab of tabContents) {
334
- while (tab.lastChild) tab.lastChild.remove()
335
- }
336
- // Create scope & spectrum plots
337
- analyser = new AnalyserNode(audioCtx, {
338
- fftSize: Math.pow(2, 11), minDecibels: -96, maxDecibels: 0, smoothingTimeConstant: 0.85
339
- })
340
- node.connect(analyser)
341
- scope = new Scope(tabContents[2])
342
- spectrum = new Scope(tabContents[3])
343
-
344
- // If there are UI elements, open Faust UI (controls tab); otherwise open spectrum analyzer.
345
- const ui = node.getUI()
346
- openTab(ui.length > 1 || ui[0].items.length > 0 ? 0 : 3)
347
-
348
- // Create controls via Faust UI
349
- const faustUI = new FaustUI({ ui, root: faustUIRoot })
350
- faustUI.paramChangeByUI = (path, value) => node?.setParamValue(path, value)
351
- node.setOutputParamHandler((path, value) => faustUI.paramChangeByDSP(path, value))
352
-
353
- // Create SVG block diagram
354
- setSVG(svgDiagrams.from("main", code, "")["process.svg"])
355
- }
356
-
357
- const setSVG = (svgString: string) => {
358
- faustDiagram.innerHTML = svgString
359
-
360
- for (const a of faustDiagram.querySelectorAll("a")) {
361
- a.onclick = e => {
362
- e.preventDefault()
363
- const filename = (a.href as any as SVGAnimatedString).baseVal
364
- const svgString = compiler.fs().readFile("main-svg/" + filename, { encoding: "utf8" }) as string
365
- setSVG(svgString)
366
- }
367
- }
368
- }
369
-
370
- let animPlot: number | undefined
371
- const drawScope = () => {
372
- scope!.renderScope([{
373
- analyser: analyser!,
374
- style: "rgb(212, 100, 100)",
375
- edgeThreshold: 0.09,
376
- }])
377
- animPlot = requestAnimationFrame(drawScope)
378
- }
379
-
380
- const drawSpectrum = () => {
381
- spectrum!.renderSpectrum(analyser!)
382
- animPlot = requestAnimationFrame(drawSpectrum)
383
- }
384
-
385
- const openTab = (i: number) => {
386
- for (const [j, tab] of tabButtons.entries()) {
387
- if (i === j) {
388
- tab.classList.add("active")
389
- tabContents[j].classList.add("active")
390
- } else {
391
- tab.classList.remove("active")
392
- tabContents[j].classList.remove("active")
393
- }
394
- }
395
- if (i === 2) {
396
- scope!.onResize()
397
- if (animPlot !== undefined) cancelAnimationFrame(animPlot)
398
- animPlot = requestAnimationFrame(drawScope)
399
- } else if (i === 3) {
400
- spectrum!.onResize()
401
- if (animPlot !== undefined) cancelAnimationFrame(animPlot)
402
- animPlot = requestAnimationFrame(drawSpectrum)
403
- } else if (animPlot !== undefined) {
404
- cancelAnimationFrame(animPlot)
405
- animPlot = undefined
406
- }
407
- }
408
-
409
- for (const [i, tabButton] of tabButtons.entries()) {
410
- tabButton.onclick = () => openTab(i)
411
- }
412
-
413
- stopButton.onclick = () => {
414
- if (node !== undefined) {
415
- node.disconnect()
416
- node.destroy()
417
- node = undefined
418
- stopButton.disabled = true
419
- // TODO: Maybe disable controls in faust-ui tab.
420
- }
421
- }
422
-
423
- const audioInputSelector = this.shadowRoot!.querySelector("#audio-input") as HTMLSelectElement
424
-
425
- const updateInputDevices = (devices: MediaDeviceInfo[]) => {
426
- if (audioInputSelector.disabled) return
427
- while (audioInputSelector.lastChild) audioInputSelector.lastChild.remove()
428
- for (const device of devices) {
429
- if (device.kind === "audioinput") {
430
- audioInputSelector.appendChild(new Option(device.label || device.deviceId, device.deviceId))
431
- }
432
- }
433
- }
434
- deviceUpdateCallbacks.push(updateInputDevices)
435
-
436
- const connectInput = async () => {
437
- const deviceId = audioInputSelector.value
438
- const stream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId, echoCancellation: false, noiseSuppression: false, autoGainControl: false } })
439
- if (input) {
440
- input.disconnect()
441
- input = undefined
442
- }
443
- if (node && node.numberOfInputs > 0) {
444
- input = audioCtx.createMediaStreamSource(stream)
445
- input.connect(node!)
446
- }
447
- }
448
-
449
- audioInputSelector.onchange = connectInput
450
- }
451
- }
@@ -1,226 +0,0 @@
1
- import { icon } from "@fortawesome/fontawesome-svg-core"
2
- import faustCSS from "@shren/faust-ui/dist/esm/index.css?inline"
3
- import faustSvg from "./faustText.svg"
4
- import { IFaustMonoWebAudioNode } from "@grame/faustwasm"
5
- import { IFaustPolyWebAudioNode } from "@grame/faustwasm"
6
- import { FaustUI } from "@shren/faust-ui"
7
- import { faustPromise, audioCtx, mono_generator, poly_generator, compiler, getInputDevices, deviceUpdateCallbacks, accessMIDIDevice, midiInputCallback, extractMidiAndNvoices } from "./common"
8
-
9
- const template = document.createElement("template")
10
- template.innerHTML = `
11
- <div id="root">
12
- <div id="controls">
13
- <button title="On/off" class="button" id="power" disabled>${icon({ prefix: "fas", iconName: "power-off" }).html[0]}</button>
14
- <select id="audio-input" class="dropdown" disabled>
15
- <option>Audio input</option>
16
- </select>
17
- <!-- TODO: MIDI input
18
- <select id="midi-input" class="dropdown" disabled>
19
- <option>MIDI input</option>
20
- </select>
21
- -->
22
- <!-- TODO: volume control? <input id="volume" type="range" min="0" max="100"> -->
23
- <a title="Faust website" id="faust" href="https://faust.grame.fr/" target="_blank"><img src="${faustSvg}" height="15px" /></a>
24
- </div>
25
- <div id="faust-ui"></div>
26
- </div>
27
- <style>
28
- #root {
29
- border: 1px solid black;
30
- border-radius: 5px;
31
- box-sizing: border-box;
32
- display: inline-block;
33
- background-color: #384d64;
34
- }
35
-
36
- *, *:before, *:after {
37
- box-sizing: inherit;
38
- }
39
-
40
- #controls {
41
- display: flex;
42
- margin-bottom: -20px;
43
- position: relative;
44
- z-index: 1;
45
- }
46
-
47
- #faust {
48
- margin-left: auto;
49
- padding-left: 10px;
50
- margin-right: 10px;
51
- display: flex;
52
- align-items: center;
53
- }
54
-
55
- a.button {
56
- appearance: button;
57
- }
58
-
59
- .button {
60
- background-color: #384d64;
61
- border: 0;
62
- padding: 5px;
63
- width: 25px;
64
- height: 25px;
65
- color: #fff;
66
- }
67
-
68
- .button:hover {
69
- background-color: #4b71a1;
70
- }
71
-
72
- .button:active {
73
- background-color: #373736;
74
- }
75
-
76
- .button:disabled {
77
- opacity: 0.65;
78
- cursor: not-allowed;
79
- pointer-events: none;
80
- }
81
-
82
- #controls > .button > svg {
83
- width: 15px;
84
- height: 15px;
85
- vertical-align: top;
86
- }
87
-
88
- .dropdown {
89
- height: 19px;
90
- margin: 3px 0 3px 10px;
91
- border: 0;
92
- background: #fff;
93
- }
94
-
95
- ${faustCSS}
96
- </style>
97
- `
98
-
99
- export default class FaustWidget extends HTMLElement {
100
- constructor() {
101
- super()
102
- }
103
-
104
- connectedCallback() {
105
- const code = this.innerHTML.replace("<!--", "").replace("-->", "").trim()
106
- this.attachShadow({ mode: "open" }).appendChild(template.content.cloneNode(true))
107
-
108
- const powerButton = this.shadowRoot!.querySelector("#power") as HTMLButtonElement
109
- const faustUIRoot = this.shadowRoot!.querySelector("#faust-ui") as HTMLDivElement
110
-
111
- faustPromise.then(() => powerButton.disabled = false)
112
-
113
- let on = false
114
- let gmidi = false
115
- let gnvoices = -1
116
- let node: IFaustMonoWebAudioNode | IFaustPolyWebAudioNode
117
- let input: MediaStreamAudioSourceNode | undefined
118
- let faustUI: FaustUI
119
-
120
- const setup = async () => {
121
- await faustPromise
122
- // Compile Faust code to access JSON metadata
123
- await mono_generator.compile(compiler, "main", code, "")
124
- const json = mono_generator.getMeta()
125
- let { midi, nvoices } = extractMidiAndNvoices(json);
126
- gmidi = midi;
127
- gnvoices = nvoices;
128
-
129
- // Build the generator and generate UI
130
- const generator = nvoices > 0 ? poly_generator : mono_generator;
131
- await generator.compile(compiler, "main", code, "");
132
- const ui = generator.getUI();
133
-
134
- faustUI = new FaustUI({ ui, root: faustUIRoot });
135
- faustUIRoot.style.width = faustUI.minWidth * 1.25 + "px";
136
- faustUIRoot.style.height = faustUI.minHeight * 1.25 + "px";
137
- faustUI.resize();
138
- }
139
-
140
- const start = async () => {
141
- if (audioCtx.state === "suspended") {
142
- await audioCtx.resume()
143
- }
144
-
145
- // Create an audio node from compiled Faust
146
- if (node === undefined) {
147
- if (gnvoices > 0) {
148
- node = (await poly_generator.createNode(audioCtx, gnvoices))!
149
- } else {
150
- node = (await mono_generator.createNode(audioCtx))!
151
- }
152
- }
153
-
154
- // Access MIDI device
155
- if (gmidi) {
156
- accessMIDIDevice(midiInputCallback(node))
157
- .then(() => {
158
- console.log('Successfully connected to the MIDI device.');
159
- })
160
- .catch((error) => {
161
- console.error('Error accessing MIDI device:', error.message);
162
- });
163
- }
164
-
165
- faustUI.paramChangeByUI = (path, value) => node?.setParamValue(path, value)
166
- node.setOutputParamHandler((path, value) => faustUI.paramChangeByDSP(path, value))
167
-
168
- if (node.numberOfInputs > 0) {
169
- audioInputSelector.disabled = false
170
- updateInputDevices(await getInputDevices())
171
- await connectInput()
172
- } else {
173
- audioInputSelector.disabled = true
174
- audioInputSelector.innerHTML = "<option>Audio input</option>"
175
- }
176
-
177
- node.connect(audioCtx.destination)
178
- powerButton.style.color = "#ffa500"
179
- }
180
-
181
- const stop = () => {
182
- node?.disconnect()
183
- powerButton.style.color = "#fff"
184
- }
185
-
186
- powerButton.onclick = () => {
187
- if (on) {
188
- stop()
189
- } else {
190
- start()
191
- }
192
- on = !on
193
- }
194
-
195
- const audioInputSelector = this.shadowRoot!.querySelector("#audio-input") as HTMLSelectElement
196
-
197
- const updateInputDevices = (devices: MediaDeviceInfo[]) => {
198
- if (audioInputSelector.disabled) return
199
- while (audioInputSelector.lastChild) audioInputSelector.lastChild.remove()
200
- for (const device of devices) {
201
- if (device.kind === "audioinput") {
202
- audioInputSelector.appendChild(new Option(device.label || device.deviceId, device.deviceId))
203
- }
204
- }
205
- }
206
- deviceUpdateCallbacks.push(updateInputDevices)
207
-
208
- const connectInput = async () => {
209
- const deviceId = audioInputSelector.value
210
- const stream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId, echoCancellation: false, noiseSuppression: false, autoGainControl: false } })
211
- if (input) {
212
- input.disconnect()
213
- input = undefined
214
- }
215
- if (node && node.numberOfInputs > 0) {
216
- input = audioCtx.createMediaStreamSource(stream)
217
- input.connect(node!)
218
- }
219
- }
220
-
221
- audioInputSelector.onchange = connectInput
222
-
223
- setup()
224
- }
225
- }
226
-
package/src/faustText.svg DELETED
@@ -1,2 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2" xml:space="preserve" width="64.333328" height="12.414666" viewBox="0 0 64.333327 12.414666"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs6"><clipPath clipPathUnits="userSpaceOnUse" id="clipPath18"><path d="M 0,93.507 H 93.507 V 0 H 0 Z" id="path16"/></clipPath></defs><g style="fill:#ffffff" id="g10" transform="matrix(1.3333333,0,0,-1.3333333,-31.440266,68.495732)"><g id="g12" style="fill:#ffffff"><g id="g14" clip-path="url(#clipPath18)" style="fill:#ffffff"><g id="g20" transform="translate(69.0172,49.3868)" style="fill:#ffffff"><path d="M 0,0 V -7.026 H -2.017 V 0 H -4.843 V 1.747 H 2.813 V 0 Z m -8.276,-5.615 c -0.176,-0.333 -0.415,-0.62 -0.718,-0.863 -0.302,-0.243 -0.658,-0.433 -1.067,-0.569 -0.409,-0.136 -0.849,-0.204 -1.321,-0.204 -0.435,0 -0.833,0.041 -1.193,0.124 -0.361,0.082 -0.685,0.191 -0.973,0.327 -0.289,0.135 -0.548,0.29 -0.779,0.463 -0.232,0.174 -0.431,0.352 -0.598,0.534 l 1.278,1.384 c 0.115,-0.125 0.248,-0.252 0.4,-0.381 0.152,-0.129 0.321,-0.247 0.509,-0.352 0.187,-0.106 0.392,-0.191 0.614,-0.255 0.221,-0.065 0.46,-0.097 0.716,-0.097 0.15,0 0.3,0.021 0.447,0.064 0.149,0.043 0.285,0.107 0.41,0.191 0.124,0.084 0.223,0.185 0.296,0.303 0.073,0.119 0.11,0.253 0.11,0.404 0,0.327 -0.158,0.581 -0.474,0.762 -0.316,0.181 -0.817,0.36 -1.504,0.536 -0.333,0.078 -0.64,0.192 -0.922,0.342 -0.283,0.151 -0.526,0.332 -0.729,0.543 -0.204,0.211 -0.361,0.453 -0.474,0.726 -0.112,0.274 -0.169,0.578 -0.169,0.914 0,0.368 0.065,0.714 0.195,1.038 0.13,0.325 0.328,0.611 0.595,0.859 0.266,0.247 0.597,0.443 0.993,0.589 0.397,0.145 0.865,0.218 1.406,0.218 0.446,0 0.842,-0.046 1.187,-0.137 0.344,-0.092 0.637,-0.201 0.877,-0.329 0.24,-0.127 0.437,-0.258 0.591,-0.391 0.155,-0.134 0.271,-0.239 0.348,-0.316 l -1.143,-1.266 c -0.099,0.078 -0.212,0.162 -0.338,0.255 -0.127,0.093 -0.268,0.179 -0.425,0.258 -0.156,0.08 -0.33,0.147 -0.521,0.201 -0.19,0.053 -0.391,0.08 -0.601,0.08 -0.142,0 -0.28,-0.022 -0.416,-0.067 -0.135,-0.046 -0.258,-0.105 -0.367,-0.178 -0.11,-0.073 -0.198,-0.161 -0.264,-0.265 -0.066,-0.103 -0.1,-0.211 -0.1,-0.323 0,-0.301 0.159,-0.544 0.477,-0.73 0.318,-0.185 0.753,-0.34 1.307,-0.465 0.327,-0.077 0.645,-0.184 0.955,-0.319 0.311,-0.136 0.588,-0.314 0.832,-0.536 0.244,-0.222 0.441,-0.493 0.591,-0.814 0.15,-0.321 0.225,-0.711 0.225,-1.172 0,-0.392 -0.088,-0.754 -0.263,-1.086 m -10.307,1.854 c 0,-0.527 -0.086,-1.01 -0.257,-1.449 -0.172,-0.439 -0.418,-0.813 -0.74,-1.124 -0.321,-0.31 -0.71,-0.553 -1.167,-0.729 -0.456,-0.175 -0.965,-0.263 -1.526,-0.263 -0.56,0 -1.067,0.086 -1.522,0.257 -0.455,0.171 -0.841,0.414 -1.159,0.729 -0.318,0.315 -0.563,0.691 -0.734,1.13 -0.171,0.439 -0.256,0.922 -0.256,1.449 v 5.446 h 1.985 v -5.271 c 0,-0.295 0.029,-0.56 0.086,-0.795 0.058,-0.235 0.153,-0.437 0.284,-0.606 0.131,-0.169 0.304,-0.301 0.521,-0.394 0.217,-0.094 0.481,-0.14 0.795,-0.14 0.309,0 0.57,0.046 0.785,0.14 0.214,0.093 0.388,0.225 0.521,0.394 0.133,0.169 0.227,0.371 0.283,0.606 0.056,0.235 0.084,0.5 0.084,0.795 v 5.271 h 2.017 z M -30.68,-7.026 c -0.596,0 -1.078,0.482 -1.078,1.077 0,0.595 0.482,1.078 1.078,1.078 0.595,0 1.077,-0.483 1.077,-1.078 0,-0.595 -0.482,-1.077 -1.077,-1.077 m -1.702,3.551 -1.067,3.314 -1.092,-3.314 -0.054,-0.181 h -1.899 l 2.018,5.403 h 2.196 l 1.977,-5.4 -2.023,-0.005 z m -3.708,-3.551 c -0.595,0 -1.078,0.482 -1.078,1.077 0,0.595 0.483,1.078 1.078,1.078 0.595,0 1.078,-0.483 1.078,-1.078 0,-0.595 -0.483,-1.077 -1.078,-1.077 M -39.541,0 h -3.912 v -1.991 h 2.974 v -1.696 h -2.974 v -3.339 h -1.984 v 8.773 h 5.896 z" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path22"/></g></g></g></g></svg>
package/src/main.ts DELETED
@@ -1,5 +0,0 @@
1
- import FaustEditor from "./faust-editor"
2
- import FaustWidget from "./faust-widget"
3
-
4
- customElements.define("faust-editor", FaustEditor)
5
- customElements.define("faust-widget", FaustWidget)