occam-custom-grammars 5.0.1229 → 5.0.1230
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/example.js +206 -182
- package/lib/constants.js +5 -1
- package/lib/customGrammar/combined.js +29 -18
- package/lib/customGrammar/default.js +3 -3
- package/lib/example/customGrammar/userDefined1.js +2 -2
- package/lib/example/view.js +29 -27
- package/lib/utilities/validate.js +107 -0
- package/lib/utilities/vocabulary.js +8 -37
- package/package.json +1 -1
- package/src/constants.js +3 -0
- package/src/customGrammar/combined.js +42 -26
- package/src/customGrammar/default.js +2 -2
- package/src/example/customGrammar/userDefined1.js +1 -5
- package/src/example/view.js +8 -8
- package/src/utilities/{bnf.js → validate.js} +66 -10
- package/src/utilities/vocabulary.js +5 -40
- package/lib/utilities/bnf.js +0 -66
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { arrayUtilities } from "necessary";
|
|
4
|
+
import { specialSymbols } from "occam-lexers";
|
|
4
5
|
import { parserUtilities } from "occam-parsers";
|
|
5
6
|
import { eliminateLeftRecursion } from "occam-grammar-utilities";
|
|
6
7
|
|
|
7
8
|
import defaultCustomGrammar from "../customGrammar/default";
|
|
8
9
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
10
|
+
import { expressionsFromVocabulary } from "../utilities/vocabulary";
|
|
11
|
+
import { VERTICAL_BAR, VERTICAL_SPACE } from "../constants";
|
|
12
|
+
import { validateBNF, validateVocabulary } from "../utilities/validate";
|
|
11
13
|
import { TERM_RULE_NAME, STATEMENT_RULE_NAME } from "../ruleNames";
|
|
12
|
-
import { validateVocabulary, expressionsFromVocabulary } from "../utilities/vocabulary";
|
|
13
14
|
import { TYPE_VOCABULARY_NAME, SYMBOL_VOCABULARY_NAME } from "../vocabularyNames";
|
|
14
15
|
|
|
15
|
-
const {
|
|
16
|
-
{
|
|
16
|
+
const { opaque } = specialSymbols,
|
|
17
|
+
{ rulesFromBNF } = parserUtilities,
|
|
18
|
+
{ unshift, forwardsForEach, backwardsForEach } = arrayUtilities;
|
|
17
19
|
|
|
18
20
|
export default class CombinedCustomGrammar {
|
|
19
21
|
constructor(rules, entries) {
|
|
@@ -77,10 +79,24 @@ function rulesFromCustomGrammars(customGrammars) {
|
|
|
77
79
|
|
|
78
80
|
return bnf;
|
|
79
81
|
}),
|
|
80
|
-
bnf = bnfs.join(
|
|
82
|
+
bnf = bnfs.join(VERTICAL_SPACE),
|
|
81
83
|
rules = rulesFromBNF(bnf);
|
|
82
84
|
|
|
83
|
-
combineRules(rules)
|
|
85
|
+
combineRules(rules);
|
|
86
|
+
|
|
87
|
+
const opacity = opaque; ///
|
|
88
|
+
|
|
89
|
+
ruleNames.forEach((ruleName) => {
|
|
90
|
+
const rule = rules.find((rule) => {
|
|
91
|
+
const name = rule.getName();
|
|
92
|
+
|
|
93
|
+
if (name === ruleName) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
rule.setOpacity(opacity);
|
|
99
|
+
});
|
|
84
100
|
|
|
85
101
|
return rules;
|
|
86
102
|
}
|
|
@@ -99,25 +115,6 @@ function entriesFromCustomGrammars(customGrammars) {
|
|
|
99
115
|
return entries;
|
|
100
116
|
}
|
|
101
117
|
|
|
102
|
-
function bnfFromCustomGrammars(customGrammars, ruleName) {
|
|
103
|
-
const bnfs = [];
|
|
104
|
-
|
|
105
|
-
backwardsForEach(customGrammars, (customGrammar) => {
|
|
106
|
-
const bnf = customGrammar.getBNF(ruleName),
|
|
107
|
-
customGrammarDefaultCustomGrammar = customGrammar.isDefaultCustomGrammar();
|
|
108
|
-
|
|
109
|
-
if (!customGrammarDefaultCustomGrammar) {
|
|
110
|
-
validateBNF(bnf, ruleName);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
bnfs.push(bnf);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
const bnf = bnfs.join(EMPTY_STRING);
|
|
117
|
-
|
|
118
|
-
return bnf;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
118
|
function entryFromCustomGrammars(customGrammars, vocabularyName) {
|
|
122
119
|
const expressions = [];
|
|
123
120
|
|
|
@@ -142,6 +139,25 @@ function entryFromCustomGrammars(customGrammars, vocabularyName) {
|
|
|
142
139
|
return entry;
|
|
143
140
|
}
|
|
144
141
|
|
|
142
|
+
function bnfFromCustomGrammars(customGrammars, ruleName) {
|
|
143
|
+
const bnfs = [];
|
|
144
|
+
|
|
145
|
+
forwardsForEach(customGrammars, (customGrammar) => {
|
|
146
|
+
const bnf = customGrammar.getBNF(ruleName),
|
|
147
|
+
customGrammarDefaultCustomGrammar = customGrammar.isDefaultCustomGrammar();
|
|
148
|
+
|
|
149
|
+
if (!customGrammarDefaultCustomGrammar) {
|
|
150
|
+
validateBNF(bnf, ruleName);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
bnfs.push(bnf);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const bnf = bnfs.join(VERTICAL_SPACE);
|
|
157
|
+
|
|
158
|
+
return bnf;
|
|
159
|
+
}
|
|
160
|
+
|
|
145
161
|
function combineRules(rules) {
|
|
146
162
|
let outerIndex = 0,
|
|
147
163
|
length = rules.length;
|
|
@@ -4,13 +4,13 @@ import CustomGrammar from "../customGrammar";
|
|
|
4
4
|
|
|
5
5
|
import { DEFAULT_CUSTOM_GRAMMAR_NAME } from "../grammarNames";
|
|
6
6
|
|
|
7
|
-
export const termBNF = `term
|
|
7
|
+
export const termBNF = `term ::= "(" argument ")"
|
|
8
8
|
|
|
9
9
|
| variable
|
|
10
10
|
|
|
11
11
|
;`;
|
|
12
12
|
|
|
13
|
-
export const statementBNF = `statement
|
|
13
|
+
export const statementBNF = `statement ::= "(" metaArgument ")"
|
|
14
14
|
|
|
15
15
|
| equality
|
|
16
16
|
|
|
@@ -5,11 +5,7 @@ import { CustomGrammar } from "../../index"; ///
|
|
|
5
5
|
import { USER_DEFINED_CUSTOM_GRAMMAR_NAME_1 } from "../grammarNames";
|
|
6
6
|
|
|
7
7
|
const name = USER_DEFINED_CUSTOM_GRAMMAR_NAME_1,
|
|
8
|
-
termBNF =
|
|
9
|
-
|
|
10
|
-
term ::= [type] "stuff" ;
|
|
11
|
-
|
|
12
|
-
`,
|
|
8
|
+
termBNF = "",
|
|
13
9
|
statementBNF = "",
|
|
14
10
|
typeVocabulary = "",
|
|
15
11
|
symbolVocabulary = "",
|
package/src/example/view.js
CHANGED
|
@@ -30,7 +30,7 @@ const { rulesAsString } = rulesUtilities,
|
|
|
30
30
|
|
|
31
31
|
class View extends Element {
|
|
32
32
|
keyUpHandler = (event, element) => {
|
|
33
|
-
try {
|
|
33
|
+
// try {
|
|
34
34
|
const bnf = this.getBNF(),
|
|
35
35
|
name = this.getName(),
|
|
36
36
|
ruleName = this.getRuleName(),
|
|
@@ -78,13 +78,13 @@ class View extends Element {
|
|
|
78
78
|
nominalBNF = rulesString; ///
|
|
79
79
|
|
|
80
80
|
this.setNominalBNF(nominalBNF);
|
|
81
|
-
} catch (error) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
81
|
+
// } catch (error) {
|
|
82
|
+
// console.log(error);
|
|
83
|
+
//
|
|
84
|
+
// this.clearParseTree();
|
|
85
|
+
//
|
|
86
|
+
// this.clearNominalBNF();
|
|
87
|
+
// }
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
changeHandler = (event, element) => {
|
|
@@ -4,25 +4,37 @@ import { arrayUtilities } from "necessary";
|
|
|
4
4
|
|
|
5
5
|
import typesMap from "../typesMap";
|
|
6
6
|
|
|
7
|
-
import { nodesQuery } from "../utilities/query";
|
|
8
7
|
import { nominalLexer } from "../utilities/nominal";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { UNDERSCORE_CHARACTER } from "../constants";
|
|
9
|
+
import { nodeQuery, nodesQuery } from "../utilities/query";
|
|
10
|
+
import { customGrammarBNFLexer, customGrammarBNFParser, customGrammarVocabularyLexer, customGrammarVocabularyParser } from "../utilities/grammar";
|
|
11
11
|
|
|
12
12
|
const { first, second } = arrayUtilities;
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const expressionNodesQuery = nodesQuery("//expression"),
|
|
15
|
+
ruleNameTerminalNodeQuery = nodeQuery("/document/rule/name/@*!"),
|
|
16
|
+
stringLiteralTerminalNodesQuery = nodesQuery("//stringLiteral/@*!"),
|
|
15
17
|
significantTokenTypeTerminalNodesQuery = nodesQuery("//significantTokenType/@*!");
|
|
16
18
|
|
|
17
19
|
export function validateBNF(bnf, ruleName) {
|
|
18
|
-
if ((bnf === null) || (bnf === EMPTY_STRING)) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
20
|
const content = bnf,
|
|
23
21
|
tokens = customGrammarBNFLexer.tokenise(content),
|
|
24
22
|
node = customGrammarBNFParser.parse(tokens);
|
|
25
23
|
|
|
24
|
+
if (node === null) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const ruleNameTerminalNode = ruleNameTerminalNodeQuery(node);
|
|
29
|
+
|
|
30
|
+
if (ruleNameTerminalNode !== null) {
|
|
31
|
+
const name = nameFromRuleNameTerminalNode(ruleNameTerminalNode);
|
|
32
|
+
|
|
33
|
+
if (name !== ruleName) {
|
|
34
|
+
throw new Error(`The '${name}' rule should be named '${ruleName}'.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
const types = typesMap[ruleName],
|
|
27
39
|
significantTokenTypeTerminalNodes = significantTokenTypeTerminalNodesQuery(node);
|
|
28
40
|
|
|
@@ -62,12 +74,56 @@ export function validateBNF(bnf, ruleName) {
|
|
|
62
74
|
});
|
|
63
75
|
}
|
|
64
76
|
|
|
77
|
+
export function validateVocabulary(vocabulary) {
|
|
78
|
+
const content = vocabulary, ///
|
|
79
|
+
tokens = customGrammarVocabularyLexer.tokenise(content),
|
|
80
|
+
node = customGrammarVocabularyParser.parse(tokens);
|
|
81
|
+
|
|
82
|
+
if (node === null) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const expressionNodes = expressionNodesQuery(node);
|
|
87
|
+
|
|
88
|
+
expressionNodes.forEach((expressionNode) => {
|
|
89
|
+
const content = contentFromExpressionNode(expressionNode),
|
|
90
|
+
tokens = nominalLexer.tokenise(content),
|
|
91
|
+
tokensLength = tokens.length;
|
|
92
|
+
|
|
93
|
+
if (tokensLength > 1) {
|
|
94
|
+
throw new Error(`Tokenising the '${content}' content results in more than one token.`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const firstToken = first(tokens),
|
|
98
|
+
token = firstToken,
|
|
99
|
+
type = token.getType();
|
|
100
|
+
|
|
101
|
+
if (type !== UNASSIGNED_TYPE) {
|
|
102
|
+
throw new Error(`The '${type}' type of the '${content}' token is not 'unassigned'.`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (content === UNDERSCORE_CHARACTER) {
|
|
106
|
+
throw new Error(`The '${content}' token cannot be an underscore.`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function nameFromRuleNameTerminalNode(ruleNameTerminalNode) {
|
|
112
|
+
let name;
|
|
113
|
+
|
|
114
|
+
const content = ruleNameTerminalNode.getContent();
|
|
115
|
+
|
|
116
|
+
name = content; ///
|
|
117
|
+
|
|
118
|
+
return name;
|
|
119
|
+
}
|
|
120
|
+
|
|
65
121
|
function contentFromStringLiteralTerminalNode(stringLiteralTerminalNode) {
|
|
66
122
|
let content;
|
|
67
123
|
|
|
68
124
|
content = stringLiteralTerminalNode.getContent();
|
|
69
125
|
|
|
70
|
-
const matches = content.match(/"([^"]
|
|
126
|
+
const matches = content.match(/"([^"]*)"/),
|
|
71
127
|
secondMatch = second(matches);
|
|
72
128
|
|
|
73
129
|
content = secondMatch; ///
|
|
@@ -79,7 +135,7 @@ function typeFromSignificantTokenTypeTerminalNode(significantTokenTypeTerminalNo
|
|
|
79
135
|
let type;
|
|
80
136
|
|
|
81
137
|
const content = significantTokenTypeTerminalNode.getContent(),
|
|
82
|
-
matches = content.match(/\[([^\]]
|
|
138
|
+
matches = content.match(/\[([^\]]*)\]/),
|
|
83
139
|
secondMatch = second(matches);
|
|
84
140
|
|
|
85
141
|
type = secondMatch; ///
|
|
@@ -3,57 +3,22 @@
|
|
|
3
3
|
import { arrayUtilities } from "necessary";
|
|
4
4
|
|
|
5
5
|
import { nodesQuery } from "../utilities/query";
|
|
6
|
-
import { nominalLexer } from "../utilities/nominal";
|
|
7
|
-
import { EMPTY_STRING, UNASSIGNED_TYPE, UNDERSCORE_CHARACTER } from "../constants";
|
|
8
6
|
import { customGrammarVocabularyLexer, customGrammarVocabularyParser } from "../utilities/grammar"
|
|
9
7
|
|
|
10
|
-
const {
|
|
8
|
+
const { second } = arrayUtilities;
|
|
11
9
|
|
|
12
|
-
const expressionNodesQuery = nodesQuery("//expression")
|
|
13
|
-
|
|
14
|
-
export function validateVocabulary(vocabulary) {
|
|
15
|
-
if ((vocabulary === null) || (vocabulary === EMPTY_STRING)) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
10
|
+
const expressionNodesQuery = nodesQuery("//expression");
|
|
18
11
|
|
|
12
|
+
export function expressionsFromVocabulary(vocabulary, expressions) {
|
|
19
13
|
const content = vocabulary, ///
|
|
20
14
|
tokens = customGrammarVocabularyLexer.tokenise(content),
|
|
21
15
|
node = customGrammarVocabularyParser.parse(tokens);
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
expressionNodes.forEach((expressionNode) => {
|
|
26
|
-
const content = contentFromExpressionNode(expressionNode),
|
|
27
|
-
tokens = nominalLexer.tokenise(content),
|
|
28
|
-
tokensLength = tokens.length;
|
|
29
|
-
|
|
30
|
-
if (tokensLength > 1) {
|
|
31
|
-
throw new Error(`Tokenising the '${content}' content results in more than one token.`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const firstToken = first(tokens),
|
|
35
|
-
token = firstToken,
|
|
36
|
-
type = token.getType();
|
|
37
|
-
|
|
38
|
-
if (type !== UNASSIGNED_TYPE) {
|
|
39
|
-
throw new Error(`The '${type}' type of the '${content}' token is not 'unassigned'.`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (content === UNDERSCORE_CHARACTER) {
|
|
43
|
-
throw new Error(`The '${content}' token cannot be an underscore.`);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function expressionsFromVocabulary(vocabulary, expressions) {
|
|
49
|
-
if ((vocabulary === null) || (vocabulary === EMPTY_STRING)) {
|
|
17
|
+
if (node === null) {
|
|
50
18
|
return;
|
|
51
19
|
}
|
|
52
20
|
|
|
53
|
-
const
|
|
54
|
-
tokens = customGrammarVocabularyLexer.tokenise(content),
|
|
55
|
-
node = customGrammarVocabularyParser.parse(tokens),
|
|
56
|
-
expressionNodes = expressionNodesQuery(node);
|
|
21
|
+
const expressionNodes = expressionNodesQuery(node);
|
|
57
22
|
|
|
58
23
|
expressionNodes.forEach((expressionNode) => {
|
|
59
24
|
const content = contentFromExpressionNode(expressionNode),
|
package/lib/utilities/bnf.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "validateBNF", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return validateBNF;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
var _necessary = require("necessary");
|
|
12
|
-
var _typesMap = /*#__PURE__*/ _interop_require_default(require("../typesMap"));
|
|
13
|
-
var _query = require("../utilities/query");
|
|
14
|
-
var _nominal = require("../utilities/nominal");
|
|
15
|
-
var _constants = require("../constants");
|
|
16
|
-
var _grammar = require("../utilities/grammar");
|
|
17
|
-
function _interop_require_default(obj) {
|
|
18
|
-
return obj && obj.__esModule ? obj : {
|
|
19
|
-
default: obj
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
var first = _necessary.arrayUtilities.first, second = _necessary.arrayUtilities.second;
|
|
23
|
-
var stringLiteralTerminalNodesQuery = (0, _query.nodesQuery)("//stringLiteral/@*!"), significantTokenTypeTerminalNodesQuery = (0, _query.nodesQuery)("//significantTokenType/@*!");
|
|
24
|
-
function validateBNF(bnf, ruleName) {
|
|
25
|
-
if (bnf === null || bnf === _constants.EMPTY_STRING) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
var content = bnf, tokens = _grammar.customGrammarBNFLexer.tokenise(content), node = _grammar.customGrammarBNFParser.parse(tokens);
|
|
29
|
-
var types = _typesMap.default[ruleName], significantTokenTypeTerminalNodes = significantTokenTypeTerminalNodesQuery(node);
|
|
30
|
-
significantTokenTypeTerminalNodes.forEach(function(significantTokenTypeTerminalNode) {
|
|
31
|
-
var type = typeFromSignificantTokenTypeTerminalNode(significantTokenTypeTerminalNode), typesIncludeType = types.includes(type);
|
|
32
|
-
if (!typesIncludeType) {
|
|
33
|
-
throw new Error("The '".concat(type, "' type is not included in the '").concat(ruleName, "' rule's types."));
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
var stringLiteralTerminalNodes = stringLiteralTerminalNodesQuery(node);
|
|
37
|
-
stringLiteralTerminalNodes.forEach(function(stringLiteralTerminalNode) {
|
|
38
|
-
var content = contentFromStringLiteralTerminalNode(stringLiteralTerminalNode);
|
|
39
|
-
if (content === _constants.UNDERSCORE_CHARACTER) {
|
|
40
|
-
throw new Error('The "'.concat(content, '" string literal cannot be an underscore.'));
|
|
41
|
-
}
|
|
42
|
-
var tokens = _nominal.nominalLexer.tokenise(content), tokensLength = tokens.length;
|
|
43
|
-
if (tokensLength !== 1) {
|
|
44
|
-
throw new Error('Tokenising the "'.concat(content, '" string literal does not result in a single token.'));
|
|
45
|
-
}
|
|
46
|
-
var firstToken = first(tokens), token = firstToken, type = token.getType(), typesIncludeType = types.includes(type);
|
|
47
|
-
if (!typesIncludeType) {
|
|
48
|
-
throw new Error('The "'.concat(content, "\" string literal's token's '").concat(type, "' type is not included in the '").concat(ruleName, "' rule's types."));
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
function contentFromStringLiteralTerminalNode(stringLiteralTerminalNode) {
|
|
53
|
-
var content;
|
|
54
|
-
content = stringLiteralTerminalNode.getContent();
|
|
55
|
-
var matches = content.match(/"([^"]+)"/), secondMatch = second(matches);
|
|
56
|
-
content = secondMatch; ///
|
|
57
|
-
return content;
|
|
58
|
-
}
|
|
59
|
-
function typeFromSignificantTokenTypeTerminalNode(significantTokenTypeTerminalNode) {
|
|
60
|
-
var type;
|
|
61
|
-
var content = significantTokenTypeTerminalNode.getContent(), matches = content.match(/\[([^\]]+)\]/), secondMatch = second(matches);
|
|
62
|
-
type = secondMatch; ///
|
|
63
|
-
return type;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsaXRpZXMvYm5mLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBhcnJheVV0aWxpdGllcyB9IGZyb20gXCJuZWNlc3NhcnlcIjtcblxuaW1wb3J0IHR5cGVzTWFwIGZyb20gXCIuLi90eXBlc01hcFwiO1xuXG5pbXBvcnQgeyBub2Rlc1F1ZXJ5IH0gZnJvbSBcIi4uL3V0aWxpdGllcy9xdWVyeVwiO1xuaW1wb3J0IHsgbm9taW5hbExleGVyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9ub21pbmFsXCI7XG5pbXBvcnQgeyBFTVBUWV9TVFJJTkcsIFVOREVSU0NPUkVfQ0hBUkFDVEVSIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgY3VzdG9tR3JhbW1hckJORkxleGVyLCBjdXN0b21HcmFtbWFyQk5GUGFyc2VyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9ncmFtbWFyXCI7XG5cbmNvbnN0IHsgZmlyc3QsIHNlY29uZCB9ID0gYXJyYXlVdGlsaXRpZXM7XG5cbmNvbnN0IHN0cmluZ0xpdGVyYWxUZXJtaW5hbE5vZGVzUXVlcnkgPSBub2Rlc1F1ZXJ5KFwiLy9zdHJpbmdMaXRlcmFsL0AqIVwiKSxcbiAgICAgIHNpZ25pZmljYW50VG9rZW5UeXBlVGVybWluYWxOb2Rlc1F1ZXJ5ID0gbm9kZXNRdWVyeShcIi8vc2lnbmlmaWNhbnRUb2tlblR5cGUvQCohXCIpO1xuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVCTkYoYm5mLCBydWxlTmFtZSkge1xuICBpZiAoKGJuZiA9PT0gbnVsbCkgfHwgKGJuZiA9PT0gRU1QVFlfU1RSSU5HKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnQgPSBibmYsXG4gICAgICAgIHRva2VucyA9IGN1c3RvbUdyYW1tYXJCTkZMZXhlci50b2tlbmlzZShjb250ZW50KSxcbiAgICAgICAgbm9kZSA9IGN1c3RvbUdyYW1tYXJCTkZQYXJzZXIucGFyc2UodG9rZW5zKTtcblxuICBjb25zdCB0eXBlcyA9IHR5cGVzTWFwW3J1bGVOYW1lXSxcbiAgICAgICAgc2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGVzID0gc2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGVzUXVlcnkobm9kZSk7XG5cbiAgc2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGVzLmZvckVhY2goKHNpZ25pZmljYW50VG9rZW5UeXBlVGVybWluYWxOb2RlKSA9PiB7XG4gICAgY29uc3QgdHlwZSA9IHR5cGVGcm9tU2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGUoc2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGUpLFxuICAgICAgICAgIHR5cGVzSW5jbHVkZVR5cGUgPSB0eXBlcy5pbmNsdWRlcyh0eXBlKTtcblxuICAgIGlmICghdHlwZXNJbmNsdWRlVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgJyR7dHlwZX0nIHR5cGUgaXMgbm90IGluY2x1ZGVkIGluIHRoZSAnJHtydWxlTmFtZX0nIHJ1bGUncyB0eXBlcy5gKVxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3Qgc3RyaW5nTGl0ZXJhbFRlcm1pbmFsTm9kZXMgPSBzdHJpbmdMaXRlcmFsVGVybWluYWxOb2Rlc1F1ZXJ5KG5vZGUpO1xuXG4gIHN0cmluZ0xpdGVyYWxUZXJtaW5hbE5vZGVzLmZvckVhY2goKHN0cmluZ0xpdGVyYWxUZXJtaW5hbE5vZGUpID0+IHtcbiAgICBjb25zdCBjb250ZW50ID0gY29udGVudEZyb21TdHJpbmdMaXRlcmFsVGVybWluYWxOb2RlKHN0cmluZ0xpdGVyYWxUZXJtaW5hbE5vZGUpO1xuXG4gICAgaWYgKGNvbnRlbnQgPT09IFVOREVSU0NPUkVfQ0hBUkFDVEVSKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBcIiR7Y29udGVudH1cIiBzdHJpbmcgbGl0ZXJhbCBjYW5ub3QgYmUgYW4gdW5kZXJzY29yZS5gKTtcbiAgICB9XG5cbiAgICBjb25zdCB0b2tlbnMgPSBub21pbmFsTGV4ZXIudG9rZW5pc2UoY29udGVudCksXG4gICAgICAgICAgdG9rZW5zTGVuZ3RoID0gdG9rZW5zLmxlbmd0aDtcblxuICAgIGlmICh0b2tlbnNMZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW5pc2luZyB0aGUgXCIke2NvbnRlbnR9XCIgc3RyaW5nIGxpdGVyYWwgZG9lcyBub3QgcmVzdWx0IGluIGEgc2luZ2xlIHRva2VuLmApO1xuICAgIH1cblxuICAgIGNvbnN0IGZpcnN0VG9rZW4gPSBmaXJzdCh0b2tlbnMpLFxuICAgICAgICAgIHRva2VuID0gZmlyc3RUb2tlbiwgLy8vXG4gICAgICAgICAgdHlwZSA9IHRva2VuLmdldFR5cGUoKSxcbiAgICAgICAgICB0eXBlc0luY2x1ZGVUeXBlID0gdHlwZXMuaW5jbHVkZXModHlwZSk7XG5cbiAgICBpZiAoIXR5cGVzSW5jbHVkZVR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIFwiJHtjb250ZW50fVwiIHN0cmluZyBsaXRlcmFsJ3MgdG9rZW4ncyAnJHt0eXBlfScgdHlwZSBpcyBub3QgaW5jbHVkZWQgaW4gdGhlICcke3J1bGVOYW1lfScgcnVsZSdzIHR5cGVzLmApXG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gY29udGVudEZyb21TdHJpbmdMaXRlcmFsVGVybWluYWxOb2RlKHN0cmluZ0xpdGVyYWxUZXJtaW5hbE5vZGUpIHtcbiAgbGV0IGNvbnRlbnQ7XG5cbiAgY29udGVudCA9IHN0cmluZ0xpdGVyYWxUZXJtaW5hbE5vZGUuZ2V0Q29udGVudCgpO1xuXG4gIGNvbnN0IG1hdGNoZXMgPSBjb250ZW50Lm1hdGNoKC9cIihbXlwiXSspXCIvKSxcbiAgICAgICAgc2Vjb25kTWF0Y2ggPSBzZWNvbmQobWF0Y2hlcyk7XG5cbiAgY29udGVudCA9IHNlY29uZE1hdGNoOyAvLy9cblxuICByZXR1cm4gY29udGVudDtcbn1cblxuZnVuY3Rpb24gdHlwZUZyb21TaWduaWZpY2FudFRva2VuVHlwZVRlcm1pbmFsTm9kZShzaWduaWZpY2FudFRva2VuVHlwZVRlcm1pbmFsTm9kZSkge1xuICBsZXQgdHlwZTtcblxuICBjb25zdCBjb250ZW50ID0gc2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGUuZ2V0Q29udGVudCgpLFxuICAgICAgICBtYXRjaGVzID0gY29udGVudC5tYXRjaCgvXFxbKFteXFxdXSspXFxdLyksXG4gICAgICAgIHNlY29uZE1hdGNoID0gc2Vjb25kKG1hdGNoZXMpO1xuXG4gIHR5cGUgPSBzZWNvbmRNYXRjaDsgLy8vXG5cbiAgcmV0dXJuIHR5cGU7XG59XG4iXSwibmFtZXMiOlsidmFsaWRhdGVCTkYiLCJmaXJzdCIsImFycmF5VXRpbGl0aWVzIiwic2Vjb25kIiwic3RyaW5nTGl0ZXJhbFRlcm1pbmFsTm9kZXNRdWVyeSIsIm5vZGVzUXVlcnkiLCJzaWduaWZpY2FudFRva2VuVHlwZVRlcm1pbmFsTm9kZXNRdWVyeSIsImJuZiIsInJ1bGVOYW1lIiwiRU1QVFlfU1RSSU5HIiwiY29udGVudCIsInRva2VucyIsImN1c3RvbUdyYW1tYXJCTkZMZXhlciIsInRva2VuaXNlIiwibm9kZSIsImN1c3RvbUdyYW1tYXJCTkZQYXJzZXIiLCJwYXJzZSIsInR5cGVzIiwidHlwZXNNYXAiLCJzaWduaWZpY2FudFRva2VuVHlwZVRlcm1pbmFsTm9kZXMiLCJmb3JFYWNoIiwic2lnbmlmaWNhbnRUb2tlblR5cGVUZXJtaW5hbE5vZGUiLCJ0eXBlIiwidHlwZUZyb21TaWduaWZpY2FudFRva2VuVHlwZVRlcm1pbmFsTm9kZSIsInR5cGVzSW5jbHVkZVR5cGUiLCJpbmNsdWRlcyIsIkVycm9yIiwic3RyaW5nTGl0ZXJhbFRlcm1pbmFsTm9kZXMiLCJzdHJpbmdMaXRlcmFsVGVybWluYWxOb2RlIiwiY29udGVudEZyb21TdHJpbmdMaXRlcmFsVGVybWluYWxOb2RlIiwiVU5ERVJTQ09SRV9DSEFSQUNURVIiLCJub21pbmFsTGV4ZXIiLCJ0b2tlbnNMZW5ndGgiLCJsZW5ndGgiLCJmaXJzdFRva2VuIiwidG9rZW4iLCJnZXRUeXBlIiwiZ2V0Q29udGVudCIsIm1hdGNoZXMiLCJtYXRjaCIsInNlY29uZE1hdGNoIl0sIm1hcHBpbmdzIjoiQUFBQTs7OzsrQkFnQmdCQTs7O2VBQUFBOzs7eUJBZGU7K0RBRVY7cUJBRU07dUJBQ0U7eUJBQ3NCO3VCQUNXOzs7Ozs7QUFFOUQsSUFBUUMsUUFBa0JDLHlCQUFjLENBQWhDRCxPQUFPRSxTQUFXRCx5QkFBYyxDQUF6QkM7QUFFZixJQUFNQyxrQ0FBa0NDLElBQUFBLGlCQUFVLEVBQUMsd0JBQzdDQyx5Q0FBeUNELElBQUFBLGlCQUFVLEVBQUM7QUFFbkQsU0FBU0wsWUFBWU8sR0FBRyxFQUFFQyxRQUFRO0lBQ3ZDLElBQUksQUFBQ0QsUUFBUSxRQUFVQSxRQUFRRSx1QkFBWSxFQUFHO1FBQzVDO0lBQ0Y7SUFFQSxJQUFNQyxVQUFVSCxLQUNWSSxTQUFTQyw4QkFBcUIsQ0FBQ0MsUUFBUSxDQUFDSCxVQUN4Q0ksT0FBT0MsK0JBQXNCLENBQUNDLEtBQUssQ0FBQ0w7SUFFMUMsSUFBTU0sUUFBUUMsaUJBQVEsQ0FBQ1YsU0FBUyxFQUMxQlcsb0NBQW9DYix1Q0FBdUNRO0lBRWpGSyxrQ0FBa0NDLE9BQU8sQ0FBQyxTQUFDQztRQUN6QyxJQUFNQyxPQUFPQyx5Q0FBeUNGLG1DQUNoREcsbUJBQW1CUCxNQUFNUSxRQUFRLENBQUNIO1FBRXhDLElBQUksQ0FBQ0Usa0JBQWtCO1lBQ3JCLE1BQU0sSUFBSUUsTUFBTSxBQUFDLFFBQTZDbEIsT0FBdENjLE1BQUssbUNBQTBDLE9BQVRkLFVBQVM7UUFDekU7SUFDRjtJQUVBLElBQU1tQiw2QkFBNkJ2QixnQ0FBZ0NVO0lBRW5FYSwyQkFBMkJQLE9BQU8sQ0FBQyxTQUFDUTtRQUNsQyxJQUFNbEIsVUFBVW1CLHFDQUFxQ0Q7UUFFckQsSUFBSWxCLFlBQVlvQiwrQkFBb0IsRUFBRTtZQUNwQyxNQUFNLElBQUlKLE1BQU0sQUFBQyxRQUFlLE9BQVJoQixTQUFRO1FBQ2xDO1FBRUEsSUFBTUMsU0FBU29CLHFCQUFZLENBQUNsQixRQUFRLENBQUNILFVBQy9Cc0IsZUFBZXJCLE9BQU9zQixNQUFNO1FBRWxDLElBQUlELGlCQUFpQixHQUFHO1lBQ3RCLE1BQU0sSUFBSU4sTUFBTSxBQUFDLG1CQUEwQixPQUFSaEIsU0FBUTtRQUM3QztRQUVBLElBQU13QixhQUFhakMsTUFBTVUsU0FDbkJ3QixRQUFRRCxZQUNSWixPQUFPYSxNQUFNQyxPQUFPLElBQ3BCWixtQkFBbUJQLE1BQU1RLFFBQVEsQ0FBQ0g7UUFFeEMsSUFBSSxDQUFDRSxrQkFBa0I7WUFDckIsTUFBTSxJQUFJRSxNQUFNLEFBQUMsUUFBNkNKLE9BQXRDWixTQUFRLGlDQUFvRUYsT0FBdENjLE1BQUssbUNBQTBDLE9BQVRkLFVBQVM7UUFDL0c7SUFDRjtBQUNGO0FBRUEsU0FBU3FCLHFDQUFxQ0QseUJBQXlCO0lBQ3JFLElBQUlsQjtJQUVKQSxVQUFVa0IsMEJBQTBCUyxVQUFVO0lBRTlDLElBQU1DLFVBQVU1QixRQUFRNkIsS0FBSyxDQUFDLGNBQ3hCQyxjQUFjckMsT0FBT21DO0lBRTNCNUIsVUFBVThCLGFBQWEsR0FBRztJQUUxQixPQUFPOUI7QUFDVDtBQUVBLFNBQVNhLHlDQUF5Q0YsZ0NBQWdDO0lBQ2hGLElBQUlDO0lBRUosSUFBTVosVUFBVVcsaUNBQWlDZ0IsVUFBVSxJQUNyREMsVUFBVTVCLFFBQVE2QixLQUFLLENBQUMsaUJBQ3hCQyxjQUFjckMsT0FBT21DO0lBRTNCaEIsT0FBT2tCLGFBQWEsR0FBRztJQUV2QixPQUFPbEI7QUFDVCJ9
|