@esotericsoftware/spine-pixi-v8 4.2.63

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/dist/Spine.js ADDED
@@ -0,0 +1,629 @@
1
+ /** ****************************************************************************
2
+ * Spine Runtimes License Agreement
3
+ * Last updated July 28, 2023. Replaces all prior versions.
4
+ *
5
+ * Copyright (c) 2013-2023, Esoteric Software LLC
6
+ *
7
+ * Integration of the Spine Runtimes into software or otherwise creating
8
+ * derivative works of the Spine Runtimes is permitted under the terms and
9
+ * conditions of Section 2 of the Spine Editor License Agreement:
10
+ * http://esotericsoftware.com/spine-editor-license
11
+ *
12
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software or
13
+ * otherwise create derivative works of the Spine Runtimes (collectively,
14
+ * "Products"), provided that each user of the Products must obtain their own
15
+ * Spine Editor license and redistribution of the Products in any form must
16
+ * include this license and copyright notice.
17
+ *
18
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
19
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
24
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
27
+ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ *****************************************************************************/
29
+ import { Assets, Cache, Container, DEG_TO_RAD, fastCopy, Graphics, Texture, Ticker, ViewContainer, } from 'pixi.js';
30
+ import { AnimationState, AnimationStateData, AtlasAttachmentLoader, ClippingAttachment, Color, MeshAttachment, Physics, Pool, RegionAttachment, Skeleton, SkeletonBinary, SkeletonBounds, SkeletonClipping, SkeletonData, SkeletonJson, Vector2, } from '@esotericsoftware/spine-core';
31
+ ;
32
+ const vectorAux = new Vector2();
33
+ Skeleton.yDown = true;
34
+ const clipper = new SkeletonClipping();
35
+ ;
36
+ const maskPool = new Pool(() => new Graphics);
37
+ /**
38
+ * The class to instantiate a {@link Spine} game object in Pixi.
39
+ * The static method {@link Spine.from} should be used to instantiate a Spine game object.
40
+ */
41
+ export class Spine extends ViewContainer {
42
+ // Pixi properties
43
+ batched = true;
44
+ buildId = 0;
45
+ renderPipeId = 'spine';
46
+ _didSpineUpdate = false;
47
+ beforeUpdateWorldTransforms = () => { };
48
+ afterUpdateWorldTransforms = () => { };
49
+ // Spine properties
50
+ /** The skeleton for this Spine game object. */
51
+ skeleton;
52
+ /** The animation state for this Spine game object. */
53
+ state;
54
+ skeletonBounds;
55
+ darkTint = false;
56
+ _debug = undefined;
57
+ _slotsObject = Object.create(null);
58
+ clippingSlotToPixiMasks = Object.create(null);
59
+ getSlotFromRef(slotRef) {
60
+ let slot;
61
+ if (typeof slotRef === 'number')
62
+ slot = this.skeleton.slots[slotRef];
63
+ else if (typeof slotRef === 'string')
64
+ slot = this.skeleton.findSlot(slotRef);
65
+ else
66
+ slot = slotRef;
67
+ if (!slot)
68
+ throw new Error(`No slot found with the given slot reference: ${slotRef}`);
69
+ return slot;
70
+ }
71
+ spineAttachmentsDirty = true;
72
+ spineTexturesDirty = true;
73
+ _lastAttachments = [];
74
+ _stateChanged = true;
75
+ attachmentCacheData = [];
76
+ get debug() {
77
+ return this._debug;
78
+ }
79
+ /** Pass a {@link SpineDebugRenderer} or create your own {@link ISpineDebugRenderer} to render bones, meshes, ...
80
+ * @example spineGO.debug = new SpineDebugRenderer();
81
+ */
82
+ set debug(value) {
83
+ if (this._debug) {
84
+ this._debug.unregisterSpine(this);
85
+ }
86
+ if (value) {
87
+ value.registerSpine(this);
88
+ }
89
+ this._debug = value;
90
+ }
91
+ autoUpdateWarned = false;
92
+ _autoUpdate = true;
93
+ get autoUpdate() {
94
+ return this._autoUpdate;
95
+ }
96
+ /** When `true`, the Spine AnimationState and the Skeleton will be automatically updated using the {@link Ticker.shared} instance. */
97
+ set autoUpdate(value) {
98
+ if (value) {
99
+ Ticker.shared.add(this.internalUpdate, this);
100
+ this.autoUpdateWarned = false;
101
+ }
102
+ else {
103
+ Ticker.shared.remove(this.internalUpdate, this);
104
+ }
105
+ this._autoUpdate = value;
106
+ }
107
+ constructor(options) {
108
+ if (options instanceof SkeletonData) {
109
+ options = {
110
+ skeletonData: options,
111
+ };
112
+ }
113
+ super();
114
+ const skeletonData = options instanceof SkeletonData ? options : options.skeletonData;
115
+ this.skeleton = new Skeleton(skeletonData);
116
+ this.state = new AnimationState(new AnimationStateData(skeletonData));
117
+ this.autoUpdate = options?.autoUpdate ?? true;
118
+ // dark tint can be enabled by options, otherwise is enable if at least one slot has tint black
119
+ this.darkTint = options?.darkTint === undefined
120
+ ? this.skeleton.slots.some(slot => !!slot.data.darkColor)
121
+ : options?.darkTint;
122
+ const slots = this.skeleton.slots;
123
+ for (let i = 0; i < slots.length; i++) {
124
+ this.attachmentCacheData[i] = Object.create(null);
125
+ }
126
+ this._updateState(0);
127
+ }
128
+ /** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
129
+ update(dt) {
130
+ if (this.autoUpdate && !this.autoUpdateWarned) {
131
+ console.warn('You are calling update on a Spine instance that has autoUpdate set to true. This is probably not what you want.');
132
+ this.autoUpdateWarned = true;
133
+ }
134
+ this.internalUpdate(0, dt);
135
+ }
136
+ internalUpdate(_deltaFrame, deltaSeconds) {
137
+ // Because reasons, pixi uses deltaFrames at 60fps.
138
+ // We ignore the default deltaFrames and use the deltaSeconds from pixi ticker.
139
+ this._updateState(deltaSeconds ?? Ticker.shared.deltaMS / 1000);
140
+ }
141
+ get bounds() {
142
+ if (this._boundsDirty) {
143
+ this.updateBounds();
144
+ }
145
+ return this._bounds;
146
+ }
147
+ /**
148
+ * Set the position of the bone given in input through a {@link IPointData}.
149
+ * @param bone: the bone name or the bone instance to set the position
150
+ * @param outPos: the new position of the bone.
151
+ * @throws {Error}: if the given bone is not found in the skeleton, an error is thrown
152
+ */
153
+ setBonePosition(bone, position) {
154
+ const boneAux = bone;
155
+ if (typeof bone === 'string') {
156
+ bone = this.skeleton.findBone(bone);
157
+ }
158
+ if (!bone)
159
+ throw Error(`Cant set bone position, bone ${String(boneAux)} not found`);
160
+ vectorAux.set(position.x, position.y);
161
+ if (bone.parent) {
162
+ const aux = bone.parent.worldToLocal(vectorAux);
163
+ bone.x = aux.x;
164
+ bone.y = -aux.y;
165
+ }
166
+ else {
167
+ bone.x = vectorAux.x;
168
+ bone.y = vectorAux.y;
169
+ }
170
+ }
171
+ /**
172
+ * Return the position of the bone given in input into an {@link IPointData}.
173
+ * @param bone: the bone name or the bone instance to get the position from
174
+ * @param outPos: an optional {@link IPointData} to use to return the bone position, rathern than instantiating a new object.
175
+ * @returns {IPointData | undefined}: the position of the bone, or undefined if no matching bone is found in the skeleton
176
+ */
177
+ getBonePosition(bone, outPos) {
178
+ const boneAux = bone;
179
+ if (typeof bone === 'string') {
180
+ bone = this.skeleton.findBone(bone);
181
+ }
182
+ if (!bone) {
183
+ console.error(`Cant set bone position! Bone ${String(boneAux)} not found`);
184
+ return outPos;
185
+ }
186
+ if (!outPos) {
187
+ outPos = { x: 0, y: 0 };
188
+ }
189
+ outPos.x = bone.worldX;
190
+ outPos.y = bone.worldY;
191
+ return outPos;
192
+ }
193
+ /**
194
+ * Will update the state based on the specified time, this will not apply the state to the skeleton
195
+ * as this is differed until the `applyState` method is called.
196
+ *
197
+ * @param time the time at which to set the state
198
+ * @internal
199
+ */
200
+ _updateState(time) {
201
+ this.state.update(time);
202
+ this.skeleton.update(time);
203
+ this._stateChanged = true;
204
+ this._boundsDirty = true;
205
+ this.onViewUpdate();
206
+ }
207
+ /**
208
+ * Applies the state to this spine instance.
209
+ * - updates the state to the skeleton
210
+ * - updates its world transform (spine world transform)
211
+ * - validates the attachments - to flag if the attachments have changed this state
212
+ * - transforms the attachments - to update the vertices of the attachments based on the new positions
213
+ * - update the slot attachments - to update the position, rotation, scale, and visibility of the attached containers
214
+ * @internal
215
+ */
216
+ _applyState() {
217
+ if (!this._stateChanged)
218
+ return;
219
+ this._stateChanged = false;
220
+ const { skeleton } = this;
221
+ this.state.apply(skeleton);
222
+ this.beforeUpdateWorldTransforms(this);
223
+ skeleton.updateWorldTransform(Physics.update);
224
+ this.afterUpdateWorldTransforms(this);
225
+ this.validateAttachments();
226
+ this.transformAttachments();
227
+ this.updateSlotObjects();
228
+ }
229
+ validateAttachments() {
230
+ const currentDrawOrder = this.skeleton.drawOrder;
231
+ const lastAttachments = this._lastAttachments;
232
+ let index = 0;
233
+ let spineAttachmentsDirty = false;
234
+ for (let i = 0; i < currentDrawOrder.length; i++) {
235
+ const slot = currentDrawOrder[i];
236
+ const attachment = slot.getAttachment();
237
+ if (attachment) {
238
+ if (attachment !== lastAttachments[index]) {
239
+ spineAttachmentsDirty = true;
240
+ lastAttachments[index] = attachment;
241
+ }
242
+ index++;
243
+ }
244
+ }
245
+ if (index !== lastAttachments.length) {
246
+ spineAttachmentsDirty = true;
247
+ lastAttachments.length = index;
248
+ }
249
+ this.spineAttachmentsDirty = spineAttachmentsDirty;
250
+ }
251
+ updateAndSetPixiMask(slot, last) {
252
+ // assign/create the currentClippingSlot
253
+ const attachment = slot.attachment;
254
+ if (attachment && attachment instanceof ClippingAttachment) {
255
+ const clip = (this.clippingSlotToPixiMasks[slot.data.name] ||= { slot, vertices: new Array() });
256
+ clip.maskComputed = false;
257
+ this.currentClippingSlot = this.clippingSlotToPixiMasks[slot.data.name];
258
+ return;
259
+ }
260
+ // assign the currentClippingSlot mask to the slot object
261
+ let currentClippingSlot = this.currentClippingSlot;
262
+ let slotObject = this._slotsObject[slot.data.name];
263
+ if (currentClippingSlot && slotObject) {
264
+ let slotClipping = currentClippingSlot.slot;
265
+ let clippingAttachment = slotClipping.attachment;
266
+ // create the pixi mask, only the first time and if the clipped slot is the first one clipped by this currentClippingSlot
267
+ let mask = currentClippingSlot.mask;
268
+ if (!mask) {
269
+ mask = maskPool.obtain();
270
+ currentClippingSlot.mask = mask;
271
+ this.addChild(mask);
272
+ }
273
+ // compute the pixi mask polygon, if the clipped slot is the first one clipped by this currentClippingSlot
274
+ if (!currentClippingSlot.maskComputed) {
275
+ currentClippingSlot.maskComputed = true;
276
+ const worldVerticesLength = clippingAttachment.worldVerticesLength;
277
+ const vertices = currentClippingSlot.vertices;
278
+ clippingAttachment.computeWorldVertices(slotClipping, 0, worldVerticesLength, vertices, 0, 2);
279
+ mask.clear().poly(vertices).stroke({ width: 0 }).fill({ alpha: .25 });
280
+ }
281
+ slotObject.container.mask = mask;
282
+ }
283
+ else if (slotObject?.container.mask) {
284
+ // remove the mask, if slot object has a mask, but currentClippingSlot is undefined
285
+ slotObject.container.mask = null;
286
+ }
287
+ // if current slot is the ending one of the currentClippingSlot mask, set currentClippingSlot to undefined
288
+ if (currentClippingSlot && currentClippingSlot.slot.attachment.endSlot == slot.data) {
289
+ this.currentClippingSlot = undefined;
290
+ }
291
+ // clean up unused masks
292
+ if (last) {
293
+ for (const key in this.clippingSlotToPixiMasks) {
294
+ const clippingSlotToPixiMask = this.clippingSlotToPixiMasks[key];
295
+ if ((!(clippingSlotToPixiMask.slot.attachment instanceof ClippingAttachment) || !clippingSlotToPixiMask.maskComputed) && clippingSlotToPixiMask.mask) {
296
+ this.removeChild(clippingSlotToPixiMask.mask);
297
+ maskPool.free(clippingSlotToPixiMask.mask);
298
+ clippingSlotToPixiMask.mask = undefined;
299
+ }
300
+ }
301
+ }
302
+ }
303
+ currentClippingSlot;
304
+ transformAttachments() {
305
+ const currentDrawOrder = this.skeleton.drawOrder;
306
+ for (let i = 0; i < currentDrawOrder.length; i++) {
307
+ const slot = currentDrawOrder[i];
308
+ this.updateAndSetPixiMask(slot, i === currentDrawOrder.length - 1);
309
+ const attachment = slot.getAttachment();
310
+ if (attachment) {
311
+ if (attachment instanceof MeshAttachment || attachment instanceof RegionAttachment) {
312
+ const cacheData = this._getCachedData(slot, attachment);
313
+ if (attachment instanceof RegionAttachment) {
314
+ attachment.computeWorldVertices(slot, cacheData.vertices, 0, 2);
315
+ }
316
+ else {
317
+ attachment.computeWorldVertices(slot, 0, attachment.worldVerticesLength, cacheData.vertices, 0, 2);
318
+ }
319
+ fastCopy(attachment.uvs.buffer, cacheData.uvs.buffer);
320
+ const skeleton = slot.bone.skeleton;
321
+ const skeletonColor = skeleton.color;
322
+ const slotColor = slot.color;
323
+ const attachmentColor = attachment.color;
324
+ cacheData.color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, skeletonColor.a * slotColor.a * attachmentColor.a);
325
+ if (slot.darkColor) {
326
+ cacheData.darkColor.setFromColor(slot.darkColor);
327
+ }
328
+ cacheData.skipRender = cacheData.clipped = false;
329
+ const texture = attachment.region?.texture.texture || Texture.EMPTY;
330
+ if (cacheData.texture !== texture) {
331
+ cacheData.texture = texture;
332
+ this.spineTexturesDirty = true;
333
+ }
334
+ if (clipper.isClipping()) {
335
+ this.updateClippingData(cacheData);
336
+ }
337
+ }
338
+ else if (attachment instanceof ClippingAttachment) {
339
+ clipper.clipStart(slot, attachment);
340
+ continue;
341
+ }
342
+ }
343
+ clipper.clipEndWithSlot(slot);
344
+ }
345
+ clipper.clipEnd();
346
+ }
347
+ updateClippingData(cacheData) {
348
+ cacheData.clipped = true;
349
+ clipper.clipTrianglesUnpacked(cacheData.vertices, cacheData.indices, cacheData.indices.length, cacheData.uvs);
350
+ const { clippedVertices, clippedUVs, clippedTriangles } = clipper;
351
+ const verticesCount = clippedVertices.length / 2;
352
+ const indicesCount = clippedTriangles.length;
353
+ if (!cacheData.clippedData) {
354
+ cacheData.clippedData = {
355
+ vertices: new Float32Array(verticesCount * 2),
356
+ uvs: new Float32Array(verticesCount * 2),
357
+ vertexCount: verticesCount,
358
+ indices: new Uint16Array(indicesCount),
359
+ indicesCount,
360
+ };
361
+ this.spineAttachmentsDirty = true;
362
+ }
363
+ const clippedData = cacheData.clippedData;
364
+ const sizeChange = clippedData.vertexCount !== verticesCount || indicesCount !== clippedData.indicesCount;
365
+ cacheData.skipRender = verticesCount === 0;
366
+ if (sizeChange) {
367
+ this.spineAttachmentsDirty = true;
368
+ if (clippedData.vertexCount < verticesCount) {
369
+ // buffer reuse!
370
+ clippedData.vertices = new Float32Array(verticesCount * 2);
371
+ clippedData.uvs = new Float32Array(verticesCount * 2);
372
+ }
373
+ if (clippedData.indices.length < indicesCount) {
374
+ clippedData.indices = new Uint16Array(indicesCount);
375
+ }
376
+ }
377
+ const { vertices, uvs, indices } = clippedData;
378
+ for (let i = 0; i < verticesCount; i++) {
379
+ vertices[i * 2] = clippedVertices[i * 2];
380
+ vertices[(i * 2) + 1] = clippedVertices[(i * 2) + 1];
381
+ uvs[i * 2] = clippedUVs[(i * 2)];
382
+ uvs[(i * 2) + 1] = clippedUVs[(i * 2) + 1];
383
+ }
384
+ clippedData.vertexCount = verticesCount;
385
+ for (let i = 0; i < indicesCount; i++) {
386
+ if (indices[i] !== clippedTriangles[i]) {
387
+ this.spineAttachmentsDirty = true;
388
+ indices[i] = clippedTriangles[i];
389
+ }
390
+ }
391
+ clippedData.indicesCount = indicesCount;
392
+ }
393
+ /**
394
+ * ensure that attached containers map correctly to their slots
395
+ * along with their position, rotation, scale, and visibility.
396
+ */
397
+ updateSlotObjects() {
398
+ for (const i in this._slotsObject) {
399
+ const slotAttachment = this._slotsObject[i];
400
+ if (!slotAttachment)
401
+ continue;
402
+ this.updateSlotObject(slotAttachment);
403
+ }
404
+ }
405
+ updateSlotObject(slotAttachment) {
406
+ const { slot, container } = slotAttachment;
407
+ container.visible = this.skeleton.drawOrder.includes(slot);
408
+ if (container.visible) {
409
+ const bone = slot.bone;
410
+ container.position.set(bone.worldX, bone.worldY);
411
+ container.scale.x = bone.getWorldScaleX();
412
+ container.scale.y = bone.getWorldScaleY();
413
+ container.rotation = bone.getWorldRotationX() * DEG_TO_RAD;
414
+ container.alpha = this.skeleton.color.a * slot.color.a;
415
+ }
416
+ }
417
+ /** @internal */
418
+ _getCachedData(slot, attachment) {
419
+ return this.attachmentCacheData[slot.data.index][attachment.name] || this.initCachedData(slot, attachment);
420
+ }
421
+ initCachedData(slot, attachment) {
422
+ let vertices;
423
+ if (attachment instanceof RegionAttachment) {
424
+ vertices = new Float32Array(8);
425
+ this.attachmentCacheData[slot.data.index][attachment.name] = {
426
+ id: `${slot.data.index}-${attachment.name}`,
427
+ vertices,
428
+ clipped: false,
429
+ indices: [0, 1, 2, 0, 2, 3],
430
+ uvs: new Float32Array(attachment.uvs.length),
431
+ color: new Color(1, 1, 1, 1),
432
+ darkColor: new Color(0, 0, 0, 0),
433
+ darkTint: this.darkTint,
434
+ skipRender: false,
435
+ texture: attachment.region?.texture.texture,
436
+ };
437
+ }
438
+ else {
439
+ vertices = new Float32Array(attachment.worldVerticesLength);
440
+ this.attachmentCacheData[slot.data.index][attachment.name] = {
441
+ id: `${slot.data.index}-${attachment.name}`,
442
+ vertices,
443
+ clipped: false,
444
+ indices: attachment.triangles,
445
+ uvs: new Float32Array(attachment.uvs.length),
446
+ color: new Color(1, 1, 1, 1),
447
+ darkColor: new Color(0, 0, 0, 0),
448
+ darkTint: this.darkTint,
449
+ skipRender: false,
450
+ texture: attachment.region?.texture.texture,
451
+ };
452
+ }
453
+ return this.attachmentCacheData[slot.data.index][attachment.name];
454
+ }
455
+ onViewUpdate() {
456
+ // increment from the 12th bit!
457
+ this._didChangeId += 1 << 12;
458
+ this._boundsDirty = true;
459
+ if (this.didViewUpdate)
460
+ return;
461
+ this.didViewUpdate = true;
462
+ const renderGroup = this.renderGroup || this.parentRenderGroup;
463
+ if (renderGroup) {
464
+ renderGroup.onChildViewUpdate(this);
465
+ }
466
+ this.debug?.renderDebug(this);
467
+ }
468
+ /**
469
+ * Attaches a PixiJS container to a specified slot. This will map the world transform of the slots bone
470
+ * to the attached container. A container can only be attached to one slot at a time.
471
+ *
472
+ * @param container - The container to attach to the slot
473
+ * @param slotRef - The slot id or slot to attach to
474
+ */
475
+ addSlotObject(slot, container) {
476
+ slot = this.getSlotFromRef(slot);
477
+ // need to check in on the container too...
478
+ for (const i in this._slotsObject) {
479
+ if (this._slotsObject[i]?.container === container) {
480
+ this.removeSlotObject(this._slotsObject[i].slot);
481
+ }
482
+ }
483
+ this.removeSlotObject(slot);
484
+ container.includeInBuild = false;
485
+ // TODO only add once??
486
+ this.addChild(container);
487
+ const slotObject = { container, slot };
488
+ this._slotsObject[slot.data.name] = slotObject;
489
+ this.updateSlotObject(slotObject);
490
+ }
491
+ /**
492
+ * Removes a PixiJS container from the slot it is attached to.
493
+ *
494
+ * @param container - The container to detach from the slot
495
+ * @param slotOrContainer - The container, slot id or slot to detach from
496
+ */
497
+ removeSlotObject(slotOrContainer) {
498
+ let containerToRemove;
499
+ if (slotOrContainer instanceof Container) {
500
+ for (const i in this._slotsObject) {
501
+ if (this._slotsObject[i]?.container === slotOrContainer) {
502
+ this._slotsObject[i] = null;
503
+ containerToRemove = slotOrContainer;
504
+ break;
505
+ }
506
+ }
507
+ }
508
+ else {
509
+ const slot = this.getSlotFromRef(slotOrContainer);
510
+ containerToRemove = this._slotsObject[slot.data.name]?.container;
511
+ this._slotsObject[slot.data.name] = null;
512
+ }
513
+ if (containerToRemove) {
514
+ this.removeChild(containerToRemove);
515
+ containerToRemove.includeInBuild = true;
516
+ }
517
+ }
518
+ /**
519
+ * Returns a container attached to a slot, or undefined if no container is attached.
520
+ *
521
+ * @param slotRef - The slot id or slot to get the attachment from
522
+ * @returns - The container attached to the slot
523
+ */
524
+ getSlotObject(slot) {
525
+ slot = this.getSlotFromRef(slot);
526
+ return this._slotsObject[slot.data.name]?.container;
527
+ }
528
+ updateBounds() {
529
+ this._boundsDirty = false;
530
+ this.skeletonBounds ||= new SkeletonBounds();
531
+ const skeletonBounds = this.skeletonBounds;
532
+ skeletonBounds.update(this.skeleton, true);
533
+ if (skeletonBounds.minX === Infinity) {
534
+ this._applyState();
535
+ const drawOrder = this.skeleton.drawOrder;
536
+ const bounds = this._bounds;
537
+ bounds.clear();
538
+ for (let i = 0; i < drawOrder.length; i++) {
539
+ const slot = drawOrder[i];
540
+ const attachment = slot.getAttachment();
541
+ if (attachment && (attachment instanceof RegionAttachment || attachment instanceof MeshAttachment)) {
542
+ const cacheData = this._getCachedData(slot, attachment);
543
+ bounds.addVertexData(cacheData.vertices, 0, cacheData.vertices.length);
544
+ }
545
+ }
546
+ }
547
+ else {
548
+ this._bounds.minX = skeletonBounds.minX;
549
+ this._bounds.minY = skeletonBounds.minY;
550
+ this._bounds.maxX = skeletonBounds.maxX;
551
+ this._bounds.maxY = skeletonBounds.maxY;
552
+ }
553
+ }
554
+ /** @internal */
555
+ addBounds(bounds) {
556
+ bounds.addBounds(this.bounds);
557
+ }
558
+ /**
559
+ * Destroys this sprite renderable and optionally its texture.
560
+ * @param options - Options parameter. A boolean will act as if all options
561
+ * have been set to that value
562
+ * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well
563
+ * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well
564
+ */
565
+ destroy(options = false) {
566
+ super.destroy(options);
567
+ Ticker.shared.remove(this.internalUpdate, this);
568
+ this.state.clearListeners();
569
+ this.debug = undefined;
570
+ this.skeleton = null;
571
+ this.state = null;
572
+ this._slotsObject = null;
573
+ this._lastAttachments.length = 0;
574
+ this.attachmentCacheData = null;
575
+ }
576
+ /** Converts a point from the skeleton coordinate system to the Pixi world coordinate system. */
577
+ skeletonToPixiWorldCoordinates(point) {
578
+ this.worldTransform.apply(point, point);
579
+ }
580
+ /** Converts a point from the Pixi world coordinate system to the skeleton coordinate system. */
581
+ pixiWorldCoordinatesToSkeleton(point) {
582
+ this.worldTransform.applyInverse(point, point);
583
+ }
584
+ /** Converts a point from the Pixi world coordinate system to the bone's local coordinate system. */
585
+ pixiWorldCoordinatesToBone(point, bone) {
586
+ this.pixiWorldCoordinatesToSkeleton(point);
587
+ if (bone.parent) {
588
+ bone.parent.worldToLocal(point);
589
+ }
590
+ else {
591
+ bone.worldToLocal(point);
592
+ }
593
+ }
594
+ /**
595
+ * Use this method to instantiate a Spine game object.
596
+ * Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the Assets. For example:
597
+ * ```
598
+ * PIXI.Assets.add("sackData", "./assets/sack-pro.skel");
599
+ * PIXI.Assets.add("sackAtlas", "./assets/sack-pma.atlas");
600
+ * await PIXI.Assets.load(["sackData", "sackAtlas"]);
601
+ * ```
602
+ * Once a Spine game object is created, its skeleton data is cached into {@link Cache} using the key:
603
+ * `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
604
+ *
605
+ * @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
606
+ * @returns {Spine} The Spine game object instantiated
607
+ */
608
+ static from({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true }) {
609
+ const cacheKey = `${skeleton}-${atlas}-${scale}`;
610
+ if (Cache.has(cacheKey)) {
611
+ return new Spine(Cache.get(cacheKey));
612
+ }
613
+ const skeletonAsset = Assets.get(skeleton);
614
+ const atlasAsset = Assets.get(atlas);
615
+ const attachmentLoader = new AtlasAttachmentLoader(atlasAsset);
616
+ const parser = skeletonAsset instanceof Uint8Array
617
+ ? new SkeletonBinary(attachmentLoader)
618
+ : new SkeletonJson(attachmentLoader);
619
+ parser.scale = scale;
620
+ const skeletonData = parser.readSkeletonData(skeletonAsset);
621
+ Cache.set(cacheKey, skeletonData);
622
+ return new Spine({
623
+ skeletonData,
624
+ darkTint,
625
+ autoUpdate,
626
+ });
627
+ }
628
+ }
629
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3BpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU3BpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFDTixNQUFNLEVBRU4sS0FBSyxFQUNMLFNBQVMsRUFFVCxVQUFVLEVBRVYsUUFBUSxFQUNSLFFBQVEsRUFFUixPQUFPLEVBQ1AsTUFBTSxFQUNOLGFBQWEsR0FDYixNQUFNLFNBQVMsQ0FBQztBQUVqQixPQUFPLEVBQ04sY0FBYyxFQUNkLGtCQUFrQixFQUNsQixxQkFBcUIsRUFHckIsa0JBQWtCLEVBQ2xCLEtBQUssRUFDTCxjQUFjLEVBQ2QsT0FBTyxFQUNQLElBQUksRUFDSixnQkFBZ0IsRUFDaEIsUUFBUSxFQUNSLGNBQWMsRUFDZCxjQUFjLEVBQ2QsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDWixZQUFZLEVBSVosT0FBTyxHQUNQLE1BQU0sOEJBQThCLENBQUM7QUF3QnJDLENBQUM7QUFFRixNQUFNLFNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBRWhDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBRXRCLE1BQU0sT0FBTyxHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztBQWtEdEMsQ0FBQztBQUVGLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFXLEdBQUcsRUFBRSxDQUFDLElBQUksUUFBUSxDQUFDLENBQUM7QUFFeEQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLEtBQU0sU0FBUSxhQUFhO0lBQ3ZDLGtCQUFrQjtJQUNYLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFDZixPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ00sWUFBWSxHQUFHLE9BQU8sQ0FBQztJQUN6QyxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBRXhCLDJCQUEyQixHQUE0QixHQUFHLEVBQUUsR0FBVSxDQUFDLENBQUM7SUFDeEUsMEJBQTBCLEdBQTRCLEdBQUcsRUFBRSxHQUFVLENBQUMsQ0FBQztJQUU5RSxtQkFBbUI7SUFDbkIsK0NBQStDO0lBQ3hDLFFBQVEsQ0FBVztJQUMxQixzREFBc0Q7SUFDL0MsS0FBSyxDQUFpQjtJQUN0QixjQUFjLENBQWtCO0lBRS9CLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDakIsTUFBTSxHQUFxQyxTQUFTLENBQUM7SUFFcEQsWUFBWSxHQUFnRSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pHLHVCQUF1QixHQUFvQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRS9FLGNBQWMsQ0FBRSxPQUErQjtRQUN0RCxJQUFJLElBQWlCLENBQUM7UUFFdEIsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRO1lBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ2hFLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtZQUFFLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7WUFDeEUsSUFBSSxHQUFHLE9BQU8sQ0FBQztRQUVwQixJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFdEYsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDO0lBQzdCLGtCQUFrQixHQUFHLElBQUksQ0FBQztJQUV6QixnQkFBZ0IsR0FBaUIsRUFBRSxDQUFDO0lBRXBDLGFBQWEsR0FBRyxJQUFJLENBQUM7SUFDckIsbUJBQW1CLEdBQTBDLEVBQUUsQ0FBQztJQUV4RSxJQUFXLEtBQUs7UUFDZixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDcEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBVyxLQUFLLENBQUUsS0FBc0M7UUFDdkQsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksS0FBSyxFQUFFLENBQUM7WUFDWCxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRU8sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFFM0IsSUFBVyxVQUFVO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUN6QixDQUFDO0lBQ0QscUlBQXFJO0lBQ3JJLElBQVcsVUFBVSxDQUFFLEtBQWM7UUFDcEMsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNYLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztRQUMvQixDQUFDO2FBQ0ksQ0FBQztZQUNMLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFRCxZQUFhLE9BQW9DO1FBQ2hELElBQUksT0FBTyxZQUFZLFlBQVksRUFBRSxDQUFDO1lBQ3JDLE9BQU8sR0FBRztnQkFDVCxZQUFZLEVBQUUsT0FBTzthQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUVELEtBQUssRUFBRSxDQUFDO1FBRVIsTUFBTSxZQUFZLEdBQUcsT0FBTyxZQUFZLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO1FBRXRGLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLEVBQUUsVUFBVSxJQUFJLElBQUksQ0FBQztRQUU5QywrRkFBK0Y7UUFDL0YsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLEVBQUUsUUFBUSxLQUFLLFNBQVM7WUFDOUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUN6RCxDQUFDLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQztRQUVyQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUVsQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxxSUFBcUk7SUFDOUgsTUFBTSxDQUFFLEVBQVU7UUFDeEIsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDL0MsT0FBTyxDQUFDLElBQUksQ0FBQyxpSEFBaUgsQ0FBQyxDQUFDO1lBQ2hJLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDOUIsQ0FBQztRQUVELElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFUyxjQUFjLENBQUUsV0FBZ0IsRUFBRSxZQUFxQjtRQUNoRSxtREFBbUQ7UUFDbkQsK0VBQStFO1FBQy9FLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxJQUFJLE1BQU07UUFDVCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDckIsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxlQUFlLENBQUUsSUFBbUIsRUFBRSxRQUFtQjtRQUMvRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFFckIsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM5QixJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFTLENBQUM7UUFDN0MsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxLQUFLLENBQUMsZ0NBQWdDLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEYsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVoRCxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDZixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNqQixDQUFDO2FBQ0ksQ0FBQztZQUNMLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNyQixJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsQ0FBQztJQUNGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLGVBQWUsQ0FBRSxJQUFtQixFQUFFLE1BQWtCO1FBQzlELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQztRQUVyQixJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQVMsQ0FBQztRQUM3QyxDQUFDO1FBRUQsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUUzRSxPQUFPLE1BQU0sQ0FBQztRQUNmLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDYixNQUFNLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUN6QixDQUFDO1FBRUQsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUV2QixPQUFPLE1BQU0sQ0FBQztJQUNmLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxZQUFZLENBQUUsSUFBWTtRQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUzQixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUUxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUV6QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsV0FBVztRQUNWLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFFM0IsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQztRQUUxQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUUzQixJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFdEMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFFM0IsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVPLG1CQUFtQjtRQUMxQixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1FBRWpELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztRQUU5QyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFFZCxJQUFJLHFCQUFxQixHQUFHLEtBQUssQ0FBQztRQUVsQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDbEQsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBRXhDLElBQUksVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLElBQUksVUFBVSxLQUFLLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUMzQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7b0JBQzdCLGVBQWUsQ0FBQyxLQUFLLENBQUMsR0FBRyxVQUFVLENBQUM7Z0JBQ3JDLENBQUM7Z0JBRUQsS0FBSyxFQUFFLENBQUM7WUFDVCxDQUFDO1FBQ0YsQ0FBQztRQUVELElBQUksS0FBSyxLQUFLLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0QyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7WUFDN0IsZUFBZSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDaEMsQ0FBQztRQUVELElBQUksQ0FBQyxxQkFBcUIsR0FBRyxxQkFBcUIsQ0FBQztJQUNwRCxDQUFDO0lBRU8sb0JBQW9CLENBQUUsSUFBVSxFQUFFLElBQWE7UUFDdEQsd0NBQXdDO1FBQ3hDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDbkMsSUFBSSxVQUFVLElBQUksVUFBVSxZQUFZLGtCQUFrQixFQUFFLENBQUM7WUFDNUQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxLQUFLLEVBQVUsRUFBRSxDQUFDLENBQUM7WUFDeEcsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hFLE9BQU87UUFDUixDQUFDO1FBRUQseURBQXlEO1FBQ3pELElBQUksbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1FBQ25ELElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRCxJQUFJLG1CQUFtQixJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ3ZDLElBQUksWUFBWSxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQztZQUM1QyxJQUFJLGtCQUFrQixHQUFHLFlBQVksQ0FBQyxVQUFnQyxDQUFDO1lBRXZFLHlIQUF5SDtZQUN6SCxJQUFJLElBQUksR0FBRyxtQkFBbUIsQ0FBQyxJQUFnQixDQUFDO1lBQ2hELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDWCxJQUFJLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN6QixtQkFBbUIsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3JCLENBQUM7WUFFRCwwR0FBMEc7WUFDMUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN2QyxtQkFBbUIsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2dCQUN4QyxNQUFNLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDO2dCQUNuRSxNQUFNLFFBQVEsR0FBRyxtQkFBbUIsQ0FBQyxRQUFRLENBQUM7Z0JBQzlDLGtCQUFrQixDQUFDLG9CQUFvQixDQUFDLFlBQVksRUFBRSxDQUFDLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDOUYsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQ0QsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLENBQUM7YUFBTSxJQUFJLFVBQVUsRUFBRSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDdkMsbUZBQW1GO1lBQ25GLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNsQyxDQUFDO1FBRUQsMEdBQTBHO1FBQzFHLElBQUksbUJBQW1CLElBQUssbUJBQW1CLENBQUMsSUFBSSxDQUFDLFVBQWlDLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM3RyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDO1FBQ3RDLENBQUM7UUFFRCx3QkFBd0I7UUFDeEIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNWLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7Z0JBQ2hELE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNqRSxJQUFJLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxVQUFVLFlBQVksa0JBQWtCLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFlBQVksQ0FBQyxJQUFJLHNCQUFzQixDQUFDLElBQUksRUFBRSxDQUFDO29CQUN0SixJQUFJLENBQUMsV0FBVyxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO29CQUMzQyxzQkFBc0IsQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDO2dCQUN6QyxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7SUFDRixDQUFDO0lBRU8sbUJBQW1CLENBQThCO0lBQ2pELG9CQUFvQjtRQUMzQixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1FBRWpELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVqQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFbkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBRXhDLElBQUksVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLElBQUksVUFBVSxZQUFZLGNBQWMsSUFBSSxVQUFVLFlBQVksZ0JBQWdCLEVBQUUsQ0FBQztvQkFDcEYsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBRXhELElBQUksVUFBVSxZQUFZLGdCQUFnQixFQUFFLENBQUM7d0JBQzVDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ2pFLENBQUM7eUJBQ0ksQ0FBQzt3QkFDTCxVQUFVLENBQUMsb0JBQW9CLENBQzlCLElBQUksRUFDSixDQUFDLEVBQ0QsVUFBVSxDQUFDLG1CQUFtQixFQUM5QixTQUFTLENBQUMsUUFBUSxFQUNsQixDQUFDLEVBQ0QsQ0FBQyxDQUNELENBQUM7b0JBQ0gsQ0FBQztvQkFFRCxRQUFRLENBQUUsVUFBVSxDQUFDLEdBQW9CLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBRXhFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNwQyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO29CQUNyQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUU3QixNQUFNLGVBQWUsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDO29CQUV6QyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FDbEIsYUFBYSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDLEVBQ2pELGFBQWEsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxFQUNqRCxhQUFhLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFDakQsYUFBYSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQ2pELENBQUM7b0JBRUYsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7d0JBQ3BCLFNBQVMsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDbEQsQ0FBQztvQkFFRCxTQUFTLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO29CQUVqRCxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQztvQkFFcEUsSUFBSSxTQUFTLENBQUMsT0FBTyxLQUFLLE9BQU8sRUFBRSxDQUFDO3dCQUNuQyxTQUFTLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQzt3QkFDNUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztvQkFDaEMsQ0FBQztvQkFFRCxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO3dCQUMxQixJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ3BDLENBQUM7Z0JBQ0YsQ0FBQztxQkFDSSxJQUFJLFVBQVUsWUFBWSxrQkFBa0IsRUFBRSxDQUFDO29CQUNuRCxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDcEMsU0FBUztnQkFDVixDQUFDO1lBQ0YsQ0FBQztZQUNELE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRU8sa0JBQWtCLENBQUUsU0FBOEI7UUFDekQsU0FBUyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFFekIsT0FBTyxDQUFDLHFCQUFxQixDQUM1QixTQUFTLENBQUMsUUFBUSxFQUNsQixTQUFTLENBQUMsT0FBTyxFQUNqQixTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFDeEIsU0FBUyxDQUFDLEdBQUcsQ0FDYixDQUFDO1FBRUYsTUFBTSxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxPQUFPLENBQUM7UUFFbEUsTUFBTSxhQUFhLEdBQUcsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDakQsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDO1FBRTdDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDNUIsU0FBUyxDQUFDLFdBQVcsR0FBRztnQkFDdkIsUUFBUSxFQUFFLElBQUksWUFBWSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7Z0JBQzdDLEdBQUcsRUFBRSxJQUFJLFlBQVksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO2dCQUN4QyxXQUFXLEVBQUUsYUFBYTtnQkFDMUIsT0FBTyxFQUFFLElBQUksV0FBVyxDQUFDLFlBQVksQ0FBQztnQkFDdEMsWUFBWTthQUNaLENBQUM7WUFFRixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDO1FBRTFDLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxXQUFXLEtBQUssYUFBYSxJQUFJLFlBQVksS0FBSyxXQUFXLENBQUMsWUFBWSxDQUFDO1FBRTFHLFNBQVMsQ0FBQyxVQUFVLEdBQUcsYUFBYSxLQUFLLENBQUMsQ0FBQztRQUUzQyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7WUFFbEMsSUFBSSxXQUFXLENBQUMsV0FBVyxHQUFHLGFBQWEsRUFBRSxDQUFDO2dCQUM3QyxnQkFBZ0I7Z0JBQ2hCLFdBQVcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxZQUFZLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMzRCxXQUFXLENBQUMsR0FBRyxHQUFHLElBQUksWUFBWSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN2RCxDQUFDO1lBRUQsSUFBSSxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxZQUFZLEVBQUUsQ0FBQztnQkFDL0MsV0FBVyxDQUFDLE9BQU8sR0FBRyxJQUFJLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNyRCxDQUFDO1FBQ0YsQ0FBQztRQUVELE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFHLFdBQVcsQ0FBQztRQUUvQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDeEMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFckQsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzVDLENBQUM7UUFFRCxXQUFXLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQztRQUV4QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDdkMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQztnQkFDbEMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7UUFDRixDQUFDO1FBRUQsV0FBVyxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGlCQUFpQjtRQUN4QixLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNuQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTVDLElBQUksQ0FBQyxjQUFjO2dCQUFFLFNBQVM7WUFFOUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7SUFDRixDQUFDO0lBRU8sZ0JBQWdCLENBQUUsY0FBb0Q7UUFDN0UsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxjQUFjLENBQUM7UUFFM0MsU0FBUyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFM0QsSUFBSSxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztZQUV2QixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVqRCxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDMUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRTFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLEdBQUcsVUFBVSxDQUFDO1lBRTNELFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUM7SUFDRixDQUFDO0lBRUQsZ0JBQWdCO0lBQ2hCLGNBQWMsQ0FBRSxJQUFVLEVBQUUsVUFBNkM7UUFDeEUsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDNUcsQ0FBQztJQUVPLGNBQWMsQ0FBRSxJQUFVLEVBQUUsVUFBNkM7UUFDaEYsSUFBSSxRQUFzQixDQUFDO1FBRTNCLElBQUksVUFBVSxZQUFZLGdCQUFnQixFQUFFLENBQUM7WUFDNUMsUUFBUSxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRS9CLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRztnQkFDNUQsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksVUFBVSxDQUFDLElBQUksRUFBRTtnQkFDM0MsUUFBUTtnQkFDUixPQUFPLEVBQUUsS0FBSztnQkFDZCxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDM0IsR0FBRyxFQUFFLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDO2dCQUM1QyxLQUFLLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QixTQUFTLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixPQUFPLEVBQUUsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTzthQUMzQyxDQUFDO1FBQ0gsQ0FBQzthQUNJLENBQUM7WUFDTCxRQUFRLEdBQUcsSUFBSSxZQUFZLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFFNUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHO2dCQUM1RCxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO2dCQUMzQyxRQUFRO2dCQUNSLE9BQU8sRUFBRSxLQUFLO2dCQUNkLE9BQU8sRUFBRSxVQUFVLENBQUMsU0FBUztnQkFDN0IsR0FBRyxFQUFFLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDO2dCQUM1QyxLQUFLLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QixTQUFTLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixPQUFPLEVBQUUsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTzthQUMzQyxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFUyxZQUFZO1FBQ3JCLCtCQUErQjtRQUMvQixJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFFekIsSUFBSSxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDL0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFFMUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFFL0QsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNqQixXQUFXLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxhQUFhLENBQUUsSUFBNEIsRUFBRSxTQUFvQjtRQUN2RSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqQywyQ0FBMkM7UUFDM0MsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbkMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEQsQ0FBQztRQUNGLENBQUM7UUFFRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUIsU0FBUyxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7UUFFakMsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFekIsTUFBTSxVQUFVLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQztRQUUvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksZ0JBQWdCLENBQUUsZUFBbUQ7UUFDM0UsSUFBSSxpQkFBd0MsQ0FBQztRQUU3QyxJQUFJLGVBQWUsWUFBWSxTQUFTLEVBQUUsQ0FBQztZQUMxQyxLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbkMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsS0FBSyxlQUFlLEVBQUUsQ0FBQztvQkFDekQsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7b0JBRTVCLGlCQUFpQixHQUFHLGVBQWUsQ0FBQztvQkFDcEMsTUFBTTtnQkFDUCxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7YUFDSSxDQUFDO1lBQ0wsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUVsRCxpQkFBaUIsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDMUMsQ0FBQztRQUVELElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFFcEMsaUJBQWlCLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUN6QyxDQUFDO0lBQ0YsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksYUFBYSxDQUFFLElBQTRCO1FBQ2pELElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsQ0FBQztJQUNyRCxDQUFDO0lBRU8sWUFBWTtRQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUUxQixJQUFJLENBQUMsY0FBYyxLQUFLLElBQUksY0FBYyxFQUFFLENBQUM7UUFFN0MsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUUzQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFM0MsSUFBSSxjQUFjLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVuQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQztZQUMxQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBRTVCLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUVmLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQzNDLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFMUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUV4QyxJQUFJLFVBQVUsSUFBSSxDQUFDLFVBQVUsWUFBWSxnQkFBZ0IsSUFBSSxVQUFVLFlBQVksY0FBYyxDQUFDLEVBQUUsQ0FBQztvQkFDcEcsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBRXhELE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDeEUsQ0FBQztZQUNGLENBQUM7UUFDRixDQUFDO2FBQ0ksQ0FBQztZQUNMLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUM7WUFDeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQztZQUN4QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDO1lBQ3hDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUM7UUFDekMsQ0FBQztJQUNGLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsU0FBUyxDQUFFLE1BQWM7UUFDeEIsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNhLE9BQU8sQ0FBRSxVQUEwQixLQUFLO1FBQ3ZELEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFdkIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBVyxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBVyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxZQUFvQixHQUFHLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBVyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxnR0FBZ0c7SUFDekYsOEJBQThCLENBQUUsS0FBK0I7UUFDckUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxnR0FBZ0c7SUFDekYsOEJBQThCLENBQUUsS0FBK0I7UUFDckUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxvR0FBb0c7SUFDN0YsMEJBQTBCLENBQUUsS0FBK0IsRUFBRSxJQUFVO1FBQzdFLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFnQixDQUFDLENBQUM7UUFDNUMsQ0FBQzthQUNJLENBQUM7WUFDTCxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQWdCLENBQUMsQ0FBQztRQUNyQyxDQUFDO0lBQ0YsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEdBQUcsSUFBSSxFQUFvQjtRQUN6RixNQUFNLFFBQVEsR0FBRyxHQUFHLFFBQVEsSUFBSSxLQUFLLElBQUksS0FBSyxFQUFFLENBQUM7UUFFakQsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDekIsT0FBTyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFlLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDckQsQ0FBQztRQUVELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQW1CLFFBQVEsQ0FBQyxDQUFDO1FBRTdELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQWUsS0FBSyxDQUFDLENBQUM7UUFDbkQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sTUFBTSxHQUFHLGFBQWEsWUFBWSxVQUFVO1lBQ2pELENBQUMsQ0FBQyxJQUFJLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQztZQUN0QyxDQUFDLENBQUMsSUFBSSxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUV0QyxNQUFNLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNyQixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFNUQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFbEMsT0FBTyxJQUFJLEtBQUssQ0FBQztZQUNoQixZQUFZO1lBQ1osUUFBUTtZQUNSLFVBQVU7U0FDVixDQUFDLENBQUM7SUFDSixDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBKdWx5IDI4LCAyMDIzLiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjMsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3JcbiAqIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSEVcbiAqIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQge1xuXHRBc3NldHMsXG5cdEJvdW5kcyxcblx0Q2FjaGUsXG5cdENvbnRhaW5lcixcblx0Q29udGFpbmVyT3B0aW9ucyxcblx0REVHX1RPX1JBRCxcblx0RGVzdHJveU9wdGlvbnMsXG5cdGZhc3RDb3B5LFxuXHRHcmFwaGljcyxcblx0UG9pbnREYXRhLFxuXHRUZXh0dXJlLFxuXHRUaWNrZXIsXG5cdFZpZXdDb250YWluZXIsXG59IGZyb20gJ3BpeGkuanMnO1xuaW1wb3J0IHsgSVNwaW5lRGVidWdSZW5kZXJlciB9IGZyb20gJy4vU3BpbmVEZWJ1Z1JlbmRlcmVyJztcbmltcG9ydCB7XG5cdEFuaW1hdGlvblN0YXRlLFxuXHRBbmltYXRpb25TdGF0ZURhdGEsXG5cdEF0bGFzQXR0YWNobWVudExvYWRlcixcblx0QXR0YWNobWVudCxcblx0Qm9uZSxcblx0Q2xpcHBpbmdBdHRhY2htZW50LFxuXHRDb2xvcixcblx0TWVzaEF0dGFjaG1lbnQsXG5cdFBoeXNpY3MsXG5cdFBvb2wsXG5cdFJlZ2lvbkF0dGFjaG1lbnQsXG5cdFNrZWxldG9uLFxuXHRTa2VsZXRvbkJpbmFyeSxcblx0U2tlbGV0b25Cb3VuZHMsXG5cdFNrZWxldG9uQ2xpcHBpbmcsXG5cdFNrZWxldG9uRGF0YSxcblx0U2tlbGV0b25Kc29uLFxuXHRTbG90LFxuXHR0eXBlIFRleHR1cmVBdGxhcyxcblx0VHJhY2tFbnRyeSxcblx0VmVjdG9yMixcbn0gZnJvbSAnQGVzb3Rlcmljc29mdHdhcmUvc3BpbmUtY29yZSc7XG5cbi8qKlxuICogT3B0aW9ucyB0byBjcmVhdGUgYSB7QGxpbmsgU3BpbmV9IHVzaW5nIHtAbGluayBTcGluZS5mcm9tfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGluZUZyb21PcHRpb25zIHtcblx0LyoqIHRoZSBhc3NldCBuYW1lIGZvciB0aGUgc2tlbGV0b24gYC5za2VsYCBvciBgLmpzb25gIGZpbGUgcHJldmlvdXNseSBsb2FkZWQgaW50byB0aGUgQXNzZXRzICovXG5cdHNrZWxldG9uOiBzdHJpbmc7XG5cblx0LyoqIHRoZSBhc3NldCBuYW1lIGZvciB0aGUgYXRsYXMgZmlsZSBwcmV2aW91c2x5IGxvYWRlZCBpbnRvIHRoZSBBc3NldHMgKi9cblx0YXRsYXM6IHN0cmluZztcblxuXHQvKiogIFRoZSB2YWx1ZSBwYXNzZWQgdG8gdGhlIHNrZWxldG9uIHJlYWRlci4gSWYgb21pdHRlZCwgMSBpcyBwYXNzZWQuIFNlZSB7QGxpbmsgU2tlbGV0b25CaW5hcnkuc2NhbGV9IGZvciBkZXRhaWxzLiAqL1xuXHRzY2FsZT86IG51bWJlcjtcblxuXHQvKiogIFNldCB0aGUge0BsaW5rIFNwaW5lLmF1dG9VcGRhdGV9IHZhbHVlLiBJZiBvbWl0dGVkLCBpdCBpcyBzZXQgdG8gYHRydWVgLiAqL1xuXHRhdXRvVXBkYXRlPzogYm9vbGVhbjtcblxuXHQvKipcblx0ICogSWYgYHRydWVgLCB1c2UgdGhlIGRhcmsgdGludCByZW5kZXJlciB0byByZW5kZXIgdGhlIHNrZWxldG9uXG5cdCAqIElmIGBmYWxzZWAsIHVzZSB0aGUgZGVmYXVsdCBwaXhpIHJlbmRlcmVyIHRvIHJlbmRlciB0aGUgc2tlbGV0b25cblx0ICogSWYgYHVuZGVmaW5lZGAsIHVzZSB0aGUgZGFyayB0aW50IHJlbmRlcmVyIGlmIGF0IGxlYXN0IG9uZSBzbG90IGhhcyB0aW50IGJsYWNrXG5cdCAqL1xuXHRkYXJrVGludD86IGJvb2xlYW47XG59O1xuXG5jb25zdCB2ZWN0b3JBdXggPSBuZXcgVmVjdG9yMigpO1xuXG5Ta2VsZXRvbi55RG93biA9IHRydWU7XG5cbmNvbnN0IGNsaXBwZXIgPSBuZXcgU2tlbGV0b25DbGlwcGluZygpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNwaW5lT3B0aW9ucyBleHRlbmRzIENvbnRhaW5lck9wdGlvbnMge1xuXHQvKiogdGhlIHtAbGluayBTa2VsZXRvbkRhdGF9IHVzZWQgdG8gaW5zdGFudGlhdGUgdGhlIHNrZWxldG9uICovXG5cdHNrZWxldG9uRGF0YTogU2tlbGV0b25EYXRhO1xuXG5cdC8qKiAgU2VlIHtAbGluayBTcGluZUZyb21PcHRpb25zLmF1dG9VcGRhdGV9LiAqL1xuXHRhdXRvVXBkYXRlPzogYm9vbGVhbjtcblxuXHQvKiogIFNlZSB7QGxpbmsgU3BpbmVGcm9tT3B0aW9ucy5kYXJrVGludH0uICovXG5cdGRhcmtUaW50PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBbmltYXRpb25TdGF0ZUxpc3RlbmVyIHtAbGluayBodHRwczovL2VuLmVzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWFwaS1yZWZlcmVuY2UjQW5pbWF0aW9uU3RhdGVMaXN0ZW5lciBldmVudHN9IGV4cG9zZWQgZm9yIFBpeGkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3BpbmVFdmVudHMge1xuXHRjb21wbGV0ZTogW3RyYWNrRW50cnk6IFRyYWNrRW50cnldO1xuXHRkaXNwb3NlOiBbdHJhY2tFbnRyeTogVHJhY2tFbnRyeV07XG5cdGVuZDogW3RyYWNrRW50cnk6IFRyYWNrRW50cnldO1xuXHRldmVudDogW3RyYWNrRW50cnk6IFRyYWNrRW50cnksIGV2ZW50OiBFdmVudF07XG5cdGludGVycnVwdDogW3RyYWNrRW50cnk6IFRyYWNrRW50cnldO1xuXHRzdGFydDogW3RyYWNrRW50cnk6IFRyYWNrRW50cnldO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dGFjaG1lbnRDYWNoZURhdGEge1xuXHRpZDogc3RyaW5nO1xuXHRjbGlwcGVkOiBib29sZWFuO1xuXHR2ZXJ0aWNlczogRmxvYXQzMkFycmF5O1xuXHR1dnM6IEZsb2F0MzJBcnJheTtcblx0aW5kaWNlczogbnVtYmVyW107XG5cdGNvbG9yOiBDb2xvcjtcblx0ZGFya0NvbG9yOiBDb2xvcjtcblx0ZGFya1RpbnQ6IGJvb2xlYW47XG5cdHNraXBSZW5kZXI6IGJvb2xlYW47XG5cdHRleHR1cmU6IFRleHR1cmU7XG5cdGNsaXBwZWREYXRhPzoge1xuXHRcdHZlcnRpY2VzOiBGbG9hdDMyQXJyYXk7XG5cdFx0dXZzOiBGbG9hdDMyQXJyYXk7XG5cdFx0aW5kaWNlczogVWludDE2QXJyYXk7XG5cdFx0dmVydGV4Q291bnQ6IG51bWJlcjtcblx0XHRpbmRpY2VzQ291bnQ6IG51bWJlcjtcblx0fTtcbn1cblxuaW50ZXJmYWNlIFNsb3RzVG9DbGlwcGluZyB7XG5cdHNsb3Q6IFNsb3QsXG5cdG1hc2s/OiBHcmFwaGljcyxcblx0bWFza0NvbXB1dGVkPzogYm9vbGVhbixcblx0dmVydGljZXM6IEFycmF5PG51bWJlcj4sXG59O1xuXG5jb25zdCBtYXNrUG9vbCA9IG5ldyBQb29sPEdyYXBoaWNzPigoKSA9PiBuZXcgR3JhcGhpY3MpO1xuXG4vKipcbiAqIFRoZSBjbGFzcyB0byBpbnN0YW50aWF0ZSBhIHtAbGluayBTcGluZX0gZ2FtZSBvYmplY3QgaW4gUGl4aS5cbiAqIFRoZSBzdGF0aWMgbWV0aG9kIHtAbGluayBTcGluZS5mcm9tfSBzaG91bGQgYmUgdXNlZCB0byBpbnN0YW50aWF0ZSBhIFNwaW5lIGdhbWUgb2JqZWN0LlxuICovXG5leHBvcnQgY2xhc3MgU3BpbmUgZXh0ZW5kcyBWaWV3Q29udGFpbmVyIHtcblx0Ly8gUGl4aSBwcm9wZXJ0aWVzXG5cdHB1YmxpYyBiYXRjaGVkID0gdHJ1ZTtcblx0cHVibGljIGJ1aWxkSWQgPSAwO1xuXHRwdWJsaWMgb3ZlcnJpZGUgcmVhZG9ubHkgcmVuZGVyUGlwZUlkID0gJ3NwaW5lJztcblx0cHVibGljIF9kaWRTcGluZVVwZGF0ZSA9IGZhbHNlO1xuXG5cdHB1YmxpYyBiZWZvcmVVcGRhdGVXb3JsZFRyYW5zZm9ybXM6IChvYmplY3Q6IFNwaW5lKSA9PiB2b2lkID0gKCkgPT4geyAvKiogKi8gfTtcblx0cHVibGljIGFmdGVyVXBkYXRlV29ybGRUcmFuc2Zvcm1zOiAob2JqZWN0OiBTcGluZSkgPT4gdm9pZCA9ICgpID0+IHsgLyoqICovIH07XG5cblx0Ly8gU3BpbmUgcHJvcGVydGllc1xuXHQvKiogVGhlIHNrZWxldG9uIGZvciB0aGlzIFNwaW5lIGdhbWUgb2JqZWN0LiAqL1xuXHRwdWJsaWMgc2tlbGV0b246IFNrZWxldG9uO1xuXHQvKiogVGhlIGFuaW1hdGlvbiBzdGF0ZSBmb3IgdGhpcyBTcGluZSBnYW1lIG9iamVjdC4gKi9cblx0cHVibGljIHN0YXRlOiBBbmltYXRpb25TdGF0ZTtcblx0cHVibGljIHNrZWxldG9uQm91bmRzPzogU2tlbGV0b25Cb3VuZHM7XG5cblx0cHJpdmF0ZSBkYXJrVGludCA9IGZhbHNlO1xuXHRwcml2YXRlIF9kZWJ1Zz86IElTcGluZURlYnVnUmVuZGVyZXIgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cblx0cmVhZG9ubHkgX3Nsb3RzT2JqZWN0OiBSZWNvcmQ8c3RyaW5nLCB7IHNsb3Q6IFNsb3QsIGNvbnRhaW5lcjogQ29udGFpbmVyIH0gfCBudWxsPiA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cdHByaXZhdGUgY2xpcHBpbmdTbG90VG9QaXhpTWFza3M6IFJlY29yZDxzdHJpbmcsIFNsb3RzVG9DbGlwcGluZz4gPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG5cdHByaXZhdGUgZ2V0U2xvdEZyb21SZWYgKHNsb3RSZWY6IG51bWJlciB8IHN0cmluZyB8IFNsb3QpOiBTbG90IHtcblx0XHRsZXQgc2xvdDogU2xvdCB8IG51bGw7XG5cblx0XHRpZiAodHlwZW9mIHNsb3RSZWYgPT09ICdudW1iZXInKSBzbG90ID0gdGhpcy5za2VsZXRvbi5zbG90c1tzbG90UmVmXTtcblx0XHRlbHNlIGlmICh0eXBlb2Ygc2xvdFJlZiA9PT0gJ3N0cmluZycpIHNsb3QgPSB0aGlzLnNrZWxldG9uLmZpbmRTbG90KHNsb3RSZWYpO1xuXHRcdGVsc2Ugc2xvdCA9IHNsb3RSZWY7XG5cblx0XHRpZiAoIXNsb3QpIHRocm93IG5ldyBFcnJvcihgTm8gc2xvdCBmb3VuZCB3aXRoIHRoZSBnaXZlbiBzbG90IHJlZmVyZW5jZTogJHtzbG90UmVmfWApO1xuXG5cdFx0cmV0dXJuIHNsb3Q7XG5cdH1cblxuXHRwdWJsaWMgc3BpbmVBdHRhY2htZW50c0RpcnR5ID0gdHJ1ZTtcblx0cHVibGljIHNwaW5lVGV4dHVyZXNEaXJ0eSA9IHRydWU7XG5cblx0cHJpdmF0ZSBfbGFzdEF0dGFjaG1lbnRzOiBBdHRhY2htZW50W10gPSBbXTtcblxuXHRwcml2YXRlIF9zdGF0ZUNoYW5nZWQgPSB0cnVlO1xuXHRwcml2YXRlIGF0dGFjaG1lbnRDYWNoZURhdGE6IFJlY29yZDxzdHJpbmcsIEF0dGFjaG1lbnRDYWNoZURhdGE+W10gPSBbXTtcblxuXHRwdWJsaWMgZ2V0IGRlYnVnICgpOiBJU3BpbmVEZWJ1Z1JlbmRlcmVyIHwgdW5kZWZpbmVkIHtcblx0XHRyZXR1cm4gdGhpcy5fZGVidWc7XG5cdH1cblxuXHQvKiogUGFzcyBhIHtAbGluayBTcGluZURlYnVnUmVuZGVyZXJ9IG9yIGNyZWF0ZSB5b3VyIG93biB7QGxpbmsgSVNwaW5lRGVidWdSZW5kZXJlcn0gdG8gcmVuZGVyIGJvbmVzLCBtZXNoZXMsIC4uLlxuXHQgKiBAZXhhbXBsZSBzcGluZUdPLmRlYnVnID0gbmV3IFNwaW5lRGVidWdSZW5kZXJlcigpO1xuXHQgKi9cblx0cHVibGljIHNldCBkZWJ1ZyAodmFsdWU6IElTcGluZURlYnVnUmVuZGVyZXIgfCB1bmRlZmluZWQpIHtcblx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdHRoaXMuX2RlYnVnLnVucmVnaXN0ZXJTcGluZSh0aGlzKTtcblx0XHR9XG5cdFx0aWYgKHZhbHVlKSB7XG5cdFx0XHR2YWx1ZS5yZWdpc3RlclNwaW5lKHRoaXMpO1xuXHRcdH1cblx0XHR0aGlzLl9kZWJ1ZyA9IHZhbHVlO1xuXHR9XG5cblx0cHJpdmF0ZSBhdXRvVXBkYXRlV2FybmVkID0gZmFsc2U7XG5cdHByaXZhdGUgX2F1dG9VcGRhdGUgPSB0cnVlO1xuXG5cdHB1YmxpYyBnZXQgYXV0b1VwZGF0ZSAoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX2F1dG9VcGRhdGU7XG5cdH1cblx0LyoqIFdoZW4gYHRydWVgLCB0aGUgU3BpbmUgQW5pbWF0aW9uU3RhdGUgYW5kIHRoZSBTa2VsZXRvbiB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXBkYXRlZCB1c2luZyB0aGUge0BsaW5rIFRpY2tlci5zaGFyZWR9IGluc3RhbmNlLiAqL1xuXHRwdWJsaWMgc2V0IGF1dG9VcGRhdGUgKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0aWYgKHZhbHVlKSB7XG5cdFx0XHRUaWNrZXIuc2hhcmVkLmFkZCh0aGlzLmludGVybmFsVXBkYXRlLCB0aGlzKTtcblx0XHRcdHRoaXMuYXV0b1VwZGF0ZVdhcm5lZCA9IGZhbHNlO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdFRpY2tlci5zaGFyZWQucmVtb3ZlKHRoaXMuaW50ZXJuYWxVcGRhdGUsIHRoaXMpO1xuXHRcdH1cblxuXHRcdHRoaXMuX2F1dG9VcGRhdGUgPSB2YWx1ZTtcblx0fVxuXG5cdGNvbnN0cnVjdG9yIChvcHRpb25zOiBTcGluZU9wdGlvbnMgfCBTa2VsZXRvbkRhdGEpIHtcblx0XHRpZiAob3B0aW9ucyBpbnN0YW5jZW9mIFNrZWxldG9uRGF0YSkge1xuXHRcdFx0b3B0aW9ucyA9IHtcblx0XHRcdFx0c2tlbGV0b25EYXRhOiBvcHRpb25zLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRzdXBlcigpO1xuXG5cdFx0Y29uc3Qgc2tlbGV0b25EYXRhID0gb3B0aW9ucyBpbnN0YW5jZW9mIFNrZWxldG9uRGF0YSA/IG9wdGlvbnMgOiBvcHRpb25zLnNrZWxldG9uRGF0YTtcblxuXHRcdHRoaXMuc2tlbGV0b24gPSBuZXcgU2tlbGV0b24oc2tlbGV0b25EYXRhKTtcblx0XHR0aGlzLnN0YXRlID0gbmV3IEFuaW1hdGlvblN0YXRlKG5ldyBBbmltYXRpb25TdGF0ZURhdGEoc2tlbGV0b25EYXRhKSk7XG5cdFx0dGhpcy5hdXRvVXBkYXRlID0gb3B0aW9ucz8uYXV0b1VwZGF0ZSA/PyB0cnVlO1xuXG5cdFx0Ly8gZGFyayB0aW50IGNhbiBiZSBlbmFibGVkIGJ5IG9wdGlvbnMsIG90aGVyd2lzZSBpcyBlbmFibGUgaWYgYXQgbGVhc3Qgb25lIHNsb3QgaGFzIHRpbnQgYmxhY2tcblx0XHR0aGlzLmRhcmtUaW50ID0gb3B0aW9ucz8uZGFya1RpbnQgPT09IHVuZGVmaW5lZFxuXHRcdFx0PyB0aGlzLnNrZWxldG9uLnNsb3RzLnNvbWUoc2xvdCA9PiAhIXNsb3QuZGF0YS5kYXJrQ29sb3IpXG5cdFx0XHQ6IG9wdGlvbnM/LmRhcmtUaW50O1xuXG5cdFx0Y29uc3Qgc2xvdHMgPSB0aGlzLnNrZWxldG9uLnNsb3RzO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzbG90cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5hdHRhY2htZW50Q2FjaGVEYXRhW2ldID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0XHR9XG5cblx0XHR0aGlzLl91cGRhdGVTdGF0ZSgwKTtcblx0fVxuXG5cdC8qKiBJZiB7QGxpbmsgU3BpbmUuYXV0b1VwZGF0ZX0gaXMgYGZhbHNlYCwgdGhpcyBtZXRob2QgYWxsb3dzIHRvIHVwZGF0ZSB0aGUgQW5pbWF0aW9uU3RhdGUgYW5kIHRoZSBTa2VsZXRvbiB3aXRoIHRoZSBnaXZlbiBkZWx0YS4gKi9cblx0cHVibGljIHVwZGF0ZSAoZHQ6IG51bWJlcik6IHZvaWQge1xuXHRcdGlmICh0aGlzLmF1dG9VcGRhdGUgJiYgIXRoaXMuYXV0b1VwZGF0ZVdhcm5lZCkge1xuXHRcdFx0Y29uc29sZS53YXJuKCdZb3UgYXJlIGNhbGxpbmcgdXBkYXRlIG9uIGEgU3BpbmUgaW5zdGFuY2UgdGhhdCBoYXMgYXV0b1VwZGF0ZSBzZXQgdG8gdHJ1ZS4gVGhpcyBpcyBwcm9iYWJseSBub3Qgd2hhdCB5b3Ugd2FudC4nKTtcblx0XHRcdHRoaXMuYXV0b1VwZGF0ZVdhcm5lZCA9IHRydWU7XG5cdFx0fVxuXG5cdFx0dGhpcy5pbnRlcm5hbFVwZGF0ZSgwLCBkdCk7XG5cdH1cblxuXHRwcm90ZWN0ZWQgaW50ZXJuYWxVcGRhdGUgKF9kZWx0YUZyYW1lOiBhbnksIGRlbHRhU2Vjb25kcz86IG51bWJlcik6IHZvaWQge1xuXHRcdC8vIEJlY2F1c2UgcmVhc29ucywgcGl4aSB1c2VzIGRlbHRhRnJhbWVzIGF0IDYwZnBzLlxuXHRcdC8vIFdlIGlnbm9yZSB0aGUgZGVmYXVsdCBkZWx0YUZyYW1lcyBhbmQgdXNlIHRoZSBkZWx0YVNlY29uZHMgZnJvbSBwaXhpIHRpY2tlci5cblx0XHR0aGlzLl91cGRhdGVTdGF0ZShkZWx0YVNlY29uZHMgPz8gVGlja2VyLnNoYXJlZC5kZWx0YU1TIC8gMTAwMCk7XG5cdH1cblxuXHRnZXQgYm91bmRzICgpIHtcblx0XHRpZiAodGhpcy5fYm91bmRzRGlydHkpIHtcblx0XHRcdHRoaXMudXBkYXRlQm91bmRzKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuX2JvdW5kcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBib25lIGdpdmVuIGluIGlucHV0IHRocm91Z2ggYSB7QGxpbmsgSVBvaW50RGF0YX0uXG5cdCAqIEBwYXJhbSBib25lOiB0aGUgYm9uZSBuYW1lIG9yIHRoZSBib25lIGluc3RhbmNlIHRvIHNldCB0aGUgcG9zaXRpb25cblx0ICogQHBhcmFtIG91dFBvczogdGhlIG5ldyBwb3NpdGlvbiBvZiB0aGUgYm9uZS5cblx0ICogQHRocm93cyB7RXJyb3J9OiBpZiB0aGUgZ2l2ZW4gYm9uZSBpcyBub3QgZm91bmQgaW4gdGhlIHNrZWxldG9uLCBhbiBlcnJvciBpcyB0aHJvd25cblx0ICovXG5cdHB1YmxpYyBzZXRCb25lUG9zaXRpb24gKGJvbmU6IHN0cmluZyB8IEJvbmUsIHBvc2l0aW9uOiBQb2ludERhdGEpOiB2b2lkIHtcblx0XHRjb25zdCBib25lQXV4ID0gYm9uZTtcblxuXHRcdGlmICh0eXBlb2YgYm9uZSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdGJvbmUgPSB0aGlzLnNrZWxldG9uLmZpbmRCb25lKGJvbmUpIGFzIEJvbmU7XG5cdFx0fVxuXG5cdFx0aWYgKCFib25lKSB0aHJvdyBFcnJvcihgQ2FudCBzZXQgYm9uZSBwb3NpdGlvbiwgYm9uZSAke1N0cmluZyhib25lQXV4KX0gbm90IGZvdW5kYCk7XG5cdFx0dmVjdG9yQXV4LnNldChwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcblxuXHRcdGlmIChib25lLnBhcmVudCkge1xuXHRcdFx0Y29uc3QgYXV4ID0gYm9uZS5wYXJlbnQud29ybGRUb0xvY2FsKHZlY3RvckF1eCk7XG5cblx0XHRcdGJvbmUueCA9IGF1eC54O1xuXHRcdFx0Ym9uZS55ID0gLWF1eC55O1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGJvbmUueCA9IHZlY3RvckF1eC54O1xuXHRcdFx0Ym9uZS55ID0gdmVjdG9yQXV4Lnk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGJvbmUgZ2l2ZW4gaW4gaW5wdXQgaW50byBhbiB7QGxpbmsgSVBvaW50RGF0YX0uXG5cdCAqIEBwYXJhbSBib25lOiB0aGUgYm9uZSBuYW1lIG9yIHRoZSBib25lIGluc3RhbmNlIHRvIGdldCB0aGUgcG9zaXRpb24gZnJvbVxuXHQgKiBAcGFyYW0gb3V0UG9zOiBhbiBvcHRpb25hbCB7QGxpbmsgSVBvaW50RGF0YX0gdG8gdXNlIHRvIHJldHVybiB0aGUgYm9uZSBwb3NpdGlvbiwgcmF0aGVybiB0aGFuIGluc3RhbnRpYXRpbmcgYSBuZXcgb2JqZWN0LlxuXHQgKiBAcmV0dXJucyB7SVBvaW50RGF0YSB8IHVuZGVmaW5lZH06IHRoZSBwb3NpdGlvbiBvZiB0aGUgYm9uZSwgb3IgdW5kZWZpbmVkIGlmIG5vIG1hdGNoaW5nIGJvbmUgaXMgZm91bmQgaW4gdGhlIHNrZWxldG9uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0Qm9uZVBvc2l0aW9uIChib25lOiBzdHJpbmcgfCBCb25lLCBvdXRQb3M/OiBQb2ludERhdGEpOiBQb2ludERhdGEgfCB1bmRlZmluZWQge1xuXHRcdGNvbnN0IGJvbmVBdXggPSBib25lO1xuXG5cdFx0aWYgKHR5cGVvZiBib25lID09PSAnc3RyaW5nJykge1xuXHRcdFx0Ym9uZSA9IHRoaXMuc2tlbGV0b24uZmluZEJvbmUoYm9uZSkgYXMgQm9uZTtcblx0XHR9XG5cblx0XHRpZiAoIWJvbmUpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoYENhbnQgc2V0IGJvbmUgcG9zaXRpb24hIEJvbmUgJHtTdHJpbmcoYm9uZUF1eCl9IG5vdCBmb3VuZGApO1xuXG5cdFx0XHRyZXR1cm4gb3V0UG9zO1xuXHRcdH1cblxuXHRcdGlmICghb3V0UG9zKSB7XG5cdFx0XHRvdXRQb3MgPSB7IHg6IDAsIHk6IDAgfTtcblx0XHR9XG5cblx0XHRvdXRQb3MueCA9IGJvbmUud29ybGRYO1xuXHRcdG91dFBvcy55ID0gYm9uZS53b3JsZFk7XG5cblx0XHRyZXR1cm4gb3V0UG9zO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdpbGwgdXBkYXRlIHRoZSBzdGF0ZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIHRpbWUsIHRoaXMgd2lsbCBub3QgYXBwbHkgdGhlIHN0YXRlIHRvIHRoZSBza2VsZXRvblxuXHQgKiBhcyB0aGlzIGlzIGRpZmZlcmVkIHVudGlsIHRoZSBgYXBwbHlTdGF0ZWAgbWV0aG9kIGlzIGNhbGxlZC5cblx0ICpcblx0ICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgYXQgd2hpY2ggdG8gc2V0IHRoZSBzdGF0ZVxuXHQgKiBAaW50ZXJuYWxcblx0ICovXG5cdF91cGRhdGVTdGF0ZSAodGltZTogbnVtYmVyKSB7XG5cdFx0dGhpcy5zdGF0ZS51cGRhdGUodGltZSk7XG5cdFx0dGhpcy5za2VsZXRvbi51cGRhdGUodGltZSk7XG5cblx0XHR0aGlzLl9zdGF0ZUNoYW5nZWQgPSB0cnVlO1xuXG5cdFx0dGhpcy5fYm91bmRzRGlydHkgPSB0cnVlO1xuXG5cdFx0dGhpcy5vblZpZXdVcGRhdGUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBcHBsaWVzIHRoZSBzdGF0ZSB0byB0aGlzIHNwaW5lIGluc3RhbmNlLlxuXHQgKiAtIHVwZGF0ZXMgdGhlIHN0YXRlIHRvIHRoZSBza2VsZXRvblxuXHQgKiAtIHVwZGF0ZXMgaXRzIHdvcmxkIHRyYW5zZm9ybSAoc3BpbmUgd29ybGQgdHJhbnNmb3JtKVxuXHQgKiAtIHZhbGlkYXRlcyB0aGUgYXR0YWNobWVudHMgLSB0byBmbGFnIGlmIHRoZSBhdHRhY2htZW50cyBoYXZlIGNoYW5nZWQgdGhpcyBzdGF0ZVxuXHQgKiAtIHRyYW5zZm9ybXMgdGhlIGF0dGFjaG1lbnRzIC0gdG8gdXBkYXRlIHRoZSB2ZXJ0aWNlcyBvZiB0aGUgYXR0YWNobWVudHMgYmFzZWQgb24gdGhlIG5ldyBwb3NpdGlvbnNcblx0ICogLSB1cGRhdGUgdGhlIHNsb3QgYXR0YWNobWVudHMgLSB0byB1cGRhdGUgdGhlIHBvc2l0aW9uLCByb3RhdGlvbiwgc2NhbGUsIGFuZCB2aXNpYmlsaXR5IG9mIHRoZSBhdHRhY2hlZCBjb250YWluZXJzXG5cdCAqIEBpbnRlcm5hbFxuXHQgKi9cblx0X2FwcGx5U3RhdGUgKCkge1xuXHRcdGlmICghdGhpcy5fc3RhdGVDaGFuZ2VkKSByZXR1cm47XG5cdFx0dGhpcy5fc3RhdGVDaGFuZ2VkID0gZmFsc2U7XG5cblx0XHRjb25zdCB7IHNrZWxldG9uIH0gPSB0aGlzO1xuXG5cdFx0dGhpcy5zdGF0ZS5hcHBseShza2VsZXRvbik7XG5cblx0XHR0aGlzLmJlZm9yZVVwZGF0ZVdvcmxkVHJhbnNmb3Jtcyh0aGlzKTtcblx0XHRza2VsZXRvbi51cGRhdGVXb3JsZFRyYW5zZm9ybShQaHlzaWNzLnVwZGF0ZSk7XG5cdFx0dGhpcy5hZnRlclVwZGF0ZVdvcmxkVHJhbnNmb3Jtcyh0aGlzKTtcblxuXHRcdHRoaXMudmFsaWRhdGVBdHRhY2htZW50cygpO1xuXG5cdFx0dGhpcy50cmFuc2Zvcm1BdHRhY2htZW50cygpO1xuXG5cdFx0dGhpcy51cGRhdGVTbG90T2JqZWN0cygpO1xuXHR9XG5cblx0cHJpdmF0ZSB2YWxpZGF0ZUF0dGFjaG1lbnRzICgpIHtcblx0XHRjb25zdCBjdXJyZW50RHJhd09yZGVyID0gdGhpcy5za2VsZXRvbi5kcmF3T3JkZXI7XG5cblx0XHRjb25zdCBsYXN0QXR0YWNobWVudHMgPSB0aGlzLl9sYXN0QXR0YWNobWVudHM7XG5cblx0XHRsZXQgaW5kZXggPSAwO1xuXG5cdFx0bGV0IHNwaW5lQXR0YWNobWVudHNEaXJ0eSA9IGZhbHNlO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjdXJyZW50RHJhd09yZGVyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBzbG90ID0gY3VycmVudERyYXdPcmRlcltpXTtcblx0XHRcdGNvbnN0IGF0dGFjaG1lbnQgPSBzbG90LmdldEF0dGFjaG1lbnQoKTtcblxuXHRcdFx0aWYgKGF0dGFjaG1lbnQpIHtcblx0XHRcdFx0aWYgKGF0dGFjaG1lbnQgIT09IGxhc3RBdHRhY2htZW50c1tpbmRleF0pIHtcblx0XHRcdFx0XHRzcGluZUF0dGFjaG1lbnRzRGlydHkgPSB0cnVlO1xuXHRcdFx0XHRcdGxhc3RBdHRhY2htZW50c1tpbmRleF0gPSBhdHRhY2htZW50O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aW5kZXgrKztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaW5kZXggIT09IGxhc3RBdHRhY2htZW50cy5sZW5ndGgpIHtcblx0XHRcdHNwaW5lQXR0YWNobWVudHNEaXJ0eSA9IHRydWU7XG5cdFx0XHRsYXN0QXR0YWNobWVudHMubGVuZ3RoID0gaW5kZXg7XG5cdFx0fVxuXG5cdFx0dGhpcy5zcGluZUF0dGFjaG1lbnRzRGlydHkgPSBzcGluZUF0dGFjaG1lbnRzRGlydHk7XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZUFuZFNldFBpeGlNYXNrIChzbG90OiBTbG90LCBsYXN0OiBib29sZWFuKSB7XG5cdFx0Ly8gYXNzaWduL2NyZWF0ZSB0aGUgY3VycmVudENsaXBwaW5nU2xvdFxuXHRcdGNvbnN0IGF0dGFjaG1lbnQgPSBzbG90LmF0dGFjaG1lbnQ7XG5cdFx0aWYgKGF0dGFjaG1lbnQgJiYgYXR0YWNobWVudCBpbnN0YW5jZW9mIENsaXBwaW5nQXR0YWNobWVudCkge1xuXHRcdFx0Y29uc3QgY2xpcCA9ICh0aGlzLmNsaXBwaW5nU2xvdFRvUGl4aU1hc2tzW3Nsb3QuZGF0YS5uYW1lXSB8fD0geyBzbG90LCB2ZXJ0aWNlczogbmV3IEFycmF5PG51bWJlcj4oKSB9KTtcblx0XHRcdGNsaXAubWFza0NvbXB1dGVkID0gZmFsc2U7XG5cdFx0XHR0aGlzLmN1cnJlbnRDbGlwcGluZ1Nsb3QgPSB0aGlzLmNsaXBwaW5nU2xvdFRvUGl4aU1hc2tzW3Nsb3QuZGF0YS5uYW1lXTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBhc3NpZ24gdGhlIGN1cnJlbnRDbGlwcGluZ1Nsb3QgbWFzayB0byB0aGUgc2xvdCBvYmplY3Rcblx0XHRsZXQgY3VycmVudENsaXBwaW5nU2xvdCA9IHRoaXMuY3VycmVudENsaXBwaW5nU2xvdDtcblx0XHRsZXQgc2xvdE9iamVjdCA9IHRoaXMuX3Nsb3RzT2JqZWN0W3Nsb3QuZGF0YS5uYW1lXTtcblx0XHRpZiAoY3VycmVudENsaXBwaW5nU2xvdCAmJiBzbG90T2JqZWN0KSB7XG5cdFx0XHRsZXQgc2xvdENsaXBwaW5nID0gY3VycmVudENsaXBwaW5nU2xvdC5zbG90O1xuXHRcdFx0bGV0IGNsaXBwaW5nQXR0YWNobWVudCA9IHNsb3RDbGlwcGluZy5hdHRhY2htZW50IGFzIENsaXBwaW5nQXR0YWNobWVudDtcblxuXHRcdFx0Ly8gY3JlYXRlIHRoZSBwaXhpIG1hc2ssIG9ubHkgdGhlIGZpcnN0IHRpbWUgYW5kIGlmIHRoZSBjbGlwcGVkIHNsb3QgaXMgdGhlIGZpcnN0IG9uZSBjbGlwcGVkIGJ5IHRoaXMgY3VycmVudENsaXBwaW5nU2xvdFxuXHRcdFx0bGV0IG1hc2sgPSBjdXJyZW50Q2xpcHBpbmdTbG90Lm1hc2sgYXMgR3JhcGhpY3M7XG5cdFx0XHRpZiAoIW1hc2spIHtcblx0XHRcdFx0bWFzayA9IG1hc2tQb29sLm9idGFpbigpO1xuXHRcdFx0XHRjdXJyZW50Q2xpcHBpbmdTbG90Lm1hc2sgPSBtYXNrO1xuXHRcdFx0XHR0aGlzLmFkZENoaWxkKG1hc2spO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBjb21wdXRlIHRoZSBwaXhpIG1hc2sgcG9seWdvbiwgaWYgdGhlIGNsaXBwZWQgc2xvdCBpcyB0aGUgZmlyc3Qgb25lIGNsaXBwZWQgYnkgdGhpcyBjdXJyZW50Q2xpcHBpbmdTbG90XG5cdFx0XHRpZiAoIWN1cnJlbnRDbGlwcGluZ1Nsb3QubWFza0NvbXB1dGVkKSB7XG5cdFx0XHRcdGN1cnJlbnRDbGlwcGluZ1Nsb3QubWFza0NvbXB1dGVkID0gdHJ1ZTtcblx0XHRcdFx0Y29uc3Qgd29ybGRWZXJ0aWNlc0xlbmd0aCA9IGNsaXBwaW5nQXR0YWNobWVudC53b3JsZFZlcnRpY2VzTGVuZ3RoO1xuXHRcdFx0XHRjb25zdCB2ZXJ0aWNlcyA9IGN1cnJlbnRDbGlwcGluZ1Nsb3QudmVydGljZXM7XG5cdFx0XHRcdGNsaXBwaW5nQXR0YWNobWVudC5jb21wdXRlV29ybGRWZXJ0aWNlcyhzbG90Q2xpcHBpbmcsIDAsIHdvcmxkVmVydGljZXNMZW5ndGgsIHZlcnRpY2VzLCAwLCAyKTtcblx0XHRcdFx0bWFzay5jbGVhcigpLnBvbHkodmVydGljZXMpLnN0cm9rZSh7IHdpZHRoOiAwIH0pLmZpbGwoeyBhbHBoYTogLjI1IH0pO1xuXHRcdFx0fVxuXHRcdFx0c2xvdE9iamVjdC5jb250YWluZXIubWFzayA9IG1hc2s7XG5cdFx0fSBlbHNlIGlmIChzbG90T2JqZWN0Py5jb250YWluZXIubWFzaykge1xuXHRcdFx0Ly8gcmVtb3ZlIHRoZSBtYXNrLCBpZiBzbG90IG9iamVjdCBoYXMgYSBtYXNrLCBidXQgY3VycmVudENsaXBwaW5nU2xvdCBpcyB1bmRlZmluZWRcblx0XHRcdHNsb3RPYmplY3QuY29udGFpbmVyLm1hc2sgPSBudWxsO1xuXHRcdH1cblxuXHRcdC8vIGlmIGN1cnJlbnQgc2xvdCBpcyB0aGUgZW5kaW5nIG9uZSBvZiB0aGUgY3VycmVudENsaXBwaW5nU2xvdCBtYXNrLCBzZXQgY3VycmVudENsaXBwaW5nU2xvdCB0byB1bmRlZmluZWRcblx0XHRpZiAoY3VycmVudENsaXBwaW5nU2xvdCAmJiAoY3VycmVudENsaXBwaW5nU2xvdC5zbG90LmF0dGFjaG1lbnQgYXMgQ2xpcHBpbmdBdHRhY2htZW50KS5lbmRTbG90ID09IHNsb3QuZGF0YSkge1xuXHRcdFx0dGhpcy5jdXJyZW50Q2xpcHBpbmdTbG90ID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIGNsZWFuIHVwIHVudXNlZCBtYXNrc1xuXHRcdGlmIChsYXN0KSB7XG5cdFx0XHRmb3IgKGNvbnN0IGtleSBpbiB0aGlzLmNsaXBwaW5nU2xvdFRvUGl4aU1hc2tzKSB7XG5cdFx0XHRcdGNvbnN0IGNsaXBwaW5nU2xvdFRvUGl4aU1hc2sgPSB0aGlzLmNsaXBwaW5nU2xvdFRvUGl4aU1hc2tzW2tleV07XG5cdFx0XHRcdGlmICgoIShjbGlwcGluZ1Nsb3RUb1BpeGlNYXNrLnNsb3QuYXR0YWNobWVudCBpbnN0YW5jZW9mIENsaXBwaW5nQXR0YWNobWVudCkgfHwgIWNsaXBwaW5nU2xvdFRvUGl4aU1hc2subWFza0NvbXB1dGVkKSAmJiBjbGlwcGluZ1Nsb3RUb1BpeGlNYXNrLm1hc2spIHtcblx0XHRcdFx0XHR0aGlzLnJlbW92ZUNoaWxkKGNsaXBwaW5nU2xvdFRvUGl4aU1hc2subWFzayk7XG5cdFx0XHRcdFx0bWFza1Bvb2wuZnJlZShjbGlwcGluZ1Nsb3RUb1BpeGlNYXNrLm1hc2spO1xuXHRcdFx0XHRcdGNsaXBwaW5nU2xvdFRvUGl4aU1hc2subWFzayA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgY3VycmVudENsaXBwaW5nU2xvdDogU2xvdHNUb0NsaXBwaW5nIHwgdW5kZWZpbmVkO1xuXHRwcml2YXRlIHRyYW5zZm9ybUF0dGFjaG1lbnRzICgpIHtcblx0XHRjb25zdCBjdXJyZW50RHJhd09yZGVyID0gdGhpcy5za2VsZXRvbi5kcmF3T3JkZXI7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnREcmF3T3JkZXIubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IHNsb3QgPSBjdXJyZW50RHJhd09yZGVyW2ldO1xuXG5cdFx0XHR0aGlzLnVwZGF0ZUFuZFNldFBpeGlNYXNrKHNsb3QsIGkgPT09IGN1cnJlbnREcmF3T3JkZXIubGVuZ3RoIC0gMSk7XG5cblx0XHRcdGNvbnN0IGF0dGFjaG1lbnQgPSBzbG90LmdldEF0dGFjaG1lbnQoKTtcblxuXHRcdFx0aWYgKGF0dGFjaG1lbnQpIHtcblx0XHRcdFx0aWYgKGF0dGFjaG1lbnQgaW5zdGFuY2VvZiBNZXNoQXR0YWNobWVudCB8fCBhdHRhY2htZW50IGluc3RhbmNlb2YgUmVnaW9uQXR0YWNobWVudCkge1xuXHRcdFx0XHRcdGNvbnN0IGNhY2hlRGF0YSA9IHRoaXMuX2dldENhY2hlZERhdGEoc2xvdCwgYXR0YWNobWVudCk7XG5cblx0XHRcdFx0XHRpZiAoYXR0YWNobWVudCBpbnN0YW5jZW9mIFJlZ2lvbkF0dGFjaG1lbnQpIHtcblx0XHRcdFx0XHRcdGF0dGFjaG1lbnQuY29tcHV0ZVdvcmxkVmVydGljZXMoc2xvdCwgY2FjaGVEYXRhLnZlcnRpY2VzLCAwLCAyKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRhdHRhY2htZW50LmNvbXB1dGVXb3JsZFZlcnRpY2VzKFxuXHRcdFx0XHRcdFx0XHRzbG90LFxuXHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHRhdHRhY2htZW50LndvcmxkVmVydGljZXNMZW5ndGgsXG5cdFx0XHRcdFx0XHRcdGNhY2hlRGF0YS52ZXJ0aWNlcyxcblx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0Mixcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZmFzdENvcHkoKGF0dGFjaG1lbnQudXZzIGFzIEZsb2F0MzJBcnJheSkuYnVmZmVyLCBjYWNoZURhdGEudXZzLmJ1ZmZlcik7XG5cblx0XHRcdFx0XHRjb25zdCBza2VsZXRvbiA9IHNsb3QuYm9uZS5za2VsZXRvbjtcblx0XHRcdFx0XHRjb25zdCBza2VsZXRvbkNvbG9yID0gc2tlbGV0b24uY29sb3I7XG5cdFx0XHRcdFx0Y29uc3Qgc2xvdENvbG9yID0gc2xvdC5jb2xvcjtcblxuXHRcdFx0XHRcdGNvbnN0IGF0dGFjaG1lbnRDb2xvciA9IGF0dGFjaG1lbnQuY29sb3I7XG5cblx0XHRcdFx0XHRjYWNoZURhdGEuY29sb3Iuc2V0KFxuXHRcdFx0XHRcdFx0c2tlbGV0b25Db2xvci5yICogc2xvdENvbG9yLnIgKiBhdHRhY2htZW50Q29sb3Iucixcblx0XHRcdFx0XHRcdHNrZWxldG9uQ29sb3IuZyAqIHNsb3RDb2xvci5nICogYXR0YWNobWVudENvbG9yLmcsXG5cdFx0XHRcdFx0XHRza2VsZXRvbkNvbG9yLmIgKiBzbG90Q29sb3IuYiAqIGF0dGFjaG1lbnRDb2xvci5iLFxuXHRcdFx0XHRcdFx0c2tlbGV0b25Db2xvci5hICogc2xvdENvbG9yLmEgKiBhdHRhY2htZW50Q29sb3IuYSxcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0aWYgKHNsb3QuZGFya0NvbG9yKSB7XG5cdFx0XHRcdFx0XHRjYWNoZURhdGEuZGFya0NvbG9yLnNldEZyb21Db2xvcihzbG90LmRhcmtDb2xvcik7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y2FjaGVEYXRhLnNraXBSZW5kZXIgPSBjYWNoZURhdGEuY2xpcHBlZCA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0Y29uc3QgdGV4dHVyZSA9IGF0dGFjaG1lbnQucmVnaW9uPy50ZXh0dXJlLnRleHR1cmUgfHwgVGV4dHVyZS5FTVBUWTtcblxuXHRcdFx0XHRcdGlmIChjYWNoZURhdGEudGV4dHVyZSAhPT0gdGV4dHVyZSkge1xuXHRcdFx0XHRcdFx0Y2FjaGVEYXRhLnRleHR1cmUgPSB0ZXh0dXJlO1xuXHRcdFx0XHRcdFx0dGhpcy5zcGluZVRleHR1cmVzRGlydHkgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmIChjbGlwcGVyLmlzQ2xpcHBpbmcoKSkge1xuXHRcdFx0XHRcdFx0dGhpcy51cGRhdGVDbGlwcGluZ0RhdGEoY2FjaGVEYXRhKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSBpZiAoYXR0YWNobWVudCBpbnN0YW5jZW9mIENsaXBwaW5nQXR0YWNobWVudCkge1xuXHRcdFx0XHRcdGNsaXBwZXIuY2xpcFN0YXJ0KHNsb3QsIGF0dGFjaG1lbnQpO1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjbGlwcGVyLmNsaXBFbmRXaXRoU2xvdChzbG90KTtcblx0XHR9XG5cdFx0Y2xpcHBlci5jbGlwRW5kKCk7XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZUNsaXBwaW5nRGF0YSAoY2FjaGVEYXRhOiBBdHRhY2htZW50Q2FjaGVEYXRhKSB7XG5cdFx0Y2FjaGVEYXRhLmNsaXBwZWQgPSB0cnVlO1xuXG5cdFx0Y2xpcHBlci5jbGlwVHJpYW5nbGVzVW5wYWNrZWQoXG5cdFx0XHRjYWNoZURhdGEudmVydGljZXMsXG5cdFx0XHRjYWNoZURhdGEuaW5kaWNlcyxcblx0XHRcdGNhY2hlRGF0YS5pbmRpY2VzLmxlbmd0aCxcblx0XHRcdGNhY2hlRGF0YS51dnMsXG5cdFx0KTtcblxuXHRcdGNvbnN0IHsgY2xpcHBlZFZlcnRpY2VzLCBjbGlwcGVkVVZzLCBjbGlwcGVkVHJpYW5nbGVzIH0gPSBjbGlwcGVyO1xuXG5cdFx0Y29uc3QgdmVydGljZXNDb3VudCA9IGNsaXBwZWRWZXJ0aWNlcy5sZW5ndGggLyAyO1xuXHRcdGNvbnN0IGluZGljZXNDb3VudCA9IGNsaXBwZWRUcmlhbmdsZXMubGVuZ3RoO1xuXG5cdFx0aWYgKCFjYWNoZURhdGEuY2xpcHBlZERhdGEpIHtcblx0XHRcdGNhY2hlRGF0YS5jbGlwcGVkRGF0YSA9IHtcblx0XHRcdFx0dmVydGljZXM6IG5ldyBGbG9hdDMyQXJyYXkodmVydGljZXNDb3VudCAqIDIpLFxuXHRcdFx0XHR1dnM6IG5ldyBGbG9hdDMyQXJyYXkodmVydGljZXNDb3VudCAqIDIpLFxuXHRcdFx0XHR2ZXJ0ZXhDb3VudDogdmVydGljZXNDb3VudCxcblx0XHRcdFx0aW5kaWNlczogbmV3IFVpbnQxNkFycmF5KGluZGljZXNDb3VudCksXG5cdFx0XHRcdGluZGljZXNDb3VudCxcblx0XHRcdH07XG5cblx0XHRcdHRoaXMuc3BpbmVBdHRhY2htZW50c0RpcnR5ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBjbGlwcGVkRGF0YSA9IGNhY2hlRGF0YS5jbGlwcGVkRGF0YTtcblxuXHRcdGNvbnN0IHNpemVDaGFuZ2UgPSBjbGlwcGVkRGF0YS52ZXJ0ZXhDb3VudCAhPT0gdmVydGljZXNDb3VudCB8fCBpbmRpY2VzQ291bnQgIT09IGNsaXBwZWREYXRhLmluZGljZXNDb3VudDtcblxuXHRcdGNhY2hlRGF0YS5za2lwUmVuZGVyID0gdmVydGljZXNDb3VudCA9PT0gMDtcblxuXHRcdGlmIChzaXplQ2hhbmdlKSB7XG5cdFx0XHR0aGlzLnNwaW5lQXR0YWNobWVudHNEaXJ0eSA9IHRydWU7XG5cblx0XHRcdGlmIChjbGlwcGVkRGF0YS52ZXJ0ZXhDb3VudCA8IHZlcnRpY2VzQ291bnQpIHtcblx0XHRcdFx0Ly8gYnVmZmVyIHJldXNlIVxuXHRcdFx0XHRjbGlwcGVkRGF0YS52ZXJ0aWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkodmVydGljZXNDb3VudCAqIDIpO1xuXHRcdFx0XHRjbGlwcGVkRGF0YS51dnMgPSBuZXcgRmxvYXQzMkFycmF5KHZlcnRpY2VzQ291bnQgKiAyKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGNsaXBwZWREYXRhLmluZGljZXMubGVuZ3RoIDwgaW5kaWNlc0NvdW50KSB7XG5cdFx0XHRcdGNsaXBwZWREYXRhLmluZGljZXMgPSBuZXcgVWludDE2QXJyYXkoaW5kaWNlc0NvdW50KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRjb25zdCB7IHZlcnRpY2VzLCB1dnMsIGluZGljZXMgfSA9IGNsaXBwZWREYXRhO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB2ZXJ0aWNlc0NvdW50OyBpKyspIHtcblx0XHRcdHZlcnRpY2VzW2kgKiAyXSA9IGNsaXBwZWRWZXJ0aWNlc1tpICogMl07XG5cdFx0XHR2ZXJ0aWNlc1soaSAqIDIpICsgMV0gPSBjbGlwcGVkVmVydGljZXNbKGkgKiAyKSArIDFdO1xuXG5cdFx0XHR1dnNbaSAqIDJdID0gY2xpcHBlZFVWc1soaSAqIDIpXTtcblx0XHRcdHV2c1soaSAqIDIpICsgMV0gPSBjbGlwcGVkVVZzWyhpICogMikgKyAxXTtcblx0XHR9XG5cblx0XHRjbGlwcGVkRGF0YS52ZXJ0ZXhDb3VudCA9IHZlcnRpY2VzQ291bnQ7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXNDb3VudDsgaSsrKSB7XG5cdFx0XHRpZiAoaW5kaWNlc1tpXSAhPT0gY2xpcHBlZFRyaWFuZ2xlc1tpXSkge1xuXHRcdFx0XHR0aGlzLnNwaW5lQXR0YWNobWVudHNEaXJ0eSA9IHRydWU7XG5cdFx0XHRcdGluZGljZXNbaV0gPSBjbGlwcGVkVHJpYW5nbGVzW2ldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNsaXBwZWREYXRhLmluZGljZXNDb3VudCA9IGluZGljZXNDb3VudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBlbnN1cmUgdGhhdCBhdHRhY2hlZCBjb250YWluZXJzIG1hcCBjb3JyZWN0bHkgdG8gdGhlaXIgc2xvdHNcblx0ICogYWxvbmcgd2l0aCB0aGVpciBwb3NpdGlvbiwgcm90YXRpb24sIHNjYWxlLCBhbmQgdmlzaWJpbGl0eS5cblx0ICovXG5cdHByaXZhdGUgdXBkYXRlU2xvdE9iamVjdHMgKCkge1xuXHRcdGZvciAoY29uc3QgaSBpbiB0aGlzLl9zbG90c09iamVjdCkge1xuXHRcdFx0Y29uc3Qgc2xvdEF0dGFjaG1lbnQgPSB0aGlzLl9zbG90c09iamVjdFtpXTtcblxuXHRcdFx0aWYgKCFzbG90QXR0YWNobWVudCkgY29udGludWU7XG5cblx0XHRcdHRoaXMudXBkYXRlU2xvdE9iamVjdChzbG90QXR0YWNobWVudCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVTbG90T2JqZWN0IChzbG90QXR0YWNobWVudDogeyBzbG90OiBTbG90LCBjb250YWluZXI6IENvbnRhaW5lciB9KSB7XG5cdFx0Y29uc3QgeyBzbG90LCBjb250YWluZXIgfSA9IHNsb3RBdHRhY2htZW50O1xuXG5cdFx0Y29udGFpbmVyLnZpc2libGUgPSB0aGlzLnNrZWxldG9uLmRyYXdPcmRlci5pbmNsdWRlcyhzbG90KTtcblxuXHRcdGlmIChjb250YWluZXIudmlzaWJsZSkge1xuXHRcdFx0Y29uc3QgYm9uZSA9IHNsb3QuYm9uZTtcblxuXHRcdFx0Y29udGFpbmVyLnBvc2l0aW9uLnNldChib25lLndvcmxkWCwgYm9uZS53b3JsZFkpO1xuXG5cdFx0XHRjb250YWluZXIuc2NhbGUueCA9IGJvbmUuZ2V0V29ybGRTY2FsZVgoKTtcblx0XHRcdGNvbnRhaW5lci5zY2FsZS55ID0gYm9uZS5nZXRXb3JsZFNjYWxlWSgpO1xuXG5cdFx0XHRjb250YWluZXIucm90YXRpb24gPSBib25lLmdldFdvcmxkUm90YXRpb25YKCkgKiBERUdfVE9fUkFEO1xuXG5cdFx0XHRjb250YWluZXIuYWxwaGEgPSB0aGlzLnNrZWxldG9uLmNvbG9yLmEgKiBzbG90LmNvbG9yLmE7XG5cdFx0fVxuXHR9XG5cblx0LyoqIEBpbnRlcm5hbCAqL1xuXHRfZ2V0Q2FjaGVkRGF0YSAoc2xvdDogU2xvdCwgYXR0YWNobWVudDogUmVnaW9uQXR0YWNobWVudCB8IE1lc2hBdHRhY2htZW50KTogQXR0YWNobWVudENhY2hlRGF0YSB7XG5cdFx0cmV0dXJuIHRoaXMuYXR0YWNobWVudENhY2hlRGF0YVtzbG90LmRhdGEuaW5kZXhdW2F0dGFjaG1lbnQubmFtZV0gfHwgdGhpcy5pbml0Q2FjaGVkRGF0YShzbG90LCBhdHRhY2htZW50KTtcblx0fVxuXG5cdHByaXZhdGUgaW5pdENhY2hlZERhdGEgKHNsb3Q6IFNsb3QsIGF0dGFjaG1lbnQ6IFJlZ2lvbkF0dGFjaG1lbnQgfCBNZXNoQXR0YWNobWVudCk6IEF0dGFjaG1lbnRDYWNoZURhdGEge1xuXHRcdGxldCB2ZXJ0aWNlczogRmxvYXQzMkFycmF5O1xuXG5cdFx0aWYgKGF0dGFjaG1lbnQgaW5zdGFuY2VvZiBSZWdpb25BdHRhY2htZW50KSB7XG5cdFx0XHR2ZXJ0aWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkoOCk7XG5cblx0XHRcdHRoaXMuYXR0YWNobWVudENhY2hlRGF0YVtzbG90LmRhdGEuaW5kZXhdW2F0dGFjaG1lbnQubmFtZV0gPSB7XG5cdFx0XHRcdGlkOiBgJHtzbG90LmRhdGEuaW5kZXh9LSR7YXR0YWNobWVudC5uYW1lfWAsXG5cdFx0XHRcdHZlcnRpY2VzLFxuXHRcdFx0XHRjbGlwcGVkOiBmYWxzZSxcblx0XHRcdFx0aW5kaWNlczogWzAsIDEsIDIsIDAsIDIsIDNdLFxuXHRcdFx0XHR1dnM6IG5ldyBGbG9hdDMyQXJyYXkoYXR0YWNobWVudC51dnMubGVuZ3RoKSxcblx0XHRcdFx0Y29sb3I6IG5ldyBDb2xvcigxLCAxLCAxLCAxKSxcblx0XHRcdFx0ZGFya0NvbG9yOiBuZXcgQ29sb3IoMCwgMCwgMCwgMCksXG5cdFx0XHRcdGRhcmtUaW50OiB0aGlzLmRhcmtUaW50LFxuXHRcdFx0XHRza2lwUmVuZGVyOiBmYWxzZSxcblx0XHRcdFx0dGV4dHVyZTogYXR0YWNobWVudC5yZWdpb24/LnRleHR1cmUudGV4dHVyZSxcblx0XHRcdH07XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0dmVydGljZXMgPSBuZXcgRmxvYXQzMkFycmF5KGF0dGFjaG1lbnQud29ybGRWZXJ0aWNlc0xlbmd0aCk7XG5cblx0XHRcdHRoaXMuYXR0YWNobWVudENhY2hlRGF0YVtzbG90LmRhdGEuaW5kZXhdW2F0dGFjaG1lbnQubmFtZV0gPSB7XG5cdFx0XHRcdGlkOiBgJHtzbG90LmRhdGEuaW5kZXh9LSR7YXR0YWNobWVudC5uYW1lfWAsXG5cdFx0XHRcdHZlcnRpY2VzLFxuXHRcdFx0XHRjbGlwcGVkOiBmYWxzZSxcblx0XHRcdFx0aW5kaWNlczogYXR0YWNobWVudC50cmlhbmdsZXMsXG5cdFx0XHRcdHV2czogbmV3IEZsb2F0MzJBcnJheShhdHRhY2htZW50LnV2cy5sZW5ndGgpLFxuXHRcdFx0XHRjb2xvcjogbmV3IENvbG9yKDEsIDEsIDEsIDEpLFxuXHRcdFx0XHRkYXJrQ29sb3I6IG5ldyBDb2xvcigwLCAwLCAwLCAwKSxcblx0XHRcdFx0ZGFya1RpbnQ6IHRoaXMuZGFya1RpbnQsXG5cdFx0XHRcdHNraXBSZW5kZXI6IGZhbHNlLFxuXHRcdFx0XHR0ZXh0dXJlOiBhdHRhY2htZW50LnJlZ2lvbj8udGV4dHVyZS50ZXh0dXJlLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5hdHRhY2htZW50Q2FjaGVEYXRhW3Nsb3QuZGF0YS5pbmRleF1bYXR0YWNobWVudC5uYW1lXTtcblx0fVxuXG5cdHByb3RlY3RlZCBvblZpZXdVcGRhdGUgKCkge1xuXHRcdC8vIGluY3JlbWVudCBmcm9tIHRoZSAxMnRoIGJpdCFcblx0XHR0aGlzLl9kaWRDaGFuZ2VJZCArPSAxIDw8IDEyO1xuXG5cdFx0dGhpcy5fYm91bmRzRGlydHkgPSB0cnVlO1xuXG5cdFx0aWYgKHRoaXMuZGlkVmlld1VwZGF0ZSkgcmV0dXJuO1xuXHRcdHRoaXMuZGlkVmlld1VwZGF0ZSA9IHRydWU7XG5cblx0XHRjb25zdCByZW5kZXJHcm91cCA9IHRoaXMucmVuZGVyR3JvdXAgfHwgdGhpcy5wYXJlbnRSZW5kZXJHcm91cDtcblxuXHRcdGlmIChyZW5kZXJHcm91cCkge1xuXHRcdFx0cmVuZGVyR3JvdXAub25DaGlsZFZpZXdVcGRhdGUodGhpcyk7XG5cdFx0fVxuXG5cdFx0dGhpcy5kZWJ1Zz8ucmVuZGVyRGVidWcodGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQXR0YWNoZXMgYSBQaXhpSlMgY29udGFpbmVyIHRvIGEgc3BlY2lmaWVkIHNsb3QuIFRoaXMgd2lsbCBtYXAgdGhlIHdvcmxkIHRyYW5zZm9ybSBvZiB0aGUgc2xvdHMgYm9uZVxuXHQgKiB0byB0aGUgYXR0YWNoZWQgY29udGFpbmVyLiBBIGNvbnRhaW5lciBjYW4gb25seSBiZSBhdHRhY2hlZCB0byBvbmUgc2xvdCBhdCBhIHRpbWUuXG5cdCAqXG5cdCAqIEBwYXJhbSBjb250YWluZXIgLSBUaGUgY29udGFpbmVyIHRvIGF0dGFjaCB0byB0aGUgc2xvdFxuXHQgKiBAcGFyYW0gc2xvdFJlZiAtIFRoZSBzbG90IGlkIG9yICBzbG90IHRvIGF0dGFjaCB0b1xuXHQgKi9cblx0cHVibGljIGFkZFNsb3RPYmplY3QgKHNsb3Q6IG51bWJlciB8IHN0cmluZyB8IFNsb3QsIGNvbnRhaW5lcjogQ29udGFpbmVyKSB7XG5cdFx0c2xvdCA9IHRoaXMuZ2V0U2xvdEZyb21SZWYoc2xvdCk7XG5cblx0XHQvLyBuZWVkIHRvIGNoZWNrIGluIG9uIHRoZSBjb250YWluZXIgdG9vLi4uXG5cdFx0Zm9yIChjb25zdCBpIGluIHRoaXMuX3Nsb3RzT2JqZWN0KSB7XG5cdFx0XHRpZiAodGhpcy5fc2xvdHNPYmplY3RbaV0/LmNvbnRhaW5lciA9PT0gY29udGFpbmVyKSB7XG5cdFx0XHRcdHRoaXMucmVtb3ZlU2xvdE9iamVjdCh0aGlzLl9zbG90c09iamVjdFtpXS5zbG90KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLnJlbW92ZVNsb3RPYmplY3Qoc2xvdCk7XG5cblx0XHRjb250YWluZXIuaW5jbHVkZUluQnVpbGQgPSBmYWxzZTtcblxuXHRcdC8vIFRPRE8gb25seSBhZGQgb25jZT8/XG5cdFx0dGhpcy5hZGRDaGlsZChjb250YWluZXIpO1xuXG5cdFx0Y29uc3Qgc2xvdE9iamVjdCA9IHsgY29udGFpbmVyLCBzbG90IH07XG5cdFx0dGhpcy5fc2xvdHNPYmplY3Rbc2xvdC5kYXRhLm5hbWVdID0gc2xvdE9iamVjdDtcblxuXHRcdHRoaXMudXBkYXRlU2xvdE9iamVjdChzbG90T2JqZWN0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgUGl4aUpTIGNvbnRhaW5lciBmcm9tIHRoZSBzbG90IGl0IGlzIGF0dGFjaGVkIHRvLlxuXHQgKlxuXHQgKiBAcGFyYW0gY29udGFpbmVyIC0gVGhlIGNvbnRhaW5lciB0byBkZXRhY2ggZnJvbSB0aGUgc2xvdFxuXHQgKiBAcGFyYW0gc2xvdE9yQ29udGFpbmVyIC0gVGhlIGNvbnRhaW5lciwgc2xvdCBpZCBvciBzbG90IHRvIGRldGFjaCBmcm9tXG5cdCAqL1xuXHRwdWJsaWMgcmVtb3ZlU2xvdE9iamVjdCAoc2xvdE9yQ29udGFpbmVyOiBudW1iZXIgfCBzdHJpbmcgfCBTbG90IHwgQ29udGFpbmVyKSB7XG5cdFx0bGV0IGNvbnRhaW5lclRvUmVtb3ZlOiBDb250YWluZXIgfCB1bmRlZmluZWQ7XG5cblx0XHRpZiAoc2xvdE9yQ29udGFpbmVyIGluc3RhbmNlb2YgQ29udGFpbmVyKSB7XG5cdFx0XHRmb3IgKGNvbnN0IGkgaW4gdGhpcy5fc2xvdHNPYmplY3QpIHtcblx0XHRcdFx0aWYgKHRoaXMuX3Nsb3RzT2JqZWN0W2ldPy5jb250YWluZXIgPT09IHNsb3RPckNvbnRhaW5lcikge1xuXHRcdFx0XHRcdHRoaXMuX3Nsb3RzT2JqZWN0W2ldID0gbnVsbDtcblxuXHRcdFx0XHRcdGNvbnRhaW5lclRvUmVtb3ZlID0gc2xvdE9yQ29udGFpbmVyO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0Y29uc3Qgc2xvdCA9IHRoaXMuZ2V0U2xvdEZyb21SZWYoc2xvdE9yQ29udGFpbmVyKTtcblxuXHRcdFx0Y29udGFpbmVyVG9SZW1vdmUgPSB0aGlzLl9zbG90c09iamVjdFtzbG90LmRhdGEubmFtZV0/LmNvbnRhaW5lcjtcblx0XHRcdHRoaXMuX3Nsb3RzT2JqZWN0W3Nsb3QuZGF0YS5uYW1lXSA9IG51bGw7XG5cdFx0fVxuXG5cdFx0aWYgKGNvbnRhaW5lclRvUmVtb3ZlKSB7XG5cdFx0XHR0aGlzLnJlbW92ZUNoaWxkKGNvbnRhaW5lclRvUmVtb3ZlKTtcblxuXHRcdFx0Y29udGFpbmVyVG9SZW1vdmUuaW5jbHVkZUluQnVpbGQgPSB0cnVlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgY29udGFpbmVyIGF0dGFjaGVkIHRvIGEgc2xvdCwgb3IgdW5kZWZpbmVkIGlmIG5vIGNvbnRhaW5lciBpcyBhdHRhY2hlZC5cblx0ICpcblx0ICogQHBhcmFtIHNsb3RSZWYgLSBUaGUgc2xvdCBpZCBvciBzbG90IHRvIGdldCB0aGUgYXR0YWNobWVudCBmcm9tXG5cdCAqIEByZXR1cm5zIC0gVGhlIGNvbnRhaW5lciBhdHRhY2hlZCB0byB0aGUgc2xvdFxuXHQgKi9cblx0cHVibGljIGdldFNsb3RPYmplY3QgKHNsb3Q6IG51bWJlciB8IHN0cmluZyB8IFNsb3QpIHtcblx0XHRzbG90ID0gdGhpcy5nZXRTbG90RnJvbVJlZihzbG90KTtcblxuXHRcdHJldHVybiB0aGlzLl9zbG90c09iamVjdFtzbG90LmRhdGEubmFtZV0/LmNvbnRhaW5lcjtcblx0fVxuXG5cdHByaXZhdGUgdXBkYXRlQm91bmRzICgpIHtcblx0XHR0aGlzLl9ib3VuZHNEaXJ0eSA9IGZhbHNlO1xuXG5cdFx0dGhpcy5za2VsZXRvbkJvdW5kcyB8fD0gbmV3IFNrZWxldG9uQm91bmRzKCk7XG5cblx0XHRjb25zdCBza2VsZXRvbkJvdW5kcyA9IHRoaXMuc2tlbGV0b25Cb3VuZHM7XG5cblx0XHRza2VsZXRvbkJvdW5kcy51cGRhdGUodGhpcy5za2VsZXRvbiwgdHJ1ZSk7XG5cblx0XHRpZiAoc2tlbGV0b25Cb3VuZHMubWluWCA9PT0gSW5maW5pdHkpIHtcblx0XHRcdHRoaXMuX2FwcGx5U3RhdGUoKTtcblxuXHRcdFx0Y29uc3QgZHJhd09yZGVyID0gdGhpcy5za2VsZXRvbi5kcmF3T3JkZXI7XG5cdFx0XHRjb25zdCBib3VuZHMgPSB0aGlzLl9ib3VuZHM7XG5cblx0XHRcdGJvdW5kcy5jbGVhcigpO1xuXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGRyYXdPcmRlci5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRjb25zdCBzbG90ID0gZHJhd09yZGVyW2ldO1xuXG5cdFx0XHRcdGNvbnN0IGF0dGFjaG1lbnQgPSBzbG90LmdldEF0dGFjaG1lbnQoKTtcblxuXHRcdFx0XHRpZiAoYXR0YWNobWVudCAmJiAoYXR0YWNobWVudCBpbnN0YW5jZW9mIFJlZ2lvbkF0dGFjaG1lbnQgfHwgYXR0YWNobWVudCBpbnN0YW5jZW9mIE1lc2hBdHRhY2htZW50KSkge1xuXHRcdFx0XHRcdGNvbnN0IGNhY2hlRGF0YSA9IHRoaXMuX2dldENhY2hlZERhdGEoc2xvdCwgYXR0YWNobWVudCk7XG5cblx0XHRcdFx0XHRib3VuZHMuYWRkVmVydGV4RGF0YShjYWNoZURhdGEudmVydGljZXMsIDAsIGNhY2hlRGF0YS52ZXJ0aWNlcy5sZW5ndGgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0dGhpcy5fYm91bmRzLm1pblggPSBza2VsZXRvbkJvdW5kcy5taW5YO1xuXHRcdFx0dGhpcy5fYm91bmRzLm1pblkgPSBza2VsZXRvbkJvdW5kcy5taW5ZO1xuXHRcdFx0dGhpcy5fYm91bmRzLm1heFggPSBza2VsZXRvbkJvdW5kcy5tYXhYO1xuXHRcdFx0dGhpcy5fYm91bmRzLm1heFkgPSBza2VsZXRvbkJvdW5kcy5tYXhZO1xuXHRcdH1cblx0fVxuXG5cdC8qKiBAaW50ZXJuYWwgKi9cblx0YWRkQm91bmRzIChib3VuZHM6IEJvdW5kcykge1xuXHRcdGJvdW5kcy5hZGRCb3VuZHModGhpcy5ib3VuZHMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlc3Ryb3lzIHRoaXMgc3ByaXRlIHJlbmRlcmFibGUgYW5kIG9wdGlvbmFsbHkgaXRzIHRleHR1cmUuXG5cdCAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyBwYXJhbWV0ZXIuIEEgYm9vbGVhbiB3aWxsIGFjdCBhcyBpZiBhbGwgb3B0aW9uc1xuXHQgKiAgaGF2ZSBiZWVuIHNldCB0byB0aGF0IHZhbHVlXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudGV4dHVyZT1mYWxzZV0gLSBTaG91bGQgaXQgZGVzdHJveSB0aGUgY3VycmVudCB0ZXh0dXJlIG9mIHRoZSByZW5kZXJhYmxlIGFzIHdlbGxcblx0ICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50ZXh0dXJlU291cmNlPWZhbHNlXSAtIFNob3VsZCBpdCBkZXN0cm95IHRoZSB0ZXh0dXJlU291cmNlIG9mIHRoZSByZW5kZXJhYmxlIGFzIHdlbGxcblx0ICovXG5cdHB1YmxpYyBvdmVycmlkZSBkZXN0cm95IChvcHRpb25zOiBEZXN0cm95T3B0aW9ucyA9IGZhbHNlKSB7XG5cdFx0c3VwZXIuZGVzdHJveShvcHRpb25zKTtcblxuXHRcdFRpY2tlci5zaGFyZWQucmVtb3ZlKHRoaXMuaW50ZXJuYWxVcGRhdGUsIHRoaXMpO1xuXHRcdHRoaXMuc3RhdGUuY2xlYXJMaXN0ZW5lcnMoKTtcblx0XHR0aGlzLmRlYnVnID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuc2tlbGV0b24gPSBudWxsIGFzIGFueTtcblx0XHR0aGlzLnN0YXRlID0gbnVsbCBhcyBhbnk7XG5cdFx0KHRoaXMuX3Nsb3RzT2JqZWN0IGFzIGFueSkgPSBudWxsO1xuXHRcdHRoaXMuX2xhc3RBdHRhY2htZW50cy5sZW5ndGggPSAwO1xuXHRcdHRoaXMuYXR0YWNobWVudENhY2hlRGF0YSA9IG51bGwgYXMgYW55O1xuXHR9XG5cblx0LyoqIENvbnZlcnRzIGEgcG9pbnQgZnJvbSB0aGUgc2tlbGV0b24gY29vcmRpbmF0ZSBzeXN0ZW0gdG8gdGhlIFBpeGkgd29ybGQgY29vcmRpbmF0ZSBzeXN0ZW0uICovXG5cdHB1YmxpYyBza2VsZXRvblRvUGl4aVdvcmxkQ29vcmRpbmF0ZXMgKHBvaW50OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0pIHtcblx0XHR0aGlzLndvcmxkVHJhbnNmb3JtLmFwcGx5KHBvaW50LCBwb2ludCk7XG5cdH1cblxuXHQvKiogQ29udmVydHMgYSBwb2ludCBmcm9tIHRoZSBQaXhpIHdvcmxkIGNvb3JkaW5hdGUgc3lzdGVtIHRvIHRoZSBza2VsZXRvbiBjb29yZGluYXRlIHN5c3RlbS4gKi9cblx0cHVibGljIHBpeGlXb3JsZENvb3JkaW5hdGVzVG9Ta2VsZXRvbiAocG9pbnQ6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSkge1xuXHRcdHRoaXMud29ybGRUcmFuc2Zvcm0uYXBwbHlJbnZlcnNlKHBvaW50LCBwb2ludCk7XG5cdH1cblxuXHQvKiogQ29udmVydHMgYSBwb2ludCBmcm9tIHRoZSBQaXhpIHdvcmxkIGNvb3JkaW5hdGUgc3lzdGVtIHRvIHRoZSBib25lJ3MgbG9jYWwgY29vcmRpbmF0ZSBzeXN0ZW0uICovXG5cdHB1YmxpYyBwaXhpV29ybGRDb29yZGluYXRlc1RvQm9uZSAocG9pbnQ6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSwgYm9uZTogQm9uZSkge1xuXHRcdHRoaXMucGl4aVdvcmxkQ29vcmRpbmF0ZXNUb1NrZWxldG9uKHBvaW50KTtcblx0XHRpZiAoYm9uZS5wYXJlbnQpIHtcblx0XHRcdGJvbmUucGFyZW50LndvcmxkVG9Mb2NhbChwb2ludCBhcyBWZWN0b3IyKTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRib25lLndvcmxkVG9Mb2NhbChwb2ludCBhcyBWZWN0b3IyKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVXNlIHRoaXMgbWV0aG9kIHRvIGluc3RhbnRpYXRlIGEgU3BpbmUgZ2FtZSBvYmplY3QuXG5cdCAqIEJlZm9yZSBpbnN0YW50aWF0aW5nIGEgU3BpbmUgZ2FtZSBvYmplY3QsIHRoZSBza2VsZXRvbiAoYC5za2VsYCBvciBgLmpzb25gKSBhbmQgdGhlIGF0bGFzIHRleHQgZmlsZXMgbXVzdCBiZSBsb2FkZWQgaW50byB0aGUgQXNzZXRzLiBGb3IgZXhhbXBsZTpcblx0ICogYGBgXG5cdCAqIFBJWEkuQXNzZXRzLmFkZChcInNhY2tEYXRhXCIsIFwiLi9hc3NldHMvc2Fjay1wcm8uc2tlbFwiKTtcblx0ICogUElYSS5Bc3NldHMuYWRkKFwic2Fja0F0bGFzXCIsIFwiLi9hc3NldHMvc2Fjay1wbWEuYXRsYXNcIik7XG5cdCAqIGF3YWl0IFBJWEkuQXNzZXRzLmxvYWQoW1wic2Fja0RhdGFcIiwgXCJzYWNrQXRsYXNcIl0pO1xuXHQgKiBgYGBcblx0ICogT25jZSBhIFNwaW5lIGdhbWUgb2JqZWN0IGlzIGNyZWF0ZWQsIGl0cyBza2VsZXRvbiBkYXRhIGlzIGNhY2hlZCBpbnRvIHtAbGluayBDYWNoZX0gdXNpbmcgdGhlIGtleTpcblx0ICogYCR7c2tlbGV0b25Bc3NldE5hbWV9LSR7YXRsYXNBc3NldE5hbWV9LSR7b3B0aW9ucz8uc2NhbGUgPz8gMX1gXG5cdCAqXG5cdCAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyB0byBjb25maWd1cmUgdGhlIFNwaW5lIGdhbWUgb2JqZWN0LiBTZWUge0BsaW5rIFNwaW5lRnJvbU9wdGlvbnN9XG5cdCAqIEByZXR1cm5zIHtTcGluZX0gVGhlIFNwaW5lIGdhbWUgb2JqZWN0IGluc3RhbnRpYXRlZFxuXHQgKi9cblx0c3RhdGljIGZyb20gKHsgc2tlbGV0b24sIGF0bGFzLCBzY2FsZSA9IDEsIGRhcmtUaW50LCBhdXRvVXBkYXRlID0gdHJ1ZSB9OiBTcGluZUZyb21PcHRpb25zKSB7XG5cdFx0Y29uc3QgY2FjaGVLZXkgPSBgJHtza2VsZXRvbn0tJHthdGxhc30tJHtzY2FsZX1gO1xuXG5cdFx0aWYgKENhY2hlLmhhcyhjYWNoZUtleSkpIHtcblx0XHRcdHJldHVybiBuZXcgU3BpbmUoQ2FjaGUuZ2V0PFNrZWxldG9uRGF0YT4oY2FjaGVLZXkpKTtcblx0XHR9XG5cblx0XHRjb25zdCBza2VsZXRvbkFzc2V0ID0gQXNzZXRzLmdldDxhbnkgfCBVaW50OEFycmF5Pihza2VsZXRvbik7XG5cblx0XHRjb25zdCBhdGxhc0Fzc2V0ID0gQXNzZXRzLmdldDxUZXh0dXJlQXRsYXM+KGF0bGFzKTtcblx0XHRjb25zdCBhdHRhY2htZW50TG9hZGVyID0gbmV3IEF0bGFzQXR0YWNobWVudExvYWRlcihhdGxhc0Fzc2V0KTtcblx0XHRjb25zdCBwYXJzZXIgPSBza2VsZXRvbkFzc2V0IGluc3RhbmNlb2YgVWludDhBcnJheVxuXHRcdFx0PyBuZXcgU2tlbGV0b25CaW5hcnkoYXR0YWNobWVudExvYWRlcilcblx0XHRcdDogbmV3IFNrZWxldG9uSnNvbihhdHRhY2htZW50TG9hZGVyKTtcblxuXHRcdHBhcnNlci5zY2FsZSA9IHNjYWxlO1xuXHRcdGNvbnN0IHNrZWxldG9uRGF0YSA9IHBhcnNlci5yZWFkU2tlbGV0b25EYXRhKHNrZWxldG9uQXNzZXQpO1xuXG5cdFx0Q2FjaGUuc2V0KGNhY2hlS2V5LCBza2VsZXRvbkRhdGEpO1xuXG5cdFx0cmV0dXJuIG5ldyBTcGluZSh7XG5cdFx0XHRza2VsZXRvbkRhdGEsXG5cdFx0XHRkYXJrVGludCxcblx0XHRcdGF1dG9VcGRhdGUsXG5cdFx0fSk7XG5cdH1cbn1cbiJdfQ==