occam-custom-grammars 5.0.1229 → 5.0.1231

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,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 { validateBNF } from "../utilities/bnf";
10
- import { EMPTY_STRING, VERTICAL_BAR } from "../constants";
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 { rulesFromBNF } = parserUtilities,
16
- { unshift, backwardsForEach } = arrayUtilities;
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(EMPTY_STRING),
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. ::= "(" argument ")"
7
+ export const termBNF = `term ::= "(" argument ")"
8
8
 
9
9
  | variable
10
10
 
11
11
  ;`;
12
12
 
13
- export const statementBNF = `statement. ::= "(" metaArgument ")"
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 = "",
@@ -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
- console.log(error);
83
-
84
- this.clearParseTree();
85
-
86
- this.clearNominalBNF();
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 { EMPTY_STRING, UNDERSCORE_CHARACTER } from "../constants";
10
- import { customGrammarBNFLexer, customGrammarBNFParser } from "../utilities/grammar";
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 stringLiteralTerminalNodesQuery = nodesQuery("//stringLiteral/@*!"),
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 { first, second } = arrayUtilities;
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
- const expressionNodes = expressionNodesQuery(node);
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 content = vocabulary, ///
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),
@@ -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