aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-10-31 19:41:24 +0100
committerLibravatar GitHub <noreply@github.com>2021-10-31 19:41:24 +0100
commit7918d78948de7f349f9948837caf76f2a514c96c (patch)
tree0f7c24a9e0046dffd719d6a66be4a1f73b7fa4c7
parentMerge pull request #7 from golej-marci/language-to-store (diff)
parentchore: bump dependency versions (diff)
downloadrefinery-7918d78948de7f349f9948837caf76f2a514c96c.tar.gz
refinery-7918d78948de7f349f9948837caf76f2a514c96c.tar.zst
refinery-7918d78948de7f349f9948837caf76f2a514c96c.zip
Merge pull request #8 from kris7t/cm6
Switch to CodeMirror 6 editor and WebSocket-based transport for Xtext
-rw-r--r--.editorconfig2
-rw-r--r--build.gradle2
-rw-r--r--gradle.properties9
-rw-r--r--gradle/junit.gradle2
-rw-r--r--language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java8
-rw-r--r--language-ide/src/main/java/tools/refinery/language/ide/contentassist/FuzzyMatcher.java44
-rw-r--r--language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java51
-rw-r--r--language-mwe2/build.gradle6
-rw-r--r--language-mwe2/src/main/java/tools/refinery/language/mwe2/ProblemWebIntegrationFragment.java61
-rw-r--r--language-web/.eslintrc.ci.js2
-rw-r--r--language-web/build.gradle27
-rw-r--r--language-web/package.json88
-rw-r--r--language-web/src/main/css/index.scss213
-rw-r--r--language-web/src/main/css/xtext/xtext-codemirror.css58
-rw-r--r--language-web/src/main/images/error_an.gifbin553 -> 0 bytes
-rw-r--r--language-web/src/main/images/info_an.gifbin101 -> 0 bytes
-rw-r--r--language-web/src/main/images/warning_an.gifbin522 -> 0 bytes
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java21
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java24
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/ProblemWebSocketServlet.java (renamed from language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java)13
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java73
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/occurrences/ProblemOccurrencesService.java16
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java107
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java53
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java196
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/PongResult.java44
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandler.java8
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java14
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/SubscribingServiceContext.java26
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java180
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorKind.java11
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorResponse.java79
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebOkResponse.java72
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebPushMessage.java81
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebRequest.java57
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebResponse.java4
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PrecomputationListener.java15
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushServiceDispatcher.java23
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocument.java89
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentAccess.java68
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentProvider.java33
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleServiceContext.java26
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleSession.java35
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextStatusCode.java9
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java133
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java83
-rw-r--r--language-web/src/main/js/App.tsx11
-rw-r--r--language-web/src/main/js/RootStore.tsx4
-rw-r--r--language-web/src/main/js/editor/EditorArea.tsx170
-rw-r--r--language-web/src/main/js/editor/EditorButtons.tsx70
-rw-r--r--language-web/src/main/js/editor/EditorParent.ts200
-rw-r--r--language-web/src/main/js/editor/EditorStore.ts358
-rw-r--r--language-web/src/main/js/editor/GenerateButton.tsx44
-rw-r--r--language-web/src/main/js/editor/decorationSetExtension.ts39
-rw-r--r--language-web/src/main/js/editor/editor.ts18
-rw-r--r--language-web/src/main/js/editor/findOccurrences.ts35
-rw-r--r--language-web/src/main/js/editor/semanticHighlighting.ts24
-rw-r--r--language-web/src/main/js/index.tsx30
-rw-r--r--language-web/src/main/js/language/folding.ts115
-rw-r--r--language-web/src/main/js/language/indentation.ts87
-rw-r--r--language-web/src/main/js/language/problem.grammar145
-rw-r--r--language-web/src/main/js/language/problemLanguageSupport.ts92
-rw-r--r--language-web/src/main/js/theme/ThemeStore.ts7
-rw-r--r--language-web/src/main/js/utils/ConditionVariable.ts64
-rw-r--r--language-web/src/main/js/utils/PendingTask.ts60
-rw-r--r--language-web/src/main/js/utils/Timer.ts33
-rw-r--r--language-web/src/main/js/utils/logger.ts (renamed from language-web/src/main/js/logging.tsx)2
-rw-r--r--language-web/src/main/js/xtext/CodeMirrorEditorContext.js111
-rw-r--r--language-web/src/main/js/xtext/ContentAssistService.ts177
-rw-r--r--language-web/src/main/js/xtext/HighlightingService.ts43
-rw-r--r--language-web/src/main/js/xtext/OccurrencesService.ts116
-rw-r--r--language-web/src/main/js/xtext/ServiceBuilder.js285
-rw-r--r--language-web/src/main/js/xtext/UpdateService.ts310
-rw-r--r--language-web/src/main/js/xtext/ValidationService.ts45
-rw-r--r--language-web/src/main/js/xtext/XtextClient.ts83
-rw-r--r--language-web/src/main/js/xtext/XtextWebSocketClient.ts341
-rw-r--r--language-web/src/main/js/xtext/compatibility.js63
-rw-r--r--language-web/src/main/js/xtext/services/ContentAssistService.js132
-rw-r--r--language-web/src/main/js/xtext/services/FormattingService.js52
-rw-r--r--language-web/src/main/js/xtext/services/HighlightingService.js33
-rw-r--r--language-web/src/main/js/xtext/services/HoverService.js59
-rw-r--r--language-web/src/main/js/xtext/services/LoadResourceService.js42
-rw-r--r--language-web/src/main/js/xtext/services/OccurrencesService.js39
-rw-r--r--language-web/src/main/js/xtext/services/SaveResourceService.js32
-rw-r--r--language-web/src/main/js/xtext/services/UpdateService.js159
-rw-r--r--language-web/src/main/js/xtext/services/ValidationService.js33
-rw-r--r--language-web/src/main/js/xtext/services/XtextService.js280
-rw-r--r--language-web/src/main/js/xtext/xtext-codemirror.d.ts43
-rw-r--r--language-web/src/main/js/xtext/xtext-codemirror.js473
-rw-r--r--language-web/src/main/js/xtext/xtextMessages.ts62
-rw-r--r--language-web/src/main/js/xtext/xtextServiceResults.ts239
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java204
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java42
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/tests/ProblemWebInjectorProvider.java47
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java109
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java98
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java165
-rw-r--r--language-web/tsconfig.json5
-rw-r--r--language-web/tsconfig.sonar.json3
-rw-r--r--language-web/webpack.config.js11
-rw-r--r--language-web/yarn.lock2499
-rw-r--r--language/build.gradle3
-rw-r--r--language/src/main/java/tools/refinery/language/GenerateProblem.mwe232
-rw-r--r--language/src/main/java/tools/refinery/language/Problem.xtext4
-rw-r--r--settings.gradle1
105 files changed, 6128 insertions, 4121 deletions
diff --git a/.editorconfig b/.editorconfig
index 5ce3abdf..60e56bf7 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,6 +10,6 @@ insert_final_newline = true
10indent_style = tab 10indent_style = tab
11indent_size = 4 11indent_size = 4
12 12
13[*.{html,js,json,jsx,scss,ts,tsx,yml}] 13[*.{grammar,html,js,json,jsx,scss,ts,tsx,yml}]
14indent_style = space 14indent_style = space
15indent_size = 2 15indent_size = 2
diff --git a/build.gradle b/build.gradle
index 72f1bc57..694d5c2d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
1plugins { 1plugins {
2 id 'com.github.johnrengelman.shadow' version '7.0.0' apply false 2 id 'com.github.johnrengelman.shadow' version '7.1.0' apply false
3 id 'org.siouan.frontend-jdk11' version '5.3.0' apply false 3 id 'org.siouan.frontend-jdk11' version '5.3.0' apply false
4 id 'org.sonarqube' version '3.3' 4 id 'org.sonarqube' version '3.3'
5 id 'org.xtext.xtend' version '3.0.0-M1' apply false 5 id 'org.xtext.xtend' version '3.0.0-M1' apply false
diff --git a/gradle.properties b/gradle.properties
index 5c0df1d3..57ff8621 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,14 +2,15 @@ ecoreVersion=2.25.0
2ecoreCodegenVersion=2.27.0 2ecoreCodegenVersion=2.27.0
3ecoreXmiVersion=2.16.0 3ecoreXmiVersion=2.16.0
4hamcrestVersion=2.2 4hamcrestVersion=2.2
5jettyVersion=11.0.6 5jettyVersion=11.0.7
6jmhVersion=1.32 6jmhVersion=1.33
7junitVersion=5.8.1 7junitVersion=5.8.1
8mockitoVersion=4.0.0
8mweVersion=1.6.2.M1 9mweVersion=1.6.2.M1
9mwe2Version=2.12.2.M1 10mwe2Version=2.12.2.M1
10nodeVersion=14.18.0 11nodeVersion=16.13.0
11slf4JVersion=2.0.0-alpha5 12slf4JVersion=2.0.0-alpha5
12viatraVersion=2.6.0 13viatraVersion=2.6.0
13xtextVersion=2.26.0.M2 14xtextVersion=2.26.0.M2
14xtextAntlrGeneratorVersion=2.1.1 15xtextAntlrGeneratorVersion=2.1.1
15yarnVersion=1.22.11 16yarnVersion=1.22.17
diff --git a/gradle/junit.gradle b/gradle/junit.gradle
index da0cea8c..44a463c7 100644
--- a/gradle/junit.gradle
+++ b/gradle/junit.gradle
@@ -5,6 +5,8 @@ dependencies {
5 testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}" 5 testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
6 testImplementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}" 6 testImplementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}"
7 testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}" 7 testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
8 testImplementation "org.mockito:mockito-core:${mockitoVersion}"
9 testImplementation "org.mockito:mockito-junit-jupiter:${mockitoVersion}"
8} 10}
9 11
10def jacocoTestReport = tasks.named('jacocoTestReport') 12def jacocoTestReport = tasks.named('jacocoTestReport')
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java b/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java
index 5327f7b4..3502c29f 100644
--- a/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java
+++ b/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java
@@ -3,16 +3,22 @@
3 */ 3 */
4package tools.refinery.language.ide; 4package tools.refinery.language.ide;
5 5
6import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher;
6import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator; 7import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator;
7 8
9import tools.refinery.language.ide.contentassist.FuzzyMatcher;
8import tools.refinery.language.ide.syntaxcoloring.ProblemSemanticHighlightingCalculator; 10import tools.refinery.language.ide.syntaxcoloring.ProblemSemanticHighlightingCalculator;
9 11
10/** 12/**
11 * Use this class to register ide components. 13 * Use this class to register ide components.
12 */ 14 */
13public class ProblemIdeModule extends AbstractProblemIdeModule { 15public class ProblemIdeModule extends AbstractProblemIdeModule {
14
15 public Class<? extends ISemanticHighlightingCalculator> bindISemanticHighlightingCalculator() { 16 public Class<? extends ISemanticHighlightingCalculator> bindISemanticHighlightingCalculator() {
16 return ProblemSemanticHighlightingCalculator.class; 17 return ProblemSemanticHighlightingCalculator.class;
17 } 18 }
19
20 @Override
21 public Class<? extends IPrefixMatcher> bindIPrefixMatcher() {
22 return FuzzyMatcher.class;
23 }
18} 24}
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/contentassist/FuzzyMatcher.java b/language-ide/src/main/java/tools/refinery/language/ide/contentassist/FuzzyMatcher.java
new file mode 100644
index 00000000..fe722ca1
--- /dev/null
+++ b/language-ide/src/main/java/tools/refinery/language/ide/contentassist/FuzzyMatcher.java
@@ -0,0 +1,44 @@
1package tools.refinery.language.ide.contentassist;
2
3import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher;
4
5import com.google.inject.Singleton;
6
7/**
8 * Implements the candidate matching algoritm used by CodeMirror 6.
9 *
10 * Using this class ensures that the same candidates will be returned when
11 * filtering content assist proposals on the server as on the client.
12 *
13 * The matching is "fuzzy" (<code>fzf</code>-like), i.e., the prefix characters
14 * may occur anywhere in the name, but must be in the same order as in the
15 * prefix.
16 *
17 * @author Kristóf Marussy
18 */
19@Singleton
20public class FuzzyMatcher implements IPrefixMatcher {
21 @Override
22 public boolean isCandidateMatchingPrefix(String name, String prefix) {
23 var nameIgnoreCase = name.toLowerCase();
24 var prefixIgnoreCase = prefix.toLowerCase();
25 int prefixLength = prefixIgnoreCase.length();
26 if (prefixLength == 0) {
27 return true;
28 }
29 int nameLength = nameIgnoreCase.length();
30 if (prefixLength > nameLength) {
31 return false;
32 }
33 int prefixIndex = 0;
34 for (int nameIndex = 0; nameIndex < nameLength; nameIndex++) {
35 if (nameIgnoreCase.charAt(nameIndex) == prefixIgnoreCase.charAt(prefixIndex)) {
36 prefixIndex++;
37 if (prefixIndex == prefixLength) {
38 return true;
39 }
40 }
41 }
42 return false;
43 }
44}
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
index 76a67f96..d9abf12d 100644
--- a/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
+++ b/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
@@ -17,30 +17,20 @@ import com.google.inject.Inject;
17 17
18import tools.refinery.language.model.ProblemUtil; 18import tools.refinery.language.model.ProblemUtil;
19import tools.refinery.language.model.problem.ClassDeclaration; 19import tools.refinery.language.model.problem.ClassDeclaration;
20import tools.refinery.language.model.problem.EnumDeclaration;
21import tools.refinery.language.model.problem.NamedElement; 20import tools.refinery.language.model.problem.NamedElement;
22import tools.refinery.language.model.problem.Node; 21import tools.refinery.language.model.problem.Node;
23import tools.refinery.language.model.problem.Parameter;
24import tools.refinery.language.model.problem.PredicateDefinition; 22import tools.refinery.language.model.problem.PredicateDefinition;
25import tools.refinery.language.model.problem.ProblemPackage; 23import tools.refinery.language.model.problem.ProblemPackage;
26import tools.refinery.language.model.problem.ReferenceDeclaration; 24import tools.refinery.language.model.problem.ReferenceDeclaration;
27import tools.refinery.language.model.problem.Variable;
28 25
29public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator { 26public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator {
30 private static final String BUILTIN_CLASS = "cm-keyword"; 27 private static final String BUILTIN_CLASS = "builtin";
31 private static final String CLASS_CLASS = "problem-class"; 28 private static final String ABSTRACT_CLASS = "abstract";
32 private static final String ABSTRACT_CLASS = "problem-abstract"; 29 private static final String CONTAINMENT_CLASS = "containment";
33 private static final String ENUM_CLASS = "problem-enum"; 30 private static final String ERROR_CLASS = "error";
34 private static final String REFERENCE_CLASS = "problem-reference"; 31 private static final String NODE_CLASS = "node";
35 private static final String CONTAINMENT_CLASS = "problem-containment"; 32 private static final String UNIQUE_NODE_CLASS = "unique";
36 private static final String PREDICATE_CLASS = "problem-predicate"; 33 private static final String NEW_NODE_CLASS = "new";
37 private static final String ERROR_CLASS = "problem-error";
38 private static final String NODE_CLASS = "problem-node";
39 private static final String UNIQUE_NODE_CLASS = "problem-unique-node";
40 private static final String NEW_NODE_CLASS = "problem-new-node";
41 private static final String PARAMETER_CLASS = "problem-parameter";
42 private static final String VARIABLE_CLASS = "problem-variable";
43 private static final String SINGLETON_VARIABLE_CLASS = "problem-singleton-variable";
44 34
45 @Inject 35 @Inject
46 private OperationCanceledManager operationCanceledManager; 36 private OperationCanceledManager operationCanceledManager;
@@ -57,7 +47,7 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
57 if (!(object instanceof NamedElement)) { 47 if (!(object instanceof NamedElement)) {
58 return; 48 return;
59 } 49 }
60 String[] highlightClass = getHighlightClass(object); 50 String[] highlightClass = getHighlightClass(object, null);
61 if (highlightClass.length > 0) { 51 if (highlightClass.length > 0) {
62 highlightFeature(acceptor, object, ProblemPackage.Literals.NAMED_ELEMENT__NAME, highlightClass); 52 highlightFeature(acceptor, object, ProblemPackage.Literals.NAMED_ELEMENT__NAME, highlightClass);
63 } 53 }
@@ -80,7 +70,7 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
80 70
81 protected void highlightSingleValue(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) { 71 protected void highlightSingleValue(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
82 EObject valueObj = (EObject) object.eGet(reference); 72 EObject valueObj = (EObject) object.eGet(reference);
83 String[] highlightClass = getHighlightClass(valueObj); 73 String[] highlightClass = getHighlightClass(valueObj, reference);
84 if (highlightClass.length > 0) { 74 if (highlightClass.length > 0) {
85 highlightFeature(acceptor, object, reference, highlightClass); 75 highlightFeature(acceptor, object, reference, highlightClass);
86 } 76 }
@@ -94,41 +84,37 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
94 for (var i = 0; i < size; i++) { 84 for (var i = 0; i < size; i++) {
95 EObject valueInList = values.get(i); 85 EObject valueInList = values.get(i);
96 INode node = nodes.get(i); 86 INode node = nodes.get(i);
97 String[] highlightClass = getHighlightClass(valueInList); 87 String[] highlightClass = getHighlightClass(valueInList, reference);
98 if (highlightClass.length > 0) { 88 if (highlightClass.length > 0) {
99 highlightNode(acceptor, node, highlightClass); 89 highlightNode(acceptor, node, highlightClass);
100 } 90 }
101 } 91 }
102 } 92 }
103 93
104 protected String[] getHighlightClass(EObject eObject) { 94 protected String[] getHighlightClass(EObject eObject, EReference reference) {
105 if (ProblemUtil.isBuiltIn(eObject)) { 95 if (ProblemUtil.isBuiltIn(eObject)) {
106 return new String[] { BUILTIN_CLASS }; 96 return new String[] { BUILTIN_CLASS };
107 } 97 }
108 ImmutableList.Builder<String> classesBuilder = ImmutableList.builder(); 98 ImmutableList.Builder<String> classesBuilder = ImmutableList.builder();
109 if (eObject instanceof ClassDeclaration classDeclaration) { 99 if (eObject instanceof ClassDeclaration classDeclaration) {
110 classesBuilder.add(CLASS_CLASS);
111 if (classDeclaration.isAbstract()) { 100 if (classDeclaration.isAbstract()) {
112 classesBuilder.add(ABSTRACT_CLASS); 101 classesBuilder.add(ABSTRACT_CLASS);
113 } 102 }
114 } 103 }
115 if (eObject instanceof EnumDeclaration) {
116 classesBuilder.add(ENUM_CLASS);
117 }
118 if (eObject instanceof ReferenceDeclaration referenceDeclaration) { 104 if (eObject instanceof ReferenceDeclaration referenceDeclaration) {
119 classesBuilder.add(REFERENCE_CLASS);
120 if (referenceDeclaration.isContainment()) { 105 if (referenceDeclaration.isContainment()) {
121 classesBuilder.add(CONTAINMENT_CLASS); 106 classesBuilder.add(CONTAINMENT_CLASS);
122 } 107 }
123 } 108 }
124 if (eObject instanceof PredicateDefinition predicateDefinition) { 109 if (eObject instanceof PredicateDefinition predicateDefinition) {
125 classesBuilder.add(PREDICATE_CLASS);
126 if (predicateDefinition.isError()) { 110 if (predicateDefinition.isError()) {
127 classesBuilder.add(ERROR_CLASS); 111 classesBuilder.add(ERROR_CLASS);
128 } 112 }
129 } 113 }
130 if (eObject instanceof Node node) { 114 if (eObject instanceof Node node) {
131 classesBuilder.add(NODE_CLASS); 115 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) {
116 classesBuilder.add(NODE_CLASS);
117 }
132 if (ProblemUtil.isUniqueNode(node)) { 118 if (ProblemUtil.isUniqueNode(node)) {
133 classesBuilder.add(UNIQUE_NODE_CLASS); 119 classesBuilder.add(UNIQUE_NODE_CLASS);
134 } 120 }
@@ -136,15 +122,6 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
136 classesBuilder.add(NEW_NODE_CLASS); 122 classesBuilder.add(NEW_NODE_CLASS);
137 } 123 }
138 } 124 }
139 if (eObject instanceof Parameter) {
140 classesBuilder.add(PARAMETER_CLASS);
141 }
142 if (eObject instanceof Variable variable) {
143 classesBuilder.add(VARIABLE_CLASS);
144 if (ProblemUtil.isSingletonVariable(variable)) {
145 classesBuilder.add(SINGLETON_VARIABLE_CLASS);
146 }
147 }
148 List<String> classes = classesBuilder.build(); 125 List<String> classes = classesBuilder.build();
149 return classes.toArray(new String[0]); 126 return classes.toArray(new String[0]);
150 } 127 }
diff --git a/language-mwe2/build.gradle b/language-mwe2/build.gradle
deleted file mode 100644
index 4b9017c5..00000000
--- a/language-mwe2/build.gradle
+++ /dev/null
@@ -1,6 +0,0 @@
1apply plugin: 'java-library'
2apply from: "${rootDir}/gradle/java-common.gradle"
3
4dependencies {
5 api "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}"
6}
diff --git a/language-mwe2/src/main/java/tools/refinery/language/mwe2/ProblemWebIntegrationFragment.java b/language-mwe2/src/main/java/tools/refinery/language/mwe2/ProblemWebIntegrationFragment.java
deleted file mode 100644
index cdebe452..00000000
--- a/language-mwe2/src/main/java/tools/refinery/language/mwe2/ProblemWebIntegrationFragment.java
+++ /dev/null
@@ -1,61 +0,0 @@
1package tools.refinery.language.mwe2;
2
3import java.util.Set;
4
5import org.eclipse.xtext.xtext.generator.web.WebIntegrationFragment;
6
7import com.google.common.collect.Multimap;
8
9public class ProblemWebIntegrationFragment extends WebIntegrationFragment {
10 private static final String START_STATE = "start";
11 private static final String PREDICATE_BODY_STATE = "predicateBody";
12 private static final String CM_MODE_META = "meta";
13
14 public ProblemWebIntegrationFragment() {
15 setFramework(Framework.CODEMIRROR.name());
16 // Use the CodeMirror default .cm-number instead of .cm-constant.cm-numeric
17 addSuppressPattern("number_decimal");
18 // We use our own custom single-line comments
19 addSuppressPattern("comment_singleLine");
20 // Override bracket indentation behavior
21 addSuppressPattern("bracket_open");
22 addSuppressPattern("parenthesis_open");
23 addSuppressPattern("brace_open");
24 addSuppressPattern("bracket_close");
25 addSuppressPattern("parenthesis_close");
26 addSuppressPattern("brace_close");
27 }
28
29 @Override
30 public void setFramework(String frameworkName) {
31 if (!frameworkName.toUpperCase().equals(Framework.CODEMIRROR.name())) {
32 throw new IllegalStateException("Framework cannot be changed from CodeMirror");
33 }
34 super.setFramework(frameworkName);
35 }
36
37 @Override
38 protected Multimap<String, String> createCodeMirrorPatterns(String langId, Set<String> keywords) {
39 Multimap<String, String> patterns = super.createCodeMirrorPatterns(langId, keywords);
40 // Use the CodeMirror default .cm-number instead of .cm-constant.cm-numeric
41 patterns.put(START_STATE,
42 "{token: \"number\", regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"}");
43 // We use our own custom single-line comments
44 patterns.put(START_STATE, "{token: \"comment\", regex: \"%.*$\"}");
45 patterns.put(START_STATE, "{token: \"comment\", regex: \"\\\\/\\\\/.*$\"}");
46 patterns.put(CM_MODE_META, "lineComment: \"%\"");
47 // Override indentation behavior
48 patterns.put(START_STATE, "{token: \"lparen\", indent: true, regex: \"[[({]\"}");
49 patterns.put(START_STATE, "{token: \"rparen\", dedent: true, regex: \"[\\\\])}]\"}");
50 patterns.putAll(PREDICATE_BODY_STATE, patterns.get(START_STATE));
51 patterns.put(START_STATE, "{indent: true, push: \"" + PREDICATE_BODY_STATE + "\", regex: \"<->\"}");
52 patterns.put(PREDICATE_BODY_STATE,
53 "{dedent: true, dedentIfLineStart: false, pop: true, regex: \"\\\\.\\\\s*$\"}");
54 patterns.put(PREDICATE_BODY_STATE, "{indent: true, dedent: true, regex: \"[;]\"}");
55 // We must repeat the keyword rule here, because Xtext only adds it to "main"
56 // later
57 patterns.put(PREDICATE_BODY_STATE, "{token: \"keyword\", regex: \"\\\\b(?:\" + keywords + \")\\\\b\"}");
58 patterns.put(CM_MODE_META, "electricChars: \"])];\"");
59 return patterns;
60 }
61}
diff --git a/language-web/.eslintrc.ci.js b/language-web/.eslintrc.ci.js
index b4c83bb8..d0fb9e98 100644
--- a/language-web/.eslintrc.ci.js
+++ b/language-web/.eslintrc.ci.js
@@ -28,6 +28,6 @@ module.exports = {
28 ignorePatterns: [ 28 ignorePatterns: [
29 '*.js', 29 '*.js',
30 'build/**/*', 30 'build/**/*',
31 'src/main/js/xtext/**/*', 31 'node_modules/**/*',
32 ], 32 ],
33}; 33};
diff --git a/language-web/build.gradle b/language-web/build.gradle
index c467c019..ea2f1269 100644
--- a/language-web/build.gradle
+++ b/language-web/build.gradle
@@ -1,5 +1,6 @@
1apply plugin: 'java' 1apply plugin: 'java'
2apply from: "${rootDir}/gradle/xtext-common.gradle" 2apply from: "${rootDir}/gradle/xtext-common.gradle"
3apply from: "${rootDir}/gradle/junit.gradle"
3 4
4dependencies { 5dependencies {
5 implementation project(':refinery-language') 6 implementation project(':refinery-language')
@@ -8,8 +9,12 @@ dependencies {
8 implementation "org.eclipse.xtend:org.eclipse.xtend.lib:${xtextVersion}" 9 implementation "org.eclipse.xtend:org.eclipse.xtend.lib:${xtextVersion}"
9 implementation "org.eclipse.jetty:jetty-server:${jettyVersion}" 10 implementation "org.eclipse.jetty:jetty-server:${jettyVersion}"
10 implementation "org.eclipse.jetty:jetty-servlet:${jettyVersion}" 11 implementation "org.eclipse.jetty:jetty-servlet:${jettyVersion}"
12 implementation "org.eclipse.jetty.websocket:websocket-jetty-server:${jettyVersion}"
11 implementation "org.slf4j:slf4j-simple:${slf4JVersion}" 13 implementation "org.slf4j:slf4j-simple:${slf4JVersion}"
12 implementation "org.slf4j:log4j-over-slf4j:${slf4JVersion}" 14 implementation "org.slf4j:log4j-over-slf4j:${slf4JVersion}"
15 testImplementation testFixtures(project(':refinery-language'))
16 testImplementation "org.eclipse.xtext:org.eclipse.xtext.testing:${xtextVersion}"
17 testImplementation "org.eclipse.jetty.websocket:websocket-jetty-client:${jettyVersion}"
13} 18}
14 19
15def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage') 20def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage')
@@ -35,18 +40,28 @@ frontend {
35 yarnEnabled = true 40 yarnEnabled = true
36 yarnVersion = project.ext.yarnVersion 41 yarnVersion = project.ext.yarnVersion
37 yarnInstallDirectory = file("${rootDir}/.gradle/yarn") 42 yarnInstallDirectory = file("${rootDir}/.gradle/yarn")
38 assembleScript = 'run assemble' 43 assembleScript = 'run assemble:webpack'
39} 44}
40 45
41def installFrontend = tasks.named('installFrontend') 46def installFrontend = tasks.named('installFrontend')
42 47
48def generateLezerGrammar = tasks.register('generateLezerGrammar', RunNpmYarn) {
49 dependsOn installFrontend
50 inputs.file('src/main/js/language/problem.grammar')
51 inputs.files('package.json', 'yarn.lock')
52 outputs.file "${buildDir}/generated/sources/lezer/problem.ts"
53 outputs.file "${buildDir}/generated/sources/lezer/problem.terms.ts"
54 script = 'run assemble:lezer'
55}
56
43def assembleFrontend = tasks.named('assembleFrontend') 57def assembleFrontend = tasks.named('assembleFrontend')
44assembleFrontend.configure { 58assembleFrontend.configure {
45 dependsOn generateXtextLanguage 59 dependsOn generateLezerGrammar
46 inputs.dir 'src/main/css' 60 inputs.dir 'src/main/css'
47 inputs.dir 'src/main/html' 61 inputs.dir 'src/main/html'
48 inputs.dir 'src/main/js' 62 inputs.dir 'src/main/js'
49 inputs.dir "${buildDir}/generated/sources/xtext/js" 63 inputs.file "${buildDir}/generated/sources/lezer/problem.ts"
64 inputs.file "${buildDir}/generated/sources/lezer/problem.terms.ts"
50 inputs.files('package.json', 'yarn.lock', 'webpack.config.js') 65 inputs.files('package.json', 'yarn.lock', 'webpack.config.js')
51 outputs.dir productionResources 66 outputs.dir productionResources
52} 67}
@@ -125,7 +140,7 @@ def jettyRun = tasks.register('jettyRun', JavaExec) {
125 140
126tasks.register('webpackServe', RunNpmYarn) { 141tasks.register('webpackServe', RunNpmYarn) {
127 dependsOn installFrontend 142 dependsOn installFrontend
128 dependsOn generateXtextLanguage 143 dependsOn generateLezerGrammar
129 outputs.dir "${webpackOutputDir}/development" 144 outputs.dir "${webpackOutputDir}/development"
130 script = 'run serve' 145 script = 'run serve'
131 group = 'run' 146 group = 'run'
@@ -138,10 +153,6 @@ sonarqube.properties {
138 'src/main/html', 153 'src/main/html',
139 'src/main/js', 154 'src/main/js',
140 ] 155 ]
141 properties['sonar.exclusions'] += [
142 'src/main/css/xtext/**',
143 'src/main/js/xtext/**',
144 ]
145 property 'sonar.nodejs.executable', "${nodeDirectory}/bin/node" 156 property 'sonar.nodejs.executable', "${nodeDirectory}/bin/node"
146 property 'sonar.eslint.reportPaths', "${buildDir}/eslint.json" 157 property 'sonar.eslint.reportPaths', "${buildDir}/eslint.json"
147 property 'sonar.css.stylelint.reportPaths', "${buildDir}/stylelint.json" 158 property 'sonar.css.stylelint.reportPaths', "${buildDir}/stylelint.json"
diff --git a/language-web/package.json b/language-web/package.json
index 7a931d95..cb860c5f 100644
--- a/language-web/package.json
+++ b/language-web/package.json
@@ -4,7 +4,8 @@
4 "description": "Web frontend for VIATRA-Generator", 4 "description": "Web frontend for VIATRA-Generator",
5 "main": "index.js", 5 "main": "index.js",
6 "scripts": { 6 "scripts": {
7 "assemble": "webpack --node-env production", 7 "assemble:lezer": "lezer-generator src/main/js/language/problem.grammar -o build/generated/sources/lezer/problem.ts",
8 "assemble:webpack": "webpack --node-env production",
8 "serve": "webpack serve --node-env development --hot", 9 "serve": "webpack serve --node-env development --hot",
9 "check": "yarn run check:eslint && yarn run check:stylelint", 10 "check": "yarn run check:eslint && yarn run check:stylelint",
10 "check:eslint": "eslint .", 11 "check:eslint": "eslint .",
@@ -23,59 +24,76 @@
23 }, 24 },
24 "homepage": "https://refinery.tools", 25 "homepage": "https://refinery.tools",
25 "devDependencies": { 26 "devDependencies": {
26 "@babel/core": "^7.15.5", 27 "@babel/core": "^7.16.0",
27 "@babel/preset-env": "^7.15.6", 28 "@babel/preset-env": "^7.16.0",
28 "@babel/preset-react": "^7.14.5", 29 "@babel/preset-react": "^7.16.0",
29 "@babel/preset-typescript": "^7.15.0", 30 "@babel/preset-typescript": "^7.16.0",
30 "@babel/plugin-transform-runtime": "^7.15.0", 31 "@babel/plugin-transform-runtime": "^7.16.0",
31 "babel-loader": "^8.2.2", 32 "babel-loader": "^8.2.3",
32 "css-loader": "^6.3.0", 33 "css-loader": "^6.5.0",
33 "eslint": "^7.32.0", 34 "eslint": "^7.32.0",
34 "eslint-config-airbnb": "^18.2.1", 35 "eslint-config-airbnb": "^18.2.1",
35 "eslint-config-airbnb-typescript": "^14.0.0", 36 "eslint-config-airbnb-typescript": "^14.0.1",
36 "eslint-plugin-import": "^2.24.2", 37 "eslint-plugin-import": "^2.25.2",
37 "eslint-plugin-jsx-a11y": "^6.4.1", 38 "eslint-plugin-jsx-a11y": "^6.4.1",
38 "eslint-plugin-react": "^7.26.1", 39 "eslint-plugin-react": "^7.26.1",
39 "eslint-plugin-react-hooks": "^4.2.0", 40 "eslint-plugin-react-hooks": "^4.2.0",
40 "eslint-plugin-sonarjs": "^0.10.0", 41 "eslint-plugin-sonarjs": "^0.10.0",
41 "html-webpack-plugin": "^5.3.2", 42 "html-webpack-plugin": "^5.5.0",
42 "image-webpack-loader": "^8.0.1", 43 "image-webpack-loader": "^8.0.1",
44 "@lezer/generator": "^0.15.2",
43 "magic-comments-loader": "^1.4.1", 45 "magic-comments-loader": "^1.4.1",
44 "mini-css-extract-plugin": "^2.3.0", 46 "mini-css-extract-plugin": "^2.4.3",
47 "postcss": "^8.3.11",
45 "@principalstudio/html-webpack-inject-preload": "^1.2.7", 48 "@principalstudio/html-webpack-inject-preload": "^1.2.7",
46 "sass": "^1.42.1", 49 "sass": "^1.43.4",
47 "sass-loader": "^12.1.0", 50 "sass-loader": "^12.3.0",
48 "style-loader": "^3.3.0", 51 "style-loader": "^3.3.1",
49 "stylelint": "^13.13.1", 52 "stylelint": "^14.0.1",
50 "stylelint-config-recommended-scss": "^4.3.0", 53 "stylelint-config-recommended-scss": "^5.0.0",
51 "stylelint-scss": "^3.21.0", 54 "stylelint-scss": "^4.0.0",
52 "@types/codemirror": "^5.60.3", 55 "@types/react-dom": "^17.0.10",
53 "@types/react-dom": "^17.0.9", 56 "typescript": "^4.4.4",
54 "typescript": "^4.4.3", 57 "@typescript-eslint/eslint-plugin": "^4.33.0",
55 "@typescript-eslint/eslint-plugin": "^4.32.0", 58 "@typescript-eslint/parser": "^4.33.0",
56 "@typescript-eslint/parser": "^4.32.0", 59 "webpack": "^5.61.0",
57 "webpack": "^5.56.0", 60 "webpack-cli": "^4.9.1",
58 "webpack-cli": "^4.8.0", 61 "webpack-dev-server": "^4.4.0",
59 "webpack-dev-server": "^4.3.0",
60 "webpack-subresource-integrity": "^5.0.0" 62 "webpack-subresource-integrity": "^5.0.0"
61 }, 63 },
62 "dependencies": { 64 "dependencies": {
63 "ansi-styles": "^6.1.0", 65 "ansi-styles": "^6.1.0",
64 "@babel/runtime": "^7.15.4", 66 "@babel/runtime": "^7.16.0",
65 "@emotion/react": "^11.4.1", 67 "@codemirror/autocomplete": "^0.19.4",
68 "@codemirror/closebrackets": "^0.19.0",
69 "@codemirror/commands": "^0.19.5",
70 "@codemirror/comment": "^0.19.0",
71 "@codemirror/fold": "^0.19.1",
72 "@codemirror/gutter": "^0.19.4",
73 "@codemirror/highlight": "^0.19.6",
74 "@codemirror/history": "^0.19.0",
75 "@codemirror/language": "^0.19.3",
76 "@codemirror/lint": "^0.19.2",
77 "@codemirror/matchbrackets": "^0.19.3",
78 "@codemirror/rangeset": "^0.19.1",
79 "@codemirror/rectangular-selection": "^0.19.1",
80 "@codemirror/search": "^0.19.2",
81 "@codemirror/state": "^0.19.2",
82 "@codemirror/view": "^0.19.9",
83 "@emotion/react": "^11.5.0",
66 "@emotion/styled": "^11.3.0", 84 "@emotion/styled": "^11.3.0",
85 "escape-string-regexp": "^5.0.0",
67 "@fontsource/jetbrains-mono": "^4.5.0", 86 "@fontsource/jetbrains-mono": "^4.5.0",
68 "@fontsource/roboto": "^4.5.0", 87 "@fontsource/roboto": "^4.5.1",
69 "@mui/material": "5.0.2", 88 "@lezer/lr": "^0.15.4",
70 "@mui/icons-material": "5.0.1",
71 "codemirror": "^5.63.1",
72 "jquery": "^3.6.0",
73 "loglevel": "^1.7.1", 89 "loglevel": "^1.7.1",
74 "loglevel-plugin-prefix": "^0.8.4", 90 "loglevel-plugin-prefix": "^0.8.4",
75 "mobx": "^6.3.3", 91 "@mui/material": "5.0.6",
92 "@mui/icons-material": "5.0.5",
93 "mobx": "^6.3.5",
76 "mobx-react-lite": "^3.2.1", 94 "mobx-react-lite": "^3.2.1",
95 "nanoid": "^3.1.30",
77 "react": "^17.0.2", 96 "react": "^17.0.2",
78 "react-codemirror2": "npm:react17-codemirror2@^7.2.3",
79 "react-dom": "^17.0.2" 97 "react-dom": "^17.0.2"
80 } 98 }
81} 99}
diff --git a/language-web/src/main/css/index.scss b/language-web/src/main/css/index.scss
index 54f3a654..ad876aaf 100644
--- a/language-web/src/main/css/index.scss
+++ b/language-web/src/main/css/index.scss
@@ -1,13 +1,6 @@
1@use 'sass:map';
2@use '@fontsource/roboto/scss/mixins' as Roboto; 1@use '@fontsource/roboto/scss/mixins' as Roboto;
3@use '@fontsource/jetbrains-mono/scss/mixins' as JetbrainsMono; 2@use '@fontsource/jetbrains-mono/scss/mixins' as JetbrainsMono;
4 3
5@import 'codemirror/lib/codemirror';
6@import 'codemirror/addon/hint/show-hint';
7@import 'codemirror/theme/material-darker';
8
9@import './themes';
10
11$fontWeights: 300, 400, 500, 700; 4$fontWeights: 300, 400, 500, 700;
12@each $weight in $fontWeights { 5@each $weight in $fontWeights {
13 @include Roboto.fontFace($fontName: 'Roboto', $weight: $weight); 6 @include Roboto.fontFace($fontName: 'Roboto', $weight: $weight);
@@ -21,209 +14,3 @@ $monoFontWeights: 400, 700;
21} 14}
22@include JetbrainsMono.fontFaceVariable($fontName: 'JetBrains MonoVariable'); 15@include JetbrainsMono.fontFaceVariable($fontName: 'JetBrains MonoVariable');
23@include JetbrainsMono.fontFaceVariable($fontName: 'JetBrains MonoVariable', $style: italic); 16@include JetbrainsMono.fontFaceVariable($fontName: 'JetBrains MonoVariable', $style: italic);
24
25body {
26 font-family: 'Roboto', sans-serif;
27}
28
29.CodeMirror {
30 height: 100%;
31}
32
33.problem-fallback-editor {
34 display: block;
35 height: 100%;
36 width: 100%;
37 resize: none;
38 border: none;
39 outline: none;
40 padding: 4px 4px 4px 16px;
41 white-space: pre;
42 overflow-wrap: normal;
43 overflow: auto;
44}
45
46.CodeMirror, .CodeMirror-hints, .problem-fallback-editor {
47 font-size: 16px;
48 font-family: 'JetBrains MonoVariable', 'JetBrains Mono', monospace;
49 font-feature-settings: 'liga', 'calt';
50 font-weight: 400;
51 text-rendering: optimizeLegibility;
52 line-height: 1.35;
53 letter-spacing: 0;
54}
55
56@each $themeName, $theme in $themes {
57 .cm-s-problem-#{$themeName} {
58 &.CodeMirror {
59 background: map.get($theme, 'background');
60 color: map.get($theme, 'foreground');
61 }
62
63 &.problem-fallback-editor {
64 background: map.get($theme, 'background');
65 color: map.get($theme, 'foreground');
66 caret-color: map.get($theme, 'cursor');
67
68 &::selection {
69 background: map.get($theme, 'selection');
70 }
71 }
72
73 .CodeMirror-gutters {
74 background: map.get($theme, 'background');
75 border: none;
76 }
77
78 .CodeMirror-cursor {
79 border-left: 1px solid map.get($theme, 'cursor');
80 }
81
82 div.CodeMirror-selected,
83 &.CodeMirror-focused div.CodeMirror-selected,
84 .CodeMirror-line::selection,
85 .CodeMirror-line > span::selection,
86 .CodeMirror-line > span > span::selection {
87 background: map.get($theme, 'selection');
88 }
89
90 .CodeMirror-guttermarker,
91 .CodeMirror-guttermarker-subtle,
92 .CodeMirror-linenumber {
93 color: map.get($theme, 'lineNumber');
94 }
95
96 .CodeMirror-activeline-background {
97 background: map.get($theme, 'currentLine');
98 }
99
100 .CodeMirror-activeline-gutter {
101 background: map.get($theme, 'currentLine');
102
103 .CodeMirror-guttermarker,
104 .CodeMirror-guttermarker-subtle,
105 .CodeMirror-linenumber {
106 color: map.get($theme, 'foreground');
107 }
108 }
109
110 .cm-keyword {
111 color: map.get($theme, 'keyword');
112 }
113
114 .cm-number {
115 color: map.get($theme, 'number');
116 }
117
118 .cm-lparen, .cm-rparen {
119 color: map.get($theme, 'delimiter');
120 }
121
122 .cm-comment {
123 color: map.get($theme, 'comment');
124 font-style: italic;
125 }
126
127 .problem-predicate, .problem-class, .problem-reference, .problem-enum {
128 color: map.get($theme, 'predicate');
129 }
130
131 .problem-unique-node {
132 color: map.get($theme, 'uniqueNode');
133 }
134
135 .problem-variable {
136 color: map.get($theme, 'variable');
137 }
138 }
139}
140
141.CodeMirror-hints {
142 background: #333;
143 border: 0;
144 border-radius: 4px;
145 box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2),
146 0 5px 8px 0 rgba(0, 0, 0, 0.14),
147 0 1px 8px 0 rgba(0, 0, 0, 0.12);
148 padding: 0;
149}
150
151.CodeMirror-hint {
152 color: #fff;
153 border-radius: 0;
154}
155
156li.CodeMirror-hint-active {
157 background: rgba(128, 203, 196, 0.2);
158}
159
160.annotations-gutter {
161 width: 12px;
162}
163
164.xtext-annotation_error {
165 width: 12px;
166 height: 1em;
167 background-image: url('images/error_an.gif');
168 background-repeat: no-repeat;
169 background-position: bottom;
170}
171
172.xtext-annotation_warning {
173 width: 12px;
174 height: 1em;
175 background-image: url('images/warning_an.gif');
176 background-repeat: no-repeat;
177 background-position: bottom;
178}
179
180.xtext-annotation_info {
181 width: 12px;
182 height: 1em;
183 background-image: url('images/info_an.gif');
184 background-repeat: no-repeat;
185 background-position: bottom;
186}
187
188.xtext-marker_error {
189 z-index: 30;
190 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAABmJLR0QA/wD/AP+gvaeTAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
191 background-repeat: repeat-x;
192 background-position: left bottom;
193}
194
195.xtext-marker_warning {
196 z-index: 20;
197 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAABmJLR0QA/wD/AP+gvaeTAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
198 background-repeat: repeat-x;
199 background-position: left bottom;
200}
201
202.xtext-marker_info {
203 z-index: 10;
204 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAABmJLR0QA/wD/AP+gvaeTAAAANklEQVQI12NkgIIVRx8tZGBg6GZccfRRKAMDgw8DA0M3AwPDIiYGBoZKBgaG7ghruSsMDAwpABH5CoqwzCoTAAAAAElFTkSuQmCC");
205 background-repeat: repeat-x;
206 background-position: left bottom;
207}
208
209.xtext-marker_read {
210 background: rgba(128, 203, 196, 0.2);
211 display: inline-block;
212}
213
214
215.xtext-marker_write {
216 background: rgba(255, 229, 100, 0.2);
217 display: inline-block;
218}
219
220.problem-abstract {
221 font-style: italic;
222}
223
224.problem-containment {
225 font-weight: 700;
226}
227.problem-new-node {
228 font-style: italic;
229}
diff --git a/language-web/src/main/css/xtext/xtext-codemirror.css b/language-web/src/main/css/xtext/xtext-codemirror.css
deleted file mode 100644
index 831b6daf..00000000
--- a/language-web/src/main/css/xtext/xtext-codemirror.css
+++ /dev/null
@@ -1,58 +0,0 @@
1.CodeMirror {
2 height: 100%;
3}
4
5.annotations-gutter {
6 width: 12px;
7 background: #f0f0f0;
8}
9
10.xtext-annotation_error {
11 width: 12px;
12 height: 12px;
13 background-image: url('images/error_an.gif');
14 background-repeat: no-repeat;
15}
16
17.xtext-annotation_warning {
18 width: 12px;
19 height: 12px;
20 background-image: url('images/warning_an.gif');
21 background-repeat: no-repeat;
22}
23
24.xtext-annotation_info {
25 width: 12px;
26 height: 12px;
27 background-image: url('images/info_an.gif');
28 background-repeat: no-repeat;
29}
30
31.xtext-marker_error {
32 z-index: 30;
33 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAABmJLR0QA/wD/AP+gvaeTAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
34 background-repeat: repeat-x;
35 background-position: left bottom;
36}
37
38.xtext-marker_warning {
39 z-index: 20;
40 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAABmJLR0QA/wD/AP+gvaeTAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
41 background-repeat: repeat-x;
42 background-position: left bottom;
43}
44
45.xtext-marker_info {
46 z-index: 10;
47 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAABmJLR0QA/wD/AP+gvaeTAAAANklEQVQI12NkgIIVRx8tZGBg6GZccfRRKAMDgw8DA0M3AwPDIiYGBoZKBgaG7ghruSsMDAwpABH5CoqwzCoTAAAAAElFTkSuQmCC");
48 background-repeat: repeat-x;
49 background-position: left bottom;
50}
51
52.xtext-marker_read {
53 background-color: #ddd;
54}
55
56.xtext-marker_write {
57 background-color: yellow;
58}
diff --git a/language-web/src/main/images/error_an.gif b/language-web/src/main/images/error_an.gif
deleted file mode 100644
index e014ce90..00000000
--- a/language-web/src/main/images/error_an.gif
+++ /dev/null
Binary files differ
diff --git a/language-web/src/main/images/info_an.gif b/language-web/src/main/images/info_an.gif
deleted file mode 100644
index d62ad9dd..00000000
--- a/language-web/src/main/images/info_an.gif
+++ /dev/null
Binary files differ
diff --git a/language-web/src/main/images/warning_an.gif b/language-web/src/main/images/warning_an.gif
deleted file mode 100644
index 9ef66dd7..00000000
--- a/language-web/src/main/images/warning_an.gif
+++ /dev/null
Binary files differ
diff --git a/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java b/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
index cf4c00fa..b13ae95d 100644
--- a/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
+++ b/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
@@ -1,8 +1,11 @@
1package tools.refinery.language.web; 1package tools.refinery.language.web;
2 2
3import java.io.IOException; 3import java.io.IOException;
4import java.time.Duration;
4import java.util.regex.Pattern; 5import java.util.regex.Pattern;
5 6
7import org.eclipse.jetty.http.HttpHeader;
8
6import jakarta.servlet.Filter; 9import jakarta.servlet.Filter;
7import jakarta.servlet.FilterChain; 10import jakarta.servlet.FilterChain;
8import jakarta.servlet.FilterConfig; 11import jakarta.servlet.FilterConfig;
@@ -13,16 +16,11 @@ import jakarta.servlet.http.HttpServletRequest;
13import jakarta.servlet.http.HttpServletResponse; 16import jakarta.servlet.http.HttpServletResponse;
14 17
15public class CacheControlFilter implements Filter { 18public class CacheControlFilter implements Filter {
16
17 private static final String CACHE_CONTROL_HEADER = "Cache-Control";
18
19 private static final String EXPIRES_HEADER = "Expires";
20
21 private static final Pattern CACHE_URI_PATTERN = Pattern.compile(".*\\.(css|gif|js|map|png|svg|woff2)"); 19 private static final Pattern CACHE_URI_PATTERN = Pattern.compile(".*\\.(css|gif|js|map|png|svg|woff2)");
22 20
23 private static final long EXPIRY = 31536000; 21 private static final Duration EXPIRY = Duration.ofDays(365);
24 22
25 private static final String CACHE_CONTROL_CACHE_VALUE = "public, max-age: " + EXPIRY + ", immutable"; 23 private static final String CACHE_CONTROL_CACHE_VALUE = "public, max-age: " + EXPIRY.toSeconds() + ", immutable";
26 24
27 private static final String CACHE_CONTROL_NO_CACHE_VALUE = "no-cache, no-store, max-age: 0, must-revalidate"; 25 private static final String CACHE_CONTROL_NO_CACHE_VALUE = "no-cache, no-store, max-age: 0, must-revalidate";
28 26
@@ -36,11 +34,12 @@ public class CacheControlFilter implements Filter {
36 throws IOException, ServletException { 34 throws IOException, ServletException {
37 if (request instanceof HttpServletRequest httpRequest && response instanceof HttpServletResponse httpResponse) { 35 if (request instanceof HttpServletRequest httpRequest && response instanceof HttpServletResponse httpResponse) {
38 if (CACHE_URI_PATTERN.matcher(httpRequest.getRequestURI()).matches()) { 36 if (CACHE_URI_PATTERN.matcher(httpRequest.getRequestURI()).matches()) {
39 httpResponse.setHeader(CACHE_CONTROL_HEADER, CACHE_CONTROL_CACHE_VALUE); 37 httpResponse.setHeader(HttpHeader.CACHE_CONTROL.asString(), CACHE_CONTROL_CACHE_VALUE);
40 httpResponse.setDateHeader(EXPIRES_HEADER, System.currentTimeMillis() + EXPIRY * 1000L); 38 httpResponse.setDateHeader(HttpHeader.EXPIRES.asString(),
39 System.currentTimeMillis() + EXPIRY.toMillis());
41 } else { 40 } else {
42 httpResponse.setHeader(CACHE_CONTROL_HEADER, CACHE_CONTROL_NO_CACHE_VALUE); 41 httpResponse.setHeader(HttpHeader.CACHE_CONTROL.asString(), CACHE_CONTROL_NO_CACHE_VALUE);
43 httpResponse.setDateHeader(EXPIRES_HEADER, 0); 42 httpResponse.setDateHeader(HttpHeader.EXPIRES.asString(), 0);
44 } 43 }
45 } 44 }
46 chain.doFilter(request, response); 45 chain.doFilter(request, response);
diff --git a/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java b/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java
index 799a9c64..ec55036f 100644
--- a/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java
+++ b/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java
@@ -3,9 +3,33 @@
3 */ 3 */
4package tools.refinery.language.web; 4package tools.refinery.language.web;
5 5
6import org.eclipse.xtext.web.server.XtextServiceDispatcher;
7import org.eclipse.xtext.web.server.model.IWebDocumentProvider;
8import org.eclipse.xtext.web.server.model.XtextWebDocumentAccess;
9import org.eclipse.xtext.web.server.occurrences.OccurrencesService;
10
11import tools.refinery.language.web.occurrences.ProblemOccurrencesService;
12import tools.refinery.language.web.xtext.server.push.PushServiceDispatcher;
13import tools.refinery.language.web.xtext.server.push.PushWebDocumentAccess;
14import tools.refinery.language.web.xtext.server.push.PushWebDocumentProvider;
6 15
7/** 16/**
8 * Use this class to register additional components to be used within the web application. 17 * Use this class to register additional components to be used within the web application.
9 */ 18 */
10public class ProblemWebModule extends AbstractProblemWebModule { 19public class ProblemWebModule extends AbstractProblemWebModule {
20 public Class<? extends IWebDocumentProvider> bindIWebDocumentProvider() {
21 return PushWebDocumentProvider.class;
22 }
23
24 public Class<? extends XtextWebDocumentAccess> bindXtextWebDocumentAccess() {
25 return PushWebDocumentAccess.class;
26 }
27
28 public Class<? extends XtextServiceDispatcher> bindXtextServiceDispatcher() {
29 return PushServiceDispatcher.class;
30 }
31
32 public Class<? extends OccurrencesService> bindOccurrencesService() {
33 return ProblemOccurrencesService.class;
34 }
11} 35}
diff --git a/language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java b/language-web/src/main/java/tools/refinery/language/web/ProblemWebSocketServlet.java
index 49457002..df67b521 100644
--- a/language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java
+++ b/language-web/src/main/java/tools/refinery/language/web/ProblemWebSocketServlet.java
@@ -1,19 +1,13 @@
1/*
2 * generated by Xtext 2.25.0
3 */
4package tools.refinery.language.web; 1package tools.refinery.language.web;
5 2
6import org.eclipse.xtext.util.DisposableRegistry; 3import org.eclipse.xtext.util.DisposableRegistry;
7 4
8import jakarta.servlet.ServletException; 5import jakarta.servlet.ServletException;
9import tools.refinery.language.web.xtext.XtextServlet; 6import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet;
10 7
11/** 8public class ProblemWebSocketServlet extends XtextWebSocketServlet {
12 * Deploy this class into a servlet container to enable DSL-specific services.
13 */
14public class ProblemServlet extends XtextServlet {
15 9
16 private static final long serialVersionUID = -9204695886561362912L; 10 private static final long serialVersionUID = -7040955470384797008L;
17 11
18 private transient DisposableRegistry disposableRegistry; 12 private transient DisposableRegistry disposableRegistry;
19 13
@@ -32,5 +26,4 @@ public class ProblemServlet extends XtextServlet {
32 } 26 }
33 super.destroy(); 27 super.destroy();
34 } 28 }
35
36} 29}
diff --git a/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java b/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
index c253422b..ffd903d0 100644
--- a/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
+++ b/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
@@ -9,6 +9,7 @@ import java.net.InetSocketAddress;
9import java.net.URI; 9import java.net.URI;
10import java.net.URISyntaxException; 10import java.net.URISyntaxException;
11import java.util.EnumSet; 11import java.util.EnumSet;
12import java.util.Optional;
12import java.util.Set; 13import java.util.Set;
13 14
14import org.eclipse.jetty.server.Server; 15import org.eclipse.jetty.server.Server;
@@ -17,29 +18,36 @@ import org.eclipse.jetty.servlet.DefaultServlet;
17import org.eclipse.jetty.servlet.ServletContextHandler; 18import org.eclipse.jetty.servlet.ServletContextHandler;
18import org.eclipse.jetty.servlet.ServletHolder; 19import org.eclipse.jetty.servlet.ServletHolder;
19import org.eclipse.jetty.util.resource.Resource; 20import org.eclipse.jetty.util.resource.Resource;
21import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
20import org.slf4j.Logger; 22import org.slf4j.Logger;
21import org.slf4j.LoggerFactory; 23import org.slf4j.LoggerFactory;
22 24
23import jakarta.servlet.DispatcherType; 25import jakarta.servlet.DispatcherType;
24import jakarta.servlet.SessionTrackingMode; 26import jakarta.servlet.SessionTrackingMode;
27import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet;
25 28
26public class ServerLauncher { 29public class ServerLauncher {
27 public static final String DEFAULT_LISTEN_ADDRESS = "localhost"; 30 public static final String DEFAULT_LISTEN_ADDRESS = "localhost";
28 31
29 public static final int DEFAULT_LISTEN_PORT = 1312; 32 public static final int DEFAULT_LISTEN_PORT = 1312;
30 33
31 // Use this cookie name for load balancing. 34 public static final int DEFAULT_PUBLIC_PORT = 443;
32 public static final String SESSION_COOKIE_NAME = "JSESSIONID"; 35
36 public static final int HTTP_DEFAULT_PORT = 80;
37
38 public static final int HTTPS_DEFAULT_PORT = 443;
39
40 public static final String ALLOWED_ORIGINS_SEPARATOR = ";";
33 41
34 private static final Logger LOG = LoggerFactory.getLogger(ServerLauncher.class); 42 private static final Logger LOG = LoggerFactory.getLogger(ServerLauncher.class);
35 43
36 private final Server server; 44 private final Server server;
37 45
38 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource) { 46 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource, Optional<String[]> allowedOrigins) {
39 server = new Server(bindAddress); 47 server = new Server(bindAddress);
40 var handler = new ServletContextHandler(); 48 var handler = new ServletContextHandler();
41 addSessionHandler(handler); 49 addSessionHandler(handler);
42 addProblemServlet(handler); 50 addProblemServlet(handler, allowedOrigins);
43 if (baseResource != null) { 51 if (baseResource != null) {
44 handler.setBaseResource(baseResource); 52 handler.setBaseResource(baseResource);
45 handler.setWelcomeFiles(new String[] { "index.html" }); 53 handler.setWelcomeFiles(new String[] { "index.html" });
@@ -52,12 +60,21 @@ public class ServerLauncher {
52 private void addSessionHandler(ServletContextHandler handler) { 60 private void addSessionHandler(ServletContextHandler handler) {
53 var sessionHandler = new SessionHandler(); 61 var sessionHandler = new SessionHandler();
54 sessionHandler.setSessionTrackingModes(Set.of(SessionTrackingMode.COOKIE)); 62 sessionHandler.setSessionTrackingModes(Set.of(SessionTrackingMode.COOKIE));
55 sessionHandler.setSessionCookie(SESSION_COOKIE_NAME);
56 handler.setSessionHandler(sessionHandler); 63 handler.setSessionHandler(sessionHandler);
57 } 64 }
58 65
59 private void addProblemServlet(ServletContextHandler handler) { 66 private void addProblemServlet(ServletContextHandler handler, Optional<String[]> allowedOrigins) {
60 handler.addServlet(ProblemServlet.class, "/xtext-service/*"); 67 var problemServletHolder = new ServletHolder(ProblemWebSocketServlet.class);
68 if (allowedOrigins.isEmpty()) {
69 LOG.warn("All WebSocket origins are allowed! This setting should not be used in production!");
70 } else {
71 var allowedOriginsString = String.join(XtextWebSocketServlet.ALLOWED_ORIGINS_SEPARATOR,
72 allowedOrigins.get());
73 problemServletHolder.setInitParameter(XtextWebSocketServlet.ALLOWED_ORIGINS_INIT_PARAM,
74 allowedOriginsString);
75 }
76 handler.addServlet(problemServletHolder, "/xtext-service");
77 JettyWebSocketServletContainerInitializer.configure(handler, null);
61 } 78 }
62 79
63 private void addDefaultServlet(ServletContextHandler handler) { 80 private void addDefaultServlet(ServletContextHandler handler) {
@@ -80,7 +97,8 @@ public class ServerLauncher {
80 try { 97 try {
81 var bindAddress = getBindAddress(); 98 var bindAddress = getBindAddress();
82 var baseResource = getBaseResource(); 99 var baseResource = getBaseResource();
83 var serverLauncher = new ServerLauncher(bindAddress, baseResource); 100 var allowedOrigins = getAllowedOrigins();
101 var serverLauncher = new ServerLauncher(bindAddress, baseResource, allowedOrigins);
84 serverLauncher.start(); 102 serverLauncher.start();
85 } catch (Exception exception) { 103 } catch (Exception exception) {
86 LOG.error("Fatal server error", exception); 104 LOG.error("Fatal server error", exception);
@@ -132,4 +150,43 @@ public class ServerLauncher {
132 // Fall back to just serving a 404. 150 // Fall back to just serving a 404.
133 return null; 151 return null;
134 } 152 }
153
154 private static String getPublicHost() {
155 var publicHost = System.getenv("PUBLIC_HOST");
156 if (publicHost != null) {
157 return publicHost.toLowerCase();
158 }
159 return null;
160 }
161
162 private static int getPublicPort() {
163 var portStr = System.getenv("PUBLIC_PORT");
164 if (portStr != null) {
165 return Integer.parseInt(portStr);
166 }
167 return DEFAULT_LISTEN_PORT;
168 }
169
170 private static Optional<String[]> getAllowedOrigins() {
171 var allowedOrigins = System.getenv("ALLOWED_ORIGINS");
172 if (allowedOrigins != null) {
173 return Optional.of(allowedOrigins.split(ALLOWED_ORIGINS_SEPARATOR));
174 }
175 return getAllowedOriginsFromPublicHostAndPort();
176 }
177
178 private static Optional<String[]> getAllowedOriginsFromPublicHostAndPort() {
179 var publicHost = getPublicHost();
180 if (publicHost == null) {
181 return Optional.empty();
182 }
183 int publicPort = getPublicPort();
184 var scheme = publicPort == HTTPS_DEFAULT_PORT ? "https" : "http";
185 var urlWithPort = String.format("%s://%s:%d", scheme, publicHost, publicPort);
186 if (publicPort == HTTPS_DEFAULT_PORT || publicPort == HTTP_DEFAULT_PORT) {
187 var urlWithoutPort = String.format("%s://%s", scheme, publicHost);
188 return Optional.of(new String[] { urlWithPort, urlWithoutPort });
189 }
190 return Optional.of(new String[] { urlWithPort });
191 }
135} 192}
diff --git a/language-web/src/main/java/tools/refinery/language/web/occurrences/ProblemOccurrencesService.java b/language-web/src/main/java/tools/refinery/language/web/occurrences/ProblemOccurrencesService.java
new file mode 100644
index 00000000..d32bbb54
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/occurrences/ProblemOccurrencesService.java
@@ -0,0 +1,16 @@
1package tools.refinery.language.web.occurrences;
2
3import org.eclipse.emf.ecore.EObject;
4import org.eclipse.xtext.web.server.occurrences.OccurrencesService;
5
6import com.google.inject.Singleton;
7
8import tools.refinery.language.model.problem.NamedElement;
9
10@Singleton
11public class ProblemOccurrencesService extends OccurrencesService {
12 @Override
13 protected boolean filter(EObject element) {
14 return super.filter(element) && element instanceof NamedElement;
15 }
16}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java b/language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java
deleted file mode 100644
index d0ba6a2d..00000000
--- a/language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java
+++ /dev/null
@@ -1,107 +0,0 @@
1/**
2 * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 */
9package tools.refinery.language.web.xtext;
10
11import java.io.IOException;
12import java.net.URLDecoder;
13import java.nio.charset.Charset;
14import java.util.Collections;
15import java.util.Enumeration;
16import java.util.HashMap;
17import java.util.Map;
18import java.util.Set;
19
20import org.eclipse.xtext.web.server.IServiceContext;
21import org.eclipse.xtext.web.server.ISession;
22
23import com.google.common.io.CharStreams;
24
25import jakarta.servlet.http.HttpServletRequest;
26
27/**
28 * Provides the parameters and metadata of an {@link HttpServletRequest}.
29 */
30class HttpServiceContext implements IServiceContext {
31 private final HttpServletRequest request;
32
33 private final Map<String, String> parameters = new HashMap<>();
34
35 private HttpSessionWrapper sessionWrapper;
36
37 public HttpServiceContext(HttpServletRequest request) throws IOException {
38 this.request = request;
39 initializeParameters();
40 }
41
42 private void initializeParameters() throws IOException {
43 initializeUrlEncodedParameters();
44 initializeRequestParameters();
45 if (!parameters.containsKey(IServiceContext.SERVICE_TYPE)) {
46 String substring = null;
47 if (request.getPathInfo() != null) {
48 substring = request.getPathInfo().substring(1);
49 }
50 parameters.put(IServiceContext.SERVICE_TYPE, substring);
51 }
52 }
53
54 private void initializeUrlEncodedParameters() throws IOException {
55 String[] contentType = null;
56 if (request.getContentType() != null) {
57 contentType = request.getContentType().split(";(\\s*)");
58 }
59 if (contentType != null && "application/x-www-form-urlencoded".equals(contentType[0])) {
60 String charset = null;
61 if (contentType.length >= 2 && contentType[1].startsWith("charset=")) {
62 charset = (contentType[1]).substring("charset=".length());
63 } else {
64 charset = Charset.defaultCharset().toString();
65 }
66 String[] encodedParams = CharStreams.toString(request.getReader()).split("&");
67 for (String param : encodedParams) {
68 int nameEnd = param.indexOf("=");
69 if (nameEnd > 0) {
70 String key = param.substring(0, nameEnd);
71 String value = URLDecoder.decode(param.substring(nameEnd + 1), charset);
72 parameters.put(key, value);
73 }
74 }
75 }
76 }
77
78 private void initializeRequestParameters() {
79 Enumeration<String> paramNames = request.getParameterNames();
80 while (paramNames.hasMoreElements()) {
81 String name = paramNames.nextElement();
82 parameters.put(name, request.getParameter(name));
83 }
84 }
85
86 @Override
87 public Set<String> getParameterKeys() {
88 return Collections.unmodifiableSet(parameters.keySet());
89 }
90
91 @Override
92 public String getParameter(String key) {
93 return parameters.get(key);
94 }
95
96 @Override
97 public ISession getSession() {
98 if (sessionWrapper == null) {
99 sessionWrapper = new HttpSessionWrapper(request.getSession(true));
100 }
101 return sessionWrapper;
102 }
103
104 public HttpServletRequest getRequest() {
105 return request;
106 }
107}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java b/language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java
deleted file mode 100644
index 8a5e19ba..00000000
--- a/language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java
+++ /dev/null
@@ -1,53 +0,0 @@
1/**
2 * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 */
9package tools.refinery.language.web.xtext;
10
11import org.eclipse.xtext.web.server.ISession;
12import org.eclipse.xtext.xbase.lib.Functions.Function0;
13
14import jakarta.servlet.http.HttpSession;
15
16/**
17 * Provides access to the information stored in a {@link HttpSession}.
18 */
19record HttpSessionWrapper(HttpSession session) implements ISession {
20 @SuppressWarnings("unchecked")
21 @Override
22 public <T> T get(Object key) {
23 return (T) session.getAttribute(key.toString());
24 }
25
26 @Override
27 public <T> T get(Object key, Function0<? extends T> factory) {
28 synchronized (session) {
29 T sessionValue = get(key);
30 if (sessionValue != null) {
31 return sessionValue;
32 } else {
33 T factoryValue = factory.apply();
34 put(key, factoryValue);
35 return factoryValue;
36 }
37 }
38 }
39
40 @Override
41 public void put(Object key, Object value) {
42 session.setAttribute(key.toString(), value);
43 }
44
45 @Override
46 public void remove(Object key) {
47 session.removeAttribute(key.toString());
48 }
49
50 public HttpSession getSession() {
51 return session;
52 }
53}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java b/language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java
deleted file mode 100644
index f39bec12..00000000
--- a/language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java
+++ /dev/null
@@ -1,196 +0,0 @@
1/**
2 * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 */
9package tools.refinery.language.web.xtext;
10
11import java.io.IOException;
12import java.util.Set;
13
14import org.eclipse.emf.common.util.URI;
15import org.eclipse.xtext.resource.IResourceServiceProvider;
16import org.eclipse.xtext.web.server.IServiceContext;
17import org.eclipse.xtext.web.server.IServiceResult;
18import org.eclipse.xtext.web.server.IUnwrappableServiceResult;
19import org.eclipse.xtext.web.server.InvalidRequestException;
20import org.eclipse.xtext.web.server.XtextServiceDispatcher;
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
24import com.google.common.base.Objects;
25import com.google.common.base.Strings;
26import com.google.gson.Gson;
27import com.google.inject.Injector;
28
29import jakarta.servlet.ServletException;
30import jakarta.servlet.http.HttpServlet;
31import jakarta.servlet.http.HttpServletRequest;
32import jakarta.servlet.http.HttpServletResponse;
33
34/**
35 * An HTTP servlet for publishing the Xtext services. Include this into your web
36 * server by creating a subclass that executes the standalone setups of your
37 * languages in its {@link #init()} method:
38 *
39 * <pre>
40 * &#64;WebServlet(name = "Xtext Services", urlPatterns = "/xtext-service/*")
41 * class MyXtextServlet extends XtextServlet {
42 * override init() {
43 * super.init();
44 * MyDslWebSetup.doSetup();
45 * }
46 * }
47 * </pre>
48 *
49 * Use the {@code WebServlet} annotation to register your servlet. The default
50 * URL pattern for Xtext services is {@code "/xtext-service/*"}.
51 */
52public class XtextServlet extends HttpServlet {
53
54 private static final long serialVersionUID = 7784324070547781918L;
55
56 private static final IResourceServiceProvider.Registry SERVICE_PROVIDER_REGISTRY = IResourceServiceProvider.Registry.INSTANCE;
57
58 private static final String ENCODING = "UTF-8";
59
60 private static final String INVALID_REQUEST_MESSAGE = "Invalid request ({}): {}";
61
62 private final transient Logger log = LoggerFactory.getLogger(this.getClass());
63
64 private final transient Gson gson = new Gson();
65
66 @Override
67 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
68 try {
69 super.service(req, resp);
70 } catch (InvalidRequestException.ResourceNotFoundException exception) {
71 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
72 resp.sendError(HttpServletResponse.SC_NOT_FOUND, exception.getMessage());
73 } catch (InvalidRequestException.InvalidDocumentStateException exception) {
74 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
75 resp.sendError(HttpServletResponse.SC_CONFLICT, exception.getMessage());
76 } catch (InvalidRequestException.PermissionDeniedException exception) {
77 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
78 resp.sendError(HttpServletResponse.SC_FORBIDDEN, exception.getMessage());
79 } catch (InvalidRequestException exception) {
80 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
81 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, exception.getMessage());
82 }
83 }
84
85 @Override
86 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
87 XtextServiceDispatcher.ServiceDescriptor service = getService(req);
88 if (!service.isHasConflict() && (service.isHasSideEffects() || hasTextInput(service))) {
89 super.doGet(req, resp);
90 } else {
91 doService(service, resp);
92 }
93 }
94
95 @Override
96 protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
97 XtextServiceDispatcher.ServiceDescriptor service = getService(req);
98 String type = service.getContext().getParameter(IServiceContext.SERVICE_TYPE);
99 if (!service.isHasConflict() && !Objects.equal(type, "update")) {
100 super.doPut(req, resp);
101 } else {
102 doService(service, resp);
103 }
104 }
105
106 @Override
107 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
108 XtextServiceDispatcher.ServiceDescriptor service = getService(req);
109 String type = service.getContext().getParameter(IServiceContext.SERVICE_TYPE);
110 if (!service.isHasConflict()
111 && (!service.isHasSideEffects() && !hasTextInput(service) || Objects.equal(type, "update"))) {
112 super.doPost(req, resp);
113 } else {
114 doService(service, resp);
115 }
116 }
117
118 protected boolean hasTextInput(XtextServiceDispatcher.ServiceDescriptor service) {
119 Set<String> parameterKeys = service.getContext().getParameterKeys();
120 return parameterKeys.contains("fullText") || parameterKeys.contains("deltaText");
121 }
122
123 /**
124 * Retrieve the service metadata for the given request. This involves resolving
125 * the Guice injector for the respective language, querying the
126 * {@link XtextServiceDispatcher}, and checking the permission to invoke the
127 * service.
128 */
129 protected XtextServiceDispatcher.ServiceDescriptor getService(HttpServletRequest request) throws IOException {
130 HttpServiceContext serviceContext = new HttpServiceContext(request);
131 Injector injector = getInjector(serviceContext);
132 XtextServiceDispatcher serviceDispatcher = injector.getInstance(XtextServiceDispatcher.class);
133 return serviceDispatcher.getService(serviceContext);
134 }
135
136 /**
137 * Invoke the service function of the given service descriptor and write its
138 * result to the servlet response in Json format. An exception is made for
139 * {@link IUnwrappableServiceResult}: here the document itself is written into
140 * the response instead of wrapping it into a Json object.
141 */
142 protected void doService(XtextServiceDispatcher.ServiceDescriptor service, HttpServletResponse response)
143 throws IOException {
144 IServiceResult result = service.getService().apply();
145 response.setStatus(HttpServletResponse.SC_OK);
146 response.setCharacterEncoding(ENCODING);
147 response.setHeader("Cache-Control", "no-cache");
148 if (result instanceof IUnwrappableServiceResult unwrapResult && unwrapResult.getContent() != null) {
149 String contentType = null;
150 if (unwrapResult.getContentType() != null) {
151 contentType = unwrapResult.getContentType();
152 } else {
153 contentType = "text/plain";
154 }
155 response.setContentType(contentType);
156 response.getWriter().write(unwrapResult.getContent());
157 } else {
158 response.setContentType("text/x-json");
159 gson.toJson(result, response.getWriter());
160 }
161 }
162
163 /**
164 * Resolve the Guice injector for the language associated with the given
165 * context.
166 */
167 protected Injector getInjector(HttpServiceContext serviceContext)
168 throws InvalidRequestException.UnknownLanguageException {
169 IResourceServiceProvider resourceServiceProvider = null;
170 String parameter = serviceContext.getParameter("resource");
171 if (parameter == null) {
172 parameter = "";
173 }
174 URI emfURI = URI.createURI(parameter);
175 String contentType = serviceContext.getParameter("contentType");
176 if (Strings.isNullOrEmpty(contentType)) {
177 resourceServiceProvider = SERVICE_PROVIDER_REGISTRY.getResourceServiceProvider(emfURI);
178 if (resourceServiceProvider == null) {
179 if (emfURI.toString().isEmpty()) {
180 throw new InvalidRequestException.UnknownLanguageException(
181 "Unable to identify the Xtext language: missing parameter 'resource' or 'contentType'.");
182 } else {
183 throw new InvalidRequestException.UnknownLanguageException(
184 "Unable to identify the Xtext language for resource " + emfURI + ".");
185 }
186 }
187 } else {
188 resourceServiceProvider = SERVICE_PROVIDER_REGISTRY.getResourceServiceProvider(emfURI, contentType);
189 if (resourceServiceProvider == null) {
190 throw new InvalidRequestException.UnknownLanguageException(
191 "Unable to identify the Xtext language for contentType " + contentType + ".");
192 }
193 }
194 return resourceServiceProvider.get(Injector.class);
195 }
196} \ No newline at end of file
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/PongResult.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/PongResult.java
new file mode 100644
index 00000000..fe510f51
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/PongResult.java
@@ -0,0 +1,44 @@
1package tools.refinery.language.web.xtext.server;
2
3import java.util.Objects;
4
5import org.eclipse.xtext.web.server.IServiceResult;
6
7public class PongResult implements IServiceResult {
8 private String pong;
9
10 public PongResult(String pong) {
11 super();
12 this.pong = pong;
13 }
14
15 public String getPong() {
16 return pong;
17 }
18
19 public void setPong(String pong) {
20 this.pong = pong;
21 }
22
23 @Override
24 public int hashCode() {
25 return Objects.hash(pong);
26 }
27
28 @Override
29 public boolean equals(Object obj) {
30 if (this == obj)
31 return true;
32 if (obj == null)
33 return false;
34 if (getClass() != obj.getClass())
35 return false;
36 PongResult other = (PongResult) obj;
37 return Objects.equals(pong, other.pong);
38 }
39
40 @Override
41 public String toString() {
42 return "PongResult [pong=" + pong + "]";
43 }
44}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandler.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandler.java
new file mode 100644
index 00000000..2a85afe3
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandler.java
@@ -0,0 +1,8 @@
1package tools.refinery.language.web.xtext.server;
2
3import tools.refinery.language.web.xtext.server.message.XtextWebResponse;
4
5@FunctionalInterface
6public interface ResponseHandler {
7 void onResponse(XtextWebResponse response) throws ResponseHandlerException;
8}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java
new file mode 100644
index 00000000..34fcb546
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java
@@ -0,0 +1,14 @@
1package tools.refinery.language.web.xtext.server;
2
3public class ResponseHandlerException extends Exception {
4
5 private static final long serialVersionUID = 3589866922420268164L;
6
7 public ResponseHandlerException(String message, Throwable cause) {
8 super(message, cause);
9 }
10
11 public ResponseHandlerException(String message) {
12 super(message);
13 }
14}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/SubscribingServiceContext.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/SubscribingServiceContext.java
new file mode 100644
index 00000000..78e00a9e
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/SubscribingServiceContext.java
@@ -0,0 +1,26 @@
1package tools.refinery.language.web.xtext.server;
2
3import java.util.Set;
4
5import org.eclipse.xtext.web.server.IServiceContext;
6import org.eclipse.xtext.web.server.ISession;
7
8import tools.refinery.language.web.xtext.server.push.PrecomputationListener;
9
10public record SubscribingServiceContext(IServiceContext delegate, PrecomputationListener subscriber)
11 implements IServiceContext {
12 @Override
13 public Set<String> getParameterKeys() {
14 return delegate.getParameterKeys();
15 }
16
17 @Override
18 public String getParameter(String key) {
19 return delegate.getParameter(key);
20 }
21
22 @Override
23 public ISession getSession() {
24 return delegate.getSession();
25 }
26}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java
new file mode 100644
index 00000000..0b417b06
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java
@@ -0,0 +1,180 @@
1package tools.refinery.language.web.xtext.server;
2
3import java.lang.ref.WeakReference;
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
8
9import org.eclipse.emf.common.util.URI;
10import org.eclipse.xtext.resource.IResourceServiceProvider;
11import org.eclipse.xtext.util.IDisposable;
12import org.eclipse.xtext.web.server.IServiceContext;
13import org.eclipse.xtext.web.server.IServiceResult;
14import org.eclipse.xtext.web.server.ISession;
15import org.eclipse.xtext.web.server.InvalidRequestException;
16import org.eclipse.xtext.web.server.InvalidRequestException.UnknownLanguageException;
17import org.eclipse.xtext.web.server.XtextServiceDispatcher;
18import org.slf4j.Logger;
19import org.slf4j.LoggerFactory;
20
21import com.google.common.base.Strings;
22import com.google.inject.Injector;
23
24import tools.refinery.language.web.xtext.server.message.XtextWebErrorKind;
25import tools.refinery.language.web.xtext.server.message.XtextWebErrorResponse;
26import tools.refinery.language.web.xtext.server.message.XtextWebOkResponse;
27import tools.refinery.language.web.xtext.server.message.XtextWebPushMessage;
28import tools.refinery.language.web.xtext.server.message.XtextWebRequest;
29import tools.refinery.language.web.xtext.server.push.PrecomputationListener;
30import tools.refinery.language.web.xtext.server.push.PushWebDocument;
31import tools.refinery.language.web.xtext.servlet.SimpleServiceContext;
32
33public class TransactionExecutor implements IDisposable, PrecomputationListener {
34 private static final Logger LOG = LoggerFactory.getLogger(TransactionExecutor.class);
35
36 private final ISession session;
37
38 private final IResourceServiceProvider.Registry resourceServiceProviderRegistry;
39
40 private final Map<String, WeakReference<PushWebDocument>> subscriptions = new HashMap<>();
41
42 private ResponseHandler responseHandler;
43
44 private Object callPendingLock = new Object();
45
46 private boolean callPending;
47
48 private List<XtextWebPushMessage> pendingPushMessages = new ArrayList<>();
49
50 public TransactionExecutor(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) {
51 this.session = session;
52 this.resourceServiceProviderRegistry = resourceServiceProviderRegistry;
53 }
54
55 public void setResponseHandler(ResponseHandler responseHandler) {
56 this.responseHandler = responseHandler;
57 }
58
59 public void handleRequest(XtextWebRequest request) throws ResponseHandlerException {
60 var serviceContext = new SimpleServiceContext(session, request.getRequestData());
61 var ping = serviceContext.getParameter("ping");
62 if (ping != null) {
63 responseHandler.onResponse(new XtextWebOkResponse(request, new PongResult(ping)));
64 return;
65 }
66 synchronized (callPendingLock) {
67 if (callPending) {
68 LOG.error("Reentrant request detected");
69 }
70 if (!pendingPushMessages.isEmpty()) {
71 LOG.error("{} push messages got stuck without a pending request", pendingPushMessages.size());
72 }
73 callPending = true;
74 }
75 try {
76 var injector = getInjector(serviceContext);
77 var serviceDispatcher = injector.getInstance(XtextServiceDispatcher.class);
78 var service = serviceDispatcher.getService(new SubscribingServiceContext(serviceContext, this));
79 var serviceResult = service.getService().apply();
80 responseHandler.onResponse(new XtextWebOkResponse(request, serviceResult));
81 } catch (InvalidRequestException e) {
82 responseHandler.onResponse(new XtextWebErrorResponse(request, XtextWebErrorKind.REQUEST_ERROR, e));
83 } catch (RuntimeException e) {
84 responseHandler.onResponse(new XtextWebErrorResponse(request, XtextWebErrorKind.SERVER_ERROR, e));
85 } finally {
86 synchronized (callPendingLock) {
87 for (var message : pendingPushMessages) {
88 try {
89 responseHandler.onResponse(message);
90 } catch (ResponseHandlerException | RuntimeException e) {
91 LOG.error("Error while flushing push message", e);
92 }
93 }
94 pendingPushMessages.clear();
95 callPending = false;
96 }
97 }
98 }
99
100 @Override
101 public void onPrecomputedServiceResult(String resourceId, String stateId, String serviceName,
102 IServiceResult serviceResult) throws ResponseHandlerException {
103 var message = new XtextWebPushMessage(resourceId, stateId, serviceName, serviceResult);
104 synchronized (callPendingLock) {
105 // If we're currently responding to a call we must delay any push messages until
106 // the reply is sent, because push messages relating to the new state id must be
107 // sent after the response with the new state id so that the client knows about
108 // the new state when it receives the push message.
109 if (callPending) {
110 pendingPushMessages.add(message);
111 } else {
112 responseHandler.onResponse(message);
113 }
114 }
115 }
116
117 @Override
118 public void onSubscribeToPrecomputationEvents(String resourceId, PushWebDocument document) {
119 PushWebDocument previousDocument = null;
120 var previousSubscription = subscriptions.get(resourceId);
121 if (previousSubscription != null) {
122 previousDocument = previousSubscription.get();
123 }
124 if (previousDocument == document) {
125 return;
126 }
127 if (previousDocument != null) {
128 previousDocument.removePrecomputationListener(this);
129 }
130 subscriptions.put(resourceId, new WeakReference<>(document));
131 }
132
133 /**
134 * Get the injector to satisfy the request in the {@code serviceContext}.
135 *
136 * Based on {@link org.eclipse.xtext.web.servlet.XtextServlet#getInjector}.
137 *
138 * @param serviceContext the Xtext service context of the request
139 * @return the injector for the Xtext language in the request
140 * @throws UnknownLanguageException if the Xtext language cannot be determined
141 */
142 protected Injector getInjector(IServiceContext context) {
143 IResourceServiceProvider resourceServiceProvider = null;
144 var resourceName = context.getParameter("resource");
145 if (resourceName == null) {
146 resourceName = "";
147 }
148 var emfURI = URI.createURI(resourceName);
149 var contentType = context.getParameter("contentType");
150 if (Strings.isNullOrEmpty(contentType)) {
151 resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(emfURI);
152 if (resourceServiceProvider == null) {
153 if (emfURI.toString().isEmpty()) {
154 throw new UnknownLanguageException(
155 "Unable to identify the Xtext language: missing parameter 'resource' or 'contentType'.");
156 } else {
157 throw new UnknownLanguageException(
158 "Unable to identify the Xtext language for resource " + emfURI + ".");
159 }
160 }
161 } else {
162 resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(emfURI, contentType);
163 if (resourceServiceProvider == null) {
164 throw new UnknownLanguageException(
165 "Unable to identify the Xtext language for contentType " + contentType + ".");
166 }
167 }
168 return resourceServiceProvider.get(Injector.class);
169 }
170
171 @Override
172 public void dispose() {
173 for (var subscription : subscriptions.values()) {
174 var document = subscription.get();
175 if (document != null) {
176 document.removePrecomputationListener(this);
177 }
178 }
179 }
180}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorKind.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorKind.java
new file mode 100644
index 00000000..f74bae74
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorKind.java
@@ -0,0 +1,11 @@
1package tools.refinery.language.web.xtext.server.message;
2
3import com.google.gson.annotations.SerializedName;
4
5public enum XtextWebErrorKind {
6 @SerializedName("request")
7 REQUEST_ERROR,
8
9 @SerializedName("server")
10 SERVER_ERROR,
11}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorResponse.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorResponse.java
new file mode 100644
index 00000000..01d78c31
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebErrorResponse.java
@@ -0,0 +1,79 @@
1package tools.refinery.language.web.xtext.server.message;
2
3import java.util.Objects;
4
5import com.google.gson.annotations.SerializedName;
6
7public final class XtextWebErrorResponse implements XtextWebResponse {
8 private String id;
9
10 @SerializedName("error")
11 private XtextWebErrorKind errorKind;
12
13 @SerializedName("message")
14 private String errorMessage;
15
16 public XtextWebErrorResponse(String id, XtextWebErrorKind errorKind, String errorMessage) {
17 super();
18 this.id = id;
19 this.errorKind = errorKind;
20 this.errorMessage = errorMessage;
21 }
22
23 public XtextWebErrorResponse(XtextWebRequest request, XtextWebErrorKind errorKind,
24 String errorMessage) {
25 this(request.getId(), errorKind, errorMessage);
26 }
27
28 public XtextWebErrorResponse(XtextWebRequest request, XtextWebErrorKind errorKind, Throwable t) {
29 this(request, errorKind, t.getMessage());
30 }
31
32 public String getId() {
33 return id;
34 }
35
36 public void setId(String id) {
37 this.id = id;
38 }
39
40 public XtextWebErrorKind getErrorKind() {
41 return errorKind;
42 }
43
44 public void setErrorKind(XtextWebErrorKind errorKind) {
45 this.errorKind = errorKind;
46 }
47
48 public String getErrorMessage() {
49 return errorMessage;
50 }
51
52 public void setErrorMessage(String errorMessage) {
53 this.errorMessage = errorMessage;
54 }
55
56 @Override
57 public int hashCode() {
58 return Objects.hash(errorKind, errorMessage, id);
59 }
60
61 @Override
62 public boolean equals(Object obj) {
63 if (this == obj)
64 return true;
65 if (obj == null)
66 return false;
67 if (getClass() != obj.getClass())
68 return false;
69 XtextWebErrorResponse other = (XtextWebErrorResponse) obj;
70 return errorKind == other.errorKind && Objects.equals(errorMessage, other.errorMessage)
71 && Objects.equals(id, other.id);
72 }
73
74 @Override
75 public String toString() {
76 return "XtextWebSocketErrorResponse [id=" + id + ", errorKind=" + errorKind + ", errorMessage=" + errorMessage
77 + "]";
78 }
79}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebOkResponse.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebOkResponse.java
new file mode 100644
index 00000000..8af27247
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebOkResponse.java
@@ -0,0 +1,72 @@
1package tools.refinery.language.web.xtext.server.message;
2
3import java.util.Objects;
4
5import org.eclipse.xtext.web.server.IServiceResult;
6import org.eclipse.xtext.web.server.IUnwrappableServiceResult;
7
8import com.google.gson.annotations.SerializedName;
9
10public final class XtextWebOkResponse implements XtextWebResponse {
11 private String id;
12
13 @SerializedName("response")
14 private Object responseData;
15
16 public XtextWebOkResponse(String id, Object responseData) {
17 super();
18 this.id = id;
19 this.responseData = responseData;
20 }
21
22 public XtextWebOkResponse(XtextWebRequest request, IServiceResult result) {
23 this(request.getId(), maybeUnwrap(result));
24 }
25
26 public String getId() {
27 return id;
28 }
29
30 public void setId(String id) {
31 this.id = id;
32 }
33
34 public Object getResponseData() {
35 return responseData;
36 }
37
38 public void setResponseData(Object responseData) {
39 this.responseData = responseData;
40 }
41
42 @Override
43 public int hashCode() {
44 return Objects.hash(id, responseData);
45 }
46
47 @Override
48 public boolean equals(Object obj) {
49 if (this == obj)
50 return true;
51 if (obj == null)
52 return false;
53 if (getClass() != obj.getClass())
54 return false;
55 XtextWebOkResponse other = (XtextWebOkResponse) obj;
56 return Objects.equals(id, other.id) && Objects.equals(responseData, other.responseData);
57 }
58
59 @Override
60 public String toString() {
61 return "XtextWebSocketOkResponse [id=" + id + ", responseData=" + responseData + "]";
62 }
63
64 private static Object maybeUnwrap(IServiceResult result) {
65 if (result instanceof IUnwrappableServiceResult unwrappableServiceResult
66 && unwrappableServiceResult.getContent() != null) {
67 return unwrappableServiceResult.getContent();
68 } else {
69 return result;
70 }
71 }
72}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebPushMessage.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebPushMessage.java
new file mode 100644
index 00000000..c9432e1c
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebPushMessage.java
@@ -0,0 +1,81 @@
1package tools.refinery.language.web.xtext.server.message;
2
3import java.util.Objects;
4
5import com.google.gson.annotations.SerializedName;
6
7public final class XtextWebPushMessage implements XtextWebResponse {
8 @SerializedName("resource")
9 private String resourceId;
10
11 private String stateId;
12
13 private String service;
14
15 @SerializedName("push")
16 private Object pushData;
17
18 public XtextWebPushMessage(String resourceId, String stateId, String service, Object pushData) {
19 super();
20 this.resourceId = resourceId;
21 this.stateId = stateId;
22 this.service = service;
23 this.pushData = pushData;
24 }
25
26 public String getResourceId() {
27 return resourceId;
28 }
29
30 public void setResourceId(String resourceId) {
31 this.resourceId = resourceId;
32 }
33
34 public String getStateId() {
35 return stateId;
36 }
37
38 public void setStateId(String stateId) {
39 this.stateId = stateId;
40 }
41
42 public String getService() {
43 return service;
44 }
45
46 public void setService(String service) {
47 this.service = service;
48 }
49
50 public Object getPushData() {
51 return pushData;
52 }
53
54 public void setPushData(Object pushData) {
55 this.pushData = pushData;
56 }
57
58 @Override
59 public int hashCode() {
60 return Objects.hash(pushData, resourceId, service, stateId);
61 }
62
63 @Override
64 public boolean equals(Object obj) {
65 if (this == obj)
66 return true;
67 if (obj == null)
68 return false;
69 if (getClass() != obj.getClass())
70 return false;
71 XtextWebPushMessage other = (XtextWebPushMessage) obj;
72 return Objects.equals(pushData, other.pushData) && Objects.equals(resourceId, other.resourceId)
73 && Objects.equals(service, other.service) && Objects.equals(stateId, other.stateId);
74 }
75
76 @Override
77 public String toString() {
78 return "XtextWebPushMessage [resourceId=" + resourceId + ", stateId=" + stateId + ", service=" + service
79 + ", pushData=" + pushData + "]";
80 }
81}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebRequest.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebRequest.java
new file mode 100644
index 00000000..959749f8
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebRequest.java
@@ -0,0 +1,57 @@
1package tools.refinery.language.web.xtext.server.message;
2
3import java.util.Map;
4import java.util.Objects;
5
6import com.google.gson.annotations.SerializedName;
7
8public class XtextWebRequest {
9 private String id;
10
11 @SerializedName("request")
12 private Map<String, String> requestData;
13
14 public XtextWebRequest(String id, Map<String, String> requestData) {
15 super();
16 this.id = id;
17 this.requestData = requestData;
18 }
19
20 public String getId() {
21 return id;
22 }
23
24 public void setId(String id) {
25 this.id = id;
26 }
27
28 public Map<String, String> getRequestData() {
29 return requestData;
30 }
31
32 public void setRequestData(Map<String, String> requestData) {
33 this.requestData = requestData;
34 }
35
36 @Override
37 public int hashCode() {
38 return Objects.hash(id, requestData);
39 }
40
41 @Override
42 public boolean equals(Object obj) {
43 if (this == obj)
44 return true;
45 if (obj == null)
46 return false;
47 if (getClass() != obj.getClass())
48 return false;
49 XtextWebRequest other = (XtextWebRequest) obj;
50 return Objects.equals(id, other.id) && Objects.equals(requestData, other.requestData);
51 }
52
53 @Override
54 public String toString() {
55 return "XtextWebSocketRequest [id=" + id + ", requestData=" + requestData + "]";
56 }
57}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebResponse.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebResponse.java
new file mode 100644
index 00000000..3bd13047
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/message/XtextWebResponse.java
@@ -0,0 +1,4 @@
1package tools.refinery.language.web.xtext.server.message;
2
3public sealed interface XtextWebResponse permits XtextWebOkResponse,XtextWebErrorResponse,XtextWebPushMessage {
4}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PrecomputationListener.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PrecomputationListener.java
new file mode 100644
index 00000000..79a284db
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PrecomputationListener.java
@@ -0,0 +1,15 @@
1package tools.refinery.language.web.xtext.server.push;
2
3import org.eclipse.xtext.web.server.IServiceResult;
4
5import tools.refinery.language.web.xtext.server.ResponseHandlerException;
6
7@FunctionalInterface
8public interface PrecomputationListener {
9 void onPrecomputedServiceResult(String resourceId, String stateId, String serviceName, IServiceResult serviceResult)
10 throws ResponseHandlerException;
11
12 default void onSubscribeToPrecomputationEvents(String resourceId, PushWebDocument document) {
13 // Nothing to handle by default.
14 }
15}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushServiceDispatcher.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushServiceDispatcher.java
new file mode 100644
index 00000000..c7b8108d
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushServiceDispatcher.java
@@ -0,0 +1,23 @@
1package tools.refinery.language.web.xtext.server.push;
2
3import org.eclipse.xtext.web.server.IServiceContext;
4import org.eclipse.xtext.web.server.XtextServiceDispatcher;
5import org.eclipse.xtext.web.server.model.XtextWebDocument;
6
7import com.google.inject.Singleton;
8
9import tools.refinery.language.web.xtext.server.SubscribingServiceContext;
10
11@Singleton
12public class PushServiceDispatcher extends XtextServiceDispatcher {
13
14 @Override
15 protected XtextWebDocument getFullTextDocument(String fullText, String resourceId, IServiceContext context) {
16 var document = super.getFullTextDocument(fullText, resourceId, context);
17 if (document instanceof PushWebDocument pushWebDocument
18 && context instanceof SubscribingServiceContext subscribingContext) {
19 pushWebDocument.addPrecomputationListener(subscribingContext.subscriber());
20 }
21 return document;
22 }
23}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocument.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocument.java
new file mode 100644
index 00000000..906b9e30
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocument.java
@@ -0,0 +1,89 @@
1package tools.refinery.language.web.xtext.server.push;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7
8import org.eclipse.xtext.util.CancelIndicator;
9import org.eclipse.xtext.web.server.IServiceResult;
10import org.eclipse.xtext.web.server.model.AbstractCachedService;
11import org.eclipse.xtext.web.server.model.DocumentSynchronizer;
12import org.eclipse.xtext.web.server.model.XtextWebDocument;
13import org.slf4j.Logger;
14import org.slf4j.LoggerFactory;
15
16import com.google.common.collect.ImmutableList;
17
18import tools.refinery.language.web.xtext.server.ResponseHandlerException;
19
20public class PushWebDocument extends XtextWebDocument {
21 private static final Logger LOG = LoggerFactory.getLogger(PushWebDocument.class);
22
23 private final List<PrecomputationListener> precomputationListeners = new ArrayList<>();
24
25 private final Map<Class<?>, IServiceResult> precomputedServices = new HashMap<>();
26
27 public PushWebDocument(String resourceId, DocumentSynchronizer synchronizer) {
28 super(resourceId, synchronizer);
29 if (resourceId == null) {
30 throw new IllegalArgumentException("resourceId must not be null");
31 }
32 }
33
34 public boolean addPrecomputationListener(PrecomputationListener listener) {
35 synchronized (precomputationListeners) {
36 if (precomputationListeners.contains(listener)) {
37 return false;
38 }
39 precomputationListeners.add(listener);
40 listener.onSubscribeToPrecomputationEvents(getResourceId(), this);
41 return true;
42 }
43 }
44
45 public boolean removePrecomputationListener(PrecomputationListener listener) {
46 synchronized (precomputationListeners) {
47 return precomputationListeners.remove(listener);
48 }
49 }
50
51 public <T extends IServiceResult> void precomputeServiceResult(AbstractCachedService<T> service, String serviceName,
52 CancelIndicator cancelIndicator, boolean logCacheMiss) {
53 var result = getCachedServiceResult(service, cancelIndicator, logCacheMiss);
54 if (result == null) {
55 LOG.error("{} service returned null result", serviceName);
56 return;
57 }
58 var serviceClass = service.getClass();
59 var previousResult = precomputedServices.get(serviceClass);
60 if (previousResult != null && previousResult.equals(result)) {
61 return;
62 }
63 precomputedServices.put(serviceClass, result);
64 notifyPrecomputationListeners(serviceName, result);
65 }
66
67 private <T extends IServiceResult> void notifyPrecomputationListeners(String serviceName, T result) {
68 var resourceId = getResourceId();
69 var stateId = getStateId();
70 List<PrecomputationListener> copyOfListeners;
71 synchronized (precomputationListeners) {
72 copyOfListeners = ImmutableList.copyOf(precomputationListeners);
73 }
74 var toRemove = new ArrayList<PrecomputationListener>();
75 for (var listener : copyOfListeners) {
76 try {
77 listener.onPrecomputedServiceResult(resourceId, stateId, serviceName, result);
78 } catch (ResponseHandlerException e) {
79 LOG.error("Delivering precomputation push message failed", e);
80 toRemove.add(listener);
81 }
82 }
83 if (!toRemove.isEmpty()) {
84 synchronized (precomputationListeners) {
85 precomputationListeners.removeAll(toRemove);
86 }
87 }
88 }
89}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentAccess.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentAccess.java
new file mode 100644
index 00000000..b3666a86
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentAccess.java
@@ -0,0 +1,68 @@
1package tools.refinery.language.web.xtext.server.push;
2
3import org.eclipse.xtext.service.OperationCanceledManager;
4import org.eclipse.xtext.util.CancelIndicator;
5import org.eclipse.xtext.util.concurrent.CancelableUnitOfWork;
6import org.eclipse.xtext.web.server.IServiceResult;
7import org.eclipse.xtext.web.server.model.AbstractCachedService;
8import org.eclipse.xtext.web.server.model.IXtextWebDocument;
9import org.eclipse.xtext.web.server.model.PrecomputedServiceRegistry;
10import org.eclipse.xtext.web.server.model.XtextWebDocument;
11import org.eclipse.xtext.web.server.model.XtextWebDocumentAccess;
12import org.eclipse.xtext.web.server.syntaxcoloring.HighlightingService;
13import org.eclipse.xtext.web.server.validation.ValidationService;
14
15import com.google.inject.Inject;
16
17public class PushWebDocumentAccess extends XtextWebDocumentAccess {
18
19 @Inject
20 private PrecomputedServiceRegistry preComputedServiceRegistry;
21
22 @Inject
23 private OperationCanceledManager operationCanceledManager;
24
25 private PushWebDocument pushDocument;
26
27 @Override
28 protected void init(XtextWebDocument document, String requiredStateId, boolean skipAsyncWork) {
29 super.init(document, requiredStateId, skipAsyncWork);
30 if (document instanceof PushWebDocument newPushDocument) {
31 pushDocument = newPushDocument;
32 }
33 }
34
35 @Override
36 protected void performPrecomputation(CancelIndicator cancelIndicator) {
37 if (pushDocument == null) {
38 super.performPrecomputation(cancelIndicator);
39 return;
40 }
41 for (AbstractCachedService<? extends IServiceResult> service : preComputedServiceRegistry
42 .getPrecomputedServices()) {
43 operationCanceledManager.checkCanceled(cancelIndicator);
44 precomputeServiceResult(service, false);
45 }
46 }
47
48 protected <T extends IServiceResult> void precomputeServiceResult(AbstractCachedService<T> service, boolean logCacheMiss) {
49 var serviceName = getPrecomputedServiceName(service);
50 readOnly(new CancelableUnitOfWork<Void, IXtextWebDocument>() {
51 @Override
52 public java.lang.Void exec(IXtextWebDocument d, CancelIndicator cancelIndicator) throws Exception {
53 pushDocument.precomputeServiceResult(service, serviceName, cancelIndicator, logCacheMiss);
54 return null;
55 }
56 });
57 }
58
59 protected String getPrecomputedServiceName(AbstractCachedService<? extends IServiceResult> service) {
60 if (service instanceof ValidationService) {
61 return "validate";
62 }
63 if (service instanceof HighlightingService) {
64 return "highlight";
65 }
66 throw new IllegalArgumentException("Unknown precomputed service: " + service);
67 }
68}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentProvider.java b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentProvider.java
new file mode 100644
index 00000000..fc45f74a
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/server/push/PushWebDocumentProvider.java
@@ -0,0 +1,33 @@
1package tools.refinery.language.web.xtext.server.push;
2
3import org.eclipse.xtext.web.server.IServiceContext;
4import org.eclipse.xtext.web.server.model.DocumentSynchronizer;
5import org.eclipse.xtext.web.server.model.IWebDocumentProvider;
6import org.eclipse.xtext.web.server.model.XtextWebDocument;
7
8import com.google.inject.Inject;
9import com.google.inject.Provider;
10import com.google.inject.Singleton;
11
12/**
13 * Based on
14 * {@link org.eclipse.xtext.web.server.model.IWebDocumentProvider.DefaultImpl}.
15 *
16 * @author Kristóf Marussy
17 */
18@Singleton
19public class PushWebDocumentProvider implements IWebDocumentProvider {
20 @Inject
21 private Provider<DocumentSynchronizer> synchronizerProvider;
22
23 @Override
24 public XtextWebDocument get(String resourceId, IServiceContext serviceContext) {
25 if (resourceId == null) {
26 return new XtextWebDocument(resourceId, synchronizerProvider.get());
27 } else {
28 // We only need to send push messages if a resourceId is specified.
29 return new PushWebDocument(resourceId,
30 serviceContext.getSession().get(DocumentSynchronizer.class, () -> this.synchronizerProvider.get()));
31 }
32 }
33}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleServiceContext.java b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleServiceContext.java
new file mode 100644
index 00000000..43e37160
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleServiceContext.java
@@ -0,0 +1,26 @@
1package tools.refinery.language.web.xtext.servlet;
2
3import java.util.Map;
4import java.util.Set;
5
6import org.eclipse.xtext.web.server.IServiceContext;
7import org.eclipse.xtext.web.server.ISession;
8
9import com.google.common.collect.ImmutableSet;
10
11public record SimpleServiceContext(ISession session, Map<String, String> parameters) implements IServiceContext {
12 @Override
13 public Set<String> getParameterKeys() {
14 return ImmutableSet.copyOf(parameters.keySet());
15 }
16
17 @Override
18 public String getParameter(String key) {
19 return parameters.get(key);
20 }
21
22 @Override
23 public ISession getSession() {
24 return session;
25 }
26}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleSession.java b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleSession.java
new file mode 100644
index 00000000..09c055a2
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/SimpleSession.java
@@ -0,0 +1,35 @@
1package tools.refinery.language.web.xtext.servlet;
2
3import java.util.HashMap;
4import java.util.Map;
5
6import org.eclipse.xtext.web.server.ISession;
7import org.eclipse.xtext.xbase.lib.Functions.Function0;
8
9public class SimpleSession implements ISession {
10 private Map<Object, Object> map = new HashMap<>();
11
12 @Override
13 public <T> T get(Object key) {
14 @SuppressWarnings("unchecked")
15 var value = (T) map.get(key);
16 return value;
17 }
18
19 @Override
20 public <T> T get(Object key, Function0<? extends T> factory) {
21 @SuppressWarnings("unchecked")
22 var value = (T) map.computeIfAbsent(key, absentKey -> factory.apply());
23 return value;
24 }
25
26 @Override
27 public void put(Object key, Object value) {
28 map.put(key, value);
29 }
30
31 @Override
32 public void remove(Object key) {
33 map.remove(key);
34 }
35}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextStatusCode.java b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextStatusCode.java
new file mode 100644
index 00000000..0cd229e8
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextStatusCode.java
@@ -0,0 +1,9 @@
1package tools.refinery.language.web.xtext.servlet;
2
3public final class XtextStatusCode {
4 public static final int INVALID_JSON = 4007;
5
6 private XtextStatusCode() {
7 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
8 }
9}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
new file mode 100644
index 00000000..fd41f213
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
@@ -0,0 +1,133 @@
1package tools.refinery.language.web.xtext.servlet;
2
3import java.io.IOException;
4import java.io.Reader;
5
6import org.eclipse.jetty.websocket.api.Session;
7import org.eclipse.jetty.websocket.api.StatusCode;
8import org.eclipse.jetty.websocket.api.WriteCallback;
9import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
10import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
11import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
12import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
13import org.eclipse.jetty.websocket.api.annotations.WebSocket;
14import org.eclipse.xtext.resource.IResourceServiceProvider;
15import org.eclipse.xtext.web.server.ISession;
16import org.slf4j.Logger;
17import org.slf4j.LoggerFactory;
18
19import com.google.gson.Gson;
20import com.google.gson.JsonIOException;
21import com.google.gson.JsonParseException;
22
23import tools.refinery.language.web.xtext.server.ResponseHandler;
24import tools.refinery.language.web.xtext.server.ResponseHandlerException;
25import tools.refinery.language.web.xtext.server.TransactionExecutor;
26import tools.refinery.language.web.xtext.server.message.XtextWebRequest;
27import tools.refinery.language.web.xtext.server.message.XtextWebResponse;
28
29@WebSocket
30public class XtextWebSocket implements WriteCallback, ResponseHandler {
31 private static final Logger LOG = LoggerFactory.getLogger(XtextWebSocket.class);
32
33 private final Gson gson = new Gson();
34
35 private final TransactionExecutor executor;
36
37 private Session webSocketSession;
38
39 public XtextWebSocket(TransactionExecutor executor) {
40 this.executor = executor;
41 executor.setResponseHandler(this);
42 }
43
44 public XtextWebSocket(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) {
45 this(new TransactionExecutor(session, resourceServiceProviderRegistry));
46 }
47
48 @OnWebSocketConnect
49 public void onConnect(Session webSocketSession) {
50 if (this.webSocketSession != null) {
51 LOG.error("Websocket session onConnect when already connected");
52 return;
53 }
54 LOG.debug("New websocket connection from {}", webSocketSession.getRemoteAddress());
55 this.webSocketSession = webSocketSession;
56 }
57
58 @OnWebSocketClose
59 public void onClose(int statusCode, String reason) {
60 executor.dispose();
61 if (webSocketSession == null) {
62 return;
63 }
64 if (statusCode == StatusCode.NORMAL || statusCode == StatusCode.SHUTDOWN) {
65 LOG.debug("{} closed connection normally: {}", webSocketSession.getRemoteAddress(), reason);
66 } else {
67 LOG.warn("{} closed connection with status code {}: {}", webSocketSession.getRemoteAddress(), statusCode,
68 reason);
69 }
70 webSocketSession = null;
71 }
72
73 @OnWebSocketError
74 public void onError(Throwable error) {
75 if (webSocketSession == null) {
76 return;
77 }
78 LOG.error("Internal websocket error in connection from" + webSocketSession.getRemoteAddress(), error);
79 }
80
81 @OnWebSocketMessage
82 public void onMessage(Reader reader) {
83 if (webSocketSession == null) {
84 LOG.error("Trying to receive message when websocket is disconnected");
85 return;
86 }
87 XtextWebRequest request;
88 try {
89 request = gson.fromJson(reader, XtextWebRequest.class);
90 } catch (JsonIOException e) {
91 LOG.error("Cannot read from websocket from" + webSocketSession.getRemoteAddress(), e);
92 if (webSocketSession.isOpen()) {
93 webSocketSession.close(StatusCode.SERVER_ERROR, "Cannot read payload");
94 }
95 return;
96 } catch (JsonParseException e) {
97 LOG.warn("Malformed websocket request from" + webSocketSession.getRemoteAddress(), e);
98 webSocketSession.close(XtextStatusCode.INVALID_JSON, "Invalid JSON payload");
99 return;
100 }
101 try {
102 executor.handleRequest(request);
103 } catch (ResponseHandlerException e) {
104 LOG.warn("Cannot write websocket response", e);
105 if (webSocketSession.isOpen()) {
106 webSocketSession.close(StatusCode.SERVER_ERROR, "Cannot write response");
107 }
108 }
109 }
110
111 @Override
112 public void onResponse(XtextWebResponse response) throws ResponseHandlerException {
113 if (webSocketSession == null) {
114 throw new ResponseHandlerException("Trying to send message when websocket is disconnected");
115 }
116 var responseString = gson.toJson(response);
117 try {
118 webSocketSession.getRemote().sendPartialString(responseString, true, this);
119 } catch (IOException e) {
120 throw new ResponseHandlerException(
121 "Cannot initiaite async write to websocket " + webSocketSession.getRemoteAddress(), e);
122 }
123 }
124
125 @Override
126 public void writeFailed(Throwable x) {
127 if (webSocketSession == null) {
128 LOG.error("Cannot complete async write to disconnected websocket", x);
129 return;
130 }
131 LOG.warn("Cannot complete async write to websocket " + webSocketSession.getRemoteAddress(), x);
132 }
133}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java
new file mode 100644
index 00000000..942ca380
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java
@@ -0,0 +1,83 @@
1package tools.refinery.language.web.xtext.servlet;
2
3import java.io.IOException;
4import java.time.Duration;
5import java.util.Set;
6
7import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest;
8import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse;
9import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
10import org.eclipse.jetty.websocket.server.JettyWebSocketServlet;
11import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
12import org.eclipse.xtext.resource.IResourceServiceProvider;
13import org.slf4j.Logger;
14import org.slf4j.LoggerFactory;
15
16import jakarta.servlet.ServletConfig;
17import jakarta.servlet.ServletException;
18
19public abstract class XtextWebSocketServlet extends JettyWebSocketServlet implements JettyWebSocketCreator {
20
21 private static final long serialVersionUID = -3772740838165122685L;
22
23 public static final String ALLOWED_ORIGINS_SEPARATOR = ";";
24
25 public static final String ALLOWED_ORIGINS_INIT_PARAM = "tools.refinery.language.web.xtext.XtextWebSocketServlet.allowedOrigin";
26
27 public static final String XTEXT_SUBPROTOCOL_V1 = "tools.refinery.language.web.xtext.v1";
28
29 /**
30 * Maximum message size should be large enough to upload a full model file.
31 */
32 private static final long MAX_FRAME_SIZE = 4L * 1024L * 1024L;
33
34 private static final Duration IDLE_TIMEOUT = Duration.ofSeconds(30);
35
36 private transient Logger log = LoggerFactory.getLogger(getClass());
37
38 private transient Set<String> allowedOrigins = null;
39
40 @Override
41 public void init(ServletConfig config) throws ServletException {
42 var allowedOriginsStr = config.getInitParameter(ALLOWED_ORIGINS_INIT_PARAM);
43 if (allowedOriginsStr == null) {
44 log.warn("All WebSocket origins are allowed! This setting should not be used in production!");
45 } else {
46 allowedOrigins = Set.of(allowedOriginsStr.split(ALLOWED_ORIGINS_SEPARATOR));
47 log.info("Allowed origins: {}", allowedOrigins);
48 }
49 super.init(config);
50 }
51
52 @Override
53 protected void configure(JettyWebSocketServletFactory factory) {
54 factory.setMaxFrameSize(MAX_FRAME_SIZE);
55 factory.setIdleTimeout(IDLE_TIMEOUT);
56 factory.addMapping("/", this);
57 }
58
59 @Override
60 public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) {
61 if (allowedOrigins != null) {
62 var origin = req.getOrigin();
63 if (origin == null || !allowedOrigins.contains(origin.toLowerCase())) {
64 log.error("Connection from {} from forbidden origin {}", req.getRemoteSocketAddress(), origin);
65 try {
66 resp.sendForbidden("Origin not allowed");
67 } catch (IOException e) {
68 log.error("Cannot send forbidden origin error", e);
69 }
70 return null;
71 }
72 }
73 if (req.getSubProtocols().contains(XTEXT_SUBPROTOCOL_V1)) {
74 resp.setAcceptedSubProtocol(XTEXT_SUBPROTOCOL_V1);
75 } else {
76 log.error("None of the subprotocols {} offered by {} are supported", req.getSubProtocols(),
77 req.getRemoteSocketAddress());
78 resp.setAcceptedSubProtocol(null);
79 }
80 var session = new SimpleSession();
81 return new XtextWebSocket(session, IResourceServiceProvider.Registry.INSTANCE);
82 }
83}
diff --git a/language-web/src/main/js/App.tsx b/language-web/src/main/js/App.tsx
index d25ac4d3..2567aa9c 100644
--- a/language-web/src/main/js/App.tsx
+++ b/language-web/src/main/js/App.tsx
@@ -1,15 +1,14 @@
1import AppBar from '@mui/material/AppBar'; 1import AppBar from '@mui/material/AppBar';
2import Box from '@mui/material/Box'; 2import Box from '@mui/material/Box';
3import Button from '@mui/material/Button';
4import IconButton from '@mui/material/IconButton'; 3import IconButton from '@mui/material/IconButton';
5import Toolbar from '@mui/material/Toolbar'; 4import Toolbar from '@mui/material/Toolbar';
6import Typography from '@mui/material/Typography'; 5import Typography from '@mui/material/Typography';
7import MenuIcon from '@mui/icons-material/Menu'; 6import MenuIcon from '@mui/icons-material/Menu';
8import PlayArrowIcon from '@mui/icons-material/PlayArrow';
9import React from 'react'; 7import React from 'react';
10 8
11import { EditorArea } from './editor/EditorArea'; 9import { EditorArea } from './editor/EditorArea';
12import { EditorButtons } from './editor/EditorButtons'; 10import { EditorButtons } from './editor/EditorButtons';
11import { GenerateButton } from './editor/GenerateButton';
13 12
14export const App = (): JSX.Element => ( 13export const App = (): JSX.Element => (
15 <Box 14 <Box
@@ -46,13 +45,7 @@ export const App = (): JSX.Element => (
46 p={1} 45 p={1}
47 > 46 >
48 <EditorButtons /> 47 <EditorButtons />
49 <Button 48 <GenerateButton />
50 variant="outlined"
51 color="primary"
52 startIcon={<PlayArrowIcon />}
53 >
54 Generate
55 </Button>
56 </Box> 49 </Box>
57 <Box 50 <Box
58 flexGrow={1} 51 flexGrow={1}
diff --git a/language-web/src/main/js/RootStore.tsx b/language-web/src/main/js/RootStore.tsx
index 88b8a445..96e1b26a 100644
--- a/language-web/src/main/js/RootStore.tsx
+++ b/language-web/src/main/js/RootStore.tsx
@@ -8,9 +8,9 @@ export class RootStore {
8 8
9 themeStore; 9 themeStore;
10 10
11 constructor() { 11 constructor(initialValue: string) {
12 this.themeStore = new ThemeStore(); 12 this.themeStore = new ThemeStore();
13 this.editorStore = new EditorStore(this.themeStore); 13 this.editorStore = new EditorStore(initialValue, this.themeStore);
14 } 14 }
15} 15}
16 16
diff --git a/language-web/src/main/js/editor/EditorArea.tsx b/language-web/src/main/js/editor/EditorArea.tsx
index 531a57c9..678a632d 100644
--- a/language-web/src/main/js/editor/EditorArea.tsx
+++ b/language-web/src/main/js/editor/EditorArea.tsx
@@ -1,41 +1,151 @@
1import { Command, EditorView } from '@codemirror/view';
2import { closeSearchPanel, openSearchPanel } from '@codemirror/search';
3import { closeLintPanel, openLintPanel } from '@codemirror/lint';
1import { observer } from 'mobx-react-lite'; 4import { observer } from 'mobx-react-lite';
2import React, { useRef } from 'react'; 5import React, {
6 useCallback,
7 useEffect,
8 useRef,
9 useState,
10} from 'react';
3 11
12import { EditorParent } from './EditorParent';
4import { useRootStore } from '../RootStore'; 13import { useRootStore } from '../RootStore';
14import { getLogger } from '../utils/logger';
15
16const log = getLogger('editor.EditorArea');
17
18function usePanel(
19 panelId: string,
20 stateToSet: boolean,
21 editorView: EditorView | null,
22 openCommand: Command,
23 closeCommand: Command,
24 closeCallback: () => void,
25) {
26 const [cachedViewState, setCachedViewState] = useState<boolean>(false);
27 useEffect(() => {
28 if (editorView === null || cachedViewState === stateToSet) {
29 return;
30 }
31 if (stateToSet) {
32 openCommand(editorView);
33 const buttonQuery = `.cm-${panelId}.cm-panel button[name="close"]`;
34 const closeButton = editorView.dom.querySelector(buttonQuery);
35 if (closeButton) {
36 log.debug('Addig close button callback to', panelId, 'panel');
37 // We must remove the event listener added by CodeMirror from the button
38 // that dispatches a transaction without going through `EditorStorre`.
39 // Cloning a DOM node removes event listeners,
40 // see https://stackoverflow.com/a/9251864
41 const closeButtonWithoutListeners = closeButton.cloneNode(true);
42 closeButtonWithoutListeners.addEventListener('click', (event) => {
43 closeCallback();
44 event.preventDefault();
45 });
46 closeButton.replaceWith(closeButtonWithoutListeners);
47 } else {
48 log.error('Opened', panelId, 'panel has no close button');
49 }
50 } else {
51 closeCommand(editorView);
52 }
53 setCachedViewState(stateToSet);
54 }, [
55 stateToSet,
56 editorView,
57 cachedViewState,
58 panelId,
59 openCommand,
60 closeCommand,
61 closeCallback,
62 ]);
63 return setCachedViewState;
64}
65
66function fixCodeMirrorAccessibility(editorView: EditorView) {
67 // Reported by Lighthouse 8.3.0.
68 const { contentDOM } = editorView;
69 contentDOM.removeAttribute('aria-expanded');
70 contentDOM.setAttribute('aria-label', 'Code editor');
71}
5 72
6export const EditorArea = observer(() => { 73export const EditorArea = observer(() => {
7 const { editorStore } = useRootStore(); 74 const { editorStore } = useRootStore();
8 const { CodeMirror } = editorStore.chunk || {}; 75 const editorParentRef = useRef<HTMLDivElement | null>(null);
9 const fallbackTextarea = useRef<HTMLTextAreaElement>(null); 76 const [editorViewState, setEditorViewState] = useState<EditorView | null>(null);
10 77
11 if (!CodeMirror) { 78 const setSearchPanelOpen = usePanel(
12 return ( 79 'search',
13 <textarea 80 editorStore.showSearchPanel,
14 value={editorStore.value} 81 editorViewState,
15 onChange={(e) => editorStore.updateValue(e.target.value)} 82 openSearchPanel,
16 ref={fallbackTextarea} 83 closeSearchPanel,
17 className={`problem-fallback-editor cm-s-${editorStore.codeMirrorTheme}`} 84 useCallback(() => editorStore.setSearchPanelOpen(false), [editorStore]),
18 /> 85 );
19 ); 86
20 } 87 const setLintPanelOpen = usePanel(
21 88 'panel-lint',
22 const textarea = fallbackTextarea.current; 89 editorStore.showLintPanel,
23 if (textarea) { 90 editorViewState,
24 editorStore.setInitialSelection( 91 openLintPanel,
25 textarea.selectionStart, 92 closeLintPanel,
26 textarea.selectionEnd, 93 useCallback(() => editorStore.setLintPanelOpen(false), [editorStore]),
27 document.activeElement === textarea, 94 );
28 ); 95
29 } 96 useEffect(() => {
97 if (editorParentRef.current === null) {
98 // Nothing to clean up.
99 return () => {};
100 }
101
102 const editorView = new EditorView({
103 state: editorStore.state,
104 parent: editorParentRef.current,
105 dispatch: (transaction) => {
106 editorStore.onTransaction(transaction);
107 editorView.update([transaction]);
108 if (editorView.state !== editorStore.state) {
109 log.error(
110 'Failed to synchronize editor state - store state:',
111 editorStore.state,
112 'view state:',
113 editorView.state,
114 );
115 }
116 },
117 });
118 fixCodeMirrorAccessibility(editorView);
119 setEditorViewState(editorView);
120 setSearchPanelOpen(false);
121 setLintPanelOpen(false);
122 // `dispatch` is bound to the view instance,
123 // so it does not have to be called as a method.
124 // eslint-disable-next-line @typescript-eslint/unbound-method
125 editorStore.updateDispatcher(editorView.dispatch);
126 log.info('Editor created');
127
128 return () => {
129 editorStore.updateDispatcher(null);
130 editorView.destroy();
131 log.info('Editor destroyed');
132 };
133 }, [
134 editorParentRef,
135 editorStore,
136 setSearchPanelOpen,
137 setLintPanelOpen,
138 ]);
30 139
31 return ( 140 return (
32 <CodeMirror 141 <EditorParent
33 value={editorStore.value} 142 className="dark"
34 options={editorStore.codeMirrorOptions} 143 sx={{
35 editorDidMount={(editor) => editorStore.editorDidMount(editor)} 144 '.cm-lineNumbers': editorStore.showLineNumbers ? {} : {
36 editorWillUnmount={() => editorStore.editorWillUnmount()} 145 display: 'none !important',
37 onBeforeChange={(_editor, _data, value) => editorStore.updateValue(value)} 146 },
38 onChange={() => editorStore.reportChanged()} 147 }}
148 ref={editorParentRef}
39 /> 149 />
40 ); 150 );
41}); 151});
diff --git a/language-web/src/main/js/editor/EditorButtons.tsx b/language-web/src/main/js/editor/EditorButtons.tsx
index 56577e82..09ce33dd 100644
--- a/language-web/src/main/js/editor/EditorButtons.tsx
+++ b/language-web/src/main/js/editor/EditorButtons.tsx
@@ -1,14 +1,36 @@
1import type { Diagnostic } from '@codemirror/lint';
1import { observer } from 'mobx-react-lite'; 2import { observer } from 'mobx-react-lite';
3import IconButton from '@mui/material/IconButton';
2import Stack from '@mui/material/Stack'; 4import Stack from '@mui/material/Stack';
3import ToggleButton from '@mui/material/ToggleButton'; 5import ToggleButton from '@mui/material/ToggleButton';
4import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; 6import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
7import CheckIcon from '@mui/icons-material/Check';
8import ErrorIcon from '@mui/icons-material/Error';
5import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; 9import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered';
10import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
6import RedoIcon from '@mui/icons-material/Redo'; 11import RedoIcon from '@mui/icons-material/Redo';
12import SearchIcon from '@mui/icons-material/Search';
7import UndoIcon from '@mui/icons-material/Undo'; 13import UndoIcon from '@mui/icons-material/Undo';
14import WarningIcon from '@mui/icons-material/Warning';
8import React from 'react'; 15import React from 'react';
9 16
10import { useRootStore } from '../RootStore'; 17import { useRootStore } from '../RootStore';
11 18
19// Exhastive switch as proven by TypeScript.
20// eslint-disable-next-line consistent-return
21function getLintIcon(severity: Diagnostic['severity'] | null) {
22 switch (severity) {
23 case 'error':
24 return <ErrorIcon fontSize="small" />;
25 case 'warning':
26 return <WarningIcon fontSize="small" />;
27 case 'info':
28 return <InfoOutlinedIcon fontSize="small" />;
29 case null:
30 return <CheckIcon fontSize="small" />;
31 }
32}
33
12export const EditorButtons = observer(() => { 34export const EditorButtons = observer(() => {
13 const { editorStore } = useRootStore(); 35 const { editorStore } = useRootStore();
14 36
@@ -17,35 +39,55 @@ export const EditorButtons = observer(() => {
17 direction="row" 39 direction="row"
18 spacing={1} 40 spacing={1}
19 > 41 >
20 <ToggleButtonGroup 42 <Stack
21 size="small" 43 direction="row"
44 alignItems="center"
22 > 45 >
23 <ToggleButton 46 <IconButton
24 disabled={!editorStore.canUndo} 47 disabled={!editorStore.canUndo}
25 onClick={() => editorStore.undo()} 48 onClick={() => editorStore.undo()}
26 aria-label="Undo" 49 aria-label="Undo"
27 value="undo" 50 value="undo"
28 > 51 >
29 <UndoIcon fontSize="small" /> 52 <UndoIcon fontSize="small" />
30 </ToggleButton> 53 </IconButton>
31 <ToggleButton 54 <IconButton
32 disabled={!editorStore.canRedo} 55 disabled={!editorStore.canRedo}
33 onClick={() => editorStore.redo()} 56 onClick={() => editorStore.redo()}
34 aria-label="Redo" 57 aria-label="Redo"
35 value="redo" 58 value="redo"
36 > 59 >
37 <RedoIcon fontSize="small" /> 60 <RedoIcon fontSize="small" />
38 </ToggleButton> 61 </IconButton>
39 </ToggleButtonGroup> 62 </Stack>
40 <ToggleButton 63 <ToggleButtonGroup
41 selected={editorStore.showLineNumbers}
42 onChange={() => editorStore.toggleLineNumbers()}
43 size="small" 64 size="small"
44 aria-label="Show line numbers"
45 value="show-line-numbers"
46 > 65 >
47 <FormatListNumberedIcon fontSize="small" /> 66 <ToggleButton
48 </ToggleButton> 67 selected={editorStore.showLineNumbers}
68 onClick={() => editorStore.toggleLineNumbers()}
69 aria-label="Show line numbers"
70 value="show-line-numbers"
71 >
72 <FormatListNumberedIcon fontSize="small" />
73 </ToggleButton>
74 <ToggleButton
75 selected={editorStore.showSearchPanel}
76 onClick={() => editorStore.toggleSearchPanel()}
77 aria-label="Show find/replace"
78 value="show-search-panel"
79 >
80 <SearchIcon fontSize="small" />
81 </ToggleButton>
82 <ToggleButton
83 selected={editorStore.showLintPanel}
84 onClick={() => editorStore.toggleLintPanel()}
85 aria-label="Show diagnostics panel"
86 value="show-lint-panel"
87 >
88 {getLintIcon(editorStore.highestDiagnosticLevel)}
89 </ToggleButton>
90 </ToggleButtonGroup>
49 </Stack> 91 </Stack>
50 ); 92 );
51}); 93});
diff --git a/language-web/src/main/js/editor/EditorParent.ts b/language-web/src/main/js/editor/EditorParent.ts
new file mode 100644
index 00000000..ee1323f6
--- /dev/null
+++ b/language-web/src/main/js/editor/EditorParent.ts
@@ -0,0 +1,200 @@
1import { styled } from '@mui/material/styles';
2
3/**
4 * Returns a squiggly underline background image encoded as a CSS `url()` data URI with Base64.
5 *
6 * Based on
7 * https://github.com/codemirror/lint/blob/f524b4a53b0183bb343ac1e32b228d28030d17af/src/lint.ts#L501
8 *
9 * @param color the color of the underline
10 * @returns the CSS `url()`
11 */
12function underline(color: string) {
13 const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="6" height="3">
14 <path d="m0 3 l2 -2 l1 0 l2 2 l1 0" stroke="${color}" fill="none" stroke-width=".7"/>
15 </svg>`;
16 const svgBase64 = window.btoa(svg);
17 return `url('data:image/svg+xml;base64,${svgBase64}')`;
18}
19
20export const EditorParent = styled('div')(({ theme }) => {
21 const codeMirrorLintStyle: Record<string, unknown> = {};
22 (['error', 'warning', 'info'] as const).forEach((severity) => {
23 const color = theme.palette[severity].main;
24 codeMirrorLintStyle[`.cm-diagnostic-${severity}`] = {
25 borderLeftColor: color,
26 };
27 codeMirrorLintStyle[`.cm-lintRange-${severity}`] = {
28 backgroundImage: underline(color),
29 };
30 });
31
32 return {
33 background: theme.palette.background.default,
34 '&, .cm-editor': {
35 height: '100%',
36 },
37 '.cm-scroller, .cm-tooltip-autocomplete, .cm-completionLabel, .cm-completionDetail': {
38 fontSize: 16,
39 fontFamily: '"JetBrains MonoVariable", "JetBrains Mono", monospace',
40 fontFeatureSettings: '"liga", "calt"',
41 fontWeight: 400,
42 letterSpacing: 0,
43 textRendering: 'optimizeLegibility',
44 },
45 '.cm-scroller': {
46 color: theme.palette.text.secondary,
47 },
48 '.cm-gutters': {
49 background: theme.palette.background.default,
50 color: theme.palette.text.disabled,
51 border: 'none',
52 },
53 '.cm-specialChar': {
54 color: theme.palette.secondary.main,
55 },
56 '.cm-activeLine': {
57 background: 'rgba(0, 0, 0, 0.3)',
58 },
59 '.cm-activeLineGutter': {
60 background: 'rgba(0, 0, 0, 0.3)',
61 color: theme.palette.text.primary,
62 },
63 '.cm-cursor, .cm-cursor-primary': {
64 borderColor: theme.palette.primary.main,
65 background: theme.palette.common.black,
66 },
67 '.cm-selectionBackground': {
68 background: '#3e4453',
69 },
70 '.cm-focused': {
71 outline: 'none',
72 '.cm-selectionBackground': {
73 background: '#3e4453',
74 },
75 },
76 '.cm-panels-top': {
77 color: theme.palette.text.secondary,
78 },
79 '.cm-panel': {
80 '&, & button, & input': {
81 fontFamily: '"Roboto","Helvetica","Arial",sans-serif',
82 },
83 background: theme.palette.background.paper,
84 borderTop: `1px solid ${theme.palette.divider}`,
85 'button[name="close"]': {
86 background: 'transparent',
87 color: theme.palette.text.secondary,
88 cursor: 'pointer',
89 },
90 },
91 '.cm-panel.cm-panel-lint': {
92 'button[name="close"]': {
93 // Close button interferes with scrollbar, so we better hide it.
94 // The panel can still be closed from the toolbar.
95 display: 'none',
96 },
97 ul: {
98 li: {
99 borderBottom: `1px solid ${theme.palette.divider}`,
100 cursor: 'pointer',
101 },
102 '[aria-selected]': {
103 background: '#3e4453',
104 color: theme.palette.text.primary,
105 },
106 '&:focus [aria-selected]': {
107 background: theme.palette.primary.main,
108 color: theme.palette.primary.contrastText,
109 },
110 },
111 },
112 '.cm-foldPlaceholder': {
113 background: theme.palette.background.paper,
114 borderColor: theme.palette.text.disabled,
115 color: theme.palette.text.secondary,
116 },
117 '.cmt-comment': {
118 fontStyle: 'italic',
119 color: theme.palette.text.disabled,
120 },
121 '.cmt-number': {
122 color: '#6188a6',
123 },
124 '.cmt-string': {
125 color: theme.palette.secondary.dark,
126 },
127 '.cmt-keyword': {
128 color: theme.palette.primary.main,
129 },
130 '.cmt-typeName, .cmt-macroName, .cmt-atom': {
131 color: theme.palette.text.primary,
132 },
133 '.cmt-variableName': {
134 color: '#c8ae9d',
135 },
136 '.cmt-problem-node': {
137 '&, & .cmt-variableName': {
138 color: theme.palette.text.secondary,
139 },
140 },
141 '.cmt-problem-unique': {
142 '&, & .cmt-variableName': {
143 color: theme.palette.text.primary,
144 },
145 },
146 '.cmt-problem-abstract, .cmt-problem-new': {
147 fontStyle: 'italic',
148 },
149 '.cmt-problem-containment': {
150 fontWeight: 700,
151 },
152 '.cmt-problem-error': {
153 '&, & .cmt-typeName': {
154 color: theme.palette.error.main,
155 },
156 },
157 '.cmt-problem-builtin': {
158 '&, & .cmt-typeName, & .cmt-atom, & .cmt-variableName': {
159 color: theme.palette.primary.main,
160 fontWeight: 400,
161 fontStyle: 'normal',
162 },
163 },
164 '.cm-tooltip-autocomplete': {
165 background: theme.palette.background.paper,
166 boxShadow: `0px 2px 4px -1px rgb(0 0 0 / 20%),
167 0px 4px 5px 0px rgb(0 0 0 / 14%),
168 0px 1px 10px 0px rgb(0 0 0 / 12%)`,
169 '.cm-completionIcon': {
170 color: theme.palette.text.secondary,
171 },
172 '.cm-completionLabel': {
173 color: theme.palette.text.primary,
174 },
175 '.cm-completionDetail': {
176 color: theme.palette.text.secondary,
177 fontStyle: 'normal',
178 },
179 '[aria-selected]': {
180 background: `${theme.palette.primary.main} !important`,
181 '.cm-completionIcon, .cm-completionLabel, .cm-completionDetail': {
182 color: theme.palette.primary.contrastText,
183 },
184 },
185 },
186 '.cm-completionIcon': {
187 width: 16,
188 padding: 0,
189 marginRight: '0.5em',
190 textAlign: 'center',
191 },
192 ...codeMirrorLintStyle,
193 '.cm-problem-write': {
194 background: 'rgba(255, 255, 128, 0.3)',
195 },
196 '.cm-problem-read': {
197 background: 'rgba(255, 255, 255, 0.15)',
198 },
199 };
200});
diff --git a/language-web/src/main/js/editor/EditorStore.ts b/language-web/src/main/js/editor/EditorStore.ts
index 705020b9..ba31efcb 100644
--- a/language-web/src/main/js/editor/EditorStore.ts
+++ b/language-web/src/main/js/editor/EditorStore.ts
@@ -1,201 +1,283 @@
1import type { Editor, EditorConfiguration } from 'codemirror'; 1import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
2import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets';
3import { defaultKeymap, indentWithTab } from '@codemirror/commands';
4import { commentKeymap } from '@codemirror/comment';
5import { foldGutter, foldKeymap } from '@codemirror/fold';
6import { highlightActiveLineGutter, lineNumbers } from '@codemirror/gutter';
7import { classHighlightStyle } from '@codemirror/highlight';
8import {
9 history,
10 historyKeymap,
11 redo,
12 redoDepth,
13 undo,
14 undoDepth,
15} from '@codemirror/history';
16import { indentOnInput } from '@codemirror/language';
17import {
18 Diagnostic,
19 lintKeymap,
20 setDiagnostics,
21} from '@codemirror/lint';
22import { bracketMatching } from '@codemirror/matchbrackets';
23import { rectangularSelection } from '@codemirror/rectangular-selection';
24import { searchConfig, searchKeymap } from '@codemirror/search';
25import {
26 EditorState,
27 StateCommand,
28 StateEffect,
29 Transaction,
30 TransactionSpec,
31} from '@codemirror/state';
32import {
33 drawSelection,
34 EditorView,
35 highlightActiveLine,
36 highlightSpecialChars,
37 keymap,
38} from '@codemirror/view';
2import { 39import {
3 createAtom,
4 makeAutoObservable, 40 makeAutoObservable,
5 observable, 41 observable,
6 runInAction, 42 reaction,
7} from 'mobx'; 43} from 'mobx';
8import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror';
9 44
10import type { IEditorChunk } from './editor'; 45import { findOccurrences, IOccurrence, setOccurrences } from './findOccurrences';
11import { getLogger } from '../logging'; 46import { problemLanguageSupport } from '../language/problemLanguageSupport';
47import {
48 IHighlightRange,
49 semanticHighlighting,
50 setSemanticHighlighting,
51} from './semanticHighlighting';
12import type { ThemeStore } from '../theme/ThemeStore'; 52import type { ThemeStore } from '../theme/ThemeStore';
53import { getLogger } from '../utils/logger';
54import { XtextClient } from '../xtext/XtextClient';
13 55
14const log = getLogger('EditorStore'); 56const log = getLogger('editor.EditorStore');
15 57
16const xtextLang = 'problem'; 58export class EditorStore {
59 private readonly themeStore;
17 60
18const xtextOptions: IXtextOptions = { 61 state: EditorState;
19 xtextLang,
20 enableFormattingAction: true,
21};
22 62
23const codeMirrorGlobalOptions: EditorConfiguration = { 63 private readonly client: XtextClient;
24 mode: `xtext/${xtextLang}`,
25 indentUnit: 2,
26 styleActiveLine: true,
27 screenReaderLabel: 'Model source code',
28 inputStyle: 'contenteditable',
29};
30 64
31export class EditorStore { 65 showLineNumbers = false;
32 themeStore;
33 66
34 atom; 67 showSearchPanel = false;
35 68
36 chunk?: IEditorChunk; 69 showLintPanel = false;
37 70
38 editor?: Editor; 71 errorCount = 0;
39 72
40 xtextServices?: IXtextServices; 73 warningCount = 0;
41 74
42 value = ''; 75 infoCount = 0;
43 76
44 showLineNumbers = false; 77 private readonly defaultDispatcher = (tr: Transaction): void => {
78 this.onTransaction(tr);
79 };
45 80
46 initialSelection!: { start: number, end: number, focused: boolean }; 81 private dispatcher = this.defaultDispatcher;
47 82
48 constructor(themeStore: ThemeStore) { 83 constructor(initialValue: string, themeStore: ThemeStore) {
49 this.themeStore = themeStore; 84 this.themeStore = themeStore;
50 this.atom = createAtom('EditorStore'); 85 this.state = EditorState.create({
51 this.resetInitialSelection(); 86 doc: initialValue,
52 makeAutoObservable(this, { 87 extensions: [
53 themeStore: false, 88 autocompletion({
54 atom: false, 89 activateOnTyping: true,
55 chunk: observable.ref, 90 override: [
56 editor: observable.ref, 91 (context) => this.client.contentAssist(context),
57 xtextServices: observable.ref, 92 ],
58 initialSelection: false, 93 }),
94 classHighlightStyle.extension,
95 closeBrackets(),
96 bracketMatching(),
97 drawSelection(),
98 EditorState.allowMultipleSelections.of(true),
99 EditorView.theme({}, {
100 dark: this.themeStore.darkMode,
101 }),
102 findOccurrences,
103 highlightActiveLine(),
104 highlightActiveLineGutter(),
105 highlightSpecialChars(),
106 history(),
107 indentOnInput(),
108 rectangularSelection(),
109 searchConfig({
110 top: true,
111 matchCase: true,
112 }),
113 semanticHighlighting,
114 // We add the gutters to `extensions` in the order we want them to appear.
115 foldGutter(),
116 lineNumbers(),
117 keymap.of([
118 ...closeBracketsKeymap,
119 ...commentKeymap,
120 ...completionKeymap,
121 ...foldKeymap,
122 ...historyKeymap,
123 indentWithTab,
124 // Override keys in `lintKeymap` to go through the `EditorStore`.
125 { key: 'Mod-Shift-m', run: () => this.setLintPanelOpen(true) },
126 ...lintKeymap,
127 // Override keys in `searchKeymap` to go through the `EditorStore`.
128 { key: 'Mod-f', run: () => this.setSearchPanelOpen(true), scope: 'editor search-panel' },
129 { key: 'Escape', run: () => this.setSearchPanelOpen(false), scope: 'editor search-panel' },
130 ...searchKeymap,
131 ...defaultKeymap,
132 ]),
133 problemLanguageSupport(),
134 ],
59 }); 135 });
60 this.loadChunk(); 136 this.client = new XtextClient(this);
61 } 137 reaction(
62 138 () => this.themeStore.darkMode,
63 private loadChunk(): void { 139 (darkMode) => {
64 const loadingStartMillis = Date.now(); 140 log.debug('Update editor dark mode', darkMode);
65 log.info('Requesting editor chunk'); 141 this.dispatch({
66 import('./editor').then(({ editorChunk }) => { 142 effects: [
67 runInAction(() => { 143 StateEffect.appendConfig.of(EditorView.theme({}, {
68 this.chunk = editorChunk; 144 dark: darkMode,
69 }); 145 })),
70 const loadingDurationMillis = Date.now() - loadingStartMillis; 146 ],
71 log.info('Loaded editor chunk in', loadingDurationMillis, 'ms'); 147 });
72 }).catch((error) => { 148 },
73 log.error('Error while loading editor', error); 149 );
150 makeAutoObservable(this, {
151 state: observable.ref,
74 }); 152 });
75 } 153 }
76 154
77 setInitialSelection(start: number, end: number, focused: boolean): void { 155 updateDispatcher(newDispatcher: ((tr: Transaction) => void) | null): void {
78 this.initialSelection = { start, end, focused }; 156 this.dispatcher = newDispatcher || this.defaultDispatcher;
79 this.applyInitialSelectionToEditor(); 157 }
158
159 onTransaction(tr: Transaction): void {
160 log.trace('Editor transaction', tr);
161 this.state = tr.state;
162 this.client.onTransaction(tr);
80 } 163 }
81 164
82 private resetInitialSelection(): void { 165 dispatch(...specs: readonly TransactionSpec[]): void {
83 this.initialSelection = { 166 this.dispatcher(this.state.update(...specs));
84 start: 0,
85 end: 0,
86 focused: false,
87 };
88 } 167 }
89 168
90 private applyInitialSelectionToEditor(): void { 169 doStateCommand(command: StateCommand): boolean {
91 if (this.editor) { 170 return command({
92 const { start, end, focused } = this.initialSelection; 171 state: this.state,
93 const doc = this.editor.getDoc(); 172 dispatch: this.dispatcher,
94 const startPos = doc.posFromIndex(start); 173 });
95 const endPos = doc.posFromIndex(end); 174 }
96 doc.setSelection(startPos, endPos, { 175
97 scroll: true, 176 updateDiagnostics(diagnostics: Diagnostic[]): void {
98 }); 177 this.dispatch(setDiagnostics(this.state, diagnostics));
99 if (focused) { 178 this.errorCount = 0;
100 this.editor.focus(); 179 this.warningCount = 0;
180 this.infoCount = 0;
181 diagnostics.forEach(({ severity }) => {
182 switch (severity) {
183 case 'error':
184 this.errorCount += 1;
185 break;
186 case 'warning':
187 this.warningCount += 1;
188 break;
189 case 'info':
190 this.infoCount += 1;
191 break;
101 } 192 }
102 this.resetInitialSelection(); 193 });
103 }
104 } 194 }
105 195
106 /** 196 get highestDiagnosticLevel(): Diagnostic['severity'] | null {
107 * Attaches a new CodeMirror instance and creates Xtext services. 197 if (this.errorCount > 0) {
108 * 198 return 'error';
109 * The store will not subscribe to any CodeMirror events. Instead, 199 }
110 * the editor component should subscribe to them and relay them to the store. 200 if (this.warningCount > 0) {
111 * 201 return 'warning';
112 * @param newEditor The new CodeMirror instance
113 */
114 editorDidMount(newEditor: Editor): void {
115 if (!this.chunk) {
116 throw new Error('Editor not loaded yet');
117 } 202 }
118 if (this.editor) { 203 if (this.infoCount > 0) {
119 throw new Error('CoreMirror editor mounted before unmounting'); 204 return 'info';
120 } 205 }
121 this.editor = newEditor; 206 return null;
122 this.xtextServices = this.chunk.createServices(newEditor, xtextOptions);
123 this.applyInitialSelectionToEditor();
124 } 207 }
125 208
126 editorWillUnmount(): void { 209 updateSemanticHighlighting(ranges: IHighlightRange[]): void {
127 if (!this.chunk) { 210 this.dispatch(setSemanticHighlighting(ranges));
128 throw new Error('Editor not loaded yet'); 211 }
129 } 212
130 if (this.editor) { 213 updateOccurrences(write: IOccurrence[], read: IOccurrence[]): void {
131 this.chunk.removeServices(this.editor); 214 this.dispatch(setOccurrences(write, read));
132 }
133 delete this.editor;
134 delete this.xtextServices;
135 } 215 }
136 216
137 /** 217 /**
138 * Updates the contents of the editor. 218 * @returns `true` if there is history to undo
139 *
140 * @param newValue The new contents of the editor
141 */ 219 */
142 updateValue(newValue: string): void { 220 get canUndo(): boolean {
143 this.value = newValue; 221 return undoDepth(this.state) > 0;
144 } 222 }
145 223
146 reportChanged(): void { 224 // eslint-disable-next-line class-methods-use-this
147 this.atom.reportChanged(); 225 undo(): void {
226 log.debug('Undo', this.doStateCommand(undo));
148 } 227 }
149 228
150 protected observeEditorChanges(): void { 229 /**
151 this.atom.reportObserved(); 230 * @returns `true` if there is history to redo
231 */
232 get canRedo(): boolean {
233 return redoDepth(this.state) > 0;
152 } 234 }
153 235
154 get codeMirrorTheme(): string { 236 // eslint-disable-next-line class-methods-use-this
155 return `problem-${this.themeStore.className}`; 237 redo(): void {
238 log.debug('Redo', this.doStateCommand(redo));
156 } 239 }
157 240
158 get codeMirrorOptions(): EditorConfiguration { 241 toggleLineNumbers(): void {
159 return { 242 this.showLineNumbers = !this.showLineNumbers;
160 ...codeMirrorGlobalOptions, 243 log.debug('Show line numbers', this.showLineNumbers);
161 theme: this.codeMirrorTheme,
162 lineNumbers: this.showLineNumbers,
163 };
164 } 244 }
165 245
166 /** 246 /**
167 * @returns `true` if there is history to undo 247 * Sets whether the CodeMirror search panel should be open.
248 *
249 * This method can be used as a CodeMirror command,
250 * because it returns `false` if it didn't execute,
251 * allowing other commands for the same keybind to run instead.
252 * This matches the behavior of the `openSearchPanel` and `closeSearchPanel`
253 * commands from `'@codemirror/search'`.
254 *
255 * @param newShosSearchPanel whether we should show the search panel
256 * @returns `true` if the state was changed, `false` otherwise
168 */ 257 */
169 get canUndo(): boolean { 258 setSearchPanelOpen(newShowSearchPanel: boolean): boolean {
170 this.observeEditorChanges(); 259 if (this.showSearchPanel === newShowSearchPanel) {
171 if (!this.editor) {
172 return false; 260 return false;
173 } 261 }
174 const { undo: undoSize } = this.editor.historySize(); 262 this.showSearchPanel = newShowSearchPanel;
175 return undoSize > 0; 263 log.debug('Show search panel', this.showSearchPanel);
264 return true;
176 } 265 }
177 266
178 undo(): void { 267 toggleSearchPanel(): void {
179 this.editor?.undo(); 268 this.setSearchPanelOpen(!this.showSearchPanel);
180 } 269 }
181 270
182 /** 271 setLintPanelOpen(newShowLintPanel: boolean): boolean {
183 * @returns `true` if there is history to redo 272 if (this.showLintPanel === newShowLintPanel) {
184 */
185 get canRedo(): boolean {
186 this.observeEditorChanges();
187 if (!this.editor) {
188 return false; 273 return false;
189 } 274 }
190 const { redo: redoSize } = this.editor.historySize(); 275 this.showLintPanel = newShowLintPanel;
191 return redoSize > 0; 276 log.debug('Show lint panel', this.showLintPanel);
192 } 277 return true;
193
194 redo(): void {
195 this.editor?.redo();
196 } 278 }
197 279
198 toggleLineNumbers(): void { 280 toggleLintPanel(): void {
199 this.showLineNumbers = !this.showLineNumbers; 281 this.setLintPanelOpen(!this.showLintPanel);
200 } 282 }
201} 283}
diff --git a/language-web/src/main/js/editor/GenerateButton.tsx b/language-web/src/main/js/editor/GenerateButton.tsx
new file mode 100644
index 00000000..3834cec4
--- /dev/null
+++ b/language-web/src/main/js/editor/GenerateButton.tsx
@@ -0,0 +1,44 @@
1import { observer } from 'mobx-react-lite';
2import Button from '@mui/material/Button';
3import PlayArrowIcon from '@mui/icons-material/PlayArrow';
4import React from 'react';
5
6import { useRootStore } from '../RootStore';
7
8const GENERATE_LABEL = 'Generate';
9
10export const GenerateButton = observer(() => {
11 const { editorStore } = useRootStore();
12 const { errorCount, warningCount } = editorStore;
13
14 const diagnostics: string[] = [];
15 if (errorCount > 0) {
16 diagnostics.push(`${errorCount} error${errorCount === 1 ? '' : 's'}`);
17 }
18 if (warningCount > 0) {
19 diagnostics.push(`${warningCount} warning${warningCount === 1 ? '' : 's'}`);
20 }
21 const summary = diagnostics.join(' and ');
22
23 if (errorCount > 0) {
24 return (
25 <Button
26 variant="outlined"
27 color="error"
28 onClick={() => editorStore.toggleLintPanel()}
29 >
30 {summary}
31 </Button>
32 );
33 }
34
35 return (
36 <Button
37 variant="outlined"
38 color={warningCount > 0 ? 'warning' : 'primary'}
39 startIcon={<PlayArrowIcon />}
40 >
41 {summary === '' ? GENERATE_LABEL : `${GENERATE_LABEL} (${summary})`}
42 </Button>
43 );
44});
diff --git a/language-web/src/main/js/editor/decorationSetExtension.ts b/language-web/src/main/js/editor/decorationSetExtension.ts
new file mode 100644
index 00000000..2d630c20
--- /dev/null
+++ b/language-web/src/main/js/editor/decorationSetExtension.ts
@@ -0,0 +1,39 @@
1import { StateEffect, StateField, TransactionSpec } from '@codemirror/state';
2import { EditorView, Decoration, DecorationSet } from '@codemirror/view';
3
4export type TransactionSpecFactory = (decorations: DecorationSet) => TransactionSpec;
5
6export function decorationSetExtension(): [TransactionSpecFactory, StateField<DecorationSet>] {
7 const setEffect = StateEffect.define<DecorationSet>();
8 const field = StateField.define<DecorationSet>({
9 create() {
10 return Decoration.none;
11 },
12 update(currentDecorations, transaction) {
13 let newDecorations: DecorationSet | null = null;
14 transaction.effects.forEach((effect) => {
15 if (effect.is(setEffect)) {
16 newDecorations = effect.value;
17 }
18 });
19 if (newDecorations === null) {
20 if (transaction.docChanged) {
21 return currentDecorations.map(transaction.changes);
22 }
23 return currentDecorations;
24 }
25 return newDecorations;
26 },
27 provide: (f) => EditorView.decorations.from(f),
28 });
29
30 function transactionSpecFactory(decorations: DecorationSet) {
31 return {
32 effects: [
33 setEffect.of(decorations),
34 ],
35 };
36 }
37
38 return [transactionSpecFactory, field];
39}
diff --git a/language-web/src/main/js/editor/editor.ts b/language-web/src/main/js/editor/editor.ts
deleted file mode 100644
index fbf8796b..00000000
--- a/language-web/src/main/js/editor/editor.ts
+++ /dev/null
@@ -1,18 +0,0 @@
1import 'codemirror/addon/selection/active-line';
2import 'mode-problem';
3import { Controlled } from 'react-codemirror2';
4import { createServices, removeServices } from 'xtext/xtext-codemirror';
5
6export interface IEditorChunk {
7 CodeMirror: typeof Controlled;
8
9 createServices: typeof createServices;
10
11 removeServices: typeof removeServices;
12}
13
14export const editorChunk: IEditorChunk = {
15 CodeMirror: Controlled,
16 createServices,
17 removeServices,
18};
diff --git a/language-web/src/main/js/editor/findOccurrences.ts b/language-web/src/main/js/editor/findOccurrences.ts
new file mode 100644
index 00000000..92102746
--- /dev/null
+++ b/language-web/src/main/js/editor/findOccurrences.ts
@@ -0,0 +1,35 @@
1import { Range, RangeSet } from '@codemirror/rangeset';
2import type { TransactionSpec } from '@codemirror/state';
3import { Decoration } from '@codemirror/view';
4
5import { decorationSetExtension } from './decorationSetExtension';
6
7export interface IOccurrence {
8 from: number;
9
10 to: number;
11}
12
13const [setOccurrencesInteral, findOccurrences] = decorationSetExtension();
14
15const writeDecoration = Decoration.mark({
16 class: 'cm-problem-write',
17});
18
19const readDecoration = Decoration.mark({
20 class: 'cm-problem-read',
21});
22
23export function setOccurrences(write: IOccurrence[], read: IOccurrence[]): TransactionSpec {
24 const decorations: Range<Decoration>[] = [];
25 write.forEach(({ from, to }) => {
26 decorations.push(writeDecoration.range(from, to));
27 });
28 read.forEach(({ from, to }) => {
29 decorations.push(readDecoration.range(from, to));
30 });
31 const rangeSet = RangeSet.of(decorations, true);
32 return setOccurrencesInteral(rangeSet);
33}
34
35export { findOccurrences };
diff --git a/language-web/src/main/js/editor/semanticHighlighting.ts b/language-web/src/main/js/editor/semanticHighlighting.ts
new file mode 100644
index 00000000..2aed421b
--- /dev/null
+++ b/language-web/src/main/js/editor/semanticHighlighting.ts
@@ -0,0 +1,24 @@
1import { RangeSet } from '@codemirror/rangeset';
2import type { TransactionSpec } from '@codemirror/state';
3import { Decoration } from '@codemirror/view';
4
5import { decorationSetExtension } from './decorationSetExtension';
6
7export interface IHighlightRange {
8 from: number;
9
10 to: number;
11
12 classes: string[];
13}
14
15const [setSemanticHighlightingInternal, semanticHighlighting] = decorationSetExtension();
16
17export function setSemanticHighlighting(ranges: IHighlightRange[]): TransactionSpec {
18 const rangeSet = RangeSet.of(ranges.map(({ from, to, classes }) => Decoration.mark({
19 class: classes.map((c) => `cmt-problem-${c}`).join(' '),
20 }).range(from, to)), true);
21 return setSemanticHighlightingInternal(rangeSet);
22}
23
24export { semanticHighlighting };
diff --git a/language-web/src/main/js/index.tsx b/language-web/src/main/js/index.tsx
index 80c70f23..dfecde37 100644
--- a/language-web/src/main/js/index.tsx
+++ b/language-web/src/main/js/index.tsx
@@ -9,23 +9,34 @@ import { ThemeProvider } from './theme/ThemeProvider';
9import '../css/index.scss'; 9import '../css/index.scss';
10 10
11const initialValue = `class Family { 11const initialValue = `class Family {
12 contains Person[] members 12 contains Person[] members
13} 13}
14 14
15class Person { 15class Person {
16 Person[] children opposite parent 16 Person[] children opposite parent
17 Person[0..1] parent opposite children 17 Person[0..1] parent opposite children
18 int age 18 int age
19 TaxStatus taxStatus 19 TaxStatus taxStatus
20} 20}
21 21
22enum TaxStatus { 22enum TaxStatus {
23 child, student, adult, retired 23 child, student, adult, retired
24} 24}
25 25
26% A child cannot have any dependents. 26% A child cannot have any dependents.
27error invalidTaxStatus(Person p) <-> 27pred invalidTaxStatus(Person p) <->
28 taxStatus(p, child), children(p, _q). 28 taxStatus(p, child),
29 children(p, _q)
30 ; taxStatus(p, retired),
31 parent(p, q),
32 !taxStatus(q, retired).
33
34direct rule createChild(p):
35 children(p, newPerson) = unknown,
36 equals(newPerson, newPerson) = unknown
37 ~> new q,
38 children(p, q) = true,
39 taxStatus(q, child) = true.
29 40
30unique family. 41unique family.
31Family(family). 42Family(family).
@@ -44,8 +55,7 @@ age(bob, bobAge).
44scope Family = 1, Person += 5..10. 55scope Family = 1, Person += 5..10.
45`; 56`;
46 57
47const rootStore = new RootStore(); 58const rootStore = new RootStore(initialValue);
48rootStore.editorStore.updateValue(initialValue);
49 59
50const app = ( 60const app = (
51 <RootStoreProvider rootStore={rootStore}> 61 <RootStoreProvider rootStore={rootStore}>
diff --git a/language-web/src/main/js/language/folding.ts b/language-web/src/main/js/language/folding.ts
new file mode 100644
index 00000000..5d51f796
--- /dev/null
+++ b/language-web/src/main/js/language/folding.ts
@@ -0,0 +1,115 @@
1import { EditorState } from '@codemirror/state';
2import type { SyntaxNode } from '@lezer/common';
3
4export type FoldRange = { from: number, to: number };
5
6/**
7 * Folds a block comment between its delimiters.
8 *
9 * @param node the node to fold
10 * @returns the folding range or `null` is there is nothing to fold
11 */
12export function foldBlockComment(node: SyntaxNode): FoldRange {
13 return {
14 from: node.from + 2,
15 to: node.to - 2,
16 };
17}
18
19/**
20 * Folds a declaration after the first element if it appears on the opening line,
21 * otherwise folds after the opening keyword.
22 *
23 * @example
24 * First element on the opening line:
25 * ```
26 * scope Family = 1,
27 * Person += 5..10.
28 * ```
29 * becomes
30 * ```
31 * scope Family = 1,[...].
32 * ```
33 *
34 * @example
35 * First element not on the opening line:
36 * ```
37 * scope Family
38 * = 1,
39 * Person += 5..10.
40 * ```
41 * becomes
42 * ```
43 * scope [...].
44 * ```
45 *
46 * @param node the node to fold
47 * @param state the editor state
48 * @returns the folding range or `null` is there is nothing to fold
49 */
50export function foldDeclaration(node: SyntaxNode, state: EditorState): FoldRange | null {
51 const { firstChild: open, lastChild: close } = node;
52 if (open === null || close === null) {
53 return null;
54 }
55 const { cursor } = open;
56 const lineEnd = state.doc.lineAt(open.from).to;
57 let foldFrom = open.to;
58 while (cursor.next() && cursor.from < lineEnd) {
59 if (cursor.type.name === ',') {
60 foldFrom = cursor.to;
61 break;
62 }
63 }
64 return {
65 from: foldFrom,
66 to: close.from,
67 };
68}
69
70/**
71 * Folds a node only if it has at least one sibling of the same type.
72 *
73 * The folding range will be the entire `node`.
74 *
75 * @param node the node to fold
76 * @returns the folding range or `null` is there is nothing to fold
77 */
78function foldWithSibling(node: SyntaxNode): FoldRange | null {
79 const { parent } = node;
80 if (parent === null) {
81 return null;
82 }
83 const { firstChild } = parent;
84 if (firstChild === null) {
85 return null;
86 }
87 const { cursor } = firstChild;
88 let nSiblings = 0;
89 while (cursor.nextSibling()) {
90 if (cursor.type === node.type) {
91 nSiblings += 1;
92 }
93 if (nSiblings >= 2) {
94 return {
95 from: node.from,
96 to: node.to,
97 };
98 }
99 }
100 return null;
101}
102
103export function foldWholeNode(node: SyntaxNode): FoldRange {
104 return {
105 from: node.from,
106 to: node.to,
107 };
108}
109
110export function foldConjunction(node: SyntaxNode): FoldRange | null {
111 if (node.parent?.type?.name === 'PredicateBody') {
112 return foldWithSibling(node);
113 }
114 return foldWholeNode(node);
115}
diff --git a/language-web/src/main/js/language/indentation.ts b/language-web/src/main/js/language/indentation.ts
new file mode 100644
index 00000000..78f0a750
--- /dev/null
+++ b/language-web/src/main/js/language/indentation.ts
@@ -0,0 +1,87 @@
1import { TreeIndentContext } from '@codemirror/language';
2
3/**
4 * Finds the `from` of first non-skipped token, if any,
5 * after the opening keyword in the first line of the declaration.
6 *
7 * Based on
8 * https://github.com/codemirror/language/blob/cd7f7e66fa51ddbce96cf9396b1b6127d0ca4c94/src/indent.ts#L246
9 *
10 * @param context the indentation context
11 * @returns the alignment or `null` if there is no token after the opening keyword
12 */
13function findAlignmentAfterOpening(context: TreeIndentContext): number | null {
14 const {
15 node: tree,
16 simulatedBreak,
17 } = context;
18 const openingToken = tree.childAfter(tree.from);
19 if (openingToken === null) {
20 return null;
21 }
22 const openingLine = context.state.doc.lineAt(openingToken.from);
23 const lineEnd = simulatedBreak == null || simulatedBreak <= openingLine.from
24 ? openingLine.to
25 : Math.min(openingLine.to, simulatedBreak);
26 const { cursor } = openingToken;
27 while (cursor.next() && cursor.from < lineEnd) {
28 if (!cursor.type.isSkipped) {
29 return cursor.from;
30 }
31 }
32 return null;
33}
34
35/**
36 * Indents text after declarations by a single unit if it begins on a new line,
37 * otherwise it aligns with the text after the declaration.
38 *
39 * Based on
40 * https://github.com/codemirror/language/blob/cd7f7e66fa51ddbce96cf9396b1b6127d0ca4c94/src/indent.ts#L275
41 *
42 * @example
43 * Result with no hanging indent (indent unit = 2 spaces, units = 1):
44 * ```
45 * scope
46 * Family = 1,
47 * Person += 5..10.
48 * ```
49 *
50 * @example
51 * Result with hanging indent:
52 * ```
53 * scope Family = 1,
54 * Person += 5..10.
55 * ```
56 *
57 * @param context the indentation context
58 * @param units the number of units to indent
59 * @returns the desired indentation level
60 */
61function indentDeclarationStrategy(context: TreeIndentContext, units: number): number {
62 const alignment = findAlignmentAfterOpening(context);
63 if (alignment !== null) {
64 return context.column(alignment);
65 }
66 return context.baseIndent + units * context.unit;
67}
68
69export function indentBlockComment(): number {
70 // Do not indent.
71 return -1;
72}
73
74export function indentDeclaration(context: TreeIndentContext): number {
75 return indentDeclarationStrategy(context, 1);
76}
77
78export function indentPredicateOrRule(context: TreeIndentContext): number {
79 const clauseIndent = indentDeclarationStrategy(context, 1);
80 if (/^\s+(;|\.)/.exec(context.textAfter) !== null) {
81 return clauseIndent - 2;
82 }
83 if (/^\s+(~>)/.exec(context.textAfter) !== null) {
84 return clauseIndent - 3;
85 }
86 return clauseIndent;
87}
diff --git a/language-web/src/main/js/language/problem.grammar b/language-web/src/main/js/language/problem.grammar
new file mode 100644
index 00000000..c242a4ba
--- /dev/null
+++ b/language-web/src/main/js/language/problem.grammar
@@ -0,0 +1,145 @@
1@top Problem { statement* }
2
3statement {
4 ProblemDeclaration {
5 ckw<"problem"> QualifiedName "."
6 } |
7 ClassDefinition {
8 ckw<"abstract">? ckw<"class"> RelationName
9 (ckw<"extends"> sep<",", RelationName>)?
10 (ClassBody { "{" ReferenceDeclaration* "}" } | ".")
11 } |
12 EnumDefinition {
13 ckw<"enum"> RelationName
14 (EnumBody { "{" sep<",", UniqueNodeName> "}" } | ".")
15 } |
16 PredicateDefinition {
17 (ckw<"error"> ckw<"pred">? | ckw<"direct">? ckw<"pred">)
18 RelationName ParameterList<Parameter>?
19 PredicateBody { ("<->" sep<OrOp, Conjunction>)? "." }
20 } |
21 RuleDefinition {
22 ckw<"direct">? ckw<"rule">
23 RuleName ParameterList<Parameter>?
24 RuleBody { ":" sep<OrOp, Conjunction> "~>" sep<OrOp, Action> "." }
25 } |
26 Assertion {
27 ckw<"default">? (NotOp | UnknownOp)? RelationName
28 ParameterList<AssertionArgument> (":" LogicValue)? "."
29 } |
30 NodeValueAssertion {
31 UniqueNodeName ":" Constant "."
32 } |
33 UniqueDeclaration {
34 ckw<"unique"> sep<",", UniqueNodeName> "."
35 } |
36 ScopeDeclaration {
37 ckw<"scope"> sep<",", ScopeElement> "."
38 }
39}
40
41ReferenceDeclaration {
42 (kw<"refers"> | kw<"contains">)?
43 RelationName
44 RelationName
45 ( "[" Multiplicity? "]" )?
46 (kw<"opposite"> RelationName)?
47 ";"?
48}
49
50Parameter { RelationName? VariableName }
51
52Conjunction { ("," | Literal)+ }
53
54OrOp { ";" }
55
56Literal { NotOp? Atom (("=" | ":") sep1<"|", LogicValue>)? }
57
58Atom { RelationName "+"? ParameterList<Argument> }
59
60Action { ("," | ActionLiteral)+ }
61
62ActionLiteral {
63 ckw<"new"> VariableName |
64 ckw<"delete"> VariableName |
65 Literal
66}
67
68Argument { VariableName | Constant }
69
70AssertionArgument { NodeName | StarArgument | Constant }
71
72Constant { Real | String }
73
74LogicValue {
75 ckw<"true"> | ckw<"false"> | ckw<"unknown"> | ckw<"error">
76}
77
78ScopeElement { RelationName ("=" | "+=") Multiplicity }
79
80Multiplicity { (IntMult "..")? (IntMult | StarMult)}
81
82RelationName { QualifiedName }
83
84RuleName { QualifiedName }
85
86UniqueNodeName { QualifiedName }
87
88VariableName { QualifiedName }
89
90NodeName { QualifiedName }
91
92QualifiedName { identifier ("::" identifier)* }
93
94kw<term> { @specialize[@name={term}]<identifier, term> }
95
96ckw<term> { @extend[@name={term}]<identifier, term> }
97
98ParameterList<content> { "(" sep<",", content> ")" }
99
100sep<separator, content> { sep1<separator, content>? }
101
102sep1<separator, content> { content (separator content)* }
103
104@skip { LineComment | BlockComment | whitespace }
105
106@tokens {
107 whitespace { std.whitespace+ }
108
109 LineComment { ("//" | "%") ![\n]* }
110
111 BlockComment { "/*" blockCommentRest }
112
113 blockCommentRest { ![*] blockCommentRest | "*" blockCommentAfterStar }
114
115 blockCommentAfterStar { "/" | "*" blockCommentAfterStar | ![/*] blockCommentRest }
116
117 @precedence { BlockComment, LineComment }
118
119 identifier { $[A-Za-z_] $[a-zA-Z0-9_]* }
120
121 int { $[0-9]+ }
122
123 IntMult { int }
124
125 StarMult { "*" }
126
127 Real { "-"? (exponential | int ("." (int | exponential))?) }
128
129 exponential { int ("e" | "E") ("+" | "-")? int }
130
131 String {
132 "'" (![\\'\n] | "\\" ![\n] | "\\\n")+ "'" |
133 "\"" (![\\"\n] | "\\" (![\n] | "\n"))* "\""
134 }
135
136 NotOp { "!" }
137
138 UnknownOp { "?" }
139
140 StarArgument { "*" }
141
142 "{" "}" "(" ")" "[" "]" "." ".." "," ":" "<->" "~>"
143}
144
145@detectDelim
diff --git a/language-web/src/main/js/language/problemLanguageSupport.ts b/language-web/src/main/js/language/problemLanguageSupport.ts
new file mode 100644
index 00000000..ab1c55f9
--- /dev/null
+++ b/language-web/src/main/js/language/problemLanguageSupport.ts
@@ -0,0 +1,92 @@
1import { styleTags, tags as t } from '@codemirror/highlight';
2import {
3 foldInside,
4 foldNodeProp,
5 indentNodeProp,
6 indentUnit,
7 LanguageSupport,
8 LRLanguage,
9} from '@codemirror/language';
10import { LRParser } from '@lezer/lr';
11
12import { parser } from '../../../../build/generated/sources/lezer/problem';
13import {
14 foldBlockComment,
15 foldConjunction,
16 foldDeclaration,
17 foldWholeNode,
18} from './folding';
19import {
20 indentBlockComment,
21 indentDeclaration,
22 indentPredicateOrRule,
23} from './indentation';
24
25const parserWithMetadata = (parser as LRParser).configure({
26 props: [
27 styleTags({
28 LineComment: t.lineComment,
29 BlockComment: t.blockComment,
30 'problem class enum pred rule unique scope': t.definitionKeyword,
31 'abstract extends refers contains opposite error direct default': t.modifier,
32 'true false unknown error': t.keyword,
33 'new delete': t.operatorKeyword,
34 NotOp: t.keyword,
35 UnknownOp: t.keyword,
36 OrOp: t.keyword,
37 StarArgument: t.keyword,
38 'IntMult StarMult Real': t.number,
39 StarMult: t.number,
40 String: t.string,
41 'RelationName/QualifiedName': t.typeName,
42 'RuleName/QualifiedName': t.macroName,
43 'UniqueNodeName/QualifiedName': t.atom,
44 'VariableName/QualifiedName': t.variableName,
45 '{ }': t.brace,
46 '( )': t.paren,
47 '[ ]': t.squareBracket,
48 '. .. , :': t.separator,
49 '<-> ~>': t.definitionOperator,
50 }),
51 indentNodeProp.add({
52 ProblemDeclaration: indentDeclaration,
53 UniqueDeclaration: indentDeclaration,
54 ScopeDeclaration: indentDeclaration,
55 PredicateBody: indentPredicateOrRule,
56 RuleBody: indentPredicateOrRule,
57 BlockComment: indentBlockComment,
58 }),
59 foldNodeProp.add({
60 ClassBody: foldInside,
61 EnumBody: foldInside,
62 ParameterList: foldInside,
63 PredicateBody: foldInside,
64 RuleBody: foldInside,
65 Conjunction: foldConjunction,
66 Action: foldWholeNode,
67 UniqueDeclaration: foldDeclaration,
68 ScopeDeclaration: foldDeclaration,
69 BlockComment: foldBlockComment,
70 }),
71 ],
72});
73
74const problemLanguage = LRLanguage.define({
75 parser: parserWithMetadata,
76 languageData: {
77 commentTokens: {
78 block: {
79 open: '/*',
80 close: '*/',
81 },
82 line: '%',
83 },
84 indentOnInput: /^\s*(?:\{|\}|\(|\)|;|\.|~>)$/,
85 },
86});
87
88export function problemLanguageSupport(): LanguageSupport {
89 return new LanguageSupport(problemLanguage, [
90 indentUnit.of(' '),
91 ]);
92}
diff --git a/language-web/src/main/js/theme/ThemeStore.ts b/language-web/src/main/js/theme/ThemeStore.ts
index 3bbea3a1..ffaf6dde 100644
--- a/language-web/src/main/js/theme/ThemeStore.ts
+++ b/language-web/src/main/js/theme/ThemeStore.ts
@@ -42,6 +42,9 @@ export class ThemeStore {
42 secondary: { 42 secondary: {
43 main: themeData.secondary, 43 main: themeData.secondary,
44 }, 44 },
45 error: {
46 main: themeData.secondary,
47 },
45 text: { 48 text: {
46 primary: themeData.foregroundHighlight, 49 primary: themeData.foregroundHighlight,
47 secondary: themeData.foreground, 50 secondary: themeData.foreground,
@@ -51,6 +54,10 @@ export class ThemeStore {
51 return responsiveFontSizes(materialUiTheme); 54 return responsiveFontSizes(materialUiTheme);
52 } 55 }
53 56
57 get darkMode(): boolean {
58 return this.currentThemeData.paletteMode === 'dark';
59 }
60
54 get className(): string { 61 get className(): string {
55 return this.currentThemeData.className; 62 return this.currentThemeData.className;
56 } 63 }
diff --git a/language-web/src/main/js/utils/ConditionVariable.ts b/language-web/src/main/js/utils/ConditionVariable.ts
new file mode 100644
index 00000000..0910dfa6
--- /dev/null
+++ b/language-web/src/main/js/utils/ConditionVariable.ts
@@ -0,0 +1,64 @@
1import { getLogger } from './logger';
2import { PendingTask } from './PendingTask';
3
4const log = getLogger('utils.ConditionVariable');
5
6export type Condition = () => boolean;
7
8export class ConditionVariable {
9 condition: Condition;
10
11 defaultTimeout: number;
12
13 listeners: PendingTask<void>[] = [];
14
15 constructor(condition: Condition, defaultTimeout = 0) {
16 this.condition = condition;
17 this.defaultTimeout = defaultTimeout;
18 }
19
20 async waitFor(timeoutMs: number | null = null): Promise<void> {
21 if (this.condition()) {
22 return;
23 }
24 const timeoutOrDefault = timeoutMs || this.defaultTimeout;
25 let nowMs = Date.now();
26 const endMs = nowMs + timeoutOrDefault;
27 while (!this.condition() && nowMs < endMs) {
28 const remainingMs = endMs - nowMs;
29 const promise = new Promise<void>((resolve, reject) => {
30 if (this.condition()) {
31 resolve();
32 return;
33 }
34 const task = new PendingTask(resolve, reject, remainingMs);
35 this.listeners.push(task);
36 });
37 // We must keep waiting until the update has completed,
38 // so the tasks can't be started in parallel.
39 // eslint-disable-next-line no-await-in-loop
40 await promise;
41 nowMs = Date.now();
42 }
43 if (!this.condition()) {
44 log.error('Condition still does not hold after', timeoutOrDefault, 'ms');
45 throw new Error('Failed to wait for condition');
46 }
47 }
48
49 notifyAll(): void {
50 this.clearListenersWith((listener) => listener.resolve());
51 }
52
53 rejectAll(error: unknown): void {
54 this.clearListenersWith((listener) => listener.reject(error));
55 }
56
57 private clearListenersWith(callback: (listener: PendingTask<void>) => void) {
58 // Copy `listeners` so that we don't get into a race condition
59 // if one of the listeners adds another listener.
60 const { listeners } = this;
61 this.listeners = [];
62 listeners.forEach(callback);
63 }
64}
diff --git a/language-web/src/main/js/utils/PendingTask.ts b/language-web/src/main/js/utils/PendingTask.ts
new file mode 100644
index 00000000..de59a99b
--- /dev/null
+++ b/language-web/src/main/js/utils/PendingTask.ts
@@ -0,0 +1,60 @@
1import { getLogger } from './logger';
2
3const log = getLogger('utils.PendingTask');
4
5export class PendingTask<T> {
6 private readonly resolveCallback: (value: T) => void;
7
8 private readonly rejectCallback: (reason?: unknown) => void;
9
10 private resolved = false;
11
12 private timeout: NodeJS.Timeout | null;
13
14 constructor(
15 resolveCallback: (value: T) => void,
16 rejectCallback: (reason?: unknown) => void,
17 timeoutMs?: number,
18 timeoutCallback?: () => void,
19 ) {
20 this.resolveCallback = resolveCallback;
21 this.rejectCallback = rejectCallback;
22 if (timeoutMs) {
23 this.timeout = setTimeout(() => {
24 if (!this.resolved) {
25 this.reject(new Error('Request timed out'));
26 if (timeoutCallback) {
27 timeoutCallback();
28 }
29 }
30 }, timeoutMs);
31 } else {
32 this.timeout = null;
33 }
34 }
35
36 resolve(value: T): void {
37 if (this.resolved) {
38 log.warn('Trying to resolve already resolved promise');
39 return;
40 }
41 this.markResolved();
42 this.resolveCallback(value);
43 }
44
45 reject(reason?: unknown): void {
46 if (this.resolved) {
47 log.warn('Trying to reject already resolved promise');
48 return;
49 }
50 this.markResolved();
51 this.rejectCallback(reason);
52 }
53
54 private markResolved() {
55 this.resolved = true;
56 if (this.timeout !== null) {
57 clearTimeout(this.timeout);
58 }
59 }
60}
diff --git a/language-web/src/main/js/utils/Timer.ts b/language-web/src/main/js/utils/Timer.ts
new file mode 100644
index 00000000..efde6633
--- /dev/null
+++ b/language-web/src/main/js/utils/Timer.ts
@@ -0,0 +1,33 @@
1export class Timer {
2 readonly callback: () => void;
3
4 readonly defaultTimeout: number;
5
6 timeout: NodeJS.Timeout | null = null;
7
8 constructor(callback: () => void, defaultTimeout = 0) {
9 this.callback = () => {
10 this.timeout = null;
11 callback();
12 };
13 this.defaultTimeout = defaultTimeout;
14 }
15
16 schedule(timeout: number | null = null): void {
17 if (this.timeout === null) {
18 this.timeout = setTimeout(this.callback, timeout || this.defaultTimeout);
19 }
20 }
21
22 reschedule(timeout: number | null = null): void {
23 this.cancel();
24 this.schedule(timeout);
25 }
26
27 cancel(): void {
28 if (this.timeout !== null) {
29 clearTimeout(this.timeout);
30 this.timeout = null;
31 }
32 }
33}
diff --git a/language-web/src/main/js/logging.tsx b/language-web/src/main/js/utils/logger.ts
index 25f50f19..306d122c 100644
--- a/language-web/src/main/js/logging.tsx
+++ b/language-web/src/main/js/utils/logger.ts
@@ -2,7 +2,7 @@ import styles, { CSPair } from 'ansi-styles';
2import log from 'loglevel'; 2import log from 'loglevel';
3import * as prefix from 'loglevel-plugin-prefix'; 3import * as prefix from 'loglevel-plugin-prefix';
4 4
5const colors: Record<string, CSPair> = { 5const colors: Partial<Record<string, CSPair>> = {
6 TRACE: styles.magenta, 6 TRACE: styles.magenta,
7 DEBUG: styles.cyan, 7 DEBUG: styles.cyan,
8 INFO: styles.blue, 8 INFO: styles.blue,
diff --git a/language-web/src/main/js/xtext/CodeMirrorEditorContext.js b/language-web/src/main/js/xtext/CodeMirrorEditorContext.js
deleted file mode 100644
index b829c680..00000000
--- a/language-web/src/main/js/xtext/CodeMirrorEditorContext.js
+++ /dev/null
@@ -1,111 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define([], function() {
11
12 /**
13 * An editor context mediates between the Xtext services and the CodeMirror editor framework.
14 */
15 function CodeMirrorEditorContext(editor) {
16 this._editor = editor;
17 this._serverState = {};
18 this._serverStateListeners = [];
19 this._dirty = false;
20 this._dirtyStateListeners = [];
21 };
22
23 CodeMirrorEditorContext.prototype = {
24
25 getServerState: function() {
26 return this._serverState;
27 },
28
29 updateServerState: function(currentText, currentStateId) {
30 this._serverState.text = currentText;
31 this._serverState.stateId = currentStateId;
32 return this._serverStateListeners;
33 },
34
35 addServerStateListener: function(listener) {
36 this._serverStateListeners.push(listener);
37 },
38
39 getCaretOffset: function() {
40 var editor = this._editor;
41 return editor.indexFromPos(editor.getCursor());
42 },
43
44 getLineStart: function(lineNumber) {
45 var editor = this._editor;
46 return editor.indexFromPos({line: lineNumber, ch: 0});
47 },
48
49 getSelection: function() {
50 var editor = this._editor;
51 return {
52 start: editor.indexFromPos(editor.getCursor('from')),
53 end: editor.indexFromPos(editor.getCursor('to'))
54 };
55 },
56
57 getText: function(start, end) {
58 var editor = this._editor;
59 if (start && end) {
60 return editor.getRange(editor.posFromIndex(start), editor.posFromIndex(end));
61 } else {
62 return editor.getValue();
63 }
64 },
65
66 isDirty: function() {
67 return !this._clean;
68 },
69
70 setDirty: function(dirty) {
71 if (dirty != this._dirty) {
72 for (var i = 0; i < this._dirtyStateListeners.length; i++) {
73 this._dirtyStateListeners[i](dirty);
74 }
75 }
76 this._dirty = dirty;
77 },
78
79 addDirtyStateListener: function(listener) {
80 this._dirtyStateListeners.push(listener);
81 },
82
83 clearUndoStack: function() {
84 this._editor.clearHistory();
85 },
86
87 setCaretOffset: function(offset) {
88 var editor = this._editor;
89 editor.setCursor(editor.posFromIndex(offset));
90 },
91
92 setSelection: function(selection) {
93 var editor = this._editor;
94 editor.setSelection(editor.posFromIndex(selection.start), editor.posFromIndex(selection.end));
95 },
96
97 setText: function(text, start, end) {
98 var editor = this._editor;
99 if (!start)
100 start = 0;
101 if (!end)
102 end = editor.getValue().length;
103 var cursor = editor.getCursor();
104 editor.replaceRange(text, editor.posFromIndex(start), editor.posFromIndex(end));
105 editor.setCursor(cursor);
106 }
107
108 };
109
110 return CodeMirrorEditorContext;
111}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/ContentAssistService.ts b/language-web/src/main/js/xtext/ContentAssistService.ts
new file mode 100644
index 00000000..f085c5b1
--- /dev/null
+++ b/language-web/src/main/js/xtext/ContentAssistService.ts
@@ -0,0 +1,177 @@
1import type {
2 Completion,
3 CompletionContext,
4 CompletionResult,
5} from '@codemirror/autocomplete';
6import type { Transaction } from '@codemirror/state';
7import escapeStringRegexp from 'escape-string-regexp';
8
9import type { UpdateService } from './UpdateService';
10import { getLogger } from '../utils/logger';
11import type { IContentAssistEntry } from './xtextServiceResults';
12
13const PROPOSALS_LIMIT = 1000;
14
15const IDENTIFIER_REGEXP_STR = '[a-zA-Z0-9_]*';
16
17const HIGH_PRIORITY_KEYWORDS = ['<->'];
18
19const QUALIFIED_NAME_SEPARATOR_REGEXP = /::/g;
20
21const log = getLogger('xtext.ContentAssistService');
22
23function createCompletion(entry: IContentAssistEntry): Completion {
24 let boost;
25 switch (entry.kind) {
26 case 'KEYWORD':
27 // Some hard-to-type operators should be on top.
28 boost = HIGH_PRIORITY_KEYWORDS.includes(entry.proposal) ? 10 : -99;
29 break;
30 case 'TEXT':
31 case 'SNIPPET':
32 boost = -90;
33 break;
34 default: {
35 // Penalize qualified names (vs available unqualified names).
36 const extraSegments = entry.proposal.match(QUALIFIED_NAME_SEPARATOR_REGEXP)?.length || 0;
37 boost = Math.max(-5 * extraSegments, -50);
38 }
39 break;
40 }
41 return {
42 label: entry.proposal,
43 detail: entry.description,
44 info: entry.documentation,
45 type: entry.kind?.toLowerCase(),
46 boost,
47 };
48}
49
50function computeSpan(prefix: string, entryCount: number) {
51 const escapedPrefix = escapeStringRegexp(prefix);
52 if (entryCount < PROPOSALS_LIMIT) {
53 // Proposals with the current prefix fit the proposals limit.
54 // We can filter client side as long as the current prefix is preserved.
55 return new RegExp(`^${escapedPrefix}${IDENTIFIER_REGEXP_STR}$`);
56 }
57 // The current prefix overflows the proposals limits,
58 // so we have to fetch the completions again on the next keypress.
59 // Hopefully, it'll return a shorter list and we'll be able to filter client side.
60 return new RegExp(`^${escapedPrefix}$`);
61}
62
63export class ContentAssistService {
64 private readonly updateService: UpdateService;
65
66 private lastCompletion: CompletionResult | null = null;
67
68 constructor(updateService: UpdateService) {
69 this.updateService = updateService;
70 }
71
72 onTransaction(transaction: Transaction): void {
73 if (this.shouldInvalidateCachedCompletion(transaction)) {
74 this.lastCompletion = null;
75 }
76 }
77
78 async contentAssist(context: CompletionContext): Promise<CompletionResult> {
79 const tokenBefore = context.tokenBefore(['QualifiedName']);
80 let range: { from: number, to: number };
81 let prefix = '';
82 if (tokenBefore === null) {
83 if (!context.explicit) {
84 return {
85 from: context.pos,
86 options: [],
87 };
88 }
89 range = {
90 from: context.pos,
91 to: context.pos,
92 };
93 prefix = '';
94 } else {
95 range = {
96 from: tokenBefore.from,
97 to: tokenBefore.to,
98 };
99 const prefixLength = context.pos - tokenBefore.from;
100 if (prefixLength > 0) {
101 prefix = tokenBefore.text.substring(0, context.pos - tokenBefore.from);
102 }
103 }
104 if (!context.explicit && this.shouldReturnCachedCompletion(tokenBefore)) {
105 log.trace('Returning cached completion result');
106 // Postcondition of `shouldReturnCachedCompletion`: `lastCompletion !== null`
107 return {
108 ...this.lastCompletion as CompletionResult,
109 ...range,
110 };
111 }
112 this.lastCompletion = null;
113 const entries = await this.updateService.fetchContentAssist({
114 resource: this.updateService.resourceName,
115 serviceType: 'assist',
116 caretOffset: context.pos,
117 proposalsLimit: PROPOSALS_LIMIT,
118 }, context);
119 if (context.aborted) {
120 return {
121 ...range,
122 options: [],
123 };
124 }
125 const options: Completion[] = [];
126 entries.forEach((entry) => {
127 options.push(createCompletion(entry));
128 });
129 log.debug('Fetched', options.length, 'completions from server');
130 this.lastCompletion = {
131 ...range,
132 options,
133 span: computeSpan(prefix, entries.length),
134 };
135 return this.lastCompletion;
136 }
137
138 private shouldReturnCachedCompletion(
139 token: { from: number, to: number, text: string } | null,
140 ) {
141 if (token === null || this.lastCompletion === null) {
142 return false;
143 }
144 const { from, to, text } = token;
145 const { from: lastFrom, to: lastTo, span } = this.lastCompletion;
146 if (!lastTo) {
147 return true;
148 }
149 const [transformedFrom, transformedTo] = this.mapRangeInclusive(lastFrom, lastTo);
150 return from >= transformedFrom && to <= transformedTo && span && span.exec(text);
151 }
152
153 private shouldInvalidateCachedCompletion(transaction: Transaction) {
154 if (!transaction.docChanged || this.lastCompletion === null) {
155 return false;
156 }
157 const { from: lastFrom, to: lastTo } = this.lastCompletion;
158 if (!lastTo) {
159 return true;
160 }
161 const [transformedFrom, transformedTo] = this.mapRangeInclusive(lastFrom, lastTo);
162 let invalidate = false;
163 transaction.changes.iterChangedRanges((fromA, toA) => {
164 if (fromA < transformedFrom || toA > transformedTo) {
165 invalidate = true;
166 }
167 });
168 return invalidate;
169 }
170
171 private mapRangeInclusive(lastFrom: number, lastTo: number): [number, number] {
172 const changes = this.updateService.computeChangesSinceLastUpdate();
173 const transformedFrom = changes.mapPos(lastFrom);
174 const transformedTo = changes.mapPos(lastTo, 1);
175 return [transformedFrom, transformedTo];
176 }
177}
diff --git a/language-web/src/main/js/xtext/HighlightingService.ts b/language-web/src/main/js/xtext/HighlightingService.ts
new file mode 100644
index 00000000..fc3e9e53
--- /dev/null
+++ b/language-web/src/main/js/xtext/HighlightingService.ts
@@ -0,0 +1,43 @@
1import type { EditorStore } from '../editor/EditorStore';
2import type { IHighlightRange } from '../editor/semanticHighlighting';
3import type { UpdateService } from './UpdateService';
4import { getLogger } from '../utils/logger';
5import { isHighlightingResult } from './xtextServiceResults';
6
7const log = getLogger('xtext.ValidationService');
8
9export class HighlightingService {
10 private readonly store: EditorStore;
11
12 private readonly updateService: UpdateService;
13
14 constructor(store: EditorStore, updateService: UpdateService) {
15 this.store = store;
16 this.updateService = updateService;
17 }
18
19 onPush(push: unknown): void {
20 if (!isHighlightingResult(push)) {
21 log.error('Invalid highlighting result', push);
22 return;
23 }
24 const allChanges = this.updateService.computeChangesSinceLastUpdate();
25 const ranges: IHighlightRange[] = [];
26 push.regions.forEach(({ offset, length, styleClasses }) => {
27 if (styleClasses.length === 0) {
28 return;
29 }
30 const from = allChanges.mapPos(offset);
31 const to = allChanges.mapPos(offset + length);
32 if (to <= from) {
33 return;
34 }
35 ranges.push({
36 from,
37 to,
38 classes: styleClasses,
39 });
40 });
41 this.store.updateSemanticHighlighting(ranges);
42 }
43}
diff --git a/language-web/src/main/js/xtext/OccurrencesService.ts b/language-web/src/main/js/xtext/OccurrencesService.ts
new file mode 100644
index 00000000..d1dec9e9
--- /dev/null
+++ b/language-web/src/main/js/xtext/OccurrencesService.ts
@@ -0,0 +1,116 @@
1import { Transaction } from '@codemirror/state';
2
3import type { EditorStore } from '../editor/EditorStore';
4import type { IOccurrence } from '../editor/findOccurrences';
5import type { UpdateService } from './UpdateService';
6import { getLogger } from '../utils/logger';
7import { Timer } from '../utils/Timer';
8import { XtextWebSocketClient } from './XtextWebSocketClient';
9import {
10 isOccurrencesResult,
11 isServiceConflictResult,
12 ITextRegion,
13} from './xtextServiceResults';
14
15const FIND_OCCURRENCES_TIMEOUT_MS = 1000;
16
17// Must clear occurrences asynchronously from `onTransaction`,
18// because we must not emit a conflicting transaction when handling the pending transaction.
19const CLEAR_OCCURRENCES_TIMEOUT_MS = 10;
20
21const log = getLogger('xtext.OccurrencesService');
22
23function transformOccurrences(regions: ITextRegion[]): IOccurrence[] {
24 const occurrences: IOccurrence[] = [];
25 regions.forEach(({ offset, length }) => {
26 if (length > 0) {
27 occurrences.push({
28 from: offset,
29 to: offset + length,
30 });
31 }
32 });
33 return occurrences;
34}
35
36export class OccurrencesService {
37 private readonly store: EditorStore;
38
39 private readonly webSocketClient: XtextWebSocketClient;
40
41 private readonly updateService: UpdateService;
42
43 private hasOccurrences = false;
44
45 private readonly findOccurrencesTimer = new Timer(() => {
46 this.handleFindOccurrences();
47 }, FIND_OCCURRENCES_TIMEOUT_MS);
48
49 private readonly clearOccurrencesTimer = new Timer(() => {
50 this.clearOccurrences();
51 }, CLEAR_OCCURRENCES_TIMEOUT_MS);
52
53 constructor(
54 store: EditorStore,
55 webSocketClient: XtextWebSocketClient,
56 updateService: UpdateService,
57 ) {
58 this.store = store;
59 this.webSocketClient = webSocketClient;
60 this.updateService = updateService;
61 }
62
63 onTransaction(transaction: Transaction): void {
64 if (transaction.docChanged) {
65 this.clearOccurrencesTimer.schedule();
66 this.findOccurrencesTimer.reschedule();
67 }
68 if (transaction.isUserEvent('select')) {
69 this.findOccurrencesTimer.reschedule();
70 }
71 }
72
73 private handleFindOccurrences() {
74 this.clearOccurrencesTimer.cancel();
75 this.updateOccurrences().catch((error) => {
76 log.error('Unexpected error while updating occurrences', error);
77 this.clearOccurrences();
78 });
79 }
80
81 private async updateOccurrences() {
82 await this.updateService.update();
83 const result = await this.webSocketClient.send({
84 resource: this.updateService.resourceName,
85 serviceType: 'occurrences',
86 expectedStateId: this.updateService.xtextStateId,
87 caretOffset: this.store.state.selection.main.head,
88 });
89 const allChanges = this.updateService.computeChangesSinceLastUpdate();
90 if (!allChanges.empty
91 || (isServiceConflictResult(result) && result.conflict === 'canceled')) {
92 // Stale occurrences result, the user already made some changes.
93 // We can safely ignore the occurrences and schedule a new find occurrences call.
94 this.clearOccurrences();
95 this.findOccurrencesTimer.schedule();
96 return;
97 }
98 if (!isOccurrencesResult(result) || result.stateId !== this.updateService.xtextStateId) {
99 log.error('Unexpected occurrences result', result);
100 this.clearOccurrences();
101 return;
102 }
103 const write = transformOccurrences(result.writeRegions);
104 const read = transformOccurrences(result.readRegions);
105 this.hasOccurrences = write.length > 0 || read.length > 0;
106 log.debug('Found', write.length, 'write and', read.length, 'read occurrences');
107 this.store.updateOccurrences(write, read);
108 }
109
110 private clearOccurrences() {
111 if (this.hasOccurrences) {
112 this.store.updateOccurrences([], []);
113 this.hasOccurrences = false;
114 }
115 }
116}
diff --git a/language-web/src/main/js/xtext/ServiceBuilder.js b/language-web/src/main/js/xtext/ServiceBuilder.js
deleted file mode 100644
index 57fcb310..00000000
--- a/language-web/src/main/js/xtext/ServiceBuilder.js
+++ /dev/null
@@ -1,285 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 ******************************************************************************/
9
10define([
11 'jquery',
12 'xtext/services/XtextService',
13 'xtext/services/LoadResourceService',
14 'xtext/services/SaveResourceService',
15 'xtext/services/HighlightingService',
16 'xtext/services/ValidationService',
17 'xtext/services/UpdateService',
18 'xtext/services/ContentAssistService',
19 'xtext/services/HoverService',
20 'xtext/services/OccurrencesService',
21 'xtext/services/FormattingService',
22 '../logging',
23], function(jQuery, XtextService, LoadResourceService, SaveResourceService, HighlightingService,
24 ValidationService, UpdateService, ContentAssistService, HoverService, OccurrencesService,
25 FormattingService, logging) {
26
27 /**
28 * Builder class for the Xtext services.
29 */
30 function ServiceBuilder(xtextServices) {
31 this.services = xtextServices;
32 };
33
34 /**
35 * Create all the available Xtext services depending on the configuration.
36 */
37 ServiceBuilder.prototype.createServices = function() {
38 var services = this.services;
39 var options = services.options;
40 var editorContext = services.editorContext;
41 editorContext.xtextServices = services;
42 var self = this;
43 if (!options.serviceUrl) {
44 if (!options.baseUrl)
45 options.baseUrl = '/';
46 else if (options.baseUrl.charAt(0) != '/')
47 options.baseUrl = '/' + options.baseUrl;
48 options.serviceUrl = window.location.protocol + '//' + window.location.host + options.baseUrl + 'xtext-service';
49 }
50 if (options.resourceId) {
51 if (!options.xtextLang)
52 options.xtextLang = options.resourceId.split(/[?#]/)[0].split('.').pop();
53 if (options.loadFromServer === undefined)
54 options.loadFromServer = true;
55 if (options.loadFromServer && this.setupPersistenceServices) {
56 services.loadResourceService = new LoadResourceService(options.serviceUrl, options.resourceId, false);
57 services.loadResource = function(addParams) {
58 return services.loadResourceService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
59 }
60 services.saveResourceService = new SaveResourceService(options.serviceUrl, options.resourceId);
61 services.saveResource = function(addParams) {
62 return services.saveResourceService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
63 }
64 services.revertResourceService = new LoadResourceService(options.serviceUrl, options.resourceId, true);
65 services.revertResource = function(addParams) {
66 return services.revertResourceService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
67 }
68 this.setupPersistenceServices();
69 services.loadResource();
70 }
71 } else {
72 if (options.loadFromServer === undefined)
73 options.loadFromServer = false;
74 if (options.xtextLang) {
75 var randomId = Math.floor(Math.random() * 2147483648).toString(16);
76 options.resourceId = randomId + '.' + options.xtextLang;
77 }
78 }
79
80 if (this.setupSyntaxHighlighting) {
81 this.setupSyntaxHighlighting();
82 }
83 if (options.enableHighlightingService || options.enableHighlightingService === undefined) {
84 services.highlightingService = new HighlightingService(options.serviceUrl, options.resourceId);
85 services.computeHighlighting = function(addParams) {
86 return services.highlightingService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
87 }
88 }
89 if (options.enableValidationService || options.enableValidationService === undefined) {
90 services.validationService = new ValidationService(options.serviceUrl, options.resourceId);
91 services.validate = function(addParams) {
92 return services.validationService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
93 }
94 }
95 if (this.setupUpdateService) {
96 function refreshDocument() {
97 if (services.highlightingService && self.doHighlighting) {
98 services.highlightingService.setState(undefined);
99 self.doHighlighting();
100 }
101 if (services.validationService && self.doValidation) {
102 services.validationService.setState(undefined);
103 self.doValidation();
104 }
105 }
106 if (!options.sendFullText) {
107 services.updateService = new UpdateService(options.serviceUrl, options.resourceId);
108 services.update = function(addParams) {
109 return services.updateService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
110 }
111 if (services.saveResourceService)
112 services.saveResourceService._updateService = services.updateService;
113 editorContext.addServerStateListener(refreshDocument);
114 }
115 this.setupUpdateService(refreshDocument);
116 }
117 if ((options.enableContentAssistService || options.enableContentAssistService === undefined)
118 && this.setupContentAssistService) {
119 services.contentAssistService = new ContentAssistService(options.serviceUrl, options.resourceId, services.updateService);
120 services.getContentAssist = function(addParams) {
121 return services.contentAssistService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
122 }
123 this.setupContentAssistService();
124 }
125 if ((options.enableHoverService || options.enableHoverService === undefined)
126 && this.setupHoverService) {
127 services.hoverService = new HoverService(options.serviceUrl, options.resourceId, services.updateService);
128 services.getHoverInfo = function(addParams) {
129 return services.hoverService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
130 }
131 this.setupHoverService();
132 }
133 if ((options.enableOccurrencesService || options.enableOccurrencesService === undefined)
134 && this.setupOccurrencesService) {
135 services.occurrencesService = new OccurrencesService(options.serviceUrl, options.resourceId, services.updateService);
136 services.getOccurrences = function(addParams) {
137 return services.occurrencesService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
138 }
139 this.setupOccurrencesService();
140 }
141 if ((options.enableFormattingService || options.enableFormattingService === undefined)
142 && this.setupFormattingService) {
143 services.formattingService = new FormattingService(options.serviceUrl, options.resourceId, services.updateService);
144 services.format = function(addParams) {
145 return services.formattingService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
146 }
147 this.setupFormattingService();
148 }
149 if (options.enableGeneratorService || options.enableGeneratorService === undefined) {
150 services.generatorService = new XtextService();
151 services.generatorService.initialize(services, 'generate');
152 services.generatorService._initServerData = function(serverData, editorContext, params) {
153 if (params.allArtifacts)
154 serverData.allArtifacts = params.allArtifacts;
155 else if (params.artifactId)
156 serverData.artifact = params.artifactId;
157 if (params.includeContent !== undefined)
158 serverData.includeContent = params.includeContent;
159 }
160 services.generate = function(addParams) {
161 return services.generatorService.invoke(editorContext, ServiceBuilder.mergeOptions(addParams, options));
162 }
163 }
164
165 if (options.dirtyElement) {
166 var doc = options.document || document;
167 var dirtyElement;
168 if (typeof(options.dirtyElement) === 'string')
169 dirtyElement = jQuery('#' + options.dirtyElement, doc);
170 else
171 dirtyElement = jQuery(options.dirtyElement);
172 var dirtyStatusClass = options.dirtyStatusClass;
173 if (!dirtyStatusClass)
174 dirtyStatusClass = 'dirty';
175 editorContext.addDirtyStateListener(function(dirty) {
176 if (dirty)
177 dirtyElement.addClass(dirtyStatusClass);
178 else
179 dirtyElement.removeClass(dirtyStatusClass);
180 });
181 }
182
183 const log = logging.getLoggerFromRoot('xtext.XtextService');
184 services.successListeners = [function(serviceType, result) {
185 if (log.getLevel() <= log.levels.TRACE) {
186 log.trace('service', serviceType, 'request success', JSON.parse(JSON.stringify(result)));
187 }
188 }];
189 services.errorListeners = [function(serviceType, severity, message, requestData) {
190 const messageParts = ['service', serviceType, 'failed:', message || '(no message)'];
191 if (requestData) {
192 messageParts.push(JSON.parse(JSON.stringify(requestData)));
193 }
194 if (severity === 'warning') {
195 log.warn(...messageParts);
196 } else {
197 log.error(...messageParts);
198 }
199 }];
200 }
201
202 /**
203 * Change the resource associated with this service builder.
204 */
205 ServiceBuilder.prototype.changeResource = function(resourceId) {
206 var services = this.services;
207 var options = services.options;
208 options.resourceId = resourceId;
209 for (var p in services) {
210 if (services.hasOwnProperty(p)) {
211 var service = services[p];
212 if (service._serviceType && jQuery.isFunction(service.initialize))
213 services[p].initialize(options.serviceUrl, service._serviceType, resourceId, services.updateService);
214 }
215 }
216 var knownServerState = services.editorContext.getServerState();
217 delete knownServerState.stateId;
218 delete knownServerState.text;
219 if (options.loadFromServer && jQuery.isFunction(services.loadResource)) {
220 services.loadResource();
221 }
222 }
223
224 /**
225 * Create a copy of the given object.
226 */
227 ServiceBuilder.copy = function(obj) {
228 var copy = {};
229 for (var p in obj) {
230 if (obj.hasOwnProperty(p))
231 copy[p] = obj[p];
232 }
233 return copy;
234 }
235
236 /**
237 * Translate an HTML attribute name to a JS option name.
238 */
239 ServiceBuilder.optionName = function(name) {
240 var prefix = 'data-editor-';
241 if (name.substring(0, prefix.length) === prefix) {
242 var key = name.substring(prefix.length);
243 key = key.replace(/-([a-z])/ig, function(all, character) {
244 return character.toUpperCase();
245 });
246 return key;
247 }
248 return undefined;
249 }
250
251 /**
252 * Copy all default options into the given set of additional options.
253 */
254 ServiceBuilder.mergeOptions = function(options, defaultOptions) {
255 if (options) {
256 for (var p in defaultOptions) {
257 if (defaultOptions.hasOwnProperty(p))
258 options[p] = defaultOptions[p];
259 }
260 return options;
261 } else {
262 return ServiceBuilder.copy(defaultOptions);
263 }
264 }
265
266 /**
267 * Merge all properties of the given parent element with the given default options.
268 */
269 ServiceBuilder.mergeParentOptions = function(parent, defaultOptions) {
270 var options = ServiceBuilder.copy(defaultOptions);
271 for (var attr, j = 0, attrs = parent.attributes, l = attrs.length; j < l; j++) {
272 attr = attrs.item(j);
273 var key = ServiceBuilder.optionName(attr.nodeName);
274 if (key) {
275 var value = attr.nodeValue;
276 if (value === 'true' || value === 'false')
277 value = value === 'true';
278 options[key] = value;
279 }
280 }
281 return options;
282 }
283
284 return ServiceBuilder;
285});
diff --git a/language-web/src/main/js/xtext/UpdateService.ts b/language-web/src/main/js/xtext/UpdateService.ts
new file mode 100644
index 00000000..9b672e79
--- /dev/null
+++ b/language-web/src/main/js/xtext/UpdateService.ts
@@ -0,0 +1,310 @@
1import {
2 ChangeDesc,
3 ChangeSet,
4 Transaction,
5} from '@codemirror/state';
6import { nanoid } from 'nanoid';
7
8import type { EditorStore } from '../editor/EditorStore';
9import type { XtextWebSocketClient } from './XtextWebSocketClient';
10import { ConditionVariable } from '../utils/ConditionVariable';
11import { getLogger } from '../utils/logger';
12import { Timer } from '../utils/Timer';
13import {
14 IContentAssistEntry,
15 isContentAssistResult,
16 isDocumentStateResult,
17 isInvalidStateIdConflictResult,
18} from './xtextServiceResults';
19
20const UPDATE_TIMEOUT_MS = 500;
21
22const WAIT_FOR_UPDATE_TIMEOUT_MS = 1000;
23
24const log = getLogger('xtext.UpdateService');
25
26export interface IAbortSignal {
27 aborted: boolean;
28}
29
30export class UpdateService {
31 resourceName: string;
32
33 xtextStateId: string | null = null;
34
35 private readonly store: EditorStore;
36
37 /**
38 * The changes being synchronized to the server if a full or delta text update is running,
39 * `null` otherwise.
40 */
41 private pendingUpdate: ChangeDesc | null = null;
42
43 /**
44 * Local changes not yet sychronized to the server and not part of the running update, if any.
45 */
46 private dirtyChanges: ChangeDesc;
47
48 private readonly webSocketClient: XtextWebSocketClient;
49
50 private readonly updatedCondition = new ConditionVariable(
51 () => this.pendingUpdate === null && this.xtextStateId !== null,
52 WAIT_FOR_UPDATE_TIMEOUT_MS,
53 );
54
55 private readonly idleUpdateTimer = new Timer(() => {
56 this.handleIdleUpdate();
57 }, UPDATE_TIMEOUT_MS);
58
59 constructor(store: EditorStore, webSocketClient: XtextWebSocketClient) {
60 this.resourceName = `${nanoid(7)}.problem`;
61 this.store = store;
62 this.dirtyChanges = this.newEmptyChangeDesc();
63 this.webSocketClient = webSocketClient;
64 }
65
66 onReconnect(): void {
67 this.xtextStateId = null;
68 this.updateFullText().catch((error) => {
69 log.error('Unexpected error during initial update', error);
70 });
71 }
72
73 onTransaction(transaction: Transaction): void {
74 if (transaction.docChanged) {
75 this.dirtyChanges = this.dirtyChanges.composeDesc(transaction.changes.desc);
76 this.idleUpdateTimer.reschedule();
77 }
78 }
79
80 /**
81 * Computes the summary of any changes happened since the last complete update.
82 *
83 * The result reflects any changes that happened since the `xtextStateId`
84 * version was uploaded to the server.
85 *
86 * @return the summary of changes since the last update
87 */
88 computeChangesSinceLastUpdate(): ChangeDesc {
89 return this.pendingUpdate?.composeDesc(this.dirtyChanges) || this.dirtyChanges;
90 }
91
92 private handleIdleUpdate() {
93 if (!this.webSocketClient.isOpen || this.dirtyChanges.empty) {
94 return;
95 }
96 if (this.pendingUpdate === null) {
97 this.update().catch((error) => {
98 log.error('Unexpected error during scheduled update', error);
99 });
100 }
101 this.idleUpdateTimer.reschedule();
102 }
103
104 private newEmptyChangeDesc() {
105 const changeSet = ChangeSet.of([], this.store.state.doc.length);
106 return changeSet.desc;
107 }
108
109 async updateFullText(): Promise<void> {
110 await this.withUpdate(() => this.doUpdateFullText());
111 }
112
113 private async doUpdateFullText(): Promise<[string, void]> {
114 const result = await this.webSocketClient.send({
115 resource: this.resourceName,
116 serviceType: 'update',
117 fullText: this.store.state.doc.sliceString(0),
118 });
119 if (isDocumentStateResult(result)) {
120 return [result.stateId, undefined];
121 }
122 log.error('Unexpected full text update result:', result);
123 throw new Error('Full text update failed');
124 }
125
126 /**
127 * Makes sure that the document state on the server reflects recent
128 * local changes.
129 *
130 * Performs either an update with delta text or a full text update if needed.
131 * If there are not local dirty changes, the promise resolves immediately.
132 *
133 * @return a promise resolving when the update is completed
134 */
135 async update(): Promise<void> {
136 await this.prepareForDeltaUpdate();
137 const delta = this.computeDelta();
138 if (delta === null) {
139 return;
140 }
141 log.trace('Editor delta', delta);
142 await this.withUpdate(async () => {
143 const result = await this.webSocketClient.send({
144 resource: this.resourceName,
145 serviceType: 'update',
146 requiredStateId: this.xtextStateId,
147 ...delta,
148 });
149 if (isDocumentStateResult(result)) {
150 return [result.stateId, undefined];
151 }
152 if (isInvalidStateIdConflictResult(result)) {
153 return this.doFallbackToUpdateFullText();
154 }
155 log.error('Unexpected delta text update result:', result);
156 throw new Error('Delta text update failed');
157 });
158 }
159
160 private doFallbackToUpdateFullText() {
161 if (this.pendingUpdate === null) {
162 throw new Error('Only a pending update can be extended');
163 }
164 log.warn('Delta update failed, performing full text update');
165 this.xtextStateId = null;
166 this.pendingUpdate = this.pendingUpdate.composeDesc(this.dirtyChanges);
167 this.dirtyChanges = this.newEmptyChangeDesc();
168 return this.doUpdateFullText();
169 }
170
171 async fetchContentAssist(
172 params: Record<string, unknown>,
173 signal: IAbortSignal,
174 ): Promise<IContentAssistEntry[]> {
175 await this.prepareForDeltaUpdate();
176 if (signal.aborted) {
177 return [];
178 }
179 const delta = this.computeDelta();
180 if (delta !== null) {
181 log.trace('Editor delta', delta);
182 const entries = await this.withUpdate(async () => {
183 const result = await this.webSocketClient.send({
184 ...params,
185 requiredStateId: this.xtextStateId,
186 ...delta,
187 });
188 if (isContentAssistResult(result)) {
189 return [result.stateId, result.entries];
190 }
191 if (isInvalidStateIdConflictResult(result)) {
192 const [newStateId] = await this.doFallbackToUpdateFullText();
193 // We must finish this state update transaction to prepare for any push events
194 // before querying for content assist, so we just return `null` and will query
195 // the content assist service later.
196 return [newStateId, null];
197 }
198 log.error('Unextpected content assist result with delta update', result);
199 throw new Error('Unexpexted content assist result with delta update');
200 });
201 if (entries !== null) {
202 return entries;
203 }
204 if (signal.aborted) {
205 return [];
206 }
207 }
208 // Poscondition of `prepareForDeltaUpdate`: `xtextStateId !== null`
209 return this.doFetchContentAssist(params, this.xtextStateId as string);
210 }
211
212 private async doFetchContentAssist(params: Record<string, unknown>, expectedStateId: string) {
213 const result = await this.webSocketClient.send({
214 ...params,
215 requiredStateId: expectedStateId,
216 });
217 if (isContentAssistResult(result) && result.stateId === expectedStateId) {
218 return result.entries;
219 }
220 log.error('Unexpected content assist result', result);
221 throw new Error('Unexpected content assist result');
222 }
223
224 private computeDelta() {
225 if (this.dirtyChanges.empty) {
226 return null;
227 }
228 let minFromA = Number.MAX_SAFE_INTEGER;
229 let maxToA = 0;
230 let minFromB = Number.MAX_SAFE_INTEGER;
231 let maxToB = 0;
232 this.dirtyChanges.iterChangedRanges((fromA, toA, fromB, toB) => {
233 minFromA = Math.min(minFromA, fromA);
234 maxToA = Math.max(maxToA, toA);
235 minFromB = Math.min(minFromB, fromB);
236 maxToB = Math.max(maxToB, toB);
237 });
238 return {
239 deltaOffset: minFromA,
240 deltaReplaceLength: maxToA - minFromA,
241 deltaText: this.store.state.doc.sliceString(minFromB, maxToB),
242 };
243 }
244
245 /**
246 * Executes an asynchronous callback that updates the state on the server.
247 *
248 * Ensures that updates happen sequentially and manages `pendingUpdate`
249 * and `dirtyChanges` to reflect changes being synchronized to the server
250 * and not yet synchronized to the server, respectively.
251 *
252 * Optionally, `callback` may return a second value that is retured by this function.
253 *
254 * Once the remote procedure call to update the server state finishes
255 * and returns the new `stateId`, `callback` must return _immediately_
256 * to ensure that the local `stateId` is updated likewise to be able to handle
257 * push messages referring to the new `stateId` from the server.
258 * If additional work is needed to compute the second value in some cases,
259 * use `T | null` instead of `T` as a return type and signal the need for additional
260 * computations by returning `null`. Thus additional computations can be performed
261 * outside of the critical section.
262 *
263 * @param callback the asynchronous callback that updates the server state
264 * @return a promise resolving to the second value returned by `callback`
265 */
266 private async withUpdate<T>(callback: () => Promise<[string, T]>): Promise<T> {
267 if (this.pendingUpdate !== null) {
268 throw new Error('Another update is pending, will not perform update');
269 }
270 this.pendingUpdate = this.dirtyChanges;
271 this.dirtyChanges = this.newEmptyChangeDesc();
272 let newStateId: string | null = null;
273 try {
274 let result: T;
275 [newStateId, result] = await callback();
276 this.xtextStateId = newStateId;
277 this.pendingUpdate = null;
278 this.updatedCondition.notifyAll();
279 return result;
280 } catch (e) {
281 log.error('Error while update', e);
282 if (this.pendingUpdate === null) {
283 log.error('pendingUpdate was cleared during update');
284 } else {
285 this.dirtyChanges = this.pendingUpdate.composeDesc(this.dirtyChanges);
286 }
287 this.pendingUpdate = null;
288 this.webSocketClient.forceReconnectOnError();
289 this.updatedCondition.rejectAll(e);
290 throw e;
291 }
292 }
293
294 /**
295 * Ensures that there is some state available on the server (`xtextStateId`)
296 * and that there is not pending update.
297 *
298 * After this function resolves, a delta text update is possible.
299 *
300 * @return a promise resolving when there is a valid state id but no pending update
301 */
302 private async prepareForDeltaUpdate() {
303 // If no update is pending, but the full text hasn't been uploaded to the server yet,
304 // we must start a full text upload.
305 if (this.pendingUpdate === null && this.xtextStateId === null) {
306 await this.updateFullText();
307 }
308 await this.updatedCondition.waitFor();
309 }
310}
diff --git a/language-web/src/main/js/xtext/ValidationService.ts b/language-web/src/main/js/xtext/ValidationService.ts
new file mode 100644
index 00000000..8e4934ac
--- /dev/null
+++ b/language-web/src/main/js/xtext/ValidationService.ts
@@ -0,0 +1,45 @@
1import type { Diagnostic } from '@codemirror/lint';
2
3import type { EditorStore } from '../editor/EditorStore';
4import type { UpdateService } from './UpdateService';
5import { getLogger } from '../utils/logger';
6import { isValidationResult } from './xtextServiceResults';
7
8const log = getLogger('xtext.ValidationService');
9
10export class ValidationService {
11 private readonly store: EditorStore;
12
13 private readonly updateService: UpdateService;
14
15 constructor(store: EditorStore, updateService: UpdateService) {
16 this.store = store;
17 this.updateService = updateService;
18 }
19
20 onPush(push: unknown): void {
21 if (!isValidationResult(push)) {
22 log.error('Invalid validation result', push);
23 return;
24 }
25 const allChanges = this.updateService.computeChangesSinceLastUpdate();
26 const diagnostics: Diagnostic[] = [];
27 push.issues.forEach(({
28 offset,
29 length,
30 severity,
31 description,
32 }) => {
33 if (severity === 'ignore') {
34 return;
35 }
36 diagnostics.push({
37 from: allChanges.mapPos(offset),
38 to: allChanges.mapPos(offset + length),
39 severity,
40 message: description,
41 });
42 });
43 this.store.updateDiagnostics(diagnostics);
44 }
45}
diff --git a/language-web/src/main/js/xtext/XtextClient.ts b/language-web/src/main/js/xtext/XtextClient.ts
new file mode 100644
index 00000000..28f3d0cc
--- /dev/null
+++ b/language-web/src/main/js/xtext/XtextClient.ts
@@ -0,0 +1,83 @@
1import type {
2 CompletionContext,
3 CompletionResult,
4} from '@codemirror/autocomplete';
5import type { Transaction } from '@codemirror/state';
6
7import type { EditorStore } from '../editor/EditorStore';
8import { ContentAssistService } from './ContentAssistService';
9import { HighlightingService } from './HighlightingService';
10import { OccurrencesService } from './OccurrencesService';
11import { UpdateService } from './UpdateService';
12import { getLogger } from '../utils/logger';
13import { ValidationService } from './ValidationService';
14import { XtextWebSocketClient } from './XtextWebSocketClient';
15
16const log = getLogger('xtext.XtextClient');
17
18export class XtextClient {
19 private readonly webSocketClient: XtextWebSocketClient;
20
21 private readonly updateService: UpdateService;
22
23 private readonly contentAssistService: ContentAssistService;
24
25 private readonly highlightingService: HighlightingService;
26
27 private readonly validationService: ValidationService;
28
29 private readonly occurrencesService: OccurrencesService;
30
31 constructor(store: EditorStore) {
32 this.webSocketClient = new XtextWebSocketClient(
33 () => this.updateService.onReconnect(),
34 (resource, stateId, service, push) => this.onPush(resource, stateId, service, push),
35 );
36 this.updateService = new UpdateService(store, this.webSocketClient);
37 this.contentAssistService = new ContentAssistService(this.updateService);
38 this.highlightingService = new HighlightingService(store, this.updateService);
39 this.validationService = new ValidationService(store, this.updateService);
40 this.occurrencesService = new OccurrencesService(
41 store,
42 this.webSocketClient,
43 this.updateService,
44 );
45 }
46
47 onTransaction(transaction: Transaction): void {
48 // `ContentAssistService.prototype.onTransaction` needs the dirty change desc
49 // _before_ the current edit, so we call it before `updateService`.
50 this.contentAssistService.onTransaction(transaction);
51 this.updateService.onTransaction(transaction);
52 this.occurrencesService.onTransaction(transaction);
53 }
54
55 private onPush(resource: string, stateId: string, service: string, push: unknown) {
56 const { resourceName, xtextStateId } = this.updateService;
57 if (resource !== resourceName) {
58 log.error('Unknown resource name: expected:', resourceName, 'got:', resource);
59 return;
60 }
61 if (stateId !== xtextStateId) {
62 log.error('Unexpected xtext state id: expected:', xtextStateId, 'got:', stateId);
63 // The current push message might be stale (referring to a previous state),
64 // so this is not neccessarily an error and there is no need to force-reconnect.
65 return;
66 }
67 switch (service) {
68 case 'highlight':
69 this.highlightingService.onPush(push);
70 return;
71 case 'validate':
72 this.validationService.onPush(push);
73 return;
74 default:
75 log.error('Unknown push service:', service);
76 break;
77 }
78 }
79
80 contentAssist(context: CompletionContext): Promise<CompletionResult> {
81 return this.contentAssistService.contentAssist(context);
82 }
83}
diff --git a/language-web/src/main/js/xtext/XtextWebSocketClient.ts b/language-web/src/main/js/xtext/XtextWebSocketClient.ts
new file mode 100644
index 00000000..488e4b3b
--- /dev/null
+++ b/language-web/src/main/js/xtext/XtextWebSocketClient.ts
@@ -0,0 +1,341 @@
1import { nanoid } from 'nanoid';
2
3import { getLogger } from '../utils/logger';
4import { PendingTask } from '../utils/PendingTask';
5import { Timer } from '../utils/Timer';
6import {
7 isErrorResponse,
8 isOkResponse,
9 isPushMessage,
10 IXtextWebRequest,
11} from './xtextMessages';
12import { isPongResult } from './xtextServiceResults';
13
14const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1';
15
16const WEBSOCKET_CLOSE_OK = 1000;
17
18const RECONNECT_DELAY_MS = [200, 1000, 5000, 30_000];
19
20const MAX_RECONNECT_DELAY_MS = RECONNECT_DELAY_MS[RECONNECT_DELAY_MS.length - 1];
21
22const BACKGROUND_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
23
24const PING_TIMEOUT_MS = 10 * 1000;
25
26const REQUEST_TIMEOUT_MS = 1000;
27
28const log = getLogger('xtext.XtextWebSocketClient');
29
30export type ReconnectHandler = () => void;
31
32export type PushHandler = (
33 resourceId: string,
34 stateId: string,
35 service: string,
36 data: unknown,
37) => void;
38
39enum State {
40 Initial,
41 Opening,
42 TabVisible,
43 TabHiddenIdle,
44 TabHiddenWaiting,
45 Error,
46 TimedOut,
47}
48
49export class XtextWebSocketClient {
50 private nextMessageId = 0;
51
52 private connection!: WebSocket;
53
54 private readonly pendingRequests = new Map<string, PendingTask<unknown>>();
55
56 private readonly onReconnect: ReconnectHandler;
57
58 private readonly onPush: PushHandler;
59
60 private state = State.Initial;
61
62 private reconnectTryCount = 0;
63
64 private readonly idleTimer = new Timer(() => {
65 this.handleIdleTimeout();
66 }, BACKGROUND_IDLE_TIMEOUT_MS);
67
68 private readonly pingTimer = new Timer(() => {
69 this.sendPing();
70 }, PING_TIMEOUT_MS);
71
72 private readonly reconnectTimer = new Timer(() => {
73 this.handleReconnect();
74 });
75
76 constructor(onReconnect: ReconnectHandler, onPush: PushHandler) {
77 this.onReconnect = onReconnect;
78 this.onPush = onPush;
79 document.addEventListener('visibilitychange', () => {
80 this.handleVisibilityChange();
81 });
82 this.reconnect();
83 }
84
85 private get isLogicallyClosed(): boolean {
86 return this.state === State.Error || this.state === State.TimedOut;
87 }
88
89 get isOpen(): boolean {
90 return this.state === State.TabVisible
91 || this.state === State.TabHiddenIdle
92 || this.state === State.TabHiddenWaiting;
93 }
94
95 private reconnect() {
96 if (this.isOpen || this.state === State.Opening) {
97 log.error('Trying to reconnect from', this.state);
98 return;
99 }
100 this.state = State.Opening;
101 const webSocketServer = window.origin.replace(/^http/, 'ws');
102 const webSocketUrl = `${webSocketServer}/xtext-service`;
103 this.connection = new WebSocket(webSocketUrl, XTEXT_SUBPROTOCOL_V1);
104 this.connection.addEventListener('open', () => {
105 if (this.connection.protocol !== XTEXT_SUBPROTOCOL_V1) {
106 log.error('Unknown subprotocol', this.connection.protocol, 'selected by server');
107 this.forceReconnectOnError();
108 }
109 if (document.visibilityState === 'hidden') {
110 this.handleTabHidden();
111 } else {
112 this.handleTabVisibleConnected();
113 }
114 log.info('Connected to websocket');
115 this.nextMessageId = 0;
116 this.reconnectTryCount = 0;
117 this.pingTimer.schedule();
118 this.onReconnect();
119 });
120 this.connection.addEventListener('error', (event) => {
121 log.error('Unexpected websocket error', event);
122 this.forceReconnectOnError();
123 });
124 this.connection.addEventListener('message', (event) => {
125 this.handleMessage(event.data);
126 });
127 this.connection.addEventListener('close', (event) => {
128 if (this.isLogicallyClosed && event.code === WEBSOCKET_CLOSE_OK
129 && this.pendingRequests.size === 0) {
130 log.info('Websocket closed');
131 return;
132 }
133 log.error('Websocket closed unexpectedly', event.code, event.reason);
134 this.forceReconnectOnError();
135 });
136 }
137
138 private handleVisibilityChange() {
139 if (document.visibilityState === 'hidden') {
140 if (this.state === State.TabVisible) {
141 this.handleTabHidden();
142 }
143 return;
144 }
145 this.idleTimer.cancel();
146 if (this.state === State.TabHiddenIdle || this.state === State.TabHiddenWaiting) {
147 this.handleTabVisibleConnected();
148 return;
149 }
150 if (this.state === State.TimedOut) {
151 this.reconnect();
152 }
153 }
154
155 private handleTabHidden() {
156 log.debug('Tab hidden while websocket is connected');
157 this.state = State.TabHiddenIdle;
158 this.idleTimer.schedule();
159 }
160
161 private handleTabVisibleConnected() {
162 log.debug('Tab visible while websocket is connected');
163 this.state = State.TabVisible;
164 }
165
166 private handleIdleTimeout() {
167 log.trace('Waiting for pending tasks before disconnect');
168 if (this.state === State.TabHiddenIdle) {
169 this.state = State.TabHiddenWaiting;
170 this.handleWaitingForDisconnect();
171 }
172 }
173
174 private handleWaitingForDisconnect() {
175 if (this.state !== State.TabHiddenWaiting) {
176 return;
177 }
178 const pending = this.pendingRequests.size;
179 if (pending === 0) {
180 log.info('Closing idle websocket');
181 this.state = State.TimedOut;
182 this.closeConnection(1000, 'idle timeout');
183 return;
184 }
185 log.info('Waiting for', pending, 'pending requests before closing websocket');
186 }
187
188 private sendPing() {
189 if (!this.isOpen) {
190 return;
191 }
192 const ping = nanoid();
193 log.trace('Ping', ping);
194 this.send({ ping }).then((result) => {
195 if (isPongResult(result) && result.pong === ping) {
196 log.trace('Pong', ping);
197 this.pingTimer.schedule();
198 } else {
199 log.error('Invalid pong');
200 this.forceReconnectOnError();
201 }
202 }).catch((error) => {
203 log.error('Error while waiting for ping', error);
204 this.forceReconnectOnError();
205 });
206 }
207
208 send(request: unknown): Promise<unknown> {
209 if (!this.isOpen) {
210 throw new Error('Not open');
211 }
212 const messageId = this.nextMessageId.toString(16);
213 if (messageId in this.pendingRequests) {
214 log.error('Message id wraparound still pending', messageId);
215 this.rejectRequest(messageId, new Error('Message id wraparound'));
216 }
217 if (this.nextMessageId >= Number.MAX_SAFE_INTEGER) {
218 this.nextMessageId = 0;
219 } else {
220 this.nextMessageId += 1;
221 }
222 const message = JSON.stringify({
223 id: messageId,
224 request,
225 } as IXtextWebRequest);
226 log.trace('Sending message', message);
227 return new Promise((resolve, reject) => {
228 const task = new PendingTask(resolve, reject, REQUEST_TIMEOUT_MS, () => {
229 this.removePendingRequest(messageId);
230 });
231 this.pendingRequests.set(messageId, task);
232 this.connection.send(message);
233 });
234 }
235
236 private handleMessage(messageStr: unknown) {
237 if (typeof messageStr !== 'string') {
238 log.error('Unexpected binary message', messageStr);
239 this.forceReconnectOnError();
240 return;
241 }
242 log.trace('Incoming websocket message', messageStr);
243 let message: unknown;
244 try {
245 message = JSON.parse(messageStr);
246 } catch (error) {
247 log.error('Json parse error', error);
248 this.forceReconnectOnError();
249 return;
250 }
251 if (isOkResponse(message)) {
252 this.resolveRequest(message.id, message.response);
253 } else if (isErrorResponse(message)) {
254 this.rejectRequest(message.id, new Error(`${message.error} error: ${message.message}`));
255 if (message.error === 'server') {
256 log.error('Reconnecting due to server error: ', message.message);
257 this.forceReconnectOnError();
258 }
259 } else if (isPushMessage(message)) {
260 this.onPush(
261 message.resource,
262 message.stateId,
263 message.service,
264 message.push,
265 );
266 } else {
267 log.error('Unexpected websocket message', message);
268 this.forceReconnectOnError();
269 }
270 }
271
272 private resolveRequest(messageId: string, value: unknown) {
273 const pendingRequest = this.pendingRequests.get(messageId);
274 if (pendingRequest) {
275 pendingRequest.resolve(value);
276 this.removePendingRequest(messageId);
277 return;
278 }
279 log.error('Trying to resolve unknown request', messageId, 'with', value);
280 }
281
282 private rejectRequest(messageId: string, reason?: unknown) {
283 const pendingRequest = this.pendingRequests.get(messageId);
284 if (pendingRequest) {
285 pendingRequest.reject(reason);
286 this.removePendingRequest(messageId);
287 return;
288 }
289 log.error('Trying to reject unknown request', messageId, 'with', reason);
290 }
291
292 private removePendingRequest(messageId: string) {
293 this.pendingRequests.delete(messageId);
294 this.handleWaitingForDisconnect();
295 }
296
297 forceReconnectOnError(): void {
298 if (this.isLogicallyClosed) {
299 return;
300 }
301 this.abortPendingRequests();
302 this.closeConnection(1000, 'reconnecting due to error');
303 log.error('Reconnecting after delay due to error');
304 this.handleErrorState();
305 }
306
307 private abortPendingRequests() {
308 this.pendingRequests.forEach((request) => {
309 request.reject(new Error('Websocket disconnect'));
310 });
311 this.pendingRequests.clear();
312 }
313
314 private closeConnection(code: number, reason: string) {
315 this.pingTimer.cancel();
316 const { readyState } = this.connection;
317 if (readyState !== WebSocket.CLOSING && readyState !== WebSocket.CLOSED) {
318 this.connection.close(code, reason);
319 }
320 }
321
322 private handleErrorState() {
323 this.state = State.Error;
324 this.reconnectTryCount += 1;
325 const delay = RECONNECT_DELAY_MS[this.reconnectTryCount - 1] || MAX_RECONNECT_DELAY_MS;
326 log.info('Reconnecting in', delay, 'ms');
327 this.reconnectTimer.schedule(delay);
328 }
329
330 private handleReconnect() {
331 if (this.state !== State.Error) {
332 log.error('Unexpected reconnect in', this.state);
333 return;
334 }
335 if (document.visibilityState === 'hidden') {
336 this.state = State.TimedOut;
337 } else {
338 this.reconnect();
339 }
340 }
341}
diff --git a/language-web/src/main/js/xtext/compatibility.js b/language-web/src/main/js/xtext/compatibility.js
deleted file mode 100644
index c877fc56..00000000
--- a/language-web/src/main/js/xtext/compatibility.js
+++ /dev/null
@@ -1,63 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define([], function() {
11
12 if (!Function.prototype.bind) {
13 Function.prototype.bind = function(target) {
14 if (typeof this !== 'function')
15 throw new TypeError('bind target is not callable');
16 var args = Array.prototype.slice.call(arguments, 1);
17 var unboundFunc = this;
18 var nopFunc = function() {};
19 boundFunc = function() {
20 var localArgs = Array.prototype.slice.call(arguments);
21 return unboundFunc.apply(this instanceof nopFunc ? this : target,
22 args.concat(localArgs));
23 };
24 nopFunc.prototype = this.prototype;
25 boundFunc.prototype = new nopFunc();
26 return boundFunc;
27 }
28 }
29
30 if (!Array.prototype.map) {
31 Array.prototype.map = function(callback, thisArg) {
32 if (this == null)
33 throw new TypeError('this is null');
34 if (typeof callback !== 'function')
35 throw new TypeError('callback is not callable');
36 var srcArray = Object(this);
37 var len = srcArray.length >>> 0;
38 var tgtArray = new Array(len);
39 for (var i = 0; i < len; i++) {
40 if (i in srcArray)
41 tgtArray[i] = callback.call(thisArg, srcArray[i], i, srcArray);
42 }
43 return tgtArray;
44 }
45 }
46
47 if (!Array.prototype.forEach) {
48 Array.prototype.forEach = function(callback, thisArg) {
49 if (this == null)
50 throw new TypeError('this is null');
51 if (typeof callback !== 'function')
52 throw new TypeError('callback is not callable');
53 var srcArray = Object(this);
54 var len = srcArray.length >>> 0;
55 for (var i = 0; i < len; i++) {
56 if (i in srcArray)
57 callback.call(thisArg, srcArray[i], i, srcArray);
58 }
59 }
60 }
61
62 return {};
63});
diff --git a/language-web/src/main/js/xtext/services/ContentAssistService.js b/language-web/src/main/js/xtext/services/ContentAssistService.js
deleted file mode 100644
index 1686570d..00000000
--- a/language-web/src/main/js/xtext/services/ContentAssistService.js
+++ /dev/null
@@ -1,132 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for content assist proposals. The proposals are returned as promise of
14 * a Deferred object.
15 */
16 function ContentAssistService(serviceUrl, resourceId, updateService) {
17 this.initialize(serviceUrl, 'assist', resourceId, updateService);
18 }
19
20 ContentAssistService.prototype = new XtextService();
21
22 ContentAssistService.prototype.invoke = function(editorContext, params, deferred) {
23 if (deferred === undefined) {
24 deferred = jQuery.Deferred();
25 }
26 var serverData = {
27 contentType: params.contentType
28 };
29 if (params.offset)
30 serverData.caretOffset = params.offset;
31 else
32 serverData.caretOffset = editorContext.getCaretOffset();
33 var selection = params.selection ? params.selection : editorContext.getSelection();
34 if (selection.start != serverData.caretOffset || selection.end != serverData.caretOffset) {
35 serverData.selectionStart = selection.start;
36 serverData.selectionEnd = selection.end;
37 }
38 var currentText;
39 var httpMethod = 'GET';
40 var onComplete = undefined;
41 var knownServerState = editorContext.getServerState();
42 if (params.sendFullText) {
43 serverData.fullText = editorContext.getText();
44 httpMethod = 'POST';
45 } else {
46 serverData.requiredStateId = knownServerState.stateId;
47 if (this._updateService) {
48 if (knownServerState.text === undefined || knownServerState.updateInProgress) {
49 var self = this;
50 this._updateService.addCompletionCallback(function() {
51 self.invoke(editorContext, params, deferred);
52 });
53 return deferred.promise();
54 }
55 knownServerState.updateInProgress = true;
56 onComplete = this._updateService.onComplete.bind(this._updateService);
57 currentText = editorContext.getText();
58 this._updateService.computeDelta(knownServerState.text, currentText, serverData);
59 if (serverData.deltaText !== undefined) {
60 httpMethod = 'POST';
61 }
62 }
63 }
64
65 var self = this;
66 self.sendRequest(editorContext, {
67 type: httpMethod,
68 data: serverData,
69
70 success: function(result) {
71 if (result.conflict) {
72 // The server has lost its session state and the resource is loaded from the server
73 if (self._increaseRecursionCount(editorContext)) {
74 if (onComplete) {
75 delete knownServerState.updateInProgress;
76 delete knownServerState.text;
77 delete knownServerState.stateId;
78 self._updateService.addCompletionCallback(function() {
79 self.invoke(editorContext, params, deferred);
80 });
81 self._updateService.invoke(editorContext, params);
82 } else {
83 var paramsCopy = {};
84 for (var p in params) {
85 if (params.hasOwnProperty(p))
86 paramsCopy[p] = params[p];
87 }
88 paramsCopy.sendFullText = true;
89 self.invoke(editorContext, paramsCopy, deferred);
90 }
91 } else {
92 deferred.reject(result.conflict);
93 }
94 return false;
95 }
96 if (onComplete && result.stateId !== undefined && result.stateId != editorContext.getServerState().stateId) {
97 var listeners = editorContext.updateServerState(currentText, result.stateId);
98 for (var i = 0; i < listeners.length; i++) {
99 self._updateService.addCompletionCallback(listeners[i], params);
100 }
101 }
102 deferred.resolve(result.entries);
103 },
104
105 error: function(xhr, textStatus, errorThrown) {
106 if (onComplete && xhr.status == 404 && !params.loadFromServer && knownServerState.text !== undefined) {
107 // The server has lost its session state and the resource is not loaded from the server
108 delete knownServerState.updateInProgress;
109 delete knownServerState.text;
110 delete knownServerState.stateId;
111 self._updateService.addCompletionCallback(function() {
112 self.invoke(editorContext, params, deferred);
113 });
114 self._updateService.invoke(editorContext, params);
115 return true;
116 }
117 deferred.reject(errorThrown);
118 },
119
120 complete: onComplete
121 }, !params.sendFullText);
122 var result = deferred.promise();
123 if (onComplete) {
124 result.always(function() {
125 knownServerState.updateInProgress = false;
126 });
127 }
128 return result;
129 };
130
131 return ContentAssistService;
132});
diff --git a/language-web/src/main/js/xtext/services/FormattingService.js b/language-web/src/main/js/xtext/services/FormattingService.js
deleted file mode 100644
index f59099ee..00000000
--- a/language-web/src/main/js/xtext/services/FormattingService.js
+++ /dev/null
@@ -1,52 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for formatting text.
14 */
15 function FormattingService(serviceUrl, resourceId, updateService) {
16 this.initialize(serviceUrl, 'format', resourceId, updateService);
17 };
18
19 FormattingService.prototype = new XtextService();
20
21 FormattingService.prototype._initServerData = function(serverData, editorContext, params) {
22 var selection = params.selection ? params.selection : editorContext.getSelection();
23 if (selection.end > selection.start) {
24 serverData.selectionStart = selection.start;
25 serverData.selectionEnd = selection.end;
26 }
27 return {
28 httpMethod: 'POST'
29 };
30 };
31
32 FormattingService.prototype._processResult = function(result, editorContext) {
33 // The text update may be asynchronous, so we have to compute the new text ourselves
34 var newText;
35 if (result.replaceRegion) {
36 var fullText = editorContext.getText();
37 var start = result.replaceRegion.offset;
38 var end = result.replaceRegion.offset + result.replaceRegion.length;
39 editorContext.setText(result.formattedText, start, end);
40 newText = fullText.substring(0, start) + result.formattedText + fullText.substring(end);
41 } else {
42 editorContext.setText(result.formattedText);
43 newText = result.formattedText;
44 }
45 var listeners = editorContext.updateServerState(newText, result.stateId);
46 for (var i = 0; i < listeners.length; i++) {
47 listeners[i]({});
48 }
49 };
50
51 return FormattingService;
52}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/HighlightingService.js b/language-web/src/main/js/xtext/services/HighlightingService.js
deleted file mode 100644
index 5a5ac8ba..00000000
--- a/language-web/src/main/js/xtext/services/HighlightingService.js
+++ /dev/null
@@ -1,33 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for semantic highlighting.
14 */
15 function HighlightingService(serviceUrl, resourceId) {
16 this.initialize(serviceUrl, 'highlight', resourceId);
17 };
18
19 HighlightingService.prototype = new XtextService();
20
21 HighlightingService.prototype._checkPreconditions = function(editorContext, params) {
22 return this._state === undefined;
23 }
24
25 HighlightingService.prototype._onConflict = function(editorContext, cause) {
26 this.setState(undefined);
27 return {
28 suppressForcedUpdate: true
29 };
30 };
31
32 return HighlightingService;
33}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/HoverService.js b/language-web/src/main/js/xtext/services/HoverService.js
deleted file mode 100644
index 03c5a52b..00000000
--- a/language-web/src/main/js/xtext/services/HoverService.js
+++ /dev/null
@@ -1,59 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for hover information.
14 */
15 function HoverService(serviceUrl, resourceId, updateService) {
16 this.initialize(serviceUrl, 'hover', resourceId, updateService);
17 };
18
19 HoverService.prototype = new XtextService();
20
21 HoverService.prototype._initServerData = function(serverData, editorContext, params) {
22 // In order to display hover info for a selected completion proposal while the content
23 // assist popup is shown, the selected proposal is passed as parameter
24 if (params.proposal && params.proposal.proposal)
25 serverData.proposal = params.proposal.proposal;
26 if (params.offset)
27 serverData.caretOffset = params.offset;
28 else
29 serverData.caretOffset = editorContext.getCaretOffset();
30 var selection = params.selection ? params.selection : editorContext.getSelection();
31 if (selection.start != serverData.caretOffset || selection.end != serverData.caretOffset) {
32 serverData.selectionStart = selection.start;
33 serverData.selectionEnd = selection.end;
34 }
35 };
36
37 HoverService.prototype._getSuccessCallback = function(editorContext, params, deferred) {
38 var delay = params.mouseHoverDelay;
39 if (!delay)
40 delay = 500;
41 var showTime = new Date().getTime() + delay;
42 return function(result) {
43 if (result.conflict || !result.title && !result.content) {
44 deferred.reject();
45 } else {
46 var remainingTimeout = Math.max(0, showTime - new Date().getTime());
47 setTimeout(function() {
48 if (!params.sendFullText && result.stateId !== undefined
49 && result.stateId != editorContext.getServerState().stateId)
50 deferred.reject();
51 else
52 deferred.resolve(result);
53 }, remainingTimeout);
54 }
55 };
56 };
57
58 return HoverService;
59}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/LoadResourceService.js b/language-web/src/main/js/xtext/services/LoadResourceService.js
deleted file mode 100644
index b5a315c3..00000000
--- a/language-web/src/main/js/xtext/services/LoadResourceService.js
+++ /dev/null
@@ -1,42 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for loading resources. The resulting text is passed to the editor context.
14 */
15 function LoadResourceService(serviceUrl, resourceId, revert) {
16 this.initialize(serviceUrl, revert ? 'revert' : 'load', resourceId);
17 };
18
19 LoadResourceService.prototype = new XtextService();
20
21 LoadResourceService.prototype._initServerData = function(serverData, editorContext, params) {
22 return {
23 suppressContent: true,
24 httpMethod: this._serviceType == 'revert' ? 'POST' : 'GET'
25 };
26 };
27
28 LoadResourceService.prototype._getSuccessCallback = function(editorContext, params, deferred) {
29 return function(result) {
30 editorContext.setText(result.fullText);
31 editorContext.clearUndoStack();
32 editorContext.setDirty(result.dirty);
33 var listeners = editorContext.updateServerState(result.fullText, result.stateId);
34 for (var i = 0; i < listeners.length; i++) {
35 listeners[i](params);
36 }
37 deferred.resolve(result);
38 }
39 }
40
41 return LoadResourceService;
42}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/OccurrencesService.js b/language-web/src/main/js/xtext/services/OccurrencesService.js
deleted file mode 100644
index 2e2d0b1a..00000000
--- a/language-web/src/main/js/xtext/services/OccurrencesService.js
+++ /dev/null
@@ -1,39 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for marking occurrences.
14 */
15 function OccurrencesService(serviceUrl, resourceId, updateService) {
16 this.initialize(serviceUrl, 'occurrences', resourceId, updateService);
17 };
18
19 OccurrencesService.prototype = new XtextService();
20
21 OccurrencesService.prototype._initServerData = function(serverData, editorContext, params) {
22 if (params.offset)
23 serverData.caretOffset = params.offset;
24 else
25 serverData.caretOffset = editorContext.getCaretOffset();
26 };
27
28 OccurrencesService.prototype._getSuccessCallback = function(editorContext, params, deferred) {
29 return function(result) {
30 if (result.conflict || !params.sendFullText && result.stateId !== undefined
31 && result.stateId != editorContext.getServerState().stateId)
32 deferred.reject();
33 else
34 deferred.resolve(result);
35 }
36 }
37
38 return OccurrencesService;
39}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/SaveResourceService.js b/language-web/src/main/js/xtext/services/SaveResourceService.js
deleted file mode 100644
index 66cdaff5..00000000
--- a/language-web/src/main/js/xtext/services/SaveResourceService.js
+++ /dev/null
@@ -1,32 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for saving resources.
14 */
15 function SaveResourceService(serviceUrl, resourceId) {
16 this.initialize(serviceUrl, 'save', resourceId);
17 };
18
19 SaveResourceService.prototype = new XtextService();
20
21 SaveResourceService.prototype._initServerData = function(serverData, editorContext, params) {
22 return {
23 httpMethod: 'POST'
24 };
25 };
26
27 SaveResourceService.prototype._processResult = function(result, editorContext) {
28 editorContext.setDirty(false);
29 };
30
31 return SaveResourceService;
32}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/UpdateService.js b/language-web/src/main/js/xtext/services/UpdateService.js
deleted file mode 100644
index b78d846d..00000000
--- a/language-web/src/main/js/xtext/services/UpdateService.js
+++ /dev/null
@@ -1,159 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for updating the server-side representation of a resource.
14 * This service only makes sense with a stateful server, where an update request is sent
15 * after each modification. This can greatly improve response times compared to the
16 * stateless alternative, where the full text content is sent with each service request.
17 */
18 function UpdateService(serviceUrl, resourceId) {
19 this.initialize(serviceUrl, 'update', resourceId, this);
20 this._completionCallbacks = [];
21 };
22
23 UpdateService.prototype = new XtextService();
24
25 /**
26 * Compute a delta between two versions of a text. If a difference is found, the result
27 * contains three properties:
28 * deltaText - the text to insert into s1
29 * deltaOffset - the text insertion offset
30 * deltaReplaceLength - the number of characters that shall be replaced by the inserted text
31 */
32 UpdateService.prototype.computeDelta = function(s1, s2, result) {
33 var start = 0, s1length = s1.length, s2length = s2.length;
34 while (start < s1length && start < s2length && s1.charCodeAt(start) === s2.charCodeAt(start)) {
35 start++;
36 }
37 if (start === s1length && start === s2length) {
38 return;
39 }
40 result.deltaOffset = start;
41 if (start === s1length) {
42 result.deltaText = s2.substring(start, s2length);
43 result.deltaReplaceLength = 0;
44 return;
45 } else if (start === s2length) {
46 result.deltaText = '';
47 result.deltaReplaceLength = s1length - start;
48 return;
49 }
50
51 var end1 = s1length - 1, end2 = s2length - 1;
52 while (end1 >= start && end2 >= start && s1.charCodeAt(end1) === s2.charCodeAt(end2)) {
53 end1--;
54 end2--;
55 }
56 result.deltaText = s2.substring(start, end2 + 1);
57 result.deltaReplaceLength = end1 - start + 1;
58 };
59
60 /**
61 * Invoke all completion callbacks and clear the list afterwards.
62 */
63 UpdateService.prototype.onComplete = function(xhr, textStatus) {
64 var callbacks = this._completionCallbacks;
65 this._completionCallbacks = [];
66 for (var i = 0; i < callbacks.length; i++) {
67 var callback = callbacks[i].callback;
68 var params = callbacks[i].params;
69 callback(params);
70 }
71 }
72
73 /**
74 * Add a callback to be invoked when the service call has completed.
75 */
76 UpdateService.prototype.addCompletionCallback = function(callback, params) {
77 this._completionCallbacks.push({callback: callback, params: params});
78 }
79
80 UpdateService.prototype.invoke = function(editorContext, params, deferred) {
81 if (deferred === undefined) {
82 deferred = jQuery.Deferred();
83 }
84 var knownServerState = editorContext.getServerState();
85 if (knownServerState.updateInProgress) {
86 var self = this;
87 this.addCompletionCallback(function() { self.invoke(editorContext, params, deferred) });
88 return deferred.promise();
89 }
90
91 var serverData = {
92 contentType: params.contentType
93 };
94 var currentText = editorContext.getText();
95 if (params.sendFullText || knownServerState.text === undefined) {
96 serverData.fullText = currentText;
97 } else {
98 this.computeDelta(knownServerState.text, currentText, serverData);
99 if (serverData.deltaText === undefined) {
100 if (params.forceUpdate) {
101 serverData.deltaText = '';
102 serverData.deltaOffset = editorContext.getCaretOffset();
103 serverData.deltaReplaceLength = 0;
104 } else {
105 deferred.resolve(knownServerState);
106 this.onComplete();
107 return deferred.promise();
108 }
109 }
110 serverData.requiredStateId = knownServerState.stateId;
111 }
112
113 knownServerState.updateInProgress = true;
114 var self = this;
115 self.sendRequest(editorContext, {
116 type: 'PUT',
117 data: serverData,
118
119 success: function(result) {
120 if (result.conflict) {
121 // The server has lost its session state and the resource is loaded from the server
122 if (knownServerState.text !== undefined) {
123 delete knownServerState.updateInProgress;
124 delete knownServerState.text;
125 delete knownServerState.stateId;
126 self.invoke(editorContext, params, deferred);
127 } else {
128 deferred.reject(result.conflict);
129 }
130 return false;
131 }
132 var listeners = editorContext.updateServerState(currentText, result.stateId);
133 for (var i = 0; i < listeners.length; i++) {
134 self.addCompletionCallback(listeners[i], params);
135 }
136 deferred.resolve(result);
137 },
138
139 error: function(xhr, textStatus, errorThrown) {
140 if (xhr.status == 404 && !params.loadFromServer && knownServerState.text !== undefined) {
141 // The server has lost its session state and the resource is not loaded from the server
142 delete knownServerState.updateInProgress;
143 delete knownServerState.text;
144 delete knownServerState.stateId;
145 self.invoke(editorContext, params, deferred);
146 return true;
147 }
148 deferred.reject(errorThrown);
149 },
150
151 complete: self.onComplete.bind(self)
152 }, true);
153 return deferred.promise().always(function() {
154 knownServerState.updateInProgress = false;
155 });
156 };
157
158 return UpdateService;
159}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/ValidationService.js b/language-web/src/main/js/xtext/services/ValidationService.js
deleted file mode 100644
index 85c9953d..00000000
--- a/language-web/src/main/js/xtext/services/ValidationService.js
+++ /dev/null
@@ -1,33 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['xtext/services/XtextService', 'jquery'], function(XtextService, jQuery) {
11
12 /**
13 * Service class for validation.
14 */
15 function ValidationService(serviceUrl, resourceId) {
16 this.initialize(serviceUrl, 'validate', resourceId);
17 };
18
19 ValidationService.prototype = new XtextService();
20
21 ValidationService.prototype._checkPreconditions = function(editorContext, params) {
22 return this._state === undefined;
23 }
24
25 ValidationService.prototype._onConflict = function(editorContext, cause) {
26 this.setState(undefined);
27 return {
28 suppressForcedUpdate: true
29 };
30 };
31
32 return ValidationService;
33}); \ No newline at end of file
diff --git a/language-web/src/main/js/xtext/services/XtextService.js b/language-web/src/main/js/xtext/services/XtextService.js
deleted file mode 100644
index d3a4842f..00000000
--- a/language-web/src/main/js/xtext/services/XtextService.js
+++ /dev/null
@@ -1,280 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015, 2017 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10define(['jquery'], function(jQuery) {
11
12 var globalState = {};
13
14 /**
15 * Generic service implementation that can serve as superclass for specialized services.
16 */
17 function XtextService() {};
18
19 /**
20 * Initialize the request metadata for this service class. Two variants:
21 * - initialize(serviceUrl, serviceType, resourceId, updateService)
22 * - initialize(xtextServices, serviceType)
23 */
24 XtextService.prototype.initialize = function() {
25 this._serviceType = arguments[1];
26 if (typeof(arguments[0]) === 'string') {
27 this._requestUrl = arguments[0] + '/' + this._serviceType;
28 var resourceId = arguments[2];
29 if (resourceId)
30 this._encodedResourceId = encodeURIComponent(resourceId);
31 this._updateService = arguments[3];
32 } else {
33 var xtextServices = arguments[0];
34 if (xtextServices.options) {
35 this._requestUrl = xtextServices.options.serviceUrl + '/' + this._serviceType;
36 var resourceId = xtextServices.options.resourceId;
37 if (resourceId)
38 this._encodedResourceId = encodeURIComponent(resourceId);
39 }
40 this._updateService = xtextServices.updateService;
41 }
42 }
43
44 XtextService.prototype.setState = function(state) {
45 this._state = state;
46 }
47
48 /**
49 * Invoke the service with default service behavior.
50 */
51 XtextService.prototype.invoke = function(editorContext, params, deferred, callbacks) {
52 if (deferred === undefined) {
53 deferred = jQuery.Deferred();
54 }
55 if (jQuery.isFunction(this._checkPreconditions) && !this._checkPreconditions(editorContext, params)) {
56 deferred.reject();
57 return deferred.promise();
58 }
59 var serverData = {
60 contentType: params.contentType
61 };
62 var initResult;
63 if (jQuery.isFunction(this._initServerData))
64 initResult = this._initServerData(serverData, editorContext, params);
65 var httpMethod = 'GET';
66 if (initResult && initResult.httpMethod)
67 httpMethod = initResult.httpMethod;
68 var self = this;
69 if (!(initResult && initResult.suppressContent)) {
70 if (params.sendFullText) {
71 serverData.fullText = editorContext.getText();
72 httpMethod = 'POST';
73 } else {
74 var knownServerState = editorContext.getServerState();
75 if (knownServerState.updateInProgress) {
76 if (self._updateService) {
77 self._updateService.addCompletionCallback(function() {
78 self.invoke(editorContext, params, deferred);
79 });
80 } else {
81 deferred.reject();
82 }
83 return deferred.promise();
84 }
85 if (knownServerState.stateId !== undefined) {
86 serverData.requiredStateId = knownServerState.stateId;
87 }
88 }
89 }
90
91 var onSuccess;
92 if (jQuery.isFunction(this._getSuccessCallback)) {
93 onSuccess = this._getSuccessCallback(editorContext, params, deferred);
94 } else {
95 onSuccess = function(result) {
96 if (result.conflict) {
97 if (self._increaseRecursionCount(editorContext)) {
98 var onConflictResult;
99 if (jQuery.isFunction(self._onConflict)) {
100 onConflictResult = self._onConflict(editorContext, result.conflict);
101 }
102 if (!(onConflictResult && onConflictResult.suppressForcedUpdate) && !params.sendFullText
103 && result.conflict == 'invalidStateId' && self._updateService) {
104 self._updateService.addCompletionCallback(function() {
105 self.invoke(editorContext, params, deferred);
106 });
107 var knownServerState = editorContext.getServerState();
108 delete knownServerState.stateId;
109 delete knownServerState.text;
110 self._updateService.invoke(editorContext, params);
111 } else {
112 self.invoke(editorContext, params, deferred);
113 }
114 } else {
115 deferred.reject();
116 }
117 return false;
118 }
119 if (jQuery.isFunction(self._processResult)) {
120 var processedResult = self._processResult(result, editorContext);
121 if (processedResult) {
122 deferred.resolve(processedResult);
123 return true;
124 }
125 }
126 deferred.resolve(result);
127 };
128 }
129
130 var onError = function(xhr, textStatus, errorThrown) {
131 if (xhr.status == 404 && !params.loadFromServer && self._increaseRecursionCount(editorContext)) {
132 var onConflictResult;
133 if (jQuery.isFunction(self._onConflict)) {
134 onConflictResult = self._onConflict(editorContext, errorThrown);
135 }
136 var knownServerState = editorContext.getServerState();
137 if (!(onConflictResult && onConflictResult.suppressForcedUpdate)
138 && knownServerState.text !== undefined && self._updateService) {
139 self._updateService.addCompletionCallback(function() {
140 self.invoke(editorContext, params, deferred);
141 });
142 delete knownServerState.stateId;
143 delete knownServerState.text;
144 self._updateService.invoke(editorContext, params);
145 return true;
146 }
147 }
148 deferred.reject(errorThrown);
149 }
150
151 self.sendRequest(editorContext, {
152 type: httpMethod,
153 data: serverData,
154 success: onSuccess,
155 error: onError
156 }, !params.sendFullText);
157 return deferred.promise().always(function() {
158 self._recursionCount = undefined;
159 });
160 }
161
162 /**
163 * Send an HTTP request to invoke the service.
164 */
165 XtextService.prototype.sendRequest = function(editorContext, settings, needsSession) {
166 var self = this;
167 self.setState('started');
168 var corsEnabled = editorContext.xtextServices.options['enableCors'];
169 if(corsEnabled) {
170 settings.crossDomain = true;
171 settings.xhrFields = {withCredentials: true};
172 }
173 var onSuccess = settings.success;
174 settings.success = function(result) {
175 var accepted = true;
176 if (jQuery.isFunction(onSuccess)) {
177 accepted = onSuccess(result);
178 }
179 if (accepted || accepted === undefined) {
180 self.setState('finished');
181 if (editorContext.xtextServices) {
182 var successListeners = editorContext.xtextServices.successListeners;
183 if (successListeners) {
184 for (var i = 0; i < successListeners.length; i++) {
185 var listener = successListeners[i];
186 if (jQuery.isFunction(listener)) {
187 listener(self._serviceType, result);
188 }
189 }
190 }
191 }
192 }
193 };
194
195 var onError = settings.error;
196 settings.error = function(xhr, textStatus, errorThrown) {
197 var resolved = false;
198 if (jQuery.isFunction(onError)) {
199 resolved = onError(xhr, textStatus, errorThrown);
200 }
201 if (!resolved) {
202 self.setState(undefined);
203 self._reportError(editorContext, textStatus, errorThrown, xhr);
204 }
205 };
206
207 settings.async = true;
208 var requestUrl = self._requestUrl;
209 if (!settings.data.resource && self._encodedResourceId) {
210 if (requestUrl.indexOf('?') >= 0)
211 requestUrl += '&resource=' + self._encodedResourceId;
212 else
213 requestUrl += '?resource=' + self._encodedResourceId;
214 }
215
216 if (needsSession && globalState._initPending) {
217 // We have to wait until the initial request has finished to make sure the client has
218 // received a valid session id
219 if (!globalState._waitingRequests)
220 globalState._waitingRequests = [];
221 globalState._waitingRequests.push({requestUrl: requestUrl, settings: settings});
222 } else {
223 if (needsSession && !globalState._initDone) {
224 globalState._initPending = true;
225 var onComplete = settings.complete;
226 settings.complete = function(xhr, textStatus) {
227 if (jQuery.isFunction(onComplete)) {
228 onComplete(xhr, textStatus);
229 }
230 delete globalState._initPending;
231 globalState._initDone = true;
232 if (globalState._waitingRequests) {
233 for (var i = 0; i < globalState._waitingRequests.length; i++) {
234 var request = globalState._waitingRequests[i];
235 jQuery.ajax(request.requestUrl, request.settings);
236 }
237 delete globalState._waitingRequests;
238 }
239 }
240 }
241 jQuery.ajax(requestUrl, settings);
242 }
243 }
244
245 /**
246 * Use this in case of a conflict before retrying the service invocation. If the number
247 * of retries exceeds the limit, an error is reported and the function returns false.
248 */
249 XtextService.prototype._increaseRecursionCount = function(editorContext) {
250 if (this._recursionCount === undefined)
251 this._recursionCount = 1;
252 else
253 this._recursionCount++;
254
255 if (this._recursionCount >= 10) {
256 this._reportError(editorContext, 'warning', 'Xtext service request failed after 10 attempts.', {});
257 return false;
258 }
259 return true;
260 },
261
262 /**
263 * Report an error to the listeners.
264 */
265 XtextService.prototype._reportError = function(editorContext, severity, message, requestData) {
266 if (editorContext.xtextServices) {
267 var errorListeners = editorContext.xtextServices.errorListeners;
268 if (errorListeners) {
269 for (var i = 0; i < errorListeners.length; i++) {
270 var listener = errorListeners[i];
271 if (jQuery.isFunction(listener)) {
272 listener(this._serviceType, severity, message, requestData);
273 }
274 }
275 }
276 }
277 }
278
279 return XtextService;
280});
diff --git a/language-web/src/main/js/xtext/xtext-codemirror.d.ts b/language-web/src/main/js/xtext/xtext-codemirror.d.ts
deleted file mode 100644
index fff850b8..00000000
--- a/language-web/src/main/js/xtext/xtext-codemirror.d.ts
+++ /dev/null
@@ -1,43 +0,0 @@
1import { Editor } from 'codemirror';
2
3export function createEditor(options: IXtextOptions): IXtextCodeMirrorEditor;
4
5export function createServices(editor: Editor, options: IXtextOptions): IXtextServices;
6
7export function removeServices(editor: Editor): void;
8
9export interface IXtextOptions {
10 baseUrl?: string;
11 contentType?: string;
12 dirtyElement?: string | Element;
13 dirtyStatusClass?: string;
14 document?: Document;
15 enableContentAssistService?: boolean;
16 enableCors?: boolean;
17 enableFormattingAction?: boolean;
18 enableFormattingService?: boolean;
19 enableGeneratorService?: boolean;
20 enableHighlightingService?: boolean;
21 enableOccurrencesService?: boolean;
22 enableSaveAction?: boolean;
23 enableValidationService?: boolean;
24 loadFromServer?: boolean;
25 mode?: string;
26 parent?: string | Element;
27 parentClass?: string;
28 resourceId?: string;
29 selectionUpdateDelay?: number;
30 sendFullText?: boolean;
31 serviceUrl?: string;
32 showErrorDialogs?: boolean;
33 syntaxDefinition?: string;
34 textUpdateDelay?: number;
35 xtextLang?: string;
36}
37
38export interface IXtextCodeMirrorEditor extends Editor {
39 xtextServices: IXtextServices;
40}
41
42export interface IXtextServices {
43}
diff --git a/language-web/src/main/js/xtext/xtext-codemirror.js b/language-web/src/main/js/xtext/xtext-codemirror.js
deleted file mode 100644
index d246172a..00000000
--- a/language-web/src/main/js/xtext/xtext-codemirror.js
+++ /dev/null
@@ -1,473 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015, 2017 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10/*
11 * Use `createEditor(options)` to create an Xtext editor. You can specify options either
12 * through the function parameter or through `data-editor-x` attributes, where x is an
13 * option name with camelCase converted to hyphen-separated.
14 * In addition to the options supported by CodeMirror (https://codemirror.net/doc/manual.html#config),
15 * the following options are available:
16 *
17 * baseUrl = "/" {String}
18 * The path segment where the Xtext service is found; see serviceUrl option.
19 * contentType {String}
20 * The content type included in requests to the Xtext server.
21 * dirtyElement {String | DOMElement}
22 * An element into which the dirty status class is written when the editor is marked dirty;
23 * it can be either a DOM element or an ID for a DOM element.
24 * dirtyStatusClass = 'dirty' {String}
25 * A CSS class name written into the dirtyElement when the editor is marked dirty.
26 * document {Document}
27 * The document; if not specified, the global document is used.
28 * enableContentAssistService = true {Boolean}
29 * Whether content assist should be enabled.
30 * enableCors = true {Boolean}
31 * Whether CORS should be enabled for service request.
32 * enableFormattingAction = false {Boolean}
33 * Whether the formatting action should be bound to the standard keystroke ctrl+shift+s / cmd+shift+f.
34 * enableFormattingService = true {Boolean}
35 * Whether text formatting should be enabled.
36 * enableGeneratorService = true {Boolean}
37 * Whether code generation should be enabled (must be triggered through JavaScript code).
38 * enableHighlightingService = true {Boolean}
39 * Whether semantic highlighting (computed on the server) should be enabled.
40 * enableOccurrencesService = true {Boolean}
41 * Whether marking occurrences should be enabled.
42 * enableSaveAction = false {Boolean}
43 * Whether the save action should be bound to the standard keystroke ctrl+s / cmd+s.
44 * enableValidationService = true {Boolean}
45 * Whether validation should be enabled.
46 * loadFromServer = true {Boolean}
47 * Whether to load the editor content from the server.
48 * mode {String}
49 * The name of the syntax highlighting mode to use; the mode has to be registered externally
50 * (see CodeMirror documentation).
51 * parent = 'xtext-editor' {String | DOMElement}
52 * The parent element for the view; it can be either a DOM element or an ID for a DOM element.
53 * parentClass = 'xtext-editor' {String}
54 * If the 'parent' option is not given, this option is used to find elements that match the given class name.
55 * resourceId {String}
56 * The identifier of the resource displayed in the text editor; this option is sent to the server to
57 * communicate required information on the respective resource.
58 * selectionUpdateDelay = 550 {Number}
59 * The number of milliseconds to wait after a selection change before Xtext services are invoked.
60 * sendFullText = false {Boolean}
61 * Whether the full text shall be sent to the server with each request; use this if you want
62 * the server to run in stateless mode. If the option is inactive, the server state is updated regularly.
63 * serviceUrl {String}
64 * The URL of the Xtext servlet; if no value is given, it is constructed using the baseUrl option in the form
65 * {location.protocol}//{location.host}{baseUrl}xtext-service
66 * showErrorDialogs = false {Boolean}
67 * Whether errors should be displayed in popup dialogs.
68 * syntaxDefinition {String}
69 * If the 'mode' option is not set, the default mode 'xtext/{xtextLang}' is used. Set this option to
70 * 'none' to suppress this behavior and disable syntax highlighting.
71 * textUpdateDelay = 500 {Number}
72 * The number of milliseconds to wait after a text change before Xtext services are invoked.
73 * xtextLang {String}
74 * The language name (usually the file extension configured for the language).
75 */
76define([
77 'jquery',
78 'codemirror',
79 'codemirror/addon/hint/show-hint',
80 'xtext/compatibility',
81 'xtext/ServiceBuilder',
82 'xtext/CodeMirrorEditorContext',
83 'codemirror/mode/javascript/javascript'
84], function(jQuery, CodeMirror, ShowHint, compatibility, ServiceBuilder, EditorContext) {
85
86 var exports = {};
87
88 /**
89 * Create one or more Xtext editor instances configured with the given options.
90 * The return value is either a CodeMirror editor or an array of CodeMirror editors.
91 */
92 exports.createEditor = function(options) {
93 if (!options)
94 options = {};
95
96 var query;
97 if (jQuery.type(options.parent) === 'string') {
98 query = jQuery('#' + options.parent, options.document);
99 } else if (options.parent) {
100 query = jQuery(options.parent);
101 } else if (jQuery.type(options.parentClass) === 'string') {
102 query = jQuery('.' + options.parentClass, options.document);
103 } else {
104 query = jQuery('#xtext-editor', options.document);
105 if (query.length == 0)
106 query = jQuery('.xtext-editor', options.document);
107 }
108
109 var editors = [];
110 query.each(function(index, parent) {
111 var editorOptions = ServiceBuilder.mergeParentOptions(parent, options);
112 if (!editorOptions.value)
113 editorOptions.value = jQuery(parent).text();
114 var editor = CodeMirror(function(element) {
115 jQuery(parent).empty().append(element);
116 }, editorOptions);
117
118 exports.createServices(editor, editorOptions);
119 editors[index] = editor;
120 });
121
122 if (editors.length == 1)
123 return editors[0];
124 else
125 return editors;
126 }
127
128 function CodeMirrorServiceBuilder(editor, xtextServices) {
129 this.editor = editor;
130 xtextServices.editorContext._highlightingMarkers = [];
131 xtextServices.editorContext._validationMarkers = [];
132 xtextServices.editorContext._occurrenceMarkers = [];
133 ServiceBuilder.call(this, xtextServices);
134 }
135 CodeMirrorServiceBuilder.prototype = new ServiceBuilder();
136
137 /**
138 * Configure Xtext services for the given editor. The editor does not have to be created
139 * with createEditor(options).
140 */
141 exports.createServices = function(editor, options) {
142 if (options.enableValidationService || options.enableValidationService === undefined) {
143 editor.setOption('gutters', ['annotations-gutter']);
144 }
145 var xtextServices = {
146 options: options,
147 editorContext: new EditorContext(editor)
148 };
149 var serviceBuilder = new CodeMirrorServiceBuilder(editor, xtextServices);
150 serviceBuilder.createServices();
151 xtextServices.serviceBuilder = serviceBuilder;
152 editor.xtextServices = xtextServices;
153 return xtextServices;
154 }
155
156 /**
157 * Remove all services and listeners that have been previously created with createServices(editor, options).
158 */
159 exports.removeServices = function(editor) {
160 if (!editor.xtextServices)
161 return;
162 var services = editor.xtextServices;
163 if (services.modelChangeListener)
164 editor.off('changes', services.modelChangeListener);
165 if (services.cursorActivityListener)
166 editor.off('cursorActivity', services.cursorActivityListener);
167 if (services.saveKeyMap)
168 editor.removeKeyMap(services.saveKeyMap);
169 if (services.contentAssistKeyMap)
170 editor.removeKeyMap(services.contentAssistKeyMap);
171 if (services.formatKeyMap)
172 editor.removeKeyMap(services.formatKeyMap);
173 var editorContext = services.editorContext;
174 var highlightingMarkers = editorContext._highlightingMarkers;
175 if (highlightingMarkers) {
176 for (var i = 0; i < highlightingMarkers.length; i++) {
177 highlightingMarkers[i].clear();
178 }
179 }
180 if (editorContext._validationAnnotations)
181 services.serviceBuilder._clearAnnotations(editorContext._validationAnnotations);
182 var validationMarkers = editorContext._validationMarkers;
183 if (validationMarkers) {
184 for (var i = 0; i < validationMarkers.length; i++) {
185 validationMarkers[i].clear();
186 }
187 }
188 var occurrenceMarkers = editorContext._occurrenceMarkers;
189 if (occurrenceMarkers) {
190 for (var i = 0; i < occurrenceMarkers.length; i++)  {
191 occurrenceMarkers[i].clear();
192 }
193 }
194 delete editor.xtextServices;
195 }
196
197 /**
198 * Syntax highlighting (without semantic highlighting).
199 */
200 CodeMirrorServiceBuilder.prototype.setupSyntaxHighlighting = function() {
201 var options = this.services.options;
202 // If the mode option is set, syntax highlighting has already been configured by CM
203 if (!options.mode && options.syntaxDefinition != 'none' && options.xtextLang) {
204 this.editor.setOption('mode', 'xtext/' + options.xtextLang);
205 }
206 }
207
208 /**
209 * Document update service.
210 */
211 CodeMirrorServiceBuilder.prototype.setupUpdateService = function(refreshDocument) {
212 var services = this.services;
213 var editorContext = services.editorContext;
214 var textUpdateDelay = services.options.textUpdateDelay;
215 if (!textUpdateDelay)
216 textUpdateDelay = 500;
217 services.modelChangeListener = function(event) {
218 if (!event._xtext_init)
219 editorContext.setDirty(true);
220 if (editorContext._modelChangeTimeout)
221 clearTimeout(editorContext._modelChangeTimeout);
222 editorContext._modelChangeTimeout = setTimeout(function() {
223 if (services.options.sendFullText)
224 refreshDocument();
225 else
226 services.update();
227 }, textUpdateDelay);
228 }
229 if (!services.options.resourceId || !services.options.loadFromServer)
230 services.modelChangeListener({_xtext_init: true});
231 this.editor.on('changes', services.modelChangeListener);
232 }
233
234 /**
235 * Persistence services: load, save, and revert.
236 */
237 CodeMirrorServiceBuilder.prototype.setupPersistenceServices = function() {
238 var services = this.services;
239 if (services.options.enableSaveAction) {
240 var userAgent = navigator.userAgent.toLowerCase();
241 var saveFunction = function(editor) {
242 services.saveResource();
243 };
244 services.saveKeyMap = /mac os/.test(userAgent) ? {'Cmd-S': saveFunction}: {'Ctrl-S': saveFunction};
245 this.editor.addKeyMap(services.saveKeyMap);
246 }
247 }
248
249 /**
250 * Content assist service.
251 */
252 CodeMirrorServiceBuilder.prototype.setupContentAssistService = function() {
253 var services = this.services;
254 var editorContext = services.editorContext;
255 services.contentAssistKeyMap = {'Ctrl-Space': function(editor) {
256 var params = ServiceBuilder.copy(services.options);
257 var cursor = editor.getCursor();
258 params.offset = editor.indexFromPos(cursor);
259 services.contentAssistService.invoke(editorContext, params).done(function(entries) {
260 editor.showHint({hint: function(editor, options) {
261 return {
262 list: entries.map(function(entry) {
263 var displayText;
264 if (entry.label)
265 displayText = entry.label;
266 else
267 displayText = entry.proposal;
268 if (entry.description)
269 displayText += ' (' + entry.description + ')';
270 var prefixLength = 0
271 if (entry.prefix)
272 prefixLength = entry.prefix.length
273 return {
274 text: entry.proposal,
275 displayText: displayText,
276 from: {
277 line: cursor.line,
278 ch: cursor.ch - prefixLength
279 }
280 };
281 }),
282 from: cursor,
283 to: cursor
284 };
285 }});
286 });
287 }};
288 this.editor.addKeyMap(services.contentAssistKeyMap);
289 }
290
291 /**
292 * Semantic highlighting service.
293 */
294 CodeMirrorServiceBuilder.prototype.doHighlighting = function() {
295 var services = this.services;
296 var editorContext = services.editorContext;
297 var editor = this.editor;
298 services.computeHighlighting().always(function() {
299 var highlightingMarkers = editorContext._highlightingMarkers;
300 if (highlightingMarkers) {
301 for (var i = 0; i < highlightingMarkers.length; i++) {
302 highlightingMarkers[i].clear();
303 }
304 }
305 editorContext._highlightingMarkers = [];
306 }).done(function(result) {
307 for (var i = 0; i < result.regions.length; ++i) {
308 var region = result.regions[i];
309 var from = editor.posFromIndex(region.offset);
310 var to = editor.posFromIndex(region.offset + region.length);
311 region.styleClasses.forEach(function(styleClass) {
312 var marker = editor.markText(from, to, {className: styleClass});
313 editorContext._highlightingMarkers.push(marker);
314 });
315 }
316 });
317 }
318
319 var annotationWeight = {
320 error: 30,
321 warning: 20,
322 info: 10
323 };
324 CodeMirrorServiceBuilder.prototype._getAnnotationWeight = function(annotation) {
325 if (annotationWeight[annotation] !== undefined)
326 return annotationWeight[annotation];
327 else
328 return 0;
329 }
330
331 CodeMirrorServiceBuilder.prototype._clearAnnotations = function(annotations) {
332 var editor = this.editor;
333 editor.clearGutter('annotations-gutter');
334 for (var i = 0; i < annotations.length; i++) {
335 var annotation = annotations[i];
336 if (annotation) {
337 annotations[i] = undefined;
338 }
339 }
340 }
341
342 CodeMirrorServiceBuilder.prototype._refreshAnnotations = function(annotations) {
343 var editor = this.editor;
344 for (var i = 0; i < annotations.length; i++) {
345 var annotation = annotations[i];
346 if (annotation) {
347 var classProp = ' class="xtext-annotation_' + annotation.type + '"';
348 var titleProp = annotation.description ? ' title="' + annotation.description.replace(/"/g, '&quot;') + '"' : '';
349 var element = jQuery('<div' + classProp + titleProp + '></div>').get(0);
350 editor.setGutterMarker(i, 'annotations-gutter', element);
351 }
352 }
353 }
354
355 /**
356 * Validation service.
357 */
358 CodeMirrorServiceBuilder.prototype.doValidation = function() {
359 var services = this.services;
360 var editorContext = services.editorContext;
361 var editor = this.editor;
362 var self = this;
363 services.validate().always(function() {
364 if (editorContext._validationAnnotations)
365 self._clearAnnotations(editorContext._validationAnnotations);
366 else
367 editorContext._validationAnnotations = [];
368 var validationMarkers = editorContext._validationMarkers;
369 if (validationMarkers) {
370 for (var i = 0; i < validationMarkers.length; i++) {
371 validationMarkers[i].clear();
372 }
373 }
374 editorContext._validationMarkers = [];
375 }).done(function(result) {
376 var validationAnnotations = editorContext._validationAnnotations;
377 for (var i = 0; i < result.issues.length; i++) {
378 var entry = result.issues[i];
379 var annotation = validationAnnotations[entry.line - 1];
380 var weight = self._getAnnotationWeight(entry.severity);
381 if (annotation) {
382 if (annotation.weight < weight) {
383 annotation.type = entry.severity;
384 annotation.weight = weight;
385 }
386 if (annotation.description)
387 annotation.description += '\n' + entry.description;
388 else
389 annotation.description = entry.description;
390 } else {
391 validationAnnotations[entry.line - 1] = {
392 type: entry.severity,
393 weight: weight,
394 description: entry.description
395 };
396 }
397 var from = editor.posFromIndex(entry.offset);
398 var to = editor.posFromIndex(entry.offset + entry.length);
399 var marker = editor.markText(from, to, {
400 className: 'xtext-marker_' + entry.severity,
401 title: entry.description
402 });
403 editorContext._validationMarkers.push(marker);
404 }
405 self._refreshAnnotations(validationAnnotations);
406 });
407 }
408
409 /**
410 * Occurrences service.
411 */
412 CodeMirrorServiceBuilder.prototype.setupOccurrencesService = function() {
413 var services = this.services;
414 var editorContext = services.editorContext;
415 var selectionUpdateDelay = services.options.selectionUpdateDelay;
416 if (!selectionUpdateDelay)
417 selectionUpdateDelay = 550;
418 var editor = this.editor;
419 var self = this;
420 services.cursorActivityListener = function() {
421 if (editorContext._selectionChangeTimeout) {
422 clearTimeout(editorContext._selectionChangeTimeout);
423 }
424 editorContext._selectionChangeTimeout = setTimeout(function() {
425 var params = ServiceBuilder.copy(services.options);
426 var cursor = editor.getCursor();
427 params.offset = editor.indexFromPos(cursor);
428 services.occurrencesService.invoke(editorContext, params).always(function() {
429 var occurrenceMarkers = editorContext._occurrenceMarkers;
430 if (occurrenceMarkers) {
431 for (var i = 0; i < occurrenceMarkers.length; i++)  {
432 occurrenceMarkers[i].clear();
433 }
434 }
435 editorContext._occurrenceMarkers = [];
436 }).done(function(occurrencesResult) {
437 for (var i = 0; i < occurrencesResult.readRegions.length; i++) {
438 var region = occurrencesResult.readRegions[i];
439 var from = editor.posFromIndex(region.offset);
440 var to = editor.posFromIndex(region.offset + region.length);
441 var marker = editor.markText(from, to, {className: 'xtext-marker_read'});
442 editorContext._occurrenceMarkers.push(marker);
443 }
444 for (var i = 0; i < occurrencesResult.writeRegions.length; i++) {
445 var region = occurrencesResult.writeRegions[i];
446 var from = editor.posFromIndex(region.offset);
447 var to = editor.posFromIndex(region.offset + region.length);
448 var marker = editor.markText(from, to, {className: 'xtext-marker_write'});
449 editorContext._occurrenceMarkers.push(marker);
450 }
451 });
452 }, selectionUpdateDelay);
453 }
454 editor.on('cursorActivity', services.cursorActivityListener);
455 }
456
457 /**
458 * Formatting service.
459 */
460 CodeMirrorServiceBuilder.prototype.setupFormattingService = function() {
461 var services = this.services;
462 if (services.options.enableFormattingAction) {
463 var userAgent = navigator.userAgent.toLowerCase();
464 var formatFunction = function(editor) {
465 services.format();
466 };
467 services.formatKeyMap = /mac os/.test(userAgent) ? {'Shift-Cmd-F': formatFunction}: {'Shift-Ctrl-S': formatFunction};
468 this.editor.addKeyMap(services.formatKeyMap);
469 }
470 }
471
472 return exports;
473});
diff --git a/language-web/src/main/js/xtext/xtextMessages.ts b/language-web/src/main/js/xtext/xtextMessages.ts
new file mode 100644
index 00000000..68737958
--- /dev/null
+++ b/language-web/src/main/js/xtext/xtextMessages.ts
@@ -0,0 +1,62 @@
1export interface IXtextWebRequest {
2 id: string;
3
4 request: unknown;
5}
6
7export interface IXtextWebOkResponse {
8 id: string;
9
10 response: unknown;
11}
12
13export function isOkResponse(response: unknown): response is IXtextWebOkResponse {
14 const okResponse = response as IXtextWebOkResponse;
15 return typeof okResponse === 'object'
16 && typeof okResponse.id === 'string'
17 && typeof okResponse.response !== 'undefined';
18}
19
20export const VALID_XTEXT_WEB_ERROR_KINDS = ['request', 'server'] as const;
21
22export type XtextWebErrorKind = typeof VALID_XTEXT_WEB_ERROR_KINDS[number];
23
24export function isXtextWebErrorKind(value: unknown): value is XtextWebErrorKind {
25 return typeof value === 'string'
26 && VALID_XTEXT_WEB_ERROR_KINDS.includes(value as XtextWebErrorKind);
27}
28
29export interface IXtextWebErrorResponse {
30 id: string;
31
32 error: XtextWebErrorKind;
33
34 message: string;
35}
36
37export function isErrorResponse(response: unknown): response is IXtextWebErrorResponse {
38 const errorResponse = response as IXtextWebErrorResponse;
39 return typeof errorResponse === 'object'
40 && typeof errorResponse.id === 'string'
41 && isXtextWebErrorKind(errorResponse.error)
42 && typeof errorResponse.message === 'string';
43}
44
45export interface IXtextWebPushMessage {
46 resource: string;
47
48 stateId: string;
49
50 service: string;
51
52 push: unknown;
53}
54
55export function isPushMessage(response: unknown): response is IXtextWebPushMessage {
56 const pushMessage = response as IXtextWebPushMessage;
57 return typeof pushMessage === 'object'
58 && typeof pushMessage.resource === 'string'
59 && typeof pushMessage.stateId === 'string'
60 && typeof pushMessage.service === 'string'
61 && typeof pushMessage.push !== 'undefined';
62}
diff --git a/language-web/src/main/js/xtext/xtextServiceResults.ts b/language-web/src/main/js/xtext/xtextServiceResults.ts
new file mode 100644
index 00000000..b2de1e4a
--- /dev/null
+++ b/language-web/src/main/js/xtext/xtextServiceResults.ts
@@ -0,0 +1,239 @@
1export interface IPongResult {
2 pong: string;
3}
4
5export function isPongResult(result: unknown): result is IPongResult {
6 const pongResult = result as IPongResult;
7 return typeof pongResult === 'object'
8 && typeof pongResult.pong === 'string';
9}
10
11export interface IDocumentStateResult {
12 stateId: string;
13}
14
15export function isDocumentStateResult(result: unknown): result is IDocumentStateResult {
16 const documentStateResult = result as IDocumentStateResult;
17 return typeof documentStateResult === 'object'
18 && typeof documentStateResult.stateId === 'string';
19}
20
21export const VALID_CONFLICTS = ['invalidStateId', 'canceled'] as const;
22
23export type Conflict = typeof VALID_CONFLICTS[number];
24
25export function isConflict(value: unknown): value is Conflict {
26 return typeof value === 'string' && VALID_CONFLICTS.includes(value as Conflict);
27}
28
29export interface IServiceConflictResult {
30 conflict: Conflict;
31}
32
33export function isServiceConflictResult(result: unknown): result is IServiceConflictResult {
34 const serviceConflictResult = result as IServiceConflictResult;
35 return typeof serviceConflictResult === 'object'
36 && isConflict(serviceConflictResult.conflict);
37}
38
39export function isInvalidStateIdConflictResult(result: unknown): boolean {
40 return isServiceConflictResult(result) && result.conflict === 'invalidStateId';
41}
42
43export const VALID_SEVERITIES = ['error', 'warning', 'info', 'ignore'] as const;
44
45export type Severity = typeof VALID_SEVERITIES[number];
46
47export function isSeverity(value: unknown): value is Severity {
48 return typeof value === 'string' && VALID_SEVERITIES.includes(value as Severity);
49}
50
51export interface IIssue {
52 description: string;
53
54 severity: Severity;
55
56 line: number;
57
58 column: number;
59
60 offset: number;
61
62 length: number;
63}
64
65export function isIssue(value: unknown): value is IIssue {
66 const issue = value as IIssue;
67 return typeof issue === 'object'
68 && typeof issue.description === 'string'
69 && isSeverity(issue.severity)
70 && typeof issue.line === 'number'
71 && typeof issue.column === 'number'
72 && typeof issue.offset === 'number'
73 && typeof issue.length === 'number';
74}
75
76export interface IValidationResult {
77 issues: IIssue[];
78}
79
80function isArrayOfType<T>(value: unknown, check: (entry: unknown) => entry is T): value is T[] {
81 return Array.isArray(value) && (value as T[]).every(check);
82}
83
84export function isValidationResult(result: unknown): result is IValidationResult {
85 const validationResult = result as IValidationResult;
86 return typeof validationResult === 'object'
87 && isArrayOfType(validationResult.issues, isIssue);
88}
89
90export interface IReplaceRegion {
91 offset: number;
92
93 length: number;
94
95 text: string;
96}
97
98export function isReplaceRegion(value: unknown): value is IReplaceRegion {
99 const replaceRegion = value as IReplaceRegion;
100 return typeof replaceRegion === 'object'
101 && typeof replaceRegion.offset === 'number'
102 && typeof replaceRegion.length === 'number'
103 && typeof replaceRegion.text === 'string';
104}
105
106export interface ITextRegion {
107 offset: number;
108
109 length: number;
110}
111
112export function isTextRegion(value: unknown): value is ITextRegion {
113 const textRegion = value as ITextRegion;
114 return typeof textRegion === 'object'
115 && typeof textRegion.offset === 'number'
116 && typeof textRegion.length === 'number';
117}
118
119export const VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS = [
120 'TEXT',
121 'METHOD',
122 'FUNCTION',
123 'CONSTRUCTOR',
124 'FIELD',
125 'VARIABLE',
126 'CLASS',
127 'INTERFACE',
128 'MODULE',
129 'PROPERTY',
130 'UNIT',
131 'VALUE',
132 'ENUM',
133 'KEYWORD',
134 'SNIPPET',
135 'COLOR',
136 'FILE',
137 'REFERENCE',
138 'UNKNOWN',
139] as const;
140
141export type XtextContentAssistEntryKind = typeof VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS[number];
142
143export function isXtextContentAssistEntryKind(
144 value: unknown,
145): value is XtextContentAssistEntryKind {
146 return typeof value === 'string'
147 && VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS.includes(value as XtextContentAssistEntryKind);
148}
149
150export interface IContentAssistEntry {
151 prefix: string;
152
153 proposal: string;
154
155 label?: string;
156
157 description?: string;
158
159 documentation?: string;
160
161 escapePosition?: number;
162
163 textReplacements: IReplaceRegion[];
164
165 editPositions: ITextRegion[];
166
167 kind: XtextContentAssistEntryKind | string;
168}
169
170function isStringOrUndefined(value: unknown): value is string | undefined {
171 return typeof value === 'string' || typeof value === 'undefined';
172}
173
174function isNumberOrUndefined(value: unknown): value is number | undefined {
175 return typeof value === 'number' || typeof value === 'undefined';
176}
177
178export function isContentAssistEntry(value: unknown): value is IContentAssistEntry {
179 const entry = value as IContentAssistEntry;
180 return typeof entry === 'object'
181 && typeof entry.prefix === 'string'
182 && typeof entry.proposal === 'string'
183 && isStringOrUndefined(entry.label)
184 && isStringOrUndefined(entry.description)
185 && isStringOrUndefined(entry.documentation)
186 && isNumberOrUndefined(entry.escapePosition)
187 && isArrayOfType(entry.textReplacements, isReplaceRegion)
188 && isArrayOfType(entry.editPositions, isTextRegion)
189 && typeof entry.kind === 'string';
190}
191
192export interface IContentAssistResult extends IDocumentStateResult {
193 entries: IContentAssistEntry[];
194}
195
196export function isContentAssistResult(result: unknown): result is IContentAssistResult {
197 const contentAssistResult = result as IContentAssistResult;
198 return isDocumentStateResult(result)
199 && isArrayOfType(contentAssistResult.entries, isContentAssistEntry);
200}
201
202export interface IHighlightingRegion {
203 offset: number;
204
205 length: number;
206
207 styleClasses: string[];
208}
209
210export function isHighlightingRegion(value: unknown): value is IHighlightingRegion {
211 const region = value as IHighlightingRegion;
212 return typeof region === 'object'
213 && typeof region.offset === 'number'
214 && typeof region.length === 'number'
215 && isArrayOfType(region.styleClasses, (s): s is string => typeof s === 'string');
216}
217
218export interface IHighlightingResult {
219 regions: IHighlightingRegion[];
220}
221
222export function isHighlightingResult(result: unknown): result is IHighlightingResult {
223 const highlightingResult = result as IHighlightingResult;
224 return typeof highlightingResult === 'object'
225 && isArrayOfType(highlightingResult.regions, isHighlightingRegion);
226}
227
228export interface IOccurrencesResult extends IDocumentStateResult {
229 writeRegions: ITextRegion[];
230
231 readRegions: ITextRegion[];
232}
233
234export function isOccurrencesResult(result: unknown): result is IOccurrencesResult {
235 const occurrencesResult = result as IOccurrencesResult;
236 return isDocumentStateResult(occurrencesResult)
237 && isArrayOfType(occurrencesResult.writeRegions, isTextRegion)
238 && isArrayOfType(occurrencesResult.readRegions, isTextRegion);
239}
diff --git a/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java b/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java
new file mode 100644
index 00000000..d42cc15c
--- /dev/null
+++ b/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java
@@ -0,0 +1,204 @@
1package tools.refinery.language.web;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.equalTo;
5import static org.hamcrest.Matchers.hasSize;
6import static org.hamcrest.Matchers.instanceOf;
7import static org.hamcrest.Matchers.startsWith;
8import static org.junit.jupiter.api.Assertions.assertThrows;
9
10import java.io.IOException;
11import java.net.InetSocketAddress;
12import java.net.URI;
13import java.util.concurrent.CompletableFuture;
14import java.util.concurrent.CompletionException;
15
16import org.eclipse.jetty.http.HttpHeader;
17import org.eclipse.jetty.http.HttpStatus;
18import org.eclipse.jetty.server.Server;
19import org.eclipse.jetty.servlet.ServletContextHandler;
20import org.eclipse.jetty.servlet.ServletHolder;
21import org.eclipse.jetty.websocket.api.Session;
22import org.eclipse.jetty.websocket.api.StatusCode;
23import org.eclipse.jetty.websocket.api.annotations.WebSocket;
24import org.eclipse.jetty.websocket.api.exceptions.UpgradeException;
25import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
26import org.eclipse.jetty.websocket.client.WebSocketClient;
27import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
28import org.eclipse.xtext.testing.GlobalRegistries;
29import org.eclipse.xtext.testing.GlobalRegistries.GlobalStateMemento;
30import org.junit.jupiter.api.AfterEach;
31import org.junit.jupiter.api.BeforeEach;
32import org.junit.jupiter.api.Test;
33import org.junit.jupiter.params.ParameterizedTest;
34import org.junit.jupiter.params.provider.ValueSource;
35
36import tools.refinery.language.web.tests.WebSocketIntegrationTestClient;
37import tools.refinery.language.web.xtext.servlet.XtextStatusCode;
38import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet;
39
40class ProblemWebSocketServletIntegrationTest {
41 private static int SERVER_PORT = 28080;
42
43 private static String SERVLET_URI = "/xtext-service";
44
45 private GlobalStateMemento stateBeforeInjectorCreation;
46
47 private Server server;
48
49 private WebSocketClient client;
50
51 @BeforeEach
52 void beforeEach() throws Exception {
53 stateBeforeInjectorCreation = GlobalRegistries.makeCopyOfGlobalState();
54 client = new WebSocketClient();
55 client.start();
56 }
57
58 @AfterEach
59 void afterEach() throws Exception {
60 client.stop();
61 client = null;
62 if (server != null) {
63 server.stop();
64 server = null;
65 }
66 stateBeforeInjectorCreation.restoreGlobalState();
67 stateBeforeInjectorCreation = null;
68 }
69
70 @Test
71 void updateTest() {
72 startServer(null);
73 var clientSocket = new UpdateTestClient();
74 var session = connect(clientSocket, null, XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1);
75 assertThat(session.getUpgradeResponse().getAcceptedSubProtocol(),
76 equalTo(XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1));
77 clientSocket.waitForTestResult();
78 assertThat(clientSocket.getCloseStatusCode(), equalTo(StatusCode.NORMAL));
79 var responses = clientSocket.getResponses();
80 assertThat(responses, hasSize(5));
81 assertThat(responses.get(0), equalTo("{\"id\":\"foo\",\"response\":{\"stateId\":\"-80000000\"}}"));
82 assertThat(responses.get(1), startsWith(
83 "{\"resource\":\"test.problem\",\"stateId\":\"-80000000\",\"service\":\"highlight\",\"push\":{\"regions\":["));
84 assertThat(responses.get(2), equalTo(
85 "{\"resource\":\"test.problem\",\"stateId\":\"-80000000\",\"service\":\"validate\",\"push\":{\"issues\":[]}}"));
86 assertThat(responses.get(3), equalTo("{\"id\":\"bar\",\"response\":{\"stateId\":\"-7fffffff\"}}"));
87 assertThat(responses.get(4), startsWith(
88 "{\"resource\":\"test.problem\",\"stateId\":\"-7fffffff\",\"service\":\"highlight\",\"push\":{\"regions\":["));
89 }
90
91 @WebSocket
92 public static class UpdateTestClient extends WebSocketIntegrationTestClient {
93 @Override
94 protected void arrange(Session session, int responsesReceived) throws IOException {
95 switch (responsesReceived) {
96 case 0 -> session.getRemote().sendString(
97 "{\"id\":\"foo\",\"request\":{\"resource\":\"test.problem\",\"serviceType\":\"update\",\"fullText\":\"class Person.\n\"}}");
98 case 3 -> session.getRemote().sendString(
99 "{\"id\":\"bar\",\"request\":{\"resource\":\"test.problem\",\"serviceType\":\"update\",\"requiredStateId\":\"-80000000\",\"deltaText\":\"unique q.\nnode(q).\n\",\"deltaOffset\":\"0\",\"deltaReplaceLength\":\"0\"}}");
100 case 5 -> session.close();
101 }
102 }
103 }
104
105 @Test
106 void badSubProtocolTest() {
107 startServer(null);
108 var clientSocket = new CloseImmediatelyTestClient();
109 var session = connect(clientSocket, null, "<invalid sub-protocol>");
110 assertThat(session.getUpgradeResponse().getAcceptedSubProtocol(), equalTo(null));
111 clientSocket.waitForTestResult();
112 assertThat(clientSocket.getCloseStatusCode(), equalTo(StatusCode.NORMAL));
113 }
114
115 @WebSocket
116 public static class CloseImmediatelyTestClient extends WebSocketIntegrationTestClient {
117 @Override
118 protected void arrange(Session session, int responsesReceived) throws IOException {
119 session.close();
120 }
121 }
122
123 @Test
124 void subProtocolNegotiationTest() {
125 startServer(null);
126 var clientSocket = new CloseImmediatelyTestClient();
127 var session = connect(clientSocket, null, "<invalid sub-protocol>", XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1);
128 assertThat(session.getUpgradeResponse().getAcceptedSubProtocol(),
129 equalTo(XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1));
130 clientSocket.waitForTestResult();
131 assertThat(clientSocket.getCloseStatusCode(), equalTo(StatusCode.NORMAL));
132 }
133
134 @Test
135 void invalidJsonTest() {
136 startServer(null);
137 var clientSocket = new InvalidJsonTestClient();
138 connect(clientSocket, null, XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1);
139 clientSocket.waitForTestResult();
140 assertThat(clientSocket.getCloseStatusCode(), equalTo(XtextStatusCode.INVALID_JSON));
141 }
142
143 @WebSocket
144 public static class InvalidJsonTestClient extends WebSocketIntegrationTestClient {
145 @Override
146 protected void arrange(Session session, int responsesReceived) throws IOException {
147 session.getRemote().sendString("<invalid json>");
148 }
149 }
150
151 @ParameterizedTest(name = "Origin: {0}")
152 @ValueSource(strings = { "https://refinery.example", "https://refinery.example:443", "HTTPS://REFINERY.EXAMPLE" })
153 void validOriginTest(String origin) {
154 startServer("https://refinery.example;https://refinery.example:443");
155 var clientSocket = new CloseImmediatelyTestClient();
156 connect(clientSocket, origin, XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1);
157 clientSocket.waitForTestResult();
158 assertThat(clientSocket.getCloseStatusCode(), equalTo(StatusCode.NORMAL));
159 }
160
161 @Test
162 void invalidOriginTest() {
163 startServer("https://refinery.example;https://refinery.example:443");
164 var clientSocket = new CloseImmediatelyTestClient();
165 var exception = assertThrows(CompletionException.class,
166 () -> connect(clientSocket, "https://invalid.example", XtextWebSocketServlet.XTEXT_SUBPROTOCOL_V1));
167 var innerException = exception.getCause();
168 assertThat(innerException, instanceOf(UpgradeException.class));
169 assertThat(((UpgradeException) innerException).getResponseStatusCode(), equalTo(HttpStatus.FORBIDDEN_403));
170 }
171
172 private void startServer(String allowedOrigins) {
173 server = new Server(new InetSocketAddress(SERVER_PORT));
174 var handler = new ServletContextHandler();
175 var holder = new ServletHolder(ProblemWebSocketServlet.class);
176 if (allowedOrigins != null) {
177 holder.setInitParameter(ProblemWebSocketServlet.ALLOWED_ORIGINS_INIT_PARAM, allowedOrigins);
178 }
179 handler.addServlet(holder, SERVLET_URI);
180 JettyWebSocketServletContainerInitializer.configure(handler, null);
181 server.setHandler(handler);
182 try {
183 server.start();
184 } catch (Exception e) {
185 throw new RuntimeException("Failed to start websocket server");
186 }
187 }
188
189 private Session connect(Object webSocketClient, String origin, String... subProtocols) {
190 var upgradeRequest = new ClientUpgradeRequest();
191 if (origin != null) {
192 upgradeRequest.setHeader(HttpHeader.ORIGIN.name(), origin);
193 }
194 upgradeRequest.setSubProtocols(subProtocols);
195 CompletableFuture<Session> sessionFuture;
196 try {
197 sessionFuture = client.connect(webSocketClient, URI.create("ws://localhost:" + SERVER_PORT + SERVLET_URI),
198 upgradeRequest);
199 } catch (IOException e) {
200 throw new AssertionError("Unexpected exception while connection to websocket", e);
201 }
202 return sessionFuture.join();
203 }
204}
diff --git a/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java b/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java
new file mode 100644
index 00000000..b70d0ed5
--- /dev/null
+++ b/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java
@@ -0,0 +1,42 @@
1package tools.refinery.language.web.tests;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.concurrent.ExecutorService;
6
7import org.eclipse.xtext.ide.ExecutorServiceProvider;
8
9import com.google.inject.Singleton;
10
11@Singleton
12public class AwaitTerminationExecutorServiceProvider extends ExecutorServiceProvider {
13 private List<RestartableCachedThreadPool> servicesToShutDown = new ArrayList<>();
14
15 @Override
16 protected ExecutorService createInstance(String key) {
17 var instance = new RestartableCachedThreadPool();
18 synchronized (servicesToShutDown) {
19 servicesToShutDown.add(instance);
20 }
21 return instance;
22 }
23
24 public void waitForAllTasksToFinish() {
25 synchronized (servicesToShutDown) {
26 for (var executorService : servicesToShutDown) {
27 executorService.waitForAllTasksToFinish();
28 }
29 }
30 }
31
32 @Override
33 public void dispose() {
34 super.dispose();
35 synchronized (servicesToShutDown) {
36 for (var executorService : servicesToShutDown) {
37 executorService.waitForTermination();
38 }
39 servicesToShutDown.clear();
40 }
41 }
42}
diff --git a/language-web/src/test/java/tools/refinery/language/web/tests/ProblemWebInjectorProvider.java b/language-web/src/test/java/tools/refinery/language/web/tests/ProblemWebInjectorProvider.java
new file mode 100644
index 00000000..43c12faa
--- /dev/null
+++ b/language-web/src/test/java/tools/refinery/language/web/tests/ProblemWebInjectorProvider.java
@@ -0,0 +1,47 @@
1package tools.refinery.language.web.tests;
2
3import org.eclipse.xtext.ide.ExecutorServiceProvider;
4import org.eclipse.xtext.util.DisposableRegistry;
5import org.eclipse.xtext.util.Modules2;
6
7import com.google.inject.Guice;
8import com.google.inject.Injector;
9
10import tools.refinery.language.ide.ProblemIdeModule;
11import tools.refinery.language.tests.ProblemInjectorProvider;
12import tools.refinery.language.web.ProblemWebModule;
13import tools.refinery.language.web.ProblemWebSetup;
14
15public class ProblemWebInjectorProvider extends ProblemInjectorProvider {
16
17 protected Injector internalCreateInjector() {
18 return new ProblemWebSetup() {
19 @Override
20 public Injector createInjector() {
21 return Guice.createInjector(
22 Modules2.mixin(createRuntimeModule(), new ProblemIdeModule(), createWebModule()));
23 }
24 }.createInjectorAndDoEMFRegistration();
25 }
26
27 protected ProblemWebModule createWebModule() {
28 // Await termination of the executor service to avoid race conditions between
29 // the tasks in the service and the {@link
30 // org.eclipse.xtext.testing.extensions.InjectionExtension}.
31 return new ProblemWebModule() {
32 @SuppressWarnings("unused")
33 public Class<? extends ExecutorServiceProvider> bindExecutorServiceProvider() {
34 return AwaitTerminationExecutorServiceProvider.class;
35 }
36 };
37 }
38
39 @Override
40 public void restoreRegistry() {
41 // Also make sure to dispose any IDisposable instances (that may depend on the
42 // global state) created by Xtext before restoring the global state.
43 var disposableRegistry = getInjector().getInstance(DisposableRegistry.class);
44 disposableRegistry.dispose();
45 super.restoreRegistry();
46 }
47}
diff --git a/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java b/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java
new file mode 100644
index 00000000..1468273d
--- /dev/null
+++ b/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java
@@ -0,0 +1,109 @@
1package tools.refinery.language.web.tests;
2
3import java.util.Collection;
4import java.util.List;
5import java.util.concurrent.Callable;
6import java.util.concurrent.ExecutionException;
7import java.util.concurrent.ExecutorService;
8import java.util.concurrent.Executors;
9import java.util.concurrent.Future;
10import java.util.concurrent.TimeUnit;
11import java.util.concurrent.TimeoutException;
12
13import org.slf4j.Logger;
14import org.slf4j.LoggerFactory;
15
16public class RestartableCachedThreadPool implements ExecutorService {
17 private static final Logger LOG = LoggerFactory.getLogger(RestartableCachedThreadPool.class);
18
19 private ExecutorService delegate;
20
21 public RestartableCachedThreadPool() {
22 delegate = createExecutorService();
23 }
24
25 public void waitForAllTasksToFinish() {
26 delegate.shutdown();
27 waitForTermination();
28 delegate = createExecutorService();
29 }
30
31 public void waitForTermination() {
32 try {
33 delegate.awaitTermination(1, TimeUnit.SECONDS);
34 } catch (InterruptedException e) {
35 LOG.warn("Interrupted while waiting for delegate executor to stop", e);
36 }
37 }
38
39 protected ExecutorService createExecutorService() {
40 return Executors.newCachedThreadPool();
41 }
42
43 @Override
44 public boolean awaitTermination(long arg0, TimeUnit arg1) throws InterruptedException {
45 return delegate.awaitTermination(arg0, arg1);
46 }
47
48 @Override
49 public void execute(Runnable arg0) {
50 delegate.execute(arg0);
51 }
52
53 @Override
54 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> arg0, long arg1, TimeUnit arg2)
55 throws InterruptedException {
56 return delegate.invokeAll(arg0, arg1, arg2);
57 }
58
59 @Override
60 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> arg0) throws InterruptedException {
61 return delegate.invokeAll(arg0);
62 }
63
64 @Override
65 public <T> T invokeAny(Collection<? extends Callable<T>> arg0, long arg1, TimeUnit arg2)
66 throws InterruptedException, ExecutionException, TimeoutException {
67 return delegate.invokeAny(arg0, arg1, arg2);
68 }
69
70 @Override
71 public <T> T invokeAny(Collection<? extends Callable<T>> arg0) throws InterruptedException, ExecutionException {
72 return delegate.invokeAny(arg0);
73 }
74
75 @Override
76 public boolean isShutdown() {
77 return delegate.isShutdown();
78 }
79
80 @Override
81 public boolean isTerminated() {
82 return delegate.isTerminated();
83 }
84
85 @Override
86 public void shutdown() {
87 delegate.shutdown();
88 }
89
90 @Override
91 public List<Runnable> shutdownNow() {
92 return delegate.shutdownNow();
93 }
94
95 @Override
96 public <T> Future<T> submit(Callable<T> arg0) {
97 return delegate.submit(arg0);
98 }
99
100 @Override
101 public <T> Future<T> submit(Runnable arg0, T arg1) {
102 return delegate.submit(arg0, arg1);
103 }
104
105 @Override
106 public Future<?> submit(Runnable arg0) {
107 return delegate.submit(arg0);
108 }
109}
diff --git a/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java b/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java
new file mode 100644
index 00000000..49464d27
--- /dev/null
+++ b/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java
@@ -0,0 +1,98 @@
1package tools.refinery.language.web.tests;
2
3import static org.junit.jupiter.api.Assertions.fail;
4
5import java.io.IOException;
6import java.time.Duration;
7import java.util.ArrayList;
8import java.util.List;
9
10import org.eclipse.jetty.websocket.api.Session;
11import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
12import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
13import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
14import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
15
16public abstract class WebSocketIntegrationTestClient {
17 private static long TIMEOUT_MILLIS = Duration.ofSeconds(1).toMillis();
18
19 private boolean finished = false;
20
21 private Object lock = new Object();
22
23 private Throwable error;
24
25 private int closeStatusCode;
26
27 private List<String> responses = new ArrayList<>();
28
29 public int getCloseStatusCode() {
30 return closeStatusCode;
31 }
32
33 public List<String> getResponses() {
34 return responses;
35 }
36
37 @OnWebSocketConnect
38 public void onConnect(Session session) {
39 arrangeAndCatchErrors(session);
40 }
41
42 private void arrangeAndCatchErrors(Session session) {
43 try {
44 arrange(session, responses.size());
45 } catch (Exception e) {
46 finishedWithError(e);
47 }
48 }
49
50 protected abstract void arrange(Session session, int responsesReceived) throws IOException;
51
52 @OnWebSocketClose
53 public void onClose(int statusCode, String reason) {
54 closeStatusCode = statusCode;
55 testFinished();
56 }
57
58 @OnWebSocketError
59 public void onError(Throwable error) {
60 finishedWithError(error);
61 }
62
63 @OnWebSocketMessage
64 public void onMessage(Session session, String message) {
65 responses.add(message);
66 arrangeAndCatchErrors(session);
67 }
68
69 private void finishedWithError(Throwable t) {
70 error = t;
71 testFinished();
72 }
73
74 private void testFinished() {
75 synchronized (lock) {
76 finished = true;
77 lock.notify();
78 }
79 }
80
81 public void waitForTestResult() {
82 synchronized (lock) {
83 if (!finished) {
84 try {
85 lock.wait(TIMEOUT_MILLIS);
86 } catch (InterruptedException e) {
87 fail("Unexpected InterruptedException", e);
88 }
89 }
90 }
91 if (!finished) {
92 fail("Test still not finished after timeout");
93 }
94 if (error != null) {
95 fail("Unexpected exception in websocket thread", error);
96 }
97 }
98}
diff --git a/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java b/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java
new file mode 100644
index 00000000..975d120c
--- /dev/null
+++ b/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java
@@ -0,0 +1,165 @@
1package tools.refinery.language.web.xtext.servlet;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.equalTo;
5import static org.hamcrest.Matchers.hasProperty;
6import static org.hamcrest.Matchers.instanceOf;
7import static org.mockito.Mockito.mock;
8import static org.mockito.Mockito.times;
9import static org.mockito.Mockito.verify;
10
11import java.util.List;
12import java.util.Map;
13
14import org.eclipse.emf.common.util.URI;
15import org.eclipse.xtext.resource.IResourceServiceProvider;
16import org.eclipse.xtext.testing.InjectWith;
17import org.eclipse.xtext.testing.extensions.InjectionExtension;
18import org.eclipse.xtext.web.server.model.DocumentStateResult;
19import org.eclipse.xtext.web.server.syntaxcoloring.HighlightingResult;
20import org.eclipse.xtext.web.server.validation.ValidationResult;
21import org.junit.jupiter.api.BeforeEach;
22import org.junit.jupiter.api.Test;
23import org.junit.jupiter.api.extension.ExtendWith;
24import org.mockito.ArgumentCaptor;
25import org.mockito.junit.jupiter.MockitoExtension;
26
27import com.google.inject.Inject;
28
29import tools.refinery.language.web.tests.AwaitTerminationExecutorServiceProvider;
30import tools.refinery.language.web.tests.ProblemWebInjectorProvider;
31import tools.refinery.language.web.xtext.server.ResponseHandler;
32import tools.refinery.language.web.xtext.server.ResponseHandlerException;
33import tools.refinery.language.web.xtext.server.TransactionExecutor;
34import tools.refinery.language.web.xtext.server.message.XtextWebOkResponse;
35import tools.refinery.language.web.xtext.server.message.XtextWebRequest;
36import tools.refinery.language.web.xtext.server.message.XtextWebResponse;
37
38@ExtendWith(MockitoExtension.class)
39@ExtendWith(InjectionExtension.class)
40@InjectWith(ProblemWebInjectorProvider.class)
41class TransactionExecutorTest {
42 private static final String RESOURCE_NAME = "test.problem";
43
44 private static final String PROBLEM_CONTENT_TYPE = "application/x-tools.refinery.problem";
45
46 private static final String TEST_PROBLEM = """
47 class Person {
48 Person[0..*] friend opposite friend
49 }
50
51 friend(a, b).
52 """;
53
54 private static final Map<String, String> UPDATE_FULL_TEXT_PARAMS = Map.of("resource", RESOURCE_NAME, "serviceType",
55 "update", "fullText", TEST_PROBLEM);
56
57 @Inject
58 private IResourceServiceProvider.Registry resourceServiceProviderRegistry;
59
60 @Inject
61 private AwaitTerminationExecutorServiceProvider executorServices;
62
63 private TransactionExecutor transactionExecutor;
64
65 @BeforeEach
66 void beforeEach() {
67 transactionExecutor = new TransactionExecutor(new SimpleSession(), resourceServiceProviderRegistry);
68 }
69
70 @Test
71 void updateFullTextTest() throws ResponseHandlerException {
72 var captor = newCaptor();
73 var stateId = updateFullText(captor);
74 assertThatPrecomputedMessagesAreReceived(stateId, captor.getAllValues());
75 }
76
77 @Test
78 void updateDeltaTextHighlightAndValidationChange() throws ResponseHandlerException {
79 var stateId = updateFullText();
80 var responseHandler = sendRequestAndWaitForAllResponses(
81 new XtextWebRequest("bar", Map.of("resource", RESOURCE_NAME, "serviceType", "update", "requiredStateId",
82 stateId, "deltaText", "unique q.\nnode(q).\n<invalid text>\n", "deltaOffset", "0", "deltaReplaceLength", "0")));
83
84 var captor = newCaptor();
85 verify(responseHandler, times(3)).onResponse(captor.capture());
86 var newStateId = getStateId("bar", captor.getAllValues().get(0));
87 assertThatPrecomputedMessagesAreReceived(newStateId, captor.getAllValues());
88 }
89
90 @Test
91 void updateDeltaTextHighlightChangeOnly() throws ResponseHandlerException {
92 var stateId = updateFullText();
93 var responseHandler = sendRequestAndWaitForAllResponses(
94 new XtextWebRequest("bar", Map.of("resource", RESOURCE_NAME, "serviceType", "update", "requiredStateId",
95 stateId, "deltaText", "unique q.\nnode(q).\n", "deltaOffset", "0", "deltaReplaceLength", "0")));
96
97 var captor = newCaptor();
98 verify(responseHandler, times(2)).onResponse(captor.capture());
99 var newStateId = getStateId("bar", captor.getAllValues().get(0));
100 assertHighlightingResponse(newStateId, captor.getAllValues().get(1));
101 }
102
103 @Test
104 void fullTextWithoutResourceTest() throws ResponseHandlerException {
105 var resourceServiceProvider = resourceServiceProviderRegistry
106 .getResourceServiceProvider(URI.createFileURI(RESOURCE_NAME));
107 resourceServiceProviderRegistry.getContentTypeToFactoryMap().put(PROBLEM_CONTENT_TYPE, resourceServiceProvider);
108 var responseHandler = sendRequestAndWaitForAllResponses(new XtextWebRequest("foo",
109 Map.of("contentType", PROBLEM_CONTENT_TYPE, "fullText", TEST_PROBLEM, "serviceType", "validate")));
110
111 var captor = newCaptor();
112 verify(responseHandler).onResponse(captor.capture());
113 var response = captor.getValue();
114 assertThat(response, hasProperty("id", equalTo("foo")));
115 assertThat(response, hasProperty("responseData", instanceOf(ValidationResult.class)));
116 }
117
118 private ArgumentCaptor<XtextWebResponse> newCaptor() {
119 return ArgumentCaptor.forClass(XtextWebResponse.class);
120 }
121
122 private String updateFullText() throws ResponseHandlerException {
123 return updateFullText(newCaptor());
124 }
125
126 private String updateFullText(ArgumentCaptor<XtextWebResponse> captor) throws ResponseHandlerException {
127 var responseHandler = sendRequestAndWaitForAllResponses(new XtextWebRequest("foo", UPDATE_FULL_TEXT_PARAMS));
128
129 verify(responseHandler, times(3)).onResponse(captor.capture());
130 return getStateId("foo", captor.getAllValues().get(0));
131 }
132
133 private ResponseHandler sendRequestAndWaitForAllResponses(XtextWebRequest request) throws ResponseHandlerException {
134 var responseHandler = mock(ResponseHandler.class);
135 transactionExecutor.setResponseHandler(responseHandler);
136 transactionExecutor.handleRequest(request);
137 executorServices.waitForAllTasksToFinish();
138 return responseHandler;
139 }
140
141 private String getStateId(String requestId, XtextWebResponse okResponse) {
142 assertThat(okResponse, hasProperty("id", equalTo(requestId)));
143 assertThat(okResponse, hasProperty("responseData", instanceOf(DocumentStateResult.class)));
144 return ((DocumentStateResult) ((XtextWebOkResponse) okResponse).getResponseData()).getStateId();
145 }
146
147 private void assertThatPrecomputedMessagesAreReceived(String stateId, List<XtextWebResponse> responses) {
148 assertHighlightingResponse(stateId, responses.get(1));
149 assertValidationResponse(stateId, responses.get(2));
150 }
151
152 private void assertHighlightingResponse(String stateId, XtextWebResponse highlightingResponse) {
153 assertThat(highlightingResponse, hasProperty("resourceId", equalTo(RESOURCE_NAME)));
154 assertThat(highlightingResponse, hasProperty("stateId", equalTo(stateId)));
155 assertThat(highlightingResponse, hasProperty("service", equalTo("highlight")));
156 assertThat(highlightingResponse, hasProperty("pushData", instanceOf(HighlightingResult.class)));
157 }
158
159 private void assertValidationResponse(String stateId, XtextWebResponse validationResponse) {
160 assertThat(validationResponse, hasProperty("resourceId", equalTo(RESOURCE_NAME)));
161 assertThat(validationResponse, hasProperty("stateId", equalTo(stateId)));
162 assertThat(validationResponse, hasProperty("service", equalTo("validate")));
163 assertThat(validationResponse, hasProperty("pushData", instanceOf(ValidationResult.class)));
164 }
165}
diff --git a/language-web/tsconfig.json b/language-web/tsconfig.json
index 7f43a8b5..f1f24a1f 100644
--- a/language-web/tsconfig.json
+++ b/language-web/tsconfig.json
@@ -3,9 +3,6 @@
3 "target": "ES2020", 3 "target": "ES2020",
4 "module": "ES2020", 4 "module": "ES2020",
5 "moduleResolution": "node", 5 "moduleResolution": "node",
6 "paths": {
7 "xtext/*": ["./src/main/js/xtext/*"]
8 },
9 "esModuleInterop": true, 6 "esModuleInterop": true,
10 "allowSyntheticDefaultImports": true, 7 "allowSyntheticDefaultImports": true,
11 "jsx": "react", 8 "jsx": "react",
@@ -16,5 +13,5 @@
16 "noEmit": true 13 "noEmit": true
17 }, 14 },
18 "include": ["./src/main/js/**/*"], 15 "include": ["./src/main/js/**/*"],
19 "exclude": ["./src/main/js/xtext/**/*"] 16 "exclude": ["./build/generated/sources/lezer/*"]
20} 17}
diff --git a/language-web/tsconfig.sonar.json b/language-web/tsconfig.sonar.json
index 1cc74f23..ea3ecc19 100644
--- a/language-web/tsconfig.sonar.json
+++ b/language-web/tsconfig.sonar.json
@@ -3,9 +3,6 @@
3 "target": "ES2020", 3 "target": "ES2020",
4 "module": "ES2020", 4 "module": "ES2020",
5 "moduleResolution": "node", 5 "moduleResolution": "node",
6 "paths": {
7 "xtext/*": ["./src/main/js/xtext/*"]
8 },
9 "esModuleInterop": true, 6 "esModuleInterop": true,
10 "allowSyntheticDefaultImports": true, 7 "allowSyntheticDefaultImports": true,
11 "jsx": "react", 8 "jsx": "react",
diff --git a/language-web/webpack.config.js b/language-web/webpack.config.js
index c51d55d6..801a705c 100644
--- a/language-web/webpack.config.js
+++ b/language-web/webpack.config.js
@@ -25,11 +25,9 @@ const publicHost = process.env['PUBLIC_HOST'] || listenHost;
25const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort); 25const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort);
26 26
27const resolveSources = sources => path.resolve(__dirname, 'src', sources); 27const resolveSources = sources => path.resolve(__dirname, 'src', sources);
28const resolveGenerated = sources => path.resolve(__dirname, 'build/generated/sources', sources);
29const mainJsSources = resolveSources('main/js'); 28const mainJsSources = resolveSources('main/js');
30const babelLoaderFilters = { 29const babelLoaderFilters = {
31 include: [mainJsSources], 30 include: [mainJsSources],
32 exclude: [resolveSources('main/js/xtext')],
33}; 31};
34const babelPresets = [ 32const babelPresets = [
35 [ 33 [
@@ -150,12 +148,8 @@ module.exports = {
150 modules: [ 148 modules: [
151 'node_modules', 149 'node_modules',
152 mainJsSources, 150 mainJsSources,
153 resolveGenerated('xtext/js'),
154 ], 151 ],
155 extensions: ['.js', '.jsx', '.ts', '.tsx'], 152 extensions: ['.js', '.jsx', '.ts', '.tsx'],
156 alias: {
157 images: resolveSources('main/images'),
158 },
159 }, 153 },
160 devtool: devMode ? 'inline-source-map' : 'source-map', 154 devtool: devMode ? 'inline-source-map' : 'source-map',
161 optimization: { 155 optimization: {
@@ -193,7 +187,10 @@ module.exports = {
193 host: listenHost, 187 host: listenHost,
194 port: listenPort, 188 port: listenPort,
195 proxy: { 189 proxy: {
196 '/xtext-service': `${apiPort === 443 ? 'https' : 'http'}://${apiHost}:${apiPort}`, 190 '/xtext-service': {
191 target: `${apiPort === 443 ? 'https' : 'http'}://${apiHost}:${apiPort}`,
192 ws: true,
193 },
197 }, 194 },
198 }, 195 },
199 plugins: [ 196 plugins: [
diff --git a/language-web/yarn.lock b/language-web/yarn.lock
index e87bc6ee..e05f4fa6 100644
--- a/language-web/yarn.lock
+++ b/language-web/yarn.lock
@@ -16,25 +16,37 @@
16 dependencies: 16 dependencies:
17 "@babel/highlight" "^7.14.5" 17 "@babel/highlight" "^7.14.5"
18 18
19"@babel/code-frame@^7.16.0":
20 version "7.16.0"
21 resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
22 integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
23 dependencies:
24 "@babel/highlight" "^7.16.0"
25
19"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.15.0": 26"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.15.0":
20 version "7.15.0" 27 version "7.15.0"
21 resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" 28 resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176"
22 integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== 29 integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==
23 30
24"@babel/core@>=7.9.0", "@babel/core@^7.15.5": 31"@babel/compat-data@^7.16.0":
25 version "7.15.5" 32 version "7.16.0"
26 resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.5.tgz#f8ed9ace730722544609f90c9bb49162dc3bf5b9" 33 resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa"
27 integrity sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg== 34 integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew==
28 dependencies: 35
29 "@babel/code-frame" "^7.14.5" 36"@babel/core@^7.16.0":
30 "@babel/generator" "^7.15.4" 37 version "7.16.0"
31 "@babel/helper-compilation-targets" "^7.15.4" 38 resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4"
32 "@babel/helper-module-transforms" "^7.15.4" 39 integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==
33 "@babel/helpers" "^7.15.4" 40 dependencies:
34 "@babel/parser" "^7.15.5" 41 "@babel/code-frame" "^7.16.0"
35 "@babel/template" "^7.15.4" 42 "@babel/generator" "^7.16.0"
36 "@babel/traverse" "^7.15.4" 43 "@babel/helper-compilation-targets" "^7.16.0"
37 "@babel/types" "^7.15.4" 44 "@babel/helper-module-transforms" "^7.16.0"
45 "@babel/helpers" "^7.16.0"
46 "@babel/parser" "^7.16.0"
47 "@babel/template" "^7.16.0"
48 "@babel/traverse" "^7.16.0"
49 "@babel/types" "^7.16.0"
38 convert-source-map "^1.7.0" 50 convert-source-map "^1.7.0"
39 debug "^4.1.0" 51 debug "^4.1.0"
40 gensync "^1.0.0-beta.2" 52 gensync "^1.0.0-beta.2"
@@ -51,22 +63,38 @@
51 jsesc "^2.5.1" 63 jsesc "^2.5.1"
52 source-map "^0.5.0" 64 source-map "^0.5.0"
53 65
54"@babel/helper-annotate-as-pure@^7.14.5", "@babel/helper-annotate-as-pure@^7.15.4": 66"@babel/generator@^7.16.0":
67 version "7.16.0"
68 resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2"
69 integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==
70 dependencies:
71 "@babel/types" "^7.16.0"
72 jsesc "^2.5.1"
73 source-map "^0.5.0"
74
75"@babel/helper-annotate-as-pure@^7.14.5":
55 version "7.15.4" 76 version "7.15.4"
56 resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835" 77 resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835"
57 integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA== 78 integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==
58 dependencies: 79 dependencies:
59 "@babel/types" "^7.15.4" 80 "@babel/types" "^7.15.4"
60 81
61"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": 82"@babel/helper-annotate-as-pure@^7.16.0":
62 version "7.15.4" 83 version "7.16.0"
63 resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz#21ad815f609b84ee0e3058676c33cf6d1670525f" 84 resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d"
64 integrity sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q== 85 integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==
65 dependencies: 86 dependencies:
66 "@babel/helper-explode-assignable-expression" "^7.15.4" 87 "@babel/types" "^7.16.0"
67 "@babel/types" "^7.15.4" 88
89"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.0":
90 version "7.16.0"
91 resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.0.tgz#f1a686b92da794020c26582eb852e9accd0d7882"
92 integrity sha512-9KuleLT0e77wFUku6TUkqZzCEymBdtuQQ27MhEKzf9UOOJu3cYj98kyaDAzxpC7lV6DGiZFuC8XqDsq8/Kl6aQ==
93 dependencies:
94 "@babel/helper-explode-assignable-expression" "^7.16.0"
95 "@babel/types" "^7.16.0"
68 96
69"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.15.4": 97"@babel/helper-compilation-targets@^7.13.0":
70 version "7.15.4" 98 version "7.15.4"
71 resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" 99 resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9"
72 integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== 100 integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==
@@ -76,17 +104,27 @@
76 browserslist "^4.16.6" 104 browserslist "^4.16.6"
77 semver "^6.3.0" 105 semver "^6.3.0"
78 106
79"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.4": 107"@babel/helper-compilation-targets@^7.16.0":
80 version "7.15.4" 108 version "7.16.0"
81 resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz#7f977c17bd12a5fba363cb19bea090394bf37d2e" 109 resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz#01d615762e796c17952c29e3ede9d6de07d235a8"
82 integrity sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw== 110 integrity sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==
83 dependencies: 111 dependencies:
84 "@babel/helper-annotate-as-pure" "^7.15.4" 112 "@babel/compat-data" "^7.16.0"
85 "@babel/helper-function-name" "^7.15.4" 113 "@babel/helper-validator-option" "^7.14.5"
86 "@babel/helper-member-expression-to-functions" "^7.15.4" 114 browserslist "^4.16.6"
87 "@babel/helper-optimise-call-expression" "^7.15.4" 115 semver "^6.3.0"
88 "@babel/helper-replace-supers" "^7.15.4" 116
89 "@babel/helper-split-export-declaration" "^7.15.4" 117"@babel/helper-create-class-features-plugin@^7.16.0":
118 version "7.16.0"
119 resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b"
120 integrity sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==
121 dependencies:
122 "@babel/helper-annotate-as-pure" "^7.16.0"
123 "@babel/helper-function-name" "^7.16.0"
124 "@babel/helper-member-expression-to-functions" "^7.16.0"
125 "@babel/helper-optimise-call-expression" "^7.16.0"
126 "@babel/helper-replace-supers" "^7.16.0"
127 "@babel/helper-split-export-declaration" "^7.16.0"
90 128
91"@babel/helper-create-regexp-features-plugin@^7.14.5": 129"@babel/helper-create-regexp-features-plugin@^7.14.5":
92 version "7.14.5" 130 version "7.14.5"
@@ -96,10 +134,18 @@
96 "@babel/helper-annotate-as-pure" "^7.14.5" 134 "@babel/helper-annotate-as-pure" "^7.14.5"
97 regexpu-core "^4.7.1" 135 regexpu-core "^4.7.1"
98 136
99"@babel/helper-define-polyfill-provider@^0.2.2": 137"@babel/helper-create-regexp-features-plugin@^7.16.0":
100 version "0.2.3" 138 version "7.16.0"
101 resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" 139 resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz#06b2348ce37fccc4f5e18dcd8d75053f2a7c44ff"
102 integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== 140 integrity sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==
141 dependencies:
142 "@babel/helper-annotate-as-pure" "^7.16.0"
143 regexpu-core "^4.7.1"
144
145"@babel/helper-define-polyfill-provider@^0.2.4":
146 version "0.2.4"
147 resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.4.tgz#8867aed79d3ea6cade40f801efb7ac5c66916b10"
148 integrity sha512-OrpPZ97s+aPi6h2n1OXzdhVis1SGSsMU2aMHgLcOKfsp4/v1NWpx3CWT3lBj5eeBq9cDkPkh+YCfdF7O12uNDQ==
103 dependencies: 149 dependencies:
104 "@babel/helper-compilation-targets" "^7.13.0" 150 "@babel/helper-compilation-targets" "^7.13.0"
105 "@babel/helper-module-imports" "^7.12.13" 151 "@babel/helper-module-imports" "^7.12.13"
@@ -110,14 +156,14 @@
110 resolve "^1.14.2" 156 resolve "^1.14.2"
111 semver "^6.1.2" 157 semver "^6.1.2"
112 158
113"@babel/helper-explode-assignable-expression@^7.15.4": 159"@babel/helper-explode-assignable-expression@^7.16.0":
114 version "7.15.4" 160 version "7.16.0"
115 resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz#f9aec9d219f271eaf92b9f561598ca6b2682600c" 161 resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz#753017337a15f46f9c09f674cff10cee9b9d7778"
116 integrity sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g== 162 integrity sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==
117 dependencies: 163 dependencies:
118 "@babel/types" "^7.15.4" 164 "@babel/types" "^7.16.0"
119 165
120"@babel/helper-function-name@^7.14.5", "@babel/helper-function-name@^7.15.4": 166"@babel/helper-function-name@^7.15.4":
121 version "7.15.4" 167 version "7.15.4"
122 resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" 168 resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc"
123 integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== 169 integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==
@@ -126,6 +172,15 @@
126 "@babel/template" "^7.15.4" 172 "@babel/template" "^7.15.4"
127 "@babel/types" "^7.15.4" 173 "@babel/types" "^7.15.4"
128 174
175"@babel/helper-function-name@^7.16.0":
176 version "7.16.0"
177 resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481"
178 integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==
179 dependencies:
180 "@babel/helper-get-function-arity" "^7.16.0"
181 "@babel/template" "^7.16.0"
182 "@babel/types" "^7.16.0"
183
129"@babel/helper-get-function-arity@^7.15.4": 184"@babel/helper-get-function-arity@^7.15.4":
130 version "7.15.4" 185 version "7.15.4"
131 resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" 186 resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b"
@@ -133,6 +188,13 @@
133 dependencies: 188 dependencies:
134 "@babel/types" "^7.15.4" 189 "@babel/types" "^7.15.4"
135 190
191"@babel/helper-get-function-arity@^7.16.0":
192 version "7.16.0"
193 resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa"
194 integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==
195 dependencies:
196 "@babel/types" "^7.16.0"
197
136"@babel/helper-hoist-variables@^7.15.4": 198"@babel/helper-hoist-variables@^7.15.4":
137 version "7.15.4" 199 version "7.15.4"
138 resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" 200 resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df"
@@ -140,78 +202,92 @@
140 dependencies: 202 dependencies:
141 "@babel/types" "^7.15.4" 203 "@babel/types" "^7.15.4"
142 204
143"@babel/helper-member-expression-to-functions@^7.15.4": 205"@babel/helper-hoist-variables@^7.16.0":
144 version "7.15.4" 206 version "7.16.0"
145 resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" 207 resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a"
146 integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== 208 integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==
147 dependencies: 209 dependencies:
148 "@babel/types" "^7.15.4" 210 "@babel/types" "^7.16.0"
211
212"@babel/helper-member-expression-to-functions@^7.16.0":
213 version "7.16.0"
214 resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4"
215 integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==
216 dependencies:
217 "@babel/types" "^7.16.0"
149 218
150"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.15.4": 219"@babel/helper-module-imports@^7.12.13":
151 version "7.15.4" 220 version "7.15.4"
152 resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" 221 resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f"
153 integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== 222 integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==
154 dependencies: 223 dependencies:
155 "@babel/types" "^7.15.4" 224 "@babel/types" "^7.15.4"
156 225
157"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.4": 226"@babel/helper-module-imports@^7.16.0":
158 version "7.15.7" 227 version "7.16.0"
159 resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz#7da80c8cbc1f02655d83f8b79d25866afe50d226" 228 resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3"
160 integrity sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw== 229 integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==
161 dependencies: 230 dependencies:
162 "@babel/helper-module-imports" "^7.15.4" 231 "@babel/types" "^7.16.0"
163 "@babel/helper-replace-supers" "^7.15.4" 232
164 "@babel/helper-simple-access" "^7.15.4" 233"@babel/helper-module-transforms@^7.16.0":
165 "@babel/helper-split-export-declaration" "^7.15.4" 234 version "7.16.0"
235 resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5"
236 integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==
237 dependencies:
238 "@babel/helper-module-imports" "^7.16.0"
239 "@babel/helper-replace-supers" "^7.16.0"
240 "@babel/helper-simple-access" "^7.16.0"
241 "@babel/helper-split-export-declaration" "^7.16.0"
166 "@babel/helper-validator-identifier" "^7.15.7" 242 "@babel/helper-validator-identifier" "^7.15.7"
167 "@babel/template" "^7.15.4" 243 "@babel/template" "^7.16.0"
168 "@babel/traverse" "^7.15.4" 244 "@babel/traverse" "^7.16.0"
169 "@babel/types" "^7.15.6" 245 "@babel/types" "^7.16.0"
170 246
171"@babel/helper-optimise-call-expression@^7.15.4": 247"@babel/helper-optimise-call-expression@^7.16.0":
172 version "7.15.4" 248 version "7.16.0"
173 resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" 249 resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338"
174 integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== 250 integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==
175 dependencies: 251 dependencies:
176 "@babel/types" "^7.15.4" 252 "@babel/types" "^7.16.0"
177 253
178"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": 254"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
179 version "7.14.5" 255 version "7.14.5"
180 resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" 256 resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
181 integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== 257 integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
182 258
183"@babel/helper-remap-async-to-generator@^7.14.5", "@babel/helper-remap-async-to-generator@^7.15.4": 259"@babel/helper-remap-async-to-generator@^7.16.0":
184 version "7.15.4" 260 version "7.16.0"
185 resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz#2637c0731e4c90fbf58ac58b50b2b5a192fc970f" 261 resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.0.tgz#d5aa3b086e13a5fe05238ff40c3a5a0c2dab3ead"
186 integrity sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ== 262 integrity sha512-MLM1IOMe9aQBqMWxcRw8dcb9jlM86NIw7KA0Wri91Xkfied+dE0QuBFSBjMNvqzmS0OSIDsMNC24dBEkPUi7ew==
187 dependencies: 263 dependencies:
188 "@babel/helper-annotate-as-pure" "^7.15.4" 264 "@babel/helper-annotate-as-pure" "^7.16.0"
189 "@babel/helper-wrap-function" "^7.15.4" 265 "@babel/helper-wrap-function" "^7.16.0"
190 "@babel/types" "^7.15.4" 266 "@babel/types" "^7.16.0"
191 267
192"@babel/helper-replace-supers@^7.14.5", "@babel/helper-replace-supers@^7.15.4": 268"@babel/helper-replace-supers@^7.16.0":
193 version "7.15.4" 269 version "7.16.0"
194 resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" 270 resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17"
195 integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== 271 integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==
196 dependencies: 272 dependencies:
197 "@babel/helper-member-expression-to-functions" "^7.15.4" 273 "@babel/helper-member-expression-to-functions" "^7.16.0"
198 "@babel/helper-optimise-call-expression" "^7.15.4" 274 "@babel/helper-optimise-call-expression" "^7.16.0"
199 "@babel/traverse" "^7.15.4" 275 "@babel/traverse" "^7.16.0"
200 "@babel/types" "^7.15.4" 276 "@babel/types" "^7.16.0"
201 277
202"@babel/helper-simple-access@^7.15.4": 278"@babel/helper-simple-access@^7.16.0":
203 version "7.15.4" 279 version "7.16.0"
204 resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" 280 resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517"
205 integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== 281 integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==
206 dependencies: 282 dependencies:
207 "@babel/types" "^7.15.4" 283 "@babel/types" "^7.16.0"
208 284
209"@babel/helper-skip-transparent-expression-wrappers@^7.14.5", "@babel/helper-skip-transparent-expression-wrappers@^7.15.4": 285"@babel/helper-skip-transparent-expression-wrappers@^7.16.0":
210 version "7.15.4" 286 version "7.16.0"
211 resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz#707dbdba1f4ad0fa34f9114fc8197aec7d5da2eb" 287 resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09"
212 integrity sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A== 288 integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==
213 dependencies: 289 dependencies:
214 "@babel/types" "^7.15.4" 290 "@babel/types" "^7.16.0"
215 291
216"@babel/helper-split-export-declaration@^7.15.4": 292"@babel/helper-split-export-declaration@^7.15.4":
217 version "7.15.4" 293 version "7.15.4"
@@ -220,6 +296,13 @@
220 dependencies: 296 dependencies:
221 "@babel/types" "^7.15.4" 297 "@babel/types" "^7.15.4"
222 298
299"@babel/helper-split-export-declaration@^7.16.0":
300 version "7.16.0"
301 resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438"
302 integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==
303 dependencies:
304 "@babel/types" "^7.16.0"
305
223"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7": 306"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7":
224 version "7.15.7" 307 version "7.15.7"
225 resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" 308 resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
@@ -230,26 +313,35 @@
230 resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" 313 resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
231 integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== 314 integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
232 315
233"@babel/helper-wrap-function@^7.15.4": 316"@babel/helper-wrap-function@^7.16.0":
234 version "7.15.4" 317 version "7.16.0"
235 resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz#6f754b2446cfaf3d612523e6ab8d79c27c3a3de7" 318 resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.0.tgz#b3cf318afce774dfe75b86767cd6d68f3482e57c"
236 integrity sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw== 319 integrity sha512-VVMGzYY3vkWgCJML+qVLvGIam902mJW0FvT7Avj1zEe0Gn7D93aWdLblYARTxEw+6DhZmtzhBM2zv0ekE5zg1g==
237 dependencies: 320 dependencies:
238 "@babel/helper-function-name" "^7.15.4" 321 "@babel/helper-function-name" "^7.16.0"
239 "@babel/template" "^7.15.4" 322 "@babel/template" "^7.16.0"
240 "@babel/traverse" "^7.15.4" 323 "@babel/traverse" "^7.16.0"
241 "@babel/types" "^7.15.4" 324 "@babel/types" "^7.16.0"
242 325
243"@babel/helpers@^7.15.4": 326"@babel/helpers@^7.16.0":
244 version "7.15.4" 327 version "7.16.0"
245 resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" 328 resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.0.tgz#875519c979c232f41adfbd43a3b0398c2e388183"
246 integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== 329 integrity sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==
247 dependencies: 330 dependencies:
248 "@babel/template" "^7.15.4" 331 "@babel/template" "^7.16.0"
249 "@babel/traverse" "^7.15.4" 332 "@babel/traverse" "^7.16.0"
250 "@babel/types" "^7.15.4" 333 "@babel/types" "^7.16.0"
251 334
252"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": 335"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0":
336 version "7.16.0"
337 resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
338 integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
339 dependencies:
340 "@babel/helper-validator-identifier" "^7.15.7"
341 chalk "^2.0.0"
342 js-tokens "^4.0.0"
343
344"@babel/highlight@^7.14.5":
253 version "7.14.5" 345 version "7.14.5"
254 resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" 346 resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
255 integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== 347 integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
@@ -258,141 +350,161 @@
258 chalk "^2.0.0" 350 chalk "^2.0.0"
259 js-tokens "^4.0.0" 351 js-tokens "^4.0.0"
260 352
261"@babel/parser@^7.15.4", "@babel/parser@^7.15.5": 353"@babel/parser@^7.15.4":
262 version "7.15.7" 354 version "7.15.7"
263 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae" 355 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae"
264 integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g== 356 integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==
265 357
266"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.15.4": 358"@babel/parser@^7.16.0":
267 version "7.15.4" 359 version "7.16.0"
268 resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz#dbdeabb1e80f622d9f0b583efb2999605e0a567e" 360 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.0.tgz#cf147d7ada0a3655e79bf4b08ee846f00a00a295"
269 integrity sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog== 361 integrity sha512-TEHWXf0xxpi9wKVyBCmRcSSDjbJ/cl6LUdlbYUHEaNQUJGhreJbZrXT6sR4+fZLxVUJqNRB4KyOvjuy/D9009A==
362
363"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.0":
364 version "7.16.0"
365 resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.0.tgz#efb7f147042aca34ce8156a055906a7abaadeaf0"
366 integrity sha512-djyecbGMEh4rOb/Tc1M5bUW2Ih1IZRa9PoubnPOCzM+DRE89uGUHR1Y+3aDdTMW4drjGRZ2ol8dt1JUFg6hJLQ==
270 dependencies: 367 dependencies:
271 "@babel/helper-plugin-utils" "^7.14.5" 368 "@babel/helper-plugin-utils" "^7.14.5"
272 "@babel/helper-skip-transparent-expression-wrappers" "^7.15.4"
273 "@babel/plugin-proposal-optional-chaining" "^7.14.5"
274 369
275"@babel/plugin-proposal-async-generator-functions@^7.15.4": 370"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.0":
276 version "7.15.4" 371 version "7.16.0"
277 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.4.tgz#f82aabe96c135d2ceaa917feb9f5fca31635277e" 372 resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz#358972eaab006f5eb0826183b0c93cbcaf13e1e2"
278 integrity sha512-2zt2g5vTXpMC3OmK6uyjvdXptbhBXfA77XGrd3gh93zwG8lZYBLOBImiGBEG0RANu3JqKEACCz5CGk73OJROBw== 373 integrity sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==
374 dependencies:
375 "@babel/helper-plugin-utils" "^7.14.5"
376 "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
377 "@babel/plugin-proposal-optional-chaining" "^7.16.0"
378
379"@babel/plugin-proposal-async-generator-functions@^7.16.0":
380 version "7.16.0"
381 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.0.tgz#11425d47a60364352f668ad5fbc1d6596b2c5caf"
382 integrity sha512-nyYmIo7ZqKsY6P4lnVmBlxp9B3a96CscbLotlsNuktMHahkDwoPYEjXrZHU0Tj844Z9f1IthVxQln57mhkcExw==
279 dependencies: 383 dependencies:
280 "@babel/helper-plugin-utils" "^7.14.5" 384 "@babel/helper-plugin-utils" "^7.14.5"
281 "@babel/helper-remap-async-to-generator" "^7.15.4" 385 "@babel/helper-remap-async-to-generator" "^7.16.0"
282 "@babel/plugin-syntax-async-generators" "^7.8.4" 386 "@babel/plugin-syntax-async-generators" "^7.8.4"
283 387
284"@babel/plugin-proposal-class-properties@^7.14.5": 388"@babel/plugin-proposal-class-properties@^7.16.0":
285 version "7.14.5" 389 version "7.16.0"
286 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e" 390 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a"
287 integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg== 391 integrity sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A==
288 dependencies: 392 dependencies:
289 "@babel/helper-create-class-features-plugin" "^7.14.5" 393 "@babel/helper-create-class-features-plugin" "^7.16.0"
290 "@babel/helper-plugin-utils" "^7.14.5" 394 "@babel/helper-plugin-utils" "^7.14.5"
291 395
292"@babel/plugin-proposal-class-static-block@^7.15.4": 396"@babel/plugin-proposal-class-static-block@^7.16.0":
293 version "7.15.4" 397 version "7.16.0"
294 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz#3e7ca6128453c089e8b477a99f970c63fc1cb8d7" 398 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.0.tgz#5296942c564d8144c83eea347d0aa8a0b89170e7"
295 integrity sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA== 399 integrity sha512-mAy3sdcY9sKAkf3lQbDiv3olOfiLqI51c9DR9b19uMoR2Z6r5pmGl7dfNFqEvqOyqbf1ta4lknK4gc5PJn3mfA==
296 dependencies: 400 dependencies:
297 "@babel/helper-create-class-features-plugin" "^7.15.4" 401 "@babel/helper-create-class-features-plugin" "^7.16.0"
298 "@babel/helper-plugin-utils" "^7.14.5" 402 "@babel/helper-plugin-utils" "^7.14.5"
299 "@babel/plugin-syntax-class-static-block" "^7.14.5" 403 "@babel/plugin-syntax-class-static-block" "^7.14.5"
300 404
301"@babel/plugin-proposal-dynamic-import@^7.14.5": 405"@babel/plugin-proposal-dynamic-import@^7.16.0":
302 version "7.14.5" 406 version "7.16.0"
303 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz#0c6617df461c0c1f8fff3b47cd59772360101d2c" 407 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.0.tgz#783eca61d50526202f9b296095453977e88659f1"
304 integrity sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g== 408 integrity sha512-QGSA6ExWk95jFQgwz5GQ2Dr95cf7eI7TKutIXXTb7B1gCLTCz5hTjFTQGfLFBBiC5WSNi7udNwWsqbbMh1c4yQ==
305 dependencies: 409 dependencies:
306 "@babel/helper-plugin-utils" "^7.14.5" 410 "@babel/helper-plugin-utils" "^7.14.5"
307 "@babel/plugin-syntax-dynamic-import" "^7.8.3" 411 "@babel/plugin-syntax-dynamic-import" "^7.8.3"
308 412
309"@babel/plugin-proposal-export-namespace-from@^7.14.5": 413"@babel/plugin-proposal-export-namespace-from@^7.16.0":
310 version "7.14.5" 414 version "7.16.0"
311 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz#dbad244310ce6ccd083072167d8cea83a52faf76" 415 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.0.tgz#9c01dee40b9d6b847b656aaf4a3976a71740f222"
312 integrity sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA== 416 integrity sha512-CjI4nxM/D+5wCnhD11MHB1AwRSAYeDT+h8gCdcVJZ/OK7+wRzFsf7PFPWVpVpNRkHMmMkQWAHpTq+15IXQ1diA==
313 dependencies: 417 dependencies:
314 "@babel/helper-plugin-utils" "^7.14.5" 418 "@babel/helper-plugin-utils" "^7.14.5"
315 "@babel/plugin-syntax-export-namespace-from" "^7.8.3" 419 "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
316 420
317"@babel/plugin-proposal-json-strings@^7.14.5": 421"@babel/plugin-proposal-json-strings@^7.16.0":
318 version "7.14.5" 422 version "7.16.0"
319 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz#38de60db362e83a3d8c944ac858ddf9f0c2239eb" 423 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.0.tgz#cae35a95ed1d2a7fa29c4dc41540b84a72e9ab25"
320 integrity sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ== 424 integrity sha512-kouIPuiv8mSi5JkEhzApg5Gn6hFyKPnlkO0a9YSzqRurH8wYzSlf6RJdzluAsbqecdW5pBvDJDfyDIUR/vLxvg==
321 dependencies: 425 dependencies:
322 "@babel/helper-plugin-utils" "^7.14.5" 426 "@babel/helper-plugin-utils" "^7.14.5"
323 "@babel/plugin-syntax-json-strings" "^7.8.3" 427 "@babel/plugin-syntax-json-strings" "^7.8.3"
324 428
325"@babel/plugin-proposal-logical-assignment-operators@^7.14.5": 429"@babel/plugin-proposal-logical-assignment-operators@^7.16.0":
326 version "7.14.5" 430 version "7.16.0"
327 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz#6e6229c2a99b02ab2915f82571e0cc646a40c738" 431 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.0.tgz#a711b8ceb3ffddd3ef88d3a49e86dbd3cc7db3fd"
328 integrity sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw== 432 integrity sha512-pbW0fE30sVTYXXm9lpVQQ/Vc+iTeQKiXlaNRZPPN2A2VdlWyAtsUrsQ3xydSlDW00TFMK7a8m3cDTkBF5WnV3Q==
329 dependencies: 433 dependencies:
330 "@babel/helper-plugin-utils" "^7.14.5" 434 "@babel/helper-plugin-utils" "^7.14.5"
331 "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" 435 "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
332 436
333"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5": 437"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0":
334 version "7.14.5" 438 version "7.16.0"
335 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6" 439 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.0.tgz#44e1cce08fe2427482cf446a91bb451528ed0596"
336 integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg== 440 integrity sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ==
337 dependencies: 441 dependencies:
338 "@babel/helper-plugin-utils" "^7.14.5" 442 "@babel/helper-plugin-utils" "^7.14.5"
339 "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" 443 "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
340 444
341"@babel/plugin-proposal-numeric-separator@^7.14.5": 445"@babel/plugin-proposal-numeric-separator@^7.16.0":
342 version "7.14.5" 446 version "7.16.0"
343 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz#83631bf33d9a51df184c2102a069ac0c58c05f18" 447 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.0.tgz#5d418e4fbbf8b9b7d03125d3a52730433a373734"
344 integrity sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg== 448 integrity sha512-FAhE2I6mjispy+vwwd6xWPyEx3NYFS13pikDBWUAFGZvq6POGs5eNchw8+1CYoEgBl9n11I3NkzD7ghn25PQ9Q==
345 dependencies: 449 dependencies:
346 "@babel/helper-plugin-utils" "^7.14.5" 450 "@babel/helper-plugin-utils" "^7.14.5"
347 "@babel/plugin-syntax-numeric-separator" "^7.10.4" 451 "@babel/plugin-syntax-numeric-separator" "^7.10.4"
348 452
349"@babel/plugin-proposal-object-rest-spread@^7.15.6": 453"@babel/plugin-proposal-object-rest-spread@^7.16.0":
350 version "7.15.6" 454 version "7.16.0"
351 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz#ef68050c8703d07b25af402cb96cf7f34a68ed11" 455 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.0.tgz#5fb32f6d924d6e6712810362a60e12a2609872e6"
352 integrity sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg== 456 integrity sha512-LU/+jp89efe5HuWJLmMmFG0+xbz+I2rSI7iLc1AlaeSMDMOGzWlc5yJrMN1d04osXN4sSfpo4O+azkBNBes0jg==
353 dependencies: 457 dependencies:
354 "@babel/compat-data" "^7.15.0" 458 "@babel/compat-data" "^7.16.0"
355 "@babel/helper-compilation-targets" "^7.15.4" 459 "@babel/helper-compilation-targets" "^7.16.0"
356 "@babel/helper-plugin-utils" "^7.14.5" 460 "@babel/helper-plugin-utils" "^7.14.5"
357 "@babel/plugin-syntax-object-rest-spread" "^7.8.3" 461 "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
358 "@babel/plugin-transform-parameters" "^7.15.4" 462 "@babel/plugin-transform-parameters" "^7.16.0"
359 463
360"@babel/plugin-proposal-optional-catch-binding@^7.14.5": 464"@babel/plugin-proposal-optional-catch-binding@^7.16.0":
361 version "7.14.5" 465 version "7.16.0"
362 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz#939dd6eddeff3a67fdf7b3f044b5347262598c3c" 466 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.0.tgz#5910085811ab4c28b00d6ebffa4ab0274d1e5f16"
363 integrity sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ== 467 integrity sha512-kicDo0A/5J0nrsCPbn89mTG3Bm4XgYi0CZtvex9Oyw7gGZE3HXGD0zpQNH+mo+tEfbo8wbmMvJftOwpmPy7aVw==
364 dependencies: 468 dependencies:
365 "@babel/helper-plugin-utils" "^7.14.5" 469 "@babel/helper-plugin-utils" "^7.14.5"
366 "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" 470 "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
367 471
368"@babel/plugin-proposal-optional-chaining@^7.14.5": 472"@babel/plugin-proposal-optional-chaining@^7.16.0":
369 version "7.14.5" 473 version "7.16.0"
370 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" 474 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz#56dbc3970825683608e9efb55ea82c2a2d6c8dc0"
371 integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== 475 integrity sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg==
372 dependencies: 476 dependencies:
373 "@babel/helper-plugin-utils" "^7.14.5" 477 "@babel/helper-plugin-utils" "^7.14.5"
374 "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" 478 "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
375 "@babel/plugin-syntax-optional-chaining" "^7.8.3" 479 "@babel/plugin-syntax-optional-chaining" "^7.8.3"
376 480
377"@babel/plugin-proposal-private-methods@^7.14.5": 481"@babel/plugin-proposal-private-methods@^7.16.0":
378 version "7.14.5" 482 version "7.16.0"
379 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz#37446495996b2945f30f5be5b60d5e2aa4f5792d" 483 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz#b4dafb9c717e4301c5776b30d080d6383c89aff6"
380 integrity sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g== 484 integrity sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg==
381 dependencies: 485 dependencies:
382 "@babel/helper-create-class-features-plugin" "^7.14.5" 486 "@babel/helper-create-class-features-plugin" "^7.16.0"
383 "@babel/helper-plugin-utils" "^7.14.5" 487 "@babel/helper-plugin-utils" "^7.14.5"
384 488
385"@babel/plugin-proposal-private-property-in-object@^7.15.4": 489"@babel/plugin-proposal-private-property-in-object@^7.16.0":
386 version "7.15.4" 490 version "7.16.0"
387 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz#55c5e3b4d0261fd44fe637e3f624cfb0f484e3e5" 491 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.0.tgz#69e935b2c5c79d2488112d886f0c4e2790fee76f"
388 integrity sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA== 492 integrity sha512-3jQUr/HBbMVZmi72LpjQwlZ55i1queL8KcDTQEkAHihttJnAPrcvG9ZNXIfsd2ugpizZo595egYV6xy+pv4Ofw==
389 dependencies: 493 dependencies:
390 "@babel/helper-annotate-as-pure" "^7.15.4" 494 "@babel/helper-annotate-as-pure" "^7.16.0"
391 "@babel/helper-create-class-features-plugin" "^7.15.4" 495 "@babel/helper-create-class-features-plugin" "^7.16.0"
392 "@babel/helper-plugin-utils" "^7.14.5" 496 "@babel/helper-plugin-utils" "^7.14.5"
393 "@babel/plugin-syntax-private-property-in-object" "^7.14.5" 497 "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
394 498
395"@babel/plugin-proposal-unicode-property-regex@^7.14.5", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": 499"@babel/plugin-proposal-unicode-property-regex@^7.16.0":
500 version "7.16.0"
501 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz#890482dfc5ea378e42e19a71e709728cabf18612"
502 integrity sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g==
503 dependencies:
504 "@babel/helper-create-regexp-features-plugin" "^7.16.0"
505 "@babel/helper-plugin-utils" "^7.14.5"
506
507"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
396 version "7.14.5" 508 version "7.14.5"
397 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8" 509 resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8"
398 integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q== 510 integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==
@@ -442,13 +554,20 @@
442 dependencies: 554 dependencies:
443 "@babel/helper-plugin-utils" "^7.8.0" 555 "@babel/helper-plugin-utils" "^7.8.0"
444 556
445"@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.14.5": 557"@babel/plugin-syntax-jsx@^7.12.13":
446 version "7.14.5" 558 version "7.14.5"
447 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201" 559 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201"
448 integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw== 560 integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==
449 dependencies: 561 dependencies:
450 "@babel/helper-plugin-utils" "^7.14.5" 562 "@babel/helper-plugin-utils" "^7.14.5"
451 563
564"@babel/plugin-syntax-jsx@^7.16.0":
565 version "7.16.0"
566 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.0.tgz#f9624394317365a9a88c82358d3f8471154698f1"
567 integrity sha512-8zv2+xiPHwly31RK4RmnEYY5zziuF3O7W2kIDW+07ewWDh6Oi0dRq8kwvulRkFgt6DB97RlKs5c1y068iPlCUg==
568 dependencies:
569 "@babel/helper-plugin-utils" "^7.14.5"
570
452"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": 571"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
453 version "7.10.4" 572 version "7.10.4"
454 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" 573 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
@@ -505,71 +624,79 @@
505 dependencies: 624 dependencies:
506 "@babel/helper-plugin-utils" "^7.14.5" 625 "@babel/helper-plugin-utils" "^7.14.5"
507 626
508"@babel/plugin-syntax-typescript@^7.14.5": 627"@babel/plugin-syntax-typescript@^7.16.0":
509 version "7.14.5" 628 version "7.16.0"
510 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" 629 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz#2feeb13d9334cc582ea9111d3506f773174179bb"
511 integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== 630 integrity sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==
512 dependencies: 631 dependencies:
513 "@babel/helper-plugin-utils" "^7.14.5" 632 "@babel/helper-plugin-utils" "^7.14.5"
514 633
515"@babel/plugin-transform-arrow-functions@^7.14.5": 634"@babel/plugin-transform-arrow-functions@^7.16.0":
516 version "7.14.5" 635 version "7.16.0"
517 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" 636 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.0.tgz#951706f8b449c834ed07bd474c0924c944b95a8e"
518 integrity sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A== 637 integrity sha512-vIFb5250Rbh7roWARvCLvIJ/PtAU5Lhv7BtZ1u24COwpI9Ypjsh+bZcKk6rlIyalK+r0jOc1XQ8I4ovNxNrWrA==
519 dependencies: 638 dependencies:
520 "@babel/helper-plugin-utils" "^7.14.5" 639 "@babel/helper-plugin-utils" "^7.14.5"
521 640
522"@babel/plugin-transform-async-to-generator@^7.14.5": 641"@babel/plugin-transform-async-to-generator@^7.16.0":
523 version "7.14.5" 642 version "7.16.0"
524 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" 643 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz#df12637f9630ddfa0ef9d7a11bc414d629d38604"
525 integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== 644 integrity sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw==
526 dependencies: 645 dependencies:
527 "@babel/helper-module-imports" "^7.14.5" 646 "@babel/helper-module-imports" "^7.16.0"
528 "@babel/helper-plugin-utils" "^7.14.5" 647 "@babel/helper-plugin-utils" "^7.14.5"
529 "@babel/helper-remap-async-to-generator" "^7.14.5" 648 "@babel/helper-remap-async-to-generator" "^7.16.0"
530 649
531"@babel/plugin-transform-block-scoped-functions@^7.14.5": 650"@babel/plugin-transform-block-scoped-functions@^7.16.0":
532 version "7.14.5" 651 version "7.16.0"
533 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4" 652 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.0.tgz#c618763233ad02847805abcac4c345ce9de7145d"
534 integrity sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ== 653 integrity sha512-V14As3haUOP4ZWrLJ3VVx5rCnrYhMSHN/jX7z6FAt5hjRkLsb0snPCmJwSOML5oxkKO4FNoNv7V5hw/y2bjuvg==
535 dependencies: 654 dependencies:
536 "@babel/helper-plugin-utils" "^7.14.5" 655 "@babel/helper-plugin-utils" "^7.14.5"
537 656
538"@babel/plugin-transform-block-scoping@^7.15.3": 657"@babel/plugin-transform-block-scoping@^7.16.0":
539 version "7.15.3" 658 version "7.16.0"
540 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz#94c81a6e2fc230bcce6ef537ac96a1e4d2b3afaf" 659 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz#bcf433fb482fe8c3d3b4e8a66b1c4a8e77d37c16"
541 integrity sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q== 660 integrity sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw==
542 dependencies: 661 dependencies:
543 "@babel/helper-plugin-utils" "^7.14.5" 662 "@babel/helper-plugin-utils" "^7.14.5"
544 663
545"@babel/plugin-transform-classes@^7.15.4": 664"@babel/plugin-transform-classes@^7.16.0":
546 version "7.15.4" 665 version "7.16.0"
547 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz#50aee17aaf7f332ae44e3bce4c2e10534d5d3bf1" 666 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.0.tgz#54cf5ff0b2242c6573d753cd4bfc7077a8b282f5"
548 integrity sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg== 667 integrity sha512-HUxMvy6GtAdd+GKBNYDWCIA776byUQH8zjnfjxwT1P1ARv/wFu8eBDpmXQcLS/IwRtrxIReGiplOwMeyO7nsDQ==
549 dependencies: 668 dependencies:
550 "@babel/helper-annotate-as-pure" "^7.15.4" 669 "@babel/helper-annotate-as-pure" "^7.16.0"
551 "@babel/helper-function-name" "^7.15.4" 670 "@babel/helper-function-name" "^7.16.0"
552 "@babel/helper-optimise-call-expression" "^7.15.4" 671 "@babel/helper-optimise-call-expression" "^7.16.0"
553 "@babel/helper-plugin-utils" "^7.14.5" 672 "@babel/helper-plugin-utils" "^7.14.5"
554 "@babel/helper-replace-supers" "^7.15.4" 673 "@babel/helper-replace-supers" "^7.16.0"
555 "@babel/helper-split-export-declaration" "^7.15.4" 674 "@babel/helper-split-export-declaration" "^7.16.0"
556 globals "^11.1.0" 675 globals "^11.1.0"
557 676
558"@babel/plugin-transform-computed-properties@^7.14.5": 677"@babel/plugin-transform-computed-properties@^7.16.0":
559 version "7.14.5" 678 version "7.16.0"
560 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz#1b9d78987420d11223d41195461cc43b974b204f" 679 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.0.tgz#e0c385507d21e1b0b076d66bed6d5231b85110b7"
561 integrity sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg== 680 integrity sha512-63l1dRXday6S8V3WFY5mXJwcRAnPYxvFfTlt67bwV1rTyVTM5zrp0DBBb13Kl7+ehkCVwIZPumPpFP/4u70+Tw==
562 dependencies: 681 dependencies:
563 "@babel/helper-plugin-utils" "^7.14.5" 682 "@babel/helper-plugin-utils" "^7.14.5"
564 683
565"@babel/plugin-transform-destructuring@^7.14.7": 684"@babel/plugin-transform-destructuring@^7.16.0":
566 version "7.14.7" 685 version "7.16.0"
567 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" 686 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.0.tgz#ad3d7e74584ad5ea4eadb1e6642146c590dee33c"
568 integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== 687 integrity sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q==
569 dependencies: 688 dependencies:
570 "@babel/helper-plugin-utils" "^7.14.5" 689 "@babel/helper-plugin-utils" "^7.14.5"
571 690
572"@babel/plugin-transform-dotall-regex@^7.14.5", "@babel/plugin-transform-dotall-regex@^7.4.4": 691"@babel/plugin-transform-dotall-regex@^7.16.0":
692 version "7.16.0"
693 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.0.tgz#50bab00c1084b6162d0a58a818031cf57798e06f"
694 integrity sha512-FXlDZfQeLILfJlC6I1qyEwcHK5UpRCFkaoVyA1nk9A1L1Yu583YO4un2KsLBsu3IJb4CUbctZks8tD9xPQubLw==
695 dependencies:
696 "@babel/helper-create-regexp-features-plugin" "^7.16.0"
697 "@babel/helper-plugin-utils" "^7.14.5"
698
699"@babel/plugin-transform-dotall-regex@^7.4.4":
573 version "7.14.5" 700 version "7.14.5"
574 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a" 701 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a"
575 integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw== 702 integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==
@@ -577,268 +704,269 @@
577 "@babel/helper-create-regexp-features-plugin" "^7.14.5" 704 "@babel/helper-create-regexp-features-plugin" "^7.14.5"
578 "@babel/helper-plugin-utils" "^7.14.5" 705 "@babel/helper-plugin-utils" "^7.14.5"
579 706
580"@babel/plugin-transform-duplicate-keys@^7.14.5": 707"@babel/plugin-transform-duplicate-keys@^7.16.0":
581 version "7.14.5" 708 version "7.16.0"
582 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz#365a4844881bdf1501e3a9f0270e7f0f91177954" 709 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.0.tgz#8bc2e21813e3e89e5e5bf3b60aa5fc458575a176"
583 integrity sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A== 710 integrity sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ==
584 dependencies: 711 dependencies:
585 "@babel/helper-plugin-utils" "^7.14.5" 712 "@babel/helper-plugin-utils" "^7.14.5"
586 713
587"@babel/plugin-transform-exponentiation-operator@^7.14.5": 714"@babel/plugin-transform-exponentiation-operator@^7.16.0":
588 version "7.14.5" 715 version "7.16.0"
589 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz#5154b8dd6a3dfe6d90923d61724bd3deeb90b493" 716 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.0.tgz#a180cd2881e3533cef9d3901e48dad0fbeff4be4"
590 integrity sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA== 717 integrity sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw==
591 dependencies: 718 dependencies:
592 "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" 719 "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.0"
593 "@babel/helper-plugin-utils" "^7.14.5" 720 "@babel/helper-plugin-utils" "^7.14.5"
594 721
595"@babel/plugin-transform-for-of@^7.15.4": 722"@babel/plugin-transform-for-of@^7.16.0":
596 version "7.15.4" 723 version "7.16.0"
597 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz#25c62cce2718cfb29715f416e75d5263fb36a8c2" 724 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.0.tgz#f7abaced155260e2461359bbc7c7248aca5e6bd2"
598 integrity sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA== 725 integrity sha512-5QKUw2kO+GVmKr2wMYSATCTTnHyscl6sxFRAY+rvN7h7WB0lcG0o4NoV6ZQU32OZGVsYUsfLGgPQpDFdkfjlJQ==
599 dependencies: 726 dependencies:
600 "@babel/helper-plugin-utils" "^7.14.5" 727 "@babel/helper-plugin-utils" "^7.14.5"
601 728
602"@babel/plugin-transform-function-name@^7.14.5": 729"@babel/plugin-transform-function-name@^7.16.0":
603 version "7.14.5" 730 version "7.16.0"
604 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz#e81c65ecb900746d7f31802f6bed1f52d915d6f2" 731 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.0.tgz#02e3699c284c6262236599f751065c5d5f1f400e"
605 integrity sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ== 732 integrity sha512-lBzMle9jcOXtSOXUpc7tvvTpENu/NuekNJVova5lCCWCV9/U1ho2HH2y0p6mBg8fPm/syEAbfaaemYGOHCY3mg==
606 dependencies: 733 dependencies:
607 "@babel/helper-function-name" "^7.14.5" 734 "@babel/helper-function-name" "^7.16.0"
608 "@babel/helper-plugin-utils" "^7.14.5" 735 "@babel/helper-plugin-utils" "^7.14.5"
609 736
610"@babel/plugin-transform-literals@^7.14.5": 737"@babel/plugin-transform-literals@^7.16.0":
611 version "7.14.5" 738 version "7.16.0"
612 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz#41d06c7ff5d4d09e3cf4587bd3ecf3930c730f78" 739 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.0.tgz#79711e670ffceb31bd298229d50f3621f7980cac"
613 integrity sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A== 740 integrity sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ==
614 dependencies: 741 dependencies:
615 "@babel/helper-plugin-utils" "^7.14.5" 742 "@babel/helper-plugin-utils" "^7.14.5"
616 743
617"@babel/plugin-transform-member-expression-literals@^7.14.5": 744"@babel/plugin-transform-member-expression-literals@^7.16.0":
618 version "7.14.5" 745 version "7.16.0"
619 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz#b39cd5212a2bf235a617d320ec2b48bcc091b8a7" 746 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.0.tgz#5251b4cce01eaf8314403d21aedb269d79f5e64b"
620 integrity sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q== 747 integrity sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg==
621 dependencies: 748 dependencies:
622 "@babel/helper-plugin-utils" "^7.14.5" 749 "@babel/helper-plugin-utils" "^7.14.5"
623 750
624"@babel/plugin-transform-modules-amd@^7.14.5": 751"@babel/plugin-transform-modules-amd@^7.16.0":
625 version "7.14.5" 752 version "7.16.0"
626 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz#4fd9ce7e3411cb8b83848480b7041d83004858f7" 753 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.0.tgz#09abd41e18dcf4fd479c598c1cef7bd39eb1337e"
627 integrity sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g== 754 integrity sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw==
628 dependencies: 755 dependencies:
629 "@babel/helper-module-transforms" "^7.14.5" 756 "@babel/helper-module-transforms" "^7.16.0"
630 "@babel/helper-plugin-utils" "^7.14.5" 757 "@babel/helper-plugin-utils" "^7.14.5"
631 babel-plugin-dynamic-import-node "^2.3.3" 758 babel-plugin-dynamic-import-node "^2.3.3"
632 759
633"@babel/plugin-transform-modules-commonjs@^7.15.4": 760"@babel/plugin-transform-modules-commonjs@^7.16.0":
634 version "7.15.4" 761 version "7.16.0"
635 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz#8201101240eabb5a76c08ef61b2954f767b6b4c1" 762 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.0.tgz#add58e638c8ddc4875bd9a9ecb5c594613f6c922"
636 integrity sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA== 763 integrity sha512-Dzi+NWqyEotgzk/sb7kgQPJQf7AJkQBWsVp1N6JWc1lBVo0vkElUnGdr1PzUBmfsCCN5OOFya3RtpeHk15oLKQ==
637 dependencies: 764 dependencies:
638 "@babel/helper-module-transforms" "^7.15.4" 765 "@babel/helper-module-transforms" "^7.16.0"
639 "@babel/helper-plugin-utils" "^7.14.5" 766 "@babel/helper-plugin-utils" "^7.14.5"
640 "@babel/helper-simple-access" "^7.15.4" 767 "@babel/helper-simple-access" "^7.16.0"
641 babel-plugin-dynamic-import-node "^2.3.3" 768 babel-plugin-dynamic-import-node "^2.3.3"
642 769
643"@babel/plugin-transform-modules-systemjs@^7.15.4": 770"@babel/plugin-transform-modules-systemjs@^7.16.0":
644 version "7.15.4" 771 version "7.16.0"
645 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz#b42890c7349a78c827719f1d2d0cd38c7d268132" 772 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.0.tgz#a92cf240afeb605f4ca16670453024425e421ea4"
646 integrity sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw== 773 integrity sha512-yuGBaHS3lF1m/5R+6fjIke64ii5luRUg97N2wr+z1sF0V+sNSXPxXDdEEL/iYLszsN5VKxVB1IPfEqhzVpiqvg==
647 dependencies: 774 dependencies:
648 "@babel/helper-hoist-variables" "^7.15.4" 775 "@babel/helper-hoist-variables" "^7.16.0"
649 "@babel/helper-module-transforms" "^7.15.4" 776 "@babel/helper-module-transforms" "^7.16.0"
650 "@babel/helper-plugin-utils" "^7.14.5" 777 "@babel/helper-plugin-utils" "^7.14.5"
651 "@babel/helper-validator-identifier" "^7.14.9" 778 "@babel/helper-validator-identifier" "^7.15.7"
652 babel-plugin-dynamic-import-node "^2.3.3" 779 babel-plugin-dynamic-import-node "^2.3.3"
653 780
654"@babel/plugin-transform-modules-umd@^7.14.5": 781"@babel/plugin-transform-modules-umd@^7.16.0":
655 version "7.14.5" 782 version "7.16.0"
656 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz#fb662dfee697cce274a7cda525190a79096aa6e0" 783 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.0.tgz#195f26c2ad6d6a391b70880effce18ce625e06a7"
657 integrity sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA== 784 integrity sha512-nx4f6no57himWiHhxDM5pjwhae5vLpTK2zCnDH8+wNLJy0TVER/LJRHl2bkt6w9Aad2sPD5iNNoUpY3X9sTGDg==
658 dependencies: 785 dependencies:
659 "@babel/helper-module-transforms" "^7.14.5" 786 "@babel/helper-module-transforms" "^7.16.0"
660 "@babel/helper-plugin-utils" "^7.14.5" 787 "@babel/helper-plugin-utils" "^7.14.5"
661 788
662"@babel/plugin-transform-named-capturing-groups-regex@^7.14.9": 789"@babel/plugin-transform-named-capturing-groups-regex@^7.16.0":
663 version "7.14.9" 790 version "7.16.0"
664 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2" 791 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.0.tgz#d3db61cc5d5b97986559967cd5ea83e5c32096ca"
665 integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA== 792 integrity sha512-LogN88uO+7EhxWc8WZuQ8vxdSyVGxhkh8WTC3tzlT8LccMuQdA81e9SGV6zY7kY2LjDhhDOFdQVxdGwPyBCnvg==
666 dependencies: 793 dependencies:
667 "@babel/helper-create-regexp-features-plugin" "^7.14.5" 794 "@babel/helper-create-regexp-features-plugin" "^7.16.0"
668 795
669"@babel/plugin-transform-new-target@^7.14.5": 796"@babel/plugin-transform-new-target@^7.16.0":
670 version "7.14.5" 797 version "7.16.0"
671 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz#31bdae8b925dc84076ebfcd2a9940143aed7dbf8" 798 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.0.tgz#af823ab576f752215a49937779a41ca65825ab35"
672 integrity sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ== 799 integrity sha512-fhjrDEYv2DBsGN/P6rlqakwRwIp7rBGLPbrKxwh7oVt5NNkIhZVOY2GRV+ULLsQri1bDqwDWnU3vhlmx5B2aCw==
673 dependencies: 800 dependencies:
674 "@babel/helper-plugin-utils" "^7.14.5" 801 "@babel/helper-plugin-utils" "^7.14.5"
675 802
676"@babel/plugin-transform-object-super@^7.14.5": 803"@babel/plugin-transform-object-super@^7.16.0":
677 version "7.14.5" 804 version "7.16.0"
678 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" 805 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.0.tgz#fb20d5806dc6491a06296ac14ea8e8d6fedda72b"
679 integrity sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg== 806 integrity sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg==
680 dependencies: 807 dependencies:
681 "@babel/helper-plugin-utils" "^7.14.5" 808 "@babel/helper-plugin-utils" "^7.14.5"
682 "@babel/helper-replace-supers" "^7.14.5" 809 "@babel/helper-replace-supers" "^7.16.0"
683 810
684"@babel/plugin-transform-parameters@^7.15.4": 811"@babel/plugin-transform-parameters@^7.16.0":
685 version "7.15.4" 812 version "7.16.0"
686 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz#5f2285cc3160bf48c8502432716b48504d29ed62" 813 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.0.tgz#1b50765fc421c229819dc4c7cdb8911660b3c2d7"
687 integrity sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ== 814 integrity sha512-XgnQEm1CevKROPx+udOi/8f8TiGhrUWiHiaUCIp47tE0tpFDjzXNTZc9E5CmCwxNjXTWEVqvRfWZYOTFvMa/ZQ==
688 dependencies: 815 dependencies:
689 "@babel/helper-plugin-utils" "^7.14.5" 816 "@babel/helper-plugin-utils" "^7.14.5"
690 817
691"@babel/plugin-transform-property-literals@^7.14.5": 818"@babel/plugin-transform-property-literals@^7.16.0":
692 version "7.14.5" 819 version "7.16.0"
693 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz#0ddbaa1f83db3606f1cdf4846fa1dfb473458b34" 820 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.0.tgz#a95c552189a96a00059f6776dc4e00e3690c78d1"
694 integrity sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw== 821 integrity sha512-XLldD4V8+pOqX2hwfWhgwXzGdnDOThxaNTgqagOcpBgIxbUvpgU2FMvo5E1RyHbk756WYgdbS0T8y0Cj9FKkWQ==
695 dependencies: 822 dependencies:
696 "@babel/helper-plugin-utils" "^7.14.5" 823 "@babel/helper-plugin-utils" "^7.14.5"
697 824
698"@babel/plugin-transform-react-display-name@^7.14.5": 825"@babel/plugin-transform-react-display-name@^7.16.0":
699 version "7.15.1" 826 version "7.16.0"
700 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.15.1.tgz#6aaac6099f1fcf6589d35ae6be1b6e10c8c602b9" 827 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.0.tgz#9a0ad8aa8e8790883a7bd2736f66229a58125676"
701 integrity sha512-yQZ/i/pUCJAHI/LbtZr413S3VT26qNrEm0M5RRxQJA947/YNYwbZbBaXGDrq6CG5QsZycI1VIP6d7pQaBfP+8Q== 828 integrity sha512-FJFdJAqaCpndL+pIf0aeD/qlQwT7QXOvR6Cc8JPvNhKJBi2zc/DPc4g05Y3fbD/0iWAMQFGij4+Xw+4L/BMpTg==
702 dependencies: 829 dependencies:
703 "@babel/helper-plugin-utils" "^7.14.5" 830 "@babel/helper-plugin-utils" "^7.14.5"
704 831
705"@babel/plugin-transform-react-jsx-development@^7.14.5": 832"@babel/plugin-transform-react-jsx-development@^7.16.0":
706 version "7.14.5" 833 version "7.16.0"
707 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.14.5.tgz#1a6c73e2f7ed2c42eebc3d2ad60b0c7494fcb9af" 834 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.0.tgz#1cb52874678d23ab11d0d16488d54730807303ef"
708 integrity sha512-rdwG/9jC6QybWxVe2UVOa7q6cnTpw8JRRHOxntG/h6g/guAOe6AhtQHJuJh5FwmnXIT1bdm5vC2/5huV8ZOorQ== 835 integrity sha512-qq65iSqBRq0Hr3wq57YG2AmW0H6wgTnIzpffTphrUWUgLCOK+zf1f7G0vuOiXrp7dU1qq+fQBoqZ3wCDAkhFzw==
709 dependencies: 836 dependencies:
710 "@babel/plugin-transform-react-jsx" "^7.14.5" 837 "@babel/plugin-transform-react-jsx" "^7.16.0"
711 838
712"@babel/plugin-transform-react-jsx@^7.14.5": 839"@babel/plugin-transform-react-jsx@^7.16.0":
713 version "7.14.9" 840 version "7.16.0"
714 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.9.tgz#3314b2163033abac5200a869c4de242cd50a914c" 841 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.0.tgz#55b797d4960c3de04e07ad1c0476e2bc6a4889f1"
715 integrity sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw== 842 integrity sha512-rqDgIbukZ44pqq7NIRPGPGNklshPkvlmvqjdx3OZcGPk4zGIenYkxDTvl3LsSL8gqcc3ZzGmXPE6hR/u/voNOw==
716 dependencies: 843 dependencies:
717 "@babel/helper-annotate-as-pure" "^7.14.5" 844 "@babel/helper-annotate-as-pure" "^7.16.0"
718 "@babel/helper-module-imports" "^7.14.5" 845 "@babel/helper-module-imports" "^7.16.0"
719 "@babel/helper-plugin-utils" "^7.14.5" 846 "@babel/helper-plugin-utils" "^7.14.5"
720 "@babel/plugin-syntax-jsx" "^7.14.5" 847 "@babel/plugin-syntax-jsx" "^7.16.0"
721 "@babel/types" "^7.14.9" 848 "@babel/types" "^7.16.0"
722 849
723"@babel/plugin-transform-react-pure-annotations@^7.14.5": 850"@babel/plugin-transform-react-pure-annotations@^7.16.0":
724 version "7.14.5" 851 version "7.16.0"
725 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.14.5.tgz#18de612b84021e3a9802cbc212c9d9f46d0d11fc" 852 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.0.tgz#23db6ddf558d8abde41b8ad9d59f48ad5532ccab"
726 integrity sha512-3X4HpBJimNxW4rhUy/SONPyNQHp5YRr0HhJdT2OH1BRp0of7u3Dkirc7x9FRJMKMqTBI079VZ1hzv7Ouuz///g== 853 integrity sha512-NC/Bj2MG+t8Ef5Pdpo34Ay74X4Rt804h5y81PwOpfPtmAK3i6CizmQqwyBQzIepz1Yt8wNr2Z2L7Lu3qBMfZMA==
727 dependencies: 854 dependencies:
728 "@babel/helper-annotate-as-pure" "^7.14.5" 855 "@babel/helper-annotate-as-pure" "^7.16.0"
729 "@babel/helper-plugin-utils" "^7.14.5" 856 "@babel/helper-plugin-utils" "^7.14.5"
730 857
731"@babel/plugin-transform-regenerator@^7.14.5": 858"@babel/plugin-transform-regenerator@^7.16.0":
732 version "7.14.5" 859 version "7.16.0"
733 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" 860 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.0.tgz#eaee422c84b0232d03aea7db99c97deeaf6125a4"
734 integrity sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg== 861 integrity sha512-JAvGxgKuwS2PihiSFaDrp94XOzzTUeDeOQlcKzVAyaPap7BnZXK/lvMDiubkPTdotPKOIZq9xWXWnggUMYiExg==
735 dependencies: 862 dependencies:
736 regenerator-transform "^0.14.2" 863 regenerator-transform "^0.14.2"
737 864
738"@babel/plugin-transform-reserved-words@^7.14.5": 865"@babel/plugin-transform-reserved-words@^7.16.0":
739 version "7.14.5" 866 version "7.16.0"
740 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz#c44589b661cfdbef8d4300dcc7469dffa92f8304" 867 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.0.tgz#fff4b9dcb19e12619394bda172d14f2d04c0379c"
741 integrity sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg== 868 integrity sha512-Dgs8NNCehHSvXdhEhln8u/TtJxfVwGYCgP2OOr5Z3Ar+B+zXicEOKNTyc+eca2cuEOMtjW6m9P9ijOt8QdqWkg==
742 dependencies: 869 dependencies:
743 "@babel/helper-plugin-utils" "^7.14.5" 870 "@babel/helper-plugin-utils" "^7.14.5"
744 871
745"@babel/plugin-transform-runtime@^7.15.0": 872"@babel/plugin-transform-runtime@^7.16.0":
746 version "7.15.0" 873 version "7.16.0"
747 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.0.tgz#d3aa650d11678ca76ce294071fda53d7804183b3" 874 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.0.tgz#3fe0da36c2f0834bef7c4d3e7f2b2db0ee0c8909"
748 integrity sha512-sfHYkLGjhzWTq6xsuQ01oEsUYjkHRux9fW1iUA68dC7Qd8BS1Unq4aZ8itmQp95zUzIcyR2EbNMTzAicFj+guw== 875 integrity sha512-zlPf1/XFn5+vWdve3AAhf+Sxl+MVa5VlwTwWgnLx23u4GlatSRQJ3Eoo9vllf0a9il3woQsT4SK+5Z7c06h8ag==
749 dependencies: 876 dependencies:
750 "@babel/helper-module-imports" "^7.14.5" 877 "@babel/helper-module-imports" "^7.16.0"
751 "@babel/helper-plugin-utils" "^7.14.5" 878 "@babel/helper-plugin-utils" "^7.14.5"
752 babel-plugin-polyfill-corejs2 "^0.2.2" 879 babel-plugin-polyfill-corejs2 "^0.2.3"
753 babel-plugin-polyfill-corejs3 "^0.2.2" 880 babel-plugin-polyfill-corejs3 "^0.3.0"
754 babel-plugin-polyfill-regenerator "^0.2.2" 881 babel-plugin-polyfill-regenerator "^0.2.3"
755 semver "^6.3.0" 882 semver "^6.3.0"
756 883
757"@babel/plugin-transform-shorthand-properties@^7.14.5": 884"@babel/plugin-transform-shorthand-properties@^7.16.0":
758 version "7.14.5" 885 version "7.16.0"
759 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" 886 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz#090372e3141f7cc324ed70b3daf5379df2fa384d"
760 integrity sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g== 887 integrity sha512-iVb1mTcD8fuhSv3k99+5tlXu5N0v8/DPm2mO3WACLG6al1CGZH7v09HJyUb1TtYl/Z+KrM6pHSIJdZxP5A+xow==
761 dependencies: 888 dependencies:
762 "@babel/helper-plugin-utils" "^7.14.5" 889 "@babel/helper-plugin-utils" "^7.14.5"
763 890
764"@babel/plugin-transform-spread@^7.14.6": 891"@babel/plugin-transform-spread@^7.16.0":
765 version "7.14.6" 892 version "7.16.0"
766 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" 893 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.0.tgz#d21ca099bbd53ab307a8621e019a7bd0f40cdcfb"
767 integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== 894 integrity sha512-Ao4MSYRaLAQczZVp9/7E7QHsCuK92yHRrmVNRe/SlEJjhzivq0BSn8mEraimL8wizHZ3fuaHxKH0iwzI13GyGg==
768 dependencies: 895 dependencies:
769 "@babel/helper-plugin-utils" "^7.14.5" 896 "@babel/helper-plugin-utils" "^7.14.5"
770 "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" 897 "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
771 898
772"@babel/plugin-transform-sticky-regex@^7.14.5": 899"@babel/plugin-transform-sticky-regex@^7.16.0":
773 version "7.14.5" 900 version "7.16.0"
774 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz#5b617542675e8b7761294381f3c28c633f40aeb9" 901 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.0.tgz#c35ea31a02d86be485f6aa510184b677a91738fd"
775 integrity sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A== 902 integrity sha512-/ntT2NljR9foobKk4E/YyOSwcGUXtYWv5tinMK/3RkypyNBNdhHUaq6Orw5DWq9ZcNlS03BIlEALFeQgeVAo4Q==
776 dependencies: 903 dependencies:
777 "@babel/helper-plugin-utils" "^7.14.5" 904 "@babel/helper-plugin-utils" "^7.14.5"
778 905
779"@babel/plugin-transform-template-literals@^7.14.5": 906"@babel/plugin-transform-template-literals@^7.16.0":
780 version "7.14.5" 907 version "7.16.0"
781 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz#a5f2bc233937d8453885dc736bdd8d9ffabf3d93" 908 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.0.tgz#a8eced3a8e7b8e2d40ec4ec4548a45912630d302"
782 integrity sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg== 909 integrity sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q==
783 dependencies: 910 dependencies:
784 "@babel/helper-plugin-utils" "^7.14.5" 911 "@babel/helper-plugin-utils" "^7.14.5"
785 912
786"@babel/plugin-transform-typeof-symbol@^7.14.5": 913"@babel/plugin-transform-typeof-symbol@^7.16.0":
787 version "7.14.5" 914 version "7.16.0"
788 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz#39af2739e989a2bd291bf6b53f16981423d457d4" 915 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.0.tgz#8b19a244c6f8c9d668dca6a6f754ad6ead1128f2"
789 integrity sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw== 916 integrity sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg==
790 dependencies: 917 dependencies:
791 "@babel/helper-plugin-utils" "^7.14.5" 918 "@babel/helper-plugin-utils" "^7.14.5"
792 919
793"@babel/plugin-transform-typescript@^7.15.0": 920"@babel/plugin-transform-typescript@^7.16.0":
794 version "7.15.4" 921 version "7.16.1"
795 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.4.tgz#db7a062dcf8be5fc096bc0eeb40a13fbfa1fa251" 922 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz#cc0670b2822b0338355bc1b3d2246a42b8166409"
796 integrity sha512-sM1/FEjwYjXvMwu1PJStH11kJ154zd/lpY56NQJ5qH2D0mabMv1CAy/kdvS9RP4Xgfj9fBBA3JiSLdDHgXdzOA== 923 integrity sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==
797 dependencies: 924 dependencies:
798 "@babel/helper-create-class-features-plugin" "^7.15.4" 925 "@babel/helper-create-class-features-plugin" "^7.16.0"
799 "@babel/helper-plugin-utils" "^7.14.5" 926 "@babel/helper-plugin-utils" "^7.14.5"
800 "@babel/plugin-syntax-typescript" "^7.14.5" 927 "@babel/plugin-syntax-typescript" "^7.16.0"
801 928
802"@babel/plugin-transform-unicode-escapes@^7.14.5": 929"@babel/plugin-transform-unicode-escapes@^7.16.0":
803 version "7.14.5" 930 version "7.16.0"
804 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" 931 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.0.tgz#1a354064b4c45663a32334f46fa0cf6100b5b1f3"
805 integrity sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA== 932 integrity sha512-VFi4dhgJM7Bpk8lRc5CMaRGlKZ29W9C3geZjt9beuzSUrlJxsNwX7ReLwaL6WEvsOf2EQkyIJEPtF8EXjB/g2A==
806 dependencies: 933 dependencies:
807 "@babel/helper-plugin-utils" "^7.14.5" 934 "@babel/helper-plugin-utils" "^7.14.5"
808 935
809"@babel/plugin-transform-unicode-regex@^7.14.5": 936"@babel/plugin-transform-unicode-regex@^7.16.0":
810 version "7.14.5" 937 version "7.16.0"
811 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz#4cd09b6c8425dd81255c7ceb3fb1836e7414382e" 938 resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.0.tgz#293b80950177c8c85aede87cef280259fb995402"
812 integrity sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw== 939 integrity sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A==
813 dependencies: 940 dependencies:
814 "@babel/helper-create-regexp-features-plugin" "^7.14.5" 941 "@babel/helper-create-regexp-features-plugin" "^7.16.0"
815 "@babel/helper-plugin-utils" "^7.14.5" 942 "@babel/helper-plugin-utils" "^7.14.5"
816 943
817"@babel/preset-env@^7.15.6": 944"@babel/preset-env@^7.16.0":
818 version "7.15.6" 945 version "7.16.0"
819 resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.6.tgz#0f3898db9d63d320f21b17380d8462779de57659" 946 resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.0.tgz#97228393d217560d6a1c6c56f0adb9d12bca67f5"
820 integrity sha512-L+6jcGn7EWu7zqaO2uoTDjjMBW+88FXzV8KvrBl2z6MtRNxlsmUNRlZPaNNPUTgqhyC5DHNFk/2Jmra+ublZWw== 947 integrity sha512-cdTu/W0IrviamtnZiTfixPfIncr2M1VqRrkjzZWlr1B4TVYimCFK5jkyOdP4qw2MrlKHi+b3ORj6x8GoCew8Dg==
821 dependencies: 948 dependencies:
822 "@babel/compat-data" "^7.15.0" 949 "@babel/compat-data" "^7.16.0"
823 "@babel/helper-compilation-targets" "^7.15.4" 950 "@babel/helper-compilation-targets" "^7.16.0"
824 "@babel/helper-plugin-utils" "^7.14.5" 951 "@babel/helper-plugin-utils" "^7.14.5"
825 "@babel/helper-validator-option" "^7.14.5" 952 "@babel/helper-validator-option" "^7.14.5"
826 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.15.4" 953 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.0"
827 "@babel/plugin-proposal-async-generator-functions" "^7.15.4" 954 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0"
828 "@babel/plugin-proposal-class-properties" "^7.14.5" 955 "@babel/plugin-proposal-async-generator-functions" "^7.16.0"
829 "@babel/plugin-proposal-class-static-block" "^7.15.4" 956 "@babel/plugin-proposal-class-properties" "^7.16.0"
830 "@babel/plugin-proposal-dynamic-import" "^7.14.5" 957 "@babel/plugin-proposal-class-static-block" "^7.16.0"
831 "@babel/plugin-proposal-export-namespace-from" "^7.14.5" 958 "@babel/plugin-proposal-dynamic-import" "^7.16.0"
832 "@babel/plugin-proposal-json-strings" "^7.14.5" 959 "@babel/plugin-proposal-export-namespace-from" "^7.16.0"
833 "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" 960 "@babel/plugin-proposal-json-strings" "^7.16.0"
834 "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" 961 "@babel/plugin-proposal-logical-assignment-operators" "^7.16.0"
835 "@babel/plugin-proposal-numeric-separator" "^7.14.5" 962 "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0"
836 "@babel/plugin-proposal-object-rest-spread" "^7.15.6" 963 "@babel/plugin-proposal-numeric-separator" "^7.16.0"
837 "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" 964 "@babel/plugin-proposal-object-rest-spread" "^7.16.0"
838 "@babel/plugin-proposal-optional-chaining" "^7.14.5" 965 "@babel/plugin-proposal-optional-catch-binding" "^7.16.0"
839 "@babel/plugin-proposal-private-methods" "^7.14.5" 966 "@babel/plugin-proposal-optional-chaining" "^7.16.0"
840 "@babel/plugin-proposal-private-property-in-object" "^7.15.4" 967 "@babel/plugin-proposal-private-methods" "^7.16.0"
841 "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" 968 "@babel/plugin-proposal-private-property-in-object" "^7.16.0"
969 "@babel/plugin-proposal-unicode-property-regex" "^7.16.0"
842 "@babel/plugin-syntax-async-generators" "^7.8.4" 970 "@babel/plugin-syntax-async-generators" "^7.8.4"
843 "@babel/plugin-syntax-class-properties" "^7.12.13" 971 "@babel/plugin-syntax-class-properties" "^7.12.13"
844 "@babel/plugin-syntax-class-static-block" "^7.14.5" 972 "@babel/plugin-syntax-class-static-block" "^7.14.5"
@@ -853,50 +981,50 @@
853 "@babel/plugin-syntax-optional-chaining" "^7.8.3" 981 "@babel/plugin-syntax-optional-chaining" "^7.8.3"
854 "@babel/plugin-syntax-private-property-in-object" "^7.14.5" 982 "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
855 "@babel/plugin-syntax-top-level-await" "^7.14.5" 983 "@babel/plugin-syntax-top-level-await" "^7.14.5"
856 "@babel/plugin-transform-arrow-functions" "^7.14.5" 984 "@babel/plugin-transform-arrow-functions" "^7.16.0"
857 "@babel/plugin-transform-async-to-generator" "^7.14.5" 985 "@babel/plugin-transform-async-to-generator" "^7.16.0"
858 "@babel/plugin-transform-block-scoped-functions" "^7.14.5" 986 "@babel/plugin-transform-block-scoped-functions" "^7.16.0"
859 "@babel/plugin-transform-block-scoping" "^7.15.3" 987 "@babel/plugin-transform-block-scoping" "^7.16.0"
860 "@babel/plugin-transform-classes" "^7.15.4" 988 "@babel/plugin-transform-classes" "^7.16.0"
861 "@babel/plugin-transform-computed-properties" "^7.14.5" 989 "@babel/plugin-transform-computed-properties" "^7.16.0"
862 "@babel/plugin-transform-destructuring" "^7.14.7" 990 "@babel/plugin-transform-destructuring" "^7.16.0"
863 "@babel/plugin-transform-dotall-regex" "^7.14.5" 991 "@babel/plugin-transform-dotall-regex" "^7.16.0"
864 "@babel/plugin-transform-duplicate-keys" "^7.14.5" 992 "@babel/plugin-transform-duplicate-keys" "^7.16.0"
865 "@babel/plugin-transform-exponentiation-operator" "^7.14.5" 993 "@babel/plugin-transform-exponentiation-operator" "^7.16.0"
866 "@babel/plugin-transform-for-of" "^7.15.4" 994 "@babel/plugin-transform-for-of" "^7.16.0"
867 "@babel/plugin-transform-function-name" "^7.14.5" 995 "@babel/plugin-transform-function-name" "^7.16.0"
868 "@babel/plugin-transform-literals" "^7.14.5" 996 "@babel/plugin-transform-literals" "^7.16.0"
869 "@babel/plugin-transform-member-expression-literals" "^7.14.5" 997 "@babel/plugin-transform-member-expression-literals" "^7.16.0"
870 "@babel/plugin-transform-modules-amd" "^7.14.5" 998 "@babel/plugin-transform-modules-amd" "^7.16.0"
871 "@babel/plugin-transform-modules-commonjs" "^7.15.4" 999 "@babel/plugin-transform-modules-commonjs" "^7.16.0"
872 "@babel/plugin-transform-modules-systemjs" "^7.15.4" 1000 "@babel/plugin-transform-modules-systemjs" "^7.16.0"
873 "@babel/plugin-transform-modules-umd" "^7.14.5" 1001 "@babel/plugin-transform-modules-umd" "^7.16.0"
874 "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" 1002 "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.0"
875 "@babel/plugin-transform-new-target" "^7.14.5" 1003 "@babel/plugin-transform-new-target" "^7.16.0"
876 "@babel/plugin-transform-object-super" "^7.14.5" 1004 "@babel/plugin-transform-object-super" "^7.16.0"
877 "@babel/plugin-transform-parameters" "^7.15.4" 1005 "@babel/plugin-transform-parameters" "^7.16.0"
878 "@babel/plugin-transform-property-literals" "^7.14.5" 1006 "@babel/plugin-transform-property-literals" "^7.16.0"
879 "@babel/plugin-transform-regenerator" "^7.14.5" 1007 "@babel/plugin-transform-regenerator" "^7.16.0"
880 "@babel/plugin-transform-reserved-words" "^7.14.5" 1008 "@babel/plugin-transform-reserved-words" "^7.16.0"
881 "@babel/plugin-transform-shorthand-properties" "^7.14.5" 1009 "@babel/plugin-transform-shorthand-properties" "^7.16.0"
882 "@babel/plugin-transform-spread" "^7.14.6" 1010 "@babel/plugin-transform-spread" "^7.16.0"
883 "@babel/plugin-transform-sticky-regex" "^7.14.5" 1011 "@babel/plugin-transform-sticky-regex" "^7.16.0"
884 "@babel/plugin-transform-template-literals" "^7.14.5" 1012 "@babel/plugin-transform-template-literals" "^7.16.0"
885 "@babel/plugin-transform-typeof-symbol" "^7.14.5" 1013 "@babel/plugin-transform-typeof-symbol" "^7.16.0"
886 "@babel/plugin-transform-unicode-escapes" "^7.14.5" 1014 "@babel/plugin-transform-unicode-escapes" "^7.16.0"
887 "@babel/plugin-transform-unicode-regex" "^7.14.5" 1015 "@babel/plugin-transform-unicode-regex" "^7.16.0"
888 "@babel/preset-modules" "^0.1.4" 1016 "@babel/preset-modules" "^0.1.5"
889 "@babel/types" "^7.15.6" 1017 "@babel/types" "^7.16.0"
890 babel-plugin-polyfill-corejs2 "^0.2.2" 1018 babel-plugin-polyfill-corejs2 "^0.2.3"
891 babel-plugin-polyfill-corejs3 "^0.2.2" 1019 babel-plugin-polyfill-corejs3 "^0.3.0"
892 babel-plugin-polyfill-regenerator "^0.2.2" 1020 babel-plugin-polyfill-regenerator "^0.2.3"
893 core-js-compat "^3.16.0" 1021 core-js-compat "^3.19.0"
894 semver "^6.3.0" 1022 semver "^6.3.0"
895 1023
896"@babel/preset-modules@^0.1.4": 1024"@babel/preset-modules@^0.1.5":
897 version "0.1.4" 1025 version "0.1.5"
898 resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" 1026 resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9"
899 integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== 1027 integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==
900 dependencies: 1028 dependencies:
901 "@babel/helper-plugin-utils" "^7.0.0" 1029 "@babel/helper-plugin-utils" "^7.0.0"
902 "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" 1030 "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
@@ -904,26 +1032,26 @@
904 "@babel/types" "^7.4.4" 1032 "@babel/types" "^7.4.4"
905 esutils "^2.0.2" 1033 esutils "^2.0.2"
906 1034
907"@babel/preset-react@^7.14.5": 1035"@babel/preset-react@^7.16.0":
908 version "7.14.5" 1036 version "7.16.0"
909 resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.14.5.tgz#0fbb769513f899c2c56f3a882fa79673c2d4ab3c" 1037 resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.16.0.tgz#f71d3e8dff5218478011df037fad52660ee6d82a"
910 integrity sha512-XFxBkjyObLvBaAvkx1Ie95Iaq4S/GUEIrejyrntQ/VCMKUYvKLoyKxOBzJ2kjA3b6rC9/KL6KXfDC2GqvLiNqQ== 1038 integrity sha512-d31IFW2bLRB28uL1WoElyro8RH5l6531XfxMtCeCmp6RVAF1uTfxxUA0LH1tXl+psZdwfmIbwoG4U5VwgbhtLw==
911 dependencies: 1039 dependencies:
912 "@babel/helper-plugin-utils" "^7.14.5" 1040 "@babel/helper-plugin-utils" "^7.14.5"
913 "@babel/helper-validator-option" "^7.14.5" 1041 "@babel/helper-validator-option" "^7.14.5"
914 "@babel/plugin-transform-react-display-name" "^7.14.5" 1042 "@babel/plugin-transform-react-display-name" "^7.16.0"
915 "@babel/plugin-transform-react-jsx" "^7.14.5" 1043 "@babel/plugin-transform-react-jsx" "^7.16.0"
916 "@babel/plugin-transform-react-jsx-development" "^7.14.5" 1044 "@babel/plugin-transform-react-jsx-development" "^7.16.0"
917 "@babel/plugin-transform-react-pure-annotations" "^7.14.5" 1045 "@babel/plugin-transform-react-pure-annotations" "^7.16.0"
918 1046
919"@babel/preset-typescript@^7.15.0": 1047"@babel/preset-typescript@^7.16.0":
920 version "7.15.0" 1048 version "7.16.0"
921 resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945" 1049 resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz#b0b4f105b855fb3d631ec036cdc9d1ffd1fa5eac"
922 integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow== 1050 integrity sha512-txegdrZYgO9DlPbv+9QOVpMnKbOtezsLHWsnsRF4AjbSIsVaujrq1qg8HK0mxQpWv0jnejt0yEoW1uWpvbrDTg==
923 dependencies: 1051 dependencies:
924 "@babel/helper-plugin-utils" "^7.14.5" 1052 "@babel/helper-plugin-utils" "^7.14.5"
925 "@babel/helper-validator-option" "^7.14.5" 1053 "@babel/helper-validator-option" "^7.14.5"
926 "@babel/plugin-transform-typescript" "^7.15.0" 1054 "@babel/plugin-transform-typescript" "^7.16.0"
927 1055
928"@babel/runtime-corejs3@^7.10.2": 1056"@babel/runtime-corejs3@^7.10.2":
929 version "7.15.4" 1057 version "7.15.4"
@@ -940,6 +1068,13 @@
940 dependencies: 1068 dependencies:
941 regenerator-runtime "^0.13.4" 1069 regenerator-runtime "^0.13.4"
942 1070
1071"@babel/runtime@^7.16.0":
1072 version "7.16.0"
1073 resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b"
1074 integrity sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==
1075 dependencies:
1076 regenerator-runtime "^0.13.4"
1077
943"@babel/template@^7.15.4": 1078"@babel/template@^7.15.4":
944 version "7.15.4" 1079 version "7.15.4"
945 resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" 1080 resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194"
@@ -949,7 +1084,16 @@
949 "@babel/parser" "^7.15.4" 1084 "@babel/parser" "^7.15.4"
950 "@babel/types" "^7.15.4" 1085 "@babel/types" "^7.15.4"
951 1086
952"@babel/traverse@^7.13.0", "@babel/traverse@^7.15.4": 1087"@babel/template@^7.16.0":
1088 version "7.16.0"
1089 resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
1090 integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==
1091 dependencies:
1092 "@babel/code-frame" "^7.16.0"
1093 "@babel/parser" "^7.16.0"
1094 "@babel/types" "^7.16.0"
1095
1096"@babel/traverse@^7.13.0":
953 version "7.15.4" 1097 version "7.15.4"
954 resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" 1098 resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d"
955 integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== 1099 integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==
@@ -964,7 +1108,22 @@
964 debug "^4.1.0" 1108 debug "^4.1.0"
965 globals "^11.1.0" 1109 globals "^11.1.0"
966 1110
967"@babel/types@^7.14.9", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.4.4": 1111"@babel/traverse@^7.16.0":
1112 version "7.16.0"
1113 resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.0.tgz#965df6c6bfc0a958c1e739284d3c9fa4a6e3c45b"
1114 integrity sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==
1115 dependencies:
1116 "@babel/code-frame" "^7.16.0"
1117 "@babel/generator" "^7.16.0"
1118 "@babel/helper-function-name" "^7.16.0"
1119 "@babel/helper-hoist-variables" "^7.16.0"
1120 "@babel/helper-split-export-declaration" "^7.16.0"
1121 "@babel/parser" "^7.16.0"
1122 "@babel/types" "^7.16.0"
1123 debug "^4.1.0"
1124 globals "^11.1.0"
1125
1126"@babel/types@^7.15.4", "@babel/types@^7.4.4":
968 version "7.15.6" 1127 version "7.15.6"
969 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" 1128 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f"
970 integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== 1129 integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==
@@ -972,6 +1131,206 @@
972 "@babel/helper-validator-identifier" "^7.14.9" 1131 "@babel/helper-validator-identifier" "^7.14.9"
973 to-fast-properties "^2.0.0" 1132 to-fast-properties "^2.0.0"
974 1133
1134"@babel/types@^7.16.0":
1135 version "7.16.0"
1136 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba"
1137 integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==
1138 dependencies:
1139 "@babel/helper-validator-identifier" "^7.15.7"
1140 to-fast-properties "^2.0.0"
1141
1142"@codemirror/autocomplete@^0.19.4":
1143 version "0.19.4"
1144 resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-0.19.4.tgz#2faff94d5a566864444b22fb765d12a3d328bc02"
1145 integrity sha512-Wuuf4xZ9opIpUwMvxFMknC1C202qtTx1q5bS1GuMnTK4lBYoG+tekpAqlLBF3x6fEe2+fw6dRLwYTigtCuS7pQ==
1146 dependencies:
1147 "@codemirror/language" "^0.19.0"
1148 "@codemirror/state" "^0.19.2"
1149 "@codemirror/text" "^0.19.2"
1150 "@codemirror/tooltip" "^0.19.0"
1151 "@codemirror/view" "^0.19.0"
1152 "@lezer/common" "^0.15.0"
1153
1154"@codemirror/closebrackets@^0.19.0":
1155 version "0.19.0"
1156 resolved "https://registry.yarnpkg.com/@codemirror/closebrackets/-/closebrackets-0.19.0.tgz#69fdcee85779d638a00a42becd9f53a33a26d77f"
1157 integrity sha512-dFWX5OEVYWRNtGaifSbwIAlymnRRjxWMiMbffbAjF7p0zfGHDbdGkiT56q3Xud63h5/tQdSo5dK1iyNTzHz5vg==
1158 dependencies:
1159 "@codemirror/language" "^0.19.0"
1160 "@codemirror/rangeset" "^0.19.0"
1161 "@codemirror/state" "^0.19.0"
1162 "@codemirror/text" "^0.19.0"
1163 "@codemirror/view" "^0.19.0"
1164
1165"@codemirror/commands@^0.19.5":
1166 version "0.19.5"
1167 resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-0.19.5.tgz#2607b5c12c5c96df2cabce2e43f6285c07cfaf11"
1168 integrity sha512-8PZOtx7d/GbKhFYA88zs2wINDtaUgj3pEjLYScKTd/Vsyw8qOp86tJQQNnMFTRZj/ISQl9Lbg3aAmHvroMqspw==
1169 dependencies:
1170 "@codemirror/language" "^0.19.0"
1171 "@codemirror/matchbrackets" "^0.19.0"
1172 "@codemirror/state" "^0.19.2"
1173 "@codemirror/text" "^0.19.0"
1174 "@codemirror/view" "^0.19.0"
1175 "@lezer/common" "^0.15.0"
1176
1177"@codemirror/comment@^0.19.0":
1178 version "0.19.0"
1179 resolved "https://registry.yarnpkg.com/@codemirror/comment/-/comment-0.19.0.tgz#4f23497924e9346898c2e0123011acc535a0bea6"
1180 integrity sha512-3hqAd0548fxqOBm4khFMcXVIivX8p0bSlbAuZJ6PNoUn/0wXhxkxowPp0FmFzU2+y37Z+ZQF5cRB5EREWPRIiQ==
1181 dependencies:
1182 "@codemirror/state" "^0.19.0"
1183 "@codemirror/text" "^0.19.0"
1184 "@codemirror/view" "^0.19.0"
1185
1186"@codemirror/fold@^0.19.1":
1187 version "0.19.1"
1188 resolved "https://registry.yarnpkg.com/@codemirror/fold/-/fold-0.19.1.tgz#52000ff329ab69c4ba32e94401777941e29d8ad0"
1189 integrity sha512-3GwQpxgv03urb8BPBvX1JSjl+uMXKqngRG6qHZXSM2FefxFKvTuyL44MCb35aodtfKjGwoxizk+7b6CbAOLyOw==
1190 dependencies:
1191 "@codemirror/gutter" "^0.19.0"
1192 "@codemirror/language" "^0.19.0"
1193 "@codemirror/rangeset" "^0.19.0"
1194 "@codemirror/state" "^0.19.0"
1195 "@codemirror/view" "^0.19.0"
1196
1197"@codemirror/gutter@^0.19.0":
1198 version "0.19.2"
1199 resolved "https://registry.yarnpkg.com/@codemirror/gutter/-/gutter-0.19.2.tgz#afc61dbe2977ff83aff8675200deab6d04244c5c"
1200 integrity sha512-xiayxhc9uq1UXiG/r/E3AAYXZt+EtSdgdQXC4nlMHvbfw2EmtryfzGO3HrgasHRyAW8uNCaO9JO4n7mU7rm1rQ==
1201 dependencies:
1202 "@codemirror/rangeset" "^0.19.0"
1203 "@codemirror/state" "^0.19.0"
1204 "@codemirror/view" "^0.19.0"
1205
1206"@codemirror/gutter@^0.19.4":
1207 version "0.19.4"
1208 resolved "https://registry.yarnpkg.com/@codemirror/gutter/-/gutter-0.19.4.tgz#7f2f3ceb72b96042380d23316bb6c43a7e05f111"
1209 integrity sha512-zcDtGafuzLs9mvSBqHVuLNbS4UpHBo1+DRY6NtZfC31bV8abDxOPgokq2+6UsVPQp+RA1LgmPHatp4gOYSM+cA==
1210 dependencies:
1211 "@codemirror/rangeset" "^0.19.0"
1212 "@codemirror/state" "^0.19.0"
1213 "@codemirror/view" "^0.19.0"
1214
1215"@codemirror/highlight@^0.19.6":
1216 version "0.19.6"
1217 resolved "https://registry.yarnpkg.com/@codemirror/highlight/-/highlight-0.19.6.tgz#7f2e066f83f5649e8e0748a3abe0aaeaf64b8ac2"
1218 integrity sha512-+eibu6on9quY8uN3xJ/n3rH+YIDLlpX7YulVmFvqAIz/ukRQ5tWaBmB7fMixHmnmRIRBRZgB8rNtonuMwZSAHQ==
1219 dependencies:
1220 "@codemirror/language" "^0.19.0"
1221 "@codemirror/rangeset" "^0.19.0"
1222 "@codemirror/state" "^0.19.0"
1223 "@codemirror/view" "^0.19.0"
1224 "@lezer/common" "^0.15.0"
1225 style-mod "^4.0.0"
1226
1227"@codemirror/history@^0.19.0":
1228 version "0.19.0"
1229 resolved "https://registry.yarnpkg.com/@codemirror/history/-/history-0.19.0.tgz#cc8095c927c9566f7b69fa404074edde4c54d39c"
1230 integrity sha512-E0H+lncH66IMDhaND9jgkjE7s0dhYfjCPmS+Ig2Yes9I8+UIEecIdObj8c8HPCFGctGg3fxXqRAw2mdHl2Wouw==
1231 dependencies:
1232 "@codemirror/state" "^0.19.0"
1233 "@codemirror/view" "^0.19.0"
1234
1235"@codemirror/language@^0.19.0", "@codemirror/language@^0.19.3":
1236 version "0.19.3"
1237 resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-0.19.3.tgz#e4f61555dec0787f757b78348a54a00f3bb23c9c"
1238 integrity sha512-6vjkRYHRJg/z9wdAk75nU2fQwCJBsh2HpkIjKXIHfzISSgLt5qSDxVhPd8Uu8PD5WMmFFP8tX7I9kdIt873o0A==
1239 dependencies:
1240 "@codemirror/state" "^0.19.0"
1241 "@codemirror/text" "^0.19.0"
1242 "@codemirror/view" "^0.19.0"
1243 "@lezer/common" "^0.15.5"
1244 "@lezer/lr" "^0.15.0"
1245
1246"@codemirror/lint@^0.19.2":
1247 version "0.19.2"
1248 resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-0.19.2.tgz#1c3932cffd635da796bea3384256b0a315b6fe1e"
1249 integrity sha512-477qvXWwuf24YsBi1DzjrGyzM+qfPe5L4xEHGxQTGOMq6R0+QAFKppOJsxN3y7gzDpLrZSYZdhJzWevOuliZQg==
1250 dependencies:
1251 "@codemirror/panel" "^0.19.0"
1252 "@codemirror/state" "^0.19.0"
1253 "@codemirror/tooltip" "^0.19.0"
1254 "@codemirror/view" "^0.19.0"
1255 crelt "^1.0.5"
1256
1257"@codemirror/matchbrackets@^0.19.0", "@codemirror/matchbrackets@^0.19.3":
1258 version "0.19.3"
1259 resolved "https://registry.yarnpkg.com/@codemirror/matchbrackets/-/matchbrackets-0.19.3.tgz#1f430ada6fa21af2205280ff344ef57bb95dd3cb"
1260 integrity sha512-ljkrBxaLgh8jesroUiBa57pdEwqJamxkukXrJpL9LdyFZVJaF+9TldhztRaMsMZO1XnCSSHQ9sg32iuHo7Sc2g==
1261 dependencies:
1262 "@codemirror/language" "^0.19.0"
1263 "@codemirror/state" "^0.19.0"
1264 "@codemirror/view" "^0.19.0"
1265 "@lezer/common" "^0.15.0"
1266
1267"@codemirror/panel@^0.19.0":
1268 version "0.19.0"
1269 resolved "https://registry.yarnpkg.com/@codemirror/panel/-/panel-0.19.0.tgz#18c7a253a7a1ef686bece1ef13ec0e5eb6603265"
1270 integrity sha512-LJuu49xnuhaAztlhnLJQ57ddOirSyf8/lnl7twsQUG/05RkxodBZ9F7q8r5AOLqOkaQOy9WySEKX1Ur8lD9Q5w==
1271 dependencies:
1272 "@codemirror/state" "^0.19.0"
1273 "@codemirror/view" "^0.19.0"
1274
1275"@codemirror/rangeset@^0.19.0", "@codemirror/rangeset@^0.19.1":
1276 version "0.19.1"
1277 resolved "https://registry.yarnpkg.com/@codemirror/rangeset/-/rangeset-0.19.1.tgz#03ab6f93fb60d9ba98f810b98ed9471cba1e3854"
1278 integrity sha512-WaKTEw8JB/3QFlQzpdgRoklopcWvG8O/Xp+rxxOfFKYTaeaejpY/tjpyBBg+Ea65Ka3m7+pPp9d5j/oR2rd9NA==
1279 dependencies:
1280 "@codemirror/state" "^0.19.0"
1281
1282"@codemirror/rectangular-selection@^0.19.1":
1283 version "0.19.1"
1284 resolved "https://registry.yarnpkg.com/@codemirror/rectangular-selection/-/rectangular-selection-0.19.1.tgz#5a88ece4fb68ce5682539497db8a64fc015aae63"
1285 integrity sha512-9ElnqOg3mpZIWe0prPRd1SZ48Q9QB3bR8Aocq8UtjboJSUG8ABhRrbuTZMW/rMqpBPSjVpCe9xkCCkEQMYQVmw==
1286 dependencies:
1287 "@codemirror/state" "^0.19.0"
1288 "@codemirror/text" "^0.19.4"
1289 "@codemirror/view" "^0.19.0"
1290
1291"@codemirror/search@^0.19.2":
1292 version "0.19.2"
1293 resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-0.19.2.tgz#d549c3daa527e17c173cdfc90b7c1b02deab1502"
1294 integrity sha512-TrRxUxyJ/a7HXtUvMZhgkOUbKE1xO33UhXjn1XACEHKWhgovw1vEeEEti9dZejN8/QOOFJed39InUxmp7oQ8HA==
1295 dependencies:
1296 "@codemirror/panel" "^0.19.0"
1297 "@codemirror/rangeset" "^0.19.0"
1298 "@codemirror/state" "^0.19.2"
1299 "@codemirror/text" "^0.19.0"
1300 "@codemirror/view" "^0.19.0"
1301 crelt "^1.0.5"
1302
1303"@codemirror/state@^0.19.0", "@codemirror/state@^0.19.2":
1304 version "0.19.2"
1305 resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.19.2.tgz#81de81f89e87b9362b8bc6d51135637dddd4d33d"
1306 integrity sha512-dDqCrtkb0c/LYUlvQBLyLfkISEskbZnhvBbcVOF4j2AusJ1ptJ3EGMxBL9G16GP1TOdC1T613gA1J1qc3pbfGQ==
1307 dependencies:
1308 "@codemirror/text" "^0.19.0"
1309
1310"@codemirror/text@^0.19.0", "@codemirror/text@^0.19.2", "@codemirror/text@^0.19.4":
1311 version "0.19.4"
1312 resolved "https://registry.yarnpkg.com/@codemirror/text/-/text-0.19.4.tgz#522cbe93becdf7637ca7148b67f628b3d8b8fdf5"
1313 integrity sha512-Msd1ImS+Mmref28+oyoOrBwqjH4lbCVO/5ol2jRaCEYH7+KaMocxFADZomPLnMPgDW6Gc4mu/K2lj8IjAOFdTA==
1314
1315"@codemirror/tooltip@^0.19.0":
1316 version "0.19.2"
1317 resolved "https://registry.yarnpkg.com/@codemirror/tooltip/-/tooltip-0.19.2.tgz#a8f6b703edb64748106e136ec1f099a981a3f1d4"
1318 integrity sha512-FMMGGLrr62Ck54NEz8yTGpgo8ihobAsC3sbeQg+OpY4jv9dt1yIP5B9LzsIV+TXQB57JZQZxtTqzkhnFq76haw==
1319 dependencies:
1320 "@codemirror/state" "^0.19.0"
1321 "@codemirror/view" "^0.19.0"
1322
1323"@codemirror/view@^0.19.0", "@codemirror/view@^0.19.9":
1324 version "0.19.9"
1325 resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.19.9.tgz#cbdcbc398818e7c9603c81e4b2a2868ec0a1f954"
1326 integrity sha512-d2Z2rFl53yTwvhsRYtS97xT7ce1f/Q/NNE2uDg/Be1MVjP2v1OlwUTyTosBmxiCt4oUvMklfa+EdPGOATVJhtg==
1327 dependencies:
1328 "@codemirror/rangeset" "^0.19.0"
1329 "@codemirror/state" "^0.19.2"
1330 "@codemirror/text" "^0.19.0"
1331 style-mod "^4.0.0"
1332 w3c-keyname "^2.2.4"
1333
975"@discoveryjs/json-ext@^0.5.0": 1334"@discoveryjs/json-ext@^0.5.0":
976 version "0.5.5" 1335 version "0.5.5"
977 resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" 1336 resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3"
@@ -995,16 +1354,16 @@
995 source-map "^0.5.7" 1354 source-map "^0.5.7"
996 stylis "^4.0.3" 1355 stylis "^4.0.3"
997 1356
998"@emotion/cache@^11.4.0": 1357"@emotion/cache@^11.5.0":
999 version "11.4.0" 1358 version "11.5.0"
1000 resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.4.0.tgz#293fc9d9a7a38b9aad8e9337e5014366c3b09ac0" 1359 resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.5.0.tgz#a5eb78cbef8163939ee345e3ddf0af217b845e62"
1001 integrity sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g== 1360 integrity sha512-mAZ5QRpLriBtaj/k2qyrXwck6yeoz1V5lMt/jfj6igWU35yYlNKs2LziXVgvH81gnJZ+9QQNGelSsnuoAy6uIw==
1002 dependencies: 1361 dependencies:
1003 "@emotion/memoize" "^0.7.4" 1362 "@emotion/memoize" "^0.7.4"
1004 "@emotion/sheet" "^1.0.0" 1363 "@emotion/sheet" "^1.0.3"
1005 "@emotion/utils" "^1.0.0" 1364 "@emotion/utils" "^1.0.0"
1006 "@emotion/weak-memoize" "^0.2.5" 1365 "@emotion/weak-memoize" "^0.2.5"
1007 stylis "^4.0.3" 1366 stylis "^4.0.10"
1008 1367
1009"@emotion/hash@^0.8.0": 1368"@emotion/hash@^0.8.0":
1010 version "0.8.0" 1369 version "0.8.0"
@@ -1023,15 +1382,15 @@
1023 resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" 1382 resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
1024 integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== 1383 integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
1025 1384
1026"@emotion/react@^11.4.1": 1385"@emotion/react@^11.5.0":
1027 version "11.4.1" 1386 version "11.5.0"
1028 resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.4.1.tgz#a1b0b767b5bad57515ffb0cad9349614d27f4d57" 1387 resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.5.0.tgz#19b5771bbfbda5e8517e948a2d9064810f0022bd"
1029 integrity sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg== 1388 integrity sha512-MYq/bzp3rYbee4EMBORCn4duPQfgpiEB5XzrZEBnUZAL80Qdfr7CEv/T80jwaTl/dnZmt9SnTa8NkTrwFNpLlw==
1030 dependencies: 1389 dependencies:
1031 "@babel/runtime" "^7.13.10" 1390 "@babel/runtime" "^7.13.10"
1032 "@emotion/cache" "^11.4.0" 1391 "@emotion/cache" "^11.5.0"
1033 "@emotion/serialize" "^1.0.2" 1392 "@emotion/serialize" "^1.0.2"
1034 "@emotion/sheet" "^1.0.2" 1393 "@emotion/sheet" "^1.0.3"
1035 "@emotion/utils" "^1.0.0" 1394 "@emotion/utils" "^1.0.0"
1036 "@emotion/weak-memoize" "^0.2.5" 1395 "@emotion/weak-memoize" "^0.2.5"
1037 hoist-non-react-statics "^3.3.1" 1396 hoist-non-react-statics "^3.3.1"
@@ -1047,10 +1406,10 @@
1047 "@emotion/utils" "^1.0.0" 1406 "@emotion/utils" "^1.0.0"
1048 csstype "^3.0.2" 1407 csstype "^3.0.2"
1049 1408
1050"@emotion/sheet@^1.0.0", "@emotion/sheet@^1.0.2": 1409"@emotion/sheet@^1.0.3":
1051 version "1.0.2" 1410 version "1.0.3"
1052 resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.2.tgz#1d9ffde531714ba28e62dac6a996a8b1089719d0" 1411 resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.3.tgz#00c326cd7985c5ccb8fe2c1b592886579dcfab8f"
1053 integrity sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw== 1412 integrity sha512-YoX5GyQ4db7LpbmXHMuc8kebtBGP6nZfRC5Z13OKJMixBEwdZrJ914D6yJv/P+ZH/YY3F5s89NYX2hlZAf3SRQ==
1054 1413
1055"@emotion/styled@^11.3.0": 1414"@emotion/styled@^11.3.0":
1056 version "11.3.0" 1415 version "11.3.0"
@@ -1098,7 +1457,7 @@
1098 resolved "https://registry.yarnpkg.com/@fontsource/jetbrains-mono/-/jetbrains-mono-4.5.0.tgz#4cf4014ad1538b1441afb2794097109d8515b7e9" 1457 resolved "https://registry.yarnpkg.com/@fontsource/jetbrains-mono/-/jetbrains-mono-4.5.0.tgz#4cf4014ad1538b1441afb2794097109d8515b7e9"
1099 integrity sha512-gxUlpdCLoIrEQ6+1hkPbFHuQz8E5bPZ/iERU+13zEKb8rD/h21v3uHuAT7dTD+Co9nbSlgk6fyVkFwF5edUMog== 1458 integrity sha512-gxUlpdCLoIrEQ6+1hkPbFHuQz8E5bPZ/iERU+13zEKb8rD/h21v3uHuAT7dTD+Co9nbSlgk6fyVkFwF5edUMog==
1100 1459
1101"@fontsource/roboto@^4.5.0": 1460"@fontsource/roboto@^4.5.1":
1102 version "4.5.1" 1461 version "4.5.1"
1103 resolved "https://registry.yarnpkg.com/@fontsource/roboto/-/roboto-4.5.1.tgz#63f7b783f755d8f6727eb60198627e7e1be3ac20" 1462 resolved "https://registry.yarnpkg.com/@fontsource/roboto/-/roboto-4.5.1.tgz#63f7b783f755d8f6727eb60198627e7e1be3ac20"
1104 integrity sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg== 1463 integrity sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg==
@@ -1117,37 +1476,57 @@
1117 resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" 1476 resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
1118 integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== 1477 integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
1119 1478
1120"@mui/core@5.0.0-alpha.49": 1479"@lezer/common@^0.15.0", "@lezer/common@^0.15.5":
1121 version "5.0.0-alpha.49" 1480 version "0.15.7"
1122 resolved "https://registry.yarnpkg.com/@mui/core/-/core-5.0.0-alpha.49.tgz#e74d6ec7f83f85b55d48aa05ea6b7cefff88ce1b" 1481 resolved "https://registry.yarnpkg.com/@lezer/common/-/common-0.15.7.tgz#8b445dae9777f689783132cf490770ece3c03d7b"
1123 integrity sha512-bZ7UgH84AuKf/IT0U+knHEelDxLV0lNVFg7rKkkDfXEwUpTtAZEtZPFJjNngapSB/4MuFjaFsttex+0DGC5Z1Q== 1482 integrity sha512-Rw8TDJnBzZnkyzIXs1Tmmd241FrBLJBj8gkdy3y0joGFb8Z4I/joKEsR+gv1pb13o1TMsZxm3fmP+d/wPt2CTQ==
1483
1484"@lezer/generator@^0.15.2":
1485 version "0.15.2"
1486 resolved "https://registry.yarnpkg.com/@lezer/generator/-/generator-0.15.2.tgz#10fa8fab58a561c2bd2a27d7b4f20b1080c6cb6c"
1487 integrity sha512-nxY6TTj0ZAcAvg1zEeaZnt1xODdyPhD0lTaPOgcGOVFHhwwx0Oz7CxZB7Rh+xRCXFr5kJWDtM1uXPp80UZjhAg==
1488 dependencies:
1489 "@lezer/common" "^0.15.0"
1490 "@lezer/lr" "^0.15.0"
1491
1492"@lezer/lr@^0.15.0", "@lezer/lr@^0.15.4":
1493 version "0.15.4"
1494 resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.15.4.tgz#634670d7224040fddac1370af01211eecd9ac0a0"
1495 integrity sha512-vwgG80sihEGJn6wJp6VijXrnzVai/KPva/OzYKaWvIx0IiXKjoMQ8UAwcgpSBwfS4Fbz3IKOX/cCNXU3r1FvpQ==
1496 dependencies:
1497 "@lezer/common" "^0.15.0"
1498
1499"@mui/core@5.0.0-alpha.53":
1500 version "5.0.0-alpha.53"
1501 resolved "https://registry.yarnpkg.com/@mui/core/-/core-5.0.0-alpha.53.tgz#ede1445be3bf5a93d25bdd8ead23afdfb1b68f8b"
1502 integrity sha512-dTwuhzE0puewJ+/Cw35iAiaBGVcZqVyqspheQHVJuhysSd+o58SONRAiM6MQgI/iFKiJ57HKh+En1MwuC7DMLw==
1124 dependencies: 1503 dependencies:
1125 "@babel/runtime" "^7.15.4" 1504 "@babel/runtime" "^7.15.4"
1126 "@emotion/is-prop-valid" "^1.1.0" 1505 "@emotion/is-prop-valid" "^1.1.0"
1127 "@mui/utils" "^5.0.1" 1506 "@mui/utils" "^5.0.1"
1507 "@popperjs/core" "^2.4.4"
1128 clsx "^1.1.1" 1508 clsx "^1.1.1"
1129 prop-types "^15.7.2" 1509 prop-types "^15.7.2"
1130 react-is "^17.0.2" 1510 react-is "^17.0.2"
1131 1511
1132"@mui/icons-material@5.0.1": 1512"@mui/icons-material@5.0.5":
1133 version "5.0.1" 1513 version "5.0.5"
1134 resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.0.1.tgz#fb7ffeba0b3604aab4a9b91644d2fc1aabb3b4f1" 1514 resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.0.5.tgz#7af61046da4e54de2da7fcf4bdeb3e439e7c10a7"
1135 integrity sha512-AZehR/Uvi9VodsNPk9ae1lENKrf1evqx9suiP6VIqu7NxjZOlw/m/yA2gRAMmLEmIGr7EChfi/wcXuq6BpM9vw== 1515 integrity sha512-beJo4kmgZwr+2x0ppgHcqqdNQYX4WKddJyMn4eHJAh9dNAGyeY1AJ/8Po+TJKyoSr3C2ZqnW7WrSonAJr2HrUw==
1136 dependencies: 1516 dependencies:
1137 "@babel/runtime" "^7.15.4" 1517 "@babel/runtime" "^7.15.4"
1138 1518
1139"@mui/material@5.0.2": 1519"@mui/material@5.0.6":
1140 version "5.0.2" 1520 version "5.0.6"
1141 resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.0.2.tgz#380cf0ef42c538a68158b4da19c317178b22d10f" 1521 resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.0.6.tgz#0e688c918fd88a07f59385614c65fce937077a9f"
1142 integrity sha512-LD2xHSjTLmbN0UoCuKTu09L/7JjpEzg+Cophf+dVJOTNoK7VI0Eqv3bmpF/9pDIk5dVKmeU9Eh4t2lW1ZifM6A== 1522 integrity sha512-1NmLel2Q+PnSfhFhdrhTbZFLfGpGKcPbu8onwGJu+vbD3YMTjr8gXvQ/sYZC0Motfu8jLnQdlq4FD4fRhqndnw==
1143 dependencies: 1523 dependencies:
1144 "@babel/runtime" "^7.15.4" 1524 "@babel/runtime" "^7.15.4"
1145 "@mui/core" "5.0.0-alpha.49" 1525 "@mui/core" "5.0.0-alpha.53"
1146 "@mui/system" "^5.0.2" 1526 "@mui/system" "^5.0.6"
1147 "@mui/types" "^7.0.0" 1527 "@mui/types" "^7.0.0"
1148 "@mui/utils" "^5.0.1" 1528 "@mui/utils" "^5.0.1"
1149 "@popperjs/core" "^2.4.4" 1529 "@types/react-transition-group" "^4.4.4"
1150 "@types/react-transition-group" "^4.4.3"
1151 clsx "^1.1.1" 1530 clsx "^1.1.1"
1152 csstype "^3.0.9" 1531 csstype "^3.0.9"
1153 hoist-non-react-statics "^3.3.2" 1532 hoist-non-react-statics "^3.3.2"
@@ -1164,23 +1543,23 @@
1164 "@mui/utils" "^5.0.1" 1543 "@mui/utils" "^5.0.1"
1165 prop-types "^15.7.2" 1544 prop-types "^15.7.2"
1166 1545
1167"@mui/styled-engine@^5.0.1": 1546"@mui/styled-engine@^5.0.2":
1168 version "5.0.1" 1547 version "5.0.2"
1169 resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.0.1.tgz#401e3e0ff846ad1b1e7e097c8050b36d7b68343e" 1548 resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.0.2.tgz#a2d188e80d2c8c3501316649c1901a41ac07e376"
1170 integrity sha512-j40nCbaKr1HAZYqpX61XvZYsadYskjo3u6+pRFFaewSViAkkD1rjjbubpnh15nqVfYmijtHMZJ9/l1x1hamvfQ== 1549 integrity sha512-vApnXLj/5V+SbBy+jGFtPgu3tgs0ybSdwWLwXcnUAdNdRyJBffi2KyOP8fhUONLOcZBMU2heNXWz/Zqn5kbDKQ==
1171 dependencies: 1550 dependencies:
1172 "@babel/runtime" "^7.15.4" 1551 "@babel/runtime" "^7.15.4"
1173 "@emotion/cache" "^11.4.0" 1552 "@emotion/cache" "^11.5.0"
1174 prop-types "^15.7.2" 1553 prop-types "^15.7.2"
1175 1554
1176"@mui/system@^5.0.2": 1555"@mui/system@^5.0.6":
1177 version "5.0.2" 1556 version "5.0.6"
1178 resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.0.2.tgz#9999ab61801810ea01c44588fd0dcc1f64dfcedc" 1557 resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.0.6.tgz#053ad18e3888f041137db9f0c0ac1486c86972a0"
1179 integrity sha512-K6wMbiSEYSMeYUw7zmZ2/50JFthqtuTz4OADyKc4ic2RP8ubAf/duH/nkJ4gtsKcewU4RIub0HQHl5F77WVp4Q== 1558 integrity sha512-qZdgODiO82/r1bH9KV5bdqqx/q14i32OGUK/bO6phhXM/DX0TmWSUsnPqFX4F7/UKrvBHsGzIb8ohdRuihQD+Q==
1180 dependencies: 1559 dependencies:
1181 "@babel/runtime" "^7.15.4" 1560 "@babel/runtime" "^7.15.4"
1182 "@mui/private-theming" "^5.0.1" 1561 "@mui/private-theming" "^5.0.1"
1183 "@mui/styled-engine" "^5.0.1" 1562 "@mui/styled-engine" "^5.0.2"
1184 "@mui/types" "^7.0.0" 1563 "@mui/types" "^7.0.0"
1185 "@mui/utils" "^5.0.1" 1564 "@mui/utils" "^5.0.1"
1186 clsx "^1.1.1" 1565 clsx "^1.1.1"
@@ -1239,33 +1618,11 @@
1239 resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" 1618 resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
1240 integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== 1619 integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
1241 1620
1242"@stylelint/postcss-css-in-js@^0.37.2":
1243 version "0.37.2"
1244 resolved "https://registry.yarnpkg.com/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz#7e5a84ad181f4234a2480803422a47b8749af3d2"
1245 integrity sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==
1246 dependencies:
1247 "@babel/core" ">=7.9.0"
1248
1249"@stylelint/postcss-markdown@^0.36.2":
1250 version "0.36.2"
1251 resolved "https://registry.yarnpkg.com/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz#0a540c4692f8dcdfc13c8e352c17e7bfee2bb391"
1252 integrity sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==
1253 dependencies:
1254 remark "^13.0.0"
1255 unist-util-find-all-after "^3.0.2"
1256
1257"@trysound/sax@0.2.0": 1621"@trysound/sax@0.2.0":
1258 version "0.2.0" 1622 version "0.2.0"
1259 resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" 1623 resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
1260 integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== 1624 integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
1261 1625
1262"@types/codemirror@^5.60.3":
1263 version "5.60.4"
1264 resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-5.60.4.tgz#aa19477782fb1bd26f8a0e240ca4241f35c4170e"
1265 integrity sha512-SUQgBj9jZ+xj75zgwfgQZt0CManWBISN/YsE0xRmPwO6uDyLNpXO8bn2m59tpevsFw+eQdmx+qY1WjOrUgMDgw==
1266 dependencies:
1267 "@types/tern" "*"
1268
1269"@types/eslint-scope@^3.7.0": 1626"@types/eslint-scope@^3.7.0":
1270 version "3.7.1" 1627 version "3.7.1"
1271 resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" 1628 resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e"
@@ -1295,10 +1652,10 @@
1295 "@types/minimatch" "*" 1652 "@types/minimatch" "*"
1296 "@types/node" "*" 1653 "@types/node" "*"
1297 1654
1298"@types/html-minifier-terser@^5.0.0": 1655"@types/html-minifier-terser@^6.0.0":
1299 version "5.1.2" 1656 version "6.0.0"
1300 resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" 1657 resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.0.0.tgz#563c1c6c132cd204e71512f9c0b394ff90d3fae7"
1301 integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w== 1658 integrity sha512-NZwaaynfs1oIoLAV1vg18e7QMVDvw+6SQrdJc8w3BwUaoroVSf6EBj/Sk4PBWGxsq0dzhA2drbsuMC1/6C6KgQ==
1302 1659
1303"@types/http-proxy@^1.17.5": 1660"@types/http-proxy@^1.17.5":
1304 version "1.17.7" 1661 version "1.17.7"
@@ -1317,13 +1674,6 @@
1317 resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" 1674 resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
1318 integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= 1675 integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
1319 1676
1320"@types/mdast@^3.0.0":
1321 version "3.0.10"
1322 resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
1323 integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==
1324 dependencies:
1325 "@types/unist" "*"
1326
1327"@types/minimatch@*": 1677"@types/minimatch@*":
1328 version "3.0.5" 1678 version "3.0.5"
1329 resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" 1679 resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
@@ -1354,10 +1704,10 @@
1354 resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" 1704 resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
1355 integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== 1705 integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
1356 1706
1357"@types/react-dom@^17.0.9": 1707"@types/react-dom@^17.0.10":
1358 version "17.0.9" 1708 version "17.0.10"
1359 resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.9.tgz#441a981da9d7be117042e1a6fd3dac4b30f55add" 1709 resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.10.tgz#d6972ec018d23cf22b99597f1289343d99ea9d9d"
1360 integrity sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg== 1710 integrity sha512-8oz3NAUId2z/zQdFI09IMhQPNgIbiP8Lslhv39DIDamr846/0spjZK0vnrMak0iB8EKb9QFTTIdg2Wj2zH5a3g==
1361 dependencies: 1711 dependencies:
1362 "@types/react" "*" 1712 "@types/react" "*"
1363 1713
@@ -1368,10 +1718,10 @@
1368 dependencies: 1718 dependencies:
1369 "@types/react" "*" 1719 "@types/react" "*"
1370 1720
1371"@types/react-transition-group@^4.4.3": 1721"@types/react-transition-group@^4.4.4":
1372 version "4.4.3" 1722 version "4.4.4"
1373 resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.3.tgz#b0994da0a7023d67dbb4a8910a62112bc00d5688" 1723 resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
1374 integrity sha512-fUx5muOWSYP8Bw2BUQ9M9RK9+W1XBK/7FLJ8PTQpnpTEkn0ccyMffyEQvan4C3h53gHdx7KE5Qrxi/LnUGQtdg== 1724 integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
1375 dependencies: 1725 dependencies:
1376 "@types/react" "*" 1726 "@types/react" "*"
1377 1727
@@ -1394,25 +1744,13 @@
1394 resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" 1744 resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
1395 integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== 1745 integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
1396 1746
1397"@types/tern@*": 1747"@typescript-eslint/eslint-plugin@^4.33.0":
1398 version "0.23.4" 1748 version "4.33.0"
1399 resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.4.tgz#03926eb13dbeaf3ae0d390caf706b2643a0127fb" 1749 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276"
1400 integrity sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg== 1750 integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==
1401 dependencies: 1751 dependencies:
1402 "@types/estree" "*" 1752 "@typescript-eslint/experimental-utils" "4.33.0"
1403 1753 "@typescript-eslint/scope-manager" "4.33.0"
1404"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
1405 version "2.0.6"
1406 resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
1407 integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
1408
1409"@typescript-eslint/eslint-plugin@^4.32.0":
1410 version "4.32.0"
1411 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.32.0.tgz#46d2370ae9311092f2a6f7246d28357daf2d4e89"
1412 integrity sha512-+OWTuWRSbWI1KDK8iEyG/6uK2rTm3kpS38wuVifGUTDB6kjEuNrzBI1MUtxnkneuWG/23QehABe2zHHrj+4yuA==
1413 dependencies:
1414 "@typescript-eslint/experimental-utils" "4.32.0"
1415 "@typescript-eslint/scope-manager" "4.32.0"
1416 debug "^4.3.1" 1754 debug "^4.3.1"
1417 functional-red-black-tree "^1.0.1" 1755 functional-red-black-tree "^1.0.1"
1418 ignore "^5.1.8" 1756 ignore "^5.1.8"
@@ -1420,60 +1758,60 @@
1420 semver "^7.3.5" 1758 semver "^7.3.5"
1421 tsutils "^3.21.0" 1759 tsutils "^3.21.0"
1422 1760
1423"@typescript-eslint/experimental-utils@4.32.0": 1761"@typescript-eslint/experimental-utils@4.33.0":
1424 version "4.32.0" 1762 version "4.33.0"
1425 resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.32.0.tgz#53a8267d16ca5a79134739129871966c56a59dc4" 1763 resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd"
1426 integrity sha512-WLoXcc+cQufxRYjTWr4kFt0DyEv6hDgSaFqYhIzQZ05cF+kXfqXdUh+//kgquPJVUBbL3oQGKQxwPbLxHRqm6A== 1764 integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==
1427 dependencies: 1765 dependencies:
1428 "@types/json-schema" "^7.0.7" 1766 "@types/json-schema" "^7.0.7"
1429 "@typescript-eslint/scope-manager" "4.32.0" 1767 "@typescript-eslint/scope-manager" "4.33.0"
1430 "@typescript-eslint/types" "4.32.0" 1768 "@typescript-eslint/types" "4.33.0"
1431 "@typescript-eslint/typescript-estree" "4.32.0" 1769 "@typescript-eslint/typescript-estree" "4.33.0"
1432 eslint-scope "^5.1.1" 1770 eslint-scope "^5.1.1"
1433 eslint-utils "^3.0.0" 1771 eslint-utils "^3.0.0"
1434 1772
1435"@typescript-eslint/parser@^4.32.0": 1773"@typescript-eslint/parser@^4.33.0":
1436 version "4.32.0" 1774 version "4.33.0"
1437 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.32.0.tgz#751ecca0e2fecd3d44484a9b3049ffc1871616e5" 1775 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899"
1438 integrity sha512-lhtYqQ2iEPV5JqV7K+uOVlPePjClj4dOw7K4/Z1F2yvjIUvyr13yJnDzkK6uon4BjHYuHy3EG0c2Z9jEhFk56w== 1776 integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==
1439 dependencies: 1777 dependencies:
1440 "@typescript-eslint/scope-manager" "4.32.0" 1778 "@typescript-eslint/scope-manager" "4.33.0"
1441 "@typescript-eslint/types" "4.32.0" 1779 "@typescript-eslint/types" "4.33.0"
1442 "@typescript-eslint/typescript-estree" "4.32.0" 1780 "@typescript-eslint/typescript-estree" "4.33.0"
1443 debug "^4.3.1" 1781 debug "^4.3.1"
1444 1782
1445"@typescript-eslint/scope-manager@4.32.0": 1783"@typescript-eslint/scope-manager@4.33.0":
1446 version "4.32.0" 1784 version "4.33.0"
1447 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.32.0.tgz#e03c8668f8b954072b3f944d5b799c0c9225a7d5" 1785 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3"
1448 integrity sha512-DK+fMSHdM216C0OM/KR1lHXjP1CNtVIhJ54kQxfOE6x8UGFAjha8cXgDMBEIYS2XCYjjCtvTkjQYwL3uvGOo0w== 1786 integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==
1449 dependencies: 1787 dependencies:
1450 "@typescript-eslint/types" "4.32.0" 1788 "@typescript-eslint/types" "4.33.0"
1451 "@typescript-eslint/visitor-keys" "4.32.0" 1789 "@typescript-eslint/visitor-keys" "4.33.0"
1452 1790
1453"@typescript-eslint/types@4.32.0": 1791"@typescript-eslint/types@4.33.0":
1454 version "4.32.0" 1792 version "4.33.0"
1455 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.32.0.tgz#52c633c18da47aee09449144bf59565ab36df00d" 1793 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72"
1456 integrity sha512-LE7Z7BAv0E2UvqzogssGf1x7GPpUalgG07nGCBYb1oK4mFsOiFC/VrSMKbZQzFJdN2JL5XYmsx7C7FX9p9ns0w== 1794 integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==
1457 1795
1458"@typescript-eslint/typescript-estree@4.32.0": 1796"@typescript-eslint/typescript-estree@4.33.0":
1459 version "4.32.0" 1797 version "4.33.0"
1460 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.32.0.tgz#db00ccc41ccedc8d7367ea3f50c6994b8efa9f3b" 1798 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609"
1461 integrity sha512-tRYCgJ3g1UjMw1cGG8Yn1KzOzNlQ6u1h9AmEtPhb5V5a1TmiHWcRyF/Ic+91M4f43QeChyYlVTcf3DvDTZR9vw== 1799 integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==
1462 dependencies: 1800 dependencies:
1463 "@typescript-eslint/types" "4.32.0" 1801 "@typescript-eslint/types" "4.33.0"
1464 "@typescript-eslint/visitor-keys" "4.32.0" 1802 "@typescript-eslint/visitor-keys" "4.33.0"
1465 debug "^4.3.1" 1803 debug "^4.3.1"
1466 globby "^11.0.3" 1804 globby "^11.0.3"
1467 is-glob "^4.0.1" 1805 is-glob "^4.0.1"
1468 semver "^7.3.5" 1806 semver "^7.3.5"
1469 tsutils "^3.21.0" 1807 tsutils "^3.21.0"
1470 1808
1471"@typescript-eslint/visitor-keys@4.32.0": 1809"@typescript-eslint/visitor-keys@4.33.0":
1472 version "4.32.0" 1810 version "4.33.0"
1473 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.32.0.tgz#455ba8b51242f2722a497ffae29313f33b14cb7f" 1811 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd"
1474 integrity sha512-e7NE0qz8W+atzv3Cy9qaQ7BTLwWsm084Z0c4nIO2l3Bp6u9WIgdqCgyPyV5oSPDMIW3b20H59OOCmVk3jw3Ptw== 1812 integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==
1475 dependencies: 1813 dependencies:
1476 "@typescript-eslint/types" "4.32.0" 1814 "@typescript-eslint/types" "4.33.0"
1477 eslint-visitor-keys "^2.0.0" 1815 eslint-visitor-keys "^2.0.0"
1478 1816
1479"@webassemblyjs/ast@1.11.1": 1817"@webassemblyjs/ast@1.11.1":
@@ -1597,22 +1935,22 @@
1597 "@webassemblyjs/ast" "1.11.1" 1935 "@webassemblyjs/ast" "1.11.1"
1598 "@xtuc/long" "4.2.2" 1936 "@xtuc/long" "4.2.2"
1599 1937
1600"@webpack-cli/configtest@^1.0.4": 1938"@webpack-cli/configtest@^1.1.0":
1601 version "1.0.4" 1939 version "1.1.0"
1602 resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.0.4.tgz#f03ce6311c0883a83d04569e2c03c6238316d2aa" 1940 resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043"
1603 integrity sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ== 1941 integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==
1604 1942
1605"@webpack-cli/info@^1.3.0": 1943"@webpack-cli/info@^1.4.0":
1606 version "1.3.0" 1944 version "1.4.0"
1607 resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.3.0.tgz#9d78a31101a960997a4acd41ffd9b9300627fe2b" 1945 resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223"
1608 integrity sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w== 1946 integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==
1609 dependencies: 1947 dependencies:
1610 envinfo "^7.7.3" 1948 envinfo "^7.7.3"
1611 1949
1612"@webpack-cli/serve@^1.5.2": 1950"@webpack-cli/serve@^1.6.0":
1613 version "1.5.2" 1951 version "1.6.0"
1614 resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.5.2.tgz#ea584b637ff63c5a477f6f21604b5a205b72c9ec" 1952 resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2"
1615 integrity sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw== 1953 integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==
1616 1954
1617"@xtuc/ieee754@^1.2.0": 1955"@xtuc/ieee754@^1.2.0":
1618 version "1.2.0" 1956 version "1.2.0"
@@ -1795,19 +2133,30 @@ array-includes@^3.1.1, array-includes@^3.1.3:
1795 get-intrinsic "^1.1.1" 2133 get-intrinsic "^1.1.1"
1796 is-string "^1.0.5" 2134 is-string "^1.0.5"
1797 2135
2136array-includes@^3.1.4:
2137 version "3.1.4"
2138 resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9"
2139 integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==
2140 dependencies:
2141 call-bind "^1.0.2"
2142 define-properties "^1.1.3"
2143 es-abstract "^1.19.1"
2144 get-intrinsic "^1.1.1"
2145 is-string "^1.0.7"
2146
1798array-union@^2.1.0: 2147array-union@^2.1.0:
1799 version "2.1.0" 2148 version "2.1.0"
1800 resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 2149 resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
1801 integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 2150 integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
1802 2151
1803array.prototype.flat@^1.2.4: 2152array.prototype.flat@^1.2.5:
1804 version "1.2.4" 2153 version "1.2.5"
1805 resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" 2154 resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
1806 integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== 2155 integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
1807 dependencies: 2156 dependencies:
1808 call-bind "^1.0.0" 2157 call-bind "^1.0.2"
1809 define-properties "^1.1.3" 2158 define-properties "^1.1.3"
1810 es-abstract "^1.18.0-next.1" 2159 es-abstract "^1.19.0"
1811 2160
1812array.prototype.flatmap@^1.2.4: 2161array.prototype.flatmap@^1.2.4:
1813 version "1.2.4" 2162 version "1.2.4"
@@ -1841,19 +2190,6 @@ async@^2.6.2:
1841 dependencies: 2190 dependencies:
1842 lodash "^4.17.14" 2191 lodash "^4.17.14"
1843 2192
1844autoprefixer@^9.8.6:
1845 version "9.8.7"
1846 resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.7.tgz#e3c12de18a800af1a1a8155fbc01dc7de29ea184"
1847 integrity sha512-7Hg99B1eTH5+LgmUBUSmov1Z3bsggQJS7v3IMGo6wcScnbRuvtMc871J9J+4bSbIqa9LSX/zypFXJ8sXHpMJeQ==
1848 dependencies:
1849 browserslist "^4.12.0"
1850 caniuse-lite "^1.0.30001109"
1851 nanocolors "^0.2.8"
1852 normalize-range "^0.1.2"
1853 num2fraction "^1.2.2"
1854 postcss "^7.0.32"
1855 postcss-value-parser "^4.1.0"
1856
1857axe-core@^4.0.2: 2193axe-core@^4.0.2:
1858 version "4.3.3" 2194 version "4.3.3"
1859 resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" 2195 resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325"
@@ -1864,10 +2200,10 @@ axobject-query@^2.2.0:
1864 resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" 2200 resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
1865 integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== 2201 integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
1866 2202
1867babel-loader@^8.2.2: 2203babel-loader@^8.2.3:
1868 version "8.2.2" 2204 version "8.2.3"
1869 resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" 2205 resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d"
1870 integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== 2206 integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==
1871 dependencies: 2207 dependencies:
1872 find-cache-dir "^3.3.1" 2208 find-cache-dir "^3.3.1"
1873 loader-utils "^1.4.0" 2209 loader-utils "^1.4.0"
@@ -1890,34 +2226,29 @@ babel-plugin-macros@^2.6.1:
1890 cosmiconfig "^6.0.0" 2226 cosmiconfig "^6.0.0"
1891 resolve "^1.12.0" 2227 resolve "^1.12.0"
1892 2228
1893babel-plugin-polyfill-corejs2@^0.2.2: 2229babel-plugin-polyfill-corejs2@^0.2.3:
1894 version "0.2.2" 2230 version "0.2.3"
1895 resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" 2231 resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.3.tgz#6ed8e30981b062f8fe6aca8873a37ebcc8cc1c0f"
1896 integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== 2232 integrity sha512-NDZ0auNRzmAfE1oDDPW2JhzIMXUk+FFe2ICejmt5T4ocKgiQx3e0VCRx9NCAidcMtL2RUZaWtXnmjTCkx0tcbA==
1897 dependencies: 2233 dependencies:
1898 "@babel/compat-data" "^7.13.11" 2234 "@babel/compat-data" "^7.13.11"
1899 "@babel/helper-define-polyfill-provider" "^0.2.2" 2235 "@babel/helper-define-polyfill-provider" "^0.2.4"
1900 semver "^6.1.1" 2236 semver "^6.1.1"
1901 2237
1902babel-plugin-polyfill-corejs3@^0.2.2: 2238babel-plugin-polyfill-corejs3@^0.3.0:
1903 version "0.2.5" 2239 version "0.3.0"
1904 resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz#2779846a16a1652244ae268b1e906ada107faf92" 2240 resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.3.0.tgz#fa7ca3d1ee9ddc6193600ffb632c9785d54918af"
1905 integrity sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw== 2241 integrity sha512-JLwi9vloVdXLjzACL80j24bG6/T1gYxwowG44dg6HN/7aTPdyPbJJidf6ajoA3RPHHtW0j9KMrSOLpIZpAnPpg==
1906 dependencies: 2242 dependencies:
1907 "@babel/helper-define-polyfill-provider" "^0.2.2" 2243 "@babel/helper-define-polyfill-provider" "^0.2.4"
1908 core-js-compat "^3.16.2" 2244 core-js-compat "^3.18.0"
1909 2245
1910babel-plugin-polyfill-regenerator@^0.2.2: 2246babel-plugin-polyfill-regenerator@^0.2.3:
1911 version "0.2.2" 2247 version "0.2.3"
1912 resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" 2248 resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz#2e9808f5027c4336c994992b48a4262580cb8d6d"
1913 integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== 2249 integrity sha512-JVE78oRZPKFIeUqFGrSORNzQnrDwZR16oiWeGM8ZyjBn2XAT5OjP+wXx5ESuo33nUsFUEJYjtklnsKbxW5L+7g==
1914 dependencies: 2250 dependencies:
1915 "@babel/helper-define-polyfill-provider" "^0.2.2" 2251 "@babel/helper-define-polyfill-provider" "^0.2.4"
1916
1917bail@^1.0.0:
1918 version "1.0.5"
1919 resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
1920 integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==
1921 2252
1922balanced-match@^1.0.0: 2253balanced-match@^1.0.0:
1923 version "1.0.2" 2254 version "1.0.2"
@@ -2053,7 +2384,7 @@ braces@^3.0.1, braces@~3.0.2:
2053 dependencies: 2384 dependencies:
2054 fill-range "^7.0.1" 2385 fill-range "^7.0.1"
2055 2386
2056browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.1: 2387browserslist@^4.14.5, browserslist@^4.16.6:
2057 version "4.17.1" 2388 version "4.17.1"
2058 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.1.tgz#a98d104f54af441290b7d592626dd541fa642eb9" 2389 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.1.tgz#a98d104f54af441290b7d592626dd541fa642eb9"
2059 integrity sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ== 2390 integrity sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==
@@ -2064,6 +2395,17 @@ browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^
2064 nanocolors "^0.1.5" 2395 nanocolors "^0.1.5"
2065 node-releases "^1.1.76" 2396 node-releases "^1.1.76"
2066 2397
2398browserslist@^4.17.5:
2399 version "4.17.5"
2400 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.5.tgz#c827bbe172a4c22b123f5e337533ceebadfdd559"
2401 integrity sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==
2402 dependencies:
2403 caniuse-lite "^1.0.30001271"
2404 electron-to-chromium "^1.3.878"
2405 escalade "^3.1.1"
2406 node-releases "^2.0.1"
2407 picocolors "^1.0.0"
2408
2067buffer-alloc-unsafe@^1.1.0: 2409buffer-alloc-unsafe@^1.1.0:
2068 version "1.1.0" 2410 version "1.1.0"
2069 resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" 2411 resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@@ -2141,7 +2483,7 @@ callsites@^3.0.0:
2141 resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 2483 resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
2142 integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 2484 integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
2143 2485
2144camel-case@^4.1.1: 2486camel-case@^4.1.2:
2145 version "4.1.2" 2487 version "4.1.2"
2146 resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" 2488 resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
2147 integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== 2489 integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
@@ -2176,11 +2518,16 @@ camelcase@^5.3.1:
2176 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 2518 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
2177 integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 2519 integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
2178 2520
2179caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001259: 2521caniuse-lite@^1.0.30001259:
2180 version "1.0.30001261" 2522 version "1.0.30001261"
2181 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001261.tgz#96d89813c076ea061209a4e040d8dcf0c66a1d01" 2523 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001261.tgz#96d89813c076ea061209a4e040d8dcf0c66a1d01"
2182 integrity sha512-vM8D9Uvp7bHIN0fZ2KQ4wnmYFpJo/Etb4Vwsuc+ka0tfGDHvOPrFm6S/7CCNLSOkAUjenT2HnUPESdOIL91FaA== 2524 integrity sha512-vM8D9Uvp7bHIN0fZ2KQ4wnmYFpJo/Etb4Vwsuc+ka0tfGDHvOPrFm6S/7CCNLSOkAUjenT2HnUPESdOIL91FaA==
2183 2525
2526caniuse-lite@^1.0.30001271:
2527 version "1.0.30001274"
2528 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001274.tgz#26ca36204d15b17601ba6fc35dbdad950a647cc7"
2529 integrity sha512-+Nkvv0fHyhISkiMIjnyjmf5YJcQ1IQHZN6U9TLUMroWR38FNwpsC51Gb68yueafX1V6ifOisInSgP9WJFS13ew==
2530
2184caw@^2.0.0, caw@^2.0.1: 2531caw@^2.0.0, caw@^2.0.1:
2185 version "2.0.1" 2532 version "2.0.1"
2186 resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" 2533 resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95"
@@ -2211,7 +2558,7 @@ chalk@^2.0.0:
2211 escape-string-regexp "^1.0.5" 2558 escape-string-regexp "^1.0.5"
2212 supports-color "^5.3.0" 2559 supports-color "^5.3.0"
2213 2560
2214chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: 2561chalk@^4.0.0:
2215 version "4.1.2" 2562 version "4.1.2"
2216 resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 2563 resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
2217 integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 2564 integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -2219,22 +2566,7 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1:
2219 ansi-styles "^4.1.0" 2566 ansi-styles "^4.1.0"
2220 supports-color "^7.1.0" 2567 supports-color "^7.1.0"
2221 2568
2222character-entities-legacy@^1.0.0: 2569"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2:
2223 version "1.1.4"
2224 resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
2225 integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==
2226
2227character-entities@^1.0.0:
2228 version "1.2.4"
2229 resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b"
2230 integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==
2231
2232character-reference-invalid@^1.0.0:
2233 version "1.1.4"
2234 resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
2235 integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
2236
2237"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1:
2238 version "3.5.2" 2570 version "3.5.2"
2239 resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" 2571 resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
2240 integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== 2572 integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
@@ -2254,10 +2586,10 @@ chrome-trace-event@^1.0.2:
2254 resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" 2586 resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
2255 integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== 2587 integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
2256 2588
2257clean-css@^4.2.3: 2589clean-css@^5.1.5:
2258 version "4.2.3" 2590 version "5.2.2"
2259 resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" 2591 resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.2.tgz#d3a7c6ee2511011e051719838bdcf8314dc4548d"
2260 integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== 2592 integrity sha512-/eR8ru5zyxKzpBLv9YZvMXgTSSQn7AdkMItMYynsFgGwTveCRVam9IUPFloE85B4vAIj05IuKmmEoV7/AQjT0w==
2261 dependencies: 2593 dependencies:
2262 source-map "~0.6.0" 2594 source-map "~0.6.0"
2263 2595
@@ -2294,11 +2626,6 @@ clsx@^1.1.1:
2294 resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" 2626 resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
2295 integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== 2627 integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
2296 2628
2297codemirror@^5.63.1:
2298 version "5.63.1"
2299 resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.63.1.tgz#b0b9e8444206fd6a43a58a4b31d5740bb891fa57"
2300 integrity sha512-baivaNZreZOGh1/tYyTvCupC9NeWk7qlZeGUDi4nFKj/J0JU8FYKZND4QqLw70P7HOttlCt4JJAOj9GoIhHEkA==
2301
2302color-convert@^1.9.0: 2629color-convert@^1.9.0:
2303 version "1.9.3" 2630 version "1.9.3"
2304 resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 2631 resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -2323,31 +2650,31 @@ color-name@~1.1.4:
2323 resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 2650 resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
2324 integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 2651 integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
2325 2652
2326colorette@^1.2.1:
2327 version "1.4.0"
2328 resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
2329 integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
2330
2331colorette@^2.0.10: 2653colorette@^2.0.10:
2332 version "2.0.12" 2654 version "2.0.12"
2333 resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.12.tgz#7938ab254e7bb1bba29b0fd1b4cc168889ca4d74" 2655 resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.12.tgz#7938ab254e7bb1bba29b0fd1b4cc168889ca4d74"
2334 integrity sha512-lHID0PU+NtFzeNCwTL6JzUKdb6kDpyEjrwTD1H0cDZswTbsjLh2wTV2Eo2sNZLc0oSg0a5W1AI4Nj7bX4iIdjA== 2656 integrity sha512-lHID0PU+NtFzeNCwTL6JzUKdb6kDpyEjrwTD1H0cDZswTbsjLh2wTV2Eo2sNZLc0oSg0a5W1AI4Nj7bX4iIdjA==
2335 2657
2658colorette@^2.0.14:
2659 version "2.0.16"
2660 resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
2661 integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
2662
2336commander@^2.20.0, commander@^2.8.1: 2663commander@^2.20.0, commander@^2.8.1:
2337 version "2.20.3" 2664 version "2.20.3"
2338 resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 2665 resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
2339 integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 2666 integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
2340 2667
2341commander@^4.1.1:
2342 version "4.1.1"
2343 resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
2344 integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
2345
2346commander@^7.0.0, commander@^7.2.0: 2668commander@^7.0.0, commander@^7.2.0:
2347 version "7.2.0" 2669 version "7.2.0"
2348 resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" 2670 resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
2349 integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== 2671 integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
2350 2672
2673commander@^8.1.0:
2674 version "8.3.0"
2675 resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
2676 integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
2677
2351commondir@^1.0.1: 2678commondir@^1.0.1:
2352 version "1.0.1" 2679 version "1.0.1"
2353 resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" 2680 resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -2430,12 +2757,12 @@ cookie@0.4.0:
2430 resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" 2757 resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
2431 integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== 2758 integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
2432 2759
2433core-js-compat@^3.16.0, core-js-compat@^3.16.2: 2760core-js-compat@^3.18.0, core-js-compat@^3.19.0:
2434 version "3.18.1" 2761 version "3.19.0"
2435 resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.18.1.tgz#01942a0877caf9c6e5007c027183cf0bdae6a191" 2762 resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.0.tgz#b3b93f93c8721b3ed52b91f12f964cc410967f8b"
2436 integrity sha512-XJMYx58zo4W0kLPmIingVZA10+7TuKrMLPt83+EzDmxFJQUMcTVVmQ+n5JP4r6Z14qSzhQBRi3NSWoeVyKKXUg== 2763 integrity sha512-R09rKZ56ccGBebjTLZHvzDxhz93YPT37gBm6qUhnwj3Kt7aCjjZWD1injyNbyeFHxNKfeZBSyds6O9n3MKq1sw==
2437 dependencies: 2764 dependencies:
2438 browserslist "^4.17.1" 2765 browserslist "^4.17.5"
2439 semver "7.0.0" 2766 semver "7.0.0"
2440 2767
2441core-js-pure@^3.16.0: 2768core-js-pure@^3.16.0:
@@ -2459,7 +2786,7 @@ cosmiconfig@^6.0.0:
2459 path-type "^4.0.0" 2786 path-type "^4.0.0"
2460 yaml "^1.7.2" 2787 yaml "^1.7.2"
2461 2788
2462cosmiconfig@^7.0.0: 2789cosmiconfig@^7.0.1:
2463 version "7.0.1" 2790 version "7.0.1"
2464 resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" 2791 resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d"
2465 integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== 2792 integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==
@@ -2470,6 +2797,11 @@ cosmiconfig@^7.0.0:
2470 path-type "^4.0.0" 2797 path-type "^4.0.0"
2471 yaml "^1.10.0" 2798 yaml "^1.10.0"
2472 2799
2800crelt@^1.0.5:
2801 version "1.0.5"
2802 resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.5.tgz#57c0d52af8c859e354bace1883eb2e1eb182bb94"
2803 integrity sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==
2804
2473cross-spawn@^5.0.1: 2805cross-spawn@^5.0.1:
2474 version "5.1.0" 2806 version "5.1.0"
2475 resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 2807 resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -2499,10 +2831,10 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
2499 shebang-command "^2.0.0" 2831 shebang-command "^2.0.0"
2500 which "^2.0.1" 2832 which "^2.0.1"
2501 2833
2502css-loader@^6.3.0: 2834css-loader@^6.5.0:
2503 version "6.3.0" 2835 version "6.5.0"
2504 resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.3.0.tgz#334d3500ff0a0c14cfbd4b0670088dbb5b5c1530" 2836 resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.0.tgz#9d1cf7766a9a8f0b3c6e1638309b964dbdab46d3"
2505 integrity sha512-9NGvHOR+L6ps13Ilw/b216++Q8q+5RpJcVufCdW9S/9iCzs4KBDNa8qnA/n3FK/sSfWmH35PAIK/cfPi7LOSUg== 2837 integrity sha512-VmuSdQa3K+wJsl39i7X3qGBM5+ZHmtTnv65fqMGI+fzmHoYmszTVvTqC1XN8JwWDViCB1a8wgNim5SV4fb37xg==
2506 dependencies: 2838 dependencies:
2507 icss-utils "^5.1.0" 2839 icss-utils "^5.1.0"
2508 postcss "^8.2.15" 2840 postcss "^8.2.15"
@@ -2589,7 +2921,7 @@ debug@^3.1.1, debug@^3.2.7:
2589 dependencies: 2921 dependencies:
2590 ms "^2.1.1" 2922 ms "^2.1.1"
2591 2923
2592debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: 2924debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2:
2593 version "4.3.2" 2925 version "4.3.2"
2594 resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" 2926 resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
2595 integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 2927 integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
@@ -2795,14 +3127,6 @@ dom-helpers@^5.0.1:
2795 "@babel/runtime" "^7.8.7" 3127 "@babel/runtime" "^7.8.7"
2796 csstype "^3.0.2" 3128 csstype "^3.0.2"
2797 3129
2798dom-serializer@0:
2799 version "0.2.2"
2800 resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
2801 integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==
2802 dependencies:
2803 domelementtype "^2.0.1"
2804 entities "^2.0.0"
2805
2806dom-serializer@^1.0.1: 3130dom-serializer@^1.0.1:
2807 version "1.3.2" 3131 version "1.3.2"
2808 resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" 3132 resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
@@ -2812,23 +3136,11 @@ dom-serializer@^1.0.1:
2812 domhandler "^4.2.0" 3136 domhandler "^4.2.0"
2813 entities "^2.0.0" 3137 entities "^2.0.0"
2814 3138
2815domelementtype@1, domelementtype@^1.3.1:
2816 version "1.3.1"
2817 resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
2818 integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
2819
2820domelementtype@^2.0.1, domelementtype@^2.2.0: 3139domelementtype@^2.0.1, domelementtype@^2.2.0:
2821 version "2.2.0" 3140 version "2.2.0"
2822 resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" 3141 resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
2823 integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== 3142 integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
2824 3143
2825domhandler@^2.3.0:
2826 version "2.4.2"
2827 resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
2828 integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
2829 dependencies:
2830 domelementtype "1"
2831
2832domhandler@^4.0.0, domhandler@^4.2.0: 3144domhandler@^4.0.0, domhandler@^4.2.0:
2833 version "4.2.2" 3145 version "4.2.2"
2834 resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" 3146 resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f"
@@ -2836,14 +3148,6 @@ domhandler@^4.0.0, domhandler@^4.2.0:
2836 dependencies: 3148 dependencies:
2837 domelementtype "^2.2.0" 3149 domelementtype "^2.2.0"
2838 3150
2839domutils@^1.5.1:
2840 version "1.7.0"
2841 resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
2842 integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
2843 dependencies:
2844 dom-serializer "0"
2845 domelementtype "1"
2846
2847domutils@^2.5.2, domutils@^2.6.0: 3151domutils@^2.5.2, domutils@^2.6.0:
2848 version "2.8.0" 3152 version "2.8.0"
2849 resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" 3153 resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
@@ -2911,6 +3215,11 @@ electron-to-chromium@^1.3.846:
2911 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.853.tgz#f3ed1d31f092cb3a17af188bca6c6a3ec91c3e82" 3215 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.853.tgz#f3ed1d31f092cb3a17af188bca6c6a3ec91c3e82"
2912 integrity sha512-W4U8n+U8I5/SUaFcqZgbKRmYZwcyEIQVBDf+j5QQK6xChjXnQD+wj248eGR9X4u+dDmDR//8vIfbu4PrdBBIoQ== 3216 integrity sha512-W4U8n+U8I5/SUaFcqZgbKRmYZwcyEIQVBDf+j5QQK6xChjXnQD+wj248eGR9X4u+dDmDR//8vIfbu4PrdBBIoQ==
2913 3217
3218electron-to-chromium@^1.3.878:
3219 version "1.3.885"
3220 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.885.tgz#c8cec32fbc61364127849ae00f2395a1bae7c454"
3221 integrity sha512-JXKFJcVWrdHa09n4CNZYfYaK6EW5aAew7/wr3L1OnsD1L+JHL+RCtd7QgIsxUbFPeTwPlvnpqNNTOLkoefmtXg==
3222
2914emoji-regex@^8.0.0: 3223emoji-regex@^8.0.0:
2915 version "8.0.0" 3224 version "8.0.0"
2916 resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 3225 resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
@@ -2953,11 +3262,6 @@ enquirer@^2.3.5:
2953 dependencies: 3262 dependencies:
2954 ansi-colors "^4.1.1" 3263 ansi-colors "^4.1.1"
2955 3264
2956entities@^1.1.1:
2957 version "1.1.2"
2958 resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
2959 integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
2960
2961entities@^2.0.0: 3265entities@^2.0.0:
2962 version "2.2.0" 3266 version "2.2.0"
2963 resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" 3267 resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
@@ -2999,6 +3303,32 @@ es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.1, es-
2999 string.prototype.trimstart "^1.0.4" 3303 string.prototype.trimstart "^1.0.4"
3000 unbox-primitive "^1.0.1" 3304 unbox-primitive "^1.0.1"
3001 3305
3306es-abstract@^1.19.0, es-abstract@^1.19.1:
3307 version "1.19.1"
3308 resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
3309 integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
3310 dependencies:
3311 call-bind "^1.0.2"
3312 es-to-primitive "^1.2.1"
3313 function-bind "^1.1.1"
3314 get-intrinsic "^1.1.1"
3315 get-symbol-description "^1.0.0"
3316 has "^1.0.3"
3317 has-symbols "^1.0.2"
3318 internal-slot "^1.0.3"
3319 is-callable "^1.2.4"
3320 is-negative-zero "^2.0.1"
3321 is-regex "^1.1.4"
3322 is-shared-array-buffer "^1.0.1"
3323 is-string "^1.0.7"
3324 is-weakref "^1.0.1"
3325 object-inspect "^1.11.0"
3326 object-keys "^1.1.1"
3327 object.assign "^4.1.2"
3328 string.prototype.trimend "^1.0.4"
3329 string.prototype.trimstart "^1.0.4"
3330 unbox-primitive "^1.0.1"
3331
3002es-module-lexer@^0.9.0: 3332es-module-lexer@^0.9.0:
3003 version "0.9.1" 3333 version "0.9.1"
3004 resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.1.tgz#f203bf394a630a552d381acf01a17ef08843b140" 3334 resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.1.tgz#f203bf394a630a552d381acf01a17ef08843b140"
@@ -3033,7 +3363,12 @@ escape-string-regexp@^4.0.0:
3033 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 3363 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
3034 integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 3364 integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
3035 3365
3036eslint-config-airbnb-base@^14.2.1: 3366escape-string-regexp@^5.0.0:
3367 version "5.0.0"
3368 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
3369 integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
3370
3371eslint-config-airbnb-base@14.2.1, eslint-config-airbnb-base@^14.2.1:
3037 version "14.2.1" 3372 version "14.2.1"
3038 resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" 3373 resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e"
3039 integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== 3374 integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==
@@ -3042,10 +3377,12 @@ eslint-config-airbnb-base@^14.2.1:
3042 object.assign "^4.1.2" 3377 object.assign "^4.1.2"
3043 object.entries "^1.1.2" 3378 object.entries "^1.1.2"
3044 3379
3045eslint-config-airbnb-typescript@^14.0.0: 3380eslint-config-airbnb-typescript@^14.0.1:
3046 version "14.0.0" 3381 version "14.0.1"
3047 resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-14.0.0.tgz#fc22246973b99f0820e2ad1ab929fdd011dfa039" 3382 resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-14.0.1.tgz#6721eb320d3953ae0d4bf258e877900fcb543a38"
3048 integrity sha512-d2Nit2ByZARGRYK6tgSNl3nnmGZPyvsgbsKFcmm+nAhvT8VjVpifG5jI4tzObUUPb0sWw0E1oO/0pSpBD/pIuQ== 3383 integrity sha512-tF4GwC3sRrw8kEj4/yxX8F7AcLzj/1IESBnsCiFMplzYmxre459qm2z9DFkCpqBVQFSH6j2K4+VKVteX4m0GsQ==
3384 dependencies:
3385 eslint-config-airbnb-base "14.2.1"
3049 3386
3050eslint-config-airbnb@^18.2.1: 3387eslint-config-airbnb@^18.2.1:
3051 version "18.2.1" 3388 version "18.2.1"
@@ -3064,32 +3401,31 @@ eslint-import-resolver-node@^0.3.6:
3064 debug "^3.2.7" 3401 debug "^3.2.7"
3065 resolve "^1.20.0" 3402 resolve "^1.20.0"
3066 3403
3067eslint-module-utils@^2.6.2: 3404eslint-module-utils@^2.7.0:
3068 version "2.6.2" 3405 version "2.7.1"
3069 resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" 3406 resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c"
3070 integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== 3407 integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==
3071 dependencies: 3408 dependencies:
3072 debug "^3.2.7" 3409 debug "^3.2.7"
3410 find-up "^2.1.0"
3073 pkg-dir "^2.0.0" 3411 pkg-dir "^2.0.0"
3074 3412
3075eslint-plugin-import@^2.24.2: 3413eslint-plugin-import@^2.25.2:
3076 version "2.24.2" 3414 version "2.25.2"
3077 resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" 3415 resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz#b3b9160efddb702fc1636659e71ba1d10adbe9e9"
3078 integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== 3416 integrity sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==
3079 dependencies: 3417 dependencies:
3080 array-includes "^3.1.3" 3418 array-includes "^3.1.4"
3081 array.prototype.flat "^1.2.4" 3419 array.prototype.flat "^1.2.5"
3082 debug "^2.6.9" 3420 debug "^2.6.9"
3083 doctrine "^2.1.0" 3421 doctrine "^2.1.0"
3084 eslint-import-resolver-node "^0.3.6" 3422 eslint-import-resolver-node "^0.3.6"
3085 eslint-module-utils "^2.6.2" 3423 eslint-module-utils "^2.7.0"
3086 find-up "^2.0.0"
3087 has "^1.0.3" 3424 has "^1.0.3"
3088 is-core-module "^2.6.0" 3425 is-core-module "^2.7.0"
3426 is-glob "^4.0.3"
3089 minimatch "^3.0.4" 3427 minimatch "^3.0.4"
3090 object.values "^1.1.4" 3428 object.values "^1.1.5"
3091 pkg-up "^2.0.0"
3092 read-pkg-up "^3.0.0"
3093 resolve "^1.20.0" 3429 resolve "^1.20.0"
3094 tsconfig-paths "^3.11.0" 3430 tsconfig-paths "^3.11.0"
3095 3431
@@ -3408,17 +3744,12 @@ ext-name@^5.0.0:
3408 ext-list "^2.0.0" 3744 ext-list "^2.0.0"
3409 sort-keys-length "^1.0.0" 3745 sort-keys-length "^1.0.0"
3410 3746
3411extend@^3.0.0:
3412 version "3.0.2"
3413 resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
3414 integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
3415
3416fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 3747fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
3417 version "3.1.3" 3748 version "3.1.3"
3418 resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 3749 resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
3419 integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 3750 integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
3420 3751
3421fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.5: 3752fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.7:
3422 version "3.2.7" 3753 version "3.2.7"
3423 resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" 3754 resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
3424 integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== 3755 integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==
@@ -3578,7 +3909,7 @@ find-up@^1.0.0:
3578 path-exists "^2.0.0" 3909 path-exists "^2.0.0"
3579 pinkie-promise "^2.0.0" 3910 pinkie-promise "^2.0.0"
3580 3911
3581find-up@^2.0.0, find-up@^2.1.0: 3912find-up@^2.1.0:
3582 version "2.1.0" 3913 version "2.1.0"
3583 resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" 3914 resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
3584 integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= 3915 integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
@@ -3813,7 +4144,7 @@ globby@^10.0.0:
3813 merge2 "^1.2.3" 4144 merge2 "^1.2.3"
3814 slash "^3.0.0" 4145 slash "^3.0.0"
3815 4146
3816globby@^11.0.1, globby@^11.0.3: 4147globby@^11.0.1, globby@^11.0.3, globby@^11.0.4:
3817 version "11.0.4" 4148 version "11.0.4"
3818 resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" 4149 resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
3819 integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== 4150 integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
@@ -3830,13 +4161,6 @@ globjoin@^0.1.4:
3830 resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" 4161 resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
3831 integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= 4162 integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=
3832 4163
3833gonzales-pe@^4.3.0:
3834 version "4.3.0"
3835 resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3"
3836 integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==
3837 dependencies:
3838 minimist "^1.2.5"
3839
3840got@^7.0.0: 4164got@^7.0.0:
3841 version "7.1.0" 4165 version "7.1.0"
3842 resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" 4166 resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
@@ -3987,47 +4311,35 @@ html-entities@^2.3.2:
3987 resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" 4311 resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488"
3988 integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== 4312 integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==
3989 4313
3990html-minifier-terser@^5.0.1: 4314html-minifier-terser@^6.0.2:
3991 version "5.1.1" 4315 version "6.0.2"
3992 resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" 4316 resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.0.2.tgz#14059ad64b69bf9f8b8a33f25b53411d8321e75d"
3993 integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== 4317 integrity sha512-AgYO3UGhMYQx2S/FBJT3EM0ZYcKmH6m9XL9c1v77BeK/tYJxGPxT1/AtsdUi4FcP8kZGmqqnItCcjFPcX9hk6A==
3994 dependencies: 4318 dependencies:
3995 camel-case "^4.1.1" 4319 camel-case "^4.1.2"
3996 clean-css "^4.2.3" 4320 clean-css "^5.1.5"
3997 commander "^4.1.1" 4321 commander "^8.1.0"
3998 he "^1.2.0" 4322 he "^1.2.0"
3999 param-case "^3.0.3" 4323 param-case "^3.0.4"
4000 relateurl "^0.2.7" 4324 relateurl "^0.2.7"
4001 terser "^4.6.3" 4325 terser "^5.7.2"
4002 4326
4003html-tags@^3.1.0: 4327html-tags@^3.1.0:
4004 version "3.1.0" 4328 version "3.1.0"
4005 resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" 4329 resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
4006 integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== 4330 integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
4007 4331
4008html-webpack-plugin@^5.3.2: 4332html-webpack-plugin@^5.5.0:
4009 version "5.3.2" 4333 version "5.5.0"
4010 resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.3.2.tgz#7b04bf80b1f6fe84a6d3f66c8b79d64739321b08" 4334 resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50"
4011 integrity sha512-HvB33boVNCz2lTyBsSiMffsJ+m0YLIQ+pskblXgN9fnjS1BgEcuAfdInfXfGrkdXV406k9FiDi86eVCDBgJOyQ== 4335 integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==
4012 dependencies: 4336 dependencies:
4013 "@types/html-minifier-terser" "^5.0.0" 4337 "@types/html-minifier-terser" "^6.0.0"
4014 html-minifier-terser "^5.0.1" 4338 html-minifier-terser "^6.0.2"
4015 lodash "^4.17.21" 4339 lodash "^4.17.21"
4016 pretty-error "^3.0.4" 4340 pretty-error "^4.0.0"
4017 tapable "^2.0.0" 4341 tapable "^2.0.0"
4018 4342
4019htmlparser2@^3.10.0:
4020 version "3.10.1"
4021 resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
4022 integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
4023 dependencies:
4024 domelementtype "^1.3.1"
4025 domhandler "^2.3.0"
4026 domutils "^1.5.1"
4027 entities "^1.1.1"
4028 inherits "^2.0.1"
4029 readable-stream "^3.1.1"
4030
4031htmlparser2@^6.1.0: 4343htmlparser2@^6.1.0:
4032 version "6.1.0" 4344 version "6.1.0"
4033 resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" 4345 resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
@@ -4345,19 +4657,6 @@ ipaddr.js@^2.0.1:
4345 resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" 4657 resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0"
4346 integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== 4658 integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==
4347 4659
4348is-alphabetical@^1.0.0:
4349 version "1.0.4"
4350 resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
4351 integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==
4352
4353is-alphanumerical@^1.0.0:
4354 version "1.0.4"
4355 resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf"
4356 integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==
4357 dependencies:
4358 is-alphabetical "^1.0.0"
4359 is-decimal "^1.0.0"
4360
4361is-arguments@^1.0.4: 4660is-arguments@^1.0.4:
4362 version "1.1.1" 4661 version "1.1.1"
4363 resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" 4662 resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
@@ -4393,23 +4692,25 @@ is-boolean-object@^1.1.0:
4393 call-bind "^1.0.2" 4692 call-bind "^1.0.2"
4394 has-tostringtag "^1.0.0" 4693 has-tostringtag "^1.0.0"
4395 4694
4396is-buffer@^2.0.0:
4397 version "2.0.5"
4398 resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
4399 integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
4400
4401is-callable@^1.1.4, is-callable@^1.2.4: 4695is-callable@^1.1.4, is-callable@^1.2.4:
4402 version "1.2.4" 4696 version "1.2.4"
4403 resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" 4697 resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
4404 integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== 4698 integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
4405 4699
4406is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.6.0: 4700is-core-module@^2.2.0, is-core-module@^2.5.0:
4407 version "2.7.0" 4701 version "2.7.0"
4408 resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" 4702 resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3"
4409 integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== 4703 integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==
4410 dependencies: 4704 dependencies:
4411 has "^1.0.3" 4705 has "^1.0.3"
4412 4706
4707is-core-module@^2.7.0:
4708 version "2.8.0"
4709 resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548"
4710 integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
4711 dependencies:
4712 has "^1.0.3"
4713
4413is-cwebp-readable@^3.0.0: 4714is-cwebp-readable@^3.0.0:
4414 version "3.0.0" 4715 version "3.0.0"
4415 resolved "https://registry.yarnpkg.com/is-cwebp-readable/-/is-cwebp-readable-3.0.0.tgz#0554aaa400977a2fc4de366d8c0244f13cde58cb" 4716 resolved "https://registry.yarnpkg.com/is-cwebp-readable/-/is-cwebp-readable-3.0.0.tgz#0554aaa400977a2fc4de366d8c0244f13cde58cb"
@@ -4424,11 +4725,6 @@ is-date-object@^1.0.1:
4424 dependencies: 4725 dependencies:
4425 has-tostringtag "^1.0.0" 4726 has-tostringtag "^1.0.0"
4426 4727
4427is-decimal@^1.0.0:
4428 version "1.0.4"
4429 resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5"
4430 integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==
4431
4432is-docker@^2.0.0, is-docker@^2.1.1: 4728is-docker@^2.0.0, is-docker@^2.1.1:
4433 version "2.2.1" 4729 version "2.2.1"
4434 resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" 4730 resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
@@ -4463,10 +4759,12 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
4463 dependencies: 4759 dependencies:
4464 is-extglob "^2.1.1" 4760 is-extglob "^2.1.1"
4465 4761
4466is-hexadecimal@^1.0.0: 4762is-glob@^4.0.3:
4467 version "1.0.4" 4763 version "4.0.3"
4468 resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" 4764 resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
4469 integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== 4765 integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
4766 dependencies:
4767 is-extglob "^2.1.1"
4470 4768
4471is-ip@^3.1.0: 4769is-ip@^3.1.0:
4472 version "3.1.0" 4770 version "3.1.0"
@@ -4522,11 +4820,6 @@ is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
4522 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" 4820 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
4523 integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= 4821 integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
4524 4822
4525is-plain-obj@^2.0.0:
4526 version "2.1.0"
4527 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
4528 integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
4529
4530is-plain-obj@^3.0.0: 4823is-plain-obj@^3.0.0:
4531 version "3.0.0" 4824 version "3.0.0"
4532 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" 4825 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7"
@@ -4539,6 +4832,11 @@ is-plain-object@^2.0.4:
4539 dependencies: 4832 dependencies:
4540 isobject "^3.0.1" 4833 isobject "^3.0.1"
4541 4834
4835is-plain-object@^5.0.0:
4836 version "5.0.0"
4837 resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
4838 integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
4839
4542is-png@^2.0.0: 4840is-png@^2.0.0:
4543 version "2.0.0" 4841 version "2.0.0"
4544 resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" 4842 resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d"
@@ -4562,6 +4860,11 @@ is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
4562 resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" 4860 resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
4563 integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== 4861 integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
4564 4862
4863is-shared-array-buffer@^1.0.1:
4864 version "1.0.1"
4865 resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
4866 integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
4867
4565is-stream@^1.0.0, is-stream@^1.1.0: 4868is-stream@^1.0.0, is-stream@^1.1.0:
4566 version "1.1.0" 4869 version "1.1.0"
4567 resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 4870 resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -4598,16 +4901,18 @@ is-typedarray@^1.0.0:
4598 resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 4901 resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
4599 integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 4902 integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
4600 4903
4601is-unicode-supported@^0.1.0:
4602 version "0.1.0"
4603 resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
4604 integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
4605
4606is-utf8@^0.2.0: 4904is-utf8@^0.2.0:
4607 version "0.2.1" 4905 version "0.2.1"
4608 resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 4906 resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
4609 integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= 4907 integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
4610 4908
4909is-weakref@^1.0.1:
4910 version "1.0.1"
4911 resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2"
4912 integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==
4913 dependencies:
4914 call-bind "^1.0.0"
4915
4611is-wsl@^2.2.0: 4916is-wsl@^2.2.0:
4612 version "2.2.0" 4917 version "2.2.0"
4613 resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" 4918 resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
@@ -4647,11 +4952,6 @@ jest-worker@^27.0.6:
4647 merge-stream "^2.0.0" 4952 merge-stream "^2.0.0"
4648 supports-color "^8.0.0" 4953 supports-color "^8.0.0"
4649 4954
4650jquery@^3.6.0:
4651 version "3.6.0"
4652 resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470"
4653 integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==
4654
4655"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 4955"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
4656 version "4.0.0" 4956 version "4.0.0"
4657 resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 4957 resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -4680,7 +4980,7 @@ json-buffer@3.0.0:
4680 resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" 4980 resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
4681 integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= 4981 integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
4682 4982
4683json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: 4983json-parse-better-errors@^1.0.2:
4684 version "1.0.2" 4984 version "1.0.2"
4685 resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" 4985 resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
4686 integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== 4986 integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
@@ -4749,10 +5049,10 @@ klona@^2.0.4:
4749 resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" 5049 resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
4750 integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== 5050 integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==
4751 5051
4752known-css-properties@^0.21.0: 5052known-css-properties@^0.23.0:
4753 version "0.21.0" 5053 version "0.23.0"
4754 resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.21.0.tgz#15fbd0bbb83447f3ce09d8af247ed47c68ede80d" 5054 resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.23.0.tgz#e643e1bab2b1f8ba292eea9557121cc02e9846a0"
4755 integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw== 5055 integrity sha512-h9ivI88e1lFNmTT4HovBN33Ysn0OIJG7IPG2mkpx2uniQXFWqo35QdiX7w0TovlUFXfW8aPFblP5/q0jlOr2sA==
4756 5056
4757language-subtag-registry@~0.3.2: 5057language-subtag-registry@~0.3.2:
4758 version "0.3.21" 5058 version "0.3.21"
@@ -4790,16 +5090,6 @@ load-json-file@^1.0.0:
4790 pinkie-promise "^2.0.0" 5090 pinkie-promise "^2.0.0"
4791 strip-bom "^2.0.0" 5091 strip-bom "^2.0.0"
4792 5092
4793load-json-file@^4.0.0:
4794 version "4.0.0"
4795 resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
4796 integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs=
4797 dependencies:
4798 graceful-fs "^4.1.2"
4799 parse-json "^4.0.0"
4800 pify "^3.0.0"
4801 strip-bom "^3.0.0"
4802
4803loader-runner@^4.2.0: 5093loader-runner@^4.2.0:
4804 version "4.2.0" 5094 version "4.2.0"
4805 resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" 5095 resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
@@ -4863,14 +5153,6 @@ lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21:
4863 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 5153 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
4864 integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 5154 integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
4865 5155
4866log-symbols@^4.1.0:
4867 version "4.1.0"
4868 resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
4869 integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
4870 dependencies:
4871 chalk "^4.1.0"
4872 is-unicode-supported "^0.1.0"
4873
4874logalot@^2.0.0, logalot@^2.1.0: 5156logalot@^2.0.0, logalot@^2.1.0:
4875 version "2.1.0" 5157 version "2.1.0"
4876 resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" 5158 resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552"
@@ -4889,11 +5171,6 @@ loglevel@^1.7.1:
4889 resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" 5171 resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
4890 integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== 5172 integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
4891 5173
4892longest-streak@^2.0.0:
4893 version "2.0.4"
4894 resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
4895 integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
4896
4897longest@^1.0.0: 5174longest@^1.0.0:
4898 version "1.0.1" 5175 version "1.0.1"
4899 resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" 5176 resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -4994,34 +5271,6 @@ mathml-tag-names@^2.1.3:
4994 resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" 5271 resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
4995 integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== 5272 integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
4996 5273
4997mdast-util-from-markdown@^0.8.0:
4998 version "0.8.5"
4999 resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c"
5000 integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==
5001 dependencies:
5002 "@types/mdast" "^3.0.0"
5003 mdast-util-to-string "^2.0.0"
5004 micromark "~2.11.0"
5005 parse-entities "^2.0.0"
5006 unist-util-stringify-position "^2.0.0"
5007
5008mdast-util-to-markdown@^0.6.0:
5009 version "0.6.5"
5010 resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe"
5011 integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==
5012 dependencies:
5013 "@types/unist" "^2.0.0"
5014 longest-streak "^2.0.0"
5015 mdast-util-to-string "^2.0.0"
5016 parse-entities "^2.0.0"
5017 repeat-string "^1.0.0"
5018 zwitch "^1.0.0"
5019
5020mdast-util-to-string@^2.0.0:
5021 version "2.0.0"
5022 resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
5023 integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==
5024
5025mdn-data@2.0.14: 5274mdn-data@2.0.14:
5026 version "2.0.14" 5275 version "2.0.14"
5027 resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" 5276 resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
@@ -5093,14 +5342,6 @@ methods@~1.1.2:
5093 resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 5342 resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
5094 integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 5343 integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
5095 5344
5096micromark@~2.11.0:
5097 version "2.11.4"
5098 resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a"
5099 integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==
5100 dependencies:
5101 debug "^4.0.0"
5102 parse-entities "^2.0.0"
5103
5104micromatch@^4.0.2, micromatch@^4.0.4: 5345micromatch@^4.0.2, micromatch@^4.0.4:
5105 version "4.0.4" 5346 version "4.0.4"
5106 resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" 5347 resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
@@ -5146,10 +5387,10 @@ min-indent@^1.0.0:
5146 resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" 5387 resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
5147 integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== 5388 integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
5148 5389
5149mini-css-extract-plugin@^2.3.0: 5390mini-css-extract-plugin@^2.4.3:
5150 version "2.3.0" 5391 version "2.4.3"
5151 resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.3.0.tgz#87515f185533752944d753ac7216fc876779dafe" 5392 resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.4.3.tgz#be742943c192b028645d4389084ef187615fff82"
5152 integrity sha512-uzWaOwC+gJrnKbr23J1ZRWx/Wd9W9Ce1mKPlsBGBV/r8zG7/G7oKMxGmxbI65pVGbae2cR7CUx9Ulk0HQt8BfQ== 5393 integrity sha512-zekavl9mZuGyk7COjsfFY/f655AX61EKE0AthXPrmDk+oZyjZ9WzO4WPjXnnO9xl8obK2kmM6rAQrBEmk+WK1g==
5153 dependencies: 5394 dependencies:
5154 schema-utils "^3.1.0" 5395 schema-utils "^3.1.0"
5155 5396
@@ -5191,10 +5432,10 @@ mobx-react-lite@^3.2.1:
5191 resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.1.tgz#c549a3722f1eae51a78b12f839311614d5689c58" 5432 resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.1.tgz#c549a3722f1eae51a78b12f839311614d5689c58"
5192 integrity sha512-hwURgfmP2apX3HQrB55V9DN47kuN3C6KlQvI5UIfJRibXma72C/JudcNt2r9dWjAdFMrcZoz1ivvtXMCkJ2aQA== 5433 integrity sha512-hwURgfmP2apX3HQrB55V9DN47kuN3C6KlQvI5UIfJRibXma72C/JudcNt2r9dWjAdFMrcZoz1ivvtXMCkJ2aQA==
5193 5434
5194mobx@^6.3.3: 5435mobx@^6.3.5:
5195 version "6.3.3" 5436 version "6.3.5"
5196 resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.3.tgz#a3006c56243b1c7ea4ee671a66f963b9f43cf1af" 5437 resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.5.tgz#4464565bf2fa0f74f5dc2e4d6a9713bcee0ddf9c"
5197 integrity sha512-JoNU50rO6d1wHwKPJqKq4rmUMbYnI9CsJmBo+Cu4exBYenFvIN77LWrZENpzW6reZPADtXMmB1DicbDSfy8Clw== 5438 integrity sha512-MeDfqtiSbhVoJgXqQsrJwvq2klj7Xk9pPdMThCdFiwFt33vgWJe82ATppPwVzQoz0AI3QpSSwQzcp3TBDK4syg==
5198 5439
5199mozjpeg@^7.0.0: 5440mozjpeg@^7.0.0:
5200 version "7.1.0" 5441 version "7.1.0"
@@ -5243,7 +5484,7 @@ nanocolors@^0.1.12, nanocolors@^0.1.5:
5243 resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6" 5484 resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6"
5244 integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ== 5485 integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==
5245 5486
5246nanocolors@^0.2.2, nanocolors@^0.2.8: 5487nanocolors@^0.2.2:
5247 version "0.2.12" 5488 version "0.2.12"
5248 resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.2.12.tgz#4d05932e70116078673ea4cc6699a1c56cc77777" 5489 resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.2.12.tgz#4d05932e70116078673ea4cc6699a1c56cc77777"
5249 integrity sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug== 5490 integrity sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug==
@@ -5253,6 +5494,11 @@ nanoid@^3.1.25:
5253 resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.28.tgz#3c01bac14cb6c5680569014cc65a2f26424c6bd4" 5494 resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.28.tgz#3c01bac14cb6c5680569014cc65a2f26424c6bd4"
5254 integrity sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw== 5495 integrity sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw==
5255 5496
5497nanoid@^3.1.30:
5498 version "3.1.30"
5499 resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
5500 integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
5501
5256natural-compare@^1.4.0: 5502natural-compare@^1.4.0:
5257 version "1.4.0" 5503 version "1.4.0"
5258 resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 5504 resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -5291,6 +5537,11 @@ node-releases@^1.1.76:
5291 resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.76.tgz#df245b062b0cafbd5282ab6792f7dccc2d97f36e" 5537 resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.76.tgz#df245b062b0cafbd5282ab6792f7dccc2d97f36e"
5292 integrity sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA== 5538 integrity sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==
5293 5539
5540node-releases@^2.0.1:
5541 version "2.0.1"
5542 resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5"
5543 integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==
5544
5294normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: 5545normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0:
5295 version "2.5.0" 5546 version "2.5.0"
5296 resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" 5547 resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -5316,11 +5567,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
5316 resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 5567 resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
5317 integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 5568 integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
5318 5569
5319normalize-range@^0.1.2:
5320 version "0.1.2"
5321 resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
5322 integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
5323
5324normalize-selector@^0.2.0: 5570normalize-selector@^0.2.0:
5325 version "0.2.0" 5571 version "0.2.0"
5326 resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" 5572 resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
@@ -5364,11 +5610,6 @@ nth-check@^2.0.0:
5364 dependencies: 5610 dependencies:
5365 boolbase "^1.0.0" 5611 boolbase "^1.0.0"
5366 5612
5367num2fraction@^1.2.2:
5368 version "1.2.2"
5369 resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
5370 integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
5371
5372object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: 5613object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
5373 version "4.1.1" 5614 version "4.1.1"
5374 resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 5615 resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -5438,6 +5679,15 @@ object.values@^1.1.4:
5438 define-properties "^1.1.3" 5679 define-properties "^1.1.3"
5439 es-abstract "^1.18.2" 5680 es-abstract "^1.18.2"
5440 5681
5682object.values@^1.1.5:
5683 version "1.1.5"
5684 resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
5685 integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
5686 dependencies:
5687 call-bind "^1.0.2"
5688 define-properties "^1.1.3"
5689 es-abstract "^1.19.1"
5690
5441obuf@^1.0.0, obuf@^1.1.2: 5691obuf@^1.0.0, obuf@^1.1.2:
5442 version "1.1.2" 5692 version "1.1.2"
5443 resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" 5693 resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
@@ -5652,7 +5902,7 @@ p-try@^2.0.0:
5652 resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 5902 resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
5653 integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 5903 integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
5654 5904
5655param-case@^3.0.3: 5905param-case@^3.0.4:
5656 version "3.0.4" 5906 version "3.0.4"
5657 resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" 5907 resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
5658 integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== 5908 integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
@@ -5667,18 +5917,6 @@ parent-module@^1.0.0:
5667 dependencies: 5917 dependencies:
5668 callsites "^3.0.0" 5918 callsites "^3.0.0"
5669 5919
5670parse-entities@^2.0.0:
5671 version "2.0.0"
5672 resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
5673 integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
5674 dependencies:
5675 character-entities "^1.0.0"
5676 character-entities-legacy "^1.0.0"
5677 character-reference-invalid "^1.0.0"
5678 is-alphanumerical "^1.0.0"
5679 is-decimal "^1.0.0"
5680 is-hexadecimal "^1.0.0"
5681
5682parse-json@^2.2.0: 5920parse-json@^2.2.0:
5683 version "2.2.0" 5921 version "2.2.0"
5684 resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 5922 resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
@@ -5686,14 +5924,6 @@ parse-json@^2.2.0:
5686 dependencies: 5924 dependencies:
5687 error-ex "^1.2.0" 5925 error-ex "^1.2.0"
5688 5926
5689parse-json@^4.0.0:
5690 version "4.0.0"
5691 resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
5692 integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
5693 dependencies:
5694 error-ex "^1.3.1"
5695 json-parse-better-errors "^1.0.1"
5696
5697parse-json@^5.0.0: 5927parse-json@^5.0.0:
5698 version "5.2.0" 5928 version "5.2.0"
5699 resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" 5929 resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
@@ -5768,13 +5998,6 @@ path-type@^1.0.0:
5768 pify "^2.0.0" 5998 pify "^2.0.0"
5769 pinkie-promise "^2.0.0" 5999 pinkie-promise "^2.0.0"
5770 6000
5771path-type@^3.0.0:
5772 version "3.0.0"
5773 resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
5774 integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
5775 dependencies:
5776 pify "^3.0.0"
5777
5778path-type@^4.0.0: 6001path-type@^4.0.0:
5779 version "4.0.0" 6002 version "4.0.0"
5780 resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 6003 resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
@@ -5785,6 +6008,11 @@ pend@~1.2.0:
5785 resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" 6008 resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
5786 integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= 6009 integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
5787 6010
6011picocolors@^1.0.0:
6012 version "1.0.0"
6013 resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
6014 integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
6015
5788picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: 6016picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
5789 version "2.3.0" 6017 version "2.3.0"
5790 resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" 6018 resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
@@ -5831,13 +6059,6 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0:
5831 dependencies: 6059 dependencies:
5832 find-up "^4.0.0" 6060 find-up "^4.0.0"
5833 6061
5834pkg-up@^2.0.0:
5835 version "2.0.0"
5836 resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
5837 integrity sha1-yBmscoBZpGHKscOImivjxJoATX8=
5838 dependencies:
5839 find-up "^2.1.0"
5840
5841pngquant-bin@^6.0.0: 6062pngquant-bin@^6.0.0:
5842 version "6.0.0" 6063 version "6.0.0"
5843 resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-6.0.0.tgz#aff0d7e61095feb96ced379ad8c7294ad3dd1712" 6064 resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-6.0.0.tgz#aff0d7e61095feb96ced379ad8c7294ad3dd1712"
@@ -5857,20 +6078,6 @@ portfinder@^1.0.28:
5857 debug "^3.1.1" 6078 debug "^3.1.1"
5858 mkdirp "^0.5.5" 6079 mkdirp "^0.5.5"
5859 6080
5860postcss-html@^0.36.0:
5861 version "0.36.0"
5862 resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-0.36.0.tgz#b40913f94eaacc2453fd30a1327ad6ee1f88b204"
5863 integrity sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==
5864 dependencies:
5865 htmlparser2 "^3.10.0"
5866
5867postcss-less@^3.1.4:
5868 version "3.1.4"
5869 resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-3.1.4.tgz#369f58642b5928ef898ffbc1a6e93c958304c5ad"
5870 integrity sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==
5871 dependencies:
5872 postcss "^7.0.14"
5873
5874postcss-media-query-parser@^0.2.3: 6081postcss-media-query-parser@^0.2.3:
5875 version "0.2.3" 6082 version "0.2.3"
5876 resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" 6083 resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"
@@ -5909,29 +6116,17 @@ postcss-resolve-nested-selector@^0.1.1:
5909 resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" 6116 resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e"
5910 integrity sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4= 6117 integrity sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=
5911 6118
5912postcss-safe-parser@^4.0.2: 6119postcss-safe-parser@^6.0.0:
5913 version "4.0.2" 6120 version "6.0.0"
5914 resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" 6121 resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
5915 integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== 6122 integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
5916 dependencies:
5917 postcss "^7.0.26"
5918
5919postcss-sass@^0.4.4:
5920 version "0.4.4"
5921 resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.4.4.tgz#91f0f3447b45ce373227a98b61f8d8f0785285a3"
5922 integrity sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==
5923 dependencies:
5924 gonzales-pe "^4.3.0"
5925 postcss "^7.0.21"
5926 6123
5927postcss-scss@^2.1.1: 6124postcss-scss@^4.0.1:
5928 version "2.1.1" 6125 version "4.0.2"
5929 resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.1.1.tgz#ec3a75fa29a55e016b90bf3269026c53c1d2b383" 6126 resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.2.tgz#39ddcc0ab32f155d5ab328ee91353d67a52d537b"
5930 integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA== 6127 integrity sha512-xfdkU128CkKKKVAwkyt0M8OdnelJ3MRcIRAPPQkRpoPeuzWY3RIeg7piRCpZ79MK7Q16diLXMMAD9dN5mauPlQ==
5931 dependencies:
5932 postcss "^7.0.6"
5933 6128
5934postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: 6129postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.6:
5935 version "6.0.6" 6130 version "6.0.6"
5936 resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" 6131 resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea"
5937 integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== 6132 integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==
@@ -5939,24 +6134,11 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector
5939 cssesc "^3.0.0" 6134 cssesc "^3.0.0"
5940 util-deprecate "^1.0.2" 6135 util-deprecate "^1.0.2"
5941 6136
5942postcss-syntax@^0.36.2:
5943 version "0.36.2"
5944 resolved "https://registry.yarnpkg.com/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c"
5945 integrity sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==
5946
5947postcss-value-parser@^4.1.0: 6137postcss-value-parser@^4.1.0:
5948 version "4.1.0" 6138 version "4.1.0"
5949 resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" 6139 resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
5950 integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== 6140 integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
5951 6141
5952postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.6:
5953 version "7.0.38"
5954 resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.38.tgz#5365a9c5126643d977046ad239f60eadda2491d6"
5955 integrity sha512-wNrSHWjHDQJR/IZL5IKGxRtFgrYNaAA/UrkW2WqbtZO6uxSLMxMN+s2iqUMwnAWm3fMROlDYZB41dr0Mt7vBwQ==
5956 dependencies:
5957 nanocolors "^0.2.2"
5958 source-map "^0.6.1"
5959
5960postcss@^8.2.15: 6142postcss@^8.2.15:
5961 version "8.3.8" 6143 version "8.3.8"
5962 resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.8.tgz#9ebe2a127396b4b4570ae9f7770e7fb83db2bac1" 6144 resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.8.tgz#9ebe2a127396b4b4570ae9f7770e7fb83db2bac1"
@@ -5966,6 +6148,15 @@ postcss@^8.2.15:
5966 nanoid "^3.1.25" 6148 nanoid "^3.1.25"
5967 source-map-js "^0.6.2" 6149 source-map-js "^0.6.2"
5968 6150
6151postcss@^8.3.11:
6152 version "8.3.11"
6153 resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858"
6154 integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==
6155 dependencies:
6156 nanoid "^3.1.30"
6157 picocolors "^1.0.0"
6158 source-map-js "^0.6.2"
6159
5969prelude-ls@^1.2.1: 6160prelude-ls@^1.2.1:
5970 version "1.2.1" 6161 version "1.2.1"
5971 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 6162 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -5981,13 +6172,13 @@ prepend-http@^2.0.0:
5981 resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" 6172 resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
5982 integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= 6173 integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
5983 6174
5984pretty-error@^3.0.4: 6175pretty-error@^4.0.0:
5985 version "3.0.4" 6176 version "4.0.0"
5986 resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-3.0.4.tgz#94b1d54f76c1ed95b9c604b9de2194838e5b574e" 6177 resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6"
5987 integrity sha512-ytLFLfv1So4AO1UkoBF6GXQgJRaKbiSiGFICaOPNwQ3CMvBvXpLRubeQWyPGnsbV/t9ml9qto6IeCsho0aEvwQ== 6178 integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==
5988 dependencies: 6179 dependencies:
5989 lodash "^4.17.20" 6180 lodash "^4.17.20"
5990 renderkid "^2.0.6" 6181 renderkid "^3.0.0"
5991 6182
5992process-nextick-args@~2.0.0: 6183process-nextick-args@~2.0.0:
5993 version "2.0.1" 6184 version "2.0.1"
@@ -6095,11 +6286,6 @@ raw-body@2.4.0:
6095 iconv-lite "0.4.24" 6286 iconv-lite "0.4.24"
6096 unpipe "1.0.0" 6287 unpipe "1.0.0"
6097 6288
6098"react-codemirror2@npm:react17-codemirror2@^7.2.3":
6099 version "7.2.3"
6100 resolved "https://registry.yarnpkg.com/react17-codemirror2/-/react17-codemirror2-7.2.3.tgz#ff1ec8f5feadf9c03fb25095c40326971f3ce106"
6101 integrity sha512-XOIu5k3IFH6ajunRw5HO9BX9N6u9T7tby7BN4tKi/sz0Yq3pvd0xylbvq5PbScl2oowRMcyiJXkpPRI8+h0H9Q==
6102
6103react-dom@^17.0.2: 6289react-dom@^17.0.2:
6104 version "17.0.2" 6290 version "17.0.2"
6105 resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" 6291 resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
@@ -6145,14 +6331,6 @@ read-pkg-up@^1.0.1:
6145 find-up "^1.0.0" 6331 find-up "^1.0.0"
6146 read-pkg "^1.0.0" 6332 read-pkg "^1.0.0"
6147 6333
6148read-pkg-up@^3.0.0:
6149 version "3.0.0"
6150 resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
6151 integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=
6152 dependencies:
6153 find-up "^2.0.0"
6154 read-pkg "^3.0.0"
6155
6156read-pkg-up@^7.0.1: 6334read-pkg-up@^7.0.1:
6157 version "7.0.1" 6335 version "7.0.1"
6158 resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" 6336 resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
@@ -6171,15 +6349,6 @@ read-pkg@^1.0.0:
6171 normalize-package-data "^2.3.2" 6349 normalize-package-data "^2.3.2"
6172 path-type "^1.0.0" 6350 path-type "^1.0.0"
6173 6351
6174read-pkg@^3.0.0:
6175 version "3.0.0"
6176 resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
6177 integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=
6178 dependencies:
6179 load-json-file "^4.0.0"
6180 normalize-package-data "^2.3.2"
6181 path-type "^3.0.0"
6182
6183read-pkg@^5.2.0: 6352read-pkg@^5.2.0:
6184 version "5.2.0" 6353 version "5.2.0"
6185 resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" 6354 resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
@@ -6203,7 +6372,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.3.0, readable
6203 string_decoder "~1.1.1" 6372 string_decoder "~1.1.1"
6204 util-deprecate "~1.0.1" 6373 util-deprecate "~1.0.1"
6205 6374
6206readable-stream@^3.0.6, readable-stream@^3.1.1: 6375readable-stream@^3.0.6:
6207 version "3.6.0" 6376 version "3.6.0"
6208 resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 6377 resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
6209 integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 6378 integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -6308,44 +6477,16 @@ relateurl@^0.2.7:
6308 resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" 6477 resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
6309 integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= 6478 integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
6310 6479
6311remark-parse@^9.0.0: 6480renderkid@^3.0.0:
6312 version "9.0.0" 6481 version "3.0.0"
6313 resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" 6482 resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a"
6314 integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== 6483 integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==
6315 dependencies:
6316 mdast-util-from-markdown "^0.8.0"
6317
6318remark-stringify@^9.0.0:
6319 version "9.0.1"
6320 resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-9.0.1.tgz#576d06e910548b0a7191a71f27b33f1218862894"
6321 integrity sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==
6322 dependencies:
6323 mdast-util-to-markdown "^0.6.0"
6324
6325remark@^13.0.0:
6326 version "13.0.0"
6327 resolved "https://registry.yarnpkg.com/remark/-/remark-13.0.0.tgz#d15d9bf71a402f40287ebe36067b66d54868e425"
6328 integrity sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==
6329 dependencies:
6330 remark-parse "^9.0.0"
6331 remark-stringify "^9.0.0"
6332 unified "^9.1.0"
6333
6334renderkid@^2.0.6:
6335 version "2.0.7"
6336 resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609"
6337 integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==
6338 dependencies: 6484 dependencies:
6339 css-select "^4.1.3" 6485 css-select "^4.1.3"
6340 dom-converter "^0.2.0" 6486 dom-converter "^0.2.0"
6341 htmlparser2 "^6.1.0" 6487 htmlparser2 "^6.1.0"
6342 lodash "^4.17.21" 6488 lodash "^4.17.21"
6343 strip-ansi "^3.0.1" 6489 strip-ansi "^6.0.1"
6344
6345repeat-string@^1.0.0:
6346 version "1.6.1"
6347 resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
6348 integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
6349 6490
6350repeating@^2.0.0: 6491repeating@^2.0.0:
6351 version "2.0.1" 6492 version "2.0.1"
@@ -6455,18 +6596,18 @@ safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1,
6455 resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 6596 resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
6456 integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 6597 integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
6457 6598
6458sass-loader@^12.1.0: 6599sass-loader@^12.3.0:
6459 version "12.1.0" 6600 version "12.3.0"
6460 resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.1.0.tgz#b73324622231009da6fba61ab76013256380d201" 6601 resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.3.0.tgz#93278981c189c36a58cbfc37d4b9cef0cdc02871"
6461 integrity sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg== 6602 integrity sha512-6l9qwhdOb7qSrtOu96QQ81LVl8v6Dp9j1w3akOm0aWHyrTYtagDt5+kS32N4yq4hHk3M+rdqoRMH+lIdqvW6HA==
6462 dependencies: 6603 dependencies:
6463 klona "^2.0.4" 6604 klona "^2.0.4"
6464 neo-async "^2.6.2" 6605 neo-async "^2.6.2"
6465 6606
6466sass@^1.42.1: 6607sass@^1.43.4:
6467 version "1.42.1" 6608 version "1.43.4"
6468 resolved "https://registry.yarnpkg.com/sass/-/sass-1.42.1.tgz#5ab17bebc1cb1881ad2e0c9a932c66ad64e441e2" 6609 resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.4.tgz#68c7d6a1b004bef49af0d9caf750e9b252105d1f"
6469 integrity sha512-/zvGoN8B7dspKc5mC6HlaygyCBRvnyzzgD5khiaCfglWztY99cYoiTUksVx11NlnemrcfH5CEaCpsUKoW0cQqg== 6610 integrity sha512-/ptG7KE9lxpGSYiXn7Ar+lKOv37xfWsZRtFYal2QHNigyVQDx685VFT/h7ejVr+R8w7H4tmUgtulsKl5YpveOg==
6470 dependencies: 6611 dependencies:
6471 chokidar ">=3.0.0 <4.0.0" 6612 chokidar ">=3.0.0 <4.0.0"
6472 6613
@@ -6702,7 +6843,7 @@ source-map-js@^0.6.2:
6702 resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" 6843 resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
6703 integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== 6844 integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
6704 6845
6705source-map-support@~0.5.12, source-map-support@~0.5.20: 6846source-map-support@~0.5.20:
6706 version "0.5.20" 6847 version "0.5.20"
6707 resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" 6848 resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9"
6708 integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== 6849 integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==
@@ -6715,7 +6856,7 @@ source-map@^0.5.0, source-map@^0.5.7:
6715 resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 6856 resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
6716 integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= 6857 integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
6717 6858
6718source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: 6859source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0:
6719 version "0.6.1" 6860 version "0.6.1"
6720 resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 6861 resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
6721 integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 6862 integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -6808,7 +6949,7 @@ strict-uri-encode@^1.0.0:
6808 resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" 6949 resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
6809 integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= 6950 integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
6810 6951
6811string-width@^4.2.0, string-width@^4.2.2: 6952string-width@^4.2.3:
6812 version "4.2.3" 6953 version "4.2.3"
6813 resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 6954 resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
6814 integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 6955 integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -6861,7 +7002,7 @@ string_decoder@~1.1.1:
6861 dependencies: 7002 dependencies:
6862 safe-buffer "~5.1.0" 7003 safe-buffer "~5.1.0"
6863 7004
6864strip-ansi@^3.0.0, strip-ansi@^3.0.1: 7005strip-ansi@^3.0.0:
6865 version "3.0.1" 7006 version "3.0.1"
6866 resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 7007 resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
6867 integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 7008 integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
@@ -6942,105 +7083,95 @@ strnum@^1.0.4:
6942 resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.4.tgz#e97e36a7d6ba9f93d0d6b496b2ed0678d422832b" 7083 resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.4.tgz#e97e36a7d6ba9f93d0d6b496b2ed0678d422832b"
6943 integrity sha512-lMzNMfDpaQOLt4B2mEbfzYS0+T7dvCXeojnlGf6f1AygvWDMcWyXYaLbyICfjVu29sErR8fnRagQfBW/N/hGgw== 7084 integrity sha512-lMzNMfDpaQOLt4B2mEbfzYS0+T7dvCXeojnlGf6f1AygvWDMcWyXYaLbyICfjVu29sErR8fnRagQfBW/N/hGgw==
6944 7085
6945style-loader@^3.3.0: 7086style-loader@^3.3.1:
6946 version "3.3.0" 7087 version "3.3.1"
6947 resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.0.tgz#d66ea95fc50b22f8b79b69a9e414760fcf58d8d8" 7088 resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575"
6948 integrity sha512-szANub7ksJtQioJYtpbWwh1hUl99uK15n5HDlikeCRil/zYMZgSxucHddyF/4A3qJMUiAjPhFowrrQuNMA7jwQ== 7089 integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==
7090
7091style-mod@^4.0.0:
7092 version "4.0.0"
7093 resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.0.tgz#97e7c2d68b592975f2ca7a63d0dd6fcacfe35a01"
7094 integrity sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==
6949 7095
6950style-search@^0.1.0: 7096style-search@^0.1.0:
6951 version "0.1.0" 7097 version "0.1.0"
6952 resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" 7098 resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902"
6953 integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI= 7099 integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=
6954 7100
6955stylelint-config-recommended-scss@^4.3.0: 7101stylelint-config-recommended-scss@^5.0.0:
6956 version "4.3.0" 7102 version "5.0.0"
6957 resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-4.3.0.tgz#717dc253b4cab246da654cee208e499c5c797ae4" 7103 resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-5.0.0.tgz#0b1d8117c84f616283abf309272af97df32ba79d"
6958 integrity sha512-/noGjXlO8pJTr/Z3qGMoaRFK8n1BFfOqmAbX1RjTIcl4Yalr+LUb1zb9iQ7pRx1GsEBXOAm4g2z5/jou/pfMPg== 7104 integrity sha512-nQonGHxkv+n61WiU03bcHBHlA9XPMg7mGyD48ZmwrcnNroCEbH2nZhfn6Y1xcxfIHpD2wnwtAUPAwFaNQQpivw==
6959 dependencies: 7105 dependencies:
6960 stylelint-config-recommended "^5.0.0" 7106 postcss-scss "^4.0.1"
7107 stylelint-config-recommended "^6.0.0"
7108 stylelint-scss "^4.0.0"
6961 7109
6962stylelint-config-recommended@^5.0.0: 7110stylelint-config-recommended@^6.0.0:
6963 version "5.0.0" 7111 version "6.0.0"
6964 resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-5.0.0.tgz#fb5653f495a60b4938f2ad3e77712d9e1039ae78" 7112 resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz#fd2523a322836005ad9bf473d3e5534719c09f9d"
6965 integrity sha512-c8aubuARSu5A3vEHLBeOSJt1udOdS+1iue7BmJDTSXoCBmfEQmmWX+59vYIj3NQdJBY6a/QRv1ozVFpaB9jaqA== 7113 integrity sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==
6966 7114
6967stylelint-scss@^3.21.0: 7115stylelint-scss@^4.0.0:
6968 version "3.21.0" 7116 version "4.0.0"
6969 resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-3.21.0.tgz#9f50898691b16b1c1ca3945837381d98c5b22331" 7117 resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.0.0.tgz#4901ced92b9c68e37649799a39defbd5f2ac5bcd"
6970 integrity sha512-CMI2wSHL+XVlNExpauy/+DbUcB/oUZLARDtMIXkpV/5yd8nthzylYd1cdHeDMJVBXeYHldsnebUX6MoV5zPW4A== 7118 integrity sha512-lIRhPqtI6I065EJ6aI4mWKsmQt8Krnu6aF9XSL9s8Nd2f/cDKImST0T9TfjnUul3ReKYWozkG9dlpNTZH2FB9w==
6971 dependencies: 7119 dependencies:
6972 lodash "^4.17.15" 7120 lodash "^4.17.15"
6973 postcss-media-query-parser "^0.2.3" 7121 postcss-media-query-parser "^0.2.3"
6974 postcss-resolve-nested-selector "^0.1.1" 7122 postcss-resolve-nested-selector "^0.1.1"
6975 postcss-selector-parser "^6.0.2" 7123 postcss-selector-parser "^6.0.6"
6976 postcss-value-parser "^4.1.0" 7124 postcss-value-parser "^4.1.0"
6977 7125
6978stylelint@^13.13.1: 7126stylelint@^14.0.1:
6979 version "13.13.1" 7127 version "14.0.1"
6980 resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.13.1.tgz#fca9c9f5de7990ab26a00f167b8978f083a18f3c" 7128 resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.0.1.tgz#88e6c8bd3be61e666225ddb871826321f16661f6"
6981 integrity sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ== 7129 integrity sha512-ZcAkmFLVCultmwkQUjxKzxW/o5+CzNmDk6TPJj/d4Y7ipTGGrewIWmNm+InjdSr04PR5/yynsAJeYJY/wisdMg==
6982 dependencies: 7130 dependencies:
6983 "@stylelint/postcss-css-in-js" "^0.37.2"
6984 "@stylelint/postcss-markdown" "^0.36.2"
6985 autoprefixer "^9.8.6"
6986 balanced-match "^2.0.0" 7131 balanced-match "^2.0.0"
6987 chalk "^4.1.1" 7132 cosmiconfig "^7.0.1"
6988 cosmiconfig "^7.0.0" 7133 debug "^4.3.2"
6989 debug "^4.3.1"
6990 execall "^2.0.0" 7134 execall "^2.0.0"
6991 fast-glob "^3.2.5" 7135 fast-glob "^3.2.7"
6992 fastest-levenshtein "^1.0.12" 7136 fastest-levenshtein "^1.0.12"
6993 file-entry-cache "^6.0.1" 7137 file-entry-cache "^6.0.1"
6994 get-stdin "^8.0.0" 7138 get-stdin "^8.0.0"
6995 global-modules "^2.0.0" 7139 global-modules "^2.0.0"
6996 globby "^11.0.3" 7140 globby "^11.0.4"
6997 globjoin "^0.1.4" 7141 globjoin "^0.1.4"
6998 html-tags "^3.1.0" 7142 html-tags "^3.1.0"
6999 ignore "^5.1.8" 7143 ignore "^5.1.8"
7000 import-lazy "^4.0.0" 7144 import-lazy "^4.0.0"
7001 imurmurhash "^0.1.4" 7145 imurmurhash "^0.1.4"
7002 known-css-properties "^0.21.0" 7146 is-plain-object "^5.0.0"
7003 lodash "^4.17.21" 7147 known-css-properties "^0.23.0"
7004 log-symbols "^4.1.0"
7005 mathml-tag-names "^2.1.3" 7148 mathml-tag-names "^2.1.3"
7006 meow "^9.0.0" 7149 meow "^9.0.0"
7007 micromatch "^4.0.4" 7150 micromatch "^4.0.4"
7151 normalize-path "^3.0.0"
7008 normalize-selector "^0.2.0" 7152 normalize-selector "^0.2.0"
7009 postcss "^7.0.35" 7153 picocolors "^1.0.0"
7010 postcss-html "^0.36.0" 7154 postcss "^8.3.11"
7011 postcss-less "^3.1.4"
7012 postcss-media-query-parser "^0.2.3" 7155 postcss-media-query-parser "^0.2.3"
7013 postcss-resolve-nested-selector "^0.1.1" 7156 postcss-resolve-nested-selector "^0.1.1"
7014 postcss-safe-parser "^4.0.2" 7157 postcss-safe-parser "^6.0.0"
7015 postcss-sass "^0.4.4" 7158 postcss-selector-parser "^6.0.6"
7016 postcss-scss "^2.1.1"
7017 postcss-selector-parser "^6.0.5"
7018 postcss-syntax "^0.36.2"
7019 postcss-value-parser "^4.1.0" 7159 postcss-value-parser "^4.1.0"
7020 resolve-from "^5.0.0" 7160 resolve-from "^5.0.0"
7021 slash "^3.0.0"
7022 specificity "^0.4.1" 7161 specificity "^0.4.1"
7023 string-width "^4.2.2" 7162 string-width "^4.2.3"
7024 strip-ansi "^6.0.0" 7163 strip-ansi "^6.0.1"
7025 style-search "^0.1.0" 7164 style-search "^0.1.0"
7026 sugarss "^2.0.0"
7027 svg-tags "^1.0.0" 7165 svg-tags "^1.0.0"
7028 table "^6.6.0" 7166 table "^6.7.2"
7029 v8-compile-cache "^2.3.0" 7167 v8-compile-cache "^2.3.0"
7030 write-file-atomic "^3.0.3" 7168 write-file-atomic "^3.0.3"
7031 7169
7032stylis@^4.0.3: 7170stylis@^4.0.10, stylis@^4.0.3:
7033 version "4.0.10" 7171 version "4.0.10"
7034 resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" 7172 resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
7035 integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== 7173 integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
7036 7174
7037sugarss@^2.0.0:
7038 version "2.0.0"
7039 resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d"
7040 integrity sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==
7041 dependencies:
7042 postcss "^7.0.2"
7043
7044supports-color@^2.0.0: 7175supports-color@^2.0.0:
7045 version "2.0.0" 7176 version "2.0.0"
7046 resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 7177 resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@@ -7085,17 +7216,17 @@ svgo@^2.1.0:
7085 nanocolors "^0.1.12" 7216 nanocolors "^0.1.12"
7086 stable "^0.1.8" 7217 stable "^0.1.8"
7087 7218
7088table@^6.0.9, table@^6.6.0: 7219table@^6.0.9, table@^6.7.2:
7089 version "6.7.1" 7220 version "6.7.2"
7090 resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" 7221 resolved "https://registry.yarnpkg.com/table/-/table-6.7.2.tgz#a8d39b9f5966693ca8b0feba270a78722cbaf3b0"
7091 integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== 7222 integrity sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==
7092 dependencies: 7223 dependencies:
7093 ajv "^8.0.1" 7224 ajv "^8.0.1"
7094 lodash.clonedeep "^4.5.0" 7225 lodash.clonedeep "^4.5.0"
7095 lodash.truncate "^4.4.2" 7226 lodash.truncate "^4.4.2"
7096 slice-ansi "^4.0.0" 7227 slice-ansi "^4.0.0"
7097 string-width "^4.2.0" 7228 string-width "^4.2.3"
7098 strip-ansi "^6.0.0" 7229 strip-ansi "^6.0.1"
7099 7230
7100tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: 7231tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
7101 version "2.2.1" 7232 version "2.2.1"
@@ -7140,15 +7271,6 @@ terser-webpack-plugin@^5.1.3:
7140 source-map "^0.6.1" 7271 source-map "^0.6.1"
7141 terser "^5.7.2" 7272 terser "^5.7.2"
7142 7273
7143terser@^4.6.3:
7144 version "4.8.0"
7145 resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
7146 integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==
7147 dependencies:
7148 commander "^2.20.0"
7149 source-map "~0.6.1"
7150 source-map-support "~0.5.12"
7151
7152terser@^5.7.2: 7274terser@^5.7.2:
7153 version "5.9.0" 7275 version "5.9.0"
7154 resolved "https://registry.yarnpkg.com/terser/-/terser-5.9.0.tgz#47d6e629a522963240f2b55fcaa3c99083d2c351" 7276 resolved "https://registry.yarnpkg.com/terser/-/terser-5.9.0.tgz#47d6e629a522963240f2b55fcaa3c99083d2c351"
@@ -7217,11 +7339,6 @@ trim-repeated@^1.0.0:
7217 dependencies: 7339 dependencies:
7218 escape-string-regexp "^1.0.2" 7340 escape-string-regexp "^1.0.2"
7219 7341
7220trough@^1.0.0:
7221 version "1.0.5"
7222 resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
7223 integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
7224
7225tsconfig-paths@^3.11.0: 7342tsconfig-paths@^3.11.0:
7226 version "3.11.0" 7343 version "3.11.0"
7227 resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" 7344 resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36"
@@ -7308,10 +7425,10 @@ typedarray-to-buffer@^3.1.5:
7308 dependencies: 7425 dependencies:
7309 is-typedarray "^1.0.0" 7426 is-typedarray "^1.0.0"
7310 7427
7311typescript@^4.4.3: 7428typescript@^4.4.4:
7312 version "4.4.3" 7429 version "4.4.4"
7313 resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" 7430 resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
7314 integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== 7431 integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
7315 7432
7316unbox-primitive@^1.0.1: 7433unbox-primitive@^1.0.1:
7317 version "1.0.1" 7434 version "1.0.1"
@@ -7354,37 +7471,6 @@ unicode-property-aliases-ecmascript@^2.0.0:
7354 resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" 7471 resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8"
7355 integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== 7472 integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==
7356 7473
7357unified@^9.1.0:
7358 version "9.2.2"
7359 resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"
7360 integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==
7361 dependencies:
7362 bail "^1.0.0"
7363 extend "^3.0.0"
7364 is-buffer "^2.0.0"
7365 is-plain-obj "^2.0.0"
7366 trough "^1.0.0"
7367 vfile "^4.0.0"
7368
7369unist-util-find-all-after@^3.0.2:
7370 version "3.0.2"
7371 resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz#fdfecd14c5b7aea5e9ef38d5e0d5f774eeb561f6"
7372 integrity sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==
7373 dependencies:
7374 unist-util-is "^4.0.0"
7375
7376unist-util-is@^4.0.0:
7377 version "4.1.0"
7378 resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797"
7379 integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==
7380
7381unist-util-stringify-position@^2.0.0:
7382 version "2.0.3"
7383 resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
7384 integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==
7385 dependencies:
7386 "@types/unist" "^2.0.2"
7387
7388unpipe@1.0.0, unpipe@~1.0.0: 7474unpipe@1.0.0, unpipe@~1.0.0:
7389 version "1.0.0" 7475 version "1.0.0"
7390 resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 7476 resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@@ -7444,7 +7530,7 @@ uuid@^3.0.1, uuid@^3.4.0:
7444 resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 7530 resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
7445 integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 7531 integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
7446 7532
7447v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0, v8-compile-cache@^2.3.0: 7533v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0:
7448 version "2.3.0" 7534 version "2.3.0"
7449 resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 7535 resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
7450 integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 7536 integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
@@ -7462,23 +7548,10 @@ vary@~1.1.2:
7462 resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 7548 resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
7463 integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 7549 integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
7464 7550
7465vfile-message@^2.0.0: 7551w3c-keyname@^2.2.4:
7466 version "2.0.4" 7552 version "2.2.4"
7467 resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" 7553 resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b"
7468 integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== 7554 integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==
7469 dependencies:
7470 "@types/unist" "^2.0.0"
7471 unist-util-stringify-position "^2.0.0"
7472
7473vfile@^4.0.0:
7474 version "4.2.1"
7475 resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624"
7476 integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==
7477 dependencies:
7478 "@types/unist" "^2.0.0"
7479 is-buffer "^2.0.0"
7480 unist-util-stringify-position "^2.0.0"
7481 vfile-message "^2.0.0"
7482 7555
7483watchpack@^2.2.0: 7556watchpack@^2.2.0:
7484 version "2.2.0" 7557 version "2.2.0"
@@ -7495,23 +7568,22 @@ wbuf@^1.1.0, wbuf@^1.7.3:
7495 dependencies: 7568 dependencies:
7496 minimalistic-assert "^1.0.0" 7569 minimalistic-assert "^1.0.0"
7497 7570
7498webpack-cli@^4.8.0: 7571webpack-cli@^4.9.1:
7499 version "4.8.0" 7572 version "4.9.1"
7500 resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.8.0.tgz#5fc3c8b9401d3c8a43e2afceacfa8261962338d1" 7573 resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3"
7501 integrity sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw== 7574 integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==
7502 dependencies: 7575 dependencies:
7503 "@discoveryjs/json-ext" "^0.5.0" 7576 "@discoveryjs/json-ext" "^0.5.0"
7504 "@webpack-cli/configtest" "^1.0.4" 7577 "@webpack-cli/configtest" "^1.1.0"
7505 "@webpack-cli/info" "^1.3.0" 7578 "@webpack-cli/info" "^1.4.0"
7506 "@webpack-cli/serve" "^1.5.2" 7579 "@webpack-cli/serve" "^1.6.0"
7507 colorette "^1.2.1" 7580 colorette "^2.0.14"
7508 commander "^7.0.0" 7581 commander "^7.0.0"
7509 execa "^5.0.0" 7582 execa "^5.0.0"
7510 fastest-levenshtein "^1.0.12" 7583 fastest-levenshtein "^1.0.12"
7511 import-local "^3.0.2" 7584 import-local "^3.0.2"
7512 interpret "^2.2.0" 7585 interpret "^2.2.0"
7513 rechoir "^0.7.0" 7586 rechoir "^0.7.0"
7514 v8-compile-cache "^2.2.0"
7515 webpack-merge "^5.7.3" 7587 webpack-merge "^5.7.3"
7516 7588
7517webpack-dev-middleware@^5.2.1: 7589webpack-dev-middleware@^5.2.1:
@@ -7525,14 +7597,14 @@ webpack-dev-middleware@^5.2.1:
7525 range-parser "^1.2.1" 7597 range-parser "^1.2.1"
7526 schema-utils "^3.1.0" 7598 schema-utils "^3.1.0"
7527 7599
7528webpack-dev-server@^4.3.0: 7600webpack-dev-server@^4.4.0:
7529 version "4.3.0" 7601 version "4.4.0"
7530 resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.0.tgz#732f5869d4c06e222b599daee64bc268f5edea24" 7602 resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.4.0.tgz#10ec17088f840c9ccb2ebb0b43c49ec293206f7e"
7531 integrity sha512-kuqP9Xn4OzcKe7f0rJwd4p8xqiD+4b5Lzu8tJa8OttRL3E1Q8gI2KmUtouJTgDswjjvHOHlZDV8LTQfSY5qZSA== 7603 integrity sha512-+S0XRIbsopVjPFjCO8I07FXYBWYqkFmuP56ucGMTs2hA/gV4q2M9xTmNo5Tg4o8ffRR+Nm3AsXnQXxKRyYovrA==
7532 dependencies: 7604 dependencies:
7533 ansi-html-community "^0.0.8" 7605 ansi-html-community "^0.0.8"
7534 bonjour "^3.5.0" 7606 bonjour "^3.5.0"
7535 chokidar "^3.5.1" 7607 chokidar "^3.5.2"
7536 colorette "^2.0.10" 7608 colorette "^2.0.10"
7537 compression "^1.7.4" 7609 compression "^1.7.4"
7538 connect-history-api-fallback "^1.6.0" 7610 connect-history-api-fallback "^1.6.0"
@@ -7576,10 +7648,10 @@ webpack-subresource-integrity@^5.0.0:
7576 dependencies: 7648 dependencies:
7577 typed-assert "^1.0.8" 7649 typed-assert "^1.0.8"
7578 7650
7579webpack@^5.56.0: 7651webpack@^5.61.0:
7580 version "5.56.0" 7652 version "5.61.0"
7581 resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.56.0.tgz#91a04de09c85765002818678538c319b6e461324" 7653 resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.61.0.tgz#fa827f0ee9bdfd141dd73c3e891e955ebd52fe7f"
7582 integrity sha512-pJ7esw2AGkpZL0jqsEAKnDEfRZdrc9NVjAWA+d1mFkwj68ng9VQ6+Wnrl+kS5dlDHvrat5ASK5vd7wp6I7f53Q== 7654 integrity sha512-fPdTuaYZ/GMGFm4WrPi2KRCqS1vDp773kj9S0iI5Uc//5cszsFEDgHNaX4Rj1vobUiU1dFIV3mA9k1eHeluFpw==
7583 dependencies: 7655 dependencies:
7584 "@types/eslint-scope" "^3.7.0" 7656 "@types/eslint-scope" "^3.7.0"
7585 "@types/estree" "^0.0.50" 7657 "@types/estree" "^0.0.50"
@@ -7712,8 +7784,3 @@ yocto-queue@^0.1.0:
7712 version "0.1.0" 7784 version "0.1.0"
7713 resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 7785 resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
7714 integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 7786 integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
7715
7716zwitch@^1.0.0:
7717 version "1.0.5"
7718 resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
7719 integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==
diff --git a/language/build.gradle b/language/build.gradle
index f2b20ab5..7b9f8d75 100644
--- a/language/build.gradle
+++ b/language/build.gradle
@@ -16,7 +16,6 @@ dependencies {
16 mwe2 "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}" 16 mwe2 "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}"
17 mwe2 "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}" 17 mwe2 "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}"
18 mwe2 "org.eclipse.xtext:xtext-antlr-generator:${xtextAntlrGeneratorVersion}" 18 mwe2 "org.eclipse.xtext:xtext-antlr-generator:${xtextAntlrGeneratorVersion}"
19 mwe2 project(':refinery-language-mwe2')
20} 19}
21 20
22sourceSets { 21sourceSets {
@@ -41,7 +40,6 @@ def generateXtextLanguage = tasks.register('generateXtextLanguage', JavaExec) {
41 outputs.dir 'src/testFixtures/xtext-gen' 40 outputs.dir 'src/testFixtures/xtext-gen'
42 outputs.dir '../language-ide/src/main/xtext-gen' 41 outputs.dir '../language-ide/src/main/xtext-gen'
43 outputs.dir '../language-web/src/main/xtext-gen' 42 outputs.dir '../language-web/src/main/xtext-gen'
44 outputs.dir '../language-web/build/generated/sources/xtext'
45 args += 'src/main/java/tools/refinery/language/GenerateProblem.mwe2' 43 args += 'src/main/java/tools/refinery/language/GenerateProblem.mwe2'
46 args += '-p' 44 args += '-p'
47 args += "rootPath=/${projectDir}/.." 45 args += "rootPath=/${projectDir}/.."
@@ -58,7 +56,6 @@ tasks.named('clean') {
58 delete 'src/testFixtures/xtext-gen' 56 delete 'src/testFixtures/xtext-gen'
59 delete '../language-ide/src/main/xtext-gen' 57 delete '../language-ide/src/main/xtext-gen'
60 delete '../language-web/src/main/xtext-gen' 58 delete '../language-web/src/main/xtext-gen'
61 delete '../language-web/build/generated/sources/xtext'
62} 59}
63 60
64sonarqube.properties { 61sonarqube.properties {
diff --git a/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 b/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
index 1b177c94..58620d6a 100644
--- a/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
+++ b/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
@@ -3,42 +3,39 @@ module tools.refinery.language.GenerateProblem
3import org.eclipse.xtext.xtext.generator.* 3import org.eclipse.xtext.xtext.generator.*
4import org.eclipse.xtext.xtext.generator.model.project.* 4import org.eclipse.xtext.xtext.generator.model.project.*
5 5
6import tools.refinery.language.mwe2.* 6var rootPath = '..'
7
8var rootPath = ".."
9 7
10Workflow { 8Workflow {
11 component = XtextGenerator { 9 component = XtextGenerator {
12 configuration = { 10 configuration = {
13 project = StandardProjectConfig { 11 project = StandardProjectConfig {
14 baseName = "language" 12 baseName = 'language'
15 rootPath = rootPath 13 rootPath = rootPath
16 runtimeTest = { 14 runtimeTest = {
17 enabled = true 15 enabled = true
18 srcGen = 'src/testFixtures/xtext-gen' 16 srcGen = 'src/testFixtures/xtext-gen'
19 } 17 }
20 genericIde = { 18 genericIde = {
21 name = "language-ide" 19 name = 'language-ide'
22 } 20 }
23 web = { 21 web = {
24 enabled = true 22 enabled = true
25 name = "language-web" 23 name = 'language-web'
26 assets = "../language-web/build/generated/sources/xtext"
27 } 24 }
28 mavenLayout = true 25 mavenLayout = true
29 } 26 }
30 code = { 27 code = {
31 encoding = "UTF-8" 28 encoding = 'UTF-8'
32 lineDelimiter = "\n" 29 lineDelimiter = '\n'
33 fileHeader = "/*\n * generated by Xtext \${version}\n */" 30 fileHeader = '/*\n * generated by Xtext \${version}\n */'
34 preferXtendStubs = false 31 preferXtendStubs = false
35 } 32 }
36 } 33 }
37 34
38 language = StandardLanguage { 35 language = StandardLanguage {
39 name = "tools.refinery.language.Problem" 36 name = 'tools.refinery.language.Problem'
40 fileExtensions = "problem" 37 fileExtensions = 'problem'
41 referencedResource = "platform:/resource/refinery-language-model/model/problem.genmodel" 38 referencedResource = 'platform:/resource/refinery-language-model/model/problem.genmodel'
42 serializer = { 39 serializer = {
43 generateStub = false 40 generateStub = false
44 } 41 }
@@ -51,12 +48,15 @@ Workflow {
51 junitSupport = { 48 junitSupport = {
52 generateStub = false 49 generateStub = false
53 skipXbaseTestingPackage = true 50 skipXbaseTestingPackage = true
54 junitVersion = "5" 51 junitVersion = '5'
55 } 52 }
56 webSupport = ProblemWebIntegrationFragment { 53 webSupport = {
57 highlightingPath = "js/mode-problem.js" 54 // We only generate the {@code AbstractProblemWebModule},
55 // because we write our own integration code for CodeMirror 6.
56 framework = 'codemirror'
58 generateHtmlExample = false 57 generateHtmlExample = false
59 generateJettyLauncher = false 58 generateJettyLauncher = false
59 generateJsHighlighting = false
60 generateServlet = false 60 generateServlet = false
61 generateWebXml = false 61 generateWebXml = false
62 } 62 }
diff --git a/language/src/main/java/tools/refinery/language/Problem.xtext b/language/src/main/java/tools/refinery/language/Problem.xtext
index c4c890e3..6f6a8588 100644
--- a/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -26,7 +26,7 @@ EnumLiteral returns Node:
26 name=Identifier; 26 name=Identifier;
27 27
28ReferenceDeclaration: 28ReferenceDeclaration:
29 (-> (containment?="contains" | "refers"))? 29 (containment?="contains" | "refers")?
30 referenceType=[Relation|QualifiedName] 30 referenceType=[Relation|QualifiedName]
31 ("[" multiplicity=Multiplicity "]")? 31 ("[" multiplicity=Multiplicity "]")?
32 name=Identifier 32 name=Identifier
@@ -184,7 +184,7 @@ QualifiedName hidden():
184 184
185Identifier: 185Identifier:
186 ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | "scope" | 186 ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | "scope" |
187 "unique" | "default" | "problem" | "contains" | "refers" | "new" | "delete"; 187 "unique" | "default" | "problem" | "new" | "delete";
188 188
189Integer returns ecore::EInt hidden(): 189Integer returns ecore::EInt hidden():
190 "-"? INT; 190 "-"? INT;
diff --git a/settings.gradle b/settings.gradle
index 9edf237f..0e237de1 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,7 +3,6 @@ rootProject.name = 'refinery'
3include 'language' 3include 'language'
4include 'language-ide' 4include 'language-ide'
5include 'language-model' 5include 'language-model'
6include 'language-mwe2'
7include 'language-to-store' 6include 'language-to-store'
8include 'language-web' 7include 'language-web'
9include 'store' 8include 'store'