UNPKG

webglimpse

Version:

Webglimpse is a data visualization library for the web.

97 lines 23.2 kB
/* * 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 { concatLines, GL, hasval } from '../util/util'; import { FloatDataTexture2D } from '../texture'; import { Program, UniformMatrix4f, UniformSampler2D, Uniform1f, Attribute } from '../shader'; import { newStaticBuffer } from '../buffer'; import { glOrthoAxis } from '../matrix'; export let heatmap_VERTSHADER = concatLines(' ', ' uniform mat4 u_modelViewMatrix; ', ' attribute vec4 a_vertCoord; ', ' attribute vec2 a_texCoord; ', ' varying vec2 v_texCoord; ', ' ', ' void main( ) { ', ' gl_Position = u_modelViewMatrix * a_vertCoord; ', ' v_texCoord = a_texCoord; ', ' } ', ' '); export let heatmap_FRAGSHADER = concatLines(' ', ' precision highp float; ', ' uniform sampler2D u_dataTex; ', ' uniform sampler2D u_colorTex; ', ' uniform float u_dataMin; ', ' uniform float u_dataMax; ', ' ', ' varying vec2 v_texCoord; ', ' ', ' void main() ', ' { ', ' float dataVal = texture2D( u_dataTex, v_texCoord ).r; ', ' float normalizedVal = ( dataVal - u_dataMin ) / ( u_dataMax - u_dataMin ); ', ' clamp( normalizedVal, 0.0, 1.0 ); ', ' ', ' vec4 color = texture2D( u_colorTex, vec2( normalizedVal, 0 ) ); ', ' gl_FragColor = color; ', ' gl_FragColor.a = 1.0; ', ' } '); /** * Simple heatmap painter which displays a 2d matrix of static data */ export function newHeatmapPainter(axis, colorAxis, data, colorTexture, options) { const blend = (hasval(options) && hasval(options.blend) ? options.blend : false); // only GL_RGBA is supported with GL_FLOAT texture type in webgl (see texture.ts) // we we currently need an array 4 times bigger than necessary in order to use FLOATS // to store the matrix data in a texture const array = new Float32Array(data.xSize * data.ySize * 4); for (let x = 0; x < data.xSize; x++) { for (let y = 0; y < data.ySize; y++) { const index = x * data.ySize + y; const value = data.array[index]; array[4 * index] = value; array[4 * index + 1] = value; array[4 * index + 2] = value; array[4 * index + 3] = value; } } data.array = array; const program = new Program(heatmap_VERTSHADER, heatmap_FRAGSHADER); const u_modelViewMatrix = new UniformMatrix4f(program, 'u_modelViewMatrix'); const u_dataTexture = new UniformSampler2D(program, 'u_dataTex'); const u_colorTexture = new UniformSampler2D(program, 'u_colorTex'); const u_dataMin = new Uniform1f(program, 'u_dataMin'); const u_dataMax = new Uniform1f(program, 'u_dataMax'); const a_vertCoord = new Attribute(program, 'a_vertCoord'); const a_texCoord = new Attribute(program, 'a_texCoord'); const texture = new FloatDataTexture2D(data.xSize, data.ySize, data.array); // points in triangle strip const vertCoordArray = [data.xMin, data.yMax, data.xMax, data.yMax, data.xMin, data.yMin, data.xMax, data.yMin]; const vertCoordFloatArray = new Float32Array(vertCoordArray); const vertCoordBuffer = newStaticBuffer(vertCoordFloatArray); // texture coordinates const texCoordArray = [0, 1, 1, 1, 0, 0, 1, 0]; const texCoordFloatArray = new Float32Array(texCoordArray); const texCoordBuffer = newStaticBuffer(texCoordFloatArray); const dim = 2; const vertexCount = 4; return function (gl, viewport) { if (blend) { gl.blendFuncSeparate(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ONE, GL.ONE_MINUS_SRC_ALPHA); gl.enable(GL.BLEND); } program.use(gl); u_dataTexture.setDataAndBind(gl, 0, texture); u_colorTexture.setDataAndBind(gl, 1, colorTexture); u_modelViewMatrix.setData(gl, glOrthoAxis(axis)); u_dataMin.setData(gl, colorAxis.vMin); u_dataMax.setData(gl, colorAxis.vMax); a_vertCoord.setDataAndEnable(gl, vertCoordBuffer, dim, GL.FLOAT); a_texCoord.setDataAndEnable(gl, texCoordBuffer, dim, GL.FLOAT); gl.drawArrays(GL.TRIANGLE_STRIP, 0, vertexCount); a_vertCoord.disable(gl); a_texCoord.disable(gl); u_dataTexture.unbind(gl); u_colorTexture.unbind(gl); program.endUse(gl); }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhdG1hcF9wYWludGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dlYmdsaW1wc2UvcGxvdC9oZWF0bWFwX3BhaW50ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E0Qkc7QUFDSCxPQUFPLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdkQsT0FBTyxFQUFXLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXpELE9BQU8sRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDN0YsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU1QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBdUJ4QyxNQUFNLENBQUMsSUFBSSxrQkFBa0IsR0FBRyxXQUFXLENBQ3ZDLDREQUE0RCxFQUM1RCw0REFBNEQsRUFDNUQsNERBQTRELEVBQzVELDREQUE0RCxFQUM1RCw0REFBNEQsRUFDNUQsNERBQTRELEVBQzVELDREQUE0RCxFQUM1RCw0REFBNEQsRUFDNUQsNERBQTRELEVBQzVELDREQUE0RCxFQUM1RCw0REFBNEQsQ0FDL0QsQ0FBQztBQUdGLE1BQU0sQ0FBQyxJQUFJLGtCQUFrQixHQUFHLFdBQVcsQ0FDdkMsbUNBQW1DLEVBQ25DLG1DQUFtQyxFQUNuQyxtQ0FBbUMsRUFDbkMsbUNBQW1DLEVBQ25DLG1DQUFtQyxFQUNuQyxtQ0FBbUMsRUFDbkMsbUNBQW1DLEVBQ25DLG1DQUFtQyxFQUNuQyxxRkFBcUYsRUFDckYscUZBQXFGLEVBQ3JGLHFGQUFxRixFQUNyRixxRkFBcUYsRUFDckYscUZBQXFGLEVBQ3JGLHFGQUFxRixFQUNyRixxRkFBcUYsRUFDckYscUZBQXFGLEVBQ3JGLHFGQUFx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QUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV0QyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFL0QsRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUVqRCxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkIsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QixjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFCLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkIsQ0FBQyxDQUFDO0FBQ04sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNCwgTWV0cm9uLCBJbmMuXHJcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXHJcbiAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcclxuICpcclxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXHJcbiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxyXG4gKlxyXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXHJcbiAqICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cclxuICogICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAqXHJcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXHJcbiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XHJcbiAqICAgIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCIgQU5EXHJcbiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXHJcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcclxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1JcclxuICogQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXHJcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcclxuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OXHJcbiAqIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXHJcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTXHJcbiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxyXG4gKi9cclxuaW1wb3J0IHsgY29uY2F0TGluZXMsIEdMLCBoYXN2YWwgfSBmcm9tICcuLi91dGlsL3V0aWwnO1xyXG5pbXBvcnQgeyBBeGlzMkQsIEF4aXMxRCB9IGZyb20gJy4vYXhpcyc7XHJcbmltcG9ydCB7IFRleHR1cmUsIEZsb2F0RGF0YVRleHR1cmUyRCB9IGZyb20gJy4uL3RleHR1cmUnO1xyXG5pbXBvcnQgeyBQYWludGVyIH0gZnJvbSAnLi4vY29yZSc7XHJcbmltcG9ydCB7IFByb2dyYW0sIFVuaWZvcm1NYXRyaXg0ZiwgVW5pZm9ybVNhbXBsZXIyRCwgVW5pZm9ybTFmLCBBdHRyaWJ1dGUgfSBmcm9tICcuLi9zaGFkZXInO1xyXG5pbXBvcnQgeyBuZXdTdGF0aWNCdWZmZXIgfSBmcm9tICcuLi9idWZmZXInO1xyXG5pbXBvcnQgeyBCb3VuZHNVbm1vZGlmaWFibGUgfSBmcm9tICcuLi9ib3VuZHMnO1xyXG5pbXBvcnQgeyBnbE9ydGhvQXhpcyB9IGZyb20gJy4uL21hdHJpeCc7XHJcblxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBIZWF0bWFwUGFpbnRlck9wdGlvbnMge1xyXG4gICAgYmxlbmQ/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEhlYXRNYXBEYXRhIHtcclxuICAgIC8vIG1hdHJpeCBkYXRhIHN0b3JlZCB4LW1ham9yXHJcbiAgICBhcnJheTogRmxvYXQzMkFycmF5O1xyXG5cclxuICAgIC8vIHNpemUgb2YgdGhlIG1hdHJpeFxyXG4gICAgeFNpemU6IG51bWJlcjtcclxuICAgIHlTaXplOiBudW1iZXI7XHJcblxyXG4gICAgLy8gYm91bmRzIG9mIHRoZSBtYXRyaXggaW4gYXhpcyBjb29yZGluYXRlc1xyXG4gICAgeE1pbjogbnVtYmVyO1xyXG4gICAgeE1heDogbnVtYmVyO1xyXG4gICAgeU1pbjogbnVtYmVyO1xyXG4gICAgeU1heDogbnVtYmVyO1xyXG59XHJcblxyXG5cclxuZXhwb3J0IGxldCBoZWF0bWFwX1ZFUlRTSEFERVIgPSBjb25jYXRMaW5lcyhcclxuICAgICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4OyAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgYXR0cmlidXRlIHZlYzQgYV92ZXJ0Q29vcmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgYXR0cmlidXRlIHZlYzIgYV90ZXhDb29yZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgdmFyeWluZyB2ZWMyIHZfdGV4Q29vcmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgdm9pZCBtYWluKCApIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgICAgIGdsX1Bvc2l0aW9uID0gdV9tb2RlbFZpZXdNYXRyaXggKiBhX3ZlcnRDb29yZDsgICAgJyxcclxuICAgICcgICAgICAgIHZfdGV4Q29vcmQgPSBhX3RleENvb3JkOyAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xyXG4pO1xyXG5cclxuXHJcbmV4cG9ydCBsZXQgaGVhdG1hcF9GUkFHU0hBREVSID0gY29uY2F0TGluZXMoXHJcbiAgICAnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIHByZWNpc2lvbiBoaWdocCBmbG9hdDsgICAgICAgICAnLFxyXG4gICAgJyAgdW5pZm9ybSBzYW1wbGVyMkQgdV9kYXRhVGV4OyAgICcsXHJcbiAgICAnICB1bmlmb3JtIHNhbXBsZXIyRCB1X2NvbG9yVGV4OyAgJyxcclxuICAgICcgIHVuaWZvcm0gZmxvYXQgdV9kYXRhTWluOyAgICAgICAnLFxyXG4gICAgJyAgdW5pZm9ybSBmbG9hdCB1X2RhdGFNYXg7ICAgICAgICcsXHJcbiAgICAnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIHZhcnlpbmcgdmVjMiB2X3RleENvb3JkOyAgICAgICAnLFxyXG4gICAgJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIHZvaWQgbWFpbigpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcsXHJcbiAgICAnICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLFxyXG4gICAgJyAgICAgZmxvYXQgZGF0YVZhbCA9IHRleHR1cmUyRCggdV9kYXRhVGV4LCB2X3RleENvb3JkICkucjsgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgIGZsb2F0IG5vcm1hbGl6ZWRWYWwgPSAoIGRhdGFWYWwgLSB1X2RhdGFNaW4gKSAvICggdV9kYXRhTWF4IC0gdV9kYXRhTWluICk7ICAgICcsXHJcbiAgICAnICAgICBjbGFtcCggbm9ybWFsaXplZFZhbCwgMC4wLCAxLjAgKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLFxyXG4gICAgJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgIHZlYzQgY29sb3IgPSB0ZXh0dXJlMkQoIHVfY29sb3JUZXgsIHZlYzIoIG5vcm1hbGl6ZWRWYWwsIDAgKSApOyAgICAgICAgICAgICAgICcsXHJcbiAgICAnICAgICBnbF9GcmFnQ29sb3IgPSBjb2xvcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLFxyXG4gICAgJyAgICAgZ2xfRnJhZ0NvbG9yLmEgPSAxLjA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcclxuKTtcclxuXHJcbi8qKlxyXG4gKiBTaW1wbGUgaGVhdG1hcCBwYWludGVyIHdoaWNoIGRpc3BsYXlzIGEgMmQgbWF0cml4IG9mIHN0YXRpYyBkYXRhXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbmV3SGVhdG1hcFBhaW50ZXIoYXhpczogQXhpczJELCBjb2xvckF4aXM6IEF4aXMxRCwgZGF0YTogSGVhdE1hcERhdGEsIGNvbG9yVGV4dHVyZTogVGV4dHVyZSwgb3B0aW9ucz86IEhlYXRtYXBQYWludGVyT3B0aW9ucyk6IFBhaW50ZXIge1xyXG5cclxuICAgIGNvbnN0IGJsZW5kID0gKGhhc3ZhbChvcHRpb25zKSAmJiBoYXN2YWwob3B0aW9ucy5ibGVuZCkgPyBvcHRpb25zLmJsZW5kIDogZmFsc2UpO1xyXG5cclxuICAgIC8vIG9ubHkgR0xfUkdCQSBpcyBzdXBwb3J0ZWQgd2l0aCBHTF9GTE9BVCB0ZXh0dXJlIHR5cGUgaW4gd2ViZ2wgKHNlZSB0ZXh0dXJlLnRzKVxyXG4gICAgLy8gd2Ugd2UgY3VycmVudGx5IG5lZWQgYW4gYXJyYXkgNCB0aW1lcyBiaWdnZXIgdGhhbiBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gdXNlIEZMT0FUU1xyXG4gICAgLy8gdG8gc3RvcmUgdGhlIG1hdHJpeCBkYXRhIGluIGEgdGV4dHVyZVxyXG4gICAgY29uc3QgYXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGRhdGEueFNpemUgKiBkYXRhLnlTaXplICogNCk7XHJcbiAgICBmb3IgKGxldCB4ID0gMDsgeCA8IGRhdGEueFNpemU7IHgrKykge1xyXG4gICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgZGF0YS55U2l6ZTsgeSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0geCAqIGRhdGEueVNpemUgKyB5O1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGRhdGEuYXJyYXlbaW5kZXhdO1xyXG5cclxuICAgICAgICAgICAgYXJyYXlbNCAqIGluZGV4XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICBhcnJheVs0ICogaW5kZXggKyAxXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICBhcnJheVs0ICogaW5kZXggKyAyXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICBhcnJheVs0ICogaW5kZXggKyAzXSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGRhdGEuYXJyYXkgPSBhcnJheTtcclxuXHJcbiAgICBjb25zdCBwcm9ncmFtID0gbmV3IFByb2dyYW0oaGVhdG1hcF9WRVJUU0hBREVSLCBoZWF0bWFwX0ZSQUdTSEFERVIpO1xyXG4gICAgY29uc3QgdV9tb2RlbFZpZXdNYXRyaXggPSBuZXcgVW5pZm9ybU1hdHJpeDRmKHByb2dyYW0sICd1X21vZGVsVmlld01hdHJpeCcpO1xyXG4gICAgY29uc3QgdV9kYXRhVGV4dHVyZSA9IG5ldyBVbmlmb3JtU2FtcGxlcjJEKHByb2dyYW0sICd1X2RhdGFUZXgnKTtcclxuICAgIGNvbnN0IHVfY29sb3JUZXh0dXJlID0gbmV3IFVuaWZvcm1TYW1wbGVyMkQocHJvZ3JhbSwgJ3VfY29sb3JUZXgnKTtcclxuICAgIGNvbnN0IHVfZGF0YU1pbiA9IG5ldyBVbmlmb3JtMWYocHJvZ3JhbSwgJ3VfZGF0YU1pbicpO1xyXG4gICAgY29uc3QgdV9kYXRhTWF4ID0gbmV3IFVuaWZvcm0xZihwcm9ncmFtLCAndV9kYXRhTWF4Jyk7XHJcbiAgICBjb25zdCBhX3ZlcnRDb29yZCA9IG5ldyBBdHRyaWJ1dGUocHJvZ3JhbSwgJ2FfdmVydENvb3JkJyk7XHJcbiAgICBjb25zdCBhX3RleENvb3JkID0gbmV3IEF0dHJpYnV0ZShwcm9ncmFtLCAnYV90ZXhDb29yZCcpO1xyXG5cclxuICAgIGNvbnN0IHRleHR1cmUgPSBuZXcgRmxvYXREYXRhVGV4dHVyZTJEKGRhdGEueFNpemUsIGRhdGEueVNpemUsIGRhdGEuYXJyYXkpO1xyXG5cclxuICAgIC8vIHBvaW50cyBpbiB0cmlhbmdsZSBzdHJpcFxyXG4gICAgY29uc3QgdmVydENvb3JkQXJyYXkgPSBbZGF0YS54TWluLCBkYXRhLnlNYXgsIGRhdGEueE1heCwgZGF0YS55TWF4LCBkYXRhLnhNaW4sIGRhdGEueU1pbiwgZGF0YS54TWF4LCBkYXRhLnlNaW5dO1xyXG4gICAgY29uc3QgdmVydENvb3JkRmxvYXRBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkodmVydENvb3JkQXJyYXkpO1xyXG4gICAgY29uc3QgdmVydENvb3JkQnVmZmVyID0gbmV3U3RhdGljQnVmZmVyKHZlcnRDb29yZEZsb2F0QXJyYXkpO1xyXG5cclxuICAgIC8vIHRleHR1cmUgY29vcmRpbmF0ZXNcclxuICAgIGNvbnN0IHRleENvb3JkQXJyYXkgPSBbMCwgMSwgMSwgMSwgMCwgMCwgMSwgMF07XHJcbiAgICBjb25zdCB0ZXhDb29yZEZsb2F0QXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KHRleENvb3JkQXJyYXkpO1xyXG4gICAgY29uc3QgdGV4Q29vcmRCdWZmZXIgPSBuZXdTdGF0aWNCdWZmZXIodGV4Q29vcmRGbG9hdEFycmF5KTtcclxuXHJcbiAgICBjb25zdCBkaW0gPSAyO1xyXG4gICAgY29uc3QgdmVydGV4Q291bnQgPSA0O1xyXG5cclxuICAgIHJldHVybiBmdW5jdGlvbiAoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdmlld3BvcnQ6IEJvdW5kc1VubW9kaWZpYWJsZSkge1xyXG5cclxuICAgICAgICBpZiAoYmxlbmQpIHtcclxuICAgICAgICAgICAgZ2wuYmxlbmRGdW5jU2VwYXJhdGUoR0wuU1JDX0FMUEhBLCBHTC5PTkVfTUlOVVNfU1JDX0FMUEhBLCBHTC5PTkUsIEdMLk9ORV9NSU5VU19TUkNfQUxQSEEpO1xyXG4gICAgICAgICAgICBnbC5lbmFibGUoR0wuQkxFTkQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJvZ3JhbS51c2UoZ2wpO1xyXG4gICAgICAgIHVfZGF0YVRleHR1cmUuc2V0RGF0YUFuZEJpbmQoZ2wsIDAsIHRleHR1cmUpO1xyXG4gICAgICAgIHVfY29sb3JUZXh0dXJlLnNldERhdGFBbmRCaW5kKGdsLCAxLCBjb2xvclRleHR1cmUpO1xyXG4gICAgICAgIHVfbW9kZWxWaWV3TWF0cml4LnNldERhdGEoZ2wsIGdsT3J0aG9BeGlzKGF4aXMpKTtcclxuXHJcbiAgICAgICAgdV9kYXRhTWluLnNldERhdGEoZ2wsIGNvbG9yQXhpcy52TWluKTtcclxuICAgICAgICB1X2RhdGFNYXguc2V0RGF0YShnbCwgY29sb3JBeGlzLnZNYXgpO1xyXG5cclxuICAgICAgICBhX3ZlcnRDb29yZC5zZXREYXRhQW5kRW5hYmxlKGdsLCB2ZXJ0Q29vcmRCdWZmZXIsIGRpbSwgR0wuRkxPQVQpO1xyXG4gICAgICAgIGFfdGV4Q29vcmQuc2V0RGF0YUFuZEVuYWJsZShnbCwgdGV4Q29vcmRCdWZmZXIsIGRpbSwgR0wuRkxPQVQpO1xyXG5cclxuICAgICAgICBnbC5kcmF3QXJyYXlzKEdMLlRSSUFOR0xFX1NUUklQLCAwLCB2ZXJ0ZXhDb3VudCk7XHJcblxyXG4gICAgICAgIGFfdmVydENvb3JkLmRpc2FibGUoZ2wpO1xyXG4gICAgICAgIGFfdGV4Q29vcmQuZGlzYWJsZShnbCk7XHJcbiAgICAgICAgdV9kYXRhVGV4dHVyZS51bmJpbmQoZ2wpO1xyXG4gICAgICAgIHVfY29sb3JUZXh0dXJlLnVuYmluZChnbCk7XHJcbiAgICAgICAgcHJvZ3JhbS5lbmRVc2UoZ2wpO1xyXG4gICAgfTtcclxufVxyXG4iXX0=