Moving code around, moving more stage handling in to codeStore

This commit is contained in:
Knut Sveidqvist
2019-11-16 05:51:31 -08:00
parent 2bbe29ae3e
commit dcbd071a51
12 changed files with 344 additions and 274 deletions
+3 -1
View File
@@ -18,8 +18,10 @@
"dev": "webpack-dev-server --content-base public"
},
"dependencies": {
"js-base64": "^2.5.1",
"mermaid": "^8.4.2",
"monaco-editor": "0.18.1",
"svelte-routing": "^1.4.0"
"svelte-routing": "^1.4.0",
"svelte-spa-router": "^1.3.0"
}
}
+23 -11
View File
@@ -1,18 +1,30 @@
<script>
import Router from 'svelte-spa-router'
// Used for SSR. A falsy value is ignored by the Router.
export let url = "";
export let name;
import Editor from './Editor.svelte'
import View from './View.svelte'
import Edit from './routes/Edit.svelte'
import View from './routes/View.svelte'
const routes = {
// Exact path
'/': Edit,
// Using named parameters, with last being optional
'/edit/:data': Edit,
// Wildcard parameter
'/view/:data': View,
// Catch-all
// This is optional, but if present it must be the last
'*': Edit,
}
</script>
<style>
#app {
display: flex;
height: 100%;
}
</style>
<div id="app">
<Editor />
<View />
</div>
<body>
<Router {routes}/>
</body>
-250
View File
@@ -1,250 +0,0 @@
<script>
import { codeStore } from './code-store.js';
import { errorStore } from './error-store.js';
import { onMount } from 'svelte';
import mermaid from 'mermaid';
import Error from './error.svelte';
// (1) Desired editor features:
import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands.js';
// import 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js';
// import 'monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget.js';
// import 'monaco-editor/esm/vs/editor/browser/widget/diffNavigator.js';
// import 'monaco-editor/esm/vs/editor/contrib/bracketMatching/bracketMatching.js';
// import 'monaco-editor/esm/vs/editor/contrib/caretOperations/caretOperations.js';
// import 'monaco-editor/esm/vs/editor/contrib/caretOperations/transpose.js';
// import 'monaco-editor/esm/vs/editor/contrib/clipboard/clipboard.js';
// import 'monaco-editor/esm/vs/editor/contrib/codelens/codelensController.js';
// import 'monaco-editor/esm/vs/editor/contrib/colorPicker/colorDetector.js';
// import 'monaco-editor/esm/vs/editor/contrib/comment/comment.js';
// import 'monaco-editor/esm/vs/editor/contrib/contextmenu/contextmenu.js';
// import 'monaco-editor/esm/vs/editor/contrib/cursorUndo/cursorUndo.js';
// import 'monaco-editor/esm/vs/editor/contrib/dnd/dnd.js';
import 'monaco-editor/esm/vs/editor/contrib/find/findController.js';
// import 'monaco-editor/esm/vs/editor/contrib/folding/folding.js';
// import 'monaco-editor/esm/vs/editor/contrib/format/formatActions.js';
// import 'monaco-editor/esm/vs/editor/contrib/goToDeclaration/goToDeclarationCommands.js';
// import 'monaco-editor/esm/vs/editor/contrib/goToDeclaration/goToDeclarationMouse.js';
// import 'monaco-editor/esm/vs/editor/contrib/gotoError/gotoError.js';
// import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js';
// import 'monaco-editor/esm/vs/editor/contrib/inPlaceReplace/inPlaceReplace.js';
// import 'monaco-editor/esm/vs/editor/contrib/linesOperations/linesOperations.js';
// import 'monaco-editor/esm/vs/editor/contrib/links/links.js';
// import 'monaco-editor/esm/vs/editor/contrib/multicursor/multicursor.js';
// import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints.js';
// import 'monaco-editor/esm/vs/editor/contrib/quickFix/quickFixCommands.js';
// import 'monaco-editor/esm/vs/editor/contrib/referenceSearch/referenceSearch.js';
// import 'monaco-editor/esm/vs/editor/contrib/rename/rename.js';
// import 'monaco-editor/esm/vs/editor/contrib/smartSelect/smartSelect.js';
// import 'monaco-editor/esm/vs/editor/contrib/snippet/snippetController2.js';
// import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController.js';
// import 'monaco-editor/esm/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.js';
// import 'monaco-editor/esm/vs/editor/contrib/wordHighlighter/wordHighlighter.js';
// import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/inspectTokens/inspectTokens.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/quickOpen/quickOutline.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/quickOpen/gotoLine.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/quickOpen/quickCommand.js';
// import 'monaco-editor/esm/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.js';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
// (2) Desired languages:
// import 'monaco-editor/esm/vs/language/typescript/monaco.contribution';
// import 'monaco-editor/esm/vs/language/css/monaco.contribution';
// import 'monaco-editor/esm/vs/language/json/monaco.contribution';
// import 'monaco-editor/esm/vs/language/html/monaco.contribution';
// import 'monaco-editor/esm/vs/basic-languages/bat/bat.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/coffee/coffee.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/cpp/cpp.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/csharp/csharp.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/csp/csp.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/css/css.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/dockerfile/dockerfile.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/fsharp/fsharp.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/go/go.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/handlebars/handlebars.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/html/html.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/ini/ini.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/java/java.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/less/less.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/lua/lua.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/markdown/markdown.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/msdax/msdax.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/mysql/mysql.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/objective-c/objective-c.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/pgsql/pgsql.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/php/php.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/postiats/postiats.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/powershell/powershell.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/pug/pug.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/python/python.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/r/r.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/razor/razor.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/redis/redis.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/redshift/redshift.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/ruby/ruby.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/sb/sb.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/scss/scss.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/solidity/solidity.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/sql/sql.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/swift/swift.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/vb/vb.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/xml/xml.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution.js';
// import './mermaid-language/mermaid.contribution.js';
// import 'monaco-editor/esm/vs/basic-languages/typescript/typescript.contribution';
monaco.languages.register({ id: 'mermaid' });
// Register a tokens provider for the language
monaco.languages.setMonarchTokensProvider('mermaid', {
typeKeywords: [
'graph', 'stateDiagram', 'sequenceDiagram', 'classDiagram', 'pie'
],
keywords: [
'patricipant','as'
],
arrows: [
'---', '===', '-->', '==>'
],
tokenizer: {
root: [
[/[{}]/, 'delimiter.bracket'],
[/[a-z_$][\w$]*/, { cases: { '@typeKeywords': 'keyword',
'@keywords': 'keyword'} }],
[/[-=>ox]+/, { cases: { '@arrows': 'transition'} }],
[/[\[\{\(}]+.+?[\)\]\}]+/, "string"],
[/\".*\"/, "string"],
]
},
whitespace: [
[/[ \t\r\n]+/, 'white'],
[/\%\%.*$/, 'comment'],
],
});
onMount(async () => {
self.MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
return './editor.worker.bundle.js';
}
}
const code = `graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
D --> F[Server03]
D --> I[Server02]
D --> H[Server05]
D --> G[Server04]
`;
codeStore.set(code);
// Define a new theme that contains only rules that match this language
monaco.editor.defineTheme('myCoolTheme', {
base: 'vs',
inherit: false,
rules: [
{ token: 'keyword', foreground: '880000', fontStyle: 'bold' },
{ token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
{ token: 'string', foreground: 'AA8500' },
{ token: 'transition', foreground: '008800', fontStyle: 'bold'},
{ token: 'delimiter.bracket', foreground: '000000', fontStyle: 'bold'},
]
});
// Register a completion item provider for the new language
monaco.languages.registerCompletionItemProvider('mermaid', {
provideCompletionItems: () => {
var suggestions = [{
label: 'simpleText',
kind: monaco.languages.CompletionItemKind.Text,
insertText: 'simpleText'
}, {
label: 'testing',
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: 'testing(${1:condition})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
}, {
label: 'ifelse',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: [
'if (${1:condition}) {',
'\t$0',
'} else {',
'\t',
'}'
].join('\n'),
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'If-Else Statement'
}];
return { suggestions: suggestions };
}
});
const edit = monaco.editor.create(document.getElementById('editor'), {
value: [
code,
].join('\n'),
theme: 'myCoolTheme',
// value: getCode(),
language: 'mermaid'
// language: 'mermaid'
});
let decorations;
edit.onDidChangeModelContent(function (e) {
const code = edit.getValue();
try {
mermaid.parse(code);
codeStore.set(edit.getValue());
edit.deltaDecorations(decorations, []);
console.log(decorations);
errorStore.set(undefined);
} catch(e) {
console.log(e.hash.line);
errorStore.set(e);
const l = e.hash.line;
decorations = edit.deltaDecorations([], [
{ range: new monaco.Range(e.hash.loc.first_line,e.hash.loc.last_line,e.hash.loc.first_column,e.hash.loc.last_column), options: { inlineClassName: 'myInlineDecoration' }}]);
}
});
});
export let name;
</script>
<style>
#editor-container {
height: 80%;
max-height: 400px;
border: 1px solor darkred;
flex: 1;
}
#editor {
height: 80%;
max-height: 400px;
border: 1px solor darkred;
flex: 1;
}
.myLineDecoration {
background: lightblue;
width: 50px !important;
margin-left: 3px;
}
</style>
<div id="editor-container">
<div id="editor"> </div>
<Error />
</div>
+35
View File
@@ -1,3 +1,38 @@
import { writable } from 'svelte/store';
import mermaid from 'mermaid';
import { Base64 } from 'js-base64'
import {push, pop, replace} from 'svelte-spa-router'
export const codeStore = writable(undefined);
export const fromUrl = data => {
let code;
let state;
try {
let stateStr = Base64.decode(data)
state = JSON.parse(stateStr);
if (state.code === undefined) { // not valid json
state = { code: str, mermaid: { theme: themeFromUrl } }
}
code = state.code;
} catch (e) {
console.error('Init error', e);
code = `graph TD
A[Client] --> B[Load Balancer2]
B --> C[Server01]
B --> D[Server02]
D --> F[Server03]
D --> I[Server02]
D --> H[Server05]
D --> G[Server04]
`;
state = { code, mermaid: { theme: 'default' } };
}
codeStore.set(state);
};
export const updateCodeStore = newState => {
codeStore.set(newState);
push('/edit/' + Base64.encode(JSON.stringify(newState)))
};
+117
View File
@@ -0,0 +1,117 @@
<script>
import { codeStore, updateCodeStore } from '../code-store.js';
import { errorStore } from '../error-store.js';
import { onMount } from 'svelte';
import {push, pop, replace} from 'svelte-spa-router'
import { Base64 } from 'js-base64'
import mermaid from 'mermaid';
import Error from './Error.svelte';
import { initEditor } from './editor-utils';
import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands.js';
import 'monaco-editor/esm/vs/editor/contrib/find/findController.js';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
export let data;
export let code = '';
let edit;
let decorations = [];
const decArr = [];
const handleCodeUpdate = code => {
try {
mermaid.parse(code);
let newState = { code, mermaid: { theme: 'default' } };
updateCodeStore(newState);
decArr.forEach(decor => {
edit.deltaDecorations(decor, []);
});
// decorations = edit.deltaDecorations(decorations, [{ range: new monaco.Range(1,1,1,1), options : { } }]);
errorStore.set(undefined);
const model = edit.getModel();
// model.setValue(code);
// model.dispose();
} catch(e) {
console.log('Error in parsed', e);
errorStore.set(e);
const str = JSON.stringify({ code: code, mermaid: { theme: 'default' } });
push('/edit/' + Base64.encode(str))
const l = e.hash.line;
decArr.push(edit.deltaDecorations([], [
{ range: new monaco.Range(e.hash.loc.first_line,e.hash.loc.last_line,e.hash.loc.first_column,e.hash.loc.last_column), options: { inlineClassName: 'myInlineDecoration' }}]
));
// const model = edit.getModel();
// monaco.editor.setModelMarkers(model, 'test', {
// startLineineNumber: e.hash.loc.first_line,
// endLineNumumber: e.hash.loc.last_line,
// startColumn: e.hash.loc.first_column,
// endColumn: e.hash.loc.last_column,
// message: 'Syntax error',
// code: 'SXE',
// severity: 8
// });
}
};
const unsubscribe = codeStore.subscribe( state => {
if(!code && state) {
code = state.code;
}
if(!edit && code) {
edit = monaco.editor.create(document.getElementById('editor'), {
value: [
code,
].join('\n'),
theme: 'myCoolTheme',
language: 'mermaid'
});
let decorations = [];
edit.onDidChangeModelContent(function (e) {
const code = edit.getValue();
handleCodeUpdate(code);
});
handleCodeUpdate(code);
}
});
initEditor(monaco);
onMount(async () => {
console.log('Mounting editor');
self.MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
return './editor.worker.bundle.js';
}
}
});
export let name;
export let params = {}
</script>
<style>
#editor-container {
height: 80%;
max-height: 400px;
border: 1px solor darkred;
flex: 1;
}
#editor {
height: 80%;
max-height: 400px;
border: 1px solor darkred;
flex: 1;
}
/* .myLineDecoration {
background: lightblue;
width: 50px !important;
margin-left: 3px;
} */
</style>
<div id="editor-container">
<div id="editor"> </div>
<Error />
</div>
@@ -1,5 +1,5 @@
<script>
import { errorStore } from './error-store.js';
import { errorStore } from '../error-store.js';
import { onMount } from 'svelte';
onMount(async () => {
@@ -12,6 +12,9 @@ onMount(async () => {
export let token = '';
export let expected = '';
export let params = {}
const unsubscribeError = errorStore.subscribe( _error => {
if(typeof _error === 'undefined') {
classes = 'invisible';
+14 -9
View File
@@ -1,6 +1,6 @@
<script>
import { codeStore } from './code-store.js';
import { errorStore } from './error-store.js';
import { codeStore } from '../code-store.js';
import { errorStore } from '../error-store.js';
import { onMount } from 'svelte';
import mermaid from 'mermaid';
@@ -16,14 +16,19 @@ let insertSvg = function(svgCode, bindFunctions){
export let code = '';
export let classes = '';
const unsubscribe = codeStore.subscribe( _code => {
code = _code;
if(container) {
container.innerHTML = _code
delete container.dataset.processed
mermaid.init(undefined, container)
if(code) mermaid.render('graph-div', code, insertSvg);
const unsubscribe = codeStore.subscribe( state => {
try {
if(container && state) {
code = state.code;
container.innerHTML = code;
delete container.dataset.processed
mermaid.init(undefined, container)
if(code) mermaid.render('graph-div', code, insertSvg);
}
} catch(e) {
console.log('view fail', e);
}
});
const unsubscribeError = errorStore.subscribe( _error => {
if(typeof _error === 'undefined') {
+72
View File
@@ -0,0 +1,72 @@
export const initEditor = monaco => {
monaco.languages.register({ id: 'mermaid' });
// Register a tokens provider for the language
monaco.languages.setMonarchTokensProvider('mermaid', {
typeKeywords: [
'graph', 'stateDiagram', 'sequenceDiagram', 'classDiagram', 'pie'
],
keywords: [
'patricipant','as'
],
arrows: [
'---', '===', '-->', '==>'
],
tokenizer: {
root: [
[/[{}]/, 'delimiter.bracket'],
[/[a-z_$][\w$]*/, { cases: { '@typeKeywords': 'keyword',
'@keywords': 'keyword'} }],
[/[-=>ox]+/, { cases: { '@arrows': 'transition'} }],
[/[\[\{\(}]+.+?[\)\]\}]+/, "string"],
[/\".*\"/, "string"],
]
},
whitespace: [
[/[ \t\r\n]+/, 'white'],
[/\%\%.*$/, 'comment'],
],
});
monaco.editor.defineTheme('myCoolTheme', {
base: 'vs',
inherit: false,
rules: [
{ token: 'keyword', foreground: '880000', fontStyle: 'bold' },
{ token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
{ token: 'string', foreground: 'AA8500' },
{ token: 'transition', foreground: '008800', fontStyle: 'bold'},
{ token: 'delimiter.bracket', foreground: '000000', fontStyle: 'bold'},
]
});
// Register a completion item provider for the new language
monaco.languages.registerCompletionItemProvider('mermaid', {
provideCompletionItems: () => {
var suggestions = [{
label: 'simpleText',
kind: monaco.languages.CompletionItemKind.Text,
insertText: 'simpleText'
}, {
label: 'testing',
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: 'testing(${1:condition})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
}, {
label: 'ifelse',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: [
'if (${1:condition}) {',
'\t$0',
'} else {',
'\t',
'}'
].join('\n'),
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'If-Else Statement'
}];
return { suggestions: suggestions };
}
});
};
-1
View File
@@ -162,6 +162,5 @@ const edit = monaco.editor.create(document.getElementById('editor'), {
language: 'mermaid'
});
edit.onDidChangeModelContent(function (e) {
console.log(edit.getValue());
codeStore.set(edit.getValue());
});
+32
View File
@@ -0,0 +1,32 @@
<script>
import { onMount } from 'svelte';
import Editor from '../components/Editor.svelte';
import View from '../components/View.svelte';
import { fromUrl } from '../code-store.js';
onMount(async () => {
console.log('Data = ', params.data)
fromUrl(params.data);
});
export let code = '';
export let classes = '';
export let error = {};
export let token = '';
export let expected = '';
export let params = {};
</script>
<style>
#editor-container {
display: flex;
height: 100%;
}
</style>
<div id="editor-container">
<Editor data={params.data}/>
<View />
</div>
+26
View File
@@ -0,0 +1,26 @@
<script>
import { onMount } from 'svelte';
import Editor from '../components/Editor.svelte';
import View from '../components/View.svelte';
onMount(async () => {
});
export let code = '';
export let classes = '';
export let error = {};
export let token = '';
export let expected = '';
</script>
<style>
#view-page {
display: flex;
height: 100%;
}
</style>
<div id="view-page">
</div>
+17
View File
@@ -2543,6 +2543,11 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "http://pacman01.inkclub.local:4873/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
js-base64@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121"
integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==
json-parse-better-errors@^1.0.2:
version "1.0.2"
resolved "http://pacman01.inkclub.local:4873/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
@@ -3702,6 +3707,11 @@ regexp.prototype.flags@^1.2.0:
dependencies:
define-properties "^1.1.2"
regexparam@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
registry-auth-token@3.3.2:
version "3.3.2"
resolved "http://pacman01.inkclub.local:4873/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
@@ -4323,6 +4333,13 @@ svelte-routing@^1.4.0:
resolved "https://registry.yarnpkg.com/svelte-routing/-/svelte-routing-1.4.0.tgz#09285f3c7b19f509dfb1289fbc1235b348aa7d80"
integrity sha512-09ypn0/vD2PcuyZEEocUHFgi7kvLOxSoUUuJZ4j3p4Y4sT/kMIWtHIRpnLdsr8bQ+sGo77sbEkO+av6yd1RjPg==
svelte-spa-router@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/svelte-spa-router/-/svelte-spa-router-1.3.0.tgz#2461b43c7ee9b8b2b5c74fbb363d4bc2c3eb7dc8"
integrity sha512-DyIU8EB60hwsQ1jr7qOLOK3E5g3DrkkIjg+Kd+V4VNq4yl4MaVBt+/jUqmy0EzhOx9bpggqfDZCp3QxS/Qbp+Q==
dependencies:
regexparam "^1.3.0"
svelte@^3.0.0:
version "3.12.1"
resolved "http://pacman01.inkclub.local:4873/svelte/-/svelte-3.12.1.tgz#ddfacd43272ac3255907c682b74ee7d3d8b06b0c"