@esotericsoftware/spine-webgl
Version:
The official Spine Runtimes for the web.
248 lines • 38.5 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.
*****************************************************************************/
export class Input {
element;
mouseX = 0;
mouseY = 0;
buttonDown = false;
touch0 = null;
touch1 = null;
initialPinchDistance = 0;
listeners = [];
autoPreventDefault;
// this is needed because browsers sends mousedown-mousemove-mousesup after a touch sequence, unless touch end preventDefault
// but preventing default will result in preventing interaction with the page.
isTouch = false;
callbacks;
constructor(element, autoPreventDefault = true) {
this.element = element;
this.autoPreventDefault = autoPreventDefault;
this.callbacks = this.setupCallbacks(element);
}
setupCallbacks(element) {
const mouseDown = (ev) => {
if (ev instanceof MouseEvent && !this.isTouch) {
const rect = element.getBoundingClientRect();
this.mouseX = ev.clientX - rect.left;
this.mouseY = ev.clientY - rect.top;
this.buttonDown = true;
this.listeners.map((listener) => { if (listener.down)
listener.down(this.mouseX, this.mouseY, ev); });
}
};
const mouseMove = (ev) => {
if (ev instanceof MouseEvent && !this.isTouch) {
const rect = element.getBoundingClientRect();
this.mouseX = ev.clientX - rect.left;
this.mouseY = ev.clientY - rect.top;
this.listeners.map((listener) => {
if (this.buttonDown) {
if (listener.dragged)
listener.dragged(this.mouseX, this.mouseY, ev);
}
else {
if (listener.moved)
listener.moved(this.mouseX, this.mouseY, ev);
}
});
}
};
const mouseUp = (ev) => {
if (ev instanceof MouseEvent && !this.isTouch) {
const rect = element.getBoundingClientRect();
this.mouseX = ev.clientX - rect.left;
;
this.mouseY = ev.clientY - rect.top;
this.buttonDown = false;
this.listeners.map((listener) => { if (listener.up)
listener.up(this.mouseX, this.mouseY, ev); });
}
};
const mouseWheel = (ev) => {
if (this.autoPreventDefault)
ev.preventDefault();
let deltaY = ev.deltaY;
if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE)
deltaY *= 8;
if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE)
deltaY *= 24;
this.listeners.map((listener) => { if (listener.wheel)
listener.wheel(deltaY, ev); });
};
const touchStart = (ev) => {
this.isTouch = true;
if (!this.touch0 || !this.touch1) {
const touches = ev.changedTouches;
const nativeTouch = touches.item(0);
if (!nativeTouch)
return;
const rect = element.getBoundingClientRect();
const x = nativeTouch.clientX - rect.left;
const y = nativeTouch.clientY - rect.top;
const touch = new Touch(nativeTouch.identifier, x, y);
this.mouseX = x;
this.mouseY = y;
this.buttonDown = true;
if (!this.touch0) {
this.touch0 = touch;
this.listeners.map((listener) => { if (listener.down)
listener.down(touch.x, touch.y, ev); });
}
else if (!this.touch1) {
this.touch1 = touch;
const dx = this.touch1.x - this.touch0.x;
const dy = this.touch1.x - this.touch0.x;
this.initialPinchDistance = Math.sqrt(dx * dx + dy * dy);
this.listeners.map((listener) => { if (listener.zoom)
listener.zoom(this.initialPinchDistance, this.initialPinchDistance, ev); });
}
}
if (this.autoPreventDefault)
ev.preventDefault();
};
const touchMove = (ev) => {
this.isTouch = true;
if (this.touch0) {
const touches = ev.changedTouches;
const rect = element.getBoundingClientRect();
for (let i = 0; i < touches.length; i++) {
const nativeTouch = touches[i];
const x = nativeTouch.clientX - rect.left;
const y = nativeTouch.clientY - rect.top;
if (this.touch0.identifier === nativeTouch.identifier) {
this.touch0.x = this.mouseX = x;
this.touch0.y = this.mouseY = y;
this.listeners.map((listener) => { if (listener.dragged)
listener.dragged(x, y, ev); });
}
if (this.touch1 && this.touch1.identifier === nativeTouch.identifier) {
this.touch1.x = this.mouseX = x;
this.touch1.y = this.mouseY = y;
}
}
if (this.touch0 && this.touch1) {
const dx = this.touch1.x - this.touch0.x;
const dy = this.touch1.x - this.touch0.x;
const distance = Math.sqrt(dx * dx + dy * dy);
this.listeners.map((listener) => { if (listener.zoom)
listener.zoom(this.initialPinchDistance, distance, ev); });
}
}
if (this.autoPreventDefault)
ev.preventDefault();
};
const touchEnd = (ev) => {
this.isTouch = true;
const touch0 = this.touch0;
if (touch0) {
const touches = ev.changedTouches;
const rect = element.getBoundingClientRect();
for (let i = 0; i < touches.length; i++) {
const nativeTouch = touches[i];
const x = nativeTouch.clientX - rect.left;
const y = nativeTouch.clientY - rect.top;
if (touch0.identifier === nativeTouch.identifier) {
this.touch0 = null;
this.mouseX = x;
this.mouseY = y;
this.listeners.map((listener) => { if (listener.up)
listener.up(x, y, ev); });
if (!this.touch1) {
this.buttonDown = false;
break;
}
else {
const touch0 = this.touch0 = this.touch1;
this.touch1 = null;
this.mouseX = touch0.x;
this.mouseY = touch0.y;
this.buttonDown = true;
this.listeners.map((listener) => { if (listener.down)
listener.down(touch0.x, touch0.y, ev); });
}
}
if (this.touch1?.identifier) {
this.touch1 = null;
}
}
}
if (this.autoPreventDefault)
ev.preventDefault();
};
element.addEventListener("mousedown", mouseDown, true);
element.addEventListener("mousemove", mouseMove, true);
element.addEventListener("mouseup", mouseUp, true);
element.addEventListener("wheel", mouseWheel, true);
element.addEventListener("touchstart", touchStart, { passive: false, capture: false });
element.addEventListener("touchmove", touchMove, { passive: false, capture: false });
element.addEventListener("touchend", touchEnd, { passive: false, capture: false });
element.addEventListener("touchcancel", touchEnd);
return {
mouseDown,
mouseMove,
mouseUp,
mouseWheel,
touchStart,
touchMove,
touchEnd,
};
}
dispose() {
const element = this.element;
element.removeEventListener("mousedown", this.callbacks.mouseDown, true);
element.removeEventListener("mousemove", this.callbacks.mouseMove, true);
element.removeEventListener("mouseup", this.callbacks.mouseUp, true);
element.removeEventListener("wheel", this.callbacks.mouseWheel, true);
element.removeEventListener("touchstart", this.callbacks.touchStart, { capture: false });
element.removeEventListener("touchmove", this.callbacks.touchMove, { capture: false });
element.removeEventListener("touchend", this.callbacks.touchEnd, { capture: false });
element.removeEventListener("touchcancel", this.callbacks.touchEnd);
this.listeners.length = 0;
}
addListener(listener) {
this.listeners.push(listener);
}
removeListener(listener) {
const idx = this.listeners.indexOf(listener);
if (idx > -1) {
this.listeners.splice(idx, 1);
}
}
}
export class Touch {
identifier;
x;
y;
constructor(identifier, x, y) {
this.identifier = identifier;
this.x = x;
this.y = y;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5wdXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvSW5wdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE1BQU0sT0FBTyxLQUFLO0lBQ2pCLE9BQU8sQ0FBYztJQUNyQixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ1gsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNYLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDbkIsTUFBTSxHQUFpQixJQUFJLENBQUM7SUFDNUIsTUFBTSxHQUFpQixJQUFJLENBQUM7SUFDNUIsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLFNBQVMsR0FBRyxFQUFxQixDQUFDO0lBQ2xDLGtCQUFrQixDQUFVO0lBRXBDLDZIQUE2SDtJQUM3SCw4RUFBOEU7SUFDdEUsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUVoQixTQUFTLENBUWY7SUFFRixZQUFhLE9BQW9CLEVBQUUsa0JBQWtCLEdBQUcsSUFBSTtRQUMzRCxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7UUFDN0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFTyxjQUFjLENBQUUsT0FBb0I7UUFDM0MsTUFBTSxTQUFTLEdBQUcsQ0FBQyxFQUFXLEVBQUUsRUFBRTtZQUNqQyxJQUFJLEVBQUUsWUFBWSxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQy9DLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2dCQUM3QyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDckMsSUFBSSxDQUFDLE1BQU0sR0FBRyxF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QUMsQ0FBQztRQUNyRixPQUFPLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRCxXQUFXLENBQUUsUUFBdUI7UUFDbkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELGNBQWMsQ0FBRSxRQUF1QjtRQUN0QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDRixDQUFDO0NBQ0Q7QUFFRCxNQUFNLE9BQU8sS0FBSztJQUNHO0lBQTJCO0lBQWtCO0lBQWpFLFlBQW9CLFVBQWtCLEVBQVMsQ0FBUyxFQUFTLENBQVM7UUFBdEQsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUFTLE1BQUMsR0FBRCxDQUFDLENBQVE7UUFBUyxNQUFDLEdBQUQsQ0FBQyxDQUFRO0lBQzFFLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBEaXNwb3NhYmxlIH0gZnJvbSBcIi4vaW5kZXguanNcIlxuZXhwb3J0IGNsYXNzIElucHV0IGltcGxlbWVudHMgRGlzcG9zYWJsZSB7XG5cdGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXHRtb3VzZVggPSAwO1xuXHRtb3VzZVkgPSAwO1xuXHRidXR0b25Eb3duID0gZmFsc2U7XG5cdHRvdWNoMDogVG91Y2ggfCBudWxsID0gbnVsbDtcblx0dG91Y2gxOiBUb3VjaCB8IG51bGwgPSBudWxsO1xuXHRpbml0aWFsUGluY2hEaXN0YW5jZSA9IDA7XG5cdHByaXZhdGUgbGlzdGVuZXJzID0gW10gYXMgSW5wdXRMaXN0ZW5lcltdO1xuXHRwcml2YXRlIGF1dG9QcmV2ZW50RGVmYXVsdDogYm9vbGVhbjtcblxuXHQvLyB0aGlzIGlzIG5lZWRlZCBiZWNhdXNlIGJyb3dzZXJzIHNlbmRzIG1vdXNlZG93bi1tb3VzZW1vdmUtbW91c2VzdXAgYWZ0ZXIgYSB0b3VjaCBzZXF1ZW5jZSwgdW5sZXNzIHRvdWNoIGVuZCBwcmV2ZW50RGVmYXVsdFxuXHQvLyBidXQgcHJldmVudGluZyBkZWZhdWx0IHdpbGwgcmVzdWx0IGluIHByZXZlbnRpbmcgaW50ZXJhY3Rpb24gd2l0aCB0aGUgcGFnZS5cblx0cHJpdmF0ZSBpc1RvdWNoID0gZmFsc2U7XG5cblx0cHJpdmF0ZSBjYWxsYmFja3M6IHtcblx0XHRtb3VzZURvd246IChldjogVUlFdmVudCkgPT4gdm9pZDtcblx0XHRtb3VzZU1vdmU6IChldjogVUlFdmVudCkgPT4gdm9pZDtcblx0XHRtb3VzZVVwOiAoZXY6IFVJRXZlbnQpID0+IHZvaWQ7XG5cdFx0bW91c2VXaGVlbDogKGV2OiBXaGVlbEV2ZW50KSA9PiB2b2lkO1xuXHRcdHRvdWNoU3RhcnQ6IChldjogVG91Y2hFdmVudCkgPT4gdm9pZDtcblx0XHR0b3VjaE1vdmU6IChldjogVG91Y2hFdmVudCkgPT4gdm9pZDtcblx0XHR0b3VjaEVuZDogKGV2OiBUb3VjaEV2ZW50KSA9PiB2b2lkO1xuXHR9O1xuXG5cdGNvbnN0cnVjdG9yIChlbGVtZW50OiBIVE1MRWxlbWVudCwgYXV0b1ByZXZlbnREZWZhdWx0ID0gdHJ1ZSkge1xuXHRcdHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cdFx0dGhpcy5hdXRvUHJldmVudERlZmF1bHQgPSBhdXRvUHJldmVudERlZmF1bHQ7XG5cdFx0dGhpcy5jYWxsYmFja3MgPSB0aGlzLnNldHVwQ2FsbGJhY2tzKGVsZW1lbnQpO1xuXHR9XG5cblx0cHJpdmF0ZSBzZXR1cENhbGxiYWNrcyAoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcblx0XHRjb25zdCBtb3VzZURvd24gPSAoZXY6IFVJRXZlbnQpID0+IHtcblx0XHRcdGlmIChldiBpbnN0YW5jZW9mIE1vdXNlRXZlbnQgJiYgIXRoaXMuaXNUb3VjaCkge1xuXHRcdFx0XHRjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdFx0dGhpcy5tb3VzZVggPSBldi5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHR0aGlzLm1vdXNlWSA9IGV2LmNsaWVudFkgLSByZWN0LnRvcDtcblx0XHRcdFx0dGhpcy5idXR0b25Eb3duID0gdHJ1ZTtcblx0XHRcdFx0dGhpcy5saXN0ZW5lcnMubWFwKChsaXN0ZW5lcikgPT4geyBpZiAobGlzdGVuZXIuZG93bikgbGlzdGVuZXIuZG93bih0aGlzLm1vdXNlWCwgdGhpcy5tb3VzZVksIGV2KTsgfSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Y29uc3QgbW91c2VNb3ZlID0gKGV2OiBVSUV2ZW50KSA9PiB7XG5cdFx0XHRpZiAoZXYgaW5zdGFuY2VvZiBNb3VzZUV2ZW50ICYmICF0aGlzLmlzVG91Y2gpIHtcblx0XHRcdFx0Y29uc3QgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0XHRcdHRoaXMubW91c2VYID0gZXYuY2xpZW50WCAtIHJlY3QubGVmdDtcblx0XHRcdFx0dGhpcy5tb3VzZVkgPSBldi5jbGllbnRZIC0gcmVjdC50b3A7XG5cblx0XHRcdFx0dGhpcy5saXN0ZW5lcnMubWFwKChsaXN0ZW5lcikgPT4ge1xuXHRcdFx0XHRcdGlmICh0aGlzLmJ1dHRvbkRvd24pIHtcblx0XHRcdFx0XHRcdGlmIChsaXN0ZW5lci5kcmFnZ2VkKSBsaXN0ZW5lci5kcmFnZ2VkKHRoaXMubW91c2VYLCB0aGlzLm1vdXNlWSwgZXYpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRpZiAobGlzdGVuZXIubW92ZWQpIGxpc3RlbmVyLm1vdmVkKHRoaXMubW91c2VYLCB0aGlzLm1vdXNlWSwgZXYpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdGNvbnN0IG1vdXNlVXAgPSAoZXY6IFVJRXZlbnQpID0+IHtcblx0XHRcdGlmIChldiBpbnN0YW5jZW9mIE1vdXNlRXZlbnQgJiYgIXRoaXMuaXNUb3VjaCkge1xuXHRcdFx0XHRjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdFx0dGhpcy5tb3VzZVggPSBldi5jbGllbnRYIC0gcmVjdC5sZWZ0Oztcblx0XHRcdFx0dGhpcy5tb3VzZVkgPSBldi5jbGllbnRZIC0gcmVjdC50b3A7XG5cdFx0XHRcdHRoaXMuYnV0dG9uRG93biA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7IGlmIChsaXN0ZW5lci51cCkgbGlzdGVuZXIudXAodGhpcy5tb3VzZVgsIHRoaXMubW91c2VZLCBldik7IH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNvbnN0IG1vdXNlV2hlZWwgPSAoZXY6IFdoZWVsRXZlbnQpID0+IHtcblx0XHRcdGlmICh0aGlzLmF1dG9QcmV2ZW50RGVmYXVsdCkgZXYucHJldmVudERlZmF1bHQoKTtcblx0XHRcdGxldCBkZWx0YVkgPSBldi5kZWx0YVk7XG5cdFx0XHRpZiAoZXYuZGVsdGFNb2RlID09PSBXaGVlbEV2ZW50LkRPTV9ERUxUQV9MSU5FKSBkZWx0YVkgKj0gODtcblx0XHRcdGlmIChldi5kZWx0YU1vZGUgPT09IFdoZWVsRXZlbnQuRE9NX0RFTFRBX1BBR0UpIGRlbHRhWSAqPSAyNDtcblx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLndoZWVsKSBsaXN0ZW5lci53aGVlbChkZWx0YVksIGV2KTsgfSk7XG5cdFx0fTtcblxuXHRcdGNvbnN0IHRvdWNoU3RhcnQgPSAoZXY6IFRvdWNoRXZlbnQpID0+IHtcblx0XHRcdHRoaXMuaXNUb3VjaCA9IHRydWU7XG5cdFx0XHRpZiAoIXRoaXMudG91Y2gwIHx8ICF0aGlzLnRvdWNoMSkge1xuXHRcdFx0XHRjb25zdCB0b3VjaGVzID0gZXYuY2hhbmdlZFRvdWNoZXM7XG5cdFx0XHRcdGNvbnN0IG5hdGl2ZVRvdWNoID0gdG91Y2hlcy5pdGVtKDApO1xuXHRcdFx0XHRpZiAoIW5hdGl2ZVRvdWNoKSByZXR1cm47XG5cdFx0XHRcdGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdFx0XHRjb25zdCB4ID0gbmF0aXZlVG91Y2guY2xpZW50WCAtIHJlY3QubGVmdDtcblx0XHRcdFx0Y29uc3QgeSA9IG5hdGl2ZVRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcblx0XHRcdFx0Y29uc3QgdG91Y2ggPSBuZXcgVG91Y2gobmF0aXZlVG91Y2guaWRlbnRpZmllciwgeCwgeSk7XG5cdFx0XHRcdHRoaXMubW91c2VYID0geDtcblx0XHRcdFx0dGhpcy5tb3VzZVkgPSB5O1xuXHRcdFx0XHR0aGlzLmJ1dHRvbkRvd24gPSB0cnVlO1xuXG5cdFx0XHRcdGlmICghdGhpcy50b3VjaDApIHtcblx0XHRcdFx0XHR0aGlzLnRvdWNoMCA9IHRvdWNoO1xuXHRcdFx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLmRvd24pIGxpc3RlbmVyLmRvd24odG91Y2gueCwgdG91Y2gueSwgZXYpIH0pXG5cdFx0XHRcdH0gZWxzZSBpZiAoIXRoaXMudG91Y2gxKSB7XG5cdFx0XHRcdFx0dGhpcy50b3VjaDEgPSB0b3VjaDtcblx0XHRcdFx0XHRjb25zdCBkeCA9IHRoaXMudG91Y2gxLnggLSB0aGlzLnRvdWNoMC54O1xuXHRcdFx0XHRcdGNvbnN0IGR5ID0gdGhpcy50b3VjaDEueCAtIHRoaXMudG91Y2gwLng7XG5cdFx0XHRcdFx0dGhpcy5pbml0aWFsUGluY2hEaXN0YW5jZSA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cdFx0XHRcdFx0dGhpcy5saXN0ZW5lcnMubWFwKChsaXN0ZW5lcikgPT4geyBpZiAobGlzdGVuZXIuem9vbSkgbGlzdGVuZXIuem9vbSh0aGlzLmluaXRpYWxQaW5jaERpc3RhbmNlLCB0aGlzLmluaXRpYWxQaW5jaERpc3RhbmNlLCBldikgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLmF1dG9QcmV2ZW50RGVmYXVsdCkgZXYucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cblx0XHRjb25zdCB0b3VjaE1vdmUgPSAoZXY6IFRvdWNoRXZlbnQpID0+IHtcblx0XHRcdHRoaXMuaXNUb3VjaCA9IHRydWU7XG5cdFx0XHRpZiAodGhpcy50b3VjaDApIHtcblx0XHRcdFx0Y29uc3QgdG91Y2hlcyA9IGV2LmNoYW5nZWRUb3VjaGVzO1xuXHRcdFx0XHRjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0b3VjaGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0Y29uc3QgbmF0aXZlVG91Y2ggPSB0b3VjaGVzW2ldO1xuXHRcdFx0XHRcdGNvbnN0IHggPSBuYXRpdmVUb3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHRcdGNvbnN0IHkgPSBuYXRpdmVUb3VjaC5jbGllbnRZIC0gcmVjdC50b3A7XG5cblx0XHRcdFx0XHRpZiAodGhpcy50b3VjaDAuaWRlbnRpZmllciA9PT0gbmF0aXZlVG91Y2guaWRlbnRpZmllcikge1xuXHRcdFx0XHRcdFx0dGhpcy50b3VjaDAueCA9IHRoaXMubW91c2VYID0geDtcblx0XHRcdFx0XHRcdHRoaXMudG91Y2gwLnkgPSB0aGlzLm1vdXNlWSA9IHk7XG5cdFx0XHRcdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7IGlmIChsaXN0ZW5lci5kcmFnZ2VkKSBsaXN0ZW5lci5kcmFnZ2VkKHgsIHksIGV2KSB9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHRoaXMudG91Y2gxICYmIHRoaXMudG91Y2gxLmlkZW50aWZpZXIgPT09IG5hdGl2ZVRvdWNoLmlkZW50aWZpZXIpIHtcblx0XHRcdFx0XHRcdHRoaXMudG91Y2gxLnggPSB0aGlzLm1vdXNlWCA9IHg7XG5cdFx0XHRcdFx0XHR0aGlzLnRvdWNoMS55ID0gdGhpcy5tb3VzZVkgPSB5O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodGhpcy50b3VjaDAgJiYgdGhpcy50b3VjaDEpIHtcblx0XHRcdFx0XHRjb25zdCBkeCA9IHRoaXMudG91Y2gxLnggLSB0aGlzLnRvdWNoMC54O1xuXHRcdFx0XHRcdGNvbnN0IGR5ID0gdGhpcy50b3VjaDEueCAtIHRoaXMudG91Y2gwLng7XG5cdFx0XHRcdFx0Y29uc3QgZGlzdGFuY2UgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xuXHRcdFx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLnpvb20pIGxpc3RlbmVyLnpvb20odGhpcy5pbml0aWFsUGluY2hEaXN0YW5jZSwgZGlzdGFuY2UsIGV2KSB9KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuYXV0b1ByZXZlbnREZWZhdWx0KSBldi5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH1cblxuXHRcdGNvbnN0IHRvdWNoRW5kID0gKGV2OiBUb3VjaEV2ZW50KSA9PiB7XG5cdFx0XHR0aGlzLmlzVG91Y2ggPSB0cnVlO1xuXHRcdFx0Y29uc3QgdG91Y2gwID0gdGhpcy50b3VjaDAgYXMgVG91Y2g7XG5cdFx0XHRpZiAodG91Y2gwKSB7XG5cdFx0XHRcdGNvbnN0IHRvdWNoZXMgPSBldi5jaGFuZ2VkVG91Y2hlcztcblx0XHRcdFx0Y29uc3QgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0b3VjaGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0Y29uc3QgbmF0aXZlVG91Y2ggPSB0b3VjaGVzW2ldO1xuXHRcdFx0XHRcdGNvbnN0IHggPSBuYXRpdmVUb3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHRcdGNvbnN0IHkgPSBuYXRpdmVUb3VjaC5jbGllbnRZIC0gcmVjdC50b3A7XG5cblx0XHRcdFx0XHRpZiAodG91Y2gwLmlkZW50aWZpZXIgPT09IG5hdGl2ZVRvdWNoLmlkZW50aWZpZXIpIHtcblx0XHRcdFx0XHRcdHRoaXMudG91Y2gwID0gbnVsbDtcblx0XHRcdFx0XHRcdHRoaXMubW91c2VYID0geDtcblx0XHRcdFx0XHRcdHRoaXMubW91c2VZID0geTtcblx0XHRcdFx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLnVwKSBsaXN0ZW5lci51cCh4LCB5LCBldikgfSk7XG5cblx0XHRcdFx0XHRcdGlmICghdGhpcy50b3VjaDEpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5idXR0b25Eb3duID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgdG91Y2gwID0gdGhpcy50b3VjaDAgPSB0aGlzLnRvdWNoMTtcblx0XHRcdFx0XHRcdFx0dGhpcy50b3VjaDEgPSBudWxsO1xuXHRcdFx0XHRcdFx0XHR0aGlzLm1vdXNlWCA9IHRvdWNoMC54O1xuXHRcdFx0XHRcdFx0XHR0aGlzLm1vdXNlWSA9IHRvdWNoMC55O1xuXHRcdFx0XHRcdFx0XHR0aGlzLmJ1dHRvbkRvd24gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7IGlmIChsaXN0ZW5lci5kb3duKSBsaXN0ZW5lci5kb3duKHRvdWNoMC54LCB0b3VjaDAueSwgZXYpIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICh0aGlzLnRvdWNoMT8uaWRlbnRpZmllcikge1xuXHRcdFx0XHRcdFx0dGhpcy50b3VjaDEgPSBudWxsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuYXV0b1ByZXZlbnREZWZhdWx0KSBldi5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH07XG5cblx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgbW91c2VEb3duLCB0cnVlKTtcblx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgbW91c2VNb3ZlLCB0cnVlKTtcblx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIG1vdXNlVXAsIHRydWUpO1xuXHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsIG1vdXNlV2hlZWwsIHRydWUpO1xuXHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgdG91Y2hTdGFydCwgeyBwYXNzaXZlOiBmYWxzZSwgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRvdWNoTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSwgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdG91Y2hFbmQsIHsgcGFzc2l2ZTogZmFsc2UsIGNhcHR1cmU6IGZhbHNlIH0pO1xuXHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRvdWNoRW5kKTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRtb3VzZURvd24sXG5cdFx0XHRtb3VzZU1vdmUsXG5cdFx0XHRtb3VzZVVwLFxuXHRcdFx0bW91c2VXaGVlbCxcblx0XHRcdHRvdWNoU3RhcnQsXG5cdFx0XHR0b3VjaE1vdmUsXG5cdFx0XHR0b3VjaEVuZCxcblx0XHR9XG5cdH1cblxuXHRkaXNwb3NlICgpOiB2b2lkIHtcblx0XHRjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCB0aGlzLmNhbGxiYWNrcy5tb3VzZURvd24sIHRydWUpO1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLmNhbGxiYWNrcy5tb3VzZU1vdmUsIHRydWUpO1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5jYWxsYmFja3MubW91c2VVcCwgdHJ1ZSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwid2hlZWxcIiwgdGhpcy5jYWxsYmFja3MubW91c2VXaGVlbCwgdHJ1ZSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLmNhbGxiYWNrcy50b3VjaFN0YXJ0LCB7IGNhcHR1cmU6IGZhbHNlIH0pO1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCB0aGlzLmNhbGxiYWNrcy50b3VjaE1vdmUsIHsgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5jYWxsYmFja3MudG91Y2hFbmQsIHsgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIiwgdGhpcy5jYWxsYmFja3MudG91Y2hFbmQpO1xuXHRcdHRoaXMubGlzdGVuZXJzLmxlbmd0aCA9IDA7XG5cdH1cblxuXHRhZGRMaXN0ZW5lciAobGlzdGVuZXI6IElucHV0TGlzdGVuZXIpIHtcblx0XHR0aGlzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblx0fVxuXG5cdHJlbW92ZUxpc3RlbmVyIChsaXN0ZW5lcjogSW5wdXRMaXN0ZW5lcikge1xuXHRcdGNvbnN0IGlkeCA9IHRoaXMubGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuXHRcdGlmIChpZHggPiAtMSkge1xuXHRcdFx0dGhpcy5saXN0ZW5lcnMuc3BsaWNlKGlkeCwgMSk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBUb3VjaCB7XG5cdGNvbnN0cnVjdG9yIChwdWJsaWMgaWRlbnRpZmllcjogbnVtYmVyLCBwdWJsaWMgeDogbnVtYmVyLCBwdWJsaWMgeTogbnVtYmVyKSB7XG5cdH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbnB1dExpc3RlbmVyIHtcblx0ZG93bj8oeDogbnVtYmVyLCB5OiBudW1iZXIsIGV2PzogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkO1xuXHR1cD8oeDogbnVtYmVyLCB5OiBudW1iZXIsIGV2PzogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkO1xuXHRtb3ZlZD8oeDogbnVtYmVyLCB5OiBudW1iZXIsIGV2PzogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkO1xuXHRkcmFnZ2VkPyh4OiBudW1iZXIsIHk6IG51bWJlciwgZXY/OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IHZvaWQ7XG5cdHdoZWVsPyhkZWx0YTogbnVtYmVyLCBldj86IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZDtcblx0em9vbT8oaW5pdGlhbERpc3RhbmNlOiBudW1iZXIsIGRpc3RhbmNlOiBudW1iZXIsIGV2PzogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkO1xufVxuIl19