{"version":3,"sources":["/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/base.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/index.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/line.frag.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/line.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/line.vert.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/main.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/markers.frag.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/markers.js","/home/travis/build/bokeh/bokeh/bokehjs/build/js/tree/models/glyphs/webgl/markers.vert.js","/home/travis/build/bokeh/bokeh/bokehjs/node_modules/gloo2/gloo2.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxKA;AACA;AACA;AACA;AACA;AACA;ACLA;AACA;AACA;AACA;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChYA;AACA;AACA;AACA;ACHA;AACA;AACA;AACA;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5MA;AACA;AACA;AACA;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"generated.js","sourceRoot":"","sourcesContent":["/* models/glyphs/webgl/base */ function _(require, module, exports) {\n var color_1 = require(27) /* core/util/color */;\n var logging_1 = require(14) /* core/logging */;\n var BaseGLGlyph = /** @class */ (function () {\n function BaseGLGlyph(gl, glyph) {\n this.gl = gl;\n this.glyph = glyph;\n this.nvertices = 0;\n this.size_changed = false;\n this.data_changed = false;\n this.visuals_changed = false;\n this.init();\n }\n BaseGLGlyph.prototype.set_data_changed = function (n) {\n if (n != this.nvertices) {\n this.nvertices = n;\n this.size_changed = true;\n }\n this.data_changed = true;\n };\n BaseGLGlyph.prototype.set_visuals_changed = function () {\n this.visuals_changed = true;\n };\n BaseGLGlyph.prototype.render = function (_ctx, indices, mainglyph) {\n var _a;\n // Get transform\n var _b = [0, 1, 2], a = _b[0], b = _b[1], c = _b[2];\n var wx = 1; // Weights to scale our vectors\n var wy = 1;\n var _c = this.glyph.renderer.map_to_screen([a * wx, b * wx, c * wx], [a * wy, b * wy, c * wy]), dx = _c[0], dy = _c[1];\n if (isNaN(dx[0] + dx[1] + dx[2] + dy[0] + dy[1] + dy[2])) {\n logging_1.logger.warn(\"WebGL backend (\" + this.glyph.model.type + \"): falling back to canvas rendering\");\n return false;\n }\n // Try again, but with weighs so we're looking at ~100 in screen coordinates\n wx = 100 / Math.min(Math.max(Math.abs(dx[1] - dx[0]), 1e-12), 1e12);\n wy = 100 / Math.min(Math.max(Math.abs(dy[1] - dy[0]), 1e-12), 1e12);\n _a = this.glyph.renderer.map_to_screen([a * wx, b * wx, c * wx], [a * wy, b * wy, c * wy]), dx = _a[0], dy = _a[1];\n // Test how linear it is\n if ((Math.abs((dx[1] - dx[0]) - (dx[2] - dx[1])) > 1e-6) ||\n (Math.abs((dy[1] - dy[0]) - (dy[2] - dy[1])) > 1e-6)) {\n logging_1.logger.warn(\"WebGL backend (\" + this.glyph.model.type + \"): falling back to canvas rendering\");\n return false;\n }\n var _d = [(dx[1] - dx[0]) / wx, (dy[1] - dy[0]) / wy], sx = _d[0], sy = _d[1];\n var _e = this.glyph.renderer.plot_view.gl.canvas, width = _e.width, height = _e.height;\n var trans = {\n pixel_ratio: this.glyph.renderer.plot_view.canvas.pixel_ratio,\n width: width, height: height,\n dx: dx[0] / sx, dy: dy[0] / sy, sx: sx, sy: sy,\n };\n this.draw(indices, mainglyph, trans);\n return true;\n };\n return BaseGLGlyph;\n }());\n exports.BaseGLGlyph = BaseGLGlyph;\n function line_width(width) {\n // Increase small values to make it more similar to canvas\n if (width < 2) {\n width = Math.sqrt(width * 2);\n }\n return width;\n }\n exports.line_width = line_width;\n function fill_array_with_float(n, val) {\n var a = new Float32Array(n);\n for (var i = 0, end = n; i < end; i++) {\n a[i] = val;\n }\n return a;\n }\n exports.fill_array_with_float = fill_array_with_float;\n function fill_array_with_vec(n, m, val) {\n var a = new Float32Array(n * m);\n for (var i = 0; i < n; i++) {\n for (var j = 0; j < m; j++) {\n a[i * m + j] = val[j];\n }\n }\n return a;\n }\n exports.fill_array_with_vec = fill_array_with_vec;\n function visual_prop_is_singular(visual, propname) {\n // This touches the internals of the visual, so we limit use in this function\n // See renderer.ts:cache_select() for similar code\n return visual[propname].spec.value !== undefined;\n }\n exports.visual_prop_is_singular = visual_prop_is_singular;\n function attach_float(prog, vbo, att_name, n, visual, name) {\n // Attach a float attribute to the program. Use singleton value if we can,\n // otherwise use VBO to apply array.\n if (!visual.doit) {\n vbo.used = false;\n prog.set_attribute(att_name, 'float', [0]);\n }\n else if (visual_prop_is_singular(visual, name)) {\n vbo.used = false;\n prog.set_attribute(att_name, 'float', visual[name].value());\n }\n else {\n vbo.used = true;\n var a = new Float32Array(visual.cache[name + '_array']);\n vbo.set_size(n * 4);\n vbo.set_data(0, a);\n prog.set_attribute(att_name, 'float', vbo);\n }\n }\n exports.attach_float = attach_float;\n function attach_color(prog, vbo, att_name, n, visual, prefix) {\n // Attach the color attribute to the program. If there's just one color,\n // then use this single color for all vertices (no VBO). Otherwise we\n // create an array and upload that to the VBO, which we attahce to the prog.\n var rgba;\n var m = 4;\n var colorname = prefix + '_color';\n var alphaname = prefix + '_alpha';\n if (!visual.doit) {\n // Don't draw (draw transparent)\n vbo.used = false;\n prog.set_attribute(att_name, 'vec4', [0, 0, 0, 0]);\n }\n else if (visual_prop_is_singular(visual, colorname) && visual_prop_is_singular(visual, alphaname)) {\n // Nice and simple; both color and alpha are singular\n vbo.used = false;\n rgba = color_1.color2rgba(visual[colorname].value(), visual[alphaname].value());\n prog.set_attribute(att_name, 'vec4', rgba);\n }\n else {\n // Use vbo; we need an array for both the color and the alpha\n var alphas = void 0, colors = void 0;\n vbo.used = true;\n // Get array of colors\n if (visual_prop_is_singular(visual, colorname)) {\n colors = ((function () {\n var result = [];\n for (var i = 0, end = n; i < end; i++) {\n result.push(visual[colorname].value());\n }\n return result;\n })());\n }\n else {\n colors = visual.cache[colorname + '_array'];\n }\n // Get array of alphas\n if (visual_prop_is_singular(visual, alphaname)) {\n alphas = fill_array_with_float(n, visual[alphaname].value());\n }\n else {\n alphas = visual.cache[alphaname + '_array'];\n }\n // Create array of rgbs\n var a = new Float32Array(n * m);\n for (var i = 0, end = n; i < end; i++) {\n rgba = color_1.color2rgba(colors[i], alphas[i]);\n for (var j = 0, endj = m; j < endj; j++) {\n a[(i * m) + j] = rgba[j];\n }\n }\n // Attach vbo\n vbo.set_size(n * m * 4);\n vbo.set_data(0, a);\n prog.set_attribute(att_name, 'vec4', vbo);\n }\n }\n exports.attach_color = attach_color;\n}\n","/* models/glyphs/webgl/index */ function _(require, module, exports) {\n var tslib_1 = require(391) /* tslib */;\n tslib_1.__exportStar(require(454) /* ./line */, exports);\n tslib_1.__exportStar(require(458) /* ./markers */, exports);\n}\n","/* models/glyphs/webgl/line.frag */ function _(require, module, exports) {\n exports.fragment_shader = \"\\nprecision mediump float;\\n\\nconst float PI = 3.14159265358979323846264;\\nconst float THETA = 15.0 * 3.14159265358979323846264/180.0;\\n\\nuniform sampler2D u_dash_atlas;\\n\\nuniform vec2 u_linecaps;\\nuniform float u_miter_limit;\\nuniform float u_linejoin;\\nuniform float u_antialias;\\nuniform float u_dash_phase;\\nuniform float u_dash_period;\\nuniform float u_dash_index;\\nuniform vec2 u_dash_caps;\\nuniform float u_closed;\\n\\nvarying vec4 v_color;\\nvarying vec2 v_segment;\\nvarying vec2 v_angles;\\nvarying vec2 v_texcoord;\\nvarying vec2 v_miter;\\nvarying float v_length;\\nvarying float v_linewidth;\\n\\n// Compute distance to cap ----------------------------------------------------\\nfloat cap( int type, float dx, float dy, float t, float linewidth )\\n{\\n float d = 0.0;\\n dx = abs(dx);\\n dy = abs(dy);\\n if (type == 0) discard; // None\\n else if (type == 1) d = sqrt(dx*dx+dy*dy); // Round\\n else if (type == 3) d = (dx+abs(dy)); // Triangle in\\n else if (type == 2) d = max(abs(dy),(t+dx-abs(dy))); // Triangle out\\n else if (type == 4) d = max(dx,dy); // Square\\n else if (type == 5) d = max(dx+t,dy); // Butt\\n return d;\\n}\\n\\n// Compute distance to join -------------------------------------------------\\nfloat join( in int type, in float d, in vec2 segment, in vec2 texcoord, in vec2 miter,\\n in float linewidth )\\n{\\n // texcoord.x is distance from start\\n // texcoord.y is distance from centerline\\n // segment.x and y indicate the limits (as for texcoord.x) for this segment\\n\\n float dx = texcoord.x;\\n\\n // Round join\\n if( type == 1 ) {\\n if (dx < segment.x) {\\n d = max(d,length( texcoord - vec2(segment.x,0.0)));\\n //d = length( texcoord - vec2(segment.x,0.0));\\n } else if (dx > segment.y) {\\n d = max(d,length( texcoord - vec2(segment.y,0.0)));\\n //d = length( texcoord - vec2(segment.y,0.0));\\n }\\n }\\n // Bevel join\\n else if ( type == 2 ) {\\n if (dx < segment.x) {\\n vec2 x = texcoord - vec2(segment.x,0.0);\\n d = max(d, max(abs(x.x), abs(x.y)));\\n\\n } else if (dx > segment.y) {\\n vec2 x = texcoord - vec2(segment.y,0.0);\\n d = max(d, max(abs(x.x), abs(x.y)));\\n }\\n /* Original code for bevel which does not work for us\\n if( (dx < segment.x) || (dx > segment.y) )\\n d = max(d, min(abs(x.x),abs(x.y)));\\n */\\n }\\n\\n return d;\\n}\\n\\nvoid main()\\n{\\n // If color is fully transparent we just discard the fragment\\n if( v_color.a <= 0.0 ) {\\n discard;\\n }\\n\\n // Test if dash pattern is the solid one (0)\\n bool solid = (u_dash_index == 0.0);\\n\\n // Test if path is closed\\n bool closed = (u_closed > 0.0);\\n\\n vec4 color = v_color;\\n float dx = v_texcoord.x;\\n float dy = v_texcoord.y;\\n float t = v_linewidth/2.0-u_antialias;\\n float width = 1.0; //v_linewidth; original code had dashes scale with line width, we do not\\n float d = 0.0;\\n\\n vec2 linecaps = u_linecaps;\\n vec2 dash_caps = u_dash_caps;\\n float line_start = 0.0;\\n float line_stop = v_length;\\n\\n // Apply miter limit; fragments too far into the miter are simply discarded\\n if( (dx < v_segment.x) || (dx > v_segment.y) ) {\\n float into_miter = max(v_segment.x - dx, dx - v_segment.y);\\n if (into_miter > u_miter_limit*v_linewidth/2.0)\\n discard;\\n }\\n\\n // Solid line --------------------------------------------------------------\\n if( solid ) {\\n d = abs(dy);\\n if( (!closed) && (dx < line_start) ) {\\n d = cap( int(u_linecaps.x), abs(dx), abs(dy), t, v_linewidth );\\n }\\n else if( (!closed) && (dx > line_stop) ) {\\n d = cap( int(u_linecaps.y), abs(dx)-line_stop, abs(dy), t, v_linewidth );\\n }\\n else {\\n d = join( int(u_linejoin), abs(dy), v_segment, v_texcoord, v_miter, v_linewidth );\\n }\\n\\n // Dash line --------------------------------------------------------------\\n } else {\\n float segment_start = v_segment.x;\\n float segment_stop = v_segment.y;\\n float segment_center= (segment_start+segment_stop)/2.0;\\n float freq = u_dash_period*width;\\n float u = mod( dx + u_dash_phase*width, freq);\\n vec4 tex = texture2D(u_dash_atlas, vec2(u/freq, u_dash_index)) * 255.0 -10.0; // conversion to int-like\\n float dash_center= tex.x * width;\\n float dash_type = tex.y;\\n float _start = tex.z * width;\\n float _stop = tex.a * width;\\n float dash_start = dx - u + _start;\\n float dash_stop = dx - u + _stop;\\n\\n // Compute extents of the first dash (the one relative to v_segment.x)\\n // Note: this could be computed in the vertex shader\\n if( (dash_stop < segment_start) && (dash_caps.x != 5.0) ) {\\n float u = mod(segment_start + u_dash_phase*width, freq);\\n vec4 tex = texture2D(u_dash_atlas, vec2(u/freq, u_dash_index)) * 255.0 -10.0; // conversion to int-like\\n dash_center= tex.x * width;\\n //dash_type = tex.y;\\n float _start = tex.z * width;\\n float _stop = tex.a * width;\\n dash_start = segment_start - u + _start;\\n dash_stop = segment_start - u + _stop;\\n }\\n\\n // Compute extents of the last dash (the one relatives to v_segment.y)\\n // Note: This could be computed in the vertex shader\\n else if( (dash_start > segment_stop) && (dash_caps.y != 5.0) ) {\\n float u = mod(segment_stop + u_dash_phase*width, freq);\\n vec4 tex = texture2D(u_dash_atlas, vec2(u/freq, u_dash_index)) * 255.0 -10.0; // conversion to int-like\\n dash_center= tex.x * width;\\n //dash_type = tex.y;\\n float _start = tex.z * width;\\n float _stop = tex.a * width;\\n dash_start = segment_stop - u + _start;\\n dash_stop = segment_stop - u + _stop;\\n }\\n\\n // This test if the we are dealing with a discontinuous angle\\n bool discontinuous = ((dx < segment_center) && abs(v_angles.x) > THETA) ||\\n ((dx >= segment_center) && abs(v_angles.y) > THETA);\\n //if( dx < line_start) discontinuous = false;\\n //if( dx > line_stop) discontinuous = false;\\n\\n float d_join = join( int(u_linejoin), abs(dy),\\n v_segment, v_texcoord, v_miter, v_linewidth );\\n\\n // When path is closed, we do not have room for linecaps, so we make room\\n // by shortening the total length\\n if (closed) {\\n line_start += v_linewidth/2.0;\\n line_stop -= v_linewidth/2.0;\\n }\\n\\n // We also need to take antialias area into account\\n //line_start += u_antialias;\\n //line_stop -= u_antialias;\\n\\n // Check is dash stop is before line start\\n if( dash_stop <= line_start ) {\\n discard;\\n }\\n // Check is dash start is beyond line stop\\n if( dash_start >= line_stop ) {\\n discard;\\n }\\n\\n // Check if current dash start is beyond segment stop\\n if( discontinuous ) {\\n // Dash start is beyond segment, we discard\\n if( (dash_start > segment_stop) ) {\\n discard;\\n //gl_FragColor = vec4(1.0,0.0,0.0,.25); return;\\n }\\n\\n // Dash stop is before segment, we discard\\n if( (dash_stop < segment_start) ) {\\n discard; //gl_FragColor = vec4(0.0,1.0,0.0,.25); return;\\n }\\n\\n // Special case for round caps (nicer with this)\\n if( dash_caps.x == 1.0 ) {\\n if( (u > _stop) && (dash_stop > segment_stop ) && (abs(v_angles.y) < PI/2.0)) {\\n discard;\\n }\\n }\\n\\n // Special case for round caps (nicer with this)\\n if( dash_caps.y == 1.0 ) {\\n if( (u < _start) && (dash_start < segment_start ) && (abs(v_angles.x) < PI/2.0)) {\\n discard;\\n }\\n }\\n\\n // Special case for triangle caps (in & out) and square\\n // We make sure the cap stop at crossing frontier\\n if( (dash_caps.x != 1.0) && (dash_caps.x != 5.0) ) {\\n if( (dash_start < segment_start ) && (abs(v_angles.x) < PI/2.0) ) {\\n float a = v_angles.x/2.0;\\n float x = (segment_start-dx)*cos(a) - dy*sin(a);\\n float y = (segment_start-dx)*sin(a) + dy*cos(a);\\n if( x > 0.0 ) discard;\\n // We transform the cap into square to avoid holes\\n dash_caps.x = 4.0;\\n }\\n }\\n\\n // Special case for triangle caps (in & out) and square\\n // We make sure the cap stop at crossing frontier\\n if( (dash_caps.y != 1.0) && (dash_caps.y != 5.0) ) {\\n if( (dash_stop > segment_stop ) && (abs(v_angles.y) < PI/2.0) ) {\\n float a = v_angles.y/2.0;\\n float x = (dx-segment_stop)*cos(a) - dy*sin(a);\\n float y = (dx-segment_stop)*sin(a) + dy*cos(a);\\n if( x > 0.0 ) discard;\\n // We transform the caps into square to avoid holes\\n dash_caps.y = 4.0;\\n }\\n }\\n }\\n\\n // Line cap at start\\n if( (dx < line_start) && (dash_start < line_start) && (dash_stop > line_start) ) {\\n d = cap( int(linecaps.x), dx-line_start, dy, t, v_linewidth);\\n }\\n // Line cap at stop\\n else if( (dx > line_stop) && (dash_stop > line_stop) && (dash_start < line_stop) ) {\\n d = cap( int(linecaps.y), dx-line_stop, dy, t, v_linewidth);\\n }\\n // Dash cap left - dash_type = -1, 0 or 1, but there may be roundoff errors\\n else if( dash_type < -0.5 ) {\\n d = cap( int(dash_caps.y), abs(u-dash_center), dy, t, v_linewidth);\\n if( (dx > line_start) && (dx < line_stop) )\\n d = max(d,d_join);\\n }\\n // Dash cap right\\n else if( dash_type > 0.5 ) {\\n d = cap( int(dash_caps.x), abs(dash_center-u), dy, t, v_linewidth);\\n if( (dx > line_start) && (dx < line_stop) )\\n d = max(d,d_join);\\n }\\n // Dash body (plain)\\n else {// if( dash_type > -0.5 && dash_type < 0.5) {\\n d = abs(dy);\\n }\\n\\n // Line join\\n if( (dx > line_start) && (dx < line_stop)) {\\n if( (dx <= segment_start) && (dash_start <= segment_start)\\n && (dash_stop >= segment_start) ) {\\n d = d_join;\\n // Antialias at outer border\\n float angle = PI/2.+v_angles.x;\\n float f = abs( (segment_start - dx)*cos(angle) - dy*sin(angle));\\n d = max(f,d);\\n }\\n else if( (dx > segment_stop) && (dash_start <= segment_stop)\\n && (dash_stop >= segment_stop) ) {\\n d = d_join;\\n // Antialias at outer border\\n float angle = PI/2.+v_angles.y;\\n float f = abs((dx - segment_stop)*cos(angle) - dy*sin(angle));\\n d = max(f,d);\\n }\\n else if( dx < (segment_start - v_linewidth/2.)) {\\n discard;\\n }\\n else if( dx > (segment_stop + v_linewidth/2.)) {\\n discard;\\n }\\n }\\n else if( dx < (segment_start - v_linewidth/2.)) {\\n discard;\\n }\\n else if( dx > (segment_stop + v_linewidth/2.)) {\\n discard;\\n }\\n }\\n\\n // Distance to border ------------------------------------------------------\\n d = d - t;\\n if( d < 0.0 ) {\\n gl_FragColor = color;\\n } else {\\n d /= u_antialias;\\n gl_FragColor = vec4(color.rgb, exp(-d*d)*color.a);\\n }\\n}\\n\";\n}\n","/* models/glyphs/webgl/line */ function _(require, module, exports) {\n var tslib_1 = require(391) /* tslib */;\n var gloo2_1 = require(460) /* gloo2 */;\n var base_1 = require(451) /* ./base */;\n var line_vert_1 = require(455) /* ./line.vert */;\n var line_frag_1 = require(453) /* ./line.frag */;\n var color_1 = require(27) /* core/util/color */;\n var DashAtlas = /** @class */ (function () {\n function DashAtlas(gl) {\n this._atlas = {};\n this._index = 0;\n this._width = 256;\n this._height = 256;\n // Init texture\n this.tex = new gloo2_1.Texture2D(gl);\n this.tex.set_wrapping(gl.REPEAT, gl.REPEAT);\n this.tex.set_interpolation(gl.NEAREST, gl.NEAREST);\n this.tex.set_size([this._height, this._width], gl.RGBA);\n this.tex.set_data([0, 0], [this._height, this._width], new Uint8Array(this._height * this._width * 4));\n // Init with solid line (index 0 is reserved for this)\n this.get_atlas_data([1]);\n }\n DashAtlas.prototype.get_atlas_data = function (pattern) {\n var key = pattern.join('-');\n var findex_period = this._atlas[key];\n if (findex_period === undefined) {\n var _a = this.make_pattern(pattern), data = _a[0], period = _a[1];\n this.tex.set_data([this._index, 0], [1, this._width], new Uint8Array(data.map(function (x) { return x + 10; })));\n this._atlas[key] = [this._index / this._height, period];\n this._index += 1;\n }\n return this._atlas[key];\n };\n DashAtlas.prototype.make_pattern = function (pattern) {\n // A pattern is defined as on/off sequence of segments\n // It must be a multiple of 2\n if (pattern.length > 1 && pattern.length % 2) {\n pattern = pattern.concat(pattern);\n }\n // Period is sum of elements\n var period = 0;\n for (var _i = 0, pattern_1 = pattern; _i < pattern_1.length; _i++) {\n var v = pattern_1[_i];\n period += v;\n }\n // Find all start and end of on-segment only\n var C = [];\n var c = 0;\n for (var i = 0, end = pattern.length + 2; i < end; i += 2) {\n var a = Math.max(0.0001, pattern[i % pattern.length]);\n var b = Math.max(0.0001, pattern[(i + 1) % pattern.length]);\n C.push(c, c + a);\n c += a + b;\n }\n // Build pattern\n var n = this._width;\n var Z = new Float32Array(n * 4);\n for (var i = 0, end = n; i < end; i++) {\n var dash_end = void 0, dash_start = void 0, dash_type = void 0;\n var x = (period * i) / (n - 1);\n // get index at min - index = np.argmin(abs(C-(x)))\n var index = 0;\n var val_at_index = 1e16;\n for (var j = 0, endj = C.length; j < endj; j++) {\n var val = Math.abs(C[j] - x);\n if (val < val_at_index) {\n index = j;\n val_at_index = val;\n }\n }\n if ((index % 2) === 0) {\n dash_type = (x <= C[index]) ? +1 : 0;\n dash_start = C[index];\n dash_end = C[index + 1];\n }\n else {\n dash_type = (x > C[index]) ? -1 : 0;\n dash_start = C[index - 1];\n dash_end = C[index];\n }\n Z[(i * 4) + 0] = C[index];\n Z[(i * 4) + 1] = dash_type;\n Z[(i * 4) + 2] = dash_start;\n Z[(i * 4) + 3] = dash_end;\n }\n return [Z, period];\n };\n return DashAtlas;\n }());\n var joins = { miter: 0, round: 1, bevel: 2 };\n var caps = {\n '': 0, none: 0, '.': 0,\n round: 1, ')': 1, '(': 1, o: 1,\n 'triangle in': 2, '<': 2,\n 'triangle out': 3, '>': 3,\n square: 4, '[': 4, ']': 4, '=': 4,\n butt: 5, '|': 5,\n };\n var LineGLGlyph = /** @class */ (function (_super) {\n tslib_1.__extends(LineGLGlyph, _super);\n function LineGLGlyph() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n LineGLGlyph.prototype.init = function () {\n var gl = this.gl;\n this._scale_aspect = 0; // keep track, so we know when we need to update segment data\n var vert = line_vert_1.vertex_shader;\n var frag = line_frag_1.fragment_shader;\n // The program\n this.prog = new gloo2_1.Program(gl);\n this.prog.set_shaders(vert, frag);\n this.index_buffer = new gloo2_1.IndexBuffer(gl);\n // Buffers\n this.vbo_position = new gloo2_1.VertexBuffer(gl);\n this.vbo_tangents = new gloo2_1.VertexBuffer(gl);\n this.vbo_segment = new gloo2_1.VertexBuffer(gl);\n this.vbo_angles = new gloo2_1.VertexBuffer(gl);\n this.vbo_texcoord = new gloo2_1.VertexBuffer(gl);\n // Dash atlas\n this.dash_atlas = new DashAtlas(gl);\n };\n LineGLGlyph.prototype.draw = function (indices, mainGlyph, trans) {\n var mainGlGlyph = mainGlyph.glglyph;\n if (mainGlGlyph.data_changed) {\n if (!(isFinite(trans.dx) && isFinite(trans.dy))) {\n return; // not sure why, but it happens on init sometimes (#4367)\n }\n mainGlGlyph._baked_offset = [trans.dx, trans.dy]; // float32 precision workaround; used in _bake() and below\n mainGlGlyph._set_data();\n mainGlGlyph.data_changed = false;\n }\n if (this.visuals_changed) {\n this._set_visuals();\n this.visuals_changed = false;\n }\n // Decompose x-y scale into scalar scale and aspect-vector.\n var sx = trans.sx, sy = trans.sy;\n var scale_length = Math.sqrt(sx * sx + sy * sy);\n sx /= scale_length;\n sy /= scale_length;\n // Do we need to re-calculate segment data and cumsum?\n if (Math.abs(this._scale_aspect - sy / sx) > Math.abs(1e-3 * this._scale_aspect)) {\n mainGlGlyph._update_scale(sx, sy);\n this._scale_aspect = sy / sx;\n }\n // Select buffers from main glyph\n // (which may be this glyph but maybe not if this is a (non)selection glyph)\n this.prog.set_attribute('a_position', 'vec2', mainGlGlyph.vbo_position);\n this.prog.set_attribute('a_tangents', 'vec4', mainGlGlyph.vbo_tangents);\n this.prog.set_attribute('a_segment', 'vec2', mainGlGlyph.vbo_segment);\n this.prog.set_attribute('a_angles', 'vec2', mainGlGlyph.vbo_angles);\n this.prog.set_attribute('a_texcoord', 'vec2', mainGlGlyph.vbo_texcoord);\n //\n this.prog.set_uniform('u_length', 'float', [mainGlGlyph.cumsum]);\n this.prog.set_texture('u_dash_atlas', this.dash_atlas.tex);\n // Handle transformation to device coordinates\n var baked_offset = mainGlGlyph._baked_offset;\n this.prog.set_uniform('u_pixel_ratio', 'float', [trans.pixel_ratio]);\n this.prog.set_uniform('u_canvas_size', 'vec2', [trans.width, trans.height]);\n this.prog.set_uniform('u_offset', 'vec2', [trans.dx - baked_offset[0], trans.dy - baked_offset[1]]);\n this.prog.set_uniform('u_scale_aspect', 'vec2', [sx, sy]);\n this.prog.set_uniform('u_scale_length', 'float', [scale_length]);\n this.I_triangles = mainGlGlyph.I_triangles;\n if (this.I_triangles.length < 65535) {\n // Data is small enough to draw in one pass\n this.index_buffer.set_size(this.I_triangles.length * 2);\n this.index_buffer.set_data(0, new Uint16Array(this.I_triangles));\n this.prog.draw(this.gl.TRIANGLES, this.index_buffer);\n // @prog.draw(@gl.LINE_STRIP, @index_buffer) # Use this to draw the line skeleton\n }\n else {\n // Work around the limit that the indexbuffer must be uint16. We draw in chunks.\n // First collect indices in chunks\n indices = Array.from(this.I_triangles);\n var nvertices = this.I_triangles.length;\n var chunksize = 64008; // 65536 max. 64008 is divisible by 12\n var chunks = [];\n for (var i = 0, end = Math.ceil(nvertices / chunksize); i < end; i++) {\n chunks.push([]);\n }\n for (var i = 0, end = indices.length; i < end; i++) {\n var uint16_index = indices[i] % chunksize;\n var chunk = Math.floor(indices[i] / chunksize);\n chunks[chunk].push(uint16_index);\n }\n // Then draw each chunk\n for (var chunk = 0, end = chunks.length; chunk < end; chunk++) {\n var these_indices = new Uint16Array(chunks[chunk]);\n var offset = chunk * chunksize * 4;\n if (these_indices.length === 0) {\n continue;\n }\n this.prog.set_attribute('a_position', 'vec2', mainGlGlyph.vbo_position, 0, offset * 2);\n this.prog.set_attribute('a_tangents', 'vec4', mainGlGlyph.vbo_tangents, 0, offset * 4);\n this.prog.set_attribute('a_segment', 'vec2', mainGlGlyph.vbo_segment, 0, offset * 2);\n this.prog.set_attribute('a_angles', 'vec2', mainGlGlyph.vbo_angles, 0, offset * 2);\n this.prog.set_attribute('a_texcoord', 'vec2', mainGlGlyph.vbo_texcoord, 0, offset * 2);\n // The actual drawing\n this.index_buffer.set_size(these_indices.length * 2);\n this.index_buffer.set_data(0, these_indices);\n this.prog.draw(this.gl.TRIANGLES, this.index_buffer);\n }\n }\n };\n LineGLGlyph.prototype._set_data = function () {\n this._bake();\n this.vbo_position.set_size(this.V_position.length * 4);\n this.vbo_position.set_data(0, this.V_position);\n this.vbo_tangents.set_size(this.V_tangents.length * 4);\n this.vbo_tangents.set_data(0, this.V_tangents);\n this.vbo_angles.set_size(this.V_angles.length * 4);\n this.vbo_angles.set_data(0, this.V_angles);\n this.vbo_texcoord.set_size(this.V_texcoord.length * 4);\n this.vbo_texcoord.set_data(0, this.V_texcoord);\n };\n LineGLGlyph.prototype._set_visuals = function () {\n var _a;\n var color = color_1.color2rgba(this.glyph.visuals.line.line_color.value(), this.glyph.visuals.line.line_alpha.value());\n var cap = caps[this.glyph.visuals.line.line_cap.value()];\n var join = joins[this.glyph.visuals.line.line_join.value()];\n this.prog.set_uniform('u_color', 'vec4', color);\n this.prog.set_uniform('u_linewidth', 'float', [this.glyph.visuals.line.line_width.value()]);\n this.prog.set_uniform('u_antialias', 'float', [0.9]); // Smaller aa-region to obtain crisper images\n this.prog.set_uniform('u_linecaps', 'vec2', [cap, cap]);\n this.prog.set_uniform('u_linejoin', 'float', [join]);\n this.prog.set_uniform('u_miter_limit', 'float', [10.0]); // 10 should be a good value\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit\n var dash_pattern = this.glyph.visuals.line.line_dash.value();\n var dash_index = 0;\n var dash_period = 1;\n if (dash_pattern.length) {\n _a = this.dash_atlas.get_atlas_data(dash_pattern), dash_index = _a[0], dash_period = _a[1];\n }\n this.prog.set_uniform('u_dash_index', 'float', [dash_index]); // 0 means solid line\n this.prog.set_uniform('u_dash_phase', 'float', [this.glyph.visuals.line.line_dash_offset.value()]);\n this.prog.set_uniform('u_dash_period', 'float', [dash_period]);\n this.prog.set_uniform('u_dash_caps', 'vec2', [cap, cap]);\n this.prog.set_uniform('u_closed', 'float', [0]); // We dont do closed lines\n };\n LineGLGlyph.prototype._bake = function () {\n // This is what you get if you port 50 lines of numpy code to JS.\n // V_segment is handled in another method, because it depends on the aspect\n // ratio of the scale (The original paper/code assumed isotropic scaling).\n //\n // Buffer dtype from the Python implementation:\n //\n // self.vtype = np.dtype( [('a_position', 'f4', 2),\n // ('a_segment', 'f4', 2),\n // ('a_angles', 'f4', 2),\n // ('a_tangents', 'f4', 4),\n // ('a_texcoord', 'f4', 2) ])\n // Init array of implicit shape nx2\n var I, T, V_angles2, V_position2, V_tangents2, V_texcoord2, Vp, Vt;\n var n = this.nvertices;\n var _x = new Float64Array(this.glyph._x);\n var _y = new Float64Array(this.glyph._y);\n // Init vertex data\n var V_position = (Vp = new Float32Array(n * 2));\n //V_segment = new Float32Array(n*2) # Done later\n var V_angles = new Float32Array(n * 2);\n var V_tangents = (Vt = new Float32Array(n * 4)); // mind the 4!\n // Position\n for (var i = 0, end = n; i < end; i++) {\n V_position[(i * 2) + 0] = _x[i] + this._baked_offset[0];\n V_position[(i * 2) + 1] = _y[i] + this._baked_offset[1];\n }\n // Tangents & norms (need tangents to calculate segments based on scale)\n this.tangents = (T = new Float32Array((n * 2) - 2));\n for (var i = 0, end = n - 1; i < end; i++) {\n T[(i * 2) + 0] = Vp[((i + 1) * 2) + 0] - Vp[(i * 2) + 0];\n T[(i * 2) + 1] = Vp[((i + 1) * 2) + 1] - Vp[(i * 2) + 1];\n }\n for (var i = 0, end = n - 1; i < end; i++) {\n // V['a_tangents'][+1:, :2] = T\n V_tangents[((i + 1) * 4) + 0] = T[(i * 2) + 0];\n V_tangents[((i + 1) * 4) + 1] = T[(i * 2) + 1];\n // V['a_tangents'][:-1, 2:] = T\n V_tangents[(i * 4) + 2] = T[(i * 2) + 0];\n V_tangents[(i * 4) + 3] = T[(i * 2) + 1];\n }\n // V['a_tangents'][0 , :2] = T[0]\n V_tangents[(0 * 4) + 0] = T[0];\n V_tangents[(0 * 4) + 1] = T[1];\n // V['a_tangents'][ -1, 2:] = T[-1]\n V_tangents[((n - 1) * 4) + 2] = T[((n - 2) * 2) + 0];\n V_tangents[((n - 1) * 4) + 3] = T[((n - 2) * 2) + 1];\n // Angles\n var A = new Float32Array(n);\n for (var i = 0, end = n; i < end; i++) {\n A[i] = Math.atan2((Vt[(i * 4) + 0] * Vt[(i * 4) + 3]) - (Vt[(i * 4) + 1] * Vt[(i * 4) + 2]), (Vt[(i * 4) + 0] * Vt[(i * 4) + 2]) + (Vt[(i * 4) + 1] * Vt[(i * 4) + 3]));\n }\n for (var i = 0, end = n - 1; i < end; i++) {\n V_angles[(i * 2) + 0] = A[i];\n V_angles[(i * 2) + 1] = A[i + 1];\n }\n // Step 1: A -- B -- C => A -- B, B' -- C\n // Repeat our array 4 times\n var m = (4 * n) - 4;\n this.V_position = (V_position2 = new Float32Array(m * 2));\n this.V_angles = (V_angles2 = new Float32Array(m * 2));\n this.V_tangents = (V_tangents2 = new Float32Array(m * 4)); // mind the 4!\n this.V_texcoord = (V_texcoord2 = new Float32Array(m * 2));\n var o = 2;\n //\n // Arg, we really need an ndarray thing in JS :/\n for (var i = 0, end = n; i < end; i++) { // all nodes on the line\n for (var j = 0; j < 4; j++) { // the four quad vertices\n for (var k = 0; k < 2; k++) { // xy\n V_position2[((((i * 4) + j) - o) * 2) + k] = V_position[(i * 2) + k];\n V_angles2[(((i * 4) + j) * 2) + k] = V_angles[(i * 2) + k];\n } // no offset\n for (var k = 0; k < 4; k++) {\n V_tangents2[((((i * 4) + j) - o) * 4) + k] = V_tangents[(i * 4) + k];\n }\n }\n }\n for (var i = 0, end = n; i < end; i++) {\n V_texcoord2[(((i * 4) + 0) * 2) + 0] = -1;\n V_texcoord2[(((i * 4) + 1) * 2) + 0] = -1;\n V_texcoord2[(((i * 4) + 2) * 2) + 0] = +1;\n V_texcoord2[(((i * 4) + 3) * 2) + 0] = +1;\n //\n V_texcoord2[(((i * 4) + 0) * 2) + 1] = -1;\n V_texcoord2[(((i * 4) + 1) * 2) + 1] = +1;\n V_texcoord2[(((i * 4) + 2) * 2) + 1] = -1;\n V_texcoord2[(((i * 4) + 3) * 2) + 1] = +1;\n }\n // Indices\n //I = np.resize( np.array([0,1,2,1,2,3], dtype=np.uint32), (n-1)*(2*3))\n //I += np.repeat( 4*np.arange(n-1), 6)\n var ni = (n - 1) * 6;\n this.I_triangles = (I = new Uint32Array(ni));\n // Order of indices is such that drawing as line_strip reveals the line skeleton\n // Might have implications on culling, if we ever turn that on.\n // Order in paper was: 0 1 2 1 2 3\n for (var i = 0, end = n; i < end; i++) {\n I[(i * 6) + 0] = 0 + (4 * i);\n I[(i * 6) + 1] = 1 + (4 * i);\n I[(i * 6) + 2] = 3 + (4 * i);\n I[(i * 6) + 3] = 2 + (4 * i);\n I[(i * 6) + 4] = 0 + (4 * i);\n I[(i * 6) + 5] = 3 + (4 * i);\n }\n };\n LineGLGlyph.prototype._update_scale = function (sx, sy) {\n // Update segment data and cumsum so the length along the line has the\n // scale aspect ratio in it. In the vertex shader we multiply with the\n // \"isotropic part\" of the scale.\n var V_segment2;\n var n = this.nvertices;\n var m = (4 * n) - 4;\n // Prepare arrays\n var T = this.tangents;\n var N = new Float32Array(n - 1);\n var V_segment = new Float32Array(n * 2); // Elements are initialized with 0\n this.V_segment = (V_segment2 = new Float32Array(m * 2));\n // Calculate vector lengths - with scale aspect ratio taken into account\n for (var i = 0, end = n - 1; i < end; i++) {\n N[i] = Math.sqrt(Math.pow(T[(i * 2) + 0] * sx, 2) + Math.pow(T[(i * 2) + 1] * sy, 2));\n }\n // Calculate Segments\n var cumsum = 0;\n for (var i = 0, end = n - 1; i < end; i++) {\n cumsum += N[i];\n V_segment[((i + 1) * 2) + 0] = cumsum;\n V_segment[(i * 2) + 1] = cumsum;\n }\n // Upscale (same loop as in _bake())\n for (var i = 0, end = n; i < end; i++) {\n for (var j = 0; j < 4; j++) {\n for (var k = 0; k < 2; k++) {\n V_segment2[(((i * 4) + j) * 2) + k] = V_segment[(i * 2) + k];\n }\n }\n }\n // Update\n this.cumsum = cumsum; // L[-1] in Nico's code\n this.vbo_segment.set_size(this.V_segment.length * 4);\n this.vbo_segment.set_data(0, this.V_segment);\n };\n return LineGLGlyph;\n }(base_1.BaseGLGlyph));\n exports.LineGLGlyph = LineGLGlyph;\n}\n","/* models/glyphs/webgl/line.vert */ function _(require, module, exports) {\n exports.vertex_shader = \"\\nprecision mediump float;\\n\\nconst float PI = 3.14159265358979323846264;\\nconst float THETA = 15.0 * 3.14159265358979323846264/180.0;\\n\\nuniform float u_pixel_ratio;\\nuniform vec2 u_canvas_size, u_offset;\\nuniform vec2 u_scale_aspect;\\nuniform float u_scale_length;\\n\\nuniform vec4 u_color;\\nuniform float u_antialias;\\nuniform float u_length;\\nuniform float u_linewidth;\\nuniform float u_dash_index;\\nuniform float u_closed;\\n\\nattribute vec2 a_position;\\nattribute vec4 a_tangents;\\nattribute vec2 a_segment;\\nattribute vec2 a_angles;\\nattribute vec2 a_texcoord;\\n\\nvarying vec4 v_color;\\nvarying vec2 v_segment;\\nvarying vec2 v_angles;\\nvarying vec2 v_texcoord;\\nvarying vec2 v_miter;\\nvarying float v_length;\\nvarying float v_linewidth;\\n\\nfloat cross(in vec2 v1, in vec2 v2)\\n{\\n return v1.x*v2.y - v1.y*v2.x;\\n}\\n\\nfloat signed_distance(in vec2 v1, in vec2 v2, in vec2 v3)\\n{\\n return cross(v2-v1,v1-v3) / length(v2-v1);\\n}\\n\\nvoid rotate( in vec2 v, in float alpha, out vec2 result )\\n{\\n float c = cos(alpha);\\n float s = sin(alpha);\\n result = vec2( c*v.x - s*v.y,\\n s*v.x + c*v.y );\\n}\\n\\nvoid main()\\n{\\n bool closed = (u_closed > 0.0);\\n\\n // Attributes and uniforms to varyings\\n v_color = u_color;\\n v_linewidth = u_linewidth;\\n v_segment = a_segment * u_scale_length;\\n v_length = u_length * u_scale_length;\\n\\n // Scale to map to pixel coordinates. The original algorithm from the paper\\n // assumed isotropic scale. We obviously do not have this.\\n vec2 abs_scale_aspect = abs(u_scale_aspect);\\n vec2 abs_scale = u_scale_length * abs_scale_aspect;\\n\\n // Correct angles for aspect ratio\\n vec2 av;\\n av = vec2(1.0, tan(a_angles.x)) / abs_scale_aspect;\\n v_angles.x = atan(av.y, av.x);\\n av = vec2(1.0, tan(a_angles.y)) / abs_scale_aspect;\\n v_angles.y = atan(av.y, av.x);\\n\\n // Thickness below 1 pixel are represented using a 1 pixel thickness\\n // and a modified alpha\\n v_color.a = min(v_linewidth, v_color.a);\\n v_linewidth = max(v_linewidth, 1.0);\\n\\n // If color is fully transparent we just will discard the fragment anyway\\n if( v_color.a <= 0.0 ) {\\n gl_Position = vec4(0.0,0.0,0.0,1.0);\\n return;\\n }\\n\\n // This is the actual half width of the line\\n float w = ceil(u_antialias+v_linewidth)/2.0;\\n\\n vec2 position = (a_position + u_offset) * abs_scale;\\n\\n vec2 t1 = normalize(a_tangents.xy * abs_scale_aspect); // note the scaling for aspect ratio here\\n vec2 t2 = normalize(a_tangents.zw * abs_scale_aspect);\\n float u = a_texcoord.x;\\n float v = a_texcoord.y;\\n vec2 o1 = vec2( +t1.y, -t1.x);\\n vec2 o2 = vec2( +t2.y, -t2.x);\\n\\n // This is a join\\n // ----------------------------------------------------------------\\n if( t1 != t2 ) {\\n float angle = atan (t1.x*t2.y-t1.y*t2.x, t1.x*t2.x+t1.y*t2.y); // Angle needs recalculation for some reason\\n vec2 t = normalize(t1+t2);\\n vec2 o = vec2( + t.y, - t.x);\\n\\n if ( u_dash_index > 0.0 )\\n {\\n // Broken angle\\n // ----------------------------------------------------------------\\n if( (abs(angle) > THETA) ) {\\n position += v * w * o / cos(angle/2.0);\\n float s = sign(angle);\\n if( angle < 0.0 ) {\\n if( u == +1.0 ) {\\n u = v_segment.y + v * w * tan(angle/2.0);\\n if( v == 1.0 ) {\\n position -= 2.0 * w * t1 / sin(angle);\\n u -= 2.0 * w / sin(angle);\\n }\\n } else {\\n u = v_segment.x - v * w * tan(angle/2.0);\\n if( v == 1.0 ) {\\n position += 2.0 * w * t2 / sin(angle);\\n u += 2.0*w / sin(angle);\\n }\\n }\\n } else {\\n if( u == +1.0 ) {\\n u = v_segment.y + v * w * tan(angle/2.0);\\n if( v == -1.0 ) {\\n position += 2.0 * w * t1 / sin(angle);\\n u += 2.0 * w / sin(angle);\\n }\\n } else {\\n u = v_segment.x - v * w * tan(angle/2.0);\\n if( v == -1.0 ) {\\n position -= 2.0 * w * t2 / sin(angle);\\n u -= 2.0*w / sin(angle);\\n }\\n }\\n }\\n // Continuous angle\\n // ------------------------------------------------------------\\n } else {\\n position += v * w * o / cos(angle/2.0);\\n if( u == +1.0 ) u = v_segment.y;\\n else u = v_segment.x;\\n }\\n }\\n\\n // Solid line\\n // --------------------------------------------------------------------\\n else\\n {\\n position.xy += v * w * o / cos(angle/2.0);\\n if( angle < 0.0 ) {\\n if( u == +1.0 ) {\\n u = v_segment.y + v * w * tan(angle/2.0);\\n } else {\\n u = v_segment.x - v * w * tan(angle/2.0);\\n }\\n } else {\\n if( u == +1.0 ) {\\n u = v_segment.y + v * w * tan(angle/2.0);\\n } else {\\n u = v_segment.x - v * w * tan(angle/2.0);\\n }\\n }\\n }\\n\\n // This is a line start or end (t1 == t2)\\n // ------------------------------------------------------------------------\\n } else {\\n position += v * w * o1;\\n if( u == -1.0 ) {\\n u = v_segment.x - w;\\n position -= w * t1;\\n } else {\\n u = v_segment.y + w;\\n position += w * t2;\\n }\\n }\\n\\n // Miter distance\\n // ------------------------------------------------------------------------\\n vec2 t;\\n vec2 curr = a_position * abs_scale;\\n if( a_texcoord.x < 0.0 ) {\\n vec2 next = curr + t2*(v_segment.y-v_segment.x);\\n\\n rotate( t1, +v_angles.x/2.0, t);\\n v_miter.x = signed_distance(curr, curr+t, position);\\n\\n rotate( t2, +v_angles.y/2.0, t);\\n v_miter.y = signed_distance(next, next+t, position);\\n } else {\\n vec2 prev = curr - t1*(v_segment.y-v_segment.x);\\n\\n rotate( t1, -v_angles.x/2.0,t);\\n v_miter.x = signed_distance(prev, prev+t, position);\\n\\n rotate( t2, -v_angles.y/2.0,t);\\n v_miter.y = signed_distance(curr, curr+t, position);\\n }\\n\\n if (!closed && v_segment.x <= 0.0) {\\n v_miter.x = 1e10;\\n }\\n if (!closed && v_segment.y >= v_length)\\n {\\n v_miter.y = 1e10;\\n }\\n\\n v_texcoord = vec2( u, v*w );\\n\\n // Calculate position in device coordinates. Note that we\\n // already scaled with abs scale above.\\n vec2 normpos = position * sign(u_scale_aspect);\\n normpos += 0.5; // make up for Bokeh's offset\\n normpos /= u_canvas_size / u_pixel_ratio; // in 0..1\\n gl_Position = vec4(normpos*2.0-1.0, 0.0, 1.0);\\n gl_Position.y *= -1.0;\\n}\\n\";\n}\n","/* models/glyphs/webgl/main */ function _(require, module, exports) {\n require(452) /* ./index */;\n}\n","/* models/glyphs/webgl/markers.frag */ function _(require, module, exports) {\n exports.fragment_shader = function (marker_code) { return \"\\nprecision mediump float;\\nconst float SQRT_2 = 1.4142135623730951;\\nconst float PI = 3.14159265358979323846264;\\n//\\nuniform float u_antialias;\\n//\\nvarying vec4 v_fg_color;\\nvarying vec4 v_bg_color;\\nvarying float v_linewidth;\\nvarying float v_size;\\nvarying vec2 v_rotation;\\n\\n\" + marker_code + \"\\n\\nvec4 outline(float distance, float linewidth, float antialias, vec4 fg_color, vec4 bg_color)\\n{\\n vec4 frag_color;\\n float t = linewidth/2.0 - antialias;\\n float signed_distance = distance;\\n float border_distance = abs(signed_distance) - t;\\n float alpha = border_distance/antialias;\\n alpha = exp(-alpha*alpha);\\n\\n // If fg alpha is zero, it probably means no outline. To avoid a dark outline\\n // shining through due to aa, we set the fg color to the bg color. Avoid if (i.e. branching).\\n float select = float(bool(fg_color.a));\\n fg_color.rgb = select * fg_color.rgb + (1.0 - select) * bg_color.rgb;\\n // Similarly, if we want a transparent bg\\n select = float(bool(bg_color.a));\\n bg_color.rgb = select * bg_color.rgb + (1.0 - select) * fg_color.rgb;\\n\\n if( border_distance < 0.0)\\n frag_color = fg_color;\\n else if( signed_distance < 0.0 ) {\\n frag_color = mix(bg_color, fg_color, sqrt(alpha));\\n } else {\\n if( abs(signed_distance) < (linewidth/2.0 + antialias) ) {\\n frag_color = vec4(fg_color.rgb, fg_color.a * alpha);\\n } else {\\n discard;\\n }\\n }\\n return frag_color;\\n}\\n\\nvoid main()\\n{\\n vec2 P = gl_PointCoord.xy - vec2(0.5, 0.5);\\n P = vec2(v_rotation.x*P.x - v_rotation.y*P.y,\\n v_rotation.y*P.x + v_rotation.x*P.y);\\n float point_size = SQRT_2*v_size + 2.0 * (v_linewidth + 1.5*u_antialias);\\n float distance = marker(P*point_size, v_size);\\n gl_FragColor = outline(distance, v_linewidth, u_antialias, v_fg_color, v_bg_color);\\n //gl_FragColor.rgb *= gl_FragColor.a; // pre-multiply alpha\\n}\\n\"; };\n exports.circle = \"\\nfloat marker(vec2 P, float size)\\n{\\n return length(P) - size/2.0;\\n}\\n\";\n exports.square = \"\\nfloat marker(vec2 P, float size)\\n{\\n return max(abs(P.x), abs(P.y)) - size/2.0;\\n}\\n\";\n exports.diamond = \"\\nfloat marker(vec2 P, float size)\\n{\\n float x = SQRT_2 / 2.0 * (P.x * 1.5 - P.y);\\n float y = SQRT_2 / 2.0 * (P.x * 1.5 + P.y);\\n float r1 = max(abs(x), abs(y)) - size / (2.0 * SQRT_2);\\n return r1 / SQRT_2;\\n}\\n\";\n exports.hex = \"\\nfloat marker(vec2 P, float size)\\n{\\n vec2 q = abs(P);\\n return max(q.y * 0.57735 + q.x - 1.0 * size/2.0, q.y - 0.866 * size/2.0);\\n}\\n\";\n exports.triangle = \"\\nfloat marker(vec2 P, float size)\\n{\\n P.y -= size * 0.3;\\n float x = SQRT_2 / 2.0 * (P.x * 1.7 - P.y);\\n float y = SQRT_2 / 2.0 * (P.x * 1.7 + P.y);\\n float r1 = max(abs(x), abs(y)) - size / 1.6;\\n float r2 = P.y;\\n return max(r1 / SQRT_2, r2); // Intersect diamond with rectangle\\n}\\n\";\n exports.invertedtriangle = \"\\nfloat marker(vec2 P, float size)\\n{\\n P.y += size * 0.3;\\n float x = SQRT_2 / 2.0 * (P.x * 1.7 - P.y);\\n float y = SQRT_2 / 2.0 * (P.x * 1.7 + P.y);\\n float r1 = max(abs(x), abs(y)) - size / 1.6;\\n float r2 = - P.y;\\n return max(r1 / SQRT_2, r2); // Intersect diamond with rectangle\\n}\\n\";\n exports.cross = \"\\nfloat marker(vec2 P, float size)\\n{\\n float square = max(abs(P.x), abs(P.y)) - size / 2.5; // 2.5 is a tweak\\n float cross = min(abs(P.x), abs(P.y)) - size / 100.0; // bit of \\\"width\\\" for aa\\n return max(square, cross);\\n}\\n\";\n exports.circlecross = \"\\nfloat marker(vec2 P, float size)\\n{\\n // Define quadrants\\n float qs = size / 2.0; // quadrant size\\n float s1 = max(abs(P.x - qs), abs(P.y - qs)) - qs;\\n float s2 = max(abs(P.x + qs), abs(P.y - qs)) - qs;\\n float s3 = max(abs(P.x - qs), abs(P.y + qs)) - qs;\\n float s4 = max(abs(P.x + qs), abs(P.y + qs)) - qs;\\n // Intersect main shape with quadrants (to form cross)\\n float circle = length(P) - size/2.0;\\n float c1 = max(circle, s1);\\n float c2 = max(circle, s2);\\n float c3 = max(circle, s3);\\n float c4 = max(circle, s4);\\n // Union\\n return min(min(min(c1, c2), c3), c4);\\n}\\n\";\n exports.squarecross = \"\\nfloat marker(vec2 P, float size)\\n{\\n // Define quadrants\\n float qs = size / 2.0; // quadrant size\\n float s1 = max(abs(P.x - qs), abs(P.y - qs)) - qs;\\n float s2 = max(abs(P.x + qs), abs(P.y - qs)) - qs;\\n float s3 = max(abs(P.x - qs), abs(P.y + qs)) - qs;\\n float s4 = max(abs(P.x + qs), abs(P.y + qs)) - qs;\\n // Intersect main shape with quadrants (to form cross)\\n float square = max(abs(P.x), abs(P.y)) - size/2.0;\\n float c1 = max(square, s1);\\n float c2 = max(square, s2);\\n float c3 = max(square, s3);\\n float c4 = max(square, s4);\\n // Union\\n return min(min(min(c1, c2), c3), c4);\\n}\\n\";\n exports.diamondcross = \"\\nfloat marker(vec2 P, float size)\\n{\\n // Define quadrants\\n float qs = size / 2.0; // quadrant size\\n float s1 = max(abs(P.x - qs), abs(P.y - qs)) - qs;\\n float s2 = max(abs(P.x + qs), abs(P.y - qs)) - qs;\\n float s3 = max(abs(P.x - qs), abs(P.y + qs)) - qs;\\n float s4 = max(abs(P.x + qs), abs(P.y + qs)) - qs;\\n // Intersect main shape with quadrants (to form cross)\\n float x = SQRT_2 / 2.0 * (P.x * 1.5 - P.y);\\n float y = SQRT_2 / 2.0 * (P.x * 1.5 + P.y);\\n float diamond = max(abs(x), abs(y)) - size / (2.0 * SQRT_2);\\n diamond /= SQRT_2;\\n float c1 = max(diamond, s1);\\n float c2 = max(diamond, s2);\\n float c3 = max(diamond, s3);\\n float c4 = max(diamond, s4);\\n // Union\\n return min(min(min(c1, c2), c3), c4);\\n}\\n\";\n exports.x = \"\\nfloat marker(vec2 P, float size)\\n{\\n float circle = length(P) - size / 1.6;\\n float X = min(abs(P.x - P.y), abs(P.x + P.y)) - size / 100.0; // bit of \\\"width\\\" for aa\\n return max(circle, X);\\n}\\n\";\n exports.circlex = \"\\nfloat marker(vec2 P, float size)\\n{\\n float x = P.x - P.y;\\n float y = P.x + P.y;\\n // Define quadrants\\n float qs = size / 2.0; // quadrant size\\n float s1 = max(abs(x - qs), abs(y - qs)) - qs;\\n float s2 = max(abs(x + qs), abs(y - qs)) - qs;\\n float s3 = max(abs(x - qs), abs(y + qs)) - qs;\\n float s4 = max(abs(x + qs), abs(y + qs)) - qs;\\n // Intersect main shape with quadrants (to form cross)\\n float circle = length(P) - size/2.0;\\n float c1 = max(circle, s1);\\n float c2 = max(circle, s2);\\n float c3 = max(circle, s3);\\n float c4 = max(circle, s4);\\n // Union\\n float almost = min(min(min(c1, c2), c3), c4);\\n // In this case, the X is also outside of the main shape\\n float Xmask = length(P) - size / 1.6; // a circle\\n float X = min(abs(P.x - P.y), abs(P.x + P.y)) - size / 100.0; // bit of \\\"width\\\" for aa\\n return min(max(X, Xmask), almost);\\n}\\n\";\n exports.squarex = \"\\nfloat marker(vec2 P, float size)\\n{\\n float x = P.x - P.y;\\n float y = P.x + P.y;\\n // Define quadrants\\n float qs = size / 2.0; // quadrant size\\n float s1 = max(abs(x - qs), abs(y - qs)) - qs;\\n float s2 = max(abs(x + qs), abs(y - qs)) - qs;\\n float s3 = max(abs(x - qs), abs(y + qs)) - qs;\\n float s4 = max(abs(x + qs), abs(y + qs)) - qs;\\n // Intersect main shape with quadrants (to form cross)\\n float square = max(abs(P.x), abs(P.y)) - size/2.0;\\n float c1 = max(square, s1);\\n float c2 = max(square, s2);\\n float c3 = max(square, s3);\\n float c4 = max(square, s4);\\n // Union\\n return min(min(min(c1, c2), c3), c4);\\n}\\n\";\n exports.asterisk = \"\\nfloat marker(vec2 P, float size)\\n{\\n // Masks\\n float diamond = max(abs(SQRT_2 / 2.0 * (P.x - P.y)), abs(SQRT_2 / 2.0 * (P.x + P.y))) - size / (2.0 * SQRT_2);\\n float square = max(abs(P.x), abs(P.y)) - size / (2.0 * SQRT_2);\\n // Shapes\\n float X = min(abs(P.x - P.y), abs(P.x + P.y)) - size / 100.0; // bit of \\\"width\\\" for aa\\n float cross = min(abs(P.x), abs(P.y)) - size / 100.0; // bit of \\\"width\\\" for aa\\n // Result is union of masked shapes\\n return min(max(X, diamond), max(cross, square));\\n}\\n\";\n}\n","/* models/glyphs/webgl/markers */ function _(require, module, exports) {\n var tslib_1 = require(391) /* tslib */;\n var gloo2_1 = require(460) /* gloo2 */;\n var base_1 = require(451) /* ./base */;\n var markers_vert_1 = require(459) /* ./markers.vert */;\n var markers_frag_1 = require(457) /* ./markers.frag */;\n var circle_1 = require(120) /* ../circle */;\n var arrayable_1 = require(22) /* core/util/arrayable */;\n var logging_1 = require(14) /* core/logging */;\n // Base class for markers. All markers share the same GLSL, except for one\n // function that defines the marker geometry.\n var MarkerGLGlyph = /** @class */ (function (_super) {\n tslib_1.__extends(MarkerGLGlyph, _super);\n function MarkerGLGlyph() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n MarkerGLGlyph.prototype.init = function () {\n var gl = this.gl;\n var vert = markers_vert_1.vertex_shader;\n var frag = markers_frag_1.fragment_shader(this._marker_code);\n // The program\n this.prog = new gloo2_1.Program(gl);\n this.prog.set_shaders(vert, frag);\n // Real attributes\n this.vbo_x = new gloo2_1.VertexBuffer(gl);\n this.prog.set_attribute('a_x', 'float', this.vbo_x);\n this.vbo_y = new gloo2_1.VertexBuffer(gl);\n this.prog.set_attribute('a_y', 'float', this.vbo_y);\n this.vbo_s = new gloo2_1.VertexBuffer(gl);\n this.prog.set_attribute('a_size', 'float', this.vbo_s);\n this.vbo_a = new gloo2_1.VertexBuffer(gl);\n this.prog.set_attribute('a_angle', 'float', this.vbo_a);\n // VBO's for attributes (they may not be used if value is singleton)\n this.vbo_linewidth = new gloo2_1.VertexBuffer(gl);\n this.vbo_fg_color = new gloo2_1.VertexBuffer(gl);\n this.vbo_bg_color = new gloo2_1.VertexBuffer(gl);\n this.index_buffer = new gloo2_1.IndexBuffer(gl);\n };\n MarkerGLGlyph.prototype.draw = function (indices, mainGlyph, trans) {\n // The main glyph has the data, *this* glyph has the visuals.\n var mainGlGlyph = mainGlyph.glglyph;\n var nvertices = mainGlGlyph.nvertices;\n // Upload data if we must. Only happens for main glyph.\n if (mainGlGlyph.data_changed) {\n if (!(isFinite(trans.dx) && isFinite(trans.dy))) {\n return; // not sure why, but it happens on init sometimes (#4367)\n }\n mainGlGlyph._baked_offset = [trans.dx, trans.dy]; // float32 precision workaround; used in _set_data() and below\n mainGlGlyph._set_data(nvertices);\n mainGlGlyph.data_changed = false;\n }\n else if (this.glyph instanceof circle_1.CircleView && this.glyph._radius != null &&\n (this.last_trans == null || trans.sx != this.last_trans.sx || trans.sy != this.last_trans.sy)) {\n // Keep screen radius up-to-date for circle glyph. Only happens when a radius is given\n this.last_trans = trans;\n this.vbo_s.set_data(0, new Float32Array(arrayable_1.map(this.glyph.sradius, function (s) { return s * 2; })));\n }\n // Update visuals if we must. Can happen for all glyphs.\n if (this.visuals_changed) {\n this._set_visuals(nvertices);\n this.visuals_changed = false;\n }\n // Handle transformation to device coordinates\n // Note the baked-in offset to avoid float32 precision problems\n var baked_offset = mainGlGlyph._baked_offset;\n this.prog.set_uniform('u_pixel_ratio', 'float', [trans.pixel_ratio]);\n this.prog.set_uniform('u_canvas_size', 'vec2', [trans.width, trans.height]);\n this.prog.set_uniform('u_offset', 'vec2', [trans.dx - baked_offset[0], trans.dy - baked_offset[1]]);\n this.prog.set_uniform('u_scale', 'vec2', [trans.sx, trans.sy]);\n // Select buffers from main glyph\n // (which may be this glyph but maybe not if this is a (non)selection glyph)\n this.prog.set_attribute('a_x', 'float', mainGlGlyph.vbo_x);\n this.prog.set_attribute('a_y', 'float', mainGlGlyph.vbo_y);\n this.prog.set_attribute('a_size', 'float', mainGlGlyph.vbo_s);\n this.prog.set_attribute('a_angle', 'float', mainGlGlyph.vbo_a);\n // Draw directly or using indices. Do not handle indices if they do not\n // fit in a uint16; WebGL 1.0 does not support uint32.\n if (indices.length == 0)\n return;\n else if (indices.length === nvertices)\n this.prog.draw(this.gl.POINTS, [0, nvertices]);\n else if (nvertices < 65535) {\n // On IE the marker size is reduced to 1 px when using an index buffer\n // A MS Edge dev on Twitter said on 24-04-2014: \"gl_PointSize > 1.0 works\n // in DrawArrays; gl_PointSize > 1.0 in DrawElements is coming soon in the\n // next renderer update.\n var ua = window.navigator.userAgent;\n if ((ua.indexOf(\"MSIE \") + ua.indexOf(\"Trident/\") + ua.indexOf(\"Edge/\")) > 0) {\n logging_1.logger.warn('WebGL warning: IE is known to produce 1px sprites whith selections.');\n }\n this.index_buffer.set_size(indices.length * 2);\n this.index_buffer.set_data(0, new Uint16Array(indices));\n this.prog.draw(this.gl.POINTS, this.index_buffer);\n }\n else {\n // Work around the limit that the indexbuffer must be uint16. We draw in chunks.\n // First collect indices in chunks\n var chunksize = 64000; // 65536\n var chunks = [];\n for (var i = 0, end = Math.ceil(nvertices / chunksize); i < end; i++) {\n chunks.push([]);\n }\n for (var i = 0, end = indices.length; i < end; i++) {\n var uint16_index = indices[i] % chunksize;\n var chunk = Math.floor(indices[i] / chunksize);\n chunks[chunk].push(uint16_index);\n }\n // Then draw each chunk\n for (var chunk = 0, end = chunks.length; chunk < end; chunk++) {\n var these_indices = new Uint16Array(chunks[chunk]);\n var offset = chunk * chunksize * 4;\n if (these_indices.length === 0) {\n continue;\n }\n this.prog.set_attribute('a_x', 'float', mainGlGlyph.vbo_x, 0, offset);\n this.prog.set_attribute('a_y', 'float', mainGlGlyph.vbo_y, 0, offset);\n this.prog.set_attribute('a_size', 'float', mainGlGlyph.vbo_s, 0, offset);\n this.prog.set_attribute('a_angle', 'float', mainGlGlyph.vbo_a, 0, offset);\n if (this.vbo_linewidth.used) {\n this.prog.set_attribute('a_linewidth', 'float', this.vbo_linewidth, 0, offset);\n }\n if (this.vbo_fg_color.used) {\n this.prog.set_attribute('a_fg_color', 'vec4', this.vbo_fg_color, 0, offset * 4);\n }\n if (this.vbo_bg_color.used) {\n this.prog.set_attribute('a_bg_color', 'vec4', this.vbo_bg_color, 0, offset * 4);\n }\n // The actual drawing\n this.index_buffer.set_size(these_indices.length * 2);\n this.index_buffer.set_data(0, these_indices);\n this.prog.draw(this.gl.POINTS, this.index_buffer);\n }\n }\n };\n MarkerGLGlyph.prototype._set_data = function (nvertices) {\n var n = nvertices * 4; // in bytes\n // Set buffer size\n this.vbo_x.set_size(n);\n this.vbo_y.set_size(n);\n this.vbo_a.set_size(n);\n this.vbo_s.set_size(n);\n // Upload data for x and y, apply a baked-in offset for float32 precision (issue #3795)\n // The exact value for the baked_offset does not matter, as long as it brings the data to less extreme values\n var xx = new Float64Array(this.glyph._x);\n var yy = new Float64Array(this.glyph._y);\n for (var i = 0, end = nvertices; i < end; i++) {\n xx[i] += this._baked_offset[0];\n yy[i] += this._baked_offset[1];\n }\n this.vbo_x.set_data(0, new Float32Array(xx));\n this.vbo_y.set_data(0, new Float32Array(yy));\n // Angle if available; circle does not have angle. If we don't set data, angle is default 0 in glsl\n if (this.glyph._angle != null) {\n this.vbo_a.set_data(0, new Float32Array(this.glyph._angle));\n }\n // Radius is special; some markes allow radius in data-coords instead of screen coords\n // @radius tells us that radius is in units, sradius is the pre-calculated screen radius\n if (this.glyph instanceof circle_1.CircleView && this.glyph._radius != null)\n this.vbo_s.set_data(0, new Float32Array(arrayable_1.map(this.glyph.sradius, function (s) { return s * 2; })));\n else\n this.vbo_s.set_data(0, new Float32Array(this.glyph._size));\n };\n MarkerGLGlyph.prototype._set_visuals = function (nvertices) {\n base_1.attach_float(this.prog, this.vbo_linewidth, 'a_linewidth', nvertices, this.glyph.visuals.line, 'line_width');\n base_1.attach_color(this.prog, this.vbo_fg_color, 'a_fg_color', nvertices, this.glyph.visuals.line, 'line');\n base_1.attach_color(this.prog, this.vbo_bg_color, 'a_bg_color', nvertices, this.glyph.visuals.fill, 'fill');\n // Static value for antialias. Smaller aa-region to obtain crisper images\n this.prog.set_uniform('u_antialias', 'float', [0.8]);\n };\n return MarkerGLGlyph;\n }(base_1.BaseGLGlyph));\n exports.MarkerGLGlyph = MarkerGLGlyph;\n function mk_marker(code) {\n return /** @class */ (function (_super) {\n tslib_1.__extends(class_1, _super);\n function class_1() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n Object.defineProperty(class_1.prototype, \"_marker_code\", {\n get: function () {\n return code;\n },\n enumerable: true,\n configurable: true\n });\n return class_1;\n }(MarkerGLGlyph));\n }\n var glsl = require(457) /* ./markers.frag */;\n exports.CircleGLGlyph = mk_marker(glsl.circle);\n exports.SquareGLGlyph = mk_marker(glsl.square);\n exports.DiamondGLGlyph = mk_marker(glsl.diamond);\n exports.TriangleGLGlyph = mk_marker(glsl.triangle);\n exports.InvertedTriangleGLGlyph = mk_marker(glsl.invertedtriangle);\n exports.HexGLGlyph = mk_marker(glsl.hex);\n exports.CrossGLGlyph = mk_marker(glsl.cross);\n exports.CircleCrossGLGlyph = mk_marker(glsl.circlecross);\n exports.SquareCrossGLGlyph = mk_marker(glsl.squarecross);\n exports.DiamondCrossGLGlyph = mk_marker(glsl.diamondcross);\n exports.XGLGlyph = mk_marker(glsl.x);\n exports.CircleXGLGlyph = mk_marker(glsl.circlex);\n exports.SquareXGLGlyph = mk_marker(glsl.squarex);\n exports.AsteriskGLGlyph = mk_marker(glsl.asterisk);\n}\n","/* models/glyphs/webgl/markers.vert */ function _(require, module, exports) {\n exports.vertex_shader = \"\\nprecision mediump float;\\nconst float SQRT_2 = 1.4142135623730951;\\n//\\nuniform float u_pixel_ratio;\\nuniform vec2 u_canvas_size;\\nuniform vec2 u_offset;\\nuniform vec2 u_scale;\\nuniform float u_antialias;\\n//\\nattribute float a_x;\\nattribute float a_y;\\nattribute float a_size;\\nattribute float a_angle; // in radians\\nattribute float a_linewidth;\\nattribute vec4 a_fg_color;\\nattribute vec4 a_bg_color;\\n//\\nvarying float v_linewidth;\\nvarying float v_size;\\nvarying vec4 v_fg_color;\\nvarying vec4 v_bg_color;\\nvarying vec2 v_rotation;\\n\\nvoid main (void)\\n{\\n v_size = a_size * u_pixel_ratio;\\n v_linewidth = a_linewidth * u_pixel_ratio;\\n v_fg_color = a_fg_color;\\n v_bg_color = a_bg_color;\\n v_rotation = vec2(cos(-a_angle), sin(-a_angle));\\n // Calculate position - the -0.5 is to correct for canvas origin\\n vec2 pos = (vec2(a_x, a_y) + u_offset) * u_scale; // in pixels\\n pos += 0.5; // make up for Bokeh's offset\\n pos /= u_canvas_size / u_pixel_ratio; // in 0..1\\n gl_Position = vec4(pos*2.0-1.0, 0.0, 1.0);\\n gl_Position.y *= -1.0;\\n gl_PointSize = SQRT_2 * v_size + 2.0 * (v_linewidth + 1.5*u_antialias);\\n}\\n\";\n}\n","/* gloo2/gloo2 */ function _(require, module, exports) {\n /* Do not edit, autogenerated by flexx.pyscript */\n var _pyfunc_add = function (a, b) {\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.concat(b);\n }\n return a + b;\n };\n var _pyfunc_all = function (x) {\n for (var i = 0; i < x.length; i++) {\n if (!_pyfunc_truthy(x[i])) {\n return false;\n }\n }\n return true;\n };\n var _pyfunc_contains = function contains(a, b) {\n if (b == null) {\n }\n else if (Array.isArray(b)) {\n for (var i = 0; i < b.length; i++) {\n if (_pyfunc_equals(a, b[i]))\n return true;\n }\n return false;\n }\n else if (b.constructor === Object) {\n for (var k in b) {\n if (a == k)\n return true;\n }\n return false;\n }\n else if (b.constructor == String) {\n return b.indexOf(a) >= 0;\n }\n var e = Error('Not a container: ' + b);\n e.name = 'TypeError';\n throw e;\n };\n var _pyfunc_equals = function equals(a, b) {\n if (a == null || b == null) {\n }\n else if (Array.isArray(a) && Array.isArray(b)) {\n var i = 0, iseq = a.length == b.length;\n while (iseq && i < a.length) {\n iseq = equals(a[i], b[i]);\n i += 1;\n }\n return iseq;\n }\n else if (a.constructor === Object && b.constructor === Object) {\n var akeys = Object.keys(a), bkeys = Object.keys(b);\n akeys.sort();\n bkeys.sort();\n var i = 0, k, iseq = equals(akeys, bkeys);\n while (iseq && i < akeys.length) {\n k = akeys[i];\n iseq = equals(a[k], b[k]);\n i += 1;\n }\n return iseq;\n }\n return a == b;\n };\n var _pyfunc_instantiate = function (ob, args) {\n if ((typeof ob === \"undefined\") ||\n (typeof window !== \"undefined\" && window === ob) ||\n (typeof global !== \"undefined\" && global === ob)) {\n throw \"Class constructor is called as a function.\";\n }\n for (var name in ob) {\n if (Object[name] === undefined &&\n typeof ob[name] === 'function' && !ob[name].nobind) {\n ob[name] = ob[name].bind(ob);\n }\n }\n if (ob.__init__) {\n ob.__init__.apply(ob, args);\n }\n };\n var _pyfunc_mult = function (a, b) {\n if ((typeof a === 'number') + (typeof b === 'number') === 1) {\n if (a.constructor === String)\n return _pymeth_repeat.call(a, b);\n if (b.constructor === String)\n return _pymeth_repeat.call(b, a);\n if (Array.isArray(b)) {\n var t = a;\n a = b;\n b = t;\n }\n if (Array.isArray(a)) {\n var res = [];\n for (var i = 0; i < b; i++)\n res = res.concat(a);\n return res;\n }\n }\n return a * b;\n };\n var _pyfunc_range = function (start, end, step) {\n var i, res = [];\n var val = start;\n var n = (end - start) / step;\n for (i = 0; i < n; i++) {\n res.push(val);\n val += step;\n }\n return res;\n };\n var _pyfunc_truthy = function (v) {\n if (v === null || typeof v !== \"object\") {\n return v;\n }\n else if (v.length !== undefined) {\n return v.length ? v : false;\n }\n else if (v.byteLength !== undefined) {\n return v.byteLength ? v : false;\n }\n else if (v.constructor !== Object) {\n return true;\n }\n else {\n return Object.getOwnPropertyNames(v).length ? v : false;\n }\n };\n var _pymeth_append = function (x) {\n if (!Array.isArray(this))\n return this.append.apply(this, arguments);\n this.push(x);\n };\n var _pymeth_get = function (key, d) {\n if (this.constructor !== Object)\n return this.get.apply(this, arguments);\n if (this[key] !== undefined) {\n return this[key];\n }\n else if (d !== undefined) {\n return d;\n }\n else {\n return null;\n }\n };\n var _pymeth_keys = function () {\n if (typeof this['keys'] === 'function')\n return this.keys.apply(this, arguments);\n return Object.keys(this);\n };\n var _pymeth_lstrip = function (chars) {\n if (this.constructor !== String)\n return this.lstrip.apply(this, arguments);\n chars = (chars === undefined) ? ' \\t\\r\\n' : chars;\n for (var i = 0; i < this.length; i++) {\n if (chars.indexOf(this[i]) < 0)\n return this.slice(i);\n }\n return '';\n };\n var _pymeth_remove = function (x) {\n if (!Array.isArray(this))\n return this.remove.apply(this, arguments);\n for (var i = 0; i < this.length; i++) {\n if (_pyfunc_equals(this[i], x)) {\n this.splice(i, 1);\n return;\n }\n }\n var e = Error(x);\n e.name = 'ValueError';\n throw e;\n };\n var _pymeth_repeat = function (count) {\n if (this.repeat)\n return this.repeat(count);\n if (count < 1)\n return '';\n var result = '', pattern = this.valueOf();\n while (count > 1) {\n if (count & 1)\n result += pattern;\n count >>= 1, pattern += pattern;\n }\n return result + pattern;\n };\n var _pymeth_startswith = function (x) {\n if (this.constructor !== String)\n return this.startswith.apply(this, arguments);\n return this.indexOf(x) == 0;\n };\n var Buffer, GlooObject, IndexBuffer, Program, Texture2D, Texture3DLike, VertexBuffer, __version__, check_error, console;\n // PyScript module for gloo2.js - lightweight object oriented GL.\n { /* if this_is_js() */\n console = window.console;\n }\n __version__ = \"0.3\";\n check_error = function (gl, when) {\n var e, err, err_3, errors, msg, stub1_seq, stub2_itr;\n when = (when === undefined) ? \"periodic check\" : when;\n // Check this from time to time to detect GL errors.\n //\n // Parameters\n // ----------\n // when : str\n // Shown in the exception to help the developer determine when\n // this check was done.\n errors = [];\n while (true) {\n err = gl.getError();\n if ((_pyfunc_equals(err, gl.NO_ERROR) || (_pyfunc_truthy(errors) && _pyfunc_equals(err, errors[errors.length - 1])))) {\n break;\n }\n _pymeth_append.call(errors, err);\n }\n if (errors.length) {\n msg = \"\";\n stub1_seq = errors;\n if ((typeof stub1_seq === \"object\") && (!Array.isArray(stub1_seq))) {\n stub1_seq = Object.keys(stub1_seq);\n }\n for (stub2_itr = 0; stub2_itr < stub1_seq.length; stub2_itr += 1) {\n e = stub1_seq[stub2_itr];\n msg = _pyfunc_add(msg, e);\n }\n err_3 = new Error('RuntimeError:' + (\"OpenGL got errors (\" + when + \"): \" + msg + \"\"));\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n return null;\n };\n GlooObject = function () {\n // Abstract base class for all Gloo classes.\n _pyfunc_instantiate(this, arguments);\n };\n GlooObject.prototype._base_class = Object;\n GlooObject.prototype._class_name = \"GlooObject\";\n GlooObject.prototype.__init__ = function (gl) {\n // Init by passing the webgl context object.\n this._gl = gl;\n this.handle = null;\n this._create();\n if (!(this.handle !== null)) {\n throw \"AssertionError: \" + \"this.handle !== null\";\n }\n return null;\n };\n GlooObject.prototype._create = function () {\n var err_2;\n err_2 = new Error('NotImplementedError:' + \"\");\n err_2.name = \"NotImplementedError\";\n throw err_2;\n return null;\n };\n Program = function () {\n // The program is the central component to connect gloo objects and shaders.\n _pyfunc_instantiate(this, arguments);\n };\n Program.prototype = Object.create(GlooObject.prototype);\n Program.prototype._base_class = GlooObject.prototype;\n Program.prototype._class_name = \"Program\";\n Program.prototype.UTYPEMAP = { \"float\": \"uniform1fv\", \"vec2\": \"uniform2fv\", \"vec3\": \"uniform3fv\", \"vec4\": \"uniform4fv\", \"int\": \"uniform1iv\", \"ivec2\": \"uniform2iv\", \"ivec3\": \"uniform3iv\", \"ivec4\": \"uniform4iv\", \"bool\": \"uniform1iv\", \"bvec2\": \"uniform2iv\", \"bvec3\": \"uniform3iv\", \"bvec4\": \"uniform4iv\", \"mat2\": \"uniformMatrix2fv\", \"mat3\": \"uniformMatrix3fv\", \"mat4\": \"uniformMatrix4fv\", \"sampler1D\": \"uniform1i\", \"sampler2D\": \"uniform1i\", \"sampler3D\": \"uniform1i\" };\n Program.prototype.ATYPEMAP = { \"float\": \"vertexAttrib1f\", \"vec2\": \"vertexAttrib2f\", \"vec3\": \"vertexAttrib3f\", \"vec4\": \"vertexAttrib4f\" };\n Program.prototype.ATYPEINFO = { \"float\": [1, 5126], \"vec2\": [2, 5126], \"vec3\": [3, 5126], \"vec4\": [4, 5126] };\n Program.prototype._create = function () {\n this.handle = this._gl.createProgram();\n this.locations = {};\n this._unset_variables = [];\n this._validated = false;\n this._samplers = {};\n this._attributes = {};\n this._known_invalid = [];\n return null;\n };\n Program.prototype.delete = function () {\n // Delete the program.\n this._gl.deleteProgram(this.handle);\n return null;\n };\n Program.prototype.activate = function () {\n // Activate the program.\n this._gl.useProgram(this.handle);\n return null;\n };\n Program.prototype.deactivate = function () {\n // Disable the program.\n this._gl.useProgram(0);\n return null;\n };\n Program.prototype.set_shaders = function (vert, frag) {\n var code, err_3, err_4, errors, frag_handle, gl, handle, i, status, stub3_, tmp, type_, vert_handle;\n // Set GLSL code for the vertex and fragment shader.\n //\n // This function takes care of setting the shading code and\n // compiling+linking it into a working program object that is ready\n // to use.\n //\n // Parameters\n // ----------\n // vert : str\n // GLSL code for the vertex shader.\n // frag : str\n // GLSL code for the fragment shader.\n gl = this._gl;\n this._linked = false;\n vert_handle = gl.createShader(gl.VERTEX_SHADER);\n frag_handle = gl.createShader(gl.FRAGMENT_SHADER);\n tmp = [[vert, vert_handle, \"vertex\"], [frag, frag_handle, \"fragment\"]];\n for (i = 0; i < 2; i += 1) {\n stub3_ = tmp[i];\n code = stub3_[0];\n handle = stub3_[1];\n type_ = stub3_[2];\n gl.shaderSource(handle, code);\n gl.compileShader(handle);\n status = gl.getShaderParameter(handle, gl.COMPILE_STATUS);\n if ((!_pyfunc_truthy(status))) {\n errors = gl.getShaderInfoLog(handle);\n err_4 = new Error('RuntimeError:' + (_pyfunc_add(((\"errors in \" + type_) + \" shader:\\n\"), errors)));\n err_4.name = \"RuntimeError\";\n throw err_4;\n }\n }\n gl.attachShader(this.handle, vert_handle);\n gl.attachShader(this.handle, frag_handle);\n gl.linkProgram(this.handle);\n if ((!_pyfunc_truthy(gl.getProgramParameter(this.handle, gl.LINK_STATUS)))) {\n err_3 = new Error('RuntimeError:' + (\"Program link error:\\n\" + gl.getProgramInfoLog(this.handle)));\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n this._unset_variables = this._get_active_attributes_and_uniforms();\n gl.detachShader(this.handle, vert_handle);\n gl.detachShader(this.handle, frag_handle);\n gl.deleteShader(vert_handle);\n gl.deleteShader(frag_handle);\n this._known_invalid = [];\n this._linked = true;\n return null;\n };\n Program.prototype._get_active_attributes_and_uniforms = function () {\n var attributes, ca, container, count, cu, getActive, getLocation, gl, i, info, j, m, name, regex, stub4_, stub5_seq, stub6_itr, uniforms, x;\n // Retrieve active attributes and uniforms to be able to check that\n // all uniforms/attributes are set by the user.\n gl = this._gl;\n this.locations = {};\n regex = new window.RegExp(\"(\\\\w+)\\\\s*(\\\\[(\\\\d+)\\\\])\\\\s*\");\n cu = gl.getProgramParameter(this.handle, gl.ACTIVE_UNIFORMS);\n ca = gl.getProgramParameter(this.handle, gl.ACTIVE_ATTRIBUTES);\n attributes = [];\n uniforms = [];\n stub5_seq = [[attributes, ca, gl.getActiveAttrib, gl.getAttribLocation], [uniforms, cu, gl.getActiveUniform, gl.getUniformLocation]];\n if ((typeof stub5_seq === \"object\") && (!Array.isArray(stub5_seq))) {\n stub5_seq = Object.keys(stub5_seq);\n }\n for (stub6_itr = 0; stub6_itr < stub5_seq.length; stub6_itr += 1) {\n x = stub5_seq[stub6_itr];\n stub4_ = x;\n container = stub4_[0];\n count = stub4_[1];\n getActive = stub4_[2];\n getLocation = stub4_[3];\n for (i = 0; i < count; i += 1) {\n info = getActive.call(gl, this.handle, i);\n name = info.name;\n m = name.match(regex);\n if (_pyfunc_truthy(m)) {\n name = m[1];\n for (j = 0; j < info.size; j += 1) {\n _pymeth_append.call(container, ([\"\" + name + \"[\" + j + \"]\", info.type]));\n }\n }\n else {\n _pymeth_append.call(container, [name, info.type]);\n }\n this.locations[name] = getLocation.call(gl, this.handle, name);\n }\n }\n return _pyfunc_add(((function list_comprehenson() { var res = []; var v, iter0, i0; iter0 = attributes; if ((typeof iter0 === \"object\") && (!Array.isArray(iter0))) {\n iter0 = Object.keys(iter0);\n } for (i0 = 0; i0 < iter0.length; i0++) {\n v = iter0[i0];\n {\n res.push(v[0]);\n }\n } return res; }).apply(this)), ((function list_comprehenson() { var res = []; var v, iter0, i0; iter0 = uniforms; if ((typeof iter0 === \"object\") && (!Array.isArray(iter0))) {\n iter0 = Object.keys(iter0);\n } for (i0 = 0; i0 < iter0.length; i0++) {\n v = iter0[i0];\n {\n res.push(v[0]);\n }\n } return res; }).apply(this)));\n };\n Program.prototype.set_texture = function (name, value) {\n var err_3, handle, unit;\n // Set a texture sampler.\n //\n // A texture is a 2 dimensional grid of colors/intensities that\n // can be applied to a face (or used for other means by providing\n // a regular grid of data).\n //\n // Parameters\n // ----------\n // name : str\n // The name by which the texture is known in the GLSL code.\n // value : Texture2D\n // The gloo Texture2D object to bind.\n if ((!_pyfunc_truthy(this._linked))) {\n err_3 = new Error('RuntimeError:' + \"Cannot set uniform when program has no code\");\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n handle = _pymeth_get.call(this.locations, name, (-1));\n if (_pyfunc_truthy(handle < 0)) {\n if ((!_pyfunc_contains(name, this._known_invalid))) {\n _pymeth_append.call(this._known_invalid, name);\n console.log(\"Variable \" + name + \" is not an active texture\");\n }\n return null;\n }\n if (_pyfunc_contains(name, this._unset_variables)) {\n _pymeth_remove.call(this._unset_variables, name);\n }\n this.activate();\n if (true) {\n unit = _pymeth_keys.call(this._samplers).length;\n if (_pyfunc_contains(name, this._samplers)) {\n unit = this._samplers[name][this._samplers[name].length - 1];\n }\n this._samplers[name] = [value._target, value.handle, unit];\n this._gl.uniform1i(handle, unit);\n }\n return null;\n };\n Program.prototype.set_uniform = function (name, type_, value) {\n var a_type, count, err_3, funcname, handle, j, name_;\n // Set a uniform value.\n //\n // A uniform is a value that is global to both the vertex and\n // fragment shader.\n //\n // Parameters\n // ----------\n // name : str\n // The name by which the uniform is known in the GLSL code.\n // type_ : str\n // The type of the uniform, e.g. 'float', 'vec2', etc.\n // value : list of scalars\n // The value for the uniform. Should be a list even for type float.\n if ((!_pyfunc_truthy(this._linked))) {\n err_3 = new Error('RuntimeError:' + \"Cannot set uniform when program has no code\");\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n handle = _pymeth_get.call(this.locations, name, (-1));\n if (_pyfunc_truthy(handle < 0)) {\n if ((!_pyfunc_contains(name, this._known_invalid))) {\n _pymeth_append.call(this._known_invalid, name);\n console.log(\"Variable \" + name + \" is not an active uniform\");\n }\n return null;\n }\n if (_pyfunc_contains(name, this._unset_variables)) {\n _pymeth_remove.call(this._unset_variables, name);\n }\n count = 1;\n if ((!_pymeth_startswith.call(type_, \"mat\"))) {\n a_type = _pymeth_get.call({ \"int\": \"float\", \"bool\": \"float\" }, type_, _pymeth_lstrip.call(type_, \"ib\"));\n count = Math.floor(value.length / (this.ATYPEINFO[a_type][0]));\n }\n if (_pyfunc_truthy(count > 1)) {\n for (j = 0; j < count; j += 1) {\n if ((_pyfunc_contains((\"\" + name + \"[\" + j + \"]\"), this._unset_variables))) {\n name_ = \"\" + name + \"[\" + j + \"]\";\n if (_pyfunc_contains(name_, this._unset_variables)) {\n _pymeth_remove.call(this._unset_variables, name_);\n }\n }\n }\n }\n funcname = this.UTYPEMAP[type_];\n this.activate();\n if (_pymeth_startswith.call(type_, \"mat\")) {\n this._gl[funcname](handle, false, value);\n }\n else {\n this._gl[funcname](handle, value);\n }\n return null;\n };\n Program.prototype.set_attribute = function (name, type_, value, stride, offset) {\n var args, err_3, funcname, gtype, handle, is_vbo, size, stub7_;\n stride = (stride === undefined) ? 0 : stride;\n offset = (offset === undefined) ? 0 : offset;\n // Set an attribute value.\n //\n // An attribute represents per-vertex data and can only be used\n // in the vertex shader.\n //\n // Parameters\n // ----------\n // name : str\n // The name by which the attribute is known in the GLSL code.\n // type_ : str\n // The type of the attribute, e.g. 'float', 'vec2', etc.\n // value : VertexBuffer, array\n // If value is a VertexBuffer, it is used (with stride and offset)\n // for the vertex data. If value is an array, its used to set\n // the value of all vertices (similar to a uniform).\n // stide : int, default 0\n // The stride to \"sample\" the vertex data inside the buffer. Unless\n // multiple vertex data are packed into a single buffer, this should\n // be zero.\n // offset : int, default 0\n // The offset to \"sample\" the vertex data inside the buffer. Unless\n // multiple vertex data are packed into a single buffer, or only\n // a part of the data must be used, this should probably be zero.\n if ((!_pyfunc_truthy(this._linked))) {\n err_3 = new Error('RuntimeError:' + \"Cannot set attribute when program has no code\");\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n is_vbo = value instanceof VertexBuffer;\n handle = _pymeth_get.call(this.locations, name, (-1));\n if (_pyfunc_truthy(handle < 0)) {\n if ((!_pyfunc_contains(name, this._known_invalid))) {\n _pymeth_append.call(this._known_invalid, name);\n if ((_pyfunc_truthy(is_vbo) && _pyfunc_truthy(offset > 0))) {\n }\n else {\n console.log(\"Variable \" + name + \" is not an active attribute\");\n }\n }\n return null;\n }\n if (_pyfunc_contains(name, this._unset_variables)) {\n _pymeth_remove.call(this._unset_variables, name);\n }\n this.activate();\n if ((!_pyfunc_truthy(is_vbo))) {\n funcname = this.ATYPEMAP[type_];\n this._attributes[name] = [0, handle, funcname, value];\n }\n else {\n stub7_ = this.ATYPEINFO[type_];\n size = stub7_[0];\n gtype = stub7_[1];\n funcname = \"vertexAttribPointer\";\n args = [size, gtype, this._gl.FALSE, stride, offset];\n this._attributes[name] = [value.handle, handle, funcname, args];\n }\n return null;\n };\n Program.prototype._pre_draw = function () {\n var args, attr_handle, funcname, stub10_, stub11_seq, stub8_, stub9_seq, tex_handle, tex_target, unit, vbo_handle, x;\n // Prepare for drawing.\n this.activate();\n stub9_seq = this._samplers;\n for (x in stub9_seq) {\n if (!stub9_seq.hasOwnProperty(x)) {\n continue;\n }\n x = stub9_seq[x];\n stub8_ = x;\n tex_target = stub8_[0];\n tex_handle = stub8_[1];\n unit = stub8_[2];\n this._gl.activeTexture(_pyfunc_add(this._gl.TEXTURE0, unit));\n this._gl.bindTexture(tex_target, tex_handle);\n }\n stub11_seq = this._attributes;\n for (x in stub11_seq) {\n if (!stub11_seq.hasOwnProperty(x)) {\n continue;\n }\n x = stub11_seq[x];\n stub10_ = x;\n vbo_handle = stub10_[0];\n attr_handle = stub10_[1];\n funcname = stub10_[2];\n args = stub10_[3];\n if (_pyfunc_truthy(vbo_handle)) {\n this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vbo_handle);\n this._gl.enableVertexAttribArray(attr_handle);\n this._gl[funcname].apply(this._gl, [].concat([attr_handle], args));\n }\n else {\n this._gl.bindBuffer(this._gl.ARRAY_BUFFER, null);\n this._gl.disableVertexAttribArray(attr_handle);\n this._gl[funcname].apply(this._gl, [].concat([attr_handle], args));\n }\n }\n if ((!_pyfunc_truthy(this._validated))) {\n this._validated = true;\n this._validate();\n }\n return null;\n };\n Program.prototype._validate = function () {\n var err_3;\n if (this._unset_variables.length) {\n console.log(\"Program has unset variables: \" + this._unset_variables + \"\");\n }\n this._gl.validateProgram(this.handle);\n if ((!_pyfunc_truthy(this._gl.getProgramParameter(this.handle, this._gl.VALIDATE_STATUS)))) {\n console.log(this._gl.getProgramInfoLog(this.handle));\n err_3 = new Error('RuntimeError:' + \"Program validation error\");\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n return null;\n };\n Program.prototype.draw = function (mode, selection) {\n var count, err_3, first, gtype, stub12_;\n // Draw the current visualization defined by the program.\n //\n // Parameters\n // ----------\n // mode : GL enum\n // Can be POINTS, LINES, LINE_LOOP, LINE_STRIP, LINE_FAN, TRIANGLES\n // selection : 2-element tuple or IndexBuffer\n // The selection to draw, specified either as (first, count) or an\n // IndexBuffer object.\n if ((!_pyfunc_truthy(this._linked))) {\n err_3 = new Error('RuntimeError:' + \"Cannot draw program if code has not been set\");\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n check_error(this._gl, \"before draw\");\n if (_pyfunc_truthy(selection instanceof IndexBuffer)) {\n this._pre_draw();\n selection.activate();\n count = selection._buffer_size / 2;\n gtype = this._gl.UNSIGNED_SHORT;\n this._gl.drawElements(mode, count, gtype, 0);\n selection.deactivate();\n }\n else {\n stub12_ = selection;\n first = stub12_[0];\n count = stub12_[1];\n if (_pyfunc_truthy(count)) {\n this._pre_draw();\n this._gl.drawArrays(mode, first, count);\n }\n }\n check_error(this._gl, \"after draw\");\n return null;\n };\n Buffer = function () {\n // Base buffer class for vertex data or index data.\n _pyfunc_instantiate(this, arguments);\n };\n Buffer.prototype = Object.create(GlooObject.prototype);\n Buffer.prototype._base_class = GlooObject.prototype;\n Buffer.prototype._class_name = \"Buffer\";\n Buffer.prototype._target = null;\n Buffer.prototype._usage = 35048;\n Buffer.prototype._create = function () {\n this.handle = this._gl.createBuffer();\n this._buffer_size = 0;\n return null;\n };\n Buffer.prototype.delete = function () {\n // Delete the buffer.\n this._gl.deleteBuffer(this.handle);\n return null;\n };\n Buffer.prototype.activate = function () {\n // Activete the buffer.\n this._gl.bindBuffer(this._target, this.handle);\n return null;\n };\n Buffer.prototype.deactivate = function () {\n // Disable the buffer.\n this._gl.bindBuffer(this._target, null);\n return null;\n };\n Buffer.prototype.set_size = function (nbytes) {\n // Set the size of the buffer in bytes.\n //\n // Parameters\n // ----------\n // nbytes : int\n // The number of bytes that the buffer needs to hold.\n if ((!_pyfunc_equals(nbytes, this._buffer_size))) {\n this.activate();\n this._gl.bufferData(this._target, nbytes, this._usage);\n this._buffer_size = nbytes;\n }\n return null;\n };\n Buffer.prototype.set_data = function (offset, data) {\n // Set the buffer data.\n //\n // Parameters\n // ----------\n // offset : int\n // The offset in bytes for the new data.\n // data : typed array\n // The data to upload.\n this.activate();\n this._gl.bufferSubData(this._target, offset, data);\n return null;\n };\n VertexBuffer = function () {\n // A buffer for vertex data.\n _pyfunc_instantiate(this, arguments);\n };\n VertexBuffer.prototype = Object.create(Buffer.prototype);\n VertexBuffer.prototype._base_class = Buffer.prototype;\n VertexBuffer.prototype._class_name = \"VertexBuffer\";\n VertexBuffer.prototype._target = 34962;\n IndexBuffer = function () {\n // A buffer for index data.\n _pyfunc_instantiate(this, arguments);\n };\n IndexBuffer.prototype = Object.create(Buffer.prototype);\n IndexBuffer.prototype._base_class = Buffer.prototype;\n IndexBuffer.prototype._class_name = \"IndexBuffer\";\n IndexBuffer.prototype._target = 34963;\n Texture2D = function () {\n // A 2 dimensional regular grid.\n _pyfunc_instantiate(this, arguments);\n };\n Texture2D.prototype = Object.create(GlooObject.prototype);\n Texture2D.prototype._base_class = GlooObject.prototype;\n Texture2D.prototype._class_name = \"Texture2D\";\n Texture2D.prototype._target = 3553;\n Texture2D.prototype._types = { \"Int8Array\": 5120, \"Uint8Array\": 5121, \"Int16Array\": 5122, \"Uint16Array\": 5123, \"Int32Array\": 5124, \"Uint32Array\": 5125, \"Float32Array\": 5126 };\n Texture2D.prototype._create = function () {\n this.handle = this._gl.createTexture();\n this._shape_format = null;\n return null;\n };\n Texture2D.prototype.delete = function () {\n // Delete the texture.\n this._gl.deleteTexture(this.handle);\n return null;\n };\n Texture2D.prototype.activate = function () {\n // Activate the texture.\n this._gl.bindTexture(this._target, this.handle);\n return null;\n };\n Texture2D.prototype.deactivate = function () {\n // Disable the texture.\n this._gl.bindTexture(this._target, 0);\n return null;\n };\n Texture2D.prototype._get_alignment = function (width) {\n var alignment, alignments, stub13_seq, stub14_itr;\n // Determines a textures byte alignment. If the width isn't a\n // power of 2 we need to adjust the byte alignment of the image.\n // The image height is unimportant.\n //\n // www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads\n alignments = [4, 8, 2, 1];\n stub13_seq = alignments;\n if ((typeof stub13_seq === \"object\") && (!Array.isArray(stub13_seq))) {\n stub13_seq = Object.keys(stub13_seq);\n }\n for (stub14_itr = 0; stub14_itr < stub13_seq.length; stub14_itr += 1) {\n alignment = stub13_seq[stub14_itr];\n if ((_pyfunc_equals((width % alignment), 0))) {\n return alignment;\n }\n }\n return null;\n };\n Texture2D.prototype.set_wrapping = function (wrap_s, wrap_t) {\n // Set the texture wrapping mode.\n //\n // Parameters\n // ----------\n // wrap_s : GL enum\n // The mode to wrap the x dimension. Valid values are REPEAT\n // CLAMP_TO_EDGE MIRRORED_REPEAT\n // wrap_t : GL enum\n // The mode to wrap the y dimension. Same options as for wrap_s.\n this.activate();\n this._gl.texParameterf(this._target, this._gl.TEXTURE_WRAP_S, wrap_s);\n this._gl.texParameterf(this._target, this._gl.TEXTURE_WRAP_T, wrap_t);\n return null;\n };\n Texture2D.prototype.set_interpolation = function (min, mag) {\n // Set the texture interpolation mode\n //\n // Parameters\n // ----------\n // min : GL enum\n // The interpolation mode when minifying (i.e. zoomed out). Valid\n // values are LINEAR and NEAREST.\n // max : GL enum\n // The interpolation mode when magnifying (i.e. zoomed in). Valid\n // values are LINEAR, NEAREST, NEAREST_MIPMAP_NEAREST,\n // LINEAR_MIPMAP_NEAREST, NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_LINEAR.\n this.activate();\n this._gl.texParameterf(this._target, this._gl.TEXTURE_MIN_FILTER, min);\n this._gl.texParameterf(this._target, this._gl.TEXTURE_MAG_FILTER, mag);\n return null;\n };\n Texture2D.prototype.set_size = function (shape, format) {\n var height, stub15_, width;\n // Set the size of the 2D texture.\n //\n // Parameters\n // ----------\n // shape : tuple of ints\n // The shape of the data to upload\n // format : GL enum\n // The format of the texture data. Can be LUMINANCE, LUMINANCE_ALPHA,\n // RGB, and RGBA.\n stub15_ = shape;\n height = stub15_[0];\n width = stub15_[1];\n if ((!_pyfunc_equals([height, width, format], this._shape_format))) {\n this._shape_format = [height, width, format];\n this.activate();\n this._gl.texImage2D(this._target, 0, format, width, height, 0, format, this._gl.UNSIGNED_BYTE, null);\n }\n this.u_shape = [height, width];\n return null;\n };\n Texture2D.prototype.set_data = function (offset, shape, data) {\n var _, alignment, err_3, format, gtype, height, stub16_, stub17_, width, x, y;\n // Set the 2D texture data.\n //\n // Parameters\n // ----------\n // offset : tuple of ints\n // Offset in pixels for each dimension.\n // shape : tuple of ints\n // The shape of the data to upload\n // data : typed array\n // The actual pixel data. Can be of any type, but on the GPU the\n // dat is stored in 8 bit precision.\n if (_pyfunc_equals(shape.length, 2)) {\n shape = [shape[0], shape[1], 1];\n }\n this.activate();\n format = this._shape_format[2];\n stub16_ = shape;\n height = stub16_[0];\n width = stub16_[1];\n _ = stub16_[2];\n stub17_ = offset;\n y = stub17_[0];\n x = stub17_[1];\n gtype = _pymeth_get.call(this._types, data.constructor.name, null);\n if ((gtype === null)) {\n err_3 = new Error('ValueError:' + (\"Type \" + data.constructor.name + \" not allowed for texture\"));\n err_3.name = \"ValueError\";\n throw err_3;\n }\n alignment = this._get_alignment(_pyfunc_mult(shape[shape.length - 2], shape[shape.length - 1]));\n if ((!_pyfunc_equals(alignment, 4))) {\n this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, alignment);\n }\n this._gl.texSubImage2D(this._target, 0, x, y, width, height, format, gtype, data);\n if ((!_pyfunc_equals(alignment, 4))) {\n this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 4);\n }\n return null;\n };\n Texture3DLike = function () {\n // A 2D texture with support to simulate a 3D texture.\n //\n // To use this class, use set_size() and set_data() as if it was a 3D\n // texture. Add the GLSL_SAMPLE_NEAREST or GLSL_SAMPLE_LINEAR to the\n // shader to add the sample3D() function that can be used instead of\n // texture2D(). This function needs ``shape`` and ``tiles`` arguments\n // which can be set via uniforms, using the ``u_shape`` and ``u_tiles``\n // attributes of this object.\n _pyfunc_instantiate(this, arguments);\n };\n Texture3DLike.prototype = Object.create(Texture2D.prototype);\n Texture3DLike.prototype._base_class = Texture2D.prototype;\n Texture3DLike.prototype._class_name = \"Texture3DLike\";\n Texture3DLike.prototype.GLSL_SAMPLE_NEAREST = \"\\n vec4 sample3D(sampler2D tex, vec3 texcoord, vec3 shape, vec2 tiles) {\\n shape.xyz = shape.zyx; // silly row-major convention\\n float nrows = tiles.y, ncols = tiles.x;\\n // Don't let adjacent frames be interpolated into this one\\n texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5);\\n texcoord.x = max(0.5, texcoord.x) / shape.x;\\n texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5);\\n texcoord.y = max(0.5, texcoord.y) / shape.y;\\n\\n float zindex = floor(texcoord.z * shape.z);\\n\\n // Do a lookup in the 2D texture\\n float u = (mod(zindex, ncols) + texcoord.x) / ncols;\\n float v = (floor(zindex / ncols) + texcoord.y) / nrows;\\n\\n return texture2D(tex, vec2(u,v));\\n }\\n \";\n Texture3DLike.prototype.GLSL_SAMPLE_LINEAR = \"\\n vec4 sample3D(sampler2D tex, vec3 texcoord, vec3 shape, vec2 tiles) {\\n shape.xyz = shape.zyx; // silly row-major convention\\n float nrows = tiles.y, ncols = tiles.x;\\n // Don't let adjacent frames be interpolated into this one\\n texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5);\\n texcoord.x = max(0.5, texcoord.x) / shape.x;\\n texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5);\\n texcoord.y = max(0.5, texcoord.y) / shape.y;\\n\\n float z = texcoord.z * shape.z;\\n float zindex1 = floor(z);\\n float u1 = (mod(zindex1, ncols) + texcoord.x) / ncols;\\n float v1 = (floor(zindex1 / ncols) + texcoord.y) / nrows;\\n\\n float zindex2 = zindex1 + 1.0;\\n float u2 = (mod(zindex2, ncols) + texcoord.x) / ncols;\\n float v2 = (floor(zindex2 / ncols) + texcoord.y) / nrows;\\n\\n vec4 s1 = texture2D(tex, vec2(u1, v1));\\n vec4 s2 = texture2D(tex, vec2(u2, v2));\\n\\n return s1 * (zindex2 - z) + s2 * (z - zindex1);\\n }\\n \";\n Texture3DLike.prototype._get_tile_info = function (shape) {\n var err_3, max_size, ncols, nrows;\n max_size = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);\n nrows = Math.floor(max_size / shape[1]);\n nrows = Math.min(nrows, shape[0]);\n ncols = window.Math.ceil(shape[0] / nrows);\n if (_pyfunc_truthy(_pyfunc_mult(ncols, shape[2]) > max_size)) {\n err_3 = new Error('RuntimeError:' + (\"Cannot fit 3D data with shape \" + shape + \" onto simulated 2D texture.\"));\n err_3.name = \"RuntimeError\";\n throw err_3;\n }\n return [nrows, ncols];\n };\n Texture3DLike.prototype.set_size = function (shape, format) {\n var ncols, nrows, sim_shape, stub18_;\n // Set the size of the 3D texture.\n //\n // Parameters\n // ----------\n // shape : tuple of ints\n // The shape of the data to upload\n // format : GL enum\n // The format of the texture data. Can be LUMINANCE, LUMINANCE_ALPHA,\n // RGB, and RGBA.\n stub18_ = this._get_tile_info(shape);\n nrows = stub18_[0];\n ncols = stub18_[1];\n sim_shape = [_pyfunc_mult(shape[1], nrows), _pyfunc_mult(shape[2], ncols)];\n Texture3DLike.prototype._base_class.set_size.call(this, sim_shape, format);\n this.u_shape = [shape[0], shape[1], shape[2]];\n this.u_tiles = [ncols, nrows];\n return null;\n };\n Texture3DLike.prototype.set_data = function (offset, shape, data) {\n var Type, col, elements_per_tile, err_3, ncols, nrows, row, sim_shape, stub19_, stub20_, tile, z, zeros;\n // Set the 3D texture data.\n //\n // Parameters\n // ----------\n // offset : tuple of ints\n // Offset in pixels for each dimension.\n // shape : tuple of ints\n // The shape of the data to upload\n // data : typed array\n // The actual pixel data. Can be of any type, but on the GPU the\n // dat is stored in 8 bit precision.\n if (_pyfunc_equals(shape.length, 3)) {\n shape = [shape[0], shape[1], shape[2], 1];\n }\n if ((!(_pyfunc_all(((function list_comprehenson() { var res = []; var i, iter0, i0; iter0 = offset; if ((typeof iter0 === \"object\") && (!Array.isArray(iter0))) {\n iter0 = Object.keys(iter0);\n } for (i0 = 0; i0 < iter0.length; i0++) {\n i = iter0[i0];\n {\n res.push(_pyfunc_equals(i, 0));\n }\n } return res; }).apply(this)))))) {\n err_3 = new Error('ValueError:' + \"Texture3DLike does not support nonzero offset (for now)\");\n err_3.name = \"ValueError\";\n throw err_3;\n }\n stub19_ = this._get_tile_info(shape);\n nrows = stub19_[0];\n ncols = stub19_[1];\n sim_shape = [_pyfunc_mult(shape[1], nrows), _pyfunc_mult(shape[2], ncols), shape[3]];\n if (_pyfunc_equals(ncols, 1)) {\n Texture3DLike.prototype._base_class.set_data.call(this, [0, 0], sim_shape, data);\n }\n else {\n Type = data.constructor;\n zeros = new Type(_pyfunc_mult(_pyfunc_mult(sim_shape[0], sim_shape[1]), sim_shape[2]));\n Texture3DLike.prototype._base_class.set_data.call(this, [0, 0], sim_shape, zeros);\n for (z = 0; z < shape[0]; z += 1) {\n stub20_ = [Math.floor(z / ncols), z % ncols];\n row = stub20_[0];\n col = stub20_[1];\n elements_per_tile = Math.floor(data.length / shape[0]);\n tile = data.slice(_pyfunc_mult(z, elements_per_tile), _pyfunc_mult((z + 1), elements_per_tile));\n Texture3DLike.prototype._base_class.set_data.call(this, [_pyfunc_mult(row, shape[1]), _pyfunc_mult(col, shape[2])], shape.slice(1), tile);\n }\n }\n return null;\n };\n module.exports = {\n \"Buffer\": Buffer,\n \"GlooObject\": GlooObject,\n \"IndexBuffer\": IndexBuffer,\n \"Program\": Program,\n \"Texture2D\": Texture2D,\n \"Texture3DLike\": Texture3DLike,\n \"VertexBuffer\": VertexBuffer,\n \"check_error\": check_error,\n \"console\": console\n };\n}\n"]}