diff options
author | 2021-10-31 19:41:24 +0100 | |
---|---|---|
committer | 2021-10-31 19:41:24 +0100 | |
commit | 7918d78948de7f349f9948837caf76f2a514c96c (patch) | |
tree | 0f7c24a9e0046dffd719d6a66be4a1f73b7fa4c7 | |
parent | Merge pull request #7 from golej-marci/language-to-store (diff) | |
parent | chore: bump dependency versions (diff) | |
download | refinery-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
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 | |||
10 | indent_style = tab | 10 | indent_style = tab |
11 | indent_size = 4 | 11 | indent_size = 4 |
12 | 12 | ||
13 | [*.{html,js,json,jsx,scss,ts,tsx,yml}] | 13 | [*.{grammar,html,js,json,jsx,scss,ts,tsx,yml}] |
14 | indent_style = space | 14 | indent_style = space |
15 | indent_size = 2 | 15 | indent_size = 2 |
diff --git a/build.gradle b/build.gradle index 72f1bc57..694d5c2d 100644 --- a/build.gradle +++ b/build.gradle | |||
@@ -1,5 +1,5 @@ | |||
1 | plugins { | 1 | plugins { |
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 | |||
2 | ecoreCodegenVersion=2.27.0 | 2 | ecoreCodegenVersion=2.27.0 |
3 | ecoreXmiVersion=2.16.0 | 3 | ecoreXmiVersion=2.16.0 |
4 | hamcrestVersion=2.2 | 4 | hamcrestVersion=2.2 |
5 | jettyVersion=11.0.6 | 5 | jettyVersion=11.0.7 |
6 | jmhVersion=1.32 | 6 | jmhVersion=1.33 |
7 | junitVersion=5.8.1 | 7 | junitVersion=5.8.1 |
8 | mockitoVersion=4.0.0 | ||
8 | mweVersion=1.6.2.M1 | 9 | mweVersion=1.6.2.M1 |
9 | mwe2Version=2.12.2.M1 | 10 | mwe2Version=2.12.2.M1 |
10 | nodeVersion=14.18.0 | 11 | nodeVersion=16.13.0 |
11 | slf4JVersion=2.0.0-alpha5 | 12 | slf4JVersion=2.0.0-alpha5 |
12 | viatraVersion=2.6.0 | 13 | viatraVersion=2.6.0 |
13 | xtextVersion=2.26.0.M2 | 14 | xtextVersion=2.26.0.M2 |
14 | xtextAntlrGeneratorVersion=2.1.1 | 15 | xtextAntlrGeneratorVersion=2.1.1 |
15 | yarnVersion=1.22.11 | 16 | yarnVersion=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 | ||
10 | def jacocoTestReport = tasks.named('jacocoTestReport') | 12 | def 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 | */ |
4 | package tools.refinery.language.ide; | 4 | package tools.refinery.language.ide; |
5 | 5 | ||
6 | import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher; | ||
6 | import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator; | 7 | import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator; |
7 | 8 | ||
9 | import tools.refinery.language.ide.contentassist.FuzzyMatcher; | ||
8 | import tools.refinery.language.ide.syntaxcoloring.ProblemSemanticHighlightingCalculator; | 10 | import 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 | */ |
13 | public class ProblemIdeModule extends AbstractProblemIdeModule { | 15 | public 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 @@ | |||
1 | package tools.refinery.language.ide.contentassist; | ||
2 | |||
3 | import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher; | ||
4 | |||
5 | import 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 | ||
20 | public 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 | ||
18 | import tools.refinery.language.model.ProblemUtil; | 18 | import tools.refinery.language.model.ProblemUtil; |
19 | import tools.refinery.language.model.problem.ClassDeclaration; | 19 | import tools.refinery.language.model.problem.ClassDeclaration; |
20 | import tools.refinery.language.model.problem.EnumDeclaration; | ||
21 | import tools.refinery.language.model.problem.NamedElement; | 20 | import tools.refinery.language.model.problem.NamedElement; |
22 | import tools.refinery.language.model.problem.Node; | 21 | import tools.refinery.language.model.problem.Node; |
23 | import tools.refinery.language.model.problem.Parameter; | ||
24 | import tools.refinery.language.model.problem.PredicateDefinition; | 22 | import tools.refinery.language.model.problem.PredicateDefinition; |
25 | import tools.refinery.language.model.problem.ProblemPackage; | 23 | import tools.refinery.language.model.problem.ProblemPackage; |
26 | import tools.refinery.language.model.problem.ReferenceDeclaration; | 24 | import tools.refinery.language.model.problem.ReferenceDeclaration; |
27 | import tools.refinery.language.model.problem.Variable; | ||
28 | 25 | ||
29 | public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator { | 26 | public 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 @@ | |||
1 | apply plugin: 'java-library' | ||
2 | apply from: "${rootDir}/gradle/java-common.gradle" | ||
3 | |||
4 | dependencies { | ||
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 @@ | |||
1 | package tools.refinery.language.mwe2; | ||
2 | |||
3 | import java.util.Set; | ||
4 | |||
5 | import org.eclipse.xtext.xtext.generator.web.WebIntegrationFragment; | ||
6 | |||
7 | import com.google.common.collect.Multimap; | ||
8 | |||
9 | public 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 @@ | |||
1 | apply plugin: 'java' | 1 | apply plugin: 'java' |
2 | apply from: "${rootDir}/gradle/xtext-common.gradle" | 2 | apply from: "${rootDir}/gradle/xtext-common.gradle" |
3 | apply from: "${rootDir}/gradle/junit.gradle" | ||
3 | 4 | ||
4 | dependencies { | 5 | dependencies { |
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 | ||
15 | def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage') | 20 | def 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 | ||
41 | def installFrontend = tasks.named('installFrontend') | 46 | def installFrontend = tasks.named('installFrontend') |
42 | 47 | ||
48 | def 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 | |||
43 | def assembleFrontend = tasks.named('assembleFrontend') | 57 | def assembleFrontend = tasks.named('assembleFrontend') |
44 | assembleFrontend.configure { | 58 | assembleFrontend.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 | ||
126 | tasks.register('webpackServe', RunNpmYarn) { | 141 | tasks.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 | |||
25 | body { | ||
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 | |||
156 | li.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 @@ | |||
1 | package tools.refinery.language.web; | 1 | package tools.refinery.language.web; |
2 | 2 | ||
3 | import java.io.IOException; | 3 | import java.io.IOException; |
4 | import java.time.Duration; | ||
4 | import java.util.regex.Pattern; | 5 | import java.util.regex.Pattern; |
5 | 6 | ||
7 | import org.eclipse.jetty.http.HttpHeader; | ||
8 | |||
6 | import jakarta.servlet.Filter; | 9 | import jakarta.servlet.Filter; |
7 | import jakarta.servlet.FilterChain; | 10 | import jakarta.servlet.FilterChain; |
8 | import jakarta.servlet.FilterConfig; | 11 | import jakarta.servlet.FilterConfig; |
@@ -13,16 +16,11 @@ import jakarta.servlet.http.HttpServletRequest; | |||
13 | import jakarta.servlet.http.HttpServletResponse; | 16 | import jakarta.servlet.http.HttpServletResponse; |
14 | 17 | ||
15 | public class CacheControlFilter implements Filter { | 18 | public 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 | */ |
4 | package tools.refinery.language.web; | 4 | package tools.refinery.language.web; |
5 | 5 | ||
6 | import org.eclipse.xtext.web.server.XtextServiceDispatcher; | ||
7 | import org.eclipse.xtext.web.server.model.IWebDocumentProvider; | ||
8 | import org.eclipse.xtext.web.server.model.XtextWebDocumentAccess; | ||
9 | import org.eclipse.xtext.web.server.occurrences.OccurrencesService; | ||
10 | |||
11 | import tools.refinery.language.web.occurrences.ProblemOccurrencesService; | ||
12 | import tools.refinery.language.web.xtext.server.push.PushServiceDispatcher; | ||
13 | import tools.refinery.language.web.xtext.server.push.PushWebDocumentAccess; | ||
14 | import 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 | */ |
10 | public class ProblemWebModule extends AbstractProblemWebModule { | 19 | public 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 | */ | ||
4 | package tools.refinery.language.web; | 1 | package tools.refinery.language.web; |
5 | 2 | ||
6 | import org.eclipse.xtext.util.DisposableRegistry; | 3 | import org.eclipse.xtext.util.DisposableRegistry; |
7 | 4 | ||
8 | import jakarta.servlet.ServletException; | 5 | import jakarta.servlet.ServletException; |
9 | import tools.refinery.language.web.xtext.XtextServlet; | 6 | import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet; |
10 | 7 | ||
11 | /** | 8 | public class ProblemWebSocketServlet extends XtextWebSocketServlet { |
12 | * Deploy this class into a servlet container to enable DSL-specific services. | ||
13 | */ | ||
14 | public 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; | |||
9 | import java.net.URI; | 9 | import java.net.URI; |
10 | import java.net.URISyntaxException; | 10 | import java.net.URISyntaxException; |
11 | import java.util.EnumSet; | 11 | import java.util.EnumSet; |
12 | import java.util.Optional; | ||
12 | import java.util.Set; | 13 | import java.util.Set; |
13 | 14 | ||
14 | import org.eclipse.jetty.server.Server; | 15 | import org.eclipse.jetty.server.Server; |
@@ -17,29 +18,36 @@ import org.eclipse.jetty.servlet.DefaultServlet; | |||
17 | import org.eclipse.jetty.servlet.ServletContextHandler; | 18 | import org.eclipse.jetty.servlet.ServletContextHandler; |
18 | import org.eclipse.jetty.servlet.ServletHolder; | 19 | import org.eclipse.jetty.servlet.ServletHolder; |
19 | import org.eclipse.jetty.util.resource.Resource; | 20 | import org.eclipse.jetty.util.resource.Resource; |
21 | import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; | ||
20 | import org.slf4j.Logger; | 22 | import org.slf4j.Logger; |
21 | import org.slf4j.LoggerFactory; | 23 | import org.slf4j.LoggerFactory; |
22 | 24 | ||
23 | import jakarta.servlet.DispatcherType; | 25 | import jakarta.servlet.DispatcherType; |
24 | import jakarta.servlet.SessionTrackingMode; | 26 | import jakarta.servlet.SessionTrackingMode; |
27 | import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet; | ||
25 | 28 | ||
26 | public class ServerLauncher { | 29 | public 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 @@ | |||
1 | package tools.refinery.language.web.occurrences; | ||
2 | |||
3 | import org.eclipse.emf.ecore.EObject; | ||
4 | import org.eclipse.xtext.web.server.occurrences.OccurrencesService; | ||
5 | |||
6 | import com.google.inject.Singleton; | ||
7 | |||
8 | import tools.refinery.language.model.problem.NamedElement; | ||
9 | |||
10 | @Singleton | ||
11 | public 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 | */ | ||
9 | package tools.refinery.language.web.xtext; | ||
10 | |||
11 | import java.io.IOException; | ||
12 | import java.net.URLDecoder; | ||
13 | import java.nio.charset.Charset; | ||
14 | import java.util.Collections; | ||
15 | import java.util.Enumeration; | ||
16 | import java.util.HashMap; | ||
17 | import java.util.Map; | ||
18 | import java.util.Set; | ||
19 | |||
20 | import org.eclipse.xtext.web.server.IServiceContext; | ||
21 | import org.eclipse.xtext.web.server.ISession; | ||
22 | |||
23 | import com.google.common.io.CharStreams; | ||
24 | |||
25 | import jakarta.servlet.http.HttpServletRequest; | ||
26 | |||
27 | /** | ||
28 | * Provides the parameters and metadata of an {@link HttpServletRequest}. | ||
29 | */ | ||
30 | class 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 | */ | ||
9 | package tools.refinery.language.web.xtext; | ||
10 | |||
11 | import org.eclipse.xtext.web.server.ISession; | ||
12 | import org.eclipse.xtext.xbase.lib.Functions.Function0; | ||
13 | |||
14 | import jakarta.servlet.http.HttpSession; | ||
15 | |||
16 | /** | ||
17 | * Provides access to the information stored in a {@link HttpSession}. | ||
18 | */ | ||
19 | record 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 | */ | ||
9 | package tools.refinery.language.web.xtext; | ||
10 | |||
11 | import java.io.IOException; | ||
12 | import java.util.Set; | ||
13 | |||
14 | import org.eclipse.emf.common.util.URI; | ||
15 | import org.eclipse.xtext.resource.IResourceServiceProvider; | ||
16 | import org.eclipse.xtext.web.server.IServiceContext; | ||
17 | import org.eclipse.xtext.web.server.IServiceResult; | ||
18 | import org.eclipse.xtext.web.server.IUnwrappableServiceResult; | ||
19 | import org.eclipse.xtext.web.server.InvalidRequestException; | ||
20 | import org.eclipse.xtext.web.server.XtextServiceDispatcher; | ||
21 | import org.slf4j.Logger; | ||
22 | import org.slf4j.LoggerFactory; | ||
23 | |||
24 | import com.google.common.base.Objects; | ||
25 | import com.google.common.base.Strings; | ||
26 | import com.google.gson.Gson; | ||
27 | import com.google.inject.Injector; | ||
28 | |||
29 | import jakarta.servlet.ServletException; | ||
30 | import jakarta.servlet.http.HttpServlet; | ||
31 | import jakarta.servlet.http.HttpServletRequest; | ||
32 | import 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 | * @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 | */ | ||
52 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server; | ||
2 | |||
3 | import java.util.Objects; | ||
4 | |||
5 | import org.eclipse.xtext.web.server.IServiceResult; | ||
6 | |||
7 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server; | ||
2 | |||
3 | import tools.refinery.language.web.xtext.server.message.XtextWebResponse; | ||
4 | |||
5 | @FunctionalInterface | ||
6 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server; | ||
2 | |||
3 | import java.util.Set; | ||
4 | |||
5 | import org.eclipse.xtext.web.server.IServiceContext; | ||
6 | import org.eclipse.xtext.web.server.ISession; | ||
7 | |||
8 | import tools.refinery.language.web.xtext.server.push.PrecomputationListener; | ||
9 | |||
10 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server; | ||
2 | |||
3 | import java.lang.ref.WeakReference; | ||
4 | import java.util.ArrayList; | ||
5 | import java.util.HashMap; | ||
6 | import java.util.List; | ||
7 | import java.util.Map; | ||
8 | |||
9 | import org.eclipse.emf.common.util.URI; | ||
10 | import org.eclipse.xtext.resource.IResourceServiceProvider; | ||
11 | import org.eclipse.xtext.util.IDisposable; | ||
12 | import org.eclipse.xtext.web.server.IServiceContext; | ||
13 | import org.eclipse.xtext.web.server.IServiceResult; | ||
14 | import org.eclipse.xtext.web.server.ISession; | ||
15 | import org.eclipse.xtext.web.server.InvalidRequestException; | ||
16 | import org.eclipse.xtext.web.server.InvalidRequestException.UnknownLanguageException; | ||
17 | import org.eclipse.xtext.web.server.XtextServiceDispatcher; | ||
18 | import org.slf4j.Logger; | ||
19 | import org.slf4j.LoggerFactory; | ||
20 | |||
21 | import com.google.common.base.Strings; | ||
22 | import com.google.inject.Injector; | ||
23 | |||
24 | import tools.refinery.language.web.xtext.server.message.XtextWebErrorKind; | ||
25 | import tools.refinery.language.web.xtext.server.message.XtextWebErrorResponse; | ||
26 | import tools.refinery.language.web.xtext.server.message.XtextWebOkResponse; | ||
27 | import tools.refinery.language.web.xtext.server.message.XtextWebPushMessage; | ||
28 | import tools.refinery.language.web.xtext.server.message.XtextWebRequest; | ||
29 | import tools.refinery.language.web.xtext.server.push.PrecomputationListener; | ||
30 | import tools.refinery.language.web.xtext.server.push.PushWebDocument; | ||
31 | import tools.refinery.language.web.xtext.servlet.SimpleServiceContext; | ||
32 | |||
33 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.message; | ||
2 | |||
3 | import com.google.gson.annotations.SerializedName; | ||
4 | |||
5 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.message; | ||
2 | |||
3 | import java.util.Objects; | ||
4 | |||
5 | import com.google.gson.annotations.SerializedName; | ||
6 | |||
7 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.message; | ||
2 | |||
3 | import java.util.Objects; | ||
4 | |||
5 | import org.eclipse.xtext.web.server.IServiceResult; | ||
6 | import org.eclipse.xtext.web.server.IUnwrappableServiceResult; | ||
7 | |||
8 | import com.google.gson.annotations.SerializedName; | ||
9 | |||
10 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.message; | ||
2 | |||
3 | import java.util.Objects; | ||
4 | |||
5 | import com.google.gson.annotations.SerializedName; | ||
6 | |||
7 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.message; | ||
2 | |||
3 | import java.util.Map; | ||
4 | import java.util.Objects; | ||
5 | |||
6 | import com.google.gson.annotations.SerializedName; | ||
7 | |||
8 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.message; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.push; | ||
2 | |||
3 | import org.eclipse.xtext.web.server.IServiceResult; | ||
4 | |||
5 | import tools.refinery.language.web.xtext.server.ResponseHandlerException; | ||
6 | |||
7 | @FunctionalInterface | ||
8 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.push; | ||
2 | |||
3 | import org.eclipse.xtext.web.server.IServiceContext; | ||
4 | import org.eclipse.xtext.web.server.XtextServiceDispatcher; | ||
5 | import org.eclipse.xtext.web.server.model.XtextWebDocument; | ||
6 | |||
7 | import com.google.inject.Singleton; | ||
8 | |||
9 | import tools.refinery.language.web.xtext.server.SubscribingServiceContext; | ||
10 | |||
11 | @Singleton | ||
12 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.push; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.HashMap; | ||
5 | import java.util.List; | ||
6 | import java.util.Map; | ||
7 | |||
8 | import org.eclipse.xtext.util.CancelIndicator; | ||
9 | import org.eclipse.xtext.web.server.IServiceResult; | ||
10 | import org.eclipse.xtext.web.server.model.AbstractCachedService; | ||
11 | import org.eclipse.xtext.web.server.model.DocumentSynchronizer; | ||
12 | import org.eclipse.xtext.web.server.model.XtextWebDocument; | ||
13 | import org.slf4j.Logger; | ||
14 | import org.slf4j.LoggerFactory; | ||
15 | |||
16 | import com.google.common.collect.ImmutableList; | ||
17 | |||
18 | import tools.refinery.language.web.xtext.server.ResponseHandlerException; | ||
19 | |||
20 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.push; | ||
2 | |||
3 | import org.eclipse.xtext.service.OperationCanceledManager; | ||
4 | import org.eclipse.xtext.util.CancelIndicator; | ||
5 | import org.eclipse.xtext.util.concurrent.CancelableUnitOfWork; | ||
6 | import org.eclipse.xtext.web.server.IServiceResult; | ||
7 | import org.eclipse.xtext.web.server.model.AbstractCachedService; | ||
8 | import org.eclipse.xtext.web.server.model.IXtextWebDocument; | ||
9 | import org.eclipse.xtext.web.server.model.PrecomputedServiceRegistry; | ||
10 | import org.eclipse.xtext.web.server.model.XtextWebDocument; | ||
11 | import org.eclipse.xtext.web.server.model.XtextWebDocumentAccess; | ||
12 | import org.eclipse.xtext.web.server.syntaxcoloring.HighlightingService; | ||
13 | import org.eclipse.xtext.web.server.validation.ValidationService; | ||
14 | |||
15 | import com.google.inject.Inject; | ||
16 | |||
17 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.server.push; | ||
2 | |||
3 | import org.eclipse.xtext.web.server.IServiceContext; | ||
4 | import org.eclipse.xtext.web.server.model.DocumentSynchronizer; | ||
5 | import org.eclipse.xtext.web.server.model.IWebDocumentProvider; | ||
6 | import org.eclipse.xtext.web.server.model.XtextWebDocument; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import 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 | ||
19 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.servlet; | ||
2 | |||
3 | import java.util.Map; | ||
4 | import java.util.Set; | ||
5 | |||
6 | import org.eclipse.xtext.web.server.IServiceContext; | ||
7 | import org.eclipse.xtext.web.server.ISession; | ||
8 | |||
9 | import com.google.common.collect.ImmutableSet; | ||
10 | |||
11 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.servlet; | ||
2 | |||
3 | import java.util.HashMap; | ||
4 | import java.util.Map; | ||
5 | |||
6 | import org.eclipse.xtext.web.server.ISession; | ||
7 | import org.eclipse.xtext.xbase.lib.Functions.Function0; | ||
8 | |||
9 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.servlet; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.servlet; | ||
2 | |||
3 | import java.io.IOException; | ||
4 | import java.io.Reader; | ||
5 | |||
6 | import org.eclipse.jetty.websocket.api.Session; | ||
7 | import org.eclipse.jetty.websocket.api.StatusCode; | ||
8 | import org.eclipse.jetty.websocket.api.WriteCallback; | ||
9 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; | ||
10 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; | ||
11 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; | ||
12 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; | ||
13 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; | ||
14 | import org.eclipse.xtext.resource.IResourceServiceProvider; | ||
15 | import org.eclipse.xtext.web.server.ISession; | ||
16 | import org.slf4j.Logger; | ||
17 | import org.slf4j.LoggerFactory; | ||
18 | |||
19 | import com.google.gson.Gson; | ||
20 | import com.google.gson.JsonIOException; | ||
21 | import com.google.gson.JsonParseException; | ||
22 | |||
23 | import tools.refinery.language.web.xtext.server.ResponseHandler; | ||
24 | import tools.refinery.language.web.xtext.server.ResponseHandlerException; | ||
25 | import tools.refinery.language.web.xtext.server.TransactionExecutor; | ||
26 | import tools.refinery.language.web.xtext.server.message.XtextWebRequest; | ||
27 | import tools.refinery.language.web.xtext.server.message.XtextWebResponse; | ||
28 | |||
29 | @WebSocket | ||
30 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.servlet; | ||
2 | |||
3 | import java.io.IOException; | ||
4 | import java.time.Duration; | ||
5 | import java.util.Set; | ||
6 | |||
7 | import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; | ||
8 | import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; | ||
9 | import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; | ||
10 | import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; | ||
11 | import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; | ||
12 | import org.eclipse.xtext.resource.IResourceServiceProvider; | ||
13 | import org.slf4j.Logger; | ||
14 | import org.slf4j.LoggerFactory; | ||
15 | |||
16 | import jakarta.servlet.ServletConfig; | ||
17 | import jakarta.servlet.ServletException; | ||
18 | |||
19 | public 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 @@ | |||
1 | import AppBar from '@mui/material/AppBar'; | 1 | import AppBar from '@mui/material/AppBar'; |
2 | import Box from '@mui/material/Box'; | 2 | import Box from '@mui/material/Box'; |
3 | import Button from '@mui/material/Button'; | ||
4 | import IconButton from '@mui/material/IconButton'; | 3 | import IconButton from '@mui/material/IconButton'; |
5 | import Toolbar from '@mui/material/Toolbar'; | 4 | import Toolbar from '@mui/material/Toolbar'; |
6 | import Typography from '@mui/material/Typography'; | 5 | import Typography from '@mui/material/Typography'; |
7 | import MenuIcon from '@mui/icons-material/Menu'; | 6 | import MenuIcon from '@mui/icons-material/Menu'; |
8 | import PlayArrowIcon from '@mui/icons-material/PlayArrow'; | ||
9 | import React from 'react'; | 7 | import React from 'react'; |
10 | 8 | ||
11 | import { EditorArea } from './editor/EditorArea'; | 9 | import { EditorArea } from './editor/EditorArea'; |
12 | import { EditorButtons } from './editor/EditorButtons'; | 10 | import { EditorButtons } from './editor/EditorButtons'; |
11 | import { GenerateButton } from './editor/GenerateButton'; | ||
13 | 12 | ||
14 | export const App = (): JSX.Element => ( | 13 | export 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 @@ | |||
1 | import { Command, EditorView } from '@codemirror/view'; | ||
2 | import { closeSearchPanel, openSearchPanel } from '@codemirror/search'; | ||
3 | import { closeLintPanel, openLintPanel } from '@codemirror/lint'; | ||
1 | import { observer } from 'mobx-react-lite'; | 4 | import { observer } from 'mobx-react-lite'; |
2 | import React, { useRef } from 'react'; | 5 | import React, { |
6 | useCallback, | ||
7 | useEffect, | ||
8 | useRef, | ||
9 | useState, | ||
10 | } from 'react'; | ||
3 | 11 | ||
12 | import { EditorParent } from './EditorParent'; | ||
4 | import { useRootStore } from '../RootStore'; | 13 | import { useRootStore } from '../RootStore'; |
14 | import { getLogger } from '../utils/logger'; | ||
15 | |||
16 | const log = getLogger('editor.EditorArea'); | ||
17 | |||
18 | function 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 | |||
66 | function 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 | ||
6 | export const EditorArea = observer(() => { | 73 | export 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 @@ | |||
1 | import type { Diagnostic } from '@codemirror/lint'; | ||
1 | import { observer } from 'mobx-react-lite'; | 2 | import { observer } from 'mobx-react-lite'; |
3 | import IconButton from '@mui/material/IconButton'; | ||
2 | import Stack from '@mui/material/Stack'; | 4 | import Stack from '@mui/material/Stack'; |
3 | import ToggleButton from '@mui/material/ToggleButton'; | 5 | import ToggleButton from '@mui/material/ToggleButton'; |
4 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; | 6 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; |
7 | import CheckIcon from '@mui/icons-material/Check'; | ||
8 | import ErrorIcon from '@mui/icons-material/Error'; | ||
5 | import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; | 9 | import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; |
10 | import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; | ||
6 | import RedoIcon from '@mui/icons-material/Redo'; | 11 | import RedoIcon from '@mui/icons-material/Redo'; |
12 | import SearchIcon from '@mui/icons-material/Search'; | ||
7 | import UndoIcon from '@mui/icons-material/Undo'; | 13 | import UndoIcon from '@mui/icons-material/Undo'; |
14 | import WarningIcon from '@mui/icons-material/Warning'; | ||
8 | import React from 'react'; | 15 | import React from 'react'; |
9 | 16 | ||
10 | import { useRootStore } from '../RootStore'; | 17 | import { useRootStore } from '../RootStore'; |
11 | 18 | ||
19 | // Exhastive switch as proven by TypeScript. | ||
20 | // eslint-disable-next-line consistent-return | ||
21 | function 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 | |||
12 | export const EditorButtons = observer(() => { | 34 | export 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 @@ | |||
1 | import { 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 | */ | ||
12 | function 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 | |||
20 | export 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 @@ | |||
1 | import type { Editor, EditorConfiguration } from 'codemirror'; | 1 | import { autocompletion, completionKeymap } from '@codemirror/autocomplete'; |
2 | import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets'; | ||
3 | import { defaultKeymap, indentWithTab } from '@codemirror/commands'; | ||
4 | import { commentKeymap } from '@codemirror/comment'; | ||
5 | import { foldGutter, foldKeymap } from '@codemirror/fold'; | ||
6 | import { highlightActiveLineGutter, lineNumbers } from '@codemirror/gutter'; | ||
7 | import { classHighlightStyle } from '@codemirror/highlight'; | ||
8 | import { | ||
9 | history, | ||
10 | historyKeymap, | ||
11 | redo, | ||
12 | redoDepth, | ||
13 | undo, | ||
14 | undoDepth, | ||
15 | } from '@codemirror/history'; | ||
16 | import { indentOnInput } from '@codemirror/language'; | ||
17 | import { | ||
18 | Diagnostic, | ||
19 | lintKeymap, | ||
20 | setDiagnostics, | ||
21 | } from '@codemirror/lint'; | ||
22 | import { bracketMatching } from '@codemirror/matchbrackets'; | ||
23 | import { rectangularSelection } from '@codemirror/rectangular-selection'; | ||
24 | import { searchConfig, searchKeymap } from '@codemirror/search'; | ||
25 | import { | ||
26 | EditorState, | ||
27 | StateCommand, | ||
28 | StateEffect, | ||
29 | Transaction, | ||
30 | TransactionSpec, | ||
31 | } from '@codemirror/state'; | ||
32 | import { | ||
33 | drawSelection, | ||
34 | EditorView, | ||
35 | highlightActiveLine, | ||
36 | highlightSpecialChars, | ||
37 | keymap, | ||
38 | } from '@codemirror/view'; | ||
2 | import { | 39 | import { |
3 | createAtom, | ||
4 | makeAutoObservable, | 40 | makeAutoObservable, |
5 | observable, | 41 | observable, |
6 | runInAction, | 42 | reaction, |
7 | } from 'mobx'; | 43 | } from 'mobx'; |
8 | import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror'; | ||
9 | 44 | ||
10 | import type { IEditorChunk } from './editor'; | 45 | import { findOccurrences, IOccurrence, setOccurrences } from './findOccurrences'; |
11 | import { getLogger } from '../logging'; | 46 | import { problemLanguageSupport } from '../language/problemLanguageSupport'; |
47 | import { | ||
48 | IHighlightRange, | ||
49 | semanticHighlighting, | ||
50 | setSemanticHighlighting, | ||
51 | } from './semanticHighlighting'; | ||
12 | import type { ThemeStore } from '../theme/ThemeStore'; | 52 | import type { ThemeStore } from '../theme/ThemeStore'; |
53 | import { getLogger } from '../utils/logger'; | ||
54 | import { XtextClient } from '../xtext/XtextClient'; | ||
13 | 55 | ||
14 | const log = getLogger('EditorStore'); | 56 | const log = getLogger('editor.EditorStore'); |
15 | 57 | ||
16 | const xtextLang = 'problem'; | 58 | export class EditorStore { |
59 | private readonly themeStore; | ||
17 | 60 | ||
18 | const xtextOptions: IXtextOptions = { | 61 | state: EditorState; |
19 | xtextLang, | ||
20 | enableFormattingAction: true, | ||
21 | }; | ||
22 | 62 | ||
23 | const 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 | ||
31 | export 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 @@ | |||
1 | import { observer } from 'mobx-react-lite'; | ||
2 | import Button from '@mui/material/Button'; | ||
3 | import PlayArrowIcon from '@mui/icons-material/PlayArrow'; | ||
4 | import React from 'react'; | ||
5 | |||
6 | import { useRootStore } from '../RootStore'; | ||
7 | |||
8 | const GENERATE_LABEL = 'Generate'; | ||
9 | |||
10 | export 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 @@ | |||
1 | import { StateEffect, StateField, TransactionSpec } from '@codemirror/state'; | ||
2 | import { EditorView, Decoration, DecorationSet } from '@codemirror/view'; | ||
3 | |||
4 | export type TransactionSpecFactory = (decorations: DecorationSet) => TransactionSpec; | ||
5 | |||
6 | export 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 @@ | |||
1 | import 'codemirror/addon/selection/active-line'; | ||
2 | import 'mode-problem'; | ||
3 | import { Controlled } from 'react-codemirror2'; | ||
4 | import { createServices, removeServices } from 'xtext/xtext-codemirror'; | ||
5 | |||
6 | export interface IEditorChunk { | ||
7 | CodeMirror: typeof Controlled; | ||
8 | |||
9 | createServices: typeof createServices; | ||
10 | |||
11 | removeServices: typeof removeServices; | ||
12 | } | ||
13 | |||
14 | export 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 @@ | |||
1 | import { Range, RangeSet } from '@codemirror/rangeset'; | ||
2 | import type { TransactionSpec } from '@codemirror/state'; | ||
3 | import { Decoration } from '@codemirror/view'; | ||
4 | |||
5 | import { decorationSetExtension } from './decorationSetExtension'; | ||
6 | |||
7 | export interface IOccurrence { | ||
8 | from: number; | ||
9 | |||
10 | to: number; | ||
11 | } | ||
12 | |||
13 | const [setOccurrencesInteral, findOccurrences] = decorationSetExtension(); | ||
14 | |||
15 | const writeDecoration = Decoration.mark({ | ||
16 | class: 'cm-problem-write', | ||
17 | }); | ||
18 | |||
19 | const readDecoration = Decoration.mark({ | ||
20 | class: 'cm-problem-read', | ||
21 | }); | ||
22 | |||
23 | export 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 | |||
35 | export { 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 @@ | |||
1 | import { RangeSet } from '@codemirror/rangeset'; | ||
2 | import type { TransactionSpec } from '@codemirror/state'; | ||
3 | import { Decoration } from '@codemirror/view'; | ||
4 | |||
5 | import { decorationSetExtension } from './decorationSetExtension'; | ||
6 | |||
7 | export interface IHighlightRange { | ||
8 | from: number; | ||
9 | |||
10 | to: number; | ||
11 | |||
12 | classes: string[]; | ||
13 | } | ||
14 | |||
15 | const [setSemanticHighlightingInternal, semanticHighlighting] = decorationSetExtension(); | ||
16 | |||
17 | export 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 | |||
24 | export { 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'; | |||
9 | import '../css/index.scss'; | 9 | import '../css/index.scss'; |
10 | 10 | ||
11 | const initialValue = `class Family { | 11 | const initialValue = `class Family { |
12 | contains Person[] members | 12 | contains Person[] members |
13 | } | 13 | } |
14 | 14 | ||
15 | class Person { | 15 | class 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 | ||
22 | enum TaxStatus { | 22 | enum 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. |
27 | error invalidTaxStatus(Person p) <-> | 27 | pred 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 | |||
34 | direct 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 | ||
30 | unique family. | 41 | unique family. |
31 | Family(family). | 42 | Family(family). |
@@ -44,8 +55,7 @@ age(bob, bobAge). | |||
44 | scope Family = 1, Person += 5..10. | 55 | scope Family = 1, Person += 5..10. |
45 | `; | 56 | `; |
46 | 57 | ||
47 | const rootStore = new RootStore(); | 58 | const rootStore = new RootStore(initialValue); |
48 | rootStore.editorStore.updateValue(initialValue); | ||
49 | 59 | ||
50 | const app = ( | 60 | const 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 @@ | |||
1 | import { EditorState } from '@codemirror/state'; | ||
2 | import type { SyntaxNode } from '@lezer/common'; | ||
3 | |||
4 | export 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 | */ | ||
12 | export 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 | */ | ||
50 | export 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 | */ | ||
78 | function 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 | |||
103 | export function foldWholeNode(node: SyntaxNode): FoldRange { | ||
104 | return { | ||
105 | from: node.from, | ||
106 | to: node.to, | ||
107 | }; | ||
108 | } | ||
109 | |||
110 | export 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 @@ | |||
1 | import { 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 | */ | ||
13 | function 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 | */ | ||
61 | function 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 | |||
69 | export function indentBlockComment(): number { | ||
70 | // Do not indent. | ||
71 | return -1; | ||
72 | } | ||
73 | |||
74 | export function indentDeclaration(context: TreeIndentContext): number { | ||
75 | return indentDeclarationStrategy(context, 1); | ||
76 | } | ||
77 | |||
78 | export 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 | |||
3 | statement { | ||
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 | |||
41 | ReferenceDeclaration { | ||
42 | (kw<"refers"> | kw<"contains">)? | ||
43 | RelationName | ||
44 | RelationName | ||
45 | ( "[" Multiplicity? "]" )? | ||
46 | (kw<"opposite"> RelationName)? | ||
47 | ";"? | ||
48 | } | ||
49 | |||
50 | Parameter { RelationName? VariableName } | ||
51 | |||
52 | Conjunction { ("," | Literal)+ } | ||
53 | |||
54 | OrOp { ";" } | ||
55 | |||
56 | Literal { NotOp? Atom (("=" | ":") sep1<"|", LogicValue>)? } | ||
57 | |||
58 | Atom { RelationName "+"? ParameterList<Argument> } | ||
59 | |||
60 | Action { ("," | ActionLiteral)+ } | ||
61 | |||
62 | ActionLiteral { | ||
63 | ckw<"new"> VariableName | | ||
64 | ckw<"delete"> VariableName | | ||
65 | Literal | ||
66 | } | ||
67 | |||
68 | Argument { VariableName | Constant } | ||
69 | |||
70 | AssertionArgument { NodeName | StarArgument | Constant } | ||
71 | |||
72 | Constant { Real | String } | ||
73 | |||
74 | LogicValue { | ||
75 | ckw<"true"> | ckw<"false"> | ckw<"unknown"> | ckw<"error"> | ||
76 | } | ||
77 | |||
78 | ScopeElement { RelationName ("=" | "+=") Multiplicity } | ||
79 | |||
80 | Multiplicity { (IntMult "..")? (IntMult | StarMult)} | ||
81 | |||
82 | RelationName { QualifiedName } | ||
83 | |||
84 | RuleName { QualifiedName } | ||
85 | |||
86 | UniqueNodeName { QualifiedName } | ||
87 | |||
88 | VariableName { QualifiedName } | ||
89 | |||
90 | NodeName { QualifiedName } | ||
91 | |||
92 | QualifiedName { identifier ("::" identifier)* } | ||
93 | |||
94 | kw<term> { @specialize[@name={term}]<identifier, term> } | ||
95 | |||
96 | ckw<term> { @extend[@name={term}]<identifier, term> } | ||
97 | |||
98 | ParameterList<content> { "(" sep<",", content> ")" } | ||
99 | |||
100 | sep<separator, content> { sep1<separator, content>? } | ||
101 | |||
102 | sep1<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 @@ | |||
1 | import { styleTags, tags as t } from '@codemirror/highlight'; | ||
2 | import { | ||
3 | foldInside, | ||
4 | foldNodeProp, | ||
5 | indentNodeProp, | ||
6 | indentUnit, | ||
7 | LanguageSupport, | ||
8 | LRLanguage, | ||
9 | } from '@codemirror/language'; | ||
10 | import { LRParser } from '@lezer/lr'; | ||
11 | |||
12 | import { parser } from '../../../../build/generated/sources/lezer/problem'; | ||
13 | import { | ||
14 | foldBlockComment, | ||
15 | foldConjunction, | ||
16 | foldDeclaration, | ||
17 | foldWholeNode, | ||
18 | } from './folding'; | ||
19 | import { | ||
20 | indentBlockComment, | ||
21 | indentDeclaration, | ||
22 | indentPredicateOrRule, | ||
23 | } from './indentation'; | ||
24 | |||
25 | const 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 | |||
74 | const 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 | |||
88 | export 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 @@ | |||
1 | import { getLogger } from './logger'; | ||
2 | import { PendingTask } from './PendingTask'; | ||
3 | |||
4 | const log = getLogger('utils.ConditionVariable'); | ||
5 | |||
6 | export type Condition = () => boolean; | ||
7 | |||
8 | export 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 @@ | |||
1 | import { getLogger } from './logger'; | ||
2 | |||
3 | const log = getLogger('utils.PendingTask'); | ||
4 | |||
5 | export 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 @@ | |||
1 | export 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'; | |||
2 | import log from 'loglevel'; | 2 | import log from 'loglevel'; |
3 | import * as prefix from 'loglevel-plugin-prefix'; | 3 | import * as prefix from 'loglevel-plugin-prefix'; |
4 | 4 | ||
5 | const colors: Record<string, CSPair> = { | 5 | const 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 | |||
10 | define([], 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 @@ | |||
1 | import type { | ||
2 | Completion, | ||
3 | CompletionContext, | ||
4 | CompletionResult, | ||
5 | } from '@codemirror/autocomplete'; | ||
6 | import type { Transaction } from '@codemirror/state'; | ||
7 | import escapeStringRegexp from 'escape-string-regexp'; | ||
8 | |||
9 | import type { UpdateService } from './UpdateService'; | ||
10 | import { getLogger } from '../utils/logger'; | ||
11 | import type { IContentAssistEntry } from './xtextServiceResults'; | ||
12 | |||
13 | const PROPOSALS_LIMIT = 1000; | ||
14 | |||
15 | const IDENTIFIER_REGEXP_STR = '[a-zA-Z0-9_]*'; | ||
16 | |||
17 | const HIGH_PRIORITY_KEYWORDS = ['<->']; | ||
18 | |||
19 | const QUALIFIED_NAME_SEPARATOR_REGEXP = /::/g; | ||
20 | |||
21 | const log = getLogger('xtext.ContentAssistService'); | ||
22 | |||
23 | function 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 | |||
50 | function 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 | |||
63 | export 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 @@ | |||
1 | import type { EditorStore } from '../editor/EditorStore'; | ||
2 | import type { IHighlightRange } from '../editor/semanticHighlighting'; | ||
3 | import type { UpdateService } from './UpdateService'; | ||
4 | import { getLogger } from '../utils/logger'; | ||
5 | import { isHighlightingResult } from './xtextServiceResults'; | ||
6 | |||
7 | const log = getLogger('xtext.ValidationService'); | ||
8 | |||
9 | export 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 @@ | |||
1 | import { Transaction } from '@codemirror/state'; | ||
2 | |||
3 | import type { EditorStore } from '../editor/EditorStore'; | ||
4 | import type { IOccurrence } from '../editor/findOccurrences'; | ||
5 | import type { UpdateService } from './UpdateService'; | ||
6 | import { getLogger } from '../utils/logger'; | ||
7 | import { Timer } from '../utils/Timer'; | ||
8 | import { XtextWebSocketClient } from './XtextWebSocketClient'; | ||
9 | import { | ||
10 | isOccurrencesResult, | ||
11 | isServiceConflictResult, | ||
12 | ITextRegion, | ||
13 | } from './xtextServiceResults'; | ||
14 | |||
15 | const 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. | ||
19 | const CLEAR_OCCURRENCES_TIMEOUT_MS = 10; | ||
20 | |||
21 | const log = getLogger('xtext.OccurrencesService'); | ||
22 | |||
23 | function 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 | |||
36 | export 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 | |||
10 | define([ | ||
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 @@ | |||
1 | import { | ||
2 | ChangeDesc, | ||
3 | ChangeSet, | ||
4 | Transaction, | ||
5 | } from '@codemirror/state'; | ||
6 | import { nanoid } from 'nanoid'; | ||
7 | |||
8 | import type { EditorStore } from '../editor/EditorStore'; | ||
9 | import type { XtextWebSocketClient } from './XtextWebSocketClient'; | ||
10 | import { ConditionVariable } from '../utils/ConditionVariable'; | ||
11 | import { getLogger } from '../utils/logger'; | ||
12 | import { Timer } from '../utils/Timer'; | ||
13 | import { | ||
14 | IContentAssistEntry, | ||
15 | isContentAssistResult, | ||
16 | isDocumentStateResult, | ||
17 | isInvalidStateIdConflictResult, | ||
18 | } from './xtextServiceResults'; | ||
19 | |||
20 | const UPDATE_TIMEOUT_MS = 500; | ||
21 | |||
22 | const WAIT_FOR_UPDATE_TIMEOUT_MS = 1000; | ||
23 | |||
24 | const log = getLogger('xtext.UpdateService'); | ||
25 | |||
26 | export interface IAbortSignal { | ||
27 | aborted: boolean; | ||
28 | } | ||
29 | |||
30 | export 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 @@ | |||
1 | import type { Diagnostic } from '@codemirror/lint'; | ||
2 | |||
3 | import type { EditorStore } from '../editor/EditorStore'; | ||
4 | import type { UpdateService } from './UpdateService'; | ||
5 | import { getLogger } from '../utils/logger'; | ||
6 | import { isValidationResult } from './xtextServiceResults'; | ||
7 | |||
8 | const log = getLogger('xtext.ValidationService'); | ||
9 | |||
10 | export 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 @@ | |||
1 | import type { | ||
2 | CompletionContext, | ||
3 | CompletionResult, | ||
4 | } from '@codemirror/autocomplete'; | ||
5 | import type { Transaction } from '@codemirror/state'; | ||
6 | |||
7 | import type { EditorStore } from '../editor/EditorStore'; | ||
8 | import { ContentAssistService } from './ContentAssistService'; | ||
9 | import { HighlightingService } from './HighlightingService'; | ||
10 | import { OccurrencesService } from './OccurrencesService'; | ||
11 | import { UpdateService } from './UpdateService'; | ||
12 | import { getLogger } from '../utils/logger'; | ||
13 | import { ValidationService } from './ValidationService'; | ||
14 | import { XtextWebSocketClient } from './XtextWebSocketClient'; | ||
15 | |||
16 | const log = getLogger('xtext.XtextClient'); | ||
17 | |||
18 | export 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 @@ | |||
1 | import { nanoid } from 'nanoid'; | ||
2 | |||
3 | import { getLogger } from '../utils/logger'; | ||
4 | import { PendingTask } from '../utils/PendingTask'; | ||
5 | import { Timer } from '../utils/Timer'; | ||
6 | import { | ||
7 | isErrorResponse, | ||
8 | isOkResponse, | ||
9 | isPushMessage, | ||
10 | IXtextWebRequest, | ||
11 | } from './xtextMessages'; | ||
12 | import { isPongResult } from './xtextServiceResults'; | ||
13 | |||
14 | const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1'; | ||
15 | |||
16 | const WEBSOCKET_CLOSE_OK = 1000; | ||
17 | |||
18 | const RECONNECT_DELAY_MS = [200, 1000, 5000, 30_000]; | ||
19 | |||
20 | const MAX_RECONNECT_DELAY_MS = RECONNECT_DELAY_MS[RECONNECT_DELAY_MS.length - 1]; | ||
21 | |||
22 | const BACKGROUND_IDLE_TIMEOUT_MS = 5 * 60 * 1000; | ||
23 | |||
24 | const PING_TIMEOUT_MS = 10 * 1000; | ||
25 | |||
26 | const REQUEST_TIMEOUT_MS = 1000; | ||
27 | |||
28 | const log = getLogger('xtext.XtextWebSocketClient'); | ||
29 | |||
30 | export type ReconnectHandler = () => void; | ||
31 | |||
32 | export type PushHandler = ( | ||
33 | resourceId: string, | ||
34 | stateId: string, | ||
35 | service: string, | ||
36 | data: unknown, | ||
37 | ) => void; | ||
38 | |||
39 | enum State { | ||
40 | Initial, | ||
41 | Opening, | ||
42 | TabVisible, | ||
43 | TabHiddenIdle, | ||
44 | TabHiddenWaiting, | ||
45 | Error, | ||
46 | TimedOut, | ||
47 | } | ||
48 | |||
49 | export 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 | |||
10 | define([], 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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 | |||
10 | define(['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 @@ | |||
1 | import { Editor } from 'codemirror'; | ||
2 | |||
3 | export function createEditor(options: IXtextOptions): IXtextCodeMirrorEditor; | ||
4 | |||
5 | export function createServices(editor: Editor, options: IXtextOptions): IXtextServices; | ||
6 | |||
7 | export function removeServices(editor: Editor): void; | ||
8 | |||
9 | export 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 | |||
38 | export interface IXtextCodeMirrorEditor extends Editor { | ||
39 | xtextServices: IXtextServices; | ||
40 | } | ||
41 | |||
42 | export 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 | */ | ||
76 | define([ | ||
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, '"') + '"' : ''; | ||
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 @@ | |||
1 | export interface IXtextWebRequest { | ||
2 | id: string; | ||
3 | |||
4 | request: unknown; | ||
5 | } | ||
6 | |||
7 | export interface IXtextWebOkResponse { | ||
8 | id: string; | ||
9 | |||
10 | response: unknown; | ||
11 | } | ||
12 | |||
13 | export 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 | |||
20 | export const VALID_XTEXT_WEB_ERROR_KINDS = ['request', 'server'] as const; | ||
21 | |||
22 | export type XtextWebErrorKind = typeof VALID_XTEXT_WEB_ERROR_KINDS[number]; | ||
23 | |||
24 | export function isXtextWebErrorKind(value: unknown): value is XtextWebErrorKind { | ||
25 | return typeof value === 'string' | ||
26 | && VALID_XTEXT_WEB_ERROR_KINDS.includes(value as XtextWebErrorKind); | ||
27 | } | ||
28 | |||
29 | export interface IXtextWebErrorResponse { | ||
30 | id: string; | ||
31 | |||
32 | error: XtextWebErrorKind; | ||
33 | |||
34 | message: string; | ||
35 | } | ||
36 | |||
37 | export 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 | |||
45 | export interface IXtextWebPushMessage { | ||
46 | resource: string; | ||
47 | |||
48 | stateId: string; | ||
49 | |||
50 | service: string; | ||
51 | |||
52 | push: unknown; | ||
53 | } | ||
54 | |||
55 | export 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 @@ | |||
1 | export interface IPongResult { | ||
2 | pong: string; | ||
3 | } | ||
4 | |||
5 | export 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 | |||
11 | export interface IDocumentStateResult { | ||
12 | stateId: string; | ||
13 | } | ||
14 | |||
15 | export 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 | |||
21 | export const VALID_CONFLICTS = ['invalidStateId', 'canceled'] as const; | ||
22 | |||
23 | export type Conflict = typeof VALID_CONFLICTS[number]; | ||
24 | |||
25 | export function isConflict(value: unknown): value is Conflict { | ||
26 | return typeof value === 'string' && VALID_CONFLICTS.includes(value as Conflict); | ||
27 | } | ||
28 | |||
29 | export interface IServiceConflictResult { | ||
30 | conflict: Conflict; | ||
31 | } | ||
32 | |||
33 | export function isServiceConflictResult(result: unknown): result is IServiceConflictResult { | ||
34 | const serviceConflictResult = result as IServiceConflictResult; | ||
35 | return typeof serviceConflictResult === 'object' | ||
36 | && isConflict(serviceConflictResult.conflict); | ||
37 | } | ||
38 | |||
39 | export function isInvalidStateIdConflictResult(result: unknown): boolean { | ||
40 | return isServiceConflictResult(result) && result.conflict === 'invalidStateId'; | ||
41 | } | ||
42 | |||
43 | export const VALID_SEVERITIES = ['error', 'warning', 'info', 'ignore'] as const; | ||
44 | |||
45 | export type Severity = typeof VALID_SEVERITIES[number]; | ||
46 | |||
47 | export function isSeverity(value: unknown): value is Severity { | ||
48 | return typeof value === 'string' && VALID_SEVERITIES.includes(value as Severity); | ||
49 | } | ||
50 | |||
51 | export 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 | |||
65 | export 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 | |||
76 | export interface IValidationResult { | ||
77 | issues: IIssue[]; | ||
78 | } | ||
79 | |||
80 | function 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 | |||
84 | export 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 | |||
90 | export interface IReplaceRegion { | ||
91 | offset: number; | ||
92 | |||
93 | length: number; | ||
94 | |||
95 | text: string; | ||
96 | } | ||
97 | |||
98 | export 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 | |||
106 | export interface ITextRegion { | ||
107 | offset: number; | ||
108 | |||
109 | length: number; | ||
110 | } | ||
111 | |||
112 | export 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 | |||
119 | export 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 | |||
141 | export type XtextContentAssistEntryKind = typeof VALID_XTEXT_CONTENT_ASSIST_ENTRY_KINDS[number]; | ||
142 | |||
143 | export 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 | |||
150 | export 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 | |||
170 | function isStringOrUndefined(value: unknown): value is string | undefined { | ||
171 | return typeof value === 'string' || typeof value === 'undefined'; | ||
172 | } | ||
173 | |||
174 | function isNumberOrUndefined(value: unknown): value is number | undefined { | ||
175 | return typeof value === 'number' || typeof value === 'undefined'; | ||
176 | } | ||
177 | |||
178 | export 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 | |||
192 | export interface IContentAssistResult extends IDocumentStateResult { | ||
193 | entries: IContentAssistEntry[]; | ||
194 | } | ||
195 | |||
196 | export function isContentAssistResult(result: unknown): result is IContentAssistResult { | ||
197 | const contentAssistResult = result as IContentAssistResult; | ||
198 | return isDocumentStateResult(result) | ||
199 | && isArrayOfType(contentAssistResult.entries, isContentAssistEntry); | ||
200 | } | ||
201 | |||
202 | export interface IHighlightingRegion { | ||
203 | offset: number; | ||
204 | |||
205 | length: number; | ||
206 | |||
207 | styleClasses: string[]; | ||
208 | } | ||
209 | |||
210 | export 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 | |||
218 | export interface IHighlightingResult { | ||
219 | regions: IHighlightingRegion[]; | ||
220 | } | ||
221 | |||
222 | export 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 | |||
228 | export interface IOccurrencesResult extends IDocumentStateResult { | ||
229 | writeRegions: ITextRegion[]; | ||
230 | |||
231 | readRegions: ITextRegion[]; | ||
232 | } | ||
233 | |||
234 | export 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 @@ | |||
1 | package tools.refinery.language.web; | ||
2 | |||
3 | import static org.hamcrest.MatcherAssert.assertThat; | ||
4 | import static org.hamcrest.Matchers.equalTo; | ||
5 | import static org.hamcrest.Matchers.hasSize; | ||
6 | import static org.hamcrest.Matchers.instanceOf; | ||
7 | import static org.hamcrest.Matchers.startsWith; | ||
8 | import static org.junit.jupiter.api.Assertions.assertThrows; | ||
9 | |||
10 | import java.io.IOException; | ||
11 | import java.net.InetSocketAddress; | ||
12 | import java.net.URI; | ||
13 | import java.util.concurrent.CompletableFuture; | ||
14 | import java.util.concurrent.CompletionException; | ||
15 | |||
16 | import org.eclipse.jetty.http.HttpHeader; | ||
17 | import org.eclipse.jetty.http.HttpStatus; | ||
18 | import org.eclipse.jetty.server.Server; | ||
19 | import org.eclipse.jetty.servlet.ServletContextHandler; | ||
20 | import org.eclipse.jetty.servlet.ServletHolder; | ||
21 | import org.eclipse.jetty.websocket.api.Session; | ||
22 | import org.eclipse.jetty.websocket.api.StatusCode; | ||
23 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; | ||
24 | import org.eclipse.jetty.websocket.api.exceptions.UpgradeException; | ||
25 | import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; | ||
26 | import org.eclipse.jetty.websocket.client.WebSocketClient; | ||
27 | import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; | ||
28 | import org.eclipse.xtext.testing.GlobalRegistries; | ||
29 | import org.eclipse.xtext.testing.GlobalRegistries.GlobalStateMemento; | ||
30 | import org.junit.jupiter.api.AfterEach; | ||
31 | import org.junit.jupiter.api.BeforeEach; | ||
32 | import org.junit.jupiter.api.Test; | ||
33 | import org.junit.jupiter.params.ParameterizedTest; | ||
34 | import org.junit.jupiter.params.provider.ValueSource; | ||
35 | |||
36 | import tools.refinery.language.web.tests.WebSocketIntegrationTestClient; | ||
37 | import tools.refinery.language.web.xtext.servlet.XtextStatusCode; | ||
38 | import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet; | ||
39 | |||
40 | class 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 @@ | |||
1 | package tools.refinery.language.web.tests; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.List; | ||
5 | import java.util.concurrent.ExecutorService; | ||
6 | |||
7 | import org.eclipse.xtext.ide.ExecutorServiceProvider; | ||
8 | |||
9 | import com.google.inject.Singleton; | ||
10 | |||
11 | @Singleton | ||
12 | public 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 @@ | |||
1 | package tools.refinery.language.web.tests; | ||
2 | |||
3 | import org.eclipse.xtext.ide.ExecutorServiceProvider; | ||
4 | import org.eclipse.xtext.util.DisposableRegistry; | ||
5 | import org.eclipse.xtext.util.Modules2; | ||
6 | |||
7 | import com.google.inject.Guice; | ||
8 | import com.google.inject.Injector; | ||
9 | |||
10 | import tools.refinery.language.ide.ProblemIdeModule; | ||
11 | import tools.refinery.language.tests.ProblemInjectorProvider; | ||
12 | import tools.refinery.language.web.ProblemWebModule; | ||
13 | import tools.refinery.language.web.ProblemWebSetup; | ||
14 | |||
15 | public 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 @@ | |||
1 | package tools.refinery.language.web.tests; | ||
2 | |||
3 | import java.util.Collection; | ||
4 | import java.util.List; | ||
5 | import java.util.concurrent.Callable; | ||
6 | import java.util.concurrent.ExecutionException; | ||
7 | import java.util.concurrent.ExecutorService; | ||
8 | import java.util.concurrent.Executors; | ||
9 | import java.util.concurrent.Future; | ||
10 | import java.util.concurrent.TimeUnit; | ||
11 | import java.util.concurrent.TimeoutException; | ||
12 | |||
13 | import org.slf4j.Logger; | ||
14 | import org.slf4j.LoggerFactory; | ||
15 | |||
16 | public 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 @@ | |||
1 | package tools.refinery.language.web.tests; | ||
2 | |||
3 | import static org.junit.jupiter.api.Assertions.fail; | ||
4 | |||
5 | import java.io.IOException; | ||
6 | import java.time.Duration; | ||
7 | import java.util.ArrayList; | ||
8 | import java.util.List; | ||
9 | |||
10 | import org.eclipse.jetty.websocket.api.Session; | ||
11 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; | ||
12 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; | ||
13 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; | ||
14 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; | ||
15 | |||
16 | public 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 @@ | |||
1 | package tools.refinery.language.web.xtext.servlet; | ||
2 | |||
3 | import static org.hamcrest.MatcherAssert.assertThat; | ||
4 | import static org.hamcrest.Matchers.equalTo; | ||
5 | import static org.hamcrest.Matchers.hasProperty; | ||
6 | import static org.hamcrest.Matchers.instanceOf; | ||
7 | import static org.mockito.Mockito.mock; | ||
8 | import static org.mockito.Mockito.times; | ||
9 | import static org.mockito.Mockito.verify; | ||
10 | |||
11 | import java.util.List; | ||
12 | import java.util.Map; | ||
13 | |||
14 | import org.eclipse.emf.common.util.URI; | ||
15 | import org.eclipse.xtext.resource.IResourceServiceProvider; | ||
16 | import org.eclipse.xtext.testing.InjectWith; | ||
17 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | ||
18 | import org.eclipse.xtext.web.server.model.DocumentStateResult; | ||
19 | import org.eclipse.xtext.web.server.syntaxcoloring.HighlightingResult; | ||
20 | import org.eclipse.xtext.web.server.validation.ValidationResult; | ||
21 | import org.junit.jupiter.api.BeforeEach; | ||
22 | import org.junit.jupiter.api.Test; | ||
23 | import org.junit.jupiter.api.extension.ExtendWith; | ||
24 | import org.mockito.ArgumentCaptor; | ||
25 | import org.mockito.junit.jupiter.MockitoExtension; | ||
26 | |||
27 | import com.google.inject.Inject; | ||
28 | |||
29 | import tools.refinery.language.web.tests.AwaitTerminationExecutorServiceProvider; | ||
30 | import tools.refinery.language.web.tests.ProblemWebInjectorProvider; | ||
31 | import tools.refinery.language.web.xtext.server.ResponseHandler; | ||
32 | import tools.refinery.language.web.xtext.server.ResponseHandlerException; | ||
33 | import tools.refinery.language.web.xtext.server.TransactionExecutor; | ||
34 | import tools.refinery.language.web.xtext.server.message.XtextWebOkResponse; | ||
35 | import tools.refinery.language.web.xtext.server.message.XtextWebRequest; | ||
36 | import tools.refinery.language.web.xtext.server.message.XtextWebResponse; | ||
37 | |||
38 | @ExtendWith(MockitoExtension.class) | ||
39 | @ExtendWith(InjectionExtension.class) | ||
40 | @InjectWith(ProblemWebInjectorProvider.class) | ||
41 | class 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; | |||
25 | const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort); | 25 | const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort); |
26 | 26 | ||
27 | const resolveSources = sources => path.resolve(__dirname, 'src', sources); | 27 | const resolveSources = sources => path.resolve(__dirname, 'src', sources); |
28 | const resolveGenerated = sources => path.resolve(__dirname, 'build/generated/sources', sources); | ||
29 | const mainJsSources = resolveSources('main/js'); | 28 | const mainJsSources = resolveSources('main/js'); |
30 | const babelLoaderFilters = { | 29 | const babelLoaderFilters = { |
31 | include: [mainJsSources], | 30 | include: [mainJsSources], |
32 | exclude: [resolveSources('main/js/xtext')], | ||
33 | }; | 31 | }; |
34 | const babelPresets = [ | 32 | const 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 | ||
2136 | array-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 | |||
1798 | array-union@^2.1.0: | 2147 | array-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 | ||
1803 | array.prototype.flat@^1.2.4: | 2152 | array.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 | ||
1812 | array.prototype.flatmap@^1.2.4: | 2161 | array.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 | ||
1844 | autoprefixer@^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 | |||
1857 | axe-core@^4.0.2: | 2193 | axe-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 | ||
1867 | babel-loader@^8.2.2: | 2203 | babel-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 | ||
1893 | babel-plugin-polyfill-corejs2@^0.2.2: | 2229 | babel-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 | ||
1902 | babel-plugin-polyfill-corejs3@^0.2.2: | 2238 | babel-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 | ||
1910 | babel-plugin-polyfill-regenerator@^0.2.2: | 2246 | babel-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 | |||
1917 | bail@^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 | ||
1922 | balanced-match@^1.0.0: | 2253 | balanced-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 | ||
2056 | browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.1: | 2387 | browserslist@^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 | ||
2398 | browserslist@^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 | |||
2067 | buffer-alloc-unsafe@^1.1.0: | 2409 | buffer-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 | ||
2144 | camel-case@^4.1.1: | 2486 | camel-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 | ||
2179 | caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001259: | 2521 | caniuse-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 | ||
2526 | caniuse-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 | |||
2184 | caw@^2.0.0, caw@^2.0.1: | 2531 | caw@^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 | ||
2214 | chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: | 2561 | chalk@^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 | ||
2222 | character-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 | |||
2227 | character-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 | |||
2232 | character-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 | ||
2257 | clean-css@^4.2.3: | 2589 | clean-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 | ||
2297 | codemirror@^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 | |||
2302 | color-convert@^1.9.0: | 2629 | color-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 | ||
2326 | colorette@^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 | |||
2331 | colorette@^2.0.10: | 2653 | colorette@^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 | ||
2658 | colorette@^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 | |||
2336 | commander@^2.20.0, commander@^2.8.1: | 2663 | commander@^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 | ||
2341 | commander@^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 | |||
2346 | commander@^7.0.0, commander@^7.2.0: | 2668 | commander@^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 | ||
2673 | commander@^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 | |||
2351 | commondir@^1.0.1: | 2678 | commondir@^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 | ||
2433 | core-js-compat@^3.16.0, core-js-compat@^3.16.2: | 2760 | core-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 | ||
2441 | core-js-pure@^3.16.0: | 2768 | core-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 | ||
2462 | cosmiconfig@^7.0.0: | 2789 | cosmiconfig@^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 | ||
2800 | crelt@^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 | |||
2473 | cross-spawn@^5.0.1: | 2805 | cross-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 | ||
2502 | css-loader@^6.3.0: | 2834 | css-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 | ||
2592 | debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: | 2924 | debug@^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 | ||
2798 | dom-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 | |||
2806 | dom-serializer@^1.0.1: | 3130 | dom-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 | ||
2815 | domelementtype@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 | |||
2820 | domelementtype@^2.0.1, domelementtype@^2.2.0: | 3139 | domelementtype@^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 | ||
2825 | domhandler@^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 | |||
2832 | domhandler@^4.0.0, domhandler@^4.2.0: | 3144 | domhandler@^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 | ||
2839 | domutils@^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 | |||
2847 | domutils@^2.5.2, domutils@^2.6.0: | 3151 | domutils@^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 | ||
3218 | electron-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 | |||
2914 | emoji-regex@^8.0.0: | 3223 | emoji-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 | ||
2956 | entities@^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 | |||
2961 | entities@^2.0.0: | 3265 | entities@^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 | ||
3306 | es-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 | |||
3002 | es-module-lexer@^0.9.0: | 3332 | es-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 | ||
3036 | eslint-config-airbnb-base@^14.2.1: | 3366 | escape-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 | |||
3371 | eslint-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 | ||
3045 | eslint-config-airbnb-typescript@^14.0.0: | 3380 | eslint-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 | ||
3050 | eslint-config-airbnb@^18.2.1: | 3387 | eslint-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 | ||
3067 | eslint-module-utils@^2.6.2: | 3404 | eslint-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 | ||
3075 | eslint-plugin-import@^2.24.2: | 3413 | eslint-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 | ||
3411 | extend@^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 | |||
3416 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: | 3747 | fast-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 | ||
3421 | fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.5: | 3752 | fast-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 | ||
3581 | find-up@^2.0.0, find-up@^2.1.0: | 3912 | find-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 | ||
3816 | globby@^11.0.1, globby@^11.0.3: | 4147 | globby@^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 | ||
3833 | gonzales-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 | |||
3840 | got@^7.0.0: | 4164 | got@^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 | ||
3990 | html-minifier-terser@^5.0.1: | 4314 | html-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 | ||
4003 | html-tags@^3.1.0: | 4327 | html-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 | ||
4008 | html-webpack-plugin@^5.3.2: | 4332 | html-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 | ||
4019 | htmlparser2@^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 | |||
4031 | htmlparser2@^6.1.0: | 4343 | htmlparser2@^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 | ||
4348 | is-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 | |||
4353 | is-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 | |||
4361 | is-arguments@^1.0.4: | 4660 | is-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 | ||
4396 | is-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 | |||
4401 | is-callable@^1.1.4, is-callable@^1.2.4: | 4695 | is-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 | ||
4406 | is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.6.0: | 4700 | is-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 | ||
4707 | is-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 | |||
4413 | is-cwebp-readable@^3.0.0: | 4714 | is-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 | ||
4427 | is-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 | |||
4432 | is-docker@^2.0.0, is-docker@^2.1.1: | 4728 | is-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 | ||
4466 | is-hexadecimal@^1.0.0: | 4762 | is-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 | ||
4471 | is-ip@^3.1.0: | 4769 | is-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 | ||
4525 | is-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 | |||
4530 | is-plain-obj@^3.0.0: | 4823 | is-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 | ||
4835 | is-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 | |||
4542 | is-png@^2.0.0: | 4840 | is-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 | ||
4863 | is-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 | |||
4565 | is-stream@^1.0.0, is-stream@^1.1.0: | 4868 | is-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 | ||
4601 | is-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 | |||
4606 | is-utf8@^0.2.0: | 4904 | is-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 | ||
4909 | is-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 | |||
4611 | is-wsl@^2.2.0: | 4916 | is-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 | ||
4650 | jquery@^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 | ||
4683 | json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: | 4983 | json-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 | ||
4752 | known-css-properties@^0.21.0: | 5052 | known-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 | ||
4757 | language-subtag-registry@~0.3.2: | 5057 | language-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 | ||
4793 | load-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 | |||
4803 | loader-runner@^4.2.0: | 5093 | loader-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 | ||
4866 | log-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 | |||
4874 | logalot@^2.0.0, logalot@^2.1.0: | 5156 | logalot@^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 | ||
4892 | longest-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 | |||
4897 | longest@^1.0.0: | 5174 | longest@^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 | ||
4997 | mdast-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 | |||
5008 | mdast-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 | |||
5020 | mdast-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 | |||
5025 | mdn-data@2.0.14: | 5274 | mdn-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 | ||
5096 | micromark@~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 | |||
5104 | micromatch@^4.0.2, micromatch@^4.0.4: | 5345 | micromatch@^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 | ||
5149 | mini-css-extract-plugin@^2.3.0: | 5390 | mini-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 | ||
5194 | mobx@^6.3.3: | 5435 | mobx@^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 | ||
5199 | mozjpeg@^7.0.0: | 5440 | mozjpeg@^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 | ||
5246 | nanocolors@^0.2.2, nanocolors@^0.2.8: | 5487 | nanocolors@^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 | ||
5497 | nanoid@^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 | |||
5256 | natural-compare@^1.4.0: | 5502 | natural-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 | ||
5540 | node-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 | |||
5294 | normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: | 5545 | normalize-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 | ||
5319 | normalize-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 | |||
5324 | normalize-selector@^0.2.0: | 5570 | normalize-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 | ||
5367 | num2fraction@^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 | |||
5372 | object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: | 5613 | object-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 | ||
5682 | object.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 | |||
5441 | obuf@^1.0.0, obuf@^1.1.2: | 5691 | obuf@^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 | ||
5655 | param-case@^3.0.3: | 5905 | param-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 | ||
5670 | parse-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 | |||
5682 | parse-json@^2.2.0: | 5920 | parse-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 | ||
5689 | parse-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 | |||
5697 | parse-json@^5.0.0: | 5927 | parse-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 | ||
5771 | path-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 | |||
5778 | path-type@^4.0.0: | 6001 | path-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 | ||
6011 | picocolors@^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 | |||
5788 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: | 6016 | picomatch@^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 | ||
5834 | pkg-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 | |||
5841 | pngquant-bin@^6.0.0: | 6062 | pngquant-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 | ||
5860 | postcss-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 | |||
5867 | postcss-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 | |||
5874 | postcss-media-query-parser@^0.2.3: | 6081 | postcss-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 | ||
5912 | postcss-safe-parser@^4.0.2: | 6119 | postcss-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 | |||
5919 | postcss-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 | ||
5927 | postcss-scss@^2.1.1: | 6124 | postcss-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 | ||
5934 | postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: | 6129 | postcss-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 | ||
5942 | postcss-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 | |||
5947 | postcss-value-parser@^4.1.0: | 6137 | postcss-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 | ||
5952 | postcss@^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 | |||
5960 | postcss@^8.2.15: | 6142 | postcss@^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 | ||
6151 | postcss@^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 | |||
5969 | prelude-ls@^1.2.1: | 6160 | prelude-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 | ||
5984 | pretty-error@^3.0.4: | 6175 | pretty-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 | ||
5992 | process-nextick-args@~2.0.0: | 6183 | process-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 | |||
6103 | react-dom@^17.0.2: | 6289 | react-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 | ||
6148 | read-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 | |||
6156 | read-pkg-up@^7.0.1: | 6334 | read-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 | ||
6174 | read-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 | |||
6183 | read-pkg@^5.2.0: | 6352 | read-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 | ||
6206 | readable-stream@^3.0.6, readable-stream@^3.1.1: | 6375 | readable-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 | ||
6311 | remark-parse@^9.0.0: | 6480 | renderkid@^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 | |||
6318 | remark-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 | |||
6325 | remark@^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 | |||
6334 | renderkid@^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 | |||
6345 | repeat-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 | ||
6350 | repeating@^2.0.0: | 6491 | repeating@^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 | ||
6458 | sass-loader@^12.1.0: | 6599 | sass-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 | ||
6466 | sass@^1.42.1: | 6607 | sass@^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 | ||
6705 | source-map-support@~0.5.12, source-map-support@~0.5.20: | 6846 | source-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 | ||
6718 | source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: | 6859 | source-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 | ||
6811 | string-width@^4.2.0, string-width@^4.2.2: | 6952 | string-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 | ||
6864 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: | 7005 | strip-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 | ||
6945 | style-loader@^3.3.0: | 7086 | style-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 | |||
7091 | style-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 | ||
6950 | style-search@^0.1.0: | 7096 | style-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 | ||
6955 | stylelint-config-recommended-scss@^4.3.0: | 7101 | stylelint-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 | ||
6962 | stylelint-config-recommended@^5.0.0: | 7110 | stylelint-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 | ||
6967 | stylelint-scss@^3.21.0: | 7115 | stylelint-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 | ||
6978 | stylelint@^13.13.1: | 7126 | stylelint@^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 | ||
7032 | stylis@^4.0.3: | 7170 | stylis@^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 | ||
7037 | sugarss@^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 | |||
7044 | supports-color@^2.0.0: | 7175 | supports-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 | ||
7088 | table@^6.0.9, table@^6.6.0: | 7219 | table@^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 | ||
7100 | tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: | 7231 | tapable@^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 | ||
7143 | terser@^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 | |||
7152 | terser@^5.7.2: | 7274 | terser@^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 | ||
7220 | trough@^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 | |||
7225 | tsconfig-paths@^3.11.0: | 7342 | tsconfig-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 | ||
7311 | typescript@^4.4.3: | 7428 | typescript@^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 | ||
7316 | unbox-primitive@^1.0.1: | 7433 | unbox-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 | ||
7357 | unified@^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 | |||
7369 | unist-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 | |||
7376 | unist-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 | |||
7381 | unist-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 | |||
7388 | unpipe@1.0.0, unpipe@~1.0.0: | 7474 | unpipe@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 | ||
7447 | v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0, v8-compile-cache@^2.3.0: | 7533 | v8-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 | ||
7465 | vfile-message@^2.0.0: | 7551 | w3c-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 | |||
7473 | vfile@^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 | ||
7483 | watchpack@^2.2.0: | 7556 | watchpack@^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 | ||
7498 | webpack-cli@^4.8.0: | 7571 | webpack-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 | ||
7517 | webpack-dev-middleware@^5.2.1: | 7589 | webpack-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 | ||
7528 | webpack-dev-server@^4.3.0: | 7600 | webpack-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 | ||
7579 | webpack@^5.56.0: | 7651 | webpack@^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 | |||
7716 | zwitch@^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 | ||
22 | sourceSets { | 21 | sourceSets { |
@@ -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 | ||
64 | sonarqube.properties { | 61 | sonarqube.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 | |||
3 | import org.eclipse.xtext.xtext.generator.* | 3 | import org.eclipse.xtext.xtext.generator.* |
4 | import org.eclipse.xtext.xtext.generator.model.project.* | 4 | import org.eclipse.xtext.xtext.generator.model.project.* |
5 | 5 | ||
6 | import tools.refinery.language.mwe2.* | 6 | var rootPath = '..' |
7 | |||
8 | var rootPath = ".." | ||
9 | 7 | ||
10 | Workflow { | 8 | Workflow { |
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 | ||
28 | ReferenceDeclaration: | 28 | ReferenceDeclaration: |
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 | ||
185 | Identifier: | 185 | Identifier: |
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 | ||
189 | Integer returns ecore::EInt hidden(): | 189 | Integer 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' | |||
3 | include 'language' | 3 | include 'language' |
4 | include 'language-ide' | 4 | include 'language-ide' |
5 | include 'language-model' | 5 | include 'language-model' |
6 | include 'language-mwe2' | ||
7 | include 'language-to-store' | 6 | include 'language-to-store' |
8 | include 'language-web' | 7 | include 'language-web' |
9 | include 'store' | 8 | include 'store' |