@esotericsoftware/spine-core
Version:
The official Spine Runtimes for the web.
321 lines • 50.3 kB
JavaScript
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Inherit } from "./BoneData.js";
import { Constraint } from "./Constraint.js";
import { ScaleYMode } from "./ConstraintData.js";
import { IkConstraintPose } from "./IkConstraintPose.js";
import { MathUtils } from "./Utils.js";
/** Adjusts the local rotation of 1 or 2 constrained bones so the world position of the tip of the last bone is as close to the
* target bone as possible.
*
* See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */
export class IkConstraint extends Constraint {
/** The 1 or 2 bones that will be modified by this IK constraint. */
bones;
/** The bone that is the IK target. */
target;
constructor(data, skeleton) {
super(data, new IkConstraintPose(), new IkConstraintPose());
if (!skeleton)
throw new Error("skeleton cannot be null.");
this.bones = [];
for (const boneData of data.bones)
this.bones.push(skeleton.bones[boneData.index].constrainedPose);
this.target = skeleton.bones[data.target.index];
}
copy(skeleton) {
var copy = new IkConstraint(this.data, skeleton);
copy.pose.set(this.pose);
return copy;
}
update(skeleton, physics) {
const p = this.appliedPose;
if (p.mix === 0)
return;
const target = this.target.appliedPose;
const bones = this.bones;
switch (bones.length) {
case 1:
IkConstraint.apply(skeleton, bones[0], target.worldX, target.worldY, p.compress, p.stretch, this.data.scaleYMode, p.mix);
break;
case 2:
IkConstraint.apply(skeleton, bones[0], bones[1], target.worldX, target.worldY, p.bendDirection, p.stretch, this.data.scaleYMode, p.softness, p.mix);
break;
}
}
sort(skeleton) {
skeleton.sortBone(this.target);
const parent = this.bones[0].bone;
skeleton.sortBone(parent);
skeleton._updateCache.push(this);
parent.sorted = false;
skeleton.sortReset(parent.children);
skeleton.constrained(parent);
if (this.bones.length > 1)
skeleton.constrained(this.bones[1].bone);
}
isSourceActive() {
return this.target.active;
}
static apply(skeleton, boneOrParent, targetXorChild, targetYOrTargetX, compressOrTargetY, stretchOrBendDir, scaleYModeOrStretch, mixOrScaleYMode, softness, mix) {
if (typeof targetXorChild === "number")
IkConstraint.apply1(skeleton, boneOrParent, targetXorChild, targetYOrTargetX, compressOrTargetY, stretchOrBendDir, scaleYModeOrStretch, mixOrScaleYMode);
else
IkConstraint.apply2(skeleton, boneOrParent, targetXorChild, targetYOrTargetX, compressOrTargetY, stretchOrBendDir, scaleYModeOrStretch, mixOrScaleYMode, softness, mix);
}
static apply1(skeleton, bone, targetX, targetY, compress, stretch, scaleYMode, mix) {
bone.modifyLocal(skeleton);
// biome-ignore lint/style/noNonNullAssertion: reference runtime
const p = bone.bone.parent.appliedPose;
let pa = p.a, pb = p.b, pc = p.c, pd = p.d;
let rotationIK = -bone.shearX - bone.rotation, tx = 0, ty = 0;
switch (bone.inherit) {
case Inherit.OnlyTranslation:
tx = (targetX - bone.worldX) * MathUtils.signum(skeleton.scaleX);
ty = (targetY - bone.worldY) * MathUtils.signum(skeleton.scaleY);
break;
// biome-ignore lint/suspicious/noFallthroughSwitchClause: reference runtime
case Inherit.NoRotationOrReflection: {
const s = Math.abs(pa * pd - pb * pc) / Math.max(MathUtils.epsilon, pa * pa + pc * pc);
const sa = pa / skeleton.scaleX;
const sc = pc / skeleton.scaleY;
pb = -sc * s * skeleton.scaleX;
pd = sa * s * skeleton.scaleY;
rotationIK += MathUtils.atan2Deg(sc, sa);
}
// Fall through
default: {
const x = targetX - p.worldX, y = targetY - p.worldY;
const d = pa * pd - pb * pc;
if (Math.abs(d) <= MathUtils.epsilon) {
tx = 0;
ty = 0;
}
else {
tx = (x * pd - y * pb) / d - bone.x;
ty = (y * pa - x * pc) / d - bone.y;
}
}
}
rotationIK += MathUtils.atan2Deg(ty, tx);
if (bone.scaleX < 0)
rotationIK += 180;
if (rotationIK > 180)
rotationIK -= 360;
else if (rotationIK <= -180)
rotationIK += 360;
bone.rotation += rotationIK * mix;
if (compress || stretch) {
switch (bone.inherit) {
case Inherit.NoScale:
case Inherit.NoScaleOrReflection:
tx = targetX - bone.worldX;
ty = targetY - bone.worldY;
}
const b = bone.bone.data.length * bone.scaleX;
if (b > MathUtils.epsilon) {
const dd = tx * tx + ty * ty;
if ((compress && dd < b * b) || (stretch && dd > b * b)) {
const s = (Math.sqrt(dd) / b - 1) * mix + 1;
bone.scaleX *= s;
switch (scaleYMode) {
case ScaleYMode.Uniform:
bone.scaleY *= s;
break;
case ScaleYMode.Volume: bone.scaleY /= s < 0.7 ? 0.25 + 0.642857 * s : s;
}
}
}
}
}
/** Applies 2 bone IK. The target is specified in the world coordinate system.
* @param child A direct descendant of the parent bone. */
static apply2(skeleton, parent, child, targetX, targetY, bendDir, stretch, scaleYMode, softness, mix) {
if (parent.inherit !== Inherit.Normal || child.inherit !== Inherit.Normal)
return;
parent.modifyLocal(skeleton);
child.modifyLocal(skeleton);
let px = parent.x, py = parent.y, psx = parent.scaleX, psy = parent.scaleY, csx = child.scaleX;
let os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) {
psx = -psx;
os1 = 180;
s2 = -1;
}
else {
os1 = 0;
s2 = 1;
}
if (psy < 0) {
psy = -psy;
s2 = -s2;
}
if (csx < 0) {
csx = -csx;
os2 = 180;
}
else
os2 = 0;
let cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d;
const u = Math.abs(psx - psy) <= MathUtils.epsilon;
if (!u || stretch) {
child.y = 0;
cwx = a * child.x + parent.worldX;
cwy = c * child.x + parent.worldY;
}
else {
cwx = a * child.x + b * child.y + parent.worldX;
cwy = c * child.x + d * child.y + parent.worldY;
}
// biome-ignore lint/style/noNonNullAssertion: reference runtime
const pp = parent.bone.parent.appliedPose;
a = pp.a;
b = pp.b;
c = pp.c;
d = pp.d;
let id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY;
id = Math.abs(id) <= MathUtils.epsilon ? 0 : 1 / id;
const dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.bone.data.length * csx, a1, a2;
if (l1 < MathUtils.epsilon) {
IkConstraint.apply(skeleton, parent, targetX, targetY, false, stretch, ScaleYMode.None, mix);
child.rotation = 0;
return;
}
x = targetX - pp.worldX;
y = targetY - pp.worldY;
let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
let dd = tx * tx + ty * ty;
if (softness !== 0) {
softness *= psx * (csx + 1) * 0.5;
const td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness;
if (sd > 0) {
let p = Math.min(1, sd / (softness * 2)) - 1;
p = (sd - softness * (1 - p * p)) / td;
tx -= p * tx;
ty -= p * ty;
dd = tx * tx + ty * ty;
}
}
// biome-ignore lint/suspicious/noConfusingLabels: reference runtime
outer: if (u) {
l2 *= psx;
let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) {
cos = -1;
a2 = Math.PI * bendDir;
}
else if (cos > 1) {
cos = 1;
a2 = 0;
if (stretch) {
a = (Math.sqrt(dd) / (l1 + l2) - 1) * mix + 1;
parent.scaleX *= a;
switch (scaleYMode) {
case ScaleYMode.Uniform:
parent.scaleY *= a;
break;
case ScaleYMode.Volume: parent.scaleY /= a < 0.7 ? 0.25 + 0.642857 * a : a;
}
}
}
else
a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos;
b = l2 * Math.sin(a2);
a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
}
else {
a = psx * l2;
b = psy * l2;
const aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb;
const c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c;
if (d >= 0) {
let q = Math.sqrt(d);
if (c1 < 0)
q = -q;
q = -(c1 + q) * 0.5;
let r0 = q / c2, r1 = c / q;
const r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
r0 = dd - r * r;
if (r0 >= 0) {
y = Math.sqrt(r0) * bendDir;
a1 = ta - Math.atan2(y, r);
a2 = Math.atan2(y / psy, (r - l1) / psx);
break outer;
}
}
let minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
c = -a * l1 / (aa - bb);
if (c >= -1 && c <= 1) {
c = Math.acos(c);
x = a * Math.cos(c) + l1;
y = b * Math.sin(c);
d = x * x + y * y;
if (d < minDist) {
minAngle = c;
minDist = d;
minX = x;
minY = y;
}
if (d > maxDist) {
maxAngle = c;
maxDist = d;
maxX = x;
maxY = y;
}
}
if (dd <= (minDist + maxDist) * 0.5) {
a1 = ta - Math.atan2(minY * bendDir, minX);
a2 = minAngle * bendDir;
}
else {
a1 = ta - Math.atan2(maxY * bendDir, maxX);
a2 = maxAngle * bendDir;
}
}
const os = Math.atan2(child.y, child.x) * s2;
a1 = (a1 - os) * MathUtils.radDeg + os1 - parent.rotation;
if (a1 > 180)
a1 -= 360;
else if (a1 <= -180) //
a1 += 360;
parent.rotation += a1 * mix;
a2 = ((a2 + os) * MathUtils.radDeg - child.shearX) * s2 + os2 - child.rotation;
if (a2 > 180)
a2 -= 360;
else if (a2 <= -180) //
a2 += 360;
child.rotation += a2 * mix;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0lrQ29uc3RyYWludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWpELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBR3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFdkM7OztxR0FHcUc7QUFDckcsTUFBTSxPQUFPLFlBQWEsU0FBUSxVQUE0RDtJQUM3RixvRUFBb0U7SUFDM0QsS0FBSyxDQUFrQjtJQUVoQyxzQ0FBc0M7SUFDdEMsTUFBTSxDQUFPO0lBRWIsWUFBYSxJQUFzQixFQUFFLFFBQWtCO1FBQ3RELEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxnQkFBZ0IsRUFBRSxFQUFFLElBQUksZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRTNELElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBZ0IsQ0FBQztRQUM5QixLQUFLLE1BQU0sUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLO1lBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRWpFLElBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pELENB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QUM7UUFDWCxNQUFNLENBQUMsUUFBUSxJQUFJLEVBQUUsR0FBRyxHQUFHLENBQUM7UUFDNUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQy9FLElBQUksRUFBRSxHQUFHLEdBQUc7WUFDWCxFQUFFLElBQUksR0FBRyxDQUFDO2FBQ04sSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUN0QixFQUFFLElBQUksR0FBRyxDQUFDO1FBQ1gsS0FBSyxDQUFDLFFBQVEsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDO0lBQzVCLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBCb25lIH0gZnJvbSBcIi4vQm9uZS5qc1wiO1xuaW1wb3J0IHsgSW5oZXJpdCB9IGZyb20gXCIuL0JvbmVEYXRhLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEJvbmVQb3NlIH0gZnJvbSBcIi4vQm9uZVBvc2UuanNcIjtcbmltcG9ydCB7IENvbnN0cmFpbnQgfSBmcm9tIFwiLi9Db25zdHJhaW50LmpzXCI7XG5pbXBvcnQgeyBTY2FsZVlNb2RlIH0gZnJvbSBcIi4vQ29uc3RyYWludERhdGEuanNcIjtcbmltcG9ydCB0eXBlIHsgSWtDb25zdHJhaW50RGF0YSB9IGZyb20gXCIuL0lrQ29uc3RyYWludERhdGEuanNcIjtcbmltcG9ydCB7IElrQ29uc3RyYWludFBvc2UgfSBmcm9tIFwiLi9Ja0NvbnN0cmFpbnRQb3NlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFBoeXNpY3MgfSBmcm9tIFwiLi9QaHlzaWNzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcIi4vU2tlbGV0b24uanNcIjtcbmltcG9ydCB7IE1hdGhVdGlscyB9IGZyb20gXCIuL1V0aWxzLmpzXCI7XG5cbi8qKiBBZGp1c3RzIHRoZSBsb2NhbCByb3RhdGlvbiBvZiAxIG9yIDIgY29uc3RyYWluZWQgYm9uZXMgc28gdGhlIHdvcmxkIHBvc2l0aW9uIG9mIHRoZSB0aXAgb2YgdGhlIGxhc3QgYm9uZSBpcyBhcyBjbG9zZSB0byB0aGVcbiAqIHRhcmdldCBib25lIGFzIHBvc3NpYmxlLlxuICpcbiAqIFNlZSBbSUsgY29uc3RyYWludHNdKGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1pay1jb25zdHJhaW50cykgaW4gdGhlIFNwaW5lIFVzZXIgR3VpZGUuICovXG5leHBvcnQgY2xhc3MgSWtDb25zdHJhaW50IGV4dGVuZHMgQ29uc3RyYWludDxJa0NvbnN0cmFpbnQsIElrQ29uc3RyYWludERhdGEsIElrQ29uc3RyYWludFBvc2U+IHtcblx0LyoqIFRoZSAxIG9yIDIgYm9uZXMgdGhhdCB3aWxsIGJlIG1vZGlmaWVkIGJ5IHRoaXMgSUsgY29uc3RyYWludC4gKi9cblx0cmVhZG9ubHkgYm9uZXM6IEFycmF5PEJvbmVQb3NlPjtcblxuXHQvKiogVGhlIGJvbmUgdGhhdCBpcyB0aGUgSUsgdGFyZ2V0LiAqL1xuXHR0YXJnZXQ6IEJvbmU7XG5cblx0Y29uc3RydWN0b3IgKGRhdGE6IElrQ29uc3RyYWludERhdGEsIHNrZWxldG9uOiBTa2VsZXRvbikge1xuXHRcdHN1cGVyKGRhdGEsIG5ldyBJa0NvbnN0cmFpbnRQb3NlKCksIG5ldyBJa0NvbnN0cmFpbnRQb3NlKCkpO1xuXHRcdGlmICghc2tlbGV0b24pIHRocm93IG5ldyBFcnJvcihcInNrZWxldG9uIGNhbm5vdCBiZSBudWxsLlwiKTtcblxuXHRcdHRoaXMuYm9uZXMgPSBbXSBhcyBCb25lUG9zZVtdO1xuXHRcdGZvciAoY29uc3QgYm9uZURhdGEgb2YgZGF0YS5ib25lcylcblx0XHRcdHRoaXMuYm9uZXMucHVzaChza2VsZXRvbi5ib25lc1tib25lRGF0YS5pbmRleF0uY29uc3RyYWluZWRQb3NlKTtcblxuXHRcdHRoaXMudGFyZ2V0ID0gc2tlbGV0b24uYm9uZXNbZGF0YS50YXJnZXQuaW5kZXhdO1xuXHR9XG5cblx0Y29weSAoc2tlbGV0b246IFNrZWxldG9uKTogSWtDb25zdHJhaW50IHtcblx0XHR2YXIgY29weSA9IG5ldyBJa0NvbnN0cmFpbnQodGhpcy5kYXRhLCBza2VsZXRvbik7XG5cdFx0Y29weS5wb3NlLnNldCh0aGlzLnBvc2UpO1xuXHRcdHJldHVybiBjb3B5O1xuXHR9XG5cblx0dXBkYXRlIChza2VsZXRvbjogU2tlbGV0b24sIHBoeXNpY3M6IFBoeXNpY3MpIHtcblx0XHRjb25zdCBwID0gdGhpcy5hcHBsaWVkUG9zZTtcblx0XHRpZiAocC5taXggPT09IDApIHJldHVybjtcblx0XHRjb25zdCB0YXJnZXQgPSB0aGlzLnRhcmdldC5hcHBsaWVkUG9zZTtcblx0XHRjb25zdCBib25lcyA9IHRoaXMuYm9uZXM7XG5cdFx0c3dpdGNoIChib25lcy5sZW5ndGgpIHtcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0SWtDb25zdHJhaW50LmFwcGx5KHNrZWxldG9uLCBib25lc1swXSwgdGFyZ2V0LndvcmxkWCwgdGFyZ2V0LndvcmxkWSwgcC5jb21wcmVzcywgcC5zdHJldGNoLCB0aGlzLmRhdGEuc2NhbGVZTW9kZSwgcC5taXgpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0SWtDb25zdHJhaW50LmFwcGx5KHNrZWxldG9uLCBib25lc1swXSwgYm9uZXNbMV0sIHRhcmdldC53b3JsZFgsIHRhcmdldC53b3JsZFksIHAuYmVuZERpcmVjdGlvbiwgcC5zdHJldGNoLCB0aGlzLmRhdGEuc2NhbGVZTW9kZSxcblx0XHRcdFx0XHRwLnNvZnRuZXNzLCBwLm1peCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdHNvcnQgKHNrZWxldG9uOiBTa2VsZXRvbikge1xuXHRcdHNrZWxldG9uLnNvcnRCb25lKHRoaXMudGFyZ2V0KTtcblx0XHRjb25zdCBwYXJlbnQgPSB0aGlzLmJvbmVzWzBdLmJvbmU7XG5cdFx0c2tlbGV0b24uc29ydEJvbmUocGFyZW50KTtcblx0XHRza2VsZXRvbi5fdXBkYXRlQ2FjaGUucHVzaCh0aGlzKTtcblx0XHRwYXJlbnQuc29ydGVkID0gZmFsc2U7XG5cdFx0c2tlbGV0b24uc29ydFJlc2V0KHBhcmVudC5jaGlsZHJlbik7XG5cdFx0c2tlbGV0b24uY29uc3RyYWluZWQocGFyZW50KTtcblx0XHRpZiAodGhpcy5ib25lcy5sZW5ndGggPiAxKSBza2VsZXRvbi5jb25zdHJhaW5lZCh0aGlzLmJvbmVzWzFdLmJvbmUpO1xuXHR9XG5cblx0aXNTb3VyY2VBY3RpdmUgKCkge1xuXHRcdHJldHVybiB0aGlzLnRhcmdldC5hY3RpdmU7XG5cdH1cblxuXHQvKiogQXBwbGllcyAxIGJvbmUgSUsuIFRoZSB0YXJnZXQgaXMgc3BlY2lmaWVkIGluIHRoZSB3b3JsZCBjb29yZGluYXRlIHN5c3RlbS4gKi9cblx0cHVibGljIHN0YXRpYyBhcHBseSAoc2tlbGV0b246IFNrZWxldG9uLCBib25lOiBCb25lUG9zZSwgdGFyZ2V0WDogbnVtYmVyLCB0YXJnZXRZOiBudW1iZXIsIGNvbXByZXNzOiBib29sZWFuLCBzdHJldGNoOiBib29sZWFuLCBzY2FsZVlNb2RlOiBTY2FsZVlNb2RlLCBtaXg6IG51bWJlcik6IHZvaWQ7XG5cblx0LyoqIEFwcGxpZXMgMiBib25lIElLLiBUaGUgdGFyZ2V0IGlzIHNwZWNpZmllZCBpbiB0aGUgd29ybGQgY29vcmRpbmF0ZSBzeXN0ZW0uXG5cdCAqIEBwYXJhbSBjaGlsZCBBIGRpcmVjdCBkZXNjZW5kYW50IG9mIHRoZSBwYXJlbnQgYm9uZS4gKi9cblx0cHVibGljIHN0YXRpYyBhcHBseSAoc2tlbGV0b246IFNrZWxldG9uLCBwYXJlbnQ6IEJvbmVQb3NlLCBjaGlsZDogQm9uZVBvc2UsIHRhcmdldFg6IG51bWJlciwgdGFyZ2V0WTogbnVtYmVyLCBiZW5kRGlyOiBudW1iZXIsIHN0cmV0Y2g6IGJvb2xlYW4sIHNjYWxlWU1vZGU6IFNjYWxlWU1vZGUsIHNvZnRuZXNzOiBudW1iZXIsIG1peDogbnVtYmVyKTogdm9pZDtcblxuXHRwdWJsaWMgc3RhdGljIGFwcGx5IChza2VsZXRvbjogU2tlbGV0b24sIGJvbmVPclBhcmVudDogQm9uZVBvc2UsIHRhcmdldFhvckNoaWxkOiBudW1iZXIgfCBCb25lUG9zZSwgdGFyZ2V0WU9yVGFyZ2V0WDogbnVtYmVyLCBjb21wcmVzc09yVGFyZ2V0WTogYm9vbGVhbiB8IG51bWJlcixcblx0XHRzdHJldGNoT3JCZW5kRGlyOiBib29sZWFuIHwgbnVtYmVyLCBzY2FsZVlNb2RlT3JTdHJldGNoOiBTY2FsZVlNb2RlIHwgYm9vbGVhbiwgbWl4T3JTY2FsZVlNb2RlOiBudW1iZXIgfCBib29sZWFuLCBzb2Z0bmVzcz86IG51bWJlciwgbWl4PzogbnVtYmVyKSB7XG5cblx0XHRpZiAodHlwZW9mIHRhcmdldFhvckNoaWxkID09PSBcIm51bWJlclwiKVxuXHRcdFx0SWtDb25zdHJhaW50LmFwcGx5MShza2VsZXRvbiwgYm9uZU9yUGFyZW50LCB0YXJnZXRYb3JDaGlsZCwgdGFyZ2V0WU9yVGFyZ2V0WCwgY29tcHJlc3NPclRhcmdldFkgYXMgYm9vbGVhbiwgc3RyZXRjaE9yQmVuZERpciBhcyBib29sZWFuLCBzY2FsZVlNb2RlT3JTdHJldGNoIGFzIFNjYWxlWU1vZGUsIG1peE9yU2NhbGVZTW9kZSBhcyBudW1iZXIpO1xuXHRcdGVsc2Vcblx0XHRcdElrQ29uc3RyYWludC5hcHBseTIoc2tlbGV0b24sIGJvbmVPclBhcmVudCwgdGFyZ2V0WG9yQ2hpbGQgYXMgQm9uZVBvc2UsIHRhcmdldFlPclRhcmdldFgsIGNvbXByZXNzT3JUYXJnZXRZIGFzIG51bWJlciwgc3RyZXRjaE9yQmVuZERpciBhcyBudW1iZXIsXG5cdFx0XHRcdHNjYWxlWU1vZGVPclN0cmV0Y2ggYXMgYm9vbGVhbiwgbWl4T3JTY2FsZVlNb2RlIGFzIFNjYWxlWU1vZGUsIHNvZnRuZXNzIGFzIG51bWJlciwgbWl4IGFzIG51bWJlcik7XG5cdH1cblxuXHRwcml2YXRlIHN0YXRpYyBhcHBseTEgKHNrZWxldG9uOiBTa2VsZXRvbiwgYm9uZTogQm9uZVBvc2UsIHRhcmdldFg6IG51bWJlciwgdGFyZ2V0WTogbnVtYmVyLCBjb21wcmVzczogYm9vbGVhbiwgc3RyZXRjaDogYm9vbGVhbiwgc2NhbGVZTW9kZTogU2NhbGVZTW9kZSwgbWl4OiBudW1iZXIpIHtcblx0XHRib25lLm1vZGlmeUxvY2FsKHNrZWxldG9uKTtcblxuXHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogcmVmZXJlbmNlIHJ1bnRpbWVcblx0XHRjb25zdCBwID0gYm9uZS5ib25lLnBhcmVudCEuYXBwbGllZFBvc2U7XG5cblx0XHRsZXQgcGEgPSBwLmEsIHBiID0gcC5iLCBwYyA9IHAuYywgcGQgPSBwLmQ7XG5cdFx0bGV0IHJvdGF0aW9uSUsgPSAtYm9uZS5zaGVhclggLSBib25lLnJvdGF0aW9uLCB0eCA9IDAsIHR5ID0gMDtcblxuXHRcdHN3aXRjaCAoYm9uZS5pbmhlcml0KSB7XG5cdFx0XHRjYXNlIEluaGVyaXQuT25seVRyYW5zbGF0aW9uOlxuXHRcdFx0XHR0eCA9ICh0YXJnZXRYIC0gYm9uZS53b3JsZFgpICogTWF0aFV0aWxzLnNpZ251bShza2VsZXRvbi5zY2FsZVgpO1xuXHRcdFx0XHR0eSA9ICh0YXJnZXRZIC0gYm9uZS53b3JsZFkpICogTWF0aFV0aWxzLnNpZ251bShza2VsZXRvbi5zY2FsZVkpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9GYWxsdGhyb3VnaFN3aXRjaENsYXVzZTogcmVmZXJlbmNlIHJ1bnRpbWVcblx0XHRcdGNhc2UgSW5oZXJpdC5Ob1JvdGF0aW9uT3JSZWZsZWN0aW9uOiB7XG5cdFx0XHRcdGNvbnN0IHMgPSBNYXRoLmFicyhwYSAqIHBkIC0gcGIgKiBwYykgLyBNYXRoLm1heChNYXRoVXRpbHMuZXBzaWxvbiwgcGEgKiBwYSArIHBjICogcGMpO1xuXHRcdFx0XHRjb25zdCBzYSA9IHBhIC8gc2tlbGV0b24uc2NhbGVYO1xuXHRcdFx0XHRjb25zdCBzYyA9IHBjIC8gc2tlbGV0b24uc2NhbGVZO1xuXHRcdFx0XHRwYiA9IC1zYyAqIHMgKiBza2VsZXRvbi5zY2FsZVg7XG5cdFx0XHRcdHBkID0gc2EgKiBzICogc2tlbGV0b24uc2NhbGVZO1xuXHRcdFx0XHRyb3RhdGlvbklLICs9IE1hdGhVdGlscy5hdGFuMkRlZyhzYywgc2EpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gRmFsbCB0aHJvdWdoXG5cdFx0XHRkZWZhdWx0OiB7XG5cdFx0XHRcdGNvbnN0IHggPSB0YXJnZXRYIC0gcC53b3JsZFgsIHkgPSB0YXJnZXRZIC0gcC53b3JsZFk7XG5cdFx0XHRcdGNvbnN0IGQgPSBwYSAqIHBkIC0gcGIgKiBwYztcblx0XHRcdFx0aWYgKE1hdGguYWJzKGQpIDw9IE1hdGhVdGlscy5lcHNpbG9uKSB7XG5cdFx0XHRcdFx0dHggPSAwO1xuXHRcdFx0XHRcdHR5ID0gMDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0eCA9ICh4ICogcGQgLSB5ICogcGIpIC8gZCAtIGJvbmUueDtcblx0XHRcdFx0XHR0eSA9ICh5ICogcGEgLSB4ICogcGMpIC8gZCAtIGJvbmUueTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyb3RhdGlvbklLICs9IE1hdGhVdGlscy5hdGFuMkRlZyh0eSwgdHgpO1xuXHRcdGlmIChib25lLnNjYWxlWCA8IDApIHJvdGF0aW9uSUsgKz0gMTgwO1xuXHRcdGlmIChyb3RhdGlvbklLID4gMTgwKVxuXHRcdFx0cm90YXRpb25JSyAtPSAzNjA7XG5cdFx0ZWxzZSBpZiAocm90YXRpb25JSyA8PSAtMTgwKVxuXHRcdFx0cm90YXRpb25JSyArPSAzNjA7XG5cdFx0Ym9uZS5yb3RhdGlvbiArPSByb3RhdGlvbklLICogbWl4O1xuXHRcdGlmIChjb21wcmVzcyB8fCBzdHJldGNoKSB7XG5cdFx0XHRzd2l0Y2ggKGJvbmUuaW5oZXJpdCkge1xuXHRcdFx0XHRjYXNlIEluaGVyaXQuTm9TY2FsZTpcblx0XHRcdFx0Y2FzZSBJbmhlcml0Lk5vU2NhbGVPclJlZmxlY3Rpb246XG5cdFx0XHRcdFx0dHggPSB0YXJnZXRYIC0gYm9uZS53b3JsZFg7XG5cdFx0XHRcdFx0dHkgPSB0YXJnZXRZIC0gYm9uZS53b3JsZFk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBiID0gYm9uZS5ib25lLmRhdGEubGVuZ3RoICogYm9uZS5zY2FsZVg7XG5cdFx0XHRpZiAoYiA+IE1hdGhVdGlscy5lcHNpbG9uKSB7XG5cdFx0XHRcdGNvbnN0IGRkID0gdHggKiB0eCArIHR5ICogdHk7XG5cdFx0XHRcdGlmICgoY29tcHJlc3MgJiYgZGQgPCBiICogYikgfHwgKHN0cmV0Y2ggJiYgZGQgPiBiICogYikpIHtcblx0XHRcdFx0XHRjb25zdCBzID0gKE1hdGguc3FydChkZCkgLyBiIC0gMSkgKiBtaXggKyAxO1xuXHRcdFx0XHRcdGJvbmUuc2NhbGVYICo9IHM7XG5cdFx0XHRcdFx0c3dpdGNoIChzY2FsZVlNb2RlKSB7XG5cdFx0XHRcdFx0XHRjYXNlIFNjYWxlWU1vZGUuVW5pZm9ybTogYm9uZS5zY2FsZVkgKj0gczsgYnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFNjYWxlWU1vZGUuVm9sdW1lOiBib25lLnNjYWxlWSAvPSBzIDwgMC43ID8gMC4yNSArIDAuNjQyODU3ICogcyA6IHM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqIEFwcGxpZXMgMiBib25lIElLLiBUaGUgdGFyZ2V0IGlzIHNwZWNpZmllZCBpbiB0aGUgd29ybGQgY29vcmRpbmF0ZSBzeXN0ZW0uXG5cdCAqIEBwYXJhbSBjaGlsZCBBIGRpcmVjdCBkZXNjZW5kYW50IG9mIHRoZSBwYXJlbnQgYm9uZS4gKi9cblx0cHJpdmF0ZSBzdGF0aWMgYXBwbHkyIChza2VsZXRvbjogU2tlbGV0b24sIHBhcmVudDogQm9uZVBvc2UsIGNoaWxkOiBCb25lUG9zZSwgdGFyZ2V0WDogbnVtYmVyLCB0YXJnZXRZOiBudW1iZXIsIGJlbmREaXI6IG51bWJlciwgc3RyZXRjaDogYm9vbGVhbiwgc2NhbGVZTW9kZTogU2NhbGVZTW9kZSwgc29mdG5lc3M6IG51bWJlciwgbWl4OiBudW1iZXIpIHtcblx0XHRpZiAocGFyZW50LmluaGVyaXQgIT09IEluaGVyaXQuTm9ybWFsIHx8IGNoaWxkLmluaGVyaXQgIT09IEluaGVyaXQuTm9ybWFsKSByZXR1cm47XG5cdFx0cGFyZW50Lm1vZGlmeUxvY2FsKHNrZWxldG9uKTtcblx0XHRjaGlsZC5tb2RpZnlMb2NhbChza2VsZXRvbik7XG5cdFx0bGV0IHB4ID0gcGFyZW50LngsIHB5ID0gcGFyZW50LnksIHBzeCA9IHBhcmVudC5zY2FsZVgsIHBzeSA9IHBhcmVudC5zY2FsZVksIGNzeCA9IGNoaWxkLnNjYWxlWDtcblx0XHRsZXQgb3MxID0gMCwgb3MyID0gMCwgczIgPSAwO1xuXHRcdGlmIChwc3ggPCAwKSB7XG5cdFx0XHRwc3ggPSAtcHN4O1xuXHRcdFx0b3MxID0gMTgwO1xuXHRcdFx0czIgPSAtMTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3MxID0gMDtcblx0XHRcdHMyID0gMTtcblx0XHR9XG5cdFx0aWYgKHBzeSA8IDApIHtcblx0XHRcdHBzeSA9IC1wc3k7XG5cdFx0XHRzMiA9IC1zMjtcblx0XHR9XG5cdFx0aWYgKGNzeCA8IDApIHtcblx0XHRcdGNzeCA9IC1jc3g7XG5cdFx0XHRvczIgPSAxODA7XG5cdFx0fSBlbHNlXG5cdFx0XHRvczIgPSAwO1xuXHRcdGxldCBjd3ggPSAwLCBjd3kgPSAwLCBhID0gcGFyZW50LmEsIGIgPSBwYXJlbnQuYiwgYyA9IHBhcmVudC5jLCBkID0gcGFyZW50LmQ7XG5cdFx0Y29uc3QgdSA9IE1hdGguYWJzKHBzeCAtIHBzeSkgPD0gTWF0aFV0aWxzLmVwc2lsb247XG5cdFx0aWYgKCF1IHx8IHN0cmV0Y2gpIHtcblx0XHRcdGNoaWxkLnkgPSAwO1xuXHRcdFx0Y3d4ID0gYSAqIGNoaWxkLnggKyBwYXJlbnQud29ybGRYO1xuXHRcdFx0Y3d5ID0gYyAqIGNoaWxkLnggKyBwYXJlbnQud29ybGRZO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjd3ggPSBhICogY2hpbGQueCArIGIgKiBjaGlsZC55ICsgcGFyZW50LndvcmxkWDtcblx0XHRcdGN3eSA9IGMgKiBjaGlsZC54ICsgZCAqIGNoaWxkLnkgKyBwYXJlbnQud29ybGRZO1xuXHRcdH1cblx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdHlsZS9ub05vbk51bGxBc3NlcnRpb246IHJlZmVyZW5jZSBydW50aW1lXG5cdFx0Y29uc3QgcHAgPSBwYXJlbnQuYm9uZS5wYXJlbnQhLmFwcGxpZWRQb3NlO1xuXHRcdGEgPSBwcC5hO1xuXHRcdGIgPSBwcC5iO1xuXHRcdGMgPSBwcC5jO1xuXHRcdGQgPSBwcC5kO1xuXHRcdGxldCBpZCA9IGEgKiBkIC0gYiAqIGMsIHggPSBjd3ggLSBwcC53b3JsZFgsIHkgPSBjd3kgLSBwcC53b3JsZFk7XG5cdFx0aWQgPSBNYXRoLmFicyhpZCkgPD0gTWF0aFV0aWxzLmVwc2lsb24gPyAwIDogMSAvIGlkO1xuXHRcdGNvbnN0IGR4ID0gKHggKiBkIC0geSAqIGIpICogaWQgLSBweCwgZHkgPSAoeSAqIGEgLSB4ICogYykgKiBpZCAtIHB5O1xuXHRcdGxldCBsMSA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSksIGwyID0gY2hpbGQuYm9uZS5kYXRhLmxlbmd0aCAqIGNzeCwgYTE6IG51bWJlciwgYTI6IG51bWJlcjtcblx0XHRpZiAobDEgPCBNYXRoVXRpbHMuZXBzaWxvbikge1xuXHRcdFx0SWtDb25zdHJhaW50LmFwcGx5KHNrZWxldG9uLCBwYXJlbnQsIHRhcmdldFgsIHRhcmdldFksIGZhbHNlLCBzdHJldGNoLCBTY2FsZVlNb2RlLk5vbmUsIG1peCk7XG5cdFx0XHRjaGlsZC5yb3RhdGlvbiA9IDA7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHggPSB0YXJnZXRYIC0gcHAud29ybGRYO1xuXHRcdHkgPSB0YXJnZXRZIC0gcHAud29ybGRZO1xuXHRcdGxldCB0eCA9ICh4ICogZCAtIHkgKiBiKSAqIGlkIC0gcHgsIHR5ID0gKHkgKiBhIC0geCAqIGMpICogaWQgLSBweTtcblx0XHRsZXQgZGQgPSB0eCAqIHR4ICsgdHkgKiB0eTtcblx0XHRpZiAoc29mdG5lc3MgIT09IDApIHtcblx0XHRcdHNvZnRuZXNzICo9IHBzeCAqIChjc3ggKyAxKSAqIDAuNTtcblx0XHRcdGNvbnN0IHRkID0gTWF0aC5zcXJ0KGRkKSwgc2QgPSB0ZCAtIGwxIC0gbDIgKiBwc3ggKyBzb2Z0bmVzcztcblx0XHRcdGlmIChzZCA+IDApIHtcblx0XHRcdFx0bGV0IHAgPSBNYXRoLm1pbigxLCBzZCAvIChzb2Z0bmVzcyAqIDIpKSAtIDE7XG5cdFx0XHRcdHAgPSAoc2QgLSBzb2Z0bmVzcyAqICgxIC0gcCAqIHApKSAvIHRkO1xuXHRcdFx0XHR0eCAtPSBwICogdHg7XG5cdFx0XHRcdHR5IC09IHAgKiB0eTtcblx0XHRcdFx0ZGQgPSB0eCAqIHR4ICsgdHkgKiB0eTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0NvbmZ1c2luZ0xhYmVsczogcmVmZXJlbmNlIHJ1bnRpbWVcblx0XHRvdXRlcjpcblx0XHRpZiAodSkge1xuXHRcdFx0bDIgKj0gcHN4O1xuXHRcdFx0bGV0IGNvcyA9IChkZCAtIGwxICogbDEgLSBsMiAqIGwyKSAvICgyICogbDEgKiBsMik7XG5cdFx0XHRpZiAoY29zIDwgLTEpIHtcblx0XHRcdFx0Y29zID0gLTE7XG5cdFx0XHRcdGEyID0gTWF0aC5QSSAqIGJlbmREaXI7XG5cdFx0XHR9IGVsc2UgaWYgKGNvcyA+IDEpIHtcblx0XHRcdFx0Y29zID0gMTtcblx0XHRcdFx0YTIgPSAwO1xuXHRcdFx0XHRpZiAoc3RyZXRjaCkge1xuXHRcdFx0XHRcdGEgPSAoTWF0aC5zcXJ0KGRkKSAvIChsMSArIGwyKSAtIDEpICogbWl4ICsgMTtcblx0XHRcdFx0XHRwYXJlbnQuc2NhbGVYICo9IGE7XG5cdFx0XHRcdFx0c3dpdGNoIChzY2FsZVlNb2RlKSB7XG5cdFx0XHRcdFx0XHRjYXNlIFNjYWxlWU1vZGUuVW5pZm9ybTogcGFyZW50LnNjYWxlWSAqPSBhOyBicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgU2NhbGVZTW9kZS5Wb2x1bWU6IHBhcmVudC5zY2FsZVkgLz0gYSA8IDAuNyA/IDAuMjUgKyAwLjY0Mjg1NyAqIGEgOiBhO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlXG5cdFx0XHRcdGEyID0gTWF0aC5hY29zKGNvcykgKiBiZW5kRGlyO1xuXHRcdFx0YSA9IGwxICsgbDIgKiBjb3M7XG5cdFx0XHRiID0gbDIgKiBNYXRoLnNpbihhMik7XG5cdFx0XHRhMSA9IE1hdGguYXRhbjIodHkgKiBhIC0gdHggKiBiLCB0eCAqIGEgKyB0eSAqIGIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhID0gcHN4ICogbDI7XG5cdFx0XHRiID0gcHN5ICogbDI7XG5cdFx0XHRjb25zdCBhYSA9IGEgKiBhLCBiYiA9IGIgKiBiLCB0YSA9IE1hdGguYXRhbjIodHksIHR4KTtcblx0XHRcdGMgPSBiYiAqIGwxICogbDEgKyBhYSAqIGRkIC0gYWEgKiBiYjtcblx0XHRcdGNvbnN0IGMxID0gLTIgKiBiYiAqIGwxLCBjMiA9IGJiIC0gYWE7XG5cdFx0XHRkID0gYzEgKiBjMSAtIDQgKiBjMiAqIGM7XG5cdFx0XHRpZiAoZCA+PSAwKSB7XG5cdFx0XHRcdGxldCBxID0gTWF0aC5zcXJ0KGQpO1xuXHRcdFx0XHRpZiAoYzEgPCAwKSBxID0gLXE7XG5cdFx0XHRcdHEgPSAtKGMxICsgcSkgKiAwLjU7XG5cdFx0XHRcdGxldCByMCA9IHEgLyBjMiwgcjEgPSBjIC8gcTtcblx0XHRcdFx0Y29uc3QgciA9IE1hdGguYWJzKHIwKSA8IE1hdGguYWJzKHIxKSA/IHIwIDogcjE7XG5cdFx0XHRcdHIwID0gZGQgLSByICogcjtcblx0XHRcdFx0aWYgKHIwID49IDApIHtcblx0XHRcdFx0XHR5ID0gTWF0aC5zcXJ0KHIwKSAqIGJlbmREaXI7XG5cdFx0XHRcdFx0YTEgPSB0YSAtIE1hdGguYXRhbjIoeSwgcik7XG5cdFx0XHRcdFx0YTIgPSBNYXRoLmF0YW4yKHkgLyBwc3ksIChyIC0gbDEpIC8gcHN4KTtcblx0XHRcdFx0XHRicmVhayBvdXRlcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0bGV0IG1pbkFuZ2xlID0gTWF0aFV0aWxzLlBJLCBtaW5YID0gbDEgLSBhLCBtaW5EaXN0ID0gbWluWCAqIG1pblgsIG1pblkgPSAwO1xuXHRcdFx0bGV0IG1heEFuZ2xlID0gMCwgbWF4WCA9IGwxICsgYSwgbWF4RGlzdCA9IG1heFggKiBtYXhYLCBtYXhZID0gMDtcblx0XHRcdGMgPSAtYSAqIGwxIC8gKGFhIC0gYmIpO1xuXHRcdFx0aWYgKGMgPj0gLTEgJiYgYyA8PSAxKSB7XG5cdFx0XHRcdGMgPSBNYXRoLmFjb3MoYyk7XG5cdFx0XHRcdHggPSBhICogTWF0aC5jb3MoYykgKyBsMTtcblx0XHRcdFx0eSA9IGIgKiBNYXRoLnNpbihjKTtcblx0XHRcdFx0ZCA9IHggKiB4ICsgeSAqIHk7XG5cdFx0XHRcdGlmIChkIDwgbWluRGlzdCkge1xuXHRcdFx0XHRcdG1pbkFuZ2xlID0gYztcblx0XHRcdFx0XHRtaW5EaXN0ID0gZDtcblx0XHRcdFx0XHRtaW5YID0geDtcblx0XHRcdFx0XHRtaW5ZID0geTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoZCA+IG1heERpc3QpIHtcblx0XHRcdFx0XHRtYXhBbmdsZSA9IGM7XG5cdFx0XHRcdFx0bWF4RGlzdCA9IGQ7XG5cdFx0XHRcdFx0bWF4WCA9IHg7XG5cdFx0XHRcdFx0bWF4WSA9IHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmIChkZCA8PSAobWluRGlzdCArIG1heERpc3QpICogMC41KSB7XG5cdFx0XHRcdGExID0gdGEgLSBNYXRoLmF0YW4yKG1pblkgKiBiZW5kRGlyLCBtaW5YKTtcblx0XHRcdFx0YTIgPSBtaW5BbmdsZSAqIGJlbmREaXI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRhMSA9IHRhIC0gTWF0aC5hdGFuMihtYXhZICogYmVuZERpciwgbWF4WCk7XG5cdFx0XHRcdGEyID0gbWF4QW5nbGUgKiBiZW5kRGlyO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRjb25zdCBvcyA9IE1hdGguYXRhbjIoY2hpbGQueSwgY2hpbGQueCkgKiBzMjtcblx0XHRhMSA9IChhMSAtIG9zKSAqIE1hdGhVdGlscy5yYWREZWcgKyBvczEgLSBwYXJlbnQucm90YXRpb247XG5cdFx0aWYgKGExID4gMTgwKVxuXHRcdFx0YTEgLT0gMzYwO1xuXHRcdGVsc2UgaWYgKGExIDw9IC0xODApIC8vXG5cdFx0XHRhMSArPSAzNjA7XG5cdFx0cGFyZW50LnJvdGF0aW9uICs9IGExICogbWl4O1xuXHRcdGEyID0gKChhMiArIG9zKS