@pie-lib/mask-markup 3.1.6-beta.6 → 3.1.6-beta.8

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.
@@ -0,0 +1,449 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
5
+ var _core = require("@dnd-kit/core");
6
+ var _keyboardCoordinates = require("../keyboard-coordinates");
7
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
+ function rectsToContext(rects) {
10
+ var droppableRects = new Map(Object.entries(rects));
11
+ var droppableContainers = new Map(Object.keys(rects).map(function (id) {
12
+ return [id, {
13
+ disabled: false
14
+ }];
15
+ }));
16
+ return {
17
+ droppableRects: droppableRects,
18
+ droppableContainers: droppableContainers
19
+ };
20
+ }
21
+ function makeEvent(code) {
22
+ var shiftKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
23
+ return {
24
+ code: code,
25
+ preventDefault: function preventDefault() {},
26
+ shiftKey: shiftKey
27
+ };
28
+ }
29
+
30
+ // Mirrors dnd-kit's own KeyboardSensor, which always derives collisionRect's top-left
31
+ // from the dragged item's current on-screen position on every keydown — so a test's
32
+ // collisionRect must track currentCoordinates the same way on every simulated press,
33
+ // not stay fixed while currentCoordinates changes across multiple presses.
34
+ function press(rects, currentCoordinates, itemSize, event, active) {
35
+ var context = _objectSpread(_objectSpread({}, rectsToContext(rects)), {}, {
36
+ collisionRect: _objectSpread({
37
+ left: currentCoordinates.x,
38
+ top: currentCoordinates.y
39
+ }, itemSize)
40
+ });
41
+ return (0, _keyboardCoordinates.closestDroppableKeyboardCoordinates)(event, {
42
+ active: active,
43
+ context: context,
44
+ currentCoordinates: currentCoordinates
45
+ });
46
+ }
47
+ describe('closestDroppableKeyboardCoordinates', function () {
48
+ describe('arrow keys', function () {
49
+ it("nudges the dragged item by dnd-kit's own default step (25px), unchanged", function () {
50
+ var context = _objectSpread(_objectSpread({}, rectsToContext({})), {}, {
51
+ collisionRect: {
52
+ left: 0,
53
+ top: 0,
54
+ width: 100,
55
+ height: 40
56
+ }
57
+ });
58
+ var currentCoordinates = {
59
+ x: 10,
60
+ y: 20
61
+ };
62
+ expect((0, _keyboardCoordinates.closestDroppableKeyboardCoordinates)(makeEvent(_core.KeyboardCode.Down), {
63
+ context: context,
64
+ currentCoordinates: currentCoordinates
65
+ })).toEqual({
66
+ x: 10,
67
+ y: 45
68
+ });
69
+ expect((0, _keyboardCoordinates.closestDroppableKeyboardCoordinates)(makeEvent(_core.KeyboardCode.Up), {
70
+ context: context,
71
+ currentCoordinates: currentCoordinates
72
+ })).toEqual({
73
+ x: 10,
74
+ y: -5
75
+ });
76
+ expect((0, _keyboardCoordinates.closestDroppableKeyboardCoordinates)(makeEvent(_core.KeyboardCode.Right), {
77
+ context: context,
78
+ currentCoordinates: currentCoordinates
79
+ })).toEqual({
80
+ x: 35,
81
+ y: 20
82
+ });
83
+ expect((0, _keyboardCoordinates.closestDroppableKeyboardCoordinates)(makeEvent(_core.KeyboardCode.Left), {
84
+ context: context,
85
+ currentCoordinates: currentCoordinates
86
+ })).toEqual({
87
+ x: -15,
88
+ y: 20
89
+ });
90
+ });
91
+ });
92
+ describe('Tab / Shift+Tab', function () {
93
+ var blank0Rect = {
94
+ left: 0,
95
+ top: 0,
96
+ width: 120,
97
+ height: 40,
98
+ right: 120,
99
+ bottom: 40
100
+ };
101
+ var blank1Rect = {
102
+ left: 0,
103
+ top: 60,
104
+ width: 120,
105
+ height: 40,
106
+ right: 120,
107
+ bottom: 100
108
+ };
109
+ var boardRect = {
110
+ left: 0,
111
+ top: 120,
112
+ width: 400,
113
+ height: 300,
114
+ right: 400,
115
+ bottom: 420
116
+ };
117
+ var baseRects = {
118
+ 'mask-blank-drop-0': blank0Rect,
119
+ 'mask-blank-drop-1': blank1Rect,
120
+ 'drag-in-the-blank-droppable': boardRect
121
+ };
122
+ it('jumps to the next droppable in top-to-bottom order, landing at its center-left point', function () {
123
+ var currentCoordinates = {
124
+ x: blank0Rect.left,
125
+ y: blank0Rect.top
126
+ };
127
+ var next = press(baseRects, currentCoordinates, {
128
+ width: 120,
129
+ height: 40
130
+ }, makeEvent('Tab'));
131
+ expect(next).toEqual({
132
+ x: blank1Rect.left,
133
+ y: blank1Rect.top + blank1Rect.height / 2
134
+ });
135
+ });
136
+ it('cycles backwards with Shift+Tab, wrapping to the choice board', function () {
137
+ var currentCoordinates = {
138
+ x: blank0Rect.left,
139
+ y: blank0Rect.top
140
+ };
141
+ var next = press(baseRects, currentCoordinates, {
142
+ width: 120,
143
+ height: 40
144
+ }, makeEvent('Tab', true));
145
+ expect(next).toEqual({
146
+ x: boardRect.left,
147
+ y: boardRect.top + boardRect.height / 2
148
+ });
149
+ });
150
+ it("excludes a dragged blank's own drop-zone from the cycle", function () {
151
+ // A blank is simultaneously draggable and droppable for its own slot (the same
152
+ // shape as match-list's placed "target" tiles). Without excluding it, containment
153
+ // would match the blank to itself and cycle relative to itself instead of its
154
+ // real neighbors — this test is constructed so the two behaviors give different,
155
+ // distinguishable results (not just coincidentally the same answer).
156
+ var blankARect = {
157
+ left: 0,
158
+ top: 0,
159
+ width: 120,
160
+ height: 40,
161
+ right: 120,
162
+ bottom: 40
163
+ };
164
+ var blankBRect = {
165
+ left: 0,
166
+ top: 60,
167
+ width: 120,
168
+ height: 40,
169
+ right: 120,
170
+ bottom: 100
171
+ };
172
+ var blankCRect = {
173
+ left: 0,
174
+ top: 120,
175
+ width: 120,
176
+ height: 40,
177
+ right: 120,
178
+ bottom: 160
179
+ };
180
+ var rects = {
181
+ 'mask-blank-drop-a': blankARect,
182
+ 'mask-blank-drop-b': blankBRect,
183
+ 'mask-blank-drop-c': blankCRect
184
+ };
185
+ var active = {
186
+ data: {
187
+ current: {
188
+ id: 'b',
189
+ fromChoice: false,
190
+ type: 'MaskBlank'
191
+ }
192
+ }
193
+ };
194
+ // Sitting exactly at blank B's own position.
195
+ var currentCoordinates = {
196
+ x: blankBRect.left,
197
+ y: blankBRect.top
198
+ };
199
+ var next = press(rects, currentCoordinates, {
200
+ width: 120,
201
+ height: 40
202
+ }, makeEvent('Tab', true), active);
203
+
204
+ // With B's own slot excluded, Shift+Tab from B's position falls back to
205
+ // nearest-by-dropPosition among the remaining targets (A and C) — A is closer to
206
+ // B's actual position, making A the resolved "current", so reverse from there
207
+ // lands on C. Without the exclusion, containment would match B to itself
208
+ // directly (index 1 of [A, B, C] sorted by position), landing on A instead.
209
+ expect(next).toEqual({
210
+ x: blankCRect.left,
211
+ y: blankCRect.top + blankCRect.height / 2
212
+ });
213
+ });
214
+ it('keeps advancing on repeated Shift+Tab when the choice board is much wider than the dragged item', function () {
215
+ // Regression case for the bug already found and fixed in match-list/image-cloze-
216
+ // association: matching the "current" target by reconstructing a center from the
217
+ // dragged item's own small size (instead of checking which target's rect actually
218
+ // contains it) makes the *next* press re-match a completely different droppable
219
+ // once the item is actually sitting on a wide target, so it looks like the press
220
+ // does nothing.
221
+ var wideBlankRect = {
222
+ left: 0,
223
+ top: 0,
224
+ width: 900,
225
+ height: 40,
226
+ right: 900,
227
+ bottom: 40
228
+ };
229
+ var rects = {
230
+ 'mask-blank-drop-0': wideBlankRect,
231
+ 'drag-in-the-blank-droppable': boardRect
232
+ };
233
+ var itemSize = {
234
+ width: 100,
235
+ height: 40
236
+ };
237
+ var afterFirst = press(rects, {
238
+ x: boardRect.left,
239
+ y: boardRect.top
240
+ }, itemSize, makeEvent('Tab', true));
241
+ expect(afterFirst).toEqual({
242
+ x: 0,
243
+ y: 20
244
+ }); // wide blank's center-left point
245
+
246
+ var afterSecond = press(rects, afterFirst, itemSize, makeEvent('Tab', true));
247
+ expect(afterSecond).toEqual({
248
+ x: boardRect.left,
249
+ y: boardRect.top + boardRect.height / 2
250
+ });
251
+ });
252
+ it('correctly identifies the choice board as the current target when picking up an item positioned near its edge, close to a small neighboring blank', function () {
253
+ // Regression case for the OTHER failure mode: matching "current target" purely by
254
+ // nearest-dropPosition (instead of containment first) can misidentify a large
255
+ // droppable as some small, unrelated nearby one, because a large droppable's
256
+ // dropPosition is anchored at its own vertical middle.
257
+ var tallBoardRect = {
258
+ left: 0,
259
+ top: 0,
260
+ width: 400,
261
+ height: 600,
262
+ right: 400,
263
+ bottom: 600
264
+ };
265
+ var smallBlankRect = {
266
+ left: 0,
267
+ top: -60,
268
+ width: 100,
269
+ height: 40,
270
+ right: 100,
271
+ bottom: -20
272
+ };
273
+ var rects = {
274
+ 'mask-blank-drop-0': smallBlankRect,
275
+ 'drag-in-the-blank-droppable': tallBoardRect
276
+ };
277
+ var itemSize = {
278
+ width: 100,
279
+ height: 40
280
+ };
281
+ var currentCoordinates = {
282
+ x: 0,
283
+ y: 10
284
+ };
285
+ var next = press(rects, currentCoordinates, itemSize, makeEvent('Tab'));
286
+ expect(next).toEqual({
287
+ x: smallBlankRect.left,
288
+ y: smallBlankRect.top + smallBlankRect.height / 2
289
+ });
290
+ });
291
+ it('keeps the choice board as a fixed last stop instead of sorting it in by its own center, when the board spans multiple blank rows', function () {
292
+ // Regression case for a real bug found via manual browser testing: with 3
293
+ // choices stacked beside wrapped inline text (`choicePosition: 'right'`), the
294
+ // tall choice board's own center fell numerically BETWEEN blank 2 and blank 3's
295
+ // rows. Sorting it by position the same way as a blank interleaved it into the
296
+ // middle of the cycle, so the very first Tab press after picking up a pool
297
+ // choice jumped straight to blank 3, skipping blanks 1 and 2 entirely.
298
+ var blank0Rect = {
299
+ left: 0,
300
+ top: 200,
301
+ width: 50,
302
+ height: 50,
303
+ right: 50,
304
+ bottom: 250
305
+ };
306
+ var blank1Rect = {
307
+ left: 0,
308
+ top: 250,
309
+ width: 50,
310
+ height: 50,
311
+ right: 50,
312
+ bottom: 300
313
+ };
314
+ var blank2Rect = {
315
+ left: 0,
316
+ top: 285,
317
+ width: 50,
318
+ height: 50,
319
+ right: 50,
320
+ bottom: 335
321
+ };
322
+ // Spans all three choices stacked beside the text — its center (287.5) falls
323
+ // between blank1's (275) and blank2's (310), more than 10px from either, so the
324
+ // old position-based sort placed it between them.
325
+ var tallBoardRect = {
326
+ left: 400,
327
+ top: 195,
328
+ width: 80,
329
+ height: 185,
330
+ right: 480,
331
+ bottom: 380
332
+ };
333
+ var rects = {
334
+ 'mask-blank-drop-0': blank0Rect,
335
+ 'mask-blank-drop-1': blank1Rect,
336
+ 'mask-blank-drop-2': blank2Rect,
337
+ 'drag-in-the-blank-droppable': tallBoardRect
338
+ };
339
+ var active = {
340
+ data: {
341
+ current: {
342
+ fromChoice: true,
343
+ choice: {
344
+ id: 'x'
345
+ },
346
+ type: 'MaskBlank'
347
+ }
348
+ }
349
+ };
350
+ var itemSize = {
351
+ width: 48,
352
+ height: 50
353
+ };
354
+ // Picking up a choice from within the board — its own current position, before
355
+ // any movement, sits inside the board's rect.
356
+ var currentCoordinates = {
357
+ x: 415,
358
+ y: 205
359
+ };
360
+ var next = press(rects, currentCoordinates, itemSize, makeEvent('Tab'), active);
361
+ expect(next).toEqual({
362
+ x: blank0Rect.left,
363
+ y: blank0Rect.top + blank0Rect.height / 2
364
+ });
365
+ });
366
+ it('cycles through every blank in position order, then the board, then wraps — even when the board would otherwise sort into the middle', function () {
367
+ var blank0Rect = {
368
+ left: 0,
369
+ top: 200,
370
+ width: 50,
371
+ height: 50,
372
+ right: 50,
373
+ bottom: 250
374
+ };
375
+ var blank1Rect = {
376
+ left: 0,
377
+ top: 250,
378
+ width: 50,
379
+ height: 50,
380
+ right: 50,
381
+ bottom: 300
382
+ };
383
+ var blank2Rect = {
384
+ left: 0,
385
+ top: 285,
386
+ width: 50,
387
+ height: 50,
388
+ right: 50,
389
+ bottom: 335
390
+ };
391
+ var tallBoardRect = {
392
+ left: 400,
393
+ top: 195,
394
+ width: 80,
395
+ height: 185,
396
+ right: 480,
397
+ bottom: 380
398
+ };
399
+ var rects = {
400
+ 'mask-blank-drop-0': blank0Rect,
401
+ 'mask-blank-drop-1': blank1Rect,
402
+ 'mask-blank-drop-2': blank2Rect,
403
+ 'drag-in-the-blank-droppable': tallBoardRect
404
+ };
405
+ var active = {
406
+ data: {
407
+ current: {
408
+ fromChoice: true,
409
+ choice: {
410
+ id: 'x'
411
+ },
412
+ type: 'MaskBlank'
413
+ }
414
+ }
415
+ };
416
+ var itemSize = {
417
+ width: 48,
418
+ height: 50
419
+ };
420
+ var coords = {
421
+ x: 415,
422
+ y: 205
423
+ };
424
+ var visited = [];
425
+ for (var i = 0; i < 5; i++) {
426
+ coords = press(rects, coords, itemSize, makeEvent('Tab'), active);
427
+ visited.push(coords);
428
+ }
429
+ expect(visited).toEqual([{
430
+ x: blank0Rect.left,
431
+ y: blank0Rect.top + blank0Rect.height / 2
432
+ }, {
433
+ x: blank1Rect.left,
434
+ y: blank1Rect.top + blank1Rect.height / 2
435
+ }, {
436
+ x: blank2Rect.left,
437
+ y: blank2Rect.top + blank2Rect.height / 2
438
+ }, {
439
+ x: tallBoardRect.left,
440
+ y: tallBoardRect.top + tallBoardRect.height / 2
441
+ }, {
442
+ x: blank0Rect.left,
443
+ y: blank0Rect.top + blank0Rect.height / 2
444
+ } // wraps
445
+ ]);
446
+ });
447
+ });
448
+ });
449
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29yZSIsInJlcXVpcmUiLCJfa2V5Ym9hcmRDb29yZGluYXRlcyIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwicmVjdHNUb0NvbnRleHQiLCJyZWN0cyIsImRyb3BwYWJsZVJlY3RzIiwiTWFwIiwiZW50cmllcyIsImRyb3BwYWJsZUNvbnRhaW5lcnMiLCJtYXAiLCJpZCIsImRpc2FibGVkIiwibWFrZUV2ZW50IiwiY29kZSIsInNoaWZ0S2V5IiwidW5kZWZpbmVkIiwicHJldmVudERlZmF1bHQiLCJwcmVzcyIsImN1cnJlbnRDb29yZGluYXRlcyIsIml0ZW1TaXplIiwiZXZlbnQiLCJhY3RpdmUiLCJjb250ZXh0IiwiY29sbGlzaW9uUmVjdCIsImxlZnQiLCJ4IiwidG9wIiwieSIsImNsb3Nlc3REcm9wcGFibGVLZXlib2FyZENvb3JkaW5hdGVzIiwiZGVzY3JpYmUiLCJpdCIsIndpZHRoIiwiaGVpZ2h0IiwiZXhwZWN0IiwiS2V5Ym9hcmRDb2RlIiwiRG93biIsInRvRXF1YWwiLCJVcCIsIlJpZ2h0IiwiTGVmdCIsImJsYW5rMFJlY3QiLCJyaWdodCIsImJvdHRvbSIsImJsYW5rMVJlY3QiLCJib2FyZFJlY3QiLCJiYXNlUmVjdHMiLCJuZXh0IiwiYmxhbmtBUmVjdCIsImJsYW5rQlJlY3QiLCJibGFua0NSZWN0IiwiZGF0YSIsImN1cnJlbnQiLCJmcm9tQ2hvaWNlIiwidHlwZSIsIndpZGVCbGFua1JlY3QiLCJhZnRlckZpcnN0IiwiYWZ0ZXJTZWNvbmQiLCJ0YWxsQm9hcmRSZWN0Iiwic21hbGxCbGFua1JlY3QiLCJibGFuazJSZWN0IiwiY2hvaWNlIiwiY29vcmRzIiwidmlzaXRlZCIsImkiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvX190ZXN0c19fL2tleWJvYXJkLWNvb3JkaW5hdGVzLnRlc3QuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgS2V5Ym9hcmRDb2RlIH0gZnJvbSAnQGRuZC1raXQvY29yZSc7XG5pbXBvcnQgeyBjbG9zZXN0RHJvcHBhYmxlS2V5Ym9hcmRDb29yZGluYXRlcyB9IGZyb20gJy4uL2tleWJvYXJkLWNvb3JkaW5hdGVzJztcblxuZnVuY3Rpb24gcmVjdHNUb0NvbnRleHQocmVjdHMpIHtcbiAgY29uc3QgZHJvcHBhYmxlUmVjdHMgPSBuZXcgTWFwKE9iamVjdC5lbnRyaWVzKHJlY3RzKSk7XG4gIGNvbnN0IGRyb3BwYWJsZUNvbnRhaW5lcnMgPSBuZXcgTWFwKE9iamVjdC5rZXlzKHJlY3RzKS5tYXAoKGlkKSA9PiBbaWQsIHsgZGlzYWJsZWQ6IGZhbHNlIH1dKSk7XG5cbiAgcmV0dXJuIHsgZHJvcHBhYmxlUmVjdHMsIGRyb3BwYWJsZUNvbnRhaW5lcnMgfTtcbn1cblxuZnVuY3Rpb24gbWFrZUV2ZW50KGNvZGUsIHNoaWZ0S2V5ID0gZmFsc2UpIHtcbiAgcmV0dXJuIHsgY29kZSwgcHJldmVudERlZmF1bHQ6ICgpID0+IHt9LCBzaGlmdEtleSB9O1xufVxuXG4vLyBNaXJyb3JzIGRuZC1raXQncyBvd24gS2V5Ym9hcmRTZW5zb3IsIHdoaWNoIGFsd2F5cyBkZXJpdmVzIGNvbGxpc2lvblJlY3QncyB0b3AtbGVmdFxuLy8gZnJvbSB0aGUgZHJhZ2dlZCBpdGVtJ3MgY3VycmVudCBvbi1zY3JlZW4gcG9zaXRpb24gb24gZXZlcnkga2V5ZG93biDigJQgc28gYSB0ZXN0J3Ncbi8vIGNvbGxpc2lvblJlY3QgbXVzdCB0cmFjayBjdXJyZW50Q29vcmRpbmF0ZXMgdGhlIHNhbWUgd2F5IG9uIGV2ZXJ5IHNpbXVsYXRlZCBwcmVzcyxcbi8vIG5vdCBzdGF5IGZpeGVkIHdoaWxlIGN1cnJlbnRDb29yZGluYXRlcyBjaGFuZ2VzIGFjcm9zcyBtdWx0aXBsZSBwcmVzc2VzLlxuZnVuY3Rpb24gcHJlc3MocmVjdHMsIGN1cnJlbnRDb29yZGluYXRlcywgaXRlbVNpemUsIGV2ZW50LCBhY3RpdmUpIHtcbiAgY29uc3QgY29udGV4dCA9IHtcbiAgICAuLi5yZWN0c1RvQ29udGV4dChyZWN0cyksXG4gICAgY29sbGlzaW9uUmVjdDogeyBsZWZ0OiBjdXJyZW50Q29vcmRpbmF0ZXMueCwgdG9wOiBjdXJyZW50Q29vcmRpbmF0ZXMueSwgLi4uaXRlbVNpemUgfSxcbiAgfTtcblxuICByZXR1cm4gY2xvc2VzdERyb3BwYWJsZUtleWJvYXJkQ29vcmRpbmF0ZXMoZXZlbnQsIHsgYWN0aXZlLCBjb250ZXh0LCBjdXJyZW50Q29vcmRpbmF0ZXMgfSk7XG59XG5cbmRlc2NyaWJlKCdjbG9zZXN0RHJvcHBhYmxlS2V5Ym9hcmRDb29yZGluYXRlcycsICgpID0+IHtcbiAgZGVzY3JpYmUoJ2Fycm93IGtleXMnLCAoKSA9PiB7XG4gICAgaXQoXCJudWRnZXMgdGhlIGRyYWdnZWQgaXRlbSBieSBkbmQta2l0J3Mgb3duIGRlZmF1bHQgc3RlcCAoMjVweCksIHVuY2hhbmdlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb250ZXh0ID0geyAuLi5yZWN0c1RvQ29udGV4dCh7fSksIGNvbGxpc2lvblJlY3Q6IHsgbGVmdDogMCwgdG9wOiAwLCB3aWR0aDogMTAwLCBoZWlnaHQ6IDQwIH0gfTtcbiAgICAgIGNvbnN0IGN1cnJlbnRDb29yZGluYXRlcyA9IHsgeDogMTAsIHk6IDIwIH07XG5cbiAgICAgIGV4cGVjdChcbiAgICAgICAgY2xvc2VzdERyb3BwYWJsZUtleWJvYXJkQ29vcmRpbmF0ZXMobWFrZUV2ZW50KEtleWJvYXJkQ29kZS5Eb3duKSwgeyBjb250ZXh0LCBjdXJyZW50Q29vcmRpbmF0ZXMgfSksXG4gICAgICApLnRvRXF1YWwoeyB4OiAxMCwgeTogNDUgfSk7XG4gICAgICBleHBlY3QoXG4gICAgICAgIGNsb3Nlc3REcm9wcGFibGVLZXlib2FyZENvb3JkaW5hdGVzKG1ha2VFdmVudChLZXlib2FyZENvZGUuVXApLCB7IGNvbnRleHQsIGN1cnJlbnRDb29yZGluYXRlcyB9KSxcbiAgICAgICkudG9FcXVhbCh7IHg6IDEwLCB5OiAtNSB9KTtcbiAgICAgIGV4cGVjdChcbiAgICAgICAgY2xvc2VzdERyb3BwYWJsZUtleWJvYXJkQ29vcmRpbmF0ZXMobWFrZUV2ZW50KEtleWJvYXJkQ29kZS5SaWdodCksIHsgY29udGV4dCwgY3VycmVudENvb3JkaW5hdGVzIH0pLFxuICAgICAgKS50b0VxdWFsKHsgeDogMzUsIHk6IDIwIH0pO1xuICAgICAgZXhwZWN0KFxuICAgICAgICBjbG9zZXN0RHJvcHBhYmxlS2V5Ym9hcmRDb29yZGluYXRlcyhtYWtlRXZlbnQoS2V5Ym9hcmRDb2RlLkxlZnQpLCB7IGNvbnRleHQsIGN1cnJlbnRDb29yZGluYXRlcyB9KSxcbiAgICAgICkudG9FcXVhbCh7IHg6IC0xNSwgeTogMjAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUYWIgLyBTaGlmdCtUYWInLCAoKSA9PiB7XG4gICAgY29uc3QgYmxhbmswUmVjdCA9IHsgbGVmdDogMCwgdG9wOiAwLCB3aWR0aDogMTIwLCBoZWlnaHQ6IDQwLCByaWdodDogMTIwLCBib3R0b206IDQwIH07XG4gICAgY29uc3QgYmxhbmsxUmVjdCA9IHsgbGVmdDogMCwgdG9wOiA2MCwgd2lkdGg6IDEyMCwgaGVpZ2h0OiA0MCwgcmlnaHQ6IDEyMCwgYm90dG9tOiAxMDAgfTtcbiAgICBjb25zdCBib2FyZFJlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMTIwLCB3aWR0aDogNDAwLCBoZWlnaHQ6IDMwMCwgcmlnaHQ6IDQwMCwgYm90dG9tOiA0MjAgfTtcbiAgICBjb25zdCBiYXNlUmVjdHMgPSB7XG4gICAgICAnbWFzay1ibGFuay1kcm9wLTAnOiBibGFuazBSZWN0LFxuICAgICAgJ21hc2stYmxhbmstZHJvcC0xJzogYmxhbmsxUmVjdCxcbiAgICAgICdkcmFnLWluLXRoZS1ibGFuay1kcm9wcGFibGUnOiBib2FyZFJlY3QsXG4gICAgfTtcblxuICAgIGl0KCdqdW1wcyB0byB0aGUgbmV4dCBkcm9wcGFibGUgaW4gdG9wLXRvLWJvdHRvbSBvcmRlciwgbGFuZGluZyBhdCBpdHMgY2VudGVyLWxlZnQgcG9pbnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50Q29vcmRpbmF0ZXMgPSB7IHg6IGJsYW5rMFJlY3QubGVmdCwgeTogYmxhbmswUmVjdC50b3AgfTtcblxuICAgICAgY29uc3QgbmV4dCA9IHByZXNzKGJhc2VSZWN0cywgY3VycmVudENvb3JkaW5hdGVzLCB7IHdpZHRoOiAxMjAsIGhlaWdodDogNDAgfSwgbWFrZUV2ZW50KCdUYWInKSk7XG5cbiAgICAgIGV4cGVjdChuZXh0KS50b0VxdWFsKHsgeDogYmxhbmsxUmVjdC5sZWZ0LCB5OiBibGFuazFSZWN0LnRvcCArIGJsYW5rMVJlY3QuaGVpZ2h0IC8gMiB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjeWNsZXMgYmFja3dhcmRzIHdpdGggU2hpZnQrVGFiLCB3cmFwcGluZyB0byB0aGUgY2hvaWNlIGJvYXJkJywgKCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudENvb3JkaW5hdGVzID0geyB4OiBibGFuazBSZWN0LmxlZnQsIHk6IGJsYW5rMFJlY3QudG9wIH07XG5cbiAgICAgIGNvbnN0IG5leHQgPSBwcmVzcyhiYXNlUmVjdHMsIGN1cnJlbnRDb29yZGluYXRlcywgeyB3aWR0aDogMTIwLCBoZWlnaHQ6IDQwIH0sIG1ha2VFdmVudCgnVGFiJywgdHJ1ZSkpO1xuXG4gICAgICBleHBlY3QobmV4dCkudG9FcXVhbCh7IHg6IGJvYXJkUmVjdC5sZWZ0LCB5OiBib2FyZFJlY3QudG9wICsgYm9hcmRSZWN0LmhlaWdodCAvIDIgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcImV4Y2x1ZGVzIGEgZHJhZ2dlZCBibGFuaydzIG93biBkcm9wLXpvbmUgZnJvbSB0aGUgY3ljbGVcIiwgKCkgPT4ge1xuICAgICAgLy8gQSBibGFuayBpcyBzaW11bHRhbmVvdXNseSBkcmFnZ2FibGUgYW5kIGRyb3BwYWJsZSBmb3IgaXRzIG93biBzbG90ICh0aGUgc2FtZVxuICAgICAgLy8gc2hhcGUgYXMgbWF0Y2gtbGlzdCdzIHBsYWNlZCBcInRhcmdldFwiIHRpbGVzKS4gV2l0aG91dCBleGNsdWRpbmcgaXQsIGNvbnRhaW5tZW50XG4gICAgICAvLyB3b3VsZCBtYXRjaCB0aGUgYmxhbmsgdG8gaXRzZWxmIGFuZCBjeWNsZSByZWxhdGl2ZSB0byBpdHNlbGYgaW5zdGVhZCBvZiBpdHNcbiAgICAgIC8vIHJlYWwgbmVpZ2hib3JzIOKAlCB0aGlzIHRlc3QgaXMgY29uc3RydWN0ZWQgc28gdGhlIHR3byBiZWhhdmlvcnMgZ2l2ZSBkaWZmZXJlbnQsXG4gICAgICAvLyBkaXN0aW5ndWlzaGFibGUgcmVzdWx0cyAobm90IGp1c3QgY29pbmNpZGVudGFsbHkgdGhlIHNhbWUgYW5zd2VyKS5cbiAgICAgIGNvbnN0IGJsYW5rQVJlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMCwgd2lkdGg6IDEyMCwgaGVpZ2h0OiA0MCwgcmlnaHQ6IDEyMCwgYm90dG9tOiA0MCB9O1xuICAgICAgY29uc3QgYmxhbmtCUmVjdCA9IHsgbGVmdDogMCwgdG9wOiA2MCwgd2lkdGg6IDEyMCwgaGVpZ2h0OiA0MCwgcmlnaHQ6IDEyMCwgYm90dG9tOiAxMDAgfTtcbiAgICAgIGNvbnN0IGJsYW5rQ1JlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMTIwLCB3aWR0aDogMTIwLCBoZWlnaHQ6IDQwLCByaWdodDogMTIwLCBib3R0b206IDE2MCB9O1xuICAgICAgY29uc3QgcmVjdHMgPSB7XG4gICAgICAgICdtYXNrLWJsYW5rLWRyb3AtYSc6IGJsYW5rQVJlY3QsXG4gICAgICAgICdtYXNrLWJsYW5rLWRyb3AtYic6IGJsYW5rQlJlY3QsXG4gICAgICAgICdtYXNrLWJsYW5rLWRyb3AtYyc6IGJsYW5rQ1JlY3QsXG4gICAgICB9O1xuICAgICAgY29uc3QgYWN0aXZlID0geyBkYXRhOiB7IGN1cnJlbnQ6IHsgaWQ6ICdiJywgZnJvbUNob2ljZTogZmFsc2UsIHR5cGU6ICdNYXNrQmxhbmsnIH0gfSB9O1xuICAgICAgLy8gU2l0dGluZyBleGFjdGx5IGF0IGJsYW5rIEIncyBvd24gcG9zaXRpb24uXG4gICAgICBjb25zdCBjdXJyZW50Q29vcmRpbmF0ZXMgPSB7IHg6IGJsYW5rQlJlY3QubGVmdCwgeTogYmxhbmtCUmVjdC50b3AgfTtcblxuICAgICAgY29uc3QgbmV4dCA9IHByZXNzKHJlY3RzLCBjdXJyZW50Q29vcmRpbmF0ZXMsIHsgd2lkdGg6IDEyMCwgaGVpZ2h0OiA0MCB9LCBtYWtlRXZlbnQoJ1RhYicsIHRydWUpLCBhY3RpdmUpO1xuXG4gICAgICAvLyBXaXRoIEIncyBvd24gc2xvdCBleGNsdWRlZCwgU2hpZnQrVGFiIGZyb20gQidzIHBvc2l0aW9uIGZhbGxzIGJhY2sgdG9cbiAgICAgIC8vIG5lYXJlc3QtYnktZHJvcFBvc2l0aW9uIGFtb25nIHRoZSByZW1haW5pbmcgdGFyZ2V0cyAoQSBhbmQgQykg4oCUIEEgaXMgY2xvc2VyIHRvXG4gICAgICAvLyBCJ3MgYWN0dWFsIHBvc2l0aW9uLCBtYWtpbmcgQSB0aGUgcmVzb2x2ZWQgXCJjdXJyZW50XCIsIHNvIHJldmVyc2UgZnJvbSB0aGVyZVxuICAgICAgLy8gbGFuZHMgb24gQy4gV2l0aG91dCB0aGUgZXhjbHVzaW9uLCBjb250YWlubWVudCB3b3VsZCBtYXRjaCBCIHRvIGl0c2VsZlxuICAgICAgLy8gZGlyZWN0bHkgKGluZGV4IDEgb2YgW0EsIEIsIENdIHNvcnRlZCBieSBwb3NpdGlvbiksIGxhbmRpbmcgb24gQSBpbnN0ZWFkLlxuICAgICAgZXhwZWN0KG5leHQpLnRvRXF1YWwoeyB4OiBibGFua0NSZWN0LmxlZnQsIHk6IGJsYW5rQ1JlY3QudG9wICsgYmxhbmtDUmVjdC5oZWlnaHQgLyAyIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2tlZXBzIGFkdmFuY2luZyBvbiByZXBlYXRlZCBTaGlmdCtUYWIgd2hlbiB0aGUgY2hvaWNlIGJvYXJkIGlzIG11Y2ggd2lkZXIgdGhhbiB0aGUgZHJhZ2dlZCBpdGVtJywgKCkgPT4ge1xuICAgICAgLy8gUmVncmVzc2lvbiBjYXNlIGZvciB0aGUgYnVnIGFscmVhZHkgZm91bmQgYW5kIGZpeGVkIGluIG1hdGNoLWxpc3QvaW1hZ2UtY2xvemUtXG4gICAgICAvLyBhc3NvY2lhdGlvbjogbWF0Y2hpbmcgdGhlIFwiY3VycmVudFwiIHRhcmdldCBieSByZWNvbnN0cnVjdGluZyBhIGNlbnRlciBmcm9tIHRoZVxuICAgICAgLy8gZHJhZ2dlZCBpdGVtJ3Mgb3duIHNtYWxsIHNpemUgKGluc3RlYWQgb2YgY2hlY2tpbmcgd2hpY2ggdGFyZ2V0J3MgcmVjdCBhY3R1YWxseVxuICAgICAgLy8gY29udGFpbnMgaXQpIG1ha2VzIHRoZSAqbmV4dCogcHJlc3MgcmUtbWF0Y2ggYSBjb21wbGV0ZWx5IGRpZmZlcmVudCBkcm9wcGFibGVcbiAgICAgIC8vIG9uY2UgdGhlIGl0ZW0gaXMgYWN0dWFsbHkgc2l0dGluZyBvbiBhIHdpZGUgdGFyZ2V0LCBzbyBpdCBsb29rcyBsaWtlIHRoZSBwcmVzc1xuICAgICAgLy8gZG9lcyBub3RoaW5nLlxuICAgICAgY29uc3Qgd2lkZUJsYW5rUmVjdCA9IHsgbGVmdDogMCwgdG9wOiAwLCB3aWR0aDogOTAwLCBoZWlnaHQ6IDQwLCByaWdodDogOTAwLCBib3R0b206IDQwIH07XG4gICAgICBjb25zdCByZWN0cyA9IHsgJ21hc2stYmxhbmstZHJvcC0wJzogd2lkZUJsYW5rUmVjdCwgJ2RyYWctaW4tdGhlLWJsYW5rLWRyb3BwYWJsZSc6IGJvYXJkUmVjdCB9O1xuICAgICAgY29uc3QgaXRlbVNpemUgPSB7IHdpZHRoOiAxMDAsIGhlaWdodDogNDAgfTtcblxuICAgICAgY29uc3QgYWZ0ZXJGaXJzdCA9IHByZXNzKHJlY3RzLCB7IHg6IGJvYXJkUmVjdC5sZWZ0LCB5OiBib2FyZFJlY3QudG9wIH0sIGl0ZW1TaXplLCBtYWtlRXZlbnQoJ1RhYicsIHRydWUpKTtcblxuICAgICAgZXhwZWN0KGFmdGVyRmlyc3QpLnRvRXF1YWwoeyB4OiAwLCB5OiAyMCB9KTsgLy8gd2lkZSBibGFuaydzIGNlbnRlci1sZWZ0IHBvaW50XG5cbiAgICAgIGNvbnN0IGFmdGVyU2Vjb25kID0gcHJlc3MocmVjdHMsIGFmdGVyRmlyc3QsIGl0ZW1TaXplLCBtYWtlRXZlbnQoJ1RhYicsIHRydWUpKTtcblxuICAgICAgZXhwZWN0KGFmdGVyU2Vjb25kKS50b0VxdWFsKHsgeDogYm9hcmRSZWN0LmxlZnQsIHk6IGJvYXJkUmVjdC50b3AgKyBib2FyZFJlY3QuaGVpZ2h0IC8gMiB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjb3JyZWN0bHkgaWRlbnRpZmllcyB0aGUgY2hvaWNlIGJvYXJkIGFzIHRoZSBjdXJyZW50IHRhcmdldCB3aGVuIHBpY2tpbmcgdXAgYW4gaXRlbSBwb3NpdGlvbmVkIG5lYXIgaXRzIGVkZ2UsIGNsb3NlIHRvIGEgc21hbGwgbmVpZ2hib3JpbmcgYmxhbmsnLCAoKSA9PiB7XG4gICAgICAvLyBSZWdyZXNzaW9uIGNhc2UgZm9yIHRoZSBPVEhFUiBmYWlsdXJlIG1vZGU6IG1hdGNoaW5nIFwiY3VycmVudCB0YXJnZXRcIiBwdXJlbHkgYnlcbiAgICAgIC8vIG5lYXJlc3QtZHJvcFBvc2l0aW9uIChpbnN0ZWFkIG9mIGNvbnRhaW5tZW50IGZpcnN0KSBjYW4gbWlzaWRlbnRpZnkgYSBsYXJnZVxuICAgICAgLy8gZHJvcHBhYmxlIGFzIHNvbWUgc21hbGwsIHVucmVsYXRlZCBuZWFyYnkgb25lLCBiZWNhdXNlIGEgbGFyZ2UgZHJvcHBhYmxlJ3NcbiAgICAgIC8vIGRyb3BQb3NpdGlvbiBpcyBhbmNob3JlZCBhdCBpdHMgb3duIHZlcnRpY2FsIG1pZGRsZS5cbiAgICAgIGNvbnN0IHRhbGxCb2FyZFJlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMCwgd2lkdGg6IDQwMCwgaGVpZ2h0OiA2MDAsIHJpZ2h0OiA0MDAsIGJvdHRvbTogNjAwIH07XG4gICAgICBjb25zdCBzbWFsbEJsYW5rUmVjdCA9IHsgbGVmdDogMCwgdG9wOiAtNjAsIHdpZHRoOiAxMDAsIGhlaWdodDogNDAsIHJpZ2h0OiAxMDAsIGJvdHRvbTogLTIwIH07XG4gICAgICBjb25zdCByZWN0cyA9IHsgJ21hc2stYmxhbmstZHJvcC0wJzogc21hbGxCbGFua1JlY3QsICdkcmFnLWluLXRoZS1ibGFuay1kcm9wcGFibGUnOiB0YWxsQm9hcmRSZWN0IH07XG4gICAgICBjb25zdCBpdGVtU2l6ZSA9IHsgd2lkdGg6IDEwMCwgaGVpZ2h0OiA0MCB9O1xuXG4gICAgICBjb25zdCBjdXJyZW50Q29vcmRpbmF0ZXMgPSB7IHg6IDAsIHk6IDEwIH07XG5cbiAgICAgIGNvbnN0IG5leHQgPSBwcmVzcyhyZWN0cywgY3VycmVudENvb3JkaW5hdGVzLCBpdGVtU2l6ZSwgbWFrZUV2ZW50KCdUYWInKSk7XG5cbiAgICAgIGV4cGVjdChuZXh0KS50b0VxdWFsKHsgeDogc21hbGxCbGFua1JlY3QubGVmdCwgeTogc21hbGxCbGFua1JlY3QudG9wICsgc21hbGxCbGFua1JlY3QuaGVpZ2h0IC8gMiB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdrZWVwcyB0aGUgY2hvaWNlIGJvYXJkIGFzIGEgZml4ZWQgbGFzdCBzdG9wIGluc3RlYWQgb2Ygc29ydGluZyBpdCBpbiBieSBpdHMgb3duIGNlbnRlciwgd2hlbiB0aGUgYm9hcmQgc3BhbnMgbXVsdGlwbGUgYmxhbmsgcm93cycsICgpID0+IHtcbiAgICAgIC8vIFJlZ3Jlc3Npb24gY2FzZSBmb3IgYSByZWFsIGJ1ZyBmb3VuZCB2aWEgbWFudWFsIGJyb3dzZXIgdGVzdGluZzogd2l0aCAzXG4gICAgICAvLyBjaG9pY2VzIHN0YWNrZWQgYmVzaWRlIHdyYXBwZWQgaW5saW5lIHRleHQgKGBjaG9pY2VQb3NpdGlvbjogJ3JpZ2h0J2ApLCB0aGVcbiAgICAgIC8vIHRhbGwgY2hvaWNlIGJvYXJkJ3Mgb3duIGNlbnRlciBmZWxsIG51bWVyaWNhbGx5IEJFVFdFRU4gYmxhbmsgMiBhbmQgYmxhbmsgMydzXG4gICAgICAvLyByb3dzLiBTb3J0aW5nIGl0IGJ5IHBvc2l0aW9uIHRoZSBzYW1lIHdheSBhcyBhIGJsYW5rIGludGVybGVhdmVkIGl0IGludG8gdGhlXG4gICAgICAvLyBtaWRkbGUgb2YgdGhlIGN5Y2xlLCBzbyB0aGUgdmVyeSBmaXJzdCBUYWIgcHJlc3MgYWZ0ZXIgcGlja2luZyB1cCBhIHBvb2xcbiAgICAgIC8vIGNob2ljZSBqdW1wZWQgc3RyYWlnaHQgdG8gYmxhbmsgMywgc2tpcHBpbmcgYmxhbmtzIDEgYW5kIDIgZW50aXJlbHkuXG4gICAgICBjb25zdCBibGFuazBSZWN0ID0geyBsZWZ0OiAwLCB0b3A6IDIwMCwgd2lkdGg6IDUwLCBoZWlnaHQ6IDUwLCByaWdodDogNTAsIGJvdHRvbTogMjUwIH07XG4gICAgICBjb25zdCBibGFuazFSZWN0ID0geyBsZWZ0OiAwLCB0b3A6IDI1MCwgd2lkdGg6IDUwLCBoZWlnaHQ6IDUwLCByaWdodDogNTAsIGJvdHRvbTogMzAwIH07XG4gICAgICBjb25zdCBibGFuazJSZWN0ID0geyBsZWZ0OiAwLCB0b3A6IDI4NSwgd2lkdGg6IDUwLCBoZWlnaHQ6IDUwLCByaWdodDogNTAsIGJvdHRvbTogMzM1IH07XG4gICAgICAvLyBTcGFucyBhbGwgdGhyZWUgY2hvaWNlcyBzdGFja2VkIGJlc2lkZSB0aGUgdGV4dCDigJQgaXRzIGNlbnRlciAoMjg3LjUpIGZhbGxzXG4gICAgICAvLyBiZXR3ZWVuIGJsYW5rMSdzICgyNzUpIGFuZCBibGFuazIncyAoMzEwKSwgbW9yZSB0aGFuIDEwcHggZnJvbSBlaXRoZXIsIHNvIHRoZVxuICAgICAgLy8gb2xkIHBvc2l0aW9uLWJhc2VkIHNvcnQgcGxhY2VkIGl0IGJldHdlZW4gdGhlbS5cbiAgICAgIGNvbnN0IHRhbGxCb2FyZFJlY3QgPSB7IGxlZnQ6IDQwMCwgdG9wOiAxOTUsIHdpZHRoOiA4MCwgaGVpZ2h0OiAxODUsIHJpZ2h0OiA0ODAsIGJvdHRvbTogMzgwIH07XG4gICAgICBjb25zdCByZWN0cyA9IHtcbiAgICAgICAgJ21hc2stYmxhbmstZHJvcC0wJzogYmxhbmswUmVjdCxcbiAgICAgICAgJ21hc2stYmxhbmstZHJvcC0xJzogYmxhbmsxUmVjdCxcbiAgICAgICAgJ21hc2stYmxhbmstZHJvcC0yJzogYmxhbmsyUmVjdCxcbiAgICAgICAgJ2RyYWctaW4tdGhlLWJsYW5rLWRyb3BwYWJsZSc6IHRhbGxCb2FyZFJlY3QsXG4gICAgICB9O1xuICAgICAgY29uc3QgYWN0aXZlID0geyBkYXRhOiB7IGN1cnJlbnQ6IHsgZnJvbUNob2ljZTogdHJ1ZSwgY2hvaWNlOiB7IGlkOiAneCcgfSwgdHlwZTogJ01hc2tCbGFuaycgfSB9IH07XG4gICAgICBjb25zdCBpdGVtU2l6ZSA9IHsgd2lkdGg6IDQ4LCBoZWlnaHQ6IDUwIH07XG4gICAgICAvLyBQaWNraW5nIHVwIGEgY2hvaWNlIGZyb20gd2l0aGluIHRoZSBib2FyZCDigJQgaXRzIG93biBjdXJyZW50IHBvc2l0aW9uLCBiZWZvcmVcbiAgICAgIC8vIGFueSBtb3ZlbWVudCwgc2l0cyBpbnNpZGUgdGhlIGJvYXJkJ3MgcmVjdC5cbiAgICAgIGNvbnN0IGN1cnJlbnRDb29yZGluYXRlcyA9IHsgeDogNDE1LCB5OiAyMDUgfTtcblxuICAgICAgY29uc3QgbmV4dCA9IHByZXNzKHJlY3RzLCBjdXJyZW50Q29vcmRpbmF0ZXMsIGl0ZW1TaXplLCBtYWtlRXZlbnQoJ1RhYicpLCBhY3RpdmUpO1xuXG4gICAgICBleHBlY3QobmV4dCkudG9FcXVhbCh7IHg6IGJsYW5rMFJlY3QubGVmdCwgeTogYmxhbmswUmVjdC50b3AgKyBibGFuazBSZWN0LmhlaWdodCAvIDIgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3ljbGVzIHRocm91Z2ggZXZlcnkgYmxhbmsgaW4gcG9zaXRpb24gb3JkZXIsIHRoZW4gdGhlIGJvYXJkLCB0aGVuIHdyYXBzIOKAlCBldmVuIHdoZW4gdGhlIGJvYXJkIHdvdWxkIG90aGVyd2lzZSBzb3J0IGludG8gdGhlIG1pZGRsZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJsYW5rMFJlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMjAwLCB3aWR0aDogNTAsIGhlaWdodDogNTAsIHJpZ2h0OiA1MCwgYm90dG9tOiAyNTAgfTtcbiAgICAgIGNvbnN0IGJsYW5rMVJlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMjUwLCB3aWR0aDogNTAsIGhlaWdodDogNTAsIHJpZ2h0OiA1MCwgYm90dG9tOiAzMDAgfTtcbiAgICAgIGNvbnN0IGJsYW5rMlJlY3QgPSB7IGxlZnQ6IDAsIHRvcDogMjg1LCB3aWR0aDogNTAsIGhlaWdodDogNTAsIHJpZ2h0OiA1MCwgYm90dG9tOiAzMzUgfTtcbiAgICAgIGNvbnN0IHRhbGxCb2FyZFJlY3QgPSB7IGxlZnQ6IDQwMCwgdG9wOiAxOTUsIHdpZHRoOiA4MCwgaGVpZ2h0OiAxODUsIHJpZ2h0OiA0ODAsIGJvdHRvbTogMzgwIH07XG4gICAgICBjb25zdCByZWN0cyA9IHtcbiAgICAgICAgJ21hc2stYmxhbmstZHJvcC0wJzogYmxhbmswUmVjdCxcbiAgICAgICAgJ21hc2stYmxhbmstZHJvcC0xJzogYmxhbmsxUmVjdCxcbiAgICAgICAgJ21hc2stYmxhbmstZHJvcC0yJzogYmxhbmsyUmVjdCxcbiAgICAgICAgJ2RyYWctaW4tdGhlLWJsYW5rLWRyb3BwYWJsZSc6IHRhbGxCb2FyZFJlY3QsXG4gICAgICB9O1xuICAgICAgY29uc3QgYWN0aXZlID0geyBkYXRhOiB7IGN1cnJlbnQ6IHsgZnJvbUNob2ljZTogdHJ1ZSwgY2hvaWNlOiB7IGlkOiAneCcgfSwgdHlwZTogJ01hc2tCbGFuaycgfSB9IH07XG4gICAgICBjb25zdCBpdGVtU2l6ZSA9IHsgd2lkdGg6IDQ4LCBoZWlnaHQ6IDUwIH07XG5cbiAgICAgIGxldCBjb29yZHMgPSB7IHg6IDQxNSwgeTogMjA1IH07XG4gICAgICBjb25zdCB2aXNpdGVkID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgICAgIGNvb3JkcyA9IHByZXNzKHJlY3RzLCBjb29yZHMsIGl0ZW1TaXplLCBtYWtlRXZlbnQoJ1RhYicpLCBhY3RpdmUpO1xuICAgICAgICB2aXNpdGVkLnB1c2goY29vcmRzKTtcbiAgICAgIH1cblxuICAgICAgZXhwZWN0KHZpc2l0ZWQpLnRvRXF1YWwoW1xuICAgICAgICB7IHg6IGJsYW5rMFJlY3QubGVmdCwgeTogYmxhbmswUmVjdC50b3AgKyBibGFuazBSZWN0LmhlaWdodCAvIDIgfSxcbiAgICAgICAgeyB4OiBibGFuazFSZWN0LmxlZnQsIHk6IGJsYW5rMVJlY3QudG9wICsgYmxhbmsxUmVjdC5oZWlnaHQgLyAyIH0sXG4gICAgICAgIHsgeDogYmxhbmsyUmVjdC5sZWZ0LCB5OiBibGFuazJSZWN0LnRvcCArIGJsYW5rMlJlY3QuaGVpZ2h0IC8gMiB9LFxuICAgICAgICB7IHg6IHRhbGxCb2FyZFJlY3QubGVmdCwgeTogdGFsbEJvYXJkUmVjdC50b3AgKyB0YWxsQm9hcmRSZWN0LmhlaWdodCAvIDIgfSxcbiAgICAgICAgeyB4OiBibGFuazBSZWN0LmxlZnQsIHk6IGJsYW5rMFJlY3QudG9wICsgYmxhbmswUmVjdC5oZWlnaHQgLyAyIH0sIC8vIHdyYXBzXG4gICAgICBdKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLElBQUFBLEtBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLG9CQUFBLEdBQUFELE9BQUE7QUFBOEUsU0FBQUUsUUFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxJQUFBLENBQUFKLENBQUEsT0FBQUcsTUFBQSxDQUFBRSxxQkFBQSxRQUFBQyxDQUFBLEdBQUFILE1BQUEsQ0FBQUUscUJBQUEsQ0FBQUwsQ0FBQSxHQUFBQyxDQUFBLEtBQUFLLENBQUEsR0FBQUEsQ0FBQSxDQUFBQyxNQUFBLFdBQUFOLENB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