@esotericsoftware/spine-core
Version:
The official Spine Runtimes for the web.
158 lines • 22.4 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 { Utils } from "../Utils.js";
import { MeshAttachment } from "./MeshAttachment.js";
import { RegionAttachment } from "./RegionAttachment.js";
/** Holds texture regions, UVs, and vertex offsets for rendering a region or mesh attachment. {@link regions Regions} must be
* populated and {@link update} called before use. */
export class Sequence {
static _nextID = 0;
id = Sequence.nextID();
/** The list of texture regions this sequence will display. */
regions;
pathSuffix;
uvs;
/** Returns vertex offsets from the center of a {@link RegionAttachment}. Invalid to call for a {@link MeshAttachment}. */
offsets;
/** The starting number for the numeric {@link getPath | path} suffix. */
start = 0;
/** The minimum number of digits in the numeric {@link getPath | path} suffix, for zero padding. 0 for no zero
* padding. */
digits = 0;
/** The index of the region to show for the setup pose. */
setupIndex = 0;
/** @param count The number of texture regions this sequence will display.
* @param pathSuffix If true, the {@link getPath | path} has a numeric suffix. If false, all regions will use the
* same path, so `count` should be 1. */
constructor(count, pathSuffix) {
this.regions = new Array(count);
this.pathSuffix = pathSuffix;
}
copy() {
const regionCount = this.regions.length;
const copy = new Sequence(regionCount, this.pathSuffix);
Utils.arrayCopy(this.regions, 0, copy.regions, 0, regionCount);
copy.start = this.start;
copy.digits = this.digits;
copy.setupIndex = this.setupIndex;
if (this.uvs != null) {
const length = this.uvs[0].length;
copy.uvs = [];
for (let i = 0; i < regionCount; i++) {
copy.uvs[i] = Utils.newFloatArray(length);
Utils.arrayCopy(this.uvs[i], 0, copy.uvs[i], 0, length);
}
}
if (this.offsets != null) {
copy.offsets = [];
for (let i = 0; i < regionCount; i++) {
copy.offsets[i] = [];
Utils.arrayCopy(this.offsets[i], 0, copy.offsets[i], 0, 8);
}
}
return copy;
}
/** Computes UVs and offsets for the specified attachment. Must be called if the regions or attachment properties are
* changed. */
update(attachment) {
const regionCount = this.regions.length;
if (attachment instanceof RegionAttachment) {
this.uvs = [];
this.offsets = [];
for (let i = 0; i < regionCount; i++) {
this.uvs[i] = Utils.newFloatArray(8);
this.offsets[i] = [];
RegionAttachment.computeUVs(this.regions[i], attachment.x, attachment.y, attachment.scaleX, attachment.scaleY, attachment.rotation, attachment.width, attachment.height, this.offsets[i], this.uvs[i]);
}
}
else if (attachment instanceof MeshAttachment) {
const regionUVs = attachment.regionUVs;
this.uvs = [];
this.offsets = undefined;
for (let i = 0; i < regionCount; i++) {
this.uvs[i] = Utils.newFloatArray(regionUVs.length);
MeshAttachment.computeUVs(this.regions[i], regionUVs, this.uvs[i]);
}
}
}
/** Returns the {@link regions} index for the {@link SlotPose.getSequenceIndex}. */
resolveIndex(pose) {
let index = pose.sequenceIndex;
if (index === -1)
index = this.setupIndex;
if (index >= this.regions.length)
index = this.regions.length - 1;
return index;
}
/** Returns the UVs for the specified index. {@link regions Regions} must be populated and {@link update} called
* before calling this method. */
getUVs(index) {
// biome-ignore lint/style/noNonNullAssertion: uvs are always defined after updateSequence
return this.uvs[index];
}
/** Returns true if the {@link getPath | path} has a numeric suffix. */
hasPathSuffix() {
return this.pathSuffix;
}
/** Returns the specified base path with an optional numeric suffix for the specified index. */
getPath(basePath, index) {
if (!this.pathSuffix)
return basePath;
let result = basePath;
const frame = (this.start + index).toString();
for (let i = this.digits - frame.length; i > 0; i--)
result += "0";
result += frame;
return result;
}
static nextID() {
return Sequence._nextID++;
}
}
/** Controls how {@link Sequence.regions} are displayed over time. */
export var SequenceMode;
(function (SequenceMode) {
SequenceMode[SequenceMode["hold"] = 0] = "hold";
SequenceMode[SequenceMode["once"] = 1] = "once";
SequenceMode[SequenceMode["loop"] = 2] = "loop";
SequenceMode[SequenceMode["pingpong"] = 3] = "pingpong";
SequenceMode[SequenceMode["onceReverse"] = 4] = "onceReverse";
SequenceMode[SequenceMode["loopReverse"] = 5] = "loopReverse";
SequenceMode[SequenceMode["pingpongReverse"] = 6] = "pingpongReverse";
})(SequenceMode || (SequenceMode = {}));
export const SequenceModeValues = [
SequenceMode.hold,
SequenceMode.once,
SequenceMode.loop,
SequenceMode.pingpong,
SequenceMode.onceReverse,
SequenceMode.loopReverse,
SequenceMode.pingpongReverse
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VxdWVuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXR0YWNobWVudHMvU2VxdWVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSS9FLE9BQU8sRUFBd0IsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTFELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUV6RDtxREFDcUQ7QUFDckQsTUFBTSxPQUFPLFFBQVE7SUFDWixNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUUzQixFQUFFLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRXZCLDhEQUE4RDtJQUM5RCxPQUFPLENBQThCO0lBRTVCLFVBQVUsQ0FBVTtJQUM3QixHQUFHLENBQXFCO0lBRXhCLDBIQUEwSDtJQUMxSCxPQUFPLENBQWM7SUFFckIseUVBQXlFO0lBQ3pFLEtBQUssR0FBRyxDQUFDLENBQUM7SUFFVjtrQkFDYztJQUNkLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCwwREFBMEQ7SUFDMUQsVUFBVSxHQUFHLENBQUMsQ0FBQztJQUVmOzs0Q0FFd0M7SUFDeEMsWUFBYSxLQUFhLEVBQUUsVUFBbUI7UUFDOUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBZ0IsS0FBSyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDOUIsQ0FBQztJQUVELElBQUk7UUFDSCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUN4QyxNQUFNLElBQUksR0FBRyxJQUFJLFFBQVEsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hELEtBQUssQ0FBQyxTQUFT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QUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVU7WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUN0QyxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzlDLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ2xELE1BQU0sSUFBSSxHQUFHLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDO1FBQ2hCLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQztJQUVPLE1BQU0sQ0FBQyxNQUFNO1FBQ3BCLE9BQU8sUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLENBQUM7O0FBR0YscUVBQXFFO0FBQ3JFLE1BQU0sQ0FBTixJQUFZLFlBUVg7QUFSRCxXQUFZLFlBQVk7SUFDdkIsK0NBQVEsQ0FBQTtJQUNSLCtDQUFRLENBQUE7SUFDUiwrQ0FBUSxDQUFBO0lBQ1IsdURBQVksQ0FBQTtJQUNaLDZEQUFlLENBQUE7SUFDZiw2REFBZSxDQUFBO0lBQ2YscUVBQW1CLENBQUE7QUFDcEIsQ0FBQyxFQVJXLFlBQVksS0FBWixZQUFZLFFBUXZCO0FBRUQsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUc7SUFDakMsWUFBWSxDQUFDLElBQUk7SUFDakIsWUFBWSxDQUFDLElBQUk7SUFDakIsWUFBWSxDQUFDLElBQUk7SUFDakIsWUFBWSxDQUFDLFFBQVE7SUFDckIsWUFBWSxDQUFDLFdBQVc7SUFDeEIsWUFBWSxDQUFDLFdBQVc7SUFDeEIsWUFBWSxDQUFDLGVBQWU7Q0FDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBTbG90UG9zZSB9IGZyb20gXCIuLi9TbG90UG9zZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBUZXh0dXJlUmVnaW9uIH0gZnJvbSBcIi4uL1RleHR1cmUuanNcIjtcbmltcG9ydCB7IHR5cGUgTnVtYmVyQXJyYXlMaWtlLCBVdGlscyB9IGZyb20gXCIuLi9VdGlscy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBIYXNTZXF1ZW5jZSB9IGZyb20gXCIuL0hhc1NlcXVlbmNlLmpzXCI7XG5pbXBvcnQgeyBNZXNoQXR0YWNobWVudCB9IGZyb20gXCIuL01lc2hBdHRhY2htZW50LmpzXCI7XG5pbXBvcnQgeyBSZWdpb25BdHRhY2htZW50IH0gZnJvbSBcIi4vUmVnaW9uQXR0YWNobWVudC5qc1wiO1xuXG4vKiogSG9sZHMgdGV4dHVyZSByZWdpb25zLCBVVnMsIGFuZCB2ZXJ0ZXggb2Zmc2V0cyBmb3IgcmVuZGVyaW5nIGEgcmVnaW9uIG9yIG1lc2ggYXR0YWNobWVudC4ge0BsaW5rIHJlZ2lvbnMgUmVnaW9uc30gbXVzdCBiZVxuICogcG9wdWxhdGVkIGFuZCB7QGxpbmsgdXBkYXRlfSBjYWxsZWQgYmVmb3JlIHVzZS4gKi9cbmV4cG9ydCBjbGFzcyBTZXF1ZW5jZSB7XG5cdHByaXZhdGUgc3RhdGljIF9uZXh0SUQgPSAwO1xuXG5cdGlkID0gU2VxdWVuY2UubmV4dElEKCk7XG5cblx0LyoqIFRoZSBsaXN0IG9mIHRleHR1cmUgcmVnaW9ucyB0aGlzIHNlcXVlbmNlIHdpbGwgZGlzcGxheS4gKi9cblx0cmVnaW9uczogQXJyYXk8VGV4dHVyZVJlZ2lvbiB8IG51bGw+O1xuXG5cdHJlYWRvbmx5IHBhdGhTdWZmaXg6IGJvb2xlYW47XG5cdHV2cz86IE51bWJlckFycmF5TGlrZVtdO1xuXG5cdC8qKiBSZXR1cm5zIHZlcnRleCBvZmZzZXRzIGZyb20gdGhlIGNlbnRlciBvZiBhIHtAbGluayBSZWdpb25BdHRhY2htZW50fS4gSW52YWxpZCB0byBjYWxsIGZvciBhIHtAbGluayBNZXNoQXR0YWNobWVudH0uICovXG5cdG9mZnNldHM/OiBudW1iZXJbXVtdO1xuXG5cdC8qKiBUaGUgc3RhcnRpbmcgbnVtYmVyIGZvciB0aGUgbnVtZXJpYyB7QGxpbmsgZ2V0UGF0aCB8IHBhdGh9IHN1ZmZpeC4gKi9cblx0c3RhcnQgPSAwO1xuXG5cdC8qKiBUaGUgbWluaW11bSBudW1iZXIgb2YgZGlnaXRzIGluIHRoZSBudW1lcmljIHtAbGluayBnZXRQYXRoIHwgcGF0aH0gc3VmZml4LCBmb3IgemVybyBwYWRkaW5nLiAwIGZvciBubyB6ZXJvXG5cdCAqIHBhZGRpbmcuICovXG5cdGRpZ2l0cyA9IDA7XG5cblx0LyoqIFRoZSBpbmRleCBvZiB0aGUgcmVnaW9uIHRvIHNob3cgZm9yIHRoZSBzZXR1cCBwb3NlLiAqL1xuXHRzZXR1cEluZGV4ID0gMDtcblxuXHQvKiogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgdGV4dHVyZSByZWdpb25zIHRoaXMgc2VxdWVuY2Ugd2lsbCBkaXNwbGF5LlxuXHQgKiBAcGFyYW0gcGF0aFN1ZmZpeCBJZiB0cnVlLCB0aGUge0BsaW5rIGdldFBhdGggfCBwYXRofSBoYXMgYSBudW1lcmljIHN1ZmZpeC4gSWYgZmFsc2UsIGFsbCByZWdpb25zIHdpbGwgdXNlIHRoZVxuXHQgKiBzYW1lIHBhdGgsIHNvIGBjb3VudGAgc2hvdWxkIGJlIDEuICovXG5cdGNvbnN0cnVjdG9yIChjb3VudDogbnVtYmVyLCBwYXRoU3VmZml4OiBib29sZWFuKSB7XG5cdFx0dGhpcy5yZWdpb25zID0gbmV3IEFycmF5PFRleHR1cmVSZWdpb24+KGNvdW50KTtcblx0XHR0aGlzLnBhdGhTdWZmaXggPSBwYXRoU3VmZml4O1xuXHR9XG5cblx0Y29weSAoKTogU2VxdWVuY2Uge1xuXHRcdGNvbnN0IHJlZ2lvbkNvdW50ID0gdGhpcy5yZWdpb25zLmxlbmd0aDtcblx0XHRjb25zdCBjb3B5ID0gbmV3IFNlcXVlbmNlKHJlZ2lvbkNvdW50LCB0aGlzLnBhdGhTdWZmaXgpO1xuXHRcdFV0aWxzLmFycmF5Q29weSh0aGlzLnJlZ2lvbnMsIDAsIGNvcHkucmVnaW9ucywgMCwgcmVnaW9uQ291bnQpO1xuXHRcdGNvcHkuc3RhcnQgPSB0aGlzLnN0YXJ0O1xuXHRcdGNvcHkuZGlnaXRzID0gdGhpcy5kaWdpdHM7XG5cdFx0Y29weS5zZXR1cEluZGV4ID0gdGhpcy5zZXR1cEluZGV4O1xuXG5cdFx0aWYgKHRoaXMudXZzICE9IG51bGwpIHtcblx0XHRcdGNvbnN0IGxlbmd0aCA9IHRoaXMudXZzWzBdLmxlbmd0aDtcblx0XHRcdGNvcHkudXZzID0gW107XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHJlZ2lvbkNvdW50OyBpKyspIHtcblx0XHRcdFx0Y29weS51dnNbaV0gPSBVdGlscy5uZXdGbG9hdEFycmF5KGxlbmd0aCk7XG5cdFx0XHRcdFV0aWxzLmFycmF5Q29weSh0aGlzLnV2c1tpXSwgMCwgY29weS51dnNbaV0sIDAsIGxlbmd0aCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICh0aGlzLm9mZnNldHMgIT0gbnVsbCkge1xuXHRcdFx0Y29weS5vZmZzZXRzID0gW107XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHJlZ2lvbkNvdW50OyBpKyspIHtcblx0XHRcdFx0Y29weS5vZmZzZXRzW2ldID0gW107XG5cdFx0XHRcdFV0aWxzLmFycmF5Q29weSh0aGlzLm9mZnNldHNbaV0sIDAsIGNvcHkub2Zmc2V0c1tpXSwgMCwgOCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvcHk7XG5cdH1cblxuXHQvKiogQ29tcHV0ZXMgVVZzIGFuZCBvZmZzZXRzIGZvciB0aGUgc3BlY2lmaWVkIGF0dGFjaG1lbnQuIE11c3QgYmUgY2FsbGVkIGlmIHRoZSByZWdpb25zIG9yIGF0dGFjaG1lbnQgcHJvcGVydGllcyBhcmVcblx0ICAqIGNoYW5nZWQuICovXG5cdHB1YmxpYyB1cGRhdGUgKGF0dGFjaG1lbnQ6IEhhc1NlcXVlbmNlKSB7XG5cdFx0Y29uc3QgcmVnaW9uQ291bnQgPSB0aGlzLnJlZ2lvbnMubGVuZ3RoO1xuXHRcdGlmIChhdHRhY2htZW50IGluc3RhbmNlb2YgUmVnaW9uQXR0YWNobWVudCkge1xuXHRcdFx0dGhpcy51dnMgPSBbXTtcblx0XHRcdHRoaXMub2Zmc2V0cyA9IFtdO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCByZWdpb25Db3VudDsgaSsrKSB7XG5cdFx0XHRcdHRoaXMudXZzW2ldID0gVXRpbHMubmV3RmxvYXRBcnJheSg4KTtcblx0XHRcdFx0dGhpcy5vZmZzZXRzW2ldID0gW107XG5cdFx0XHRcdFJlZ2lvbkF0dGFjaG1lbnQuY29tcHV0ZVVWcyh0aGlzLnJlZ2lvbnNbaV0sIGF0dGFjaG1lbnQueCwgYXR0YWNobWVudC55LCBhdHRhY2htZW50LnNjYWxlWCwgYXR0YWNobWVudC5zY2FsZVksIGF0dGFjaG1lbnQucm90YXRpb24sXG5cdFx0XHRcdFx0YXR0YWNobWVudC53aWR0aCwgYXR0YWNobWVudC5oZWlnaHQsIHRoaXMub2Zmc2V0c1tpXSwgdGhpcy51dnNbaV0pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoYXR0YWNobWVudCBpbnN0YW5jZW9mIE1lc2hBdHRhY2htZW50KSB7XG5cdFx0XHRjb25zdCByZWdpb25VVnMgPSBhdHRhY2htZW50LnJlZ2lvblVWcztcblx0XHRcdHRoaXMudXZzID0gW107XG5cdFx0XHR0aGlzLm9mZnNldHMgPSB1bmRlZmluZWQ7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHJlZ2lvbkNvdW50OyBpKyspIHtcblx0XHRcdFx0dGhpcy51dnNbaV0gPSBVdGlscy5uZXdGbG9hdEFycmF5KHJlZ2lvblVWcy5sZW5ndGgpO1xuXHRcdFx0XHRNZXNoQXR0YWNobWVudC5jb21wdXRlVVZzKHRoaXMucmVnaW9uc1tpXSwgcmVnaW9uVVZzLCB0aGlzLnV2c1tpXSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqIFJldHVybnMgdGhlIHtAbGluayByZWdpb25zfSBpbmRleCBmb3IgdGhlIHtAbGluayBTbG90UG9zZS5nZXRTZXF1ZW5jZUluZGV4fS4gKi9cblx0cmVzb2x2ZUluZGV4IChwb3NlOiBTbG90UG9zZSk6IG51bWJlciB7XG5cdFx0bGV0IGluZGV4ID0gcG9zZS5zZXF1ZW5jZUluZGV4O1xuXHRcdGlmIChpbmRleCA9PT0gLTEpIGluZGV4ID0gdGhpcy5zZXR1cEluZGV4O1xuXHRcdGlmIChpbmRleCA+PSB0aGlzLnJlZ2lvbnMubGVuZ3RoKSBpbmRleCA9IHRoaXMucmVnaW9ucy5sZW5ndGggLSAxO1xuXHRcdHJldHVybiBpbmRleDtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRoZSBVVnMgZm9yIHRoZSBzcGVjaWZpZWQgaW5kZXguIHtAbGluayByZWdpb25zIFJlZ2lvbnN9IG11c3QgYmUgcG9wdWxhdGVkIGFuZCB7QGxpbmsgdXBkYXRlfSBjYWxsZWRcblx0ICAqIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLiAqL1xuXHRnZXRVVnMgKGluZGV4OiBudW1iZXIpOiBGbG9hdDMyQXJyYXkge1xuXHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogdXZzIGFyZSBhbHdheXMgZGVmaW5lZCBhZnRlciB1cGRhdGVTZXF1ZW5jZVxuXHRcdHJldHVybiB0aGlzLnV2cyFbaW5kZXhdIGFzIEZsb2F0MzJBcnJheTtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIHtAbGluayBnZXRQYXRoIHwgcGF0aH0gaGFzIGEgbnVtZXJpYyBzdWZmaXguICovXG5cdGhhc1BhdGhTdWZmaXggKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLnBhdGhTdWZmaXg7XG5cdH1cblxuXHQvKiogUmV0dXJucyB0aGUgc3BlY2lmaWVkIGJhc2UgcGF0aCB3aXRoIGFuIG9wdGlvbmFsIG51bWVyaWMgc3VmZml4IGZvciB0aGUgc3BlY2lmaWVkIGluZGV4LiAqL1xuXHRnZXRQYXRoIChiYXNlUGF0aDogc3RyaW5nLCBpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcblx0XHRpZiAoIXRoaXMucGF0aFN1ZmZpeCkgcmV0dXJuIGJhc2VQYXRoO1xuXHRcdGxldCByZXN1bHQgPSBiYXNlUGF0aDtcblx0XHRjb25zdCBmcmFtZSA9ICh0aGlzLnN0YXJ0ICsgaW5kZXgpLnRvU3RyaW5nKCk7XG5cdFx0Zm9yIChsZXQgaSA9IHRoaXMuZGlnaXRzIC0gZnJhbWUubGVuZ3RoOyBpID4gMDsgaS0tKVxuXHRcdFx0cmVzdWx0ICs9IFwiMFwiO1xuXHRcdHJlc3VsdCArPSBmcmFtZTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0cHJpdmF0ZSBzdGF0aWMgbmV4dElEICgpOiBudW1iZXIge1xuXHRcdHJldHVybiBTZXF1ZW5jZS5fbmV4dElEKys7XG5cdH1cbn1cblxuLyoqIENvbnRyb2xzIGhvdyB7QGxpbmsgU2VxdWVuY2UucmVnaW9uc30gYXJlIGRpc3BsYXllZCBvdmVyIHRpbWUuICovXG5leHBvcnQgZW51bSBTZXF1ZW5jZU1vZGUge1xuXHRob2xkID0gMCxcblx0b25jZSA9IDEsXG5cdGxvb3AgPSAyLFxuXHRwaW5ncG9uZyA9IDMsXG5cdG9uY2VSZXZlcnNlID0gNCxcblx0bG9vcFJldmVyc2UgPSA1LFxuXHRwaW5ncG9uZ1JldmVyc2UgPSA2XG59XG5cbmV4cG9ydCBjb25zdCBTZXF1ZW5jZU1vZGVWYWx1ZXMgPSBbXG5cdFNlcXVlbmNlTW9kZS5ob2xkLFxuXHRTZXF1ZW5jZU1vZGUub25jZSxcblx0U2VxdWVuY2VNb2RlLmxvb3AsXG5cdFNlcXVlbmNlTW9kZS5waW5ncG9uZyxcblx0U2VxdWVuY2VNb2RlLm9uY2VSZXZlcnNlLFxuXHRTZXF1ZW5jZU1vZGUubG9vcFJldmVyc2UsXG5cdFNlcXVlbmNlTW9kZS5waW5ncG9uZ1JldmVyc2Vcbl07XG4iXX0=