@pie-element/categorize 11.3.4-next.3 → 12.0.0-beta.1
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/CHANGELOG.md +0 -11
- package/configure/CHANGELOG.md +0 -11
- package/configure/lib/__tests__/main.test.js +100 -0
- package/configure/lib/__tests__/utils.js +39 -0
- package/configure/lib/defaults.js +3 -6
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/design/__tests__/builder.test.js +34 -0
- package/configure/lib/design/__tests__/buttons.test.js +36 -0
- package/configure/lib/design/__tests__/header.test.js +37 -0
- package/configure/lib/design/__tests__/index.test.js +125 -0
- package/configure/lib/design/__tests__/input-header.test.js +41 -0
- package/configure/lib/design/builder.js +16 -34
- package/configure/lib/design/builder.js.map +1 -1
- package/configure/lib/design/buttons.js +42 -96
- package/configure/lib/design/buttons.js.map +1 -1
- package/configure/lib/design/categories/RowLabel.js +34 -47
- package/configure/lib/design/categories/RowLabel.js.map +1 -1
- package/configure/lib/design/categories/__tests__/alternateResponses.test.js +93 -0
- package/configure/lib/design/categories/__tests__/category.test.js +65 -0
- package/configure/lib/design/categories/__tests__/choice-preview.test.js +52 -0
- package/configure/lib/design/categories/__tests__/droppable-placeholder.test.js +63 -0
- package/configure/lib/design/categories/__tests__/index.test.js +91 -0
- package/configure/lib/design/categories/alternateResponses.js +97 -252
- package/configure/lib/design/categories/alternateResponses.js.map +1 -1
- package/configure/lib/design/categories/category.js +136 -209
- package/configure/lib/design/categories/category.js.map +1 -1
- package/configure/lib/design/categories/choice-preview.js +62 -127
- package/configure/lib/design/categories/choice-preview.js.map +1 -1
- package/configure/lib/design/categories/droppable-placeholder.js +74 -166
- package/configure/lib/design/categories/droppable-placeholder.js.map +1 -1
- package/configure/lib/design/categories/index.js +196 -385
- package/configure/lib/design/categories/index.js.map +1 -1
- package/configure/lib/design/choices/__tests__/choice.test.js +62 -0
- package/configure/lib/design/choices/__tests__/config.test.js +66 -0
- package/configure/lib/design/choices/__tests__/index.test.js +70 -0
- package/configure/lib/design/choices/choice.js +156 -265
- package/configure/lib/design/choices/choice.js.map +1 -1
- package/configure/lib/design/choices/config.js +43 -99
- package/configure/lib/design/choices/config.js.map +1 -1
- package/configure/lib/design/choices/index.js +149 -237
- package/configure/lib/design/choices/index.js.map +1 -1
- package/configure/lib/design/header.js +58 -112
- package/configure/lib/design/header.js.map +1 -1
- package/configure/lib/design/index.js +633 -478
- package/configure/lib/design/index.js.map +1 -1
- package/configure/lib/design/input-header.js +95 -151
- package/configure/lib/design/input-header.js.map +1 -1
- package/configure/lib/design/utils.js +5 -16
- package/configure/lib/design/utils.js.map +1 -1
- package/configure/lib/index.js +121 -184
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +31 -75
- package/configure/lib/main.js.map +1 -1
- package/configure/lib/utils.js +23 -33
- package/configure/lib/utils.js.map +1 -1
- package/configure/package.json +15 -15
- package/controller/CHANGELOG.md +0 -11
- package/controller/lib/__tests__/index.test.js +526 -0
- package/controller/lib/defaults.js +3 -6
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +238 -319
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +29 -66
- package/controller/lib/utils.js.map +1 -1
- package/controller/package.json +5 -5
- package/docs/demo/.pie/.configure/package.json +10 -0
- package/docs/demo/.pie/.configure/yarn.lock +2181 -0
- package/docs/demo/.pie/.controllers/package.json +10 -0
- package/docs/demo/.pie/.controllers/yarn.lock +110 -0
- package/docs/demo/.pie/info.entry.js +89 -0
- package/docs/demo/.pie/info.webpack.config.js +119 -0
- package/docs/demo/.pie/package.json +10 -0
- package/docs/demo/.pie/yarn.lock +2190 -0
- package/docs/demo/pie.manifest.json +11 -0
- package/lib/__tests__/index.test.js +197 -0
- package/lib/categorize/__tests__/categories.test.js +138 -0
- package/lib/categorize/__tests__/category.test.js +137 -0
- package/lib/categorize/__tests__/choice.test.js +88 -0
- package/lib/categorize/__tests__/choices.test.js +118 -0
- package/lib/categorize/__tests__/droppable-placeholder.test.js +96 -0
- package/lib/categorize/__tests__/grid-content.test.js +48 -0
- package/lib/categorize/__tests__/index.test.js +152 -0
- package/lib/categorize/categories.js +107 -165
- package/lib/categorize/categories.js.map +1 -1
- package/lib/categorize/category.js +74 -124
- package/lib/categorize/category.js.map +1 -1
- package/lib/categorize/choice.js +119 -246
- package/lib/categorize/choice.js.map +1 -1
- package/lib/categorize/choices.js +67 -132
- package/lib/categorize/choices.js.map +1 -1
- package/lib/categorize/droppable-placeholder.js +47 -104
- package/lib/categorize/droppable-placeholder.js.map +1 -1
- package/lib/categorize/grid-content.js +40 -88
- package/lib/categorize/grid-content.js.map +1 -1
- package/lib/categorize/index.js +342 -318
- package/lib/categorize/index.js.map +1 -1
- package/lib/index.js +286 -307
- package/lib/index.js.map +1 -1
- package/package.json +16 -14
- package/esm/configure.js +0 -34401
- package/esm/configure.js.map +0 -1
- package/esm/controller.js +0 -1468
- package/esm/controller.js.map +0 -1
- package/esm/element.js +0 -13134
- package/esm/element.js.map +0 -1
- package/esm/package.json +0 -3
package/lib/index.js
CHANGED
|
@@ -1,337 +1,316 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
|
-
exports
|
|
9
|
-
|
|
10
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
|
-
|
|
12
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
13
|
-
|
|
14
|
-
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
15
|
-
|
|
16
|
-
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
17
|
-
|
|
18
|
-
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
19
|
-
|
|
20
|
-
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
|
|
21
|
-
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
22
9
|
var _react = _interopRequireDefault(require("react"));
|
|
23
|
-
|
|
24
|
-
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
25
|
-
|
|
10
|
+
var _client = require("react-dom/client");
|
|
26
11
|
var _mathRendering = require("@pie-lib/math-rendering");
|
|
27
|
-
|
|
28
12
|
var _renderUi = require("@pie-lib/render-ui");
|
|
29
|
-
|
|
30
13
|
var _piePlayerEvents = require("@pie-framework/pie-player-events");
|
|
31
|
-
|
|
32
14
|
var _categorize = _interopRequireDefault(require("./categorize"));
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function Categorize() {
|
|
44
|
-
(0, _classCallCheck2["default"])(this, Categorize);
|
|
45
|
-
return _super.apply(this, arguments);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
(0, _createClass2["default"])(Categorize, [{
|
|
49
|
-
key: "model",
|
|
50
|
-
set: function set(m) {
|
|
51
|
-
this._model = m;
|
|
52
|
-
this.eliminateBlindAnswersFromSession();
|
|
53
|
-
this.dispatchEvent(new _piePlayerEvents.ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model)); // reset the audioInitialized to false since the model changed, and we might need to reinitialize the audio
|
|
54
|
-
|
|
55
|
-
this._audioInitialized = false;
|
|
56
|
-
this.render();
|
|
57
|
-
}
|
|
58
|
-
}, {
|
|
59
|
-
key: "isComplete",
|
|
60
|
-
value: function isComplete() {
|
|
61
|
-
var _ref = this._model || {},
|
|
62
|
-
autoplayAudioEnabled = _ref.autoplayAudioEnabled,
|
|
63
|
-
choices = _ref.choices,
|
|
64
|
-
completeAudioEnabled = _ref.completeAudioEnabled,
|
|
65
|
-
hasUnplacedChoices = _ref.hasUnplacedChoices,
|
|
66
|
-
possibleResponses = _ref.possibleResponses,
|
|
67
|
-
responseAreasToBeFilled = _ref.responseAreasToBeFilled;
|
|
68
|
-
|
|
69
|
-
var elementContext = this; // check audio completion if audio settings are enabled and audio actually exists
|
|
70
|
-
|
|
71
|
-
if (autoplayAudioEnabled && completeAudioEnabled && !this.audioComplete) {
|
|
72
|
-
if (elementContext) {
|
|
73
|
-
var audio = elementContext.querySelector('audio');
|
|
74
|
-
var isInsidePrompt = audio && audio.closest('#preview-prompt'); // only require audio completion if audio exists and is inside the prompt
|
|
75
|
-
|
|
76
|
-
if (audio && isInsidePrompt) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
15
|
+
class Categorize extends HTMLElement {
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
(0, _defineProperty2.default)(this, "_scheduleMathRender", () => {
|
|
19
|
+
if (this._mathRenderPending) return;
|
|
20
|
+
this._mathRenderPending = true;
|
|
21
|
+
requestAnimationFrame(() => {
|
|
22
|
+
if (this._mathObserver && !this._mathObserverPaused) {
|
|
23
|
+
this._mathObserver.disconnect();
|
|
79
24
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
var filledResponseAreas = answers.filter(function (answer) {
|
|
94
|
-
return answer.choices.length;
|
|
95
|
-
}).length; // check if an answer choice was added to at least as many response areas
|
|
96
|
-
// as the number of populated response areas in the correct answer
|
|
97
|
-
|
|
98
|
-
var areResponseAreasFilled = filledResponseAreas >= responseAreasToBeFilled; // check if multiple placements are allowed
|
|
99
|
-
|
|
100
|
-
var duplicatesAllowed = (choices || []).some(function (choice) {
|
|
101
|
-
return choice.categoryCount === 0;
|
|
25
|
+
(0, _mathRendering.renderMath)(this);
|
|
26
|
+
this._mathRenderPending = false;
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
if (this._mathObserver && !this._mathObserverPaused) {
|
|
29
|
+
this._mathObserver.observe(this, {
|
|
30
|
+
childList: true,
|
|
31
|
+
subtree: true,
|
|
32
|
+
characterData: false
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}, 50);
|
|
102
36
|
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (hasUnplacedChoices) {
|
|
111
|
-
return areResponseAreasFilled;
|
|
37
|
+
});
|
|
38
|
+
(0, _defineProperty2.default)(this, "pauseMathObserver", () => {
|
|
39
|
+
if (this._mathObserver) {
|
|
40
|
+
this._mathObserver.disconnect();
|
|
41
|
+
this._mathObserverPaused = true;
|
|
112
42
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return requiredAnswersPlaced;
|
|
125
|
-
}
|
|
126
|
-
}, {
|
|
127
|
-
key: "session",
|
|
128
|
-
get: function get() {
|
|
129
|
-
return this._session;
|
|
130
|
-
},
|
|
131
|
-
set: function set(s) {
|
|
132
|
-
if (s && !s.answers) {
|
|
133
|
-
s.answers = [];
|
|
43
|
+
});
|
|
44
|
+
(0, _defineProperty2.default)(this, "resumeMathObserver", () => {
|
|
45
|
+
if (this._mathObserverPaused) {
|
|
46
|
+
this._mathObserverPaused = false;
|
|
47
|
+
if (this._mathObserver) {
|
|
48
|
+
this._mathObserver.observe(this, {
|
|
49
|
+
childList: true,
|
|
50
|
+
subtree: true,
|
|
51
|
+
characterData: false
|
|
52
|
+
});
|
|
53
|
+
}
|
|
134
54
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
55
|
+
});
|
|
56
|
+
this._root = null;
|
|
57
|
+
this._mathObserver = null;
|
|
58
|
+
this._mathRenderPending = false;
|
|
59
|
+
}
|
|
60
|
+
_initMathObserver() {
|
|
61
|
+
if (this._mathObserver) return;
|
|
62
|
+
this._mathObserver = new MutationObserver(() => {
|
|
63
|
+
this._scheduleMathRender();
|
|
64
|
+
});
|
|
65
|
+
this._mathObserver.observe(this, {
|
|
66
|
+
childList: true,
|
|
67
|
+
subtree: true,
|
|
68
|
+
characterData: false
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
_disconnectMathObserver() {
|
|
72
|
+
if (this._mathObserver) {
|
|
73
|
+
this._mathObserver.disconnect();
|
|
74
|
+
this._mathObserver = null;
|
|
138
75
|
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (
|
|
162
|
-
|
|
76
|
+
}
|
|
77
|
+
set model(m) {
|
|
78
|
+
this._model = m;
|
|
79
|
+
this.eliminateBlindAnswersFromSession();
|
|
80
|
+
this.dispatchEvent(new _piePlayerEvents.ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model));
|
|
81
|
+
// reset the audioInitialized to false since the model changed, and we might need to reinitialize the audio
|
|
82
|
+
this._audioInitialized = false;
|
|
83
|
+
this.render();
|
|
84
|
+
}
|
|
85
|
+
isComplete() {
|
|
86
|
+
const {
|
|
87
|
+
autoplayAudioEnabled,
|
|
88
|
+
choices,
|
|
89
|
+
completeAudioEnabled,
|
|
90
|
+
hasUnplacedChoices,
|
|
91
|
+
possibleResponses,
|
|
92
|
+
responseAreasToBeFilled
|
|
93
|
+
} = this._model || {};
|
|
94
|
+
const elementContext = this;
|
|
95
|
+
|
|
96
|
+
// check audio completion if audio settings are enabled and audio actually exists
|
|
97
|
+
if (autoplayAudioEnabled && completeAudioEnabled && !this.audioComplete) {
|
|
98
|
+
if (elementContext) {
|
|
99
|
+
const audio = elementContext.querySelector('audio');
|
|
100
|
+
const isInsidePrompt = audio && audio.closest('#preview-prompt');
|
|
101
|
+
|
|
102
|
+
// only require audio completion if audio exists and is inside the prompt
|
|
103
|
+
if (audio && isInsidePrompt) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
163
106
|
}
|
|
164
107
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
value: function changeAnswers(answers) {
|
|
168
|
-
this._session.answers = answers;
|
|
169
|
-
this._session.selector = 'Mouse';
|
|
170
|
-
this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));
|
|
171
|
-
this.render();
|
|
108
|
+
if (!this._session || !this._session.answers) {
|
|
109
|
+
return false;
|
|
172
110
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
111
|
+
const {
|
|
112
|
+
answers
|
|
113
|
+
} = this._session;
|
|
114
|
+
if (!Array.isArray(answers)) {
|
|
115
|
+
return false;
|
|
177
116
|
}
|
|
178
|
-
}, {
|
|
179
|
-
key: "_createAudioInfoToast",
|
|
180
|
-
value: function _createAudioInfoToast() {
|
|
181
|
-
var info = document.createElement('div');
|
|
182
|
-
info.id = 'play-audio-info';
|
|
183
|
-
Object.assign(info.style, {
|
|
184
|
-
position: 'absolute',
|
|
185
|
-
top: 0,
|
|
186
|
-
width: '100%',
|
|
187
|
-
height: '100%',
|
|
188
|
-
display: 'flex',
|
|
189
|
-
justifyContent: 'center',
|
|
190
|
-
alignItems: 'center',
|
|
191
|
-
background: 'white',
|
|
192
|
-
zIndex: '1000',
|
|
193
|
-
cursor: 'pointer'
|
|
194
|
-
});
|
|
195
|
-
var img = document.createElement('img');
|
|
196
|
-
img.src = _renderUi.EnableAudioAutoplayImage;
|
|
197
|
-
img.alt = 'Click anywhere to enable audio autoplay';
|
|
198
|
-
img.width = 500;
|
|
199
|
-
img.height = 300;
|
|
200
|
-
info.appendChild(img);
|
|
201
|
-
return info;
|
|
202
|
-
}
|
|
203
|
-
}, {
|
|
204
|
-
key: "connectedCallback",
|
|
205
|
-
value: function connectedCallback() {
|
|
206
|
-
var _this = this;
|
|
207
|
-
|
|
208
|
-
// Observation: audio in Chrome will have the autoplay attribute,
|
|
209
|
-
// while other browsers will not have the autoplay attribute and will need a user interaction to play the audio
|
|
210
|
-
// This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox
|
|
211
|
-
var observer = new MutationObserver(function (mutationsList, observer) {
|
|
212
|
-
mutationsList.forEach(function (mutation) {
|
|
213
|
-
if (mutation.type === 'childList') {
|
|
214
|
-
if (_this._audioInitialized) return;
|
|
215
117
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
118
|
+
// filter answers by category and count the ones with content
|
|
119
|
+
const filledResponseAreas = answers.filter(answer => answer.choices.length).length;
|
|
120
|
+
// check if an answer choice was added to at least as many response areas
|
|
121
|
+
// as the number of populated response areas in the correct answer
|
|
122
|
+
const areResponseAreasFilled = filledResponseAreas >= responseAreasToBeFilled;
|
|
123
|
+
// check if multiple placements are allowed
|
|
124
|
+
const duplicatesAllowed = (choices || []).some(choice => choice.categoryCount === 0);
|
|
125
|
+
if (duplicatesAllowed) {
|
|
126
|
+
// an answer choice can be used multiple times
|
|
127
|
+
return areResponseAreasFilled;
|
|
128
|
+
}
|
|
225
129
|
|
|
226
|
-
|
|
130
|
+
// any correct answer have any unplaced answer choices (by the author)
|
|
131
|
+
if (hasUnplacedChoices) {
|
|
132
|
+
return areResponseAreasFilled;
|
|
133
|
+
}
|
|
134
|
+
const allAnswersIds = answers.map(answer => answer.choices).flat();
|
|
227
135
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
audio.play();
|
|
231
|
-
container.removeChild(info);
|
|
232
|
-
}
|
|
136
|
+
// check if any correct answer have any unplaced answer choices (by the student)
|
|
137
|
+
const requiredAnswersPlaced = (possibleResponses || []).some(response => response.every(val => allAnswersIds.includes(val)));
|
|
233
138
|
|
|
139
|
+
// true - all choices (required for a correct response) were placed into a response area
|
|
140
|
+
return requiredAnswersPlaced;
|
|
141
|
+
}
|
|
142
|
+
set session(s) {
|
|
143
|
+
if (s && !s.answers) {
|
|
144
|
+
s.answers = [];
|
|
145
|
+
}
|
|
146
|
+
this._session = s;
|
|
147
|
+
this.render();
|
|
148
|
+
}
|
|
149
|
+
get session() {
|
|
150
|
+
return this._session;
|
|
151
|
+
}
|
|
152
|
+
eliminateBlindAnswersFromSession() {
|
|
153
|
+
const {
|
|
154
|
+
answers = []
|
|
155
|
+
} = this._session || {};
|
|
156
|
+
const {
|
|
157
|
+
choices = []
|
|
158
|
+
} = this._model || {};
|
|
159
|
+
const mappedChoices = choices.map(c => c.id) || [];
|
|
160
|
+
const filteredAnswers = answers.map(answer => {
|
|
161
|
+
const answerChoices = answer?.choices || [];
|
|
162
|
+
answer.choices = answerChoices.filter(c => mappedChoices.includes(c));
|
|
163
|
+
return answer;
|
|
164
|
+
});
|
|
165
|
+
if (filteredAnswers.length > 0) {
|
|
166
|
+
this.changeAnswers(filteredAnswers);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
changeAnswers(answers) {
|
|
170
|
+
this._session.answers = answers;
|
|
171
|
+
this._session.selector = 'Mouse';
|
|
172
|
+
this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));
|
|
173
|
+
this.render();
|
|
174
|
+
}
|
|
175
|
+
onShowCorrectToggle() {
|
|
176
|
+
(0, _mathRendering.renderMath)(this);
|
|
177
|
+
}
|
|
178
|
+
_createAudioInfoToast() {
|
|
179
|
+
const info = document.createElement('div');
|
|
180
|
+
info.id = 'play-audio-info';
|
|
181
|
+
Object.assign(info.style, {
|
|
182
|
+
position: 'absolute',
|
|
183
|
+
top: 0,
|
|
184
|
+
width: '100%',
|
|
185
|
+
height: '100%',
|
|
186
|
+
display: 'flex',
|
|
187
|
+
justifyContent: 'center',
|
|
188
|
+
alignItems: 'center',
|
|
189
|
+
background: 'white',
|
|
190
|
+
zIndex: '1000',
|
|
191
|
+
cursor: 'pointer'
|
|
192
|
+
});
|
|
193
|
+
const img = document.createElement('img');
|
|
194
|
+
img.src = _renderUi.EnableAudioAutoplayImage;
|
|
195
|
+
img.alt = 'Click anywhere to enable audio autoplay';
|
|
196
|
+
img.width = 500;
|
|
197
|
+
img.height = 300;
|
|
198
|
+
info.appendChild(img);
|
|
199
|
+
return info;
|
|
200
|
+
}
|
|
201
|
+
connectedCallback() {
|
|
202
|
+
this._initMathObserver();
|
|
203
|
+
|
|
204
|
+
// Observation: audio in Chrome will have the autoplay attribute,
|
|
205
|
+
// while other browsers will not have the autoplay attribute and will need a user interaction to play the audio
|
|
206
|
+
// This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox
|
|
207
|
+
const observer = new MutationObserver((mutationsList, observer) => {
|
|
208
|
+
mutationsList.forEach(mutation => {
|
|
209
|
+
if (mutation.type === 'childList') {
|
|
210
|
+
if (this._audioInitialized) return;
|
|
211
|
+
const audio = this.querySelector('audio');
|
|
212
|
+
const isInsidePrompt = audio && audio.closest('#preview-prompt');
|
|
213
|
+
if (!this._model) return;
|
|
214
|
+
if (!this._model.autoplayAudioEnabled) return;
|
|
215
|
+
if (audio && !isInsidePrompt) return;
|
|
216
|
+
if (!audio) return;
|
|
217
|
+
const info = this._createAudioInfoToast();
|
|
218
|
+
const container = this.querySelector('#main-container');
|
|
219
|
+
const enableAudio = () => {
|
|
220
|
+
if (this.querySelector('#play-audio-info')) {
|
|
221
|
+
audio.play();
|
|
222
|
+
container.removeChild(info);
|
|
223
|
+
}
|
|
224
|
+
document.removeEventListener('click', enableAudio);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// if the audio is paused, it means the user has not interacted with the page yet and the audio will not play
|
|
228
|
+
// FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked
|
|
229
|
+
setTimeout(() => {
|
|
230
|
+
if (audio.paused && !this.querySelector('#play-audio-info')) {
|
|
231
|
+
// add info message as a toast to enable audio playback
|
|
232
|
+
container.appendChild(info);
|
|
233
|
+
document.addEventListener('click', enableAudio);
|
|
234
|
+
} else {
|
|
234
235
|
document.removeEventListener('click', enableAudio);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
_this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(_this.tagName.toLowerCase(), _this.isComplete()));
|
|
280
|
-
|
|
281
|
-
audio.removeEventListener('ended', handleEnded);
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
audio.addEventListener('ended', handleEnded); // store references to remove later
|
|
285
|
-
|
|
286
|
-
_this._audio = audio;
|
|
287
|
-
_this._handlePlaying = handlePlaying;
|
|
288
|
-
_this._handleEnded = handleEnded;
|
|
289
|
-
_this._enableAudio = enableAudio; // set to true to prevent multiple initializations
|
|
290
|
-
|
|
291
|
-
_this._audioInitialized = true;
|
|
292
|
-
observer.disconnect();
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
observer.observe(this, {
|
|
297
|
-
childList: true,
|
|
298
|
-
subtree: true
|
|
236
|
+
}
|
|
237
|
+
}, 500);
|
|
238
|
+
|
|
239
|
+
// we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering
|
|
240
|
+
const handlePlaying = () => {
|
|
241
|
+
//timestamp when auto-played audio started playing
|
|
242
|
+
this._session.audioStartTime = this._session.audioStartTime || new Date().getTime();
|
|
243
|
+
const info = this.querySelector('#play-audio-info');
|
|
244
|
+
if (info) {
|
|
245
|
+
container.removeChild(info);
|
|
246
|
+
}
|
|
247
|
+
audio.removeEventListener('playing', handlePlaying);
|
|
248
|
+
};
|
|
249
|
+
audio.addEventListener('playing', handlePlaying);
|
|
250
|
+
|
|
251
|
+
// we need to listen for the ended event to update the isComplete state
|
|
252
|
+
const handleEnded = () => {
|
|
253
|
+
//timestamp when auto-played audio completed playing
|
|
254
|
+
this._session.audioEndTime = this._session.audioEndTime || new Date().getTime();
|
|
255
|
+
let {
|
|
256
|
+
audioStartTime,
|
|
257
|
+
audioEndTime,
|
|
258
|
+
waitTime
|
|
259
|
+
} = this._session;
|
|
260
|
+
if (!waitTime && audioStartTime && audioEndTime) {
|
|
261
|
+
// waitTime is elapsed time the user waited for auto-played audio to finish
|
|
262
|
+
this._session.waitTime = audioEndTime - audioStartTime;
|
|
263
|
+
}
|
|
264
|
+
this.audioComplete = true;
|
|
265
|
+
this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));
|
|
266
|
+
audio.removeEventListener('ended', handleEnded);
|
|
267
|
+
};
|
|
268
|
+
audio.addEventListener('ended', handleEnded);
|
|
269
|
+
|
|
270
|
+
// store references to remove later
|
|
271
|
+
this._audio = audio;
|
|
272
|
+
this._handlePlaying = handlePlaying;
|
|
273
|
+
this._handleEnded = handleEnded;
|
|
274
|
+
this._enableAudio = enableAudio;
|
|
275
|
+
// set to true to prevent multiple initializations
|
|
276
|
+
this._audioInitialized = true;
|
|
277
|
+
observer.disconnect();
|
|
278
|
+
}
|
|
299
279
|
});
|
|
280
|
+
});
|
|
281
|
+
observer.observe(this, {
|
|
282
|
+
childList: true,
|
|
283
|
+
subtree: true
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
disconnectedCallback() {
|
|
287
|
+
this._disconnectMathObserver();
|
|
288
|
+
document.removeEventListener('click', this._enableAudio);
|
|
289
|
+
if (this._audio) {
|
|
290
|
+
this._audio.removeEventListener('playing', this._handlePlaying);
|
|
291
|
+
this._audio.removeEventListener('ended', this._handleEnded);
|
|
292
|
+
this._audio = null;
|
|
300
293
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
value: function disconnectedCallback() {
|
|
304
|
-
document.removeEventListener('click', this._enableAudio);
|
|
305
|
-
|
|
306
|
-
if (this._audio) {
|
|
307
|
-
this._audio.removeEventListener('playing', this._handlePlaying);
|
|
308
|
-
|
|
309
|
-
this._audio.removeEventListener('ended', this._handleEnded);
|
|
310
|
-
|
|
311
|
-
this._audio = null;
|
|
312
|
-
}
|
|
294
|
+
if (this._root) {
|
|
295
|
+
this._root.unmount();
|
|
313
296
|
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
_reactDom["default"].render(el, this, function () {
|
|
328
|
-
(0, _mathRendering.renderMath)(_this2);
|
|
329
|
-
});
|
|
297
|
+
}
|
|
298
|
+
render() {
|
|
299
|
+
if (this._model && this._session) {
|
|
300
|
+
const el = /*#__PURE__*/_react.default.createElement(_categorize.default, {
|
|
301
|
+
model: this._model,
|
|
302
|
+
session: this._session,
|
|
303
|
+
onAnswersChange: this.changeAnswers.bind(this),
|
|
304
|
+
onShowCorrectToggle: this.onShowCorrectToggle.bind(this),
|
|
305
|
+
pauseMathObserver: this.pauseMathObserver,
|
|
306
|
+
resumeMathObserver: this.resumeMathObserver
|
|
307
|
+
});
|
|
308
|
+
if (!this._root) {
|
|
309
|
+
this._root = (0, _client.createRoot)(this);
|
|
330
310
|
}
|
|
311
|
+
this._root.render(el);
|
|
331
312
|
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
exports["default"] = Categorize;
|
|
337
|
-
//# sourceMappingURL=index.js.map
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.default = Categorize;
|
|
316
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jbGllbnQiLCJfbWF0aFJlbmRlcmluZyIsIl9yZW5kZXJVaSIsIl9waWVQbGF5ZXJFdmVudHMiLCJfY2F0ZWdvcml6ZSIsIkNhdGVnb3JpemUiLCJIVE1MRWxlbWVudCIsImNvbnN0cnVjdG9yIiwiX2RlZmluZVByb3BlcnR5MiIsImRlZmF1bHQiLCJfbWF0aFJlbmRlclBlbmRpbmciLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJfbWF0aE9ic2VydmVyIiwiX21hdGhPYnNlcnZlclBhdXNlZCIsImRpc2Nvbm5lY3QiLCJyZW5kZXJNYXRoIiwic2V0VGltZW91dCIsIm9ic2VydmUiLCJjaGlsZExpc3QiLCJzdWJ0cmVlIiwiY2hhcmFjdGVyRGF0YSIsIl9yb290IiwiX2luaXRNYXRoT2JzZXJ2ZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwiX3NjaGVkdWxlTWF0aFJlbmRlciIsIl9kaXNjb25uZWN0TWF0aE9ic2VydmVyIiwibW9kZWwiLCJtIiwiX21vZGVsIiwiZWxpbWluYXRlQmxpbmRBbnN3ZXJzRnJvbVNlc3Npb24iLCJkaXNwYXRjaEV2ZW50IiwiTW9kZWxTZXRFdmVudCIsInRhZ05hbWUiLCJ0b0xvd2VyQ2FzZSIsImlzQ29tcGxldGUiLCJfYXVkaW9Jbml0aWFsaXplZCIsInJlbmRlciIsImF1dG9wbGF5QXVkaW9FbmFibGVkIiwiY2hvaWNlcyIsImNvbXBsZXRlQXVkaW9FbmFibGVkIiwiaGFzVW5wbGFjZWRDaG9pY2VzIiwicG9zc2libGVSZXNwb25zZXMiLCJyZXNwb25zZUFyZWFzVG9CZUZpbGxlZCIsImVsZW1lbnRDb250ZXh0IiwiYXVkaW9Db21wbGV0ZSIsImF1ZGlvIiwicXVlcnlTZWxlY3RvciIsImlzSW5zaWRlUHJvbXB0IiwiY2xvc2VzdCIsIl9zZXNzaW9uIiwiYW5zd2VycyIsIkFycmF5IiwiaXNBcnJheSIsImZpbGxlZFJlc3BvbnNlQXJlYXMiLCJmaWx0ZXIiLCJhbnN3ZXIiLCJsZW5ndGgiLCJhcmVSZXNwb25zZUFyZWFzRmlsbGVkIiwiZHVwbGljYXRlc0FsbG93ZWQiLCJzb21lIiwiY2hvaWNlIiwiY2F0ZWdvcnlDb3VudCIsImFsbEFuc3dlcnNJZHMiLCJtYXAiLCJmbGF0IiwicmVxdWlyZWRBbnN3ZXJzUGxhY2VkIiwicmVzcG9uc2UiLCJldmVyeSIsInZhbCIsImluY2x1ZGVzIiwic2Vzc2lvbiIsInMiLCJtYXBwZWRDaG9pY2VzIiwiYyIsImlkIiwiZmlsdGVyZWRBbnN3ZXJzIiwiYW5zd2VyQ2hvaWNlcyIsImNoYW5nZUFuc3dlcnMiLCJzZWxlY3RvciIsIlNlc3Npb25DaGFuZ2VkRXZlbnQiLCJvblNob3dDb3JyZWN0VG9nZ2xlIiwiX2NyZWF0ZUF1ZGlvSW5mb1RvYXN0IiwiaW5mbyIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudCIsIk9iamVjdCIsImFzc2lnbiIsInN0eWxlIiwicG9zaXRpb24iLCJ0b3AiLCJ3aWR0aCIsImhlaWdodCIsImRpc3BsYXkiLCJqdXN0aWZ5Q29udGVudCIsImFsaWduSXRlbXMiLCJiYWNrZ3JvdW5kIiwiekluZGV4IiwiY3Vyc29yIiwiaW1nIiwic3JjIiwiRW5hYmxlQXVkaW9BdXRvcGxheUltYWdlIiwiYWx0IiwiYXBwZW5kQ2hpbGQiLCJjb25uZWN0ZWRDYWxsYmFjayIsIm9ic2VydmVyIiwibXV0YXRpb25zTGlzdCIsImZvckVhY2giLCJtdXRhdGlvbiIsInR5cGUiLCJjb250YWluZXIiLCJlbmFibGVBdWRpbyIsInBsYXkiLCJyZW1vdmVDaGlsZCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJwYXVzZWQiLCJhZGRFdmVudExpc3RlbmVyIiwiaGFuZGxlUGxheWluZyIsImF1ZGlvU3RhcnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJoYW5kbGVFbmRlZCIsImF1ZGlvRW5kVGltZSIsIndhaXRUaW1lIiwiX2F1ZGlvIiwiX2hhbmRsZVBsYXlpbmciLCJfaGFuZGxlRW5kZWQiLCJfZW5hYmxlQXVkaW8iLCJkaXNjb25uZWN0ZWRDYWxsYmFjayIsInVubW91bnQiLCJlbCIsIlJlYWN0IiwiQ2F0ZWdvcml6ZUNvbXBvbmVudCIsIm9uQW5zd2Vyc0NoYW5nZSIsImJpbmQiLCJwYXVzZU1hdGhPYnNlcnZlciIsInJlc3VtZU1hdGhPYnNlcnZlciIsImNyZWF0ZVJvb3QiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vc3JjL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBjcmVhdGVSb290IH0gZnJvbSAncmVhY3QtZG9tL2NsaWVudCc7XG5pbXBvcnQgeyByZW5kZXJNYXRoIH0gZnJvbSAnQHBpZS1saWIvbWF0aC1yZW5kZXJpbmcnO1xuaW1wb3J0IHsgRW5hYmxlQXVkaW9BdXRvcGxheUltYWdlIH0gZnJvbSAnQHBpZS1saWIvcmVuZGVyLXVpJztcbmltcG9ydCB7IFNlc3Npb25DaGFuZ2VkRXZlbnQsIE1vZGVsU2V0RXZlbnQgfSBmcm9tICdAcGllLWZyYW1ld29yay9waWUtcGxheWVyLWV2ZW50cyc7XG5pbXBvcnQgQ2F0ZWdvcml6ZUNvbXBvbmVudCBmcm9tICcuL2NhdGVnb3JpemUnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDYXRlZ29yaXplIGV4dGVuZHMgSFRNTEVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgIHRoaXMuX21hdGhPYnNlcnZlciA9IG51bGw7XG4gICAgdGhpcy5fbWF0aFJlbmRlclBlbmRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIF9zY2hlZHVsZU1hdGhSZW5kZXIgPSAoKSA9PiB7XG4gICAgaWYgKHRoaXMuX21hdGhSZW5kZXJQZW5kaW5nKSByZXR1cm47XG5cbiAgICB0aGlzLl9tYXRoUmVuZGVyUGVuZGluZyA9IHRydWU7XG5cbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX21hdGhPYnNlcnZlciAmJiAhdGhpcy5fbWF0aE9ic2VydmVyUGF1c2VkKSB7XG4gICAgICAgIHRoaXMuX21hdGhPYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB9XG5cbiAgICAgIHJlbmRlck1hdGgodGhpcyk7XG5cbiAgICAgIHRoaXMuX21hdGhSZW5kZXJQZW5kaW5nID0gZmFsc2U7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fbWF0aE9ic2VydmVyICYmICF0aGlzLl9tYXRoT2JzZXJ2ZXJQYXVzZWQpIHtcbiAgICAgICAgICB0aGlzLl9tYXRoT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLCB7XG4gICAgICAgICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICAgICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgICAgICAgY2hhcmFjdGVyRGF0YTogZmFsc2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sIDUwKTtcbiAgICB9KTtcbiAgfTtcblxuICBfaW5pdE1hdGhPYnNlcnZlcigpIHtcbiAgICBpZiAodGhpcy5fbWF0aE9ic2VydmVyKSByZXR1cm47XG5cbiAgICB0aGlzLl9tYXRoT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoKSA9PiB7XG4gICAgICB0aGlzLl9zY2hlZHVsZU1hdGhSZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX21hdGhPYnNlcnZlci5vYnNlcnZlKHRoaXMsIHtcbiAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgIHN1YnRyZWU6IHRydWUsXG4gICAgICBjaGFyYWN0ZXJEYXRhOiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuXG4gIF9kaXNjb25uZWN0TWF0aE9ic2VydmVyKCkge1xuICAgIGlmICh0aGlzLl9tYXRoT2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuX21hdGhPYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLl9tYXRoT2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHBhdXNlTWF0aE9ic2VydmVyID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLl9tYXRoT2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuX21hdGhPYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLl9tYXRoT2JzZXJ2ZXJQYXVzZWQgPSB0cnVlO1xuICAgIH1cbiAgfTtcblxuICByZXN1bWVNYXRoT2JzZXJ2ZXIgPSAoKSA9PiB7XG4gICAgaWYgKHRoaXMuX21hdGhPYnNlcnZlclBhdXNlZCkge1xuICAgICAgdGhpcy5fbWF0aE9ic2VydmVyUGF1c2VkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLl9tYXRoT2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5fbWF0aE9ic2VydmVyLm9ic2VydmUodGhpcywge1xuICAgICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgICAgIGNoYXJhY3RlckRhdGE6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgc2V0IG1vZGVsKG0pIHtcbiAgICB0aGlzLl9tb2RlbCA9IG07XG5cbiAgICB0aGlzLmVsaW1pbmF0ZUJsaW5kQW5zd2Vyc0Zyb21TZXNzaW9uKCk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBNb2RlbFNldEV2ZW50KHRoaXMudGFnTmFtZS50b0xvd2VyQ2FzZSgpLCB0aGlzLmlzQ29tcGxldGUoKSwgISF0aGlzLl9tb2RlbCkpO1xuICAgIC8vIHJlc2V0IHRoZSBhdWRpb0luaXRpYWxpemVkIHRvIGZhbHNlIHNpbmNlIHRoZSBtb2RlbCBjaGFuZ2VkLCBhbmQgd2UgbWlnaHQgbmVlZCB0byByZWluaXRpYWxpemUgdGhlIGF1ZGlvXG4gICAgdGhpcy5fYXVkaW9Jbml0aWFsaXplZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIGlzQ29tcGxldGUoKSB7XG4gICAgY29uc3Qge1xuICAgICAgYXV0b3BsYXlBdWRpb0VuYWJsZWQsXG4gICAgICBjaG9pY2VzLFxuICAgICAgY29tcGxldGVBdWRpb0VuYWJsZWQsXG4gICAgICBoYXNVbnBsYWNlZENob2ljZXMsXG4gICAgICBwb3NzaWJsZVJlc3BvbnNlcyxcbiAgICAgIHJlc3BvbnNlQXJlYXNUb0JlRmlsbGVkLFxuICAgIH0gPSB0aGlzLl9tb2RlbCB8fCB7fTtcbiAgICBjb25zdCBlbGVtZW50Q29udGV4dCA9IHRoaXM7XG5cbiAgICAvLyBjaGVjayBhdWRpbyBjb21wbGV0aW9uIGlmIGF1ZGlvIHNldHRpbmdzIGFyZSBlbmFibGVkIGFuZCBhdWRpbyBhY3R1YWxseSBleGlzdHNcbiAgICBpZiAoYXV0b3BsYXlBdWRpb0VuYWJsZWQgJiYgY29tcGxldGVBdWRpb0VuYWJsZWQgJiYgIXRoaXMuYXVkaW9Db21wbGV0ZSkge1xuICAgICAgaWYgKGVsZW1lbnRDb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IGF1ZGlvID0gZWxlbWVudENvbnRleHQucXVlcnlTZWxlY3RvcignYXVkaW8nKTtcbiAgICAgICAgY29uc3QgaXNJbnNpZGVQcm9tcHQgPSBhdWRpbyAmJiBhdWRpby5jbG9zZXN0KCcjcHJldmlldy1wcm9tcHQnKTtcblxuICAgICAgICAvLyBvbmx5IHJlcXVpcmUgYXVkaW8gY29tcGxldGlvbiBpZiBhdWRpbyBleGlzdHMgYW5kIGlzIGluc2lkZSB0aGUgcHJvbXB0XG4gICAgICAgIGlmIChhdWRpbyAmJiBpc0luc2lkZVByb21wdCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5fc2Vzc2lvbiB8fCAhdGhpcy5fc2Vzc2lvbi5hbnN3ZXJzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhbnN3ZXJzIH0gPSB0aGlzLl9zZXNzaW9uO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGFuc3dlcnMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gZmlsdGVyIGFuc3dlcnMgYnkgY2F0ZWdvcnkgYW5kIGNvdW50IHRoZSBvbmVzIHdpdGggY29udGVudFxuICAgIGNvbnN0IGZpbGxlZFJlc3BvbnNlQXJlYXMgPSBhbnN3ZXJzLmZpbHRlcigoYW5zd2VyKSA9PiBhbnN3ZXIuY2hvaWNlcy5sZW5ndGgpLmxlbmd0aDtcbiAgICAvLyBjaGVjayBpZiBhbiBhbnN3ZXIgY2hvaWNlIHdhcyBhZGRlZCB0byBhdCBsZWFzdCBhcyBtYW55IHJlc3BvbnNlIGFyZWFzXG4gICAgLy8gYXMgdGhlIG51bWJlciBvZiBwb3B1bGF0ZWQgcmVzcG9uc2UgYXJlYXMgaW4gdGhlIGNvcnJlY3QgYW5zd2VyXG4gICAgY29uc3QgYXJlUmVzcG9uc2VBcmVhc0ZpbGxlZCA9IGZpbGxlZFJlc3BvbnNlQXJlYXMgPj0gcmVzcG9uc2VBcmVhc1RvQmVGaWxsZWQ7XG4gICAgLy8gY2hlY2sgaWYgbXVsdGlwbGUgcGxhY2VtZW50cyBhcmUgYWxsb3dlZFxuICAgIGNvbnN0IGR1cGxpY2F0ZXNBbGxvd2VkID0gKGNob2ljZXMgfHwgW10pLnNvbWUoKGNob2ljZSkgPT4gY2hvaWNlLmNhdGVnb3J5Q291bnQgPT09IDApO1xuXG4gICAgaWYgKGR1cGxpY2F0ZXNBbGxvd2VkKSB7XG4gICAgICAvLyBhbiBhbnN3ZXIgY2hvaWNlIGNhbiBiZSB1c2VkIG11bHRpcGxlIHRpbWVzXG4gICAgICByZXR1cm4gYXJlUmVzcG9uc2VBcmVhc0ZpbGxlZDtcbiAgICB9XG5cbiAgICAvLyBhbnkgY29ycmVjdCBhbnN3ZXIgaGF2ZSBhbnkgdW5wbGFjZWQgYW5zd2VyIGNob2ljZXMgKGJ5IHRoZSBhdXRob3IpXG4gICAgaWYgKGhhc1VucGxhY2VkQ2hvaWNlcykge1xuICAgICAgcmV0dXJuIGFyZVJlc3BvbnNlQXJlYXNGaWxsZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgYWxsQW5zd2Vyc0lkcyA9IGFuc3dlcnMubWFwKChhbnN3ZXIpID0+IGFuc3dlci5jaG9pY2VzKS5mbGF0KCk7XG5cbiAgICAvLyBjaGVjayBpZiBhbnkgY29ycmVjdCBhbnN3ZXIgaGF2ZSBhbnkgdW5wbGFjZWQgYW5zd2VyIGNob2ljZXMgKGJ5IHRoZSBzdHVkZW50KVxuICAgIGNvbnN0IHJlcXVpcmVkQW5zd2Vyc1BsYWNlZCA9IChwb3NzaWJsZVJlc3BvbnNlcyB8fCBbXSkuc29tZSgocmVzcG9uc2UpID0+XG4gICAgICByZXNwb25zZS5ldmVyeSgodmFsKSA9PiBhbGxBbnN3ZXJzSWRzLmluY2x1ZGVzKHZhbCkpLFxuICAgICk7XG5cbiAgICAvLyB0cnVlIC0gYWxsIGNob2ljZXMgKHJlcXVpcmVkIGZvciBhIGNvcnJlY3QgcmVzcG9uc2UpIHdlcmUgcGxhY2VkIGludG8gYSByZXNwb25zZSBhcmVhXG4gICAgcmV0dXJuIHJlcXVpcmVkQW5zd2Vyc1BsYWNlZDtcbiAgfVxuXG4gIHNldCBzZXNzaW9uKHMpIHtcbiAgICBpZiAocyAmJiAhcy5hbnN3ZXJzKSB7XG4gICAgICBzLmFuc3dlcnMgPSBbXTtcbiAgICB9XG5cbiAgICB0aGlzLl9zZXNzaW9uID0gcztcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgZ2V0IHNlc3Npb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Nlc3Npb247XG4gIH1cblxuICBlbGltaW5hdGVCbGluZEFuc3dlcnNGcm9tU2Vzc2lvbigpIHtcbiAgICBjb25zdCB7IGFuc3dlcnMgPSBbXSB9ID0gdGhpcy5fc2Vzc2lvbiB8fCB7fTtcbiAgICBjb25zdCB7IGNob2ljZXMgPSBbXSB9ID0gdGhpcy5fbW9kZWwgfHwge307XG5cbiAgICBjb25zdCBtYXBwZWRDaG9pY2VzID0gY2hvaWNlcy5tYXAoKGMpID0+IGMuaWQpIHx8IFtdO1xuICAgIGNvbnN0IGZpbHRlcmVkQW5zd2VycyA9IGFuc3dlcnMubWFwKChhbnN3ZXIpID0+IHtcbiAgICAgIGNvbnN0IGFuc3dlckNob2ljZXMgPSBhbnN3ZXI/LmNob2ljZXMgfHwgW107XG4gICAgICBhbnN3ZXIuY2hvaWNlcyA9IGFuc3dlckNob2ljZXMuZmlsdGVyKChjKSA9PiBtYXBwZWRDaG9pY2VzLmluY2x1ZGVzKGMpKTtcblxuICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICB9KTtcblxuICAgIGlmIChmaWx0ZXJlZEFuc3dlcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5jaGFuZ2VBbnN3ZXJzKGZpbHRlcmVkQW5zd2Vycyk7XG4gICAgfVxuICB9XG5cbiAgY2hhbmdlQW5zd2VycyhhbnN3ZXJzKSB7XG4gICAgdGhpcy5fc2Vzc2lvbi5hbnN3ZXJzID0gYW5zd2VycztcbiAgICB0aGlzLl9zZXNzaW9uLnNlbGVjdG9yID0gJ01vdXNlJztcblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgU2Vzc2lvbkNoYW5nZWRFdmVudCh0aGlzLnRhZ05hbWUudG9Mb3dlckNhc2UoKSwgdGhpcy5pc0NvbXBsZXRlKCkpKTtcblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBvblNob3dDb3JyZWN0VG9nZ2xlKCkge1xuICAgIHJlbmRlck1hdGgodGhpcyk7XG4gIH1cblxuICBfY3JlYXRlQXVkaW9JbmZvVG9hc3QoKSB7XG4gICAgY29uc3QgaW5mbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGluZm8uaWQgPSAncGxheS1hdWRpby1pbmZvJztcblxuICAgIE9iamVjdC5hc3NpZ24oaW5mby5zdHlsZSwge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICBqdXN0aWZ5Q29udGVudDogJ2NlbnRlcicsXG4gICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgIGJhY2tncm91bmQ6ICd3aGl0ZScsXG4gICAgICB6SW5kZXg6ICcxMDAwJyxcbiAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG4gICAgaW1nLnNyYyA9IEVuYWJsZUF1ZGlvQXV0b3BsYXlJbWFnZTtcbiAgICBpbWcuYWx0ID0gJ0NsaWNrIGFueXdoZXJlIHRvIGVuYWJsZSBhdWRpbyBhdXRvcGxheSc7XG4gICAgaW1nLndpZHRoID0gNTAwO1xuICAgIGltZy5oZWlnaHQgPSAzMDA7XG5cbiAgICBpbmZvLmFwcGVuZENoaWxkKGltZyk7XG4gICAgcmV0dXJuIGluZm87XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9pbml0TWF0aE9ic2VydmVyKCk7XG4gICAgXG4gICAgLy8gT2JzZXJ2YXRpb246ICBhdWRpbyBpbiBDaHJvbWUgd2lsbCBoYXZlIHRoZSBhdXRvcGxheSBhdHRyaWJ1dGUsXG4gICAgLy8gd2hpbGUgb3RoZXIgYnJvd3NlcnMgd2lsbCBub3QgaGF2ZSB0aGUgYXV0b3BsYXkgYXR0cmlidXRlIGFuZCB3aWxsIG5lZWQgYSB1c2VyIGludGVyYWN0aW9uIHRvIHBsYXkgdGhlIGF1ZGlvXG4gICAgLy8gVGhpcyB3b3JrYXJvdW5kIGZpeGVzIHRoZSBpc3N1ZSBvZiBhdWRpbyBiZWluZyBjYWNoZWQgYW5kIHBsYXllZCBvbiBhbnkgdXNlciBpbnRlcmFjdGlvbiBpbiBTYWZhcmkgYW5kIEZpcmVmb3hcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnNMaXN0LCBvYnNlcnZlcikgPT4ge1xuICAgICAgbXV0YXRpb25zTGlzdC5mb3JFYWNoKChtdXRhdGlvbikgPT4ge1xuICAgICAgICBpZiAobXV0YXRpb24udHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcbiAgICAgICAgICBpZiAodGhpcy5fYXVkaW9Jbml0aWFsaXplZCkgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IGF1ZGlvID0gdGhpcy5xdWVyeVNlbGVjdG9yKCdhdWRpbycpO1xuICAgICAgICAgIGNvbnN0IGlzSW5zaWRlUHJvbXB0ID0gYXVkaW8gJiYgYXVkaW8uY2xvc2VzdCgnI3ByZXZpZXctcHJvbXB0Jyk7XG5cbiAgICAgICAgICBpZiAoIXRoaXMuX21vZGVsKSByZXR1cm47XG4gICAgICAgICAgaWYgKCF0aGlzLl9tb2RlbC5hdXRvcGxheUF1ZGlvRW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICAgIGlmIChhdWRpbyAmJiAhaXNJbnNpZGVQcm9tcHQpIHJldHVybjtcbiAgICAgICAgICBpZiAoIWF1ZGlvKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBpbmZvID0gdGhpcy5fY3JlYXRlQXVkaW9JbmZvVG9hc3QoKTtcbiAgICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLnF1ZXJ5U2VsZWN0b3IoJyNtYWluLWNvbnRhaW5lcicpO1xuICAgICAgICAgIGNvbnN0IGVuYWJsZUF1ZGlvID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucXVlcnlTZWxlY3RvcignI3BsYXktYXVkaW8taW5mbycpKSB7XG4gICAgICAgICAgICAgIGF1ZGlvLnBsYXkoKTtcbiAgICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKGluZm8pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGVuYWJsZUF1ZGlvKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLy8gaWYgdGhlIGF1ZGlvIGlzIHBhdXNlZCwgaXQgbWVhbnMgdGhlIHVzZXIgaGFzIG5vdCBpbnRlcmFjdGVkIHdpdGggdGhlIHBhZ2UgeWV0IGFuZCB0aGUgYXVkaW8gd2lsbCBub3QgcGxheVxuICAgICAgICAgIC8vIEZJWCBGT1IgU0FGQVJJOiBwbGF5IHdpdGggYSBzbGlnaHQgZGVsYXkgdG8gY2hlY2sgaWYgYXV0b3BsYXkgd2FzIGJsb2NrZWRcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmIChhdWRpby5wYXVzZWQgJiYgIXRoaXMucXVlcnlTZWxlY3RvcignI3BsYXktYXVkaW8taW5mbycpKSB7XG4gICAgICAgICAgICAgIC8vIGFkZCBpbmZvIG1lc3NhZ2UgYXMgYSB0b2FzdCB0byBlbmFibGUgYXVkaW8gcGxheWJhY2tcbiAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGluZm8pO1xuICAgICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGVuYWJsZUF1ZGlvKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZW5hYmxlQXVkaW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sIDUwMCk7XG5cbiAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGxpc3RlbiBmb3IgdGhlIHBsYXlpbmcgZXZlbnQgdG8gcmVtb3ZlIHRoZSB0b2FzdCBpbiBjYXNlIHRoZSBhdWRpbyBwbGF5cyBiZWNhdXNlIG9mIHJlLXJlbmRlcmluZ1xuICAgICAgICAgIGNvbnN0IGhhbmRsZVBsYXlpbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICAvL3RpbWVzdGFtcCB3aGVuIGF1dG8tcGxheWVkIGF1ZGlvIHN0YXJ0ZWQgcGxheWluZ1xuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbi5hdWRpb1N0YXJ0VGltZSA9IHRoaXMuX3Nlc3Npb24uYXVkaW9TdGFydFRpbWUgfHwgbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGluZm8gPSB0aGlzLnF1ZXJ5U2VsZWN0b3IoJyNwbGF5LWF1ZGlvLWluZm8nKTtcbiAgICAgICAgICAgIGlmIChpbmZvKSB7XG4gICAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChpbmZvKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXVkaW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigncGxheWluZycsIGhhbmRsZVBsYXlpbmcpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBhdWRpby5hZGRFdmVudExpc3RlbmVyKCdwbGF5aW5nJywgaGFuZGxlUGxheWluZyk7XG5cbiAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGxpc3RlbiBmb3IgdGhlIGVuZGVkIGV2ZW50IHRvIHVwZGF0ZSB0aGUgaXNDb21wbGV0ZSBzdGF0ZVxuICAgICAgICAgIGNvbnN0IGhhbmRsZUVuZGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgLy90aW1lc3RhbXAgd2hlbiBhdXRvLXBsYXllZCBhdWRpbyBjb21wbGV0ZWQgcGxheWluZ1xuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbi5hdWRpb0VuZFRpbWUgPSB0aGlzLl9zZXNzaW9uLmF1ZGlvRW5kVGltZSB8fCBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgICAgICAgbGV0IHsgYXVkaW9TdGFydFRpbWUsIGF1ZGlvRW5kVGltZSwgd2FpdFRpbWUgfSA9IHRoaXMuX3Nlc3Npb247XG4gICAgICAgICAgICBpZiAoIXdhaXRUaW1lICYmIGF1ZGlvU3RhcnRUaW1lICYmIGF1ZGlvRW5kVGltZSkge1xuICAgICAgICAgICAgICAvLyB3YWl0VGltZSBpcyBlbGFwc2VkIHRpbWUgdGhlIHVzZXIgd2FpdGVkIGZvciBhdXRvLXBsYXllZCBhdWRpbyB0byBmaW5pc2hcbiAgICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbi53YWl0VGltZSA9IGF1ZGlvRW5kVGltZSAtIGF1ZGlvU3RhcnRUaW1lO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmF1ZGlvQ29tcGxldGUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBTZXNzaW9uQ2hhbmdlZEV2ZW50KHRoaXMudGFnTmFtZS50b0xvd2VyQ2FzZSgpLCB0aGlzLmlzQ29tcGxldGUoKSkpO1xuXG4gICAgICAgICAgICBhdWRpby5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIGhhbmRsZUVuZGVkKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgYXVkaW8uYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBoYW5kbGVFbmRlZCk7XG5cbiAgICAgICAgICAvLyBzdG9yZSByZWZlcmVuY2VzIHRvIHJlbW92ZSBsYXRlclxuICAgICAgICAgIHRoaXMuX2F1ZGlvID0gYXVkaW87XG4gICAgICAgICAgdGhpcy5faGFuZGxlUGxheWluZyA9IGhhbmRsZVBsYXlpbmc7XG4gICAgICAgICAgdGhpcy5faGFuZGxlRW5kZWQgPSBoYW5kbGVFbmRlZDtcbiAgICAgICAgICB0aGlzLl9lbmFibGVBdWRpbyA9IGVuYWJsZUF1ZGlvO1xuICAgICAgICAgIC8vIHNldCB0byB0cnVlIHRvIHByZXZlbnQgbXVsdGlwbGUgaW5pdGlhbGl6YXRpb25zXG4gICAgICAgICAgdGhpcy5fYXVkaW9Jbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICAgICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLCB7IGNoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX2Rpc2Nvbm5lY3RNYXRoT2JzZXJ2ZXIoKTtcbiAgICBcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2VuYWJsZUF1ZGlvKTtcblxuICAgIGlmICh0aGlzLl9hdWRpbykge1xuICAgICAgdGhpcy5fYXVkaW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigncGxheWluZycsIHRoaXMuX2hhbmRsZVBsYXlpbmcpO1xuICAgICAgdGhpcy5fYXVkaW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCB0aGlzLl9oYW5kbGVFbmRlZCk7XG4gICAgICB0aGlzLl9hdWRpbyA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3Jvb3QpIHtcbiAgICAgIHRoaXMuX3Jvb3QudW5tb3VudCgpO1xuICAgIH1cbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5fbW9kZWwgJiYgdGhpcy5fc2Vzc2lvbikge1xuICAgICAgY29uc3QgZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KENhdGVnb3JpemVDb21wb25lbnQsIHtcbiAgICAgICAgbW9kZWw6IHRoaXMuX21vZGVsLFxuICAgICAgICBzZXNzaW9uOiB0aGlzLl9zZXNzaW9uLFxuICAgICAgICBvbkFuc3dlcnNDaGFuZ2U6IHRoaXMuY2hhbmdlQW5zd2Vycy5iaW5kKHRoaXMpLFxuICAgICAgICBvblNob3dDb3JyZWN0VG9nZ2xlOiB0aGlzLm9uU2hvd0NvcnJlY3RUb2dnbGUuYmluZCh0aGlzKSxcbiAgICAgICAgcGF1c2VNYXRoT2JzZXJ2ZXI6IHRoaXMucGF1c2VNYXRoT2JzZXJ2ZXIsXG4gICAgICAgIHJlc3VtZU1hdGhPYnNlcnZlcjogdGhpcy5yZXN1bWVNYXRoT2JzZXJ2ZXIsXG4gICAgICB9KTtcblxuICAgICAgaWYgKCF0aGlzLl9yb290KSB7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBjcmVhdGVSb290KHRoaXMpO1xuICAgICAgfVxuICAgICAgdGhpcy5fcm9vdC5yZW5kZXIoZWwpO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLGNBQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLFNBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLGdCQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxXQUFBLEdBQUFOLHNCQUFBLENBQUFDLE9BQUE7QUFFZSxNQUFNTSxVQUFVLFNBQVNDLFdBQVcsQ0FBQztFQUNsREMsV0FBV0EsQ0FBQSxFQUFHO0lBQ1osS0FBSyxDQUFDLENBQUM7SUFBQyxJQUFBQyxnQkFBQSxDQUFBQyxPQUFBLCtCQU1ZLE1BQU07TUFDMUIsSUFBSSxJQUFJLENBQUNDLGtCQUFrQixFQUFFO01BRTdC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
|