webglimpse
Version:
Webglimpse is a data visualization library for the web.
144 lines • 19.2 kB
JavaScript
/*
* Copyright (c) 2014, Metron, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import { sameColor } from './color';
import { createTextTextureFactory, getTextWidth } from './text';
import { TextureRenderer } from './texture';
import { GL, hasval } from './util/util';
export class Label {
constructor(text, font, fgColor, bgColor) {
this._font = font;
this._text = text;
this._fgColor = fgColor;
this._bgColor = bgColor;
}
get font() {
return this._font;
}
set font(font) {
if (this._font !== font) {
this._font = font;
this._textureFactory = null;
if (this._texture) {
this._texture.dispose();
this._texture = null;
}
}
}
// retained for backwards compatibility, should use fgColor
get color() {
return this._fgColor;
}
// retained for backwards compatibility, should use fgColor
set color(fgColor) {
if (!sameColor(this._fgColor, fgColor)) {
this._fgColor = fgColor;
if (this._texture) {
this._texture.dispose();
this._texture = null;
}
}
}
get fgColor() {
return this._fgColor;
}
set fgColor(fgColor) {
if (!sameColor(this._fgColor, fgColor)) {
this._fgColor = fgColor;
if (this._texture) {
this._texture.dispose();
this._texture = null;
}
}
}
get bgColor() {
return this._bgColor;
}
set bgColor(bgColor) {
if (!sameColor(this._bgColor, bgColor)) {
this._bgColor = bgColor;
}
}
get text() {
return this._text;
}
set text(text) {
if (this._text !== text) {
this._text = text;
if (this._texture) {
this._texture.dispose();
this._texture = null;
}
}
}
get texture() {
if (!this._textureFactory) {
this._textureFactory = (this._font ? createTextTextureFactory(this._font) : null);
}
if (!this._texture) {
this._texture = (this._fgColor && this._text ? this._textureFactory(this._fgColor, this._text) : null);
}
return this._texture;
}
}
export function fitToLabel(label) {
return function (parentPrefSize) {
const texture = label.texture;
parentPrefSize.w = (texture ? texture.w : 0);
parentPrefSize.h = (texture ? texture.h : 0);
};
}
export function newLabelPainter(label, xFrac, yFrac, xAnchor, yAnchor, rotation_CCWRAD, truncateLabel) {
const textureRenderer = new TextureRenderer();
return function (gl, viewport) {
if (hasval(label.bgColor)) {
gl.clearColor(label.bgColor.r, label.bgColor.g, label.bgColor.b, label.bgColor.a);
gl.clear(GL.COLOR_BUFFER_BIT);
}
let labelText = label.text;
if (truncateLabel) {
const xRight = viewport.w - 2 / viewport.w;
while (labelText && labelText !== '...') {
if (getTextWidth(label.font, labelText) > xRight) {
labelText = labelText.substring(0, labelText.length - 4).concat('...');
}
else {
break;
}
}
}
label.text = labelText;
if (label.texture) {
textureRenderer.begin(gl, viewport);
textureRenderer.draw(gl, label.texture, xFrac, yFrac, { xAnchor: xAnchor, yAnchor: label.texture.yAnchor(yAnchor), rotation_CCWRAD: rotation_CCWRAD });
textureRenderer.end(gl);
}
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFiZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViZ2xpbXBzZS9sYWJlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBUSxTQUFTLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDekMsT0FBTyxFQUFvQyx3QkFBd0IsRUFBRSxZQUFZLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFFakcsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUMxQyxPQUFPLEVBQUMsRUFBRSxFQUFFLE1BQU0sRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUd2QyxNQUFNLE9BQU8sS0FBSztJQVFkLFlBQVksSUFBYSxFQUFFLElBQWEsRUFBRSxPQUFlLEVBQUUsT0FBZTtRQUN0RSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ0osT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxJQUFZO1FBQ2pCLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7WUFDckIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDbEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7WUFDNUIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO2FBQ3hCO1NBQ0o7SUFDTCxDQUFDO0lBRUQsMkRBQTJEO0lBQzNELElBQUksS0FBSztRQUNMLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN6QixDQUFDO0lBRUQsMkRBQTJEO0lBQzNELElBQUksS0FBSyxDQUFDLE9BQWM7UUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxFQUFFO1lBQ3BDLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1lBQ3hCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDZixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQzthQUN4QjtTQUNKO0lBQ0wsQ0FBQztJQUVELElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN6QixDQUFDO0lBRUQsSUFBSSxPQUFPLENBQUMsT0FBYztRQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEVBQUU7WUFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7WUFDeEIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO2FBQ3hCO1NBQ0o7SUFDTCxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFJLE9BQU8sQ0FBQyxPQUFjO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBRTtZQUNwQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztTQUMzQjtJQUNMLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksSUFBSSxDQUFDLElBQVk7UUFDakIsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksRUFBRTtZQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztZQUNsQixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7YUFDeEI7U0FDSjtJQUNMLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDUCxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN2QixJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNyRjtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzFHO1FBQ0QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7Q0FFSjtBQUdELE1BQU0sVUFBVSxVQUFVLENBQUMsS0FBWTtJQUNuQyxPQUFxQixVQUFVLGNBQW9CO1FBQy9DLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDOUIsY0FBYyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsY0FBYyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUdELE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBWSxFQUFFLEtBQWEsRUFBRSxLQUFhLEVBQUUsT0FBZ0IsRUFBRSxPQUFnQixFQUFFLGVBQXdCLEVBQUUsYUFBdUI7SUFDN0osTUFBTSxlQUFlLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUM5QyxPQUFPLFVBQVUsRUFBeUIsRUFBRSxRQUE0QjtRQUVwRSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDdkIsRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xGLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLENBQUM7U0FDakM7UUFFRCxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQzNCLElBQUksYUFBYSxFQUFFO1lBQ2YsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUMzQyxPQUFPLFNBQVMsSUFBSSxTQUFTLEtBQUssS0FBSyxFQUFFO2dCQUNyQyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxHQUFHLE1BQU0sRUFBRTtvQkFDOUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUMxRTtxQkFBTTtvQkFDSCxNQUFNO2lCQUNUO2FBQ0o7U0FDSjtRQUVELEtBQUssQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDO1FBQ3ZCLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNmLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3BDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZKLGVBQWUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDM0I7SUFDTCxDQUFDLENBQUM7QUFDTixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQ29weXJpZ2h0IChjKSAyMDE0LCBNZXRyb24sIEluYy5cclxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuICpcclxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbixcclxuICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gKlxyXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcclxuICogICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXHJcbiAqXHJcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcclxuICogICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxyXG4gKiAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cclxuICpcclxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcclxuICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcclxuICogICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxyXG4gKlxyXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkRcclxuICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcclxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxyXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUlxyXG4gKiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcclxuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xyXG4gKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT05cclxuICogQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcclxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVNcclxuICogU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXHJcbiAqL1xyXG5pbXBvcnQge0NvbG9yLCBzYW1lQ29sb3J9IGZyb20gJy4vY29sb3InO1xyXG5pbXBvcnQge1RleHRUZXh0dXJlRmFjdG9yeSwgVGV4dFRleHR1cmUyRCwgY3JlYXRlVGV4dFRleHR1cmVGYWN0b3J5LCBnZXRUZXh0V2lkdGh9IGZyb20gJy4vdGV4dCc7XHJcbmltcG9ydCB7U2l6ZSwgQm91bmRzVW5tb2RpZmlhYmxlfSBmcm9tICcuL2JvdW5kcyc7XHJcbmltcG9ydCB7VGV4dHVyZVJlbmRlcmVyfSBmcm9tICcuL3RleHR1cmUnO1xyXG5pbXBvcnQge0dMLCBoYXN2YWx9IGZyb20gJy4vdXRpbC91dGlsJztcclxuaW1wb3J0IHtMYXlvdXRQaGFzZTF9IGZyb20gJy4vY29yZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgTGFiZWwge1xyXG4gICAgcHJpdmF0ZSBfZm9udDogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBfZmdDb2xvcjogQ29sb3I7XHJcbiAgICBwcml2YXRlIF9iZ0NvbG9yOiBDb2xvcjtcclxuICAgIHByaXZhdGUgX3RleHQ6IHN0cmluZztcclxuICAgIHByaXZhdGUgX3RleHR1cmVGYWN0b3J5OiBUZXh0VGV4dHVyZUZhY3Rvcnk7XHJcbiAgICBwcml2YXRlIF90ZXh0dXJlOiBUZXh0VGV4dHVyZTJEO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHRleHQ/OiBzdHJpbmcsIGZvbnQ/OiBzdHJpbmcsIGZnQ29sb3I/OiBDb2xvciwgYmdDb2xvcj86IENvbG9yKSB7XHJcbiAgICAgICAgdGhpcy5fZm9udCA9IGZvbnQ7XHJcbiAgICAgICAgdGhpcy5fdGV4dCA9IHRleHQ7XHJcbiAgICAgICAgdGhpcy5fZmdDb2xvciA9IGZnQ29sb3I7XHJcbiAgICAgICAgdGhpcy5fYmdDb2xvciA9IGJnQ29sb3I7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGZvbnQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZm9udDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgZm9udChmb250OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodGhpcy5fZm9udCAhPT0gZm9udCkge1xyXG4gICAgICAgICAgICB0aGlzLl9mb250ID0gZm9udDtcclxuICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUZhY3RvcnkgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fdGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyByZXRhaW5lZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIHNob3VsZCB1c2UgZmdDb2xvclxyXG4gICAgZ2V0IGNvbG9yKCk6IENvbG9yIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmdDb2xvcjtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZXRhaW5lZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIHNob3VsZCB1c2UgZmdDb2xvclxyXG4gICAgc2V0IGNvbG9yKGZnQ29sb3I6IENvbG9yKSB7XHJcbiAgICAgICAgaWYgKCFzYW1lQ29sb3IodGhpcy5fZmdDb2xvciwgZmdDb2xvcikpIHtcclxuICAgICAgICAgICAgdGhpcy5fZmdDb2xvciA9IGZnQ29sb3I7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl90ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RleHR1cmUgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBmZ0NvbG9yKCk6IENvbG9yIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmdDb2xvcjtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgZmdDb2xvcihmZ0NvbG9yOiBDb2xvcikge1xyXG4gICAgICAgIGlmICghc2FtZUNvbG9yKHRoaXMuX2ZnQ29sb3IsIGZnQ29sb3IpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZnQ29sb3IgPSBmZ0NvbG9yO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fdGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgYmdDb2xvcigpOiBDb2xvciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JnQ29sb3I7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IGJnQ29sb3IoYmdDb2xvcjogQ29sb3IpIHtcclxuICAgICAgICBpZiAoIXNhbWVDb2xvcih0aGlzLl9iZ0NvbG9yLCBiZ0NvbG9yKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9iZ0NvbG9yID0gYmdDb2xvcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRleHQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdGV4dDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgdGV4dCh0ZXh0OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodGhpcy5fdGV4dCAhPT0gdGV4dCkge1xyXG4gICAgICAgICAgICB0aGlzLl90ZXh0ID0gdGV4dDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RleHR1cmUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZSA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRleHR1cmUoKTogVGV4dFRleHR1cmUyRCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl90ZXh0dXJlRmFjdG9yeSkge1xyXG4gICAgICAgICAgICB0aGlzLl90ZXh0dXJlRmFjdG9yeSA9ICh0aGlzLl9mb250ID8gY3JlYXRlVGV4dFRleHR1cmVGYWN0b3J5KHRoaXMuX2ZvbnQpIDogbnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5fdGV4dHVyZSkge1xyXG4gICAgICAgICAgICB0aGlzLl90ZXh0dXJlID0gKHRoaXMuX2ZnQ29sb3IgJiYgdGhpcy5fdGV4dCA/IHRoaXMuX3RleHR1cmVGYWN0b3J5KHRoaXMuX2ZnQ29sb3IsIHRoaXMuX3RleHQpIDogbnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLl90ZXh0dXJlO1xyXG4gICAgfVxyXG5cclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBmaXRUb0xhYmVsKGxhYmVsOiBMYWJlbCk6IExheW91dFBoYXNlMSB7XHJcbiAgICByZXR1cm4gPExheW91dFBoYXNlMT5mdW5jdGlvbiAocGFyZW50UHJlZlNpemU6IFNpemUpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB0ZXh0dXJlID0gbGFiZWwudGV4dHVyZTtcclxuICAgICAgICBwYXJlbnRQcmVmU2l6ZS53ID0gKHRleHR1cmUgPyB0ZXh0dXJlLncgOiAwKTtcclxuICAgICAgICBwYXJlbnRQcmVmU2l6ZS5oID0gKHRleHR1cmUgPyB0ZXh0dXJlLmggOiAwKTtcclxuICAgIH07XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3TGFiZWxQYWludGVyKGxhYmVsOiBMYWJlbCwgeEZyYWM6IG51bWJlciwgeUZyYWM6IG51bWJlciwgeEFuY2hvcj86IG51bWJlciwgeUFuY2hvcj86IG51bWJlciwgcm90YXRpb25fQ0NXUkFEPzogbnVtYmVyLCB0cnVuY2F0ZUxhYmVsPzogYm9vbGVhbikge1xyXG4gICAgY29uc3QgdGV4dHVyZVJlbmRlcmVyID0gbmV3IFRleHR1cmVSZW5kZXJlcigpO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB2aWV3cG9ydDogQm91bmRzVW5tb2RpZmlhYmxlKSB7XHJcblxyXG4gICAgICAgIGlmIChoYXN2YWwobGFiZWwuYmdDb2xvcikpIHtcclxuICAgICAgICAgICAgZ2wuY2xlYXJDb2xvcihsYWJlbC5iZ0NvbG9yLnIsIGxhYmVsLmJnQ29sb3IuZywgbGFiZWwuYmdDb2xvci5iLCBsYWJlbC5iZ0NvbG9yLmEpO1xyXG4gICAgICAgICAgICBnbC5jbGVhcihHTC5DT0xPUl9CVUZGRVJfQklUKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBsYWJlbFRleHQgPSBsYWJlbC50ZXh0O1xyXG4gICAgICAgIGlmICh0cnVuY2F0ZUxhYmVsKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHhSaWdodCA9IHZpZXdwb3J0LncgLSAyIC8gdmlld3BvcnQudztcclxuICAgICAgICAgICAgd2hpbGUgKGxhYmVsVGV4dCAmJiBsYWJlbFRleHQgIT09ICcuLi4nKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ2V0VGV4dFdpZHRoKGxhYmVsLmZvbnQsIGxhYmVsVGV4dCkgPiB4UmlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBsYWJlbFRleHQgPSBsYWJlbFRleHQuc3Vic3RyaW5nKDAsIGxhYmVsVGV4dC5sZW5ndGggLSA0KS5jb25jYXQoJy4uLicpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGFiZWwudGV4dCA9IGxhYmVsVGV4dDtcclxuICAgICAgICBpZiAobGFiZWwudGV4dHVyZSkge1xyXG4gICAgICAgICAgICB0ZXh0dXJlUmVuZGVyZXIuYmVnaW4oZ2wsIHZpZXdwb3J0KTtcclxuICAgICAgICAgICAgdGV4dHVyZVJlbmRlcmVyLmRyYXcoZ2wsIGxhYmVsLnRleHR1cmUsIHhGcmFjLCB5RnJhYywgeyB4QW5jaG9yOiB4QW5jaG9yLCB5QW5jaG9yOiBsYWJlbC50ZXh0dXJlLnlBbmNob3IoeUFuY2hvciksIHJvdGF0aW9uX0NDV1JBRDogcm90YXRpb25fQ0NXUkFEIH0pO1xyXG4gICAgICAgICAgICB0ZXh0dXJlUmVuZGVyZXIuZW5kKGdsKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5cclxuXHJcbiJdfQ==