@testgorilla/tgo-typing-test 0.0.1 → 1.0.0

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.
Files changed (134) hide show
  1. package/esm2022/index.mjs +3 -0
  2. package/esm2022/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.mjs +45 -0
  3. package/esm2022/lib/components/tgo-typing-test/tgo-typing-test.component.mjs +299 -0
  4. package/esm2022/lib/helpers/config.mjs +24 -0
  5. package/esm2022/lib/helpers/constants/default-config.mjs +103 -0
  6. package/esm2022/lib/helpers/controllers/input-controller.mjs +586 -0
  7. package/esm2022/lib/helpers/controllers/quotes-controller.mjs +118 -0
  8. package/esm2022/lib/helpers/observables/config-event.mjs +16 -0
  9. package/esm2022/lib/helpers/observables/timer-event.mjs +16 -0
  10. package/esm2022/lib/helpers/states/active-page.mjs +8 -0
  11. package/esm2022/lib/helpers/states/composition.mjs +20 -0
  12. package/esm2022/lib/helpers/states/page-transition.mjs +8 -0
  13. package/esm2022/lib/helpers/states/slow-timer.mjs +15 -0
  14. package/esm2022/lib/helpers/states/test-active.mjs +8 -0
  15. package/esm2022/lib/helpers/states/time.mjs +11 -0
  16. package/esm2022/lib/helpers/test/caps-warning.mjs +50 -0
  17. package/esm2022/lib/helpers/test/caret.mjs +80 -0
  18. package/esm2022/lib/helpers/test/custom-text.mjs +59 -0
  19. package/esm2022/lib/helpers/test/english-punctuation.mjs +29 -0
  20. package/esm2022/lib/helpers/test/focus.mjs +35 -0
  21. package/esm2022/lib/helpers/test/manual-restart-tracker.mjs +11 -0
  22. package/esm2022/lib/helpers/test/out-of-focus.mjs +14 -0
  23. package/esm2022/lib/helpers/test/replay.mjs +217 -0
  24. package/esm2022/lib/helpers/test/test-input.mjs +264 -0
  25. package/esm2022/lib/helpers/test/test-logic.mjs +927 -0
  26. package/esm2022/lib/helpers/test/test-state.mjs +13 -0
  27. package/esm2022/lib/helpers/test/test-stats.mjs +342 -0
  28. package/esm2022/lib/helpers/test/test-timer.mjs +207 -0
  29. package/esm2022/lib/helpers/test/test-ui.mjs +341 -0
  30. package/esm2022/lib/helpers/test/test-words.mjs +69 -0
  31. package/esm2022/lib/helpers/test/timer-progress.mjs +15 -0
  32. package/esm2022/lib/helpers/test/weak-spot.mjs +65 -0
  33. package/esm2022/lib/helpers/test/wordset.mjs +100 -0
  34. package/esm2022/lib/utils/misc.mjs +673 -0
  35. package/esm2022/testgorilla-tgo-typing-test.mjs +5 -0
  36. package/fesm2022/testgorilla-tgo-typing-test.mjs +4707 -0
  37. package/fesm2022/testgorilla-tgo-typing-test.mjs.map +1 -0
  38. package/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.d.ts +14 -0
  39. package/lib/components/tgo-typing-test/tgo-typing-test.component.d.ts +54 -0
  40. package/lib/helpers/config.d.ts +98 -0
  41. package/lib/helpers/constants/default-config.d.ts +3 -0
  42. package/lib/helpers/controllers/input-controller.d.ts +16 -0
  43. package/lib/helpers/controllers/quotes-controller.d.ts +20 -0
  44. package/lib/helpers/observables/config-event.d.ts +5 -0
  45. package/lib/helpers/observables/timer-event.d.ts +4 -0
  46. package/lib/helpers/states/active-page.d.ts +2 -0
  47. package/lib/helpers/states/composition.d.ts +10 -0
  48. package/lib/helpers/states/page-transition.d.ts +2 -0
  49. package/lib/helpers/states/slow-timer.d.ts +3 -0
  50. package/lib/helpers/states/test-active.d.ts +2 -0
  51. package/lib/helpers/states/time.d.ts +3 -0
  52. package/lib/helpers/test/caps-warning.d.ts +5 -0
  53. package/lib/helpers/test/caret.d.ts +11 -0
  54. package/lib/helpers/test/custom-text.d.ts +16 -0
  55. package/lib/helpers/test/english-punctuation.d.ts +3 -0
  56. package/lib/helpers/test/focus.d.ts +7 -0
  57. package/lib/helpers/test/manual-restart-tracker.d.ts +3 -0
  58. package/lib/helpers/test/out-of-focus.d.ts +4 -0
  59. package/lib/helpers/test/replay.d.ts +20 -0
  60. package/lib/helpers/test/test-input.d.ts +86 -0
  61. package/lib/helpers/test/test-logic.d.ts +25 -0
  62. package/lib/helpers/test/test-state.d.ts +7 -0
  63. package/lib/helpers/test/test-stats.d.ts +92 -0
  64. package/lib/helpers/test/test-timer.d.ts +6 -0
  65. package/lib/helpers/test/test-ui.d.ts +27 -0
  66. package/lib/helpers/test/test-words.d.ts +23 -0
  67. package/lib/helpers/test/timer-progress.d.ts +3 -0
  68. package/lib/helpers/test/weak-spot.d.ts +3 -0
  69. package/lib/helpers/test/wordset.d.ts +7 -0
  70. package/lib/utils/misc.d.ts +81 -0
  71. package/package.json +18 -7
  72. package/.eslintrc.json +0 -45
  73. package/jest.config.ts +0 -21
  74. package/ng-package.json +0 -15
  75. package/project.json +0 -36
  76. package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.html +0 -30
  77. package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.spec.ts +0 -250
  78. package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.ts +0 -48
  79. package/src/lib/components/tgo-typing-test/tgo-typing-test.component.html +0 -72
  80. package/src/lib/components/tgo-typing-test/tgo-typing-test.component.spec.ts +0 -699
  81. package/src/lib/components/tgo-typing-test/tgo-typing-test.component.ts +0 -294
  82. package/src/lib/helpers/config.ts +0 -28
  83. package/src/lib/helpers/constants/default-config.ts +0 -103
  84. package/src/lib/helpers/controllers/input-controller.ts +0 -710
  85. package/src/lib/helpers/controllers/quotes-controller.ts +0 -183
  86. package/src/lib/helpers/observables/banner-event.ts +0 -18
  87. package/src/lib/helpers/observables/config-event.ts +0 -31
  88. package/src/lib/helpers/observables/timer-event.ts +0 -18
  89. package/src/lib/helpers/states/active-page.ts +0 -9
  90. package/src/lib/helpers/states/composition.ts +0 -29
  91. package/src/lib/helpers/states/page-transition.ts +0 -9
  92. package/src/lib/helpers/states/slow-timer.ts +0 -16
  93. package/src/lib/helpers/states/test-active.ts +0 -9
  94. package/src/lib/helpers/states/time.ts +0 -13
  95. package/src/lib/helpers/test/caps-warning.ts +0 -50
  96. package/src/lib/helpers/test/caret.ts +0 -92
  97. package/src/lib/helpers/test/custom-text.ts +0 -73
  98. package/src/lib/helpers/test/english-punctuation.ts +0 -38
  99. package/src/lib/helpers/test/focus.ts +0 -39
  100. package/src/lib/helpers/test/manual-restart-tracker.ts +0 -13
  101. package/src/lib/helpers/test/out-of-focus.ts +0 -19
  102. package/src/lib/helpers/test/replay.ts +0 -265
  103. package/src/lib/helpers/test/test-input.ts +0 -320
  104. package/src/lib/helpers/test/test-logic.ts +0 -1039
  105. package/src/lib/helpers/test/test-state.ts +0 -17
  106. package/src/lib/helpers/test/test-stats.ts +0 -442
  107. package/src/lib/helpers/test/test-timer.ts +0 -209
  108. package/src/lib/helpers/test/test-ui.ts +0 -370
  109. package/src/lib/helpers/test/test-words.ts +0 -72
  110. package/src/lib/helpers/test/timer-progress.ts +0 -16
  111. package/src/lib/helpers/test/tts.ts +0 -42
  112. package/src/lib/helpers/test/weak-spot.ts +0 -74
  113. package/src/lib/helpers/test/wordset.ts +0 -109
  114. package/src/lib/styles/animations.scss +0 -101
  115. package/src/lib/styles/caret.scss +0 -108
  116. package/src/lib/styles/core.scss +0 -498
  117. package/src/lib/styles/index.scss +0 -19
  118. package/src/lib/styles/inputs.scss +0 -290
  119. package/src/lib/styles/popups.scss +0 -1311
  120. package/src/lib/styles/test.scss +0 -1008
  121. package/src/lib/styles/z_media-queries.scss +0 -848
  122. package/src/lib/types/types.d.ts +0 -731
  123. package/src/lib/utils/misc.ts +0 -776
  124. package/src/test-setup.ts +0 -1
  125. package/tsconfig.json +0 -16
  126. package/tsconfig.lib.json +0 -14
  127. package/tsconfig.lib.prod.json +0 -9
  128. package/tsconfig.spec.json +0 -11
  129. /package/{src/assets → assets}/typing-test-languages/english.json +0 -0
  130. /package/{src/assets → assets}/typing-test-languages/english_punctuation.json +0 -0
  131. /package/{src/assets → assets}/typing-test-languages/quotes/english_version_1.json +0 -0
  132. /package/{src/assets → assets}/typing-test-languages/quotes/english_version_2.json +0 -0
  133. /package/{src/assets → assets}/typing-test-languages/quotes/filtered_sources.json +0 -0
  134. /package/{src/index.ts → index.d.ts} +0 -0
@@ -0,0 +1,100 @@
1
+ import { randomElementFromArray, randomIntFromRange } from '../../utils/misc';
2
+ let currentWordset = null;
3
+ let currentWordGenerator = null;
4
+ export class Wordset {
5
+ words;
6
+ length;
7
+ constructor(words) {
8
+ this.words = words;
9
+ this.length = this.words.length;
10
+ }
11
+ randomWord() {
12
+ return randomElementFromArray(this.words);
13
+ }
14
+ }
15
+ const prefixSize = 2;
16
+ class CharDistribution {
17
+ chars;
18
+ count;
19
+ constructor() {
20
+ this.chars = {};
21
+ this.count = 0;
22
+ }
23
+ addChar(char) {
24
+ this.count++;
25
+ if (char in this.chars) {
26
+ this.chars[char]++;
27
+ }
28
+ else {
29
+ this.chars[char] = 1;
30
+ }
31
+ }
32
+ randomChar() {
33
+ const randomIndex = randomIntFromRange(0, this.count - 1);
34
+ let runningCount = 0;
35
+ for (const [char, charCount] of Object.entries(this.chars)) {
36
+ runningCount += charCount;
37
+ if (runningCount > randomIndex) {
38
+ return char;
39
+ }
40
+ }
41
+ return Object.keys(this.chars)[0];
42
+ }
43
+ }
44
+ class WordGenerator extends Wordset {
45
+ ngrams = {};
46
+ constructor(words) {
47
+ super(words);
48
+ // Can generate an unbounded number of words in theory.
49
+ this.length = Infinity;
50
+ for (let word of words) {
51
+ // Mark the end of each word with a space.
52
+ word += " ";
53
+ let prefix = "";
54
+ for (const c of word) {
55
+ // Add `c` to the distribution of chars that can come after `prefix`.
56
+ if (!(prefix in this.ngrams)) {
57
+ this.ngrams[prefix] = new CharDistribution();
58
+ }
59
+ this.ngrams[prefix].addChar(c);
60
+ prefix = (prefix + c).substr(-prefixSize);
61
+ }
62
+ }
63
+ }
64
+ randomWord() {
65
+ let word = "";
66
+ for (;;) {
67
+ const prefix = word.substr(-prefixSize);
68
+ const charDistribution = this.ngrams[prefix];
69
+ if (!charDistribution) {
70
+ // This shouldn't happen if this.ngrams is complete. If it does
71
+ // somehow, start generating a new word.
72
+ word = "";
73
+ continue;
74
+ }
75
+ // Pick a random char from the distribution that comes after `prefix`.
76
+ const nextChar = charDistribution.randomChar();
77
+ if (nextChar == " ") {
78
+ // A space marks the end of the word, so stop generating and return.
79
+ break;
80
+ }
81
+ word += nextChar;
82
+ }
83
+ return word;
84
+ }
85
+ }
86
+ export function withWords(words, funbox) {
87
+ if (funbox == "pseudolang") {
88
+ if (currentWordGenerator == null || words !== currentWordGenerator.words) {
89
+ currentWordGenerator = new WordGenerator(words);
90
+ }
91
+ return currentWordGenerator;
92
+ }
93
+ else {
94
+ if (currentWordset == null || words !== currentWordset.words) {
95
+ currentWordset = new Wordset(words);
96
+ }
97
+ return currentWordset;
98
+ }
99
+ }
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29yZHNldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3Rnby10eXBpbmctdGVzdC9zcmMvbGliL2hlbHBlcnMvdGVzdC93b3Jkc2V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlFLElBQUksY0FBYyxHQUFtQixJQUFJLENBQUM7QUFDMUMsSUFBSSxvQkFBb0IsR0FBeUIsSUFBSSxDQUFDO0FBRXRELE1BQU0sT0FBTyxPQUFPO0lBQ1gsS0FBSyxDQUFXO0lBQ2hCLE1BQU0sQ0FBUztJQUN0QixZQUFZLEtBQWU7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRU0sVUFBVTtRQUNmLE9BQU8sc0JBQXNCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVDLENBQUM7Q0FDRjtBQUVELE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQztBQUVyQixNQUFNLGdCQUFnQjtJQUNiLEtBQUssQ0FBNkI7SUFDbEMsS0FBSyxDQUFTO0lBQ3JCO1FBQ0UsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDakIsQ0FBQztJQUVNLE9BQU8sQ0FBQyxJQUFZO1FBQ3pCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDckIsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFH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QUFJLGNBQWMsSUFBSSxJQUFJLElBQUksS0FBSyxLQUFLLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM3RCxjQUFjLEdBQUcsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUNELE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmFuZG9tRWxlbWVudEZyb21BcnJheSwgcmFuZG9tSW50RnJvbVJhbmdlIH0gZnJvbSAnLi4vLi4vdXRpbHMvbWlzYyc7XG5cbmxldCBjdXJyZW50V29yZHNldDogV29yZHNldCB8IG51bGwgPSBudWxsO1xubGV0IGN1cnJlbnRXb3JkR2VuZXJhdG9yOiBXb3JkR2VuZXJhdG9yIHwgbnVsbCA9IG51bGw7XG5cbmV4cG9ydCBjbGFzcyBXb3Jkc2V0IHtcbiAgcHVibGljIHdvcmRzOiBzdHJpbmdbXTtcbiAgcHVibGljIGxlbmd0aDogbnVtYmVyO1xuICBjb25zdHJ1Y3Rvcih3b3Jkczogc3RyaW5nW10pIHtcbiAgICB0aGlzLndvcmRzID0gd29yZHM7XG4gICAgdGhpcy5sZW5ndGggPSB0aGlzLndvcmRzLmxlbmd0aDtcbiAgfVxuXG4gIHB1YmxpYyByYW5kb21Xb3JkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJhbmRvbUVsZW1lbnRGcm9tQXJyYXkodGhpcy53b3Jkcyk7XG4gIH1cbn1cblxuY29uc3QgcHJlZml4U2l6ZSA9IDI7XG5cbmNsYXNzIENoYXJEaXN0cmlidXRpb24ge1xuICBwdWJsaWMgY2hhcnM6IHsgW2NoYXI6IHN0cmluZ106IG51bWJlciB9O1xuICBwdWJsaWMgY291bnQ6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jaGFycyA9IHt9O1xuICAgIHRoaXMuY291bnQgPSAwO1xuICB9XG5cbiAgcHVibGljIGFkZENoYXIoY2hhcjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jb3VudCsrO1xuICAgIGlmIChjaGFyIGluIHRoaXMuY2hhcnMpIHtcbiAgICAgIHRoaXMuY2hhcnNbY2hhcl0rKztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jaGFyc1tjaGFyXSA9IDE7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJhbmRvbUNoYXIoKTogc3RyaW5nIHtcbiAgICBjb25zdCByYW5kb21JbmRleCA9IHJhbmRvbUludEZyb21SYW5nZSgwLCB0aGlzLmNvdW50IC0gMSk7XG4gICAgbGV0IHJ1bm5pbmdDb3VudCA9IDA7XG4gICAgZm9yIChjb25zdCBbY2hhciwgY2hhckNvdW50XSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmNoYXJzKSkge1xuICAgICAgcnVubmluZ0NvdW50ICs9IGNoYXJDb3VudDtcbiAgICAgIGlmIChydW5uaW5nQ291bnQgPiByYW5kb21JbmRleCkge1xuICAgICAgICByZXR1cm4gY2hhcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5jaGFycylbMF07XG4gIH1cbn1cblxuY2xhc3MgV29yZEdlbmVyYXRvciBleHRlbmRzIFdvcmRzZXQge1xuICBwdWJsaWMgbmdyYW1zOiB7IFtwcmVmaXg6IHN0cmluZ106IENoYXJEaXN0cmlidXRpb24gfSA9IHt9O1xuICBjb25zdHJ1Y3Rvcih3b3Jkczogc3RyaW5nW10pIHtcbiAgICBzdXBlcih3b3Jkcyk7XG4gICAgLy8gQ2FuIGdlbmVyYXRlIGFuIHVuYm91bmRlZCBudW1iZXIgb2Ygd29yZHMgaW4gdGhlb3J5LlxuICAgIHRoaXMubGVuZ3RoID0gSW5maW5pdHk7XG5cbiAgICBmb3IgKGxldCB3b3JkIG9mIHdvcmRzKSB7XG4gICAgICAvLyBNYXJrIHRoZSBlbmQgb2YgZWFjaCB3b3JkIHdpdGggYSBzcGFjZS5cbiAgICAgIHdvcmQgKz0gXCIgXCI7XG4gICAgICBsZXQgcHJlZml4ID0gXCJcIjtcbiAgICAgIGZvciAoY29uc3QgYyBvZiB3b3JkKSB7XG4gICAgICAgIC8vIEFkZCBgY2AgdG8gdGhlIGRpc3RyaWJ1dGlvbiBvZiBjaGFycyB0aGF0IGNhbiBjb21lIGFmdGVyIGBwcmVmaXhgLlxuICAgICAgICBpZiAoIShwcmVmaXggaW4gdGhpcy5uZ3JhbXMpKSB7XG4gICAgICAgICAgdGhpcy5uZ3JhbXNbcHJlZml4XSA9IG5ldyBDaGFyRGlzdHJpYnV0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5uZ3JhbXNbcHJlZml4XS5hZGRDaGFyKGMpO1xuICAgICAgICBwcmVmaXggPSAocHJlZml4ICsgYykuc3Vic3RyKC1wcmVmaXhTaXplKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgcmFuZG9tV29yZCgpOiBzdHJpbmcge1xuICAgIGxldCB3b3JkID0gXCJcIjtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBjb25zdCBwcmVmaXggPSB3b3JkLnN1YnN0cigtcHJlZml4U2l6ZSk7XG4gICAgICBjb25zdCBjaGFyRGlzdHJpYnV0aW9uID0gdGhpcy5uZ3JhbXNbcHJlZml4XTtcbiAgICAgIGlmICghY2hhckRpc3RyaWJ1dGlvbikge1xuICAgICAgICAvLyBUaGlzIHNob3VsZG4ndCBoYXBwZW4gaWYgdGhpcy5uZ3JhbXMgaXMgY29tcGxldGUuIElmIGl0IGRvZXNcbiAgICAgICAgLy8gc29tZWhvdywgc3RhcnQgZ2VuZXJhdGluZyBhIG5ldyB3b3JkLlxuICAgICAgICB3b3JkID0gXCJcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBQaWNrIGEgcmFuZG9tIGNoYXIgZnJvbSB0aGUgZGlzdHJpYnV0aW9uIHRoYXQgY29tZXMgYWZ0ZXIgYHByZWZpeGAuXG4gICAgICBjb25zdCBuZXh0Q2hhciA9IGNoYXJEaXN0cmlidXRpb24ucmFuZG9tQ2hhcigpO1xuICAgICAgaWYgKG5leHRDaGFyID09IFwiIFwiKSB7XG4gICAgICAgIC8vIEEgc3BhY2UgbWFya3MgdGhlIGVuZCBvZiB0aGUgd29yZCwgc28gc3RvcCBnZW5lcmF0aW5nIGFuZCByZXR1cm4uXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgd29yZCArPSBuZXh0Q2hhcjtcbiAgICB9XG4gICAgcmV0dXJuIHdvcmQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdpdGhXb3Jkcyh3b3Jkczogc3RyaW5nW10sIGZ1bmJveDogc3RyaW5nKTogV29yZHNldCB7XG4gIGlmIChmdW5ib3ggPT0gXCJwc2V1ZG9sYW5nXCIpIHtcbiAgICBpZiAoY3VycmVudFdvcmRHZW5lcmF0b3IgPT0gbnVsbCB8fCB3b3JkcyAhPT0gY3VycmVudFdvcmRHZW5lcmF0b3Iud29yZHMpIHtcbiAgICAgIGN1cnJlbnRXb3JkR2VuZXJhdG9yID0gbmV3IFdvcmRHZW5lcmF0b3Iod29yZHMpO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFdvcmRHZW5lcmF0b3I7XG4gIH0gZWxzZSB7XG4gICAgaWYgKGN1cnJlbnRXb3Jkc2V0ID09IG51bGwgfHwgd29yZHMgIT09IGN1cnJlbnRXb3Jkc2V0LndvcmRzKSB7XG4gICAgICBjdXJyZW50V29yZHNldCA9IG5ldyBXb3Jkc2V0KHdvcmRzKTtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRXb3Jkc2V0O1xuICB9XG59XG4iXX0=