diff --git a/js/src/40_gl.ts b/js/src/40_gl.ts index eb920bb5..00c169e8 100644 --- a/js/src/40_gl.ts +++ b/js/src/40_gl.ts @@ -612,7 +612,7 @@ void main() { float coverage = smoothstep(0.0, max(fwidth(edge) * strokeWidth, 1e-5), edge); // Both stroke sources ship straight alpha; the per-item alpha stack // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; + vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : (u_strokeMode == 2 ? paint : u_stroke); float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); outColor = mix(stroke, fill, coverage); @@ -849,7 +849,7 @@ void main() { if (strokeWidth > 0.0) { // Both stroke sources ship straight alpha; the per-item alpha stack // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; + vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : (u_strokeMode == 2 ? paint : u_stroke); float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); float inner = 1.0 - smoothstep(-aa, aa, d + strokeWidth); diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index b4697fca..912481ea 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -2417,7 +2417,7 @@ export class ChartView { // stack in and premultiplies there (uniform and buffer strokes alike). const sc = g.strokeColor || [0, 0, 0, 0]; gl.uniform4f(u("u_stroke"), sc[0], sc[1], sc[2], sc[3]); - gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : 0); + gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : (g.strokeMatchFill ? 2 : 0)); gl.uniform1f(u("u_strokeOpacity"), this._strokeOpacity(g.trace.style || {})); this._setGradientUniforms(prog, g.grad); } @@ -2433,6 +2433,7 @@ export class ChartView { ? [Number(cr[0]) || 0, Number(cr[1]) || 0] : [Number(cr) || 0, Number(cr) || 0]; g.strokeWidth = Number(s.stroke_width) || 0; + g.strokeMatchFill = !!(t.stroke && t.stroke.mode === "match_fill"); const opaque = [g.color[0], g.color[1], g.color[2], 1]; g.strokeColor = s.stroke ? parseColor(this.root, s.stroke, opaque) : opaque; g.grad = this._resolveMarkFill(s, g.color); @@ -2556,6 +2557,7 @@ export class ChartView { const style = t.style || {}; g.meshStrokeWidth = Number(style.stroke_width) || 0; g.meshStroke = parseColor(this.root, style.stroke || "transparent", [0, 0, 0, 0]); + g.strokeMatchFill = !!(t.stroke && t.stroke.mode === "match_fill"); } // Hexbin ships cell centers plus one color value per cell; every hexagon @@ -3511,7 +3513,7 @@ export class ChartView { const stroke = g.meshStroke || [0, 0, 0, 0]; gl.uniform4f(u("u_stroke"), stroke[0], stroke[1], stroke[2], stroke[3]); gl.uniform1f(u("u_strokeWidth"), g.meshStrokeWidth || 0); - gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : 0); + gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : (g.strokeMatchFill ? 2 : 0)); gl.uniform1f(u("u_strokeOpacity"), this._strokeOpacity(g.trace.style)); if (g.colorMode && g.lut) { gl.activeTexture(gl.TEXTURE0); diff --git a/python/xy/_paint.py b/python/xy/_paint.py index e072b9e5..e9edcec7 100644 --- a/python/xy/_paint.py +++ b/python/xy/_paint.py @@ -10,6 +10,70 @@ ColumnReader = Callable[[int], np.ndarray] +def triangle_mesh_boundary(*vertices: np.ndarray) -> np.ndarray | None: + """Recover the single exterior ring of a tessellated simple polygon. + + ``Axes.fill`` reaches the shared triangle renderer for WebGL, but static + exporters should paint its triangulation as one polygon. Otherwise each + independently antialiased triangle leaks a hairline of background (and + applies translucent alpha more than once) along internal diagonals. + """ + if len(vertices) != 6: + raise ValueError("triangle mesh boundary requires six coordinate arrays") + arrays = [np.asarray(values, dtype=np.float64).reshape(-1) for values in vertices] + n = min((len(values) for values in arrays), default=0) + if n == 0: + return None + finite = np.concatenate(arrays) + span = float(np.nanmax(finite) - np.nanmin(finite)) + # Each triangle coordinate is transported in an independently offset + # float32 column, so the same source vertex may decode a few ULPs apart in + # x0/x1/x2. The joined-fill flag is only used for one simple polygon; a + # generous relative bucket is still far below meaningful edge spacing. + tolerance = max(span * 2e-5, 1e-12) + + def vertex_key(point: tuple[float, float]) -> tuple[int, int]: + return (round(point[0] / tolerance), round(point[1] / tolerance)) + + edge_counts: dict[tuple[tuple[int, int], tuple[int, int]], int] = {} + points_by_key: dict[tuple[int, int], tuple[float, float]] = {} + for index in range(n): + points = ( + (float(arrays[0][index]), float(arrays[1][index])), + (float(arrays[2][index]), float(arrays[3][index])), + (float(arrays[4][index]), float(arrays[5][index])), + ) + for start, end in zip(points, points[1:] + points[:1], strict=True): + start_key, end_key = vertex_key(start), vertex_key(end) + points_by_key.setdefault(start_key, start) + points_by_key.setdefault(end_key, end) + edge = (start_key, end_key) if start_key <= end_key else (end_key, start_key) + edge_counts[edge] = edge_counts.get(edge, 0) + 1 + boundary = [edge for edge, count in edge_counts.items() if count == 1] + if len(boundary) < 3: + return None + adjacency: dict[tuple[int, int], list[tuple[int, int]]] = {} + for start, end in boundary: + adjacency.setdefault(start, []).append(end) + adjacency.setdefault(end, []).append(start) + if any(len(neighbors) != 2 for neighbors in adjacency.values()): + return None + first = boundary[0][0] + ring = [first] + previous: tuple[int, int] | None = None + current = first + for _ in range(len(boundary)): + neighbors = adjacency[current] + following = neighbors[0] if neighbors[0] != previous else neighbors[1] + if following == first: + if len(ring) != len(boundary): + return None + return np.asarray([points_by_key[key] for key in ring], dtype=np.float64) + ring.append(following) + previous, current = current, following + return None + + def direct_rgba(channel: dict[str, Any], n: int, read_column: ColumnReader) -> np.ndarray | None: """Decode a packed normalized RGBA8 channel to canonical float RGBA.""" if channel.get("mode") != "direct_rgba": diff --git a/python/xy/_raster.py b/python/xy/_raster.py index 24109955..25900459 100644 --- a/python/xy/_raster.py +++ b/python/xy/_raster.py @@ -1538,7 +1538,9 @@ def read(index: int) -> np.ndarray: x0, y0, x1, y1, x2, y2 = vertices widths = _paint.style_values(t, "stroke_width", n, read, float(style.get("stroke_width", 0.0))) - if t.get("stroke") is not None: + if (t.get("stroke") or {}).get("mode") == "match_fill": + stroke_intrinsic = _trace_paint_rgba(t, "color", n, color, read) + elif t.get("stroke") is not None: stroke_intrinsic = _trace_paint_rgba(t, "stroke", n, color, read) elif style.get("stroke") is not None: stroke_intrinsic = np.tile( @@ -1554,6 +1556,14 @@ def read(index: int) -> np.ndarray: projected = (sx(x0[:n]), sy(y0[:n]), sx(x1[:n]), sy(y1[:n]), sx(x2[:n]), sy(y2[:n])) if n == 0: return + if style.get("joined_fill") and np.all(fills == fills[0]) and np.all(widths == 0.0): + boundary = _paint.triangle_mesh_boundary(x0, y0, x1, y1, x2, y2) + if boundary is not None: + cmd.fill( + list(zip(sx(boundary[:, 0]), sy(boundary[:, 1]), strict=True)), + tuple(int(value) for value in fills[0]), + ) + return if np.all(widths == widths[0]) and np.all(strokes == strokes[0]): cmd.triangles( *projected, @@ -1649,7 +1659,9 @@ def _rect_style_arrays( * 255.0 ).astype(np.uint8) style = trace.get("style") or {} - if trace.get("stroke") is not None: + if (trace.get("stroke") or {}).get("mode") == "match_fill": + stroke_face = face + elif trace.get("stroke") is not None: stroke_face = _trace_paint_rgba(trace, "stroke", n, fallback, read) elif style.get("stroke") is not None: stroke_face = np.tile( diff --git a/python/xy/_svg.py b/python/xy/_svg.py index 34c20ecb..2e29d7d6 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -2251,7 +2251,9 @@ def read(index: int) -> np.ndarray: face = _trace_paint_rgba(t, "color", n, fallback, read) fills = _paint.effective_rgba(face, t, read, component="fill", default_opacity=1.0) - if t.get("stroke") is not None: + if (t.get("stroke") or {}).get("mode") == "match_fill": + stroke_face = face + elif t.get("stroke") is not None: stroke_face = _trace_paint_rgba(t, "stroke", n, fallback, read) elif style.get("stroke") is not None: stroke_face = np.tile( @@ -2265,6 +2267,21 @@ def read(index: int) -> np.ndarray: t, "stroke_width", n, read, float(style.get("stroke_width", 0.0)) ) x0, y0, x1, y1, x2, y2 = vertices + if ( + style.get("joined_fill") + and n + and np.all(fills == fills[0]) + and np.all(stroke_widths == 0.0) + ): + boundary = _paint.triangle_mesh_boundary(x0, y0, x1, y1, x2, y2) + if boundary is not None: + points = " ".join(f"{_num(float(sx(x)))},{_num(float(sy(y)))}" for x, y in boundary) + fill = fills[0] + return ( + f'' + ) out = [""] for i in range(n): points = " ".join( @@ -2334,7 +2351,9 @@ def _rect_svg_styles( face = _trace_paint_rgba(trace, "color", n, fallback, read) fills_rgba = _paint.effective_rgba(face, trace, read, component="fill", default_opacity=0.85) - if trace.get("stroke") is not None: + if (trace.get("stroke") or {}).get("mode") == "match_fill": + stroke_face = face + elif trace.get("stroke") is not None: stroke_face = _trace_paint_rgba(trace, "stroke", n, fallback, read) elif style.get("stroke") is not None: stroke_face = np.tile( diff --git a/python/xy/components.py b/python/xy/components.py index 03ded1ef..c610a9ba 100644 --- a/python/xy/components.py +++ b/python/xy/components.py @@ -906,6 +906,7 @@ def triangle_mesh( opacity: Any = 1.0, stroke: Any = None, stroke_width: Any = 0.0, + _joined_fill: bool = False, style: Optional[dict[str, StyleValue]] = None, class_name: Optional[str] = None, x_axis: str = "x", @@ -928,6 +929,9 @@ def triangle_mesh( opacity: Triangle opacity from zero to one. stroke: Optional triangle outline color. stroke_width: Triangle outline width in pixels. + _joined_fill: Internal export hint; static exports fill a uniform, unstroked mesh as + one joined boundary ring instead of per-triangle fills, which avoids antialias + seams and repeated alpha along internal diagonals. style: Mark style overrides. class_name: Adapter-only trace metadata; it does not style canvas geometry. x_axis: Identifier of the x axis used by this mark. @@ -952,6 +956,7 @@ def triangle_mesh( "opacity": opacity, "stroke": stroke, "stroke_width": stroke_width, + "_joined_fill": _joined_fill, "x_axis": x_axis, "y_axis": y_axis, }, @@ -4613,6 +4618,7 @@ def _apply_triangle_mesh(fig: Figure, m: Mark, data: Any) -> None: opacity=m.props["opacity"], stroke=m.props["stroke"], stroke_width=m.props["stroke_width"], + _joined_fill=m.props["_joined_fill"], style=m.style, ) diff --git a/python/xy/marks.py b/python/xy/marks.py index 80e79b2c..528ca0d6 100644 --- a/python/xy/marks.py +++ b/python/xy/marks.py @@ -375,6 +375,7 @@ def triangle_mesh( opacity: Any = 1.0, stroke: Any = None, stroke_width: Any = 0.0, + _joined_fill: bool = False, style: styles.StyleMapping | None = None, ) -> "Figure": """Add independently colored filled triangles as one instanced mesh.""" @@ -431,10 +432,22 @@ def triangle_mesh( if color_ch.mode != "continuous": raise ValueError("triangle_mesh domain requires a continuous numeric color array") color_ch.domain = self._finite_increasing_pair(domain, "triangle_mesh domain") + # A width without an explicit stroke means "outline in the face color". + # Constant paints already get that fallback from the renderer; direct and + # semantic color channels need the explicit buffer-free match mode. + if ( + stroke_value is None + and stroke_ch is None + and color_ch.mode != "constant" + and (stroke_width_value or "stroke_width" in style_channels) + ): + stroke_ch = channels.ColorChannel(mode="match_fill") checkpoint = self._checkpoint() try: x0c, y0c, x1c, y1c, x2c, y2c = [self.store.ingest(values) for values in arrays] style: dict[str, Any] = {"opacity": opacity_value, "role": "triangle-mesh"} + if _joined_fill: + style["joined_fill"] = True style.update(styles._opacity_channels(css)) if stroke_value is not None: style["stroke"] = stroke_value @@ -698,6 +711,17 @@ def _bar_like( mark_style["artist_alpha"] = alpha_values[index] series_styles.append(mark_style) series_channels.append(merged_channels) + if direct_strokes is None and direct_colors is not None: + resolved_strokes: list[Optional[channels.ColorChannel]] = [ + ( + channels.ColorChannel(mode="match_fill") + if stroke_width_values[index] or "stroke_width" in series_channels[index] + else None + ) + for index in range(n_series) + ] + else: + resolved_strokes = [None] * n_series if direct_strokes is None else list(direct_strokes) checkpoint = self._checkpoint() try: if category_labels is not None: @@ -719,7 +743,7 @@ def _bar_like( role=f"{kind}-normalized" if mode == "normalized" else kind, extra_style=series_styles[0], color_ch=None if direct_colors is None else direct_colors[0], - stroke_ch=None if direct_strokes is None else direct_strokes[0], + stroke_ch=resolved_strokes[0], style_channels=series_channels[0], ) elif mode == "grouped": @@ -739,7 +763,7 @@ def _bar_like( role=f"{kind}-grouped", extra_style=series_styles[i], color_ch=None if direct_colors is None else direct_colors[i], - stroke_ch=None if direct_strokes is None else direct_strokes[i], + stroke_ch=resolved_strokes[i], style_channels=series_channels[i], ) else: @@ -761,7 +785,7 @@ def _bar_like( role=f"{kind}-{mode}", extra_style=series_styles[i], color_ch=None if direct_colors is None else direct_colors[i], - stroke_ch=None if direct_strokes is None else direct_strokes[i], + stroke_ch=resolved_strokes[i], style_channels=series_channels[i], ) pos_base = np.where(row >= 0, y1, pos_base) diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index bc3710cc..bda230d2 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -775,6 +775,12 @@ def _add(self, kind: str, entry: dict[str, Any]) -> dict[str, Any]: _transform_entry_axis(entry, axis, {"name": "linear"}, spec) nonlinear_axes.append((axis, spec)) host._entries.append(entry) + # Aspect modes may be selected before any data is added (the + # Matplotlib fill gallery does exactly this with ``axis("equal")``). + # Keep their bounds tied to the current autoscaled data until the user + # explicitly pins a domain instead of freezing the empty (0, 1) view. + if host._aspect_equal and not host._explicit_domains: + host._set_aspect_equal_from_current() for axis, spec in nonlinear_axes: # scale-generated ticks were derived from the extent at # set_*scale time; new data must refresh them (user-set ticks @@ -1475,7 +1481,7 @@ def paint(value: Any, label_text: str, default: Optional[str] = None) -> Any: if orientation == "vertical": ex, ey, exerr, eyerr = positions, bases + values, xerr, yerr else: - ex, ey, exerr, eyerr = bases + values, positions, yerr, xerr + ex, ey, exerr, eyerr = bases + values, positions, xerr, yerr err_kwargs = { "xerr": exerr, "yerr": eyerr, @@ -1918,8 +1924,8 @@ def imshow(self, z: ArrayLike, cmap: Any = None, **kwargs: Any) -> AxesImage: } if interpolation not in supported_interpolation: raise ValueError(f"unsupported imshow interpolation: {interpolation!r}") - if interpolation_stage not in (None, "data"): - raise not_implemented(f"imshow(interpolation_stage={interpolation_stage!r})") + if interpolation_stage not in (None, "auto", "data", "rgba"): + raise ValueError("imshow interpolation_stage must be 'auto', 'data', 'rgba', or None") if clip_on is not True: raise not_implemented("imshow(clip_on=False)") if transform not in (None, self.transData, self.transAxes): @@ -2036,17 +2042,33 @@ def extreme(name: str, default: tuple[float, float, float, float]) -> np.ndarray ) grid = np.dstack((rgb.reshape(grid.shape + (3,)) / 255.0, alpha_array)) truecolor = True + effective_interpolation = ( + rcParams["image.interpolation"] if interpolation is None else interpolation + ) if ( not truecolor - and interpolation not in (None, "none", "nearest") - and min(grid.shape) >= 2 + and interpolation_stage == "rgba" + and effective_interpolation not in ("none", "nearest") ): + grid = _scalar_grid_rgba( + grid, + cmap if cmap is not None else rcParams["image.cmap"], + vmin, + vmax, + ) + truecolor = True + if effective_interpolation not in ("none", "nearest") and min(grid.shape[:2]) >= 2: # The notebook's ordinary image box is ~369 px per side. A 128² # intermediate left each interpolated sample covering about 3×3 # display pixels because heatmaps intentionally use nearest texture # sampling. Keep a bounded 512² surface so non-nearest imshow output # is at least display-resolution while nearest retains source cells. - grid = _upsample_grid(grid, max(512, grid.shape[1]), max(512, grid.shape[0])) + grid = _resample_grid( + grid, + max(512, grid.shape[1]), + max(512, grid.shape[0]), + effective_interpolation, + ) if transform == self.transAxes and extent is not None: xlo, xhi = self._axis_props("x").get("domain", self._entry_extent("x")) ylo, yhi = self._axis_props("y").get("domain", self._entry_extent("y")) @@ -2743,9 +2765,16 @@ def axis( self._aspect_equal = False self._aspect_adjustable = "box" self._aspect_bounds = None - self._set_tight_domains() + # Calling an aspect/autoscale mode on an empty Axes must not turn + # the placeholder (0, 1) view into explicit limits. Matplotlib + # continues autoscaling when artists are added afterwards. + if self._entries: + self._set_tight_domains() if arg in {"equal", "scaled", "image", "square"}: - self._set_aspect_equal_from_current() + if self._entries: + self._set_aspect_equal_from_current() + else: + self._aspect_equal = True if arg == "equal": # Matplotlib spells axis("equal") as # set_aspect("equal", adjustable="datalim"): retain the axes @@ -5230,16 +5259,108 @@ def _masked_float(value: Any) -> np.ndarray: return np.ma.asarray(value, dtype=np.float64).filled(np.nan) -def _upsample_grid(grid: np.ndarray, width: int, height: int) -> np.ndarray: - """Small dependency-free bilinear resampler for interpolated imshow gradients.""" - source_y = np.linspace(0.0, 1.0, grid.shape[0]) - source_x = np.linspace(0.0, 1.0, grid.shape[1]) - target_y = np.linspace(0.0, 1.0, height) - target_x = np.linspace(0.0, 1.0, width) - horizontal = np.vstack([np.interp(target_x, source_x, row) for row in grid]) - return np.vstack( - [np.interp(target_y, source_y, horizontal[:, column]) for column in range(width)] - ).T +def _interpolation_weights(source: int, target: int, method: str) -> np.ndarray: + """Return a normalized target-by-source matrix for a separable filter.""" + positions = np.linspace(0.0, source - 1.0, target)[:, None] + distance = positions - np.arange(source, dtype=np.float64)[None, :] + absolute = np.abs(distance) + + def keys(a: float) -> np.ndarray: + first = (a + 2.0) * absolute**3 - (a + 3.0) * absolute**2 + 1.0 + second = a * absolute**3 - 5.0 * a * absolute**2 + 8.0 * a * absolute - 4.0 * a + return np.where(absolute <= 1.0, first, np.where(absolute < 2.0, second, 0.0)) + + if method == "bilinear": + weights = np.maximum(0.0, 1.0 - absolute) + elif method == "hanning": + weights = np.where(absolute < 1.0, 0.5 + 0.5 * np.cos(np.pi * absolute), 0.0) + elif method == "hamming": + weights = np.where(absolute < 1.0, 0.54 + 0.46 * np.cos(np.pi * absolute), 0.0) + elif method == "gaussian": + weights = np.where(absolute < 2.0, np.exp(-2.0 * absolute**2), 0.0) + elif method == "kaiser": + radius = 3.0 + weights = np.where( + absolute < radius, + np.i0(5.0 * np.sqrt(np.maximum(0.0, 1.0 - (absolute / radius) ** 2))) / np.i0(5.0), + 0.0, + ) + elif method == "sinc": + weights = np.where(absolute < 4.0, np.sinc(distance), 0.0) + elif method == "lanczos": + weights = np.where(absolute < 3.0, np.sinc(distance) * np.sinc(distance / 3.0), 0.0) + elif method == "bessel": + # A windowed-sinc approximation keeps this dependency-free; unlike the + # old bilinear alias it still preserves the filter's ringing character. + weights = np.where(absolute < 4.0, np.sinc(distance) * np.sinc(distance / 4.0), 0.0) + elif method == "mitchell": + b = c = 1.0 / 3.0 + first = ( + (12 - 9 * b - 6 * c) * absolute**3 + (-18 + 12 * b + 6 * c) * absolute**2 + (6 - 2 * b) + ) / 6.0 + second = ( + (-b - 6 * c) * absolute**3 + + (6 * b + 30 * c) * absolute**2 + + (-12 * b - 48 * c) * absolute + + (8 * b + 24 * c) + ) / 6.0 + weights = np.where(absolute < 1.0, first, np.where(absolute < 2.0, second, 0.0)) + else: + cubic_a = { + "bicubic": -0.75, + "catrom": -0.5, + "hermite": 0.0, + "quadric": -0.25, + "spline16": -1.0, + "spline36": -0.35, + "antialiased": -0.5, + }.get(method, -0.5) + weights = keys(cubic_a) + totals = weights.sum(axis=1, keepdims=True) + return weights / np.where(np.abs(totals) > 1e-12, totals, 1.0) + + +def _resample_grid(grid: np.ndarray, width: int, height: int, method: str) -> np.ndarray: + """Dependency-free separable resampling for scalar and RGB(A) images.""" + values = np.asarray(grid, dtype=np.float64) + wy = _interpolation_weights(values.shape[0], height, method) + wx = _interpolation_weights(values.shape[1], width, method) + + def resample(channel: np.ndarray) -> np.ndarray: + finite = np.isfinite(channel) + if finite.all(): + return wy @ channel @ wx.T + # Renormalize around masked samples instead of allowing IEEE + # ``0 * nan`` terms to poison every output pixel touched by a filter. + numerator = wy @ np.where(finite, channel, 0.0) @ wx.T + denominator = wy @ finite.astype(np.float64) @ wx.T + return np.divide( + numerator, + denominator, + out=np.full_like(numerator, np.nan), + where=np.abs(denominator) > 1e-12, + ) + + if values.ndim == 2: + return resample(values) + channels = [resample(values[..., index]) for index in range(values.shape[2])] + return np.stack(channels, axis=-1) + + +def _scalar_grid_rgba(grid: np.ndarray, cmap: Any, vmin: Any, vmax: Any) -> np.ndarray: + """Map scalar samples before RGBA-stage interpolation.""" + from xy._svg import _lut + + values = np.asarray(grid, dtype=np.float64) + finite = values[np.isfinite(values)] + lo = float(vmin) if vmin is not None else (float(finite.min()) if finite.size else 0.0) + hi = float(vmax) if vmax is not None else (float(finite.max()) if finite.size else 1.0) + normalized = np.clip((values - lo) / ((hi - lo) or 1.0), 0.0, 1.0) + rgb = _lut(resolve_cmap(cmap), np.nan_to_num(normalized, nan=0.0).reshape(-1)).reshape( + values.shape + (3,) + ) + alpha = np.where(np.isfinite(values), 1.0, 0.0) + return np.dstack((rgb / 255.0, alpha)) def _marked_values(x: Any, y: Any, markevery: Any) -> tuple[Any, Any]: diff --git a/python/xy/pyplot/_plot_types.py b/python/xy/pyplot/_plot_types.py index 5fd23ef2..794c9bcb 100644 --- a/python/xy/pyplot/_plot_types.py +++ b/python/xy/pyplot/_plot_types.py @@ -356,6 +356,41 @@ def centers(values: np.ndarray, size: int, name: str) -> Optional[np.ndarray]: return x_centers, y_centers +def _gouraud_rect_axes( + x: Any, y: Any, shape: tuple[int, int] +) -> Optional[tuple[np.ndarray, np.ndarray]]: + """Return same-shape, uniform rectilinear vertices for Gouraud shading.""" + rows, cols = shape + xa, ya = np.asarray(x, dtype=np.float64), np.asarray(y, dtype=np.float64) + if xa.ndim == ya.ndim == 2: + if xa.shape != shape or ya.shape != shape: + raise ValueError("pcolormesh Gouraud X, Y, and C must have matching shapes") + if not np.allclose(xa, xa[:1, :], equal_nan=True) or not np.allclose( + ya, ya[:, :1], equal_nan=True + ): + return None + xa, ya = xa[0], ya[:, 0] + elif xa.shape != (cols,) or ya.shape != (rows,): + raise ValueError("pcolormesh Gouraud X, Y, and C must have matching shapes") + if (len(xa) > 2 and not np.allclose(np.diff(xa), np.diff(xa)[0])) or ( + len(ya) > 2 and not np.allclose(np.diff(ya), np.diff(ya)[0]) + ): + return None + return xa, ya + + +def _bilinear_grid(grid: np.ndarray, width: int, height: int) -> np.ndarray: + """Small NumPy-only bilinear expansion used by regular Gouraud meshes.""" + source_y = np.linspace(0.0, 1.0, grid.shape[0]) + source_x = np.linspace(0.0, 1.0, grid.shape[1]) + target_y = np.linspace(0.0, 1.0, height) + target_x = np.linspace(0.0, 1.0, width) + horizontal = np.vstack([np.interp(target_x, source_x, row) for row in grid]) + return np.vstack( + [np.interp(target_y, source_y, horizontal[:, column]) for column in range(width)] + ).T + + def _regular_mesh_axes(x: Any, y: Any, shape: tuple[int, int]) -> tuple[np.ndarray, np.ndarray]: """Return axes for a rectilinear grid, including non-uniform spacing.""" rows, cols = shape @@ -847,6 +882,7 @@ def fill(self, *args: Any, data: TableLike = None, **kwargs: Any) -> list[PolyCo "color": resolve_color(chosen) if chosen is not None else self._next_color(), "name": None if label is None else str(label), "opacity": 1.0 if alpha is None else float(alpha), + "_joined_fill": True, } entry = self._add( "@mark", @@ -3381,6 +3417,38 @@ def pcolormesh(self, *args: Any, **kwargs: Any) -> PolyCollection: vmax = norm_vmax domain = (float(vmin), float(vmax)) if vmin is not None and vmax is not None else None regular = None if x is None else _uniform_mesh_axes(x, y, z.shape) + if shading == "gouraud": + gouraud_axes = ( + (np.arange(z.shape[1], dtype=float), np.arange(z.shape[0], dtype=float)) + if x is None + else _gouraud_rect_axes(x, y, z.shape) + ) + no_edges = edgecolors is None or ( + isinstance(edgecolors, str) and edgecolors.lower() == "none" + ) + if gouraud_axes is not None and no_edges: + width = max(2, min(512, max(256, z.shape[1] * 32))) + height = max(2, min(512, max(256, z.shape[0] * 32))) + smooth = _bilinear_grid(z, width, height) + gx, gy = gouraud_axes + mark_kwargs: dict[str, Any] = { + "x": np.linspace(float(gx[0]), float(gx[-1]), width), + "y": np.linspace(float(gy[0]), float(gy[-1]), height), + "colormap": colormap, + "opacity": opacity, + } + if domain is not None: + mark_kwargs["domain"] = domain + entry = self._add( + "@mark", + { + "factory": "heatmap", + "args": (smooth,), + "kwargs": mark_kwargs, + "source_z": z, + }, + ) + return PolyCollection(self, entry) if x is None or (regular is not None and shading != "gouraud"): if regular is not None: x, y = regular diff --git a/python/xy/pyplot/_rc.py b/python/xy/pyplot/_rc.py index 19537e39..bbf5d820 100644 --- a/python/xy/pyplot/_rc.py +++ b/python/xy/pyplot/_rc.py @@ -70,6 +70,10 @@ def by_key(self) -> dict[str, list[str]]: "legend.frameon": True, "text.usetex": False, "image.cmap": "viridis", + # Matplotlib's "antialiased" default resolves to nearest-neighbor when a + # small image is enlarged by more than 3x; pre-rendering has no final plot + # size yet, so nearest is the faithful and compact default here. + "image.interpolation": "nearest", "image.origin": "upper", "axes.prop_cycle": _PropCycle(), } diff --git a/python/xy/static/index.js b/python/xy/static/index.js deleted file mode 100644 index c57acf9f..00000000 --- a/python/xy/static/index.js +++ /dev/null @@ -1,770 +0,0 @@ -var e=[88,89,66,70],t=1,n=24,r=8,i=Object.freeze({maxFrameBytes:512*1024*1024,maxMetadataBytes:8*1024*1024,maxBuffers:4096,maxBufferBytes:256*1024*1024});function a(e,t=`buffer`){if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw TypeError(`${t} must be an ArrayBuffer or ArrayBuffer view`)}function o(e){let t=a(e,`chart payload`);return t.byteOffset%4==0?t:new Uint8Array(t)}function s(e,t){let n=e?.columns;if(!Array.isArray(n))return!1;let r=e=>e.dtype===`u8`?1:4;return e.buffer_layout===`split`?Array.isArray(t)?n.every(e=>{if(!Number.isInteger(e.buf))return!0;let n=t[e.buf];return!!n&&e.len*r(e)<=n.byteLength}):!1:Array.isArray(t)||!t?!1:n.every(e=>e.byte_offset+e.len*r(e)<=t.byteLength)}function c(e,t){if(e.buffer_layout===`split`){if(!Array.isArray(t))throw Error(`xy: spec says buffer_layout=split but the transport delivered one buffer`);return t.map(o)}if(Array.isArray(t))throw Error(`xy: transport delivered a buffer list but the spec is not split-layout`);return o(t)}function l(e,t){let n=i[t],r=e&&e[t]!=null?e[t]:n;if(!Number.isSafeInteger(r)||r<=0)throw RangeError(`${t} must be a positive safe integer`);return r}function u(e){return Math.ceil(e/r)*r}function d(e,t,n){let r=e.getBigUint64(t,!0);if(r>BigInt(2**53-1))throw RangeError(`${n} exceeds JavaScript's safe integer range`);return Number(r)}function f(e,t,n,r){if(n>e.byteLength)throw RangeError(`truncated ${r} padding`);for(let i=t;ic)throw RangeError(`maxMetadataBytes cannot exceed maxFrameBytes`);if(h>c)throw RangeError(`maxBufferBytes cannot exceed maxFrameBytes`);if(s.byteOffset%r!==0)throw RangeError(`frame body must start on an 8-byte boundary`);if(s.byteLength>c)throw RangeError(`frame length ${s.byteLength} exceeds limit ${c}`);if(s.byteLengthp)throw RangeError(`metadata length ${b} exceeds limit ${p}`);if(x>m)throw RangeError(`buffer count ${x} exceeds limit ${m}`);let C=n+b;if(C>s.byteLength)throw RangeError(`truncated frame metadata`);let w;try{let e=new Uint8Array(s.buffer,s.byteOffset+n,b);w=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(e))}catch(e){throw RangeError(`invalid frame metadata JSON: ${e}`)}if(!w||Array.isArray(w)||typeof w!=`object`)throw RangeError(`frame metadata must decode to an object`);let T=u(C);f(s,C,T,`metadata`);let E=[];for(let e=0;es.byteLength)throw RangeError(`truncated buffer ${e} length`);let t=d(g,T,`buffer ${e} length`);if(T+=8,t>h)throw RangeError(`buffer ${e} length ${t} exceeds limit ${h}`);let n=T+t;if(n>s.byteLength)throw RangeError(`truncated buffer ${e}`);let i=s.byteOffset+T;if(i%r!==0)throw RangeError(`buffer ${e} is not 8-byte aligned`);E.push(new Uint8Array(s.buffer,i,t));let a=u(n);f(s,n,a,`buffer ${e}`),T=a}if(T!==s.byteLength)throw RangeError(`frame has ${s.byteLength-T} trailing bytes`);return{message:w,buffers:E,version:t,byteLength:s.byteLength}}var m={binary:[[255,255,255],[0,0,0]],gray:[[0,0,0],[25,25,25],[51,51,51],[76,76,76],[102,102,102],[128,128,128],[153,153,153],[179,179,179],[204,204,204],[230,230,230],[255,255,255]],viridis:[[68,1,84],[72,36,117],[65,68,135],[53,95,141],[42,120,142],[33,145,140],[34,168,132],[68,191,112],[122,209,81],[189,223,38],[253,231,37]],plasma:[[13,8,135],[65,4,157],[106,0,168],[143,13,164],[177,42,144],[204,71,120],[225,100,98],[242,132,75],[252,166,54],[252,206,37],[240,249,33]],inferno:[[0,0,4],[22,11,57],[66,10,104],[106,23,110],[147,38,103],[188,55,84],[221,81,58],[243,120,25],[252,165,10],[246,215,70],[252,255,164]],magma:[[0,0,4],[20,14,54],[59,15,112],[100,26,128],[140,41,129],[183,55,121],[222,73,104],[247,112,92],[254,159,109],[254,207,146],[252,253,191]],cividis:[[0,34,78],[8,51,112],[53,69,108],[79,87,108],[102,105,112],[125,124,120],[148,142,119],[174,163,113],[200,184,102],[229,207,82],[254,232,56]],coolwarm:[[59,76,192],[89,119,227],[123,159,249],[158,190,255],[192,212,245],[221,220,220],[242,203,183],[247,172,142],[238,132,104],[214,82,68],[180,4,38]],turbo:[[48,18,59],[69,89,203],[62,155,254],[25,213,205],[70,248,132],[164,252,60],[225,221,55],[254,164,49],[240,91,18],[195,37,3],[122,4,3]],rainbow:[[128,0,255],[78,77,252],[25,150,243],[24,205,228],[77,243,206],[128,255,180],[178,243,150],[230,205,115],[255,150,79],[255,77,39],[255,0,0]],jet:[[0,0,128],[0,0,241],[0,76,255],[0,176,255],[41,255,206],[125,255,122],[206,255,41],[255,196,0],[255,104,0],[241,8,0],[128,0,0]],rdgy:[[103,0,31],[177,24,43],[214,96,77],[243,164,129],[253,219,199],[254,254,254],[224,224,224],[185,185,185],[135,135,135],[76,76,76],[26,26,26]],rdbu:[[103,0,31],[177,24,43],[214,96,77],[243,164,129],[253,219,199],[246,247,247],[209,229,240],[144,196,221],[67,147,195],[32,101,171],[5,48,97]],blues:[[247,251,255],[227,238,249],[208,225,242],[183,212,234],[148,196,223],[106,174,214],[74,152,201],[46,126,188],[23,100,171],[8,74,145],[8,48,107]],purples:[[252,251,253],[242,240,247],[226,226,239],[206,207,229],[182,182,216],[158,154,200],[134,131,189],[114,98,172],[97,64,155],[79,31,139],[63,0,125]],pubu:[[255,247,251],[240,234,244],[219,218,235],[192,201,226],[156,185,217],[115,169,207],[66,149,195],[24,124,182],[5,103,162],[4,83,130],[2,56,88]],piyg:[[142,1,82],[196,26,124],[222,119,174],[241,181,217],[253,224,239],[247,247,246],[230,245,208],[183,224,133],[127,188,65],[76,145,33],[39,100,25]],prgn:[[64,0,75],[117,41,130],[153,112,171],[193,164,206],[231,212,232],[246,247,246],[217,240,211],[165,218,159],[90,174,97],[26,119,54],[0,68,27]],rdylgn:[[165,0,38],[214,47,39],[244,109,67],[253,173,96],[254,224,139],[254,255,190],[217,239,139],[165,216,106],[102,189,99],[25,151,80],[0,104,55]],spectral:[[158,1,66],[212,61,79],[244,109,67],[253,173,96],[254,224,139],[255,255,190],[230,245,152],[170,220,164],[102,194,165],[51,135,188],[94,79,162]]};function h(e){let t=typeof e==`string`&&e.endsWith(`_r`),n=m[t?e.slice(0,-2):e]||m.viridis;return t?[...n].reverse():n}function g(e){let t=h(e),n=new Uint8Array(256*4);for(let e=0;e<256;e++){let r=e/255*(t.length-1),i=Math.floor(r),a=Math.min(i+1,t.length-1),o=r-i;for(let r=0;r<3;r++)n[e*4+r]=Math.round(t[i][r]*(1-o)+t[a][r]*o);n[e*4+3]=255}return n}function _(e,t){let n=document.createElement(`span`);n.style.display=`none`,n.style.color=t,e.appendChild(n);let r=getComputedStyle(n).color;e.removeChild(n);let i=r.match(/rgba?\(([^)]+)\)/);if(!i)return null;let[a,o,s,c=1]=i[1].split(/[,/\s]+/).filter(Boolean).map(Number);return[a/255,o/255,s/255,c]}function v(e,t){return getComputedStyle(e).getPropertyValue(t).trim()||null}function y(e){let t=e.replace(`#`,``);if(!/^(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(t))return null;let n=t.length===3||t.length===4?[...t].map(e=>e+e).join(``):t,r=parseInt(n.slice(0,6),16),i=n.length===8?parseInt(n.slice(6,8),16)/255:1;return[(r>>16&255)/255,(r>>8&255)/255,(r&255)/255,i]}function b(e,t,n){if(!t||typeof t!=`string`)return n;let r=t.trim();return r?(r.startsWith(`#`)?y(r):_(e,r))||(typeof console<`u`&&console.warn&&console.warn(`xy: unresolvable color ${JSON.stringify(r)}; using fallback`),n):n}function x(e){let t=_(e,`currentColor`)||[.2,.2,.2,1],n=(e,t)=>[e[0],e[1],e[2],t],r=t=>{let n=v(e,t);return n&&_(e,n)||null};return{bg:r(`--chart-bg`),grid:r(`--chart-grid`)||n(t,.14),axis:r(`--chart-axis`)||n(t,.55),label:r(`--chart-text`)||n(t,.85)}}function S([e,t,n,r]){return`rgba(${Math.round(e*255)},${Math.round(t*255)},${Math.round(n*255)},${r})`}var C=` -@layer base{ -:where(.xy [data-xy-slot="title"]){text-align:center;font-size:14px;font-weight:600;color:var(--chart-text,inherit)} -:where(.xy [data-xy-slot="tooltip"]){max-width:calc(100% - 8px);max-height:calc(100% - 8px);box-sizing:border-box;white-space:normal;overflow-wrap:anywhere;overflow:auto;background:var(--chart-tooltip-bg,rgba(20,24,33,.92));color:var(--chart-tooltip-text,#fff);padding:5px 8px;border-radius:4px;font-size:11px;line-height:1.35;box-shadow:0 2px 8px rgba(0,0,0,.3)} -:where(.xy [data-xy-slot="legend"]){left:var(--xy-legend-left,auto);right:var(--xy-legend-right,auto);top:var(--xy-legend-top,auto);bottom:var(--xy-legend-bottom,auto);transform:var(--xy-legend-transform,none);max-width:var(--xy-legend-max-width);max-height:var(--xy-legend-max-height);gap:2px;font-size:11px;background:var(--chart-legend-bg,rgba(128,128,128,.08));border-radius:4px;padding:4px 8px;color:var(--chart-text,inherit)} -:where(.xy [data-xy-slot="legend_swatch"]){width:12px;height:10px;border-radius:2px;margin-right:5px} -:where(.xy [data-xy-slot="colorbar"]){color:var(--chart-text,inherit);font-size:10px} -:where(.xy [data-xy-slot="colorbar_bar"]){background:var(--xy-colorbar-gradient);border:1px solid currentColor;box-sizing:border-box} -:where(.xy [data-xy-slot="colorbar_title"]){font-weight:500} -:where(.xy [data-xy-slot="badge"]){gap:3px;font-size:11px;line-height:1.2} -:where(.xy [data-xy-slot="badge_item"]){padding:3px 6px;border-radius:4px;color:var(--chart-badge-text,var(--xy-badge-text));background:var(--chart-badge-bg,var(--xy-badge-bg));box-shadow:var(--xy-badge-shadow)} -:where(.xy){--xy-badge-text:#0f172a;--xy-badge-bg:rgba(255,255,255,.82);--xy-badge-shadow:0 1px 4px rgba(15,23,42,.14);--xy-modebar-bg:rgba(255,255,255,.78);--xy-modebar-menu-bg:rgba(255,255,255,.94);--xy-modebar-border:rgba(128,128,128,.18);--xy-modebar-menu-border:rgba(128,128,128,.22);--xy-modebar-active:rgba(128,128,128,.2);--xy-modebar-shadow:0 1px 4px rgba(0,0,0,.08);--xy-modebar-menu-shadow:0 5px 18px rgba(15,23,42,.18)} -:where(.dark .xy,.xy.dark){--xy-badge-text:#f8fafc;--xy-badge-bg:rgba(30,35,44,.88);--xy-badge-shadow:0 1px 4px rgba(0,0,0,.5);--xy-modebar-bg:rgba(37,42,52,.9);--xy-modebar-menu-bg:rgba(30,35,44,.97);--xy-modebar-border:rgba(255,255,255,.14);--xy-modebar-menu-border:rgba(255,255,255,.16);--xy-modebar-active:rgba(255,255,255,.16);--xy-modebar-shadow:0 1px 4px rgba(0,0,0,.5);--xy-modebar-menu-shadow:0 8px 24px rgba(0,0,0,.6)} -:where(.xy [data-xy-slot="modebar"]){gap:1px;background:var(--chart-modebar-bg,var(--xy-modebar-bg));border:1px solid var(--xy-modebar-border);border-radius:4px;padding:1px;box-shadow:var(--xy-modebar-shadow)} -:where(.xy [data-xy-slot="modebar_button"]){width:24px;height:24px;padding:0;border:none;background:transparent;border-radius:3px;color:var(--chart-text,currentColor);cursor:pointer} -:where(.xy [data-xy-modebar-drag-handle]){position:relative;width:22px;margin-right:4px;cursor:move} -:where(.xy [data-xy-modebar-drag-handle])::after{content:"";position:absolute;top:4px;right:-3px;bottom:4px;width:1px;background:rgba(128,128,128,.28);pointer-events:none} -:where(.xy [data-xy-modebar-menu-trigger]){width:auto;min-width:48px;gap:1px;padding:0 4px;font-size:11px;font-variant-numeric:tabular-nums} -:where(.xy [data-xy-modebar-select-trigger]){width:auto;min-width:42px;gap:2px;padding:0 4px} -:where(.xy [data-xy-modebar-select-icon]){display:flex;flex:0 0 auto} -:where(.xy [data-xy-modebar-menu-indicator]){display:flex;flex:0 0 auto;transition:transform .15s} -:where(.xy [data-xy-modebar-menu-indicator] svg){width:11px;height:11px} -:where(.xy [data-xy-modebar-menu]){min-width:148px;gap:1px;padding:4px;background:var(--chart-modebar-bg,var(--xy-modebar-menu-bg));border:1px solid var(--xy-modebar-menu-border);border-radius:7px;box-shadow:var(--xy-modebar-menu-shadow);backdrop-filter:blur(8px)} -:where(.xy [data-xy-modebar-menu-item]){width:100%;height:28px;justify-content:flex-start;padding:0 9px;border-radius:4px;text-align:left;white-space:nowrap} -:where(.xy [data-xy-modebar-menu-item]:hover,.xy [data-xy-modebar-menu-item]:focus-visible){background:var(--chart-modebar-active,var(--xy-modebar-active));outline:none} -:where(.xy [data-xy-modebar-menu-item][data-xy-separator]){margin-top:3px;border-top:1px solid rgba(128,128,128,.2);border-radius:0 0 4px 4px} -:where(.xy [data-xy-modebar-menu-icon]){display:flex;width:16px;margin-right:7px} -:where(.xy [data-xy-modebar-menu-icon] svg){width:14px;height:14px} -:where(.xy [data-xy-slot="modebar_button"].xy-active){background:var(--chart-modebar-active,var(--xy-modebar-active))} -:where(.xy [data-xy-slot="selection"]){border:1px solid var(--chart-selection,rgba(90,140,240,.9));background:var(--chart-selection-fill,rgba(90,140,240,.15))} -:where(.xy [data-xy-slot="selection"][data-xy-band="zoom"]){border-color:var(--chart-zoom-selection,rgba(120,120,120,.9));background:var(--chart-zoom-selection-fill,rgba(120,120,120,.12))} -:where(.xy [data-xy-selection-lasso]){fill:var(--chart-selection-fill,rgba(90,140,240,.15));stroke:var(--chart-selection,rgba(90,140,240,.9));stroke-width:1.5;stroke-linejoin:round;pointer-events:none} -:where(.xy [data-xy-selection-lasso-handle]){fill:var(--chart-bg,#fff);stroke:var(--chart-selection,rgba(90,140,240,.9));stroke-width:1.5;cursor:grab;pointer-events:all} -:where(.xy [data-xy-selection-lasso-handle][data-xy-active]){cursor:grabbing;fill:var(--chart-selection,rgba(90,140,240,.9))} -:where(.xy [data-xy-slot="crosshair_x"],.xy [data-xy-slot="crosshair_y"]){background:var(--chart-crosshair,rgba(15,23,42,.42))} -:where(.xy [data-xy-slot="tick_label"]){color:var(--chart-text,inherit)} -:where(.xy [data-xy-slot="axis_title"]){color:var(--chart-text,inherit);font-size:12px} -:where(.xy [data-xy-slot="annotation_label"]){font-size:11px;line-height:1.2;font-weight:500;color:var(--chart-annotation-text,var(--chart-text,inherit))} -:where(.xy [data-xy-slot="canvas"]){cursor:var(--chart-cursor,crosshair)} -:where(.xy [data-xy-slot="canvas"][data-xy-dragmode="pan"]){cursor:var(--chart-cursor-pan,grab)} -:where(.xy [data-xy-slot="canvas"]:focus-visible,.xy [data-xy-slot="modebar_button"]:focus-visible){outline:2px solid var(--chart-focus,#2563eb);outline-offset:2px} -@media (prefers-reduced-motion:reduce){:where(.xy [data-xy-slot="modebar"]){transition-duration:0s!important}} -@media (forced-colors:active){:where(.xy [data-xy-slot="modebar"],.xy [data-xy-slot="tooltip"]){border:1px solid CanvasText}:where(.xy [data-xy-slot="modebar_button"].xy-active){outline:2px solid Highlight}:where(.xy [data-xy-slot="canvas"]:focus){outline:2px solid Highlight}} -} -/* VS Code's Jupyter webview wraps ipywidget outputs in an opaque white card so - widgets that assume a light page stay legible on dark editor themes — the - same role as matplotlib's always-opaque white figure patch, so unthemed - charts keep it. A chart that brings its own background (theme(background=), - marked data-xy-own-bg) would sit in a white frame instead, so only those - outputs drop the backdrop. !important because the host rule this overrides - carries higher specificity; it stays outside the base layer because it - overrides host CSS rather than providing an overridable default. */ -.cell-output-ipywidget-background:has(.xy[data-xy-own-bg]){background:transparent!important} -`;function w(e){let t=e&&e.getRootNode?e.getRootNode():document,n=typeof ShadowRoot<`u`&&t instanceof ShadowRoot;!n&&!(t instanceof Document)&&(t=document);let r=n?t:t.head||document.head||t.documentElement;if(!r||!r.querySelector||r.querySelector(`style[data-xy-chrome]`))return;let i=document.createElement(`style`);i.setAttribute(`data-xy-chrome`,``),i.textContent=C,r.appendChild(i)}function T(e,t,n=[.5,.5,.5,1]){let r=b(e,t,n);return S(Array.isArray(r)&&r.length>=4&&r.every(Number.isFinite)?r:n)}function E(e){if(e=Math.abs(e),!Number.isFinite(e)||e<=0)return 1;let t=10**Math.floor(Math.log10(e));for(let n of[1,2,2.5,5,10])if(e<=n*t*1.000000000001)return n*t;return 10*t}function D(e,t,n=6){if(!Number.isFinite(e)||!Number.isFinite(t))return{ticks:[],step:1};let r=Math.min(e,t),i=Math.max(e,t);if(r===i)return{ticks:[r],step:1};let a=E((i-r)/n),o=Math.ceil(r/a)*a,s=[];for(let e=o;e<=i+a*1e-9&&s.length<200;e+=a)s.push(Math.abs(e)=r*.999999999999&&o<=i*1.000000000001&&(c.push(o),n===1&&(e-a)%u===0&&l.push(o)),c.length>=200)break}}return{ticks:c,labels:l.length?l:c,step:1,log:!0}}function k(e,t,n,r=6){if(!n||!n.length)return{ticks:[],step:1};let i=Math.max(0,Math.ceil(Math.min(e,t))),a=Math.min(n.length-1,Math.floor(Math.max(e,t)));if(a14*A.d)return te(r,i,a);let o=j[j.length-1];for(let e of j)if(e>=a){o=e;break}let s=Math.ceil(r/o)*o,c=[];for(let e=s;e<=i&&c.length<200;e+=o)c.push(e);return{ticks:c,step:o}}function te(e,t,n){let r=n/(30*A.d),i=[1,2,3,6,12,24,60,120],a=i[i.length-1];for(let e of i)if(e>=r){a=e;break}let o=new Date(e),s=o.getUTCFullYear(),c=o.getUTCMonth();c=Math.ceil(c/a)*a;let l=[];for(;;){let n=Date.UTC(s+Math.floor(c/12),c%12,1);if(n>t||(n>=e&&l.push(n),c+=a,l.length>1e3))break}return{ticks:l,step:a*30*A.d}}function ne(e,t){let n=new Date(e),r=(e,t=2)=>String(e).padStart(t,`0`);return t>=28*A.d?n.getUTCMonth()===0?String(n.getUTCFullYear()):`${n.toLocaleString(`en`,{month:`short`,timeZone:`UTC`})} ${n.getUTCFullYear()}`:t>=A.d?`${n.toLocaleString(`en`,{month:`short`,timeZone:`UTC`})} ${r(n.getUTCDate())}`:t>=A.m?`${r(n.getUTCHours())}:${r(n.getUTCMinutes())}`:t>=A.s?`${r(n.getUTCHours())}:${r(n.getUTCMinutes())}:${r(n.getUTCSeconds())}`:`${r(n.getUTCMinutes())}:${r(n.getUTCSeconds())}.${r(n.getUTCMilliseconds(),3)}`}function M(e,t){let n=Math.abs(e);if(n>=1e6||n!==0&&n<1e-4)return e.toExponential(1).replace(`e+`,`e`);let r=t?Math.max(0,Math.ceil(-Math.log10(Math.abs(t)))):0;for(;r<8&&Math.abs(Number(t.toFixed(r))-t)>Math.abs(t)/1e3;)r++;return e.toFixed(Math.min(r,8))}function re(e,t=6){let n=Number(e);if(!Number.isFinite(n))return String(e);if(n===0)return Object.is(n,-0)?`-0`:`0`;let[r,i]=n.toExponential(t-1).split(`e`),a=Number(i);if(a<-4||a>=t)return r=r.replace(/0+$/,``).replace(/\.$/,``),`${r}e${a>=0?`+`:`-`}${String(Math.abs(a)).padStart(2,`0`)}`;let o=Math.max(0,t-a-1),s=Number(n.toPrecision(t)).toFixed(o);return s.includes(`.`)&&(s=s.replace(/0+$/,``).replace(/\.$/,``)),s}function ie(e,t){let n=Math.round(e);return n>=0&&nString(e).padStart(t,`0`),i=n.toLocaleString(`en`,{month:`short`,timeZone:`UTC`}),a=n.toLocaleString(`en`,{month:`long`,timeZone:`UTC`});return t.replace(/%[YmdHMSbB]/g,e=>{switch(e){case`%Y`:return String(n.getUTCFullYear());case`%m`:return r(n.getUTCMonth()+1);case`%d`:return r(n.getUTCDate());case`%H`:return r(n.getUTCHours());case`%M`:return r(n.getUTCMinutes());case`%S`:return r(n.getUTCSeconds());case`%b`:return i;case`%B`:return a;default:return e}})}function se(e,t,n){if(e&&e.kind===`category`)return ie(t,e.categories||[]);if(e&&e.kind===`time`)return oe(t,e.format)||ne(t,n);let r=ae(t,e&&e.format);return e&&e.scale===`log`&&Number(t)>0&&Number(t)<1&&r===`0`?M(t,n):r||M(t,n)}function N(e,t){if(t===`time_ms`)return new Date(e).toISOString().replace(`T`,` `).replace(`.000Z`,`Z`);if(typeof e==`string`)return e;let n=Number(e);if(!Number.isFinite(n))return String(e);if(n===0)return`0`;let r=Math.abs(n);return r>=1e6||r<1e-4?n.toExponential(3):(Math.round(n*1e4)/1e4).toString()}function ce(e,t,n){let r=e.createShader(t);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw Error(`shader compile: `+e.getShaderInfoLog(r)+` -`+n);return r}var P={ax:0,ay:1,ax0:0,ax1:1,ay0:2,ay1:3,ax2:4,ay2:5,ab0:4,ab1:5,a_pos:0,a_v1:1,a_v0:2,a_corner:0,a_cval:6,a_sval:7,a_sel:8,a_dval:9,a_len0:10,a_len1:11,a_dash0:10,a_dashDir:11,a_prevx:4,a_prevy:5,a_prevx1:7,a_prevy1:8,a_rgba:12,a_style:13,a_stroke:14,a_radius:15};function le(e,t,n){let r=e.createProgram(),i=ce(e,e.VERTEX_SHADER,t),a=ce(e,e.FRAGMENT_SHADER,n);e.attachShader(r,i),e.attachShader(r,a);for(let[t,n]of Object.entries(P))e.bindAttribLocation(r,n,t);e.linkProgram(r);let o=e.getProgramParameter(r,e.LINK_STATUS),s=e.getProgramInfoLog(r);if(e.detachShader(r,i),e.detachShader(r,a),e.deleteShader(i),e.deleteShader(a),!o)throw e.deleteProgram(r),Error(`program link: `+s);return r._u=Object.create(null),r}function F(e,t,n){let r=t._u[n];return r===void 0&&(r=e.getUniformLocation(t,n),t._u[n]=r),r}var I=` -float xyDecode(float encoded, vec2 meta) { - return encoded / max(abs(meta.y), 1e-30) + meta.x; -} -float xyAxisCoord(float encoded, vec2 meta, int mode) { - float value = xyDecode(encoded, meta); - if (mode == 1) return value > 0.0 ? log(value) / log(10.0) : -1e30; - return value; -} -float xyMap(float encoded, vec2 map, vec2 meta, int mode) { - return xyAxisCoord(encoded, meta, mode) * map.x + map.y; -} -float xyViewCoord(float value, int mode) { - if (mode == 1) return value > 0.0 ? log(value) / log(10.0) : -1e30; - return value; -} -float xyViewValue(float coord, int mode) { - if (mode == 1) return pow(10.0, coord); - return coord; -} -`,ue=`#version 300 es -in float ax; in float ay; in float a_prevx; in float a_prevy; -in float a_cval; in float a_sval; in float a_sel; in float a_dval; -in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -uniform float u_size; uniform int u_sizeMode; uniform vec2 u_sizeRange; -uniform int u_colorMode; uniform float u_dpr; uniform int u_selActive; -uniform float u_selectedOpacity; uniform float u_unselectedOpacity; -uniform float u_transitionProgress; uniform int u_transitionActive; -out float v_lutCoord; out float v_dim; out float v_dval; out float v_ptSize; out float v_sel; -out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; -${I} -void main() { - float x = u_transitionActive == 1 ? mix(a_prevx, ax, u_transitionProgress) : ax; - float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; - gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode), xyMap(y, u_ymap, u_ymeta, u_ymode), 0.0, 1.0); - float sz = u_sizeMode == 1 ? mix(u_sizeRange.x, u_sizeRange.y, a_sval) : u_size; - gl_PointSize = sz * u_dpr; - v_ptSize = sz * u_dpr; - v_sel = a_sel; - v_rgba = a_rgba; - v_style = a_style; - v_stroke = a_stroke; - // continuous: coord = value in [0,1]; categorical: center of texel a_cval. - v_lutCoord = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - // Local log-density LUT coord (drill handoff, §5): lets freshly drilled - // points wear the density colormap so the texture->points swap is seamless. - v_dval = a_dval; - // Unselected marks dim when a selection is active (§34 selected/unselected styling). - v_dim = u_selActive == 1 ? mix(u_unselectedOpacity, u_selectedOpacity, step(0.5, a_sel)) : 1.0; -}`,de=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform int u_colorMode; uniform sampler2D u_lut; uniform float u_opacity; -uniform sampler2D u_dlut; uniform float u_dblend; -uniform int u_symbol; uniform vec4 u_ptStroke; uniform float u_ptStrokeWidth; uniform int u_ptStrokeFace; -uniform int u_strokeMode; uniform float u_strokeOpacity; -uniform int u_selActive; uniform vec4 u_selColor; uniform vec4 u_unselColor; -in float v_lutCoord; in float v_dim; in float v_dval; in float v_ptSize; in float v_sel; -in vec4 v_rgba; in vec4 v_style; in vec4 v_stroke; -out vec4 outColor; - -float xySegmentDistance(vec2 p, vec2 a, vec2 b) { - vec2 e = b - a; - return length(p - a - e * clamp(dot(p - a, e) / dot(e, e), 0.0, 1.0)); -} -float xyTriangleDistance(vec2 p, vec2 a, vec2 b, vec2 c) { - float dist = min(xySegmentDistance(p, a, b), - min(xySegmentDistance(p, b, c), xySegmentDistance(p, c, a))); - float c0 = (b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x); - float c1 = (c.x-b.x)*(p.y-b.y) - (c.y-b.y)*(p.x-b.x); - float c2 = (a.x-c.x)*(p.y-c.y) - (a.y-c.y)*(p.x-c.x); - bool inside = (c0 >= 0.0 && c1 >= 0.0 && c2 >= 0.0) || - (c0 <= 0.0 && c1 <= 0.0 && c2 <= 0.0); - return inside ? -dist : dist; -} -float xyPentagonDistance(vec2 p) { - // Path.unit_regular_polygon(5), then Matplotlib's 0.5 marker transform. - vec2 a = vec2(0.0, -0.5); - vec2 b = vec2(-0.475528258, -0.154508497); - vec2 c = vec2(-0.293892626, 0.404508497); - vec2 d = vec2(0.293892626, 0.404508497); - vec2 e = vec2(0.475528258, -0.154508497); - float dist = min(min(xySegmentDistance(p, a, b), xySegmentDistance(p, b, c)), - min(min(xySegmentDistance(p, c, d), xySegmentDistance(p, d, e)), - xySegmentDistance(p, e, a))); - float c0 = (b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x); - float c1 = (c.x-b.x)*(p.y-b.y) - (c.y-b.y)*(p.x-b.x); - float c2 = (d.x-c.x)*(p.y-c.y) - (d.y-c.y)*(p.x-c.x); - float c3 = (e.x-d.x)*(p.y-d.y) - (e.y-d.y)*(p.x-d.x); - float c4 = (a.x-e.x)*(p.y-e.y) - (a.y-e.y)*(p.x-e.x); - bool inside = (c0 >= 0.0 && c1 >= 0.0 && c2 >= 0.0 && c3 >= 0.0 && c4 >= 0.0) || - (c0 <= 0.0 && c1 <= 0.0 && c2 <= 0.0 && c3 <= 0.0 && c4 <= 0.0); - return inside ? -dist : dist; -} -float xyMarkerSdf(vec2 d, int shape) { - if (shape == 1) return max(abs(d.x), abs(d.y)) - 0.5; // square - if (shape == 2) return (abs(d.x) + abs(d.y)) - 0.5; // diamond - if (shape == 4) { // cross / plus - vec2 a = abs(d); - return min(max(a.x - 0.17, a.y - 0.5), max(a.x - 0.5, a.y - 0.17)); - } - if (shape == 5) { // regular hexagon (pointy top) - const vec3 k = vec3(-0.866025404, 0.5, 0.577350269); - vec2 p = abs(vec2(d.y, d.x)); - p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy; - p -= vec2(clamp(p.x, -k.z * 0.5, k.z * 0.5), 0.5); - return length(p) * sign(p.y); - } - if (shape == 6) return xyPentagonDistance(d); // exact regular pentagon - if (shape == 7) { // five-pointed star (apex up) - const float rf = 0.45; - const vec2 k1 = vec2(0.809016994, -0.587785252); - const vec2 k2 = vec2(-k1.x, k1.y); - vec2 p = vec2(abs(d.x), -d.y); - p -= 2.0 * max(dot(k1, p), 0.0) * k1; - p -= 2.0 * max(dot(k2, p), 0.0) * k2; - p = vec2(abs(p.x), p.y - 0.5); - vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0); - float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, 0.5); - return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y); - } - if (shape == 3 || shape == 8 || shape == 9 || shape == 10) { // Matplotlib triangle path - vec2 q = d; - if (shape == 8) q = -d; - if (shape == 9) q = vec2(d.y, -d.x); - if (shape == 10) q = vec2(-d.y, d.x); - return xyTriangleDistance(q, vec2(0.0, -0.5), vec2(-0.5, 0.5), vec2(0.5, 0.5)); - } - if (shape == 11) { // diagonal x - vec2 q = vec2(d.x + d.y, d.y - d.x) * 0.707106781; - vec2 a = abs(q); - return min(max(a.x - 0.17, a.y - 0.5), max(a.x - 0.5, a.y - 0.17)); - } - if (shape == 13) return max(abs(d.x), abs(d.y)) - 0.5; // snapped pixel - if (shape == 14) return (abs(d.x) / 0.6 + abs(d.y)) - 0.5; // thin diamond - return length(d) - 0.5; // circle -} -void main() { - vec2 d = gl_PointCoord - 0.5; - float sd; - int symbol = v_style.w >= 0.0 ? int(v_style.w + 0.5) : u_symbol; - bool lineMarker = symbol == 15 || symbol == 16; - if (lineMarker) { - vec2 q = symbol == 16 ? vec2(d.x + d.y, d.y - d.x) * 0.707106781 : d; - float itemStrokeWidth = v_style.z >= 0.0 ? v_style.z : u_ptStrokeWidth; - float halfWidth = max(itemStrokeWidth, 1.0) / (2.0 * max(v_ptSize, 1.0)); - vec2 a = abs(q); - sd = min(max(a.x - 0.5, a.y - halfWidth), max(a.y - 0.5, a.x - halfWidth)); - } else { - // Scalar-only equivalent: xyMarkerSdf(d, u_symbol). The resolved symbol - // also permits a per-item glyph override from v_style.w. - sd = xyMarkerSdf(d, symbol); - } - float aa = fwidth(sd) + 1e-4; - float shapeCov = clamp(0.5 - sd / aa, 0.0, 1.0); - if (shapeCov <= 0.001) discard; - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode == 0 ? u_color : vec4(texture(u_lut, vec2(clamp(v_lutCoord, 0.0, 1.0), 0.5)).rgb, 1.0)); - vec3 rgb = paint.rgb; - // Drill handoff (§5): near the density boundary, paint by local density with - // the density ramp; ease into native colors as the zoom deepens (u_dblend->0). - if (u_dblend > 0.001) { - vec3 drgb = texture(u_dlut, vec2(clamp(v_dval, 0.0, 1.0), 0.5)).rgb; - rgb = mix(rgb, drgb, u_dblend); - } - // §34 selected/unselected recolor: when a selection is active, tint each point - // toward its state color (.a is the mix weight; 0 = keep native color). - if (u_selActive == 1) { - vec4 sc = v_sel > 0.5 ? u_selColor : u_unselColor; - rgb = mix(rgb, sc.rgb, sc.a); - } - float intrinsicAlpha = paint.a; - float fillAlpha = (v_style.y >= 0.0 ? v_style.y : intrinsicAlpha) * v_style.x * u_opacity; - vec4 px = vec4(rgb * fillAlpha, fillAlpha); // premultiplied fill - // Uniform (u_ptStroke) and per-item (v_stroke) stroke paint ship straight - // alpha and go through the same artist-alpha/opacity stack, so a scalar - // CSS edge fades under alpha overrides exactly like SVG/PNG export. - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_ptStroke; - float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; - vec4 strokePx = u_ptStrokeFace == 1 ? px : vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); - if (lineMarker) { - outColor = strokePx * (shapeCov * v_dim); - return; - } - float itemStrokeWidth = v_style.z >= 0.0 ? v_style.z : u_ptStrokeWidth; - if (itemStrokeWidth > 0.0) { - float sw = itemStrokeWidth / max(v_ptSize, 1.0); // px -> gl_PointCoord units - // The supplied point size includes the edge. Recover Matplotlib's path - // boundary half a stroke inside it, then source-over the centered stroke. - float pathCov = clamp(0.5 - (sd + sw * 0.5) / aa, 0.0, 1.0); - float innerCov = clamp(0.5 - (sd + sw) / aa, 0.0, 1.0); - float strokeCov = max(shapeCov - innerCov, 0.0); - vec4 fillLayer = px * pathCov; - vec4 strokeLayer = strokePx * strokeCov; - px = strokeLayer + fillLayer * (1.0 - strokeLayer.a); - outColor = px * v_dim; - return; - } - outColor = px * (shapeCov * v_dim); -}`,fe=`#version 300 es -in float ax; in float ay; in float a_prevx; in float a_prevy; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -uniform float u_size; uniform float u_dpr; -uniform float u_transitionProgress; uniform int u_transitionActive; -${I} -void main() { - float x = u_transitionActive == 1 ? mix(a_prevx, ax, u_transitionProgress) : ax; - float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; - gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode), xyMap(y, u_ymap, u_ymeta, u_ymode), 0.0, 1.0); - gl_PointSize = u_size * u_dpr; -}`,pe=`#version 300 es -precision highp float; -uniform vec4 u_color; -out vec4 outColor; -void main() { - float sd = length(gl_PointCoord - 0.5) - 0.5; - float aa = fwidth(sd) + 1e-4; - float coverage = clamp(0.5 - sd / aa, 0.0, 1.0); - if (coverage <= 0.001) discard; - outColor = vec4(u_color.rgb * u_color.a, u_color.a) * coverage; -}`,me=`#version 300 es -in float ax; in float ay; in float a_prevx; in float a_prevy; in float a_sval; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -uniform float u_size; uniform int u_sizeMode; uniform vec2 u_sizeRange; uniform float u_dpr; -uniform float u_transitionProgress; uniform int u_transitionActive; -flat out int v_id; -${I} -void main() { - float x = u_transitionActive == 1 ? mix(a_prevx, ax, u_transitionProgress) : ax; - float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; - gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode), xyMap(y, u_ymap, u_ymeta, u_ymode), 0.0, 1.0); - float sz = u_sizeMode == 1 ? mix(u_sizeRange.x, u_sizeRange.y, a_sval) : u_size; - gl_PointSize = max(sz, 6.0) * u_dpr; // enlarge hit target - v_id = gl_VertexID; -}`,he=`#version 300 es -precision highp float; precision highp int; -uniform int u_pick_base; -flat in int v_id; -out vec4 outColor; -void main() { - vec2 d = gl_PointCoord - 0.5; - if (length(d) > 0.5) discard; - int id = u_pick_base + v_id; - outColor = vec4( - float(id & 255) / 255.0, - float((id >> 8) & 255) / 255.0, - float((id >> 16) & 255) / 255.0, - float((id >> 24) & 255) / 255.0 - ); -}`,ge=`#version 300 es -in vec2 a_corner; -uniform vec4 u_view; // x0,x1,y0,y1 -uniform int u_xmode; uniform int u_ymode; -out vec2 v_data; -${I} -void main() { - gl_Position = vec4(a_corner * 2.0 - 1.0, 0.0, 1.0); - float x = mix(xyViewCoord(u_view.x, u_xmode), xyViewCoord(u_view.y, u_xmode), a_corner.x); - float y = mix(xyViewCoord(u_view.z, u_ymode), xyViewCoord(u_view.w, u_ymode), a_corner.y); - v_data = vec2(xyViewValue(x, u_xmode), xyViewValue(y, u_ymode)); -}`,_e=`#version 300 es -precision highp float; -uniform sampler2D u_grid; uniform sampler2D u_lut; -uniform vec4 u_gridRange; // gx0,gx1,gy0,gy1 -uniform float u_opacity; uniform vec4 u_color; uniform int u_constantColor; -in vec2 v_data; -out vec4 outColor; -void main() { - vec2 uv = vec2((v_data.x - u_gridRange.x) / (u_gridRange.y - u_gridRange.x), - (v_data.y - u_gridRange.z) / (u_gridRange.w - u_gridRange.z)); - if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) discard; - float t = texture(u_grid, uv).r; - if (t <= 0.0) discard; - vec4 paint = u_constantColor == 1 - ? u_color - : texture(u_lut, vec2(clamp(t, 0.0, 1.0), 0.5)); - vec3 rgb = paint.rgb; - float alpha = u_opacity * paint.a * clamp(t * 1.35, 0.0, 1.0); - if (alpha <= 0.01) discard; - outColor = vec4(rgb * alpha, alpha); -}`,ve=`#version 300 es -precision highp float; -uniform sampler2D u_grid; uniform sampler2D u_lut; -uniform vec4 u_gridRange; // gx0,gx1,gy0,gy1 -uniform float u_opacity; -uniform int u_truecolor; -in vec2 v_data; -out vec4 outColor; -void main() { - vec2 uv = vec2((v_data.x - u_gridRange.x) / (u_gridRange.y - u_gridRange.x), - (v_data.y - u_gridRange.z) / (u_gridRange.w - u_gridRange.z)); - if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) discard; - vec4 sampled = texture(u_grid, uv); - if (u_truecolor == 1) { - float alpha = sampled.a * u_opacity; - if (alpha <= 0.0) discard; - outColor = vec4(sampled.rgb * alpha, alpha); - return; - } - float raw = sampled.r; - if (raw <= 0.0) discard; - float t = clamp((raw * 255.0 - 1.0) / 254.0, 0.0, 1.0); - vec3 rgb = texture(u_lut, vec2(t, 0.5)).rgb; - outColor = vec4(rgb * u_opacity, u_opacity); -}`,ye=`#version 300 es -in float ax0; in float ay0; in float ax1; in float ay1; -in float a_prevx; in float a_prevy; in float a_prevx1; in float a_prevy1; -uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_res; uniform float u_width; -uniform int u_colorMode; -uniform float u_transitionProgress; uniform int u_transitionActive; -uniform float u_revealProgress; uniform float u_revealSegments; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -in float a_len0; in float a_len1; -out float v_off; out float v_dash; -const vec2 corners[4] = vec2[4](vec2(0.,-1.), vec2(0.,1.), vec2(1.,-1.), vec2(1.,1.)); -${I} -void main() { - float px0 = u_transitionActive == 1 ? mix(a_prevx, ax0, u_transitionProgress) : ax0; - float py0 = u_transitionActive == 1 ? mix(a_prevy, ay0, u_transitionProgress) : ay0; - float px1 = u_transitionActive == 1 ? mix(a_prevx1, ax1, u_transitionProgress) : ax1; - float py1 = u_transitionActive == 1 ? mix(a_prevy1, ay1, u_transitionProgress) : ay1; - vec2 p0 = vec2(xyMap(px0, u_xmap, u_xmeta, u_xmode), xyMap(py0, u_ymap, u_ymeta, u_ymode)); - vec2 p1 = vec2(xyMap(px1, u_xmap, u_xmeta, u_xmode), xyMap(py1, u_ymap, u_ymeta, u_ymode)); - float reveal = clamp(u_revealProgress * u_revealSegments - float(gl_InstanceID), 0.0, 1.0); - p1 = mix(p0, p1, reveal); - vec2 pix0 = (p0 * 0.5 + 0.5) * u_res; - vec2 pix1 = (p1 * 0.5 + 0.5) * u_res; - vec2 dir = pix1 - pix0; - float len = max(length(dir), 1e-6); - dir /= len; - vec2 n = vec2(-dir.y, dir.x); - vec2 c = corners[gl_VertexID]; - float half_w = u_width * 0.5 + 0.5; - vec2 pos = mix(pix0, pix1, c.x) + dir * (c.x * 2.0 - 1.0) * 0.5 + n * c.y * half_w; - gl_Position = vec4(pos / u_res * 2.0 - 1.0, 0.0, 1.0); - v_off = c.y * half_w; - // Cumulative screen-space arc length at this fragment (device px), fed from - // CPU-computed per-vertex lengths so dashes stay continuous across segments - // and constant on screen through zoom. - v_dash = mix(a_len0, mix(a_len0, a_len1, reveal), c.x); -}`,be=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform float u_width; -uniform int u_dashCount; uniform float u_dashArr[8]; uniform float u_dashPeriod; -in float v_off; in float v_dash; -out vec4 outColor; -void main() { - float half_w = u_width * 0.5; - float alpha = (1.0 - smoothstep(half_w - 0.5, half_w + 0.5, abs(v_off))) * u_color.a; - if (u_dashCount > 0) { - float m = mod(v_dash, u_dashPeriod); - float acc = 0.0; - float on = 0.0; - for (int i = 0; i < 8; i++) { - if (i >= u_dashCount) break; - float next = acc + u_dashArr[i]; - if (m < next) { - // 0.6px feather at each dash start/end so edges aren't aliased. - float d = min(m - acc, next - m); - on = (i % 2 == 0) ? clamp(d + 0.6, 0.0, 1.0) : 1.0 - clamp(d + 0.6, 0.0, 1.0); - break; - } - acc = next; - } - alpha *= on; - } - if (alpha <= 0.001) discard; - outColor = vec4(u_color.rgb * alpha, alpha); -}`,xe=`#version 300 es -in float ax0; in float ay0; in float ax1; in float ay1; in float a_cval; in vec4 a_rgba; in vec4 a_style; -in float a_dash0; in float a_dashDir; -uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_res; uniform float u_width; -uniform float u_animationProgress; -uniform int u_colorMode; -uniform vec2 u_x0meta; uniform vec2 u_x1meta; uniform vec2 u_y0meta; uniform vec2 u_y1meta; -uniform int u_x0mode; uniform int u_x1mode; uniform int u_y0mode; uniform int u_y1mode; -out float v_off; out float v_cval; out float v_dash; out vec4 v_rgba; out vec4 v_style; -const vec2 corners[4] = vec2[4](vec2(0.,-1.), vec2(0.,1.), vec2(1.,-1.), vec2(1.,1.)); -${I} -void main() { - vec2 p0 = vec2(xyMap(ax0, u_xmap, u_x0meta, u_x0mode), xyMap(ay0, u_ymap, u_y0meta, u_y0mode)); - vec2 p1 = vec2(xyMap(ax1, u_xmap, u_x1meta, u_x1mode), xyMap(ay1, u_ymap, u_y1meta, u_y1mode)); - vec2 center = (p0 + p1) * 0.5; - p0 = mix(center, p0, u_animationProgress); - p1 = mix(center, p1, u_animationProgress); - vec2 pix0 = (p0 * 0.5 + 0.5) * u_res; - vec2 pix1 = (p1 * 0.5 + 0.5) * u_res; - vec2 dir = pix1 - pix0; - float len = max(length(dir), 1e-6); - dir /= len; - vec2 n = vec2(-dir.y, dir.x); - vec2 c = corners[gl_VertexID]; - float itemWidth = a_style.z >= 0.0 ? a_style.z : u_width; - float half_w = itemWidth * 0.5 + 0.5; - vec2 pos = mix(pix0, pix1, c.x) + dir * (c.x * 2.0 - 1.0) * 0.5 + n * c.y * half_w; - gl_Position = vec4(pos / u_res * 2.0 - 1.0, 0.0, 1.0); - v_off = c.y * half_w; - v_cval = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - v_dash = a_dash0 + c.x * len * a_dashDir; - v_rgba = a_rgba; v_style = a_style; -}`,Se=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform float u_width; uniform int u_colorMode; uniform sampler2D u_lut; uniform float u_opacity; -uniform int u_dashCount; uniform float u_dashArr[8]; uniform float u_dashPeriod; -in float v_off; in float v_cval; in float v_dash; in vec4 v_rgba; in vec4 v_style; -out vec4 outColor; -void main() { - float itemWidth = v_style.z >= 0.0 ? v_style.z : u_width; - float half_w = itemWidth * 0.5; - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode != 0 ? vec4(texture(u_lut, vec2(clamp(v_cval, 0.0, 1.0), 0.5)).rgb, 1.0) : u_color); - vec3 rgb = paint.rgb; - float paintAlpha = (v_style.y >= 0.0 ? v_style.y : paint.a) * v_style.x * u_opacity; - float alpha = (1.0 - smoothstep(half_w - 0.5, half_w + 0.5, abs(v_off))) * paintAlpha; - if (u_dashCount > 0) { - float m = mod(v_dash, u_dashPeriod); - float acc = 0.0; - float on = 0.0; - for (int i = 0; i < 8; i++) { - if (i >= u_dashCount) break; - float next = acc + u_dashArr[i]; - if (m < next) { on = (i % 2 == 0) ? 1.0 : 0.0; break; } - acc = next; - } - alpha *= on; - } - if (alpha <= 0.001) discard; - outColor = vec4(rgb * alpha, alpha); -}`,Ce=`#version 300 es -in float ax0; in float ay0; in float ax1; in float ay1; in float ax2; in float ay2; in float a_cval; -in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_x0meta; uniform vec2 u_x1meta; uniform vec2 u_x2meta; -uniform vec2 u_y0meta; uniform vec2 u_y1meta; uniform vec2 u_y2meta; -uniform int u_x0mode; uniform int u_x1mode; uniform int u_x2mode; -uniform int u_y0mode; uniform int u_y1mode; uniform int u_y2mode; -uniform int u_colorMode; -out float v_cval; out vec3 v_bary; out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; -${I} -void main() { - int vertex = gl_VertexID % 3; - float x = vertex == 0 ? ax0 : (vertex == 1 ? ax1 : ax2); - float y = vertex == 0 ? ay0 : (vertex == 1 ? ay1 : ay2); - vec2 xm = vertex == 0 ? u_x0meta : (vertex == 1 ? u_x1meta : u_x2meta); - vec2 ym = vertex == 0 ? u_y0meta : (vertex == 1 ? u_y1meta : u_y2meta); - int xmode = vertex == 0 ? u_x0mode : (vertex == 1 ? u_x1mode : u_x2mode); - int ymode = vertex == 0 ? u_y0mode : (vertex == 1 ? u_y1mode : u_y2mode); - gl_Position = vec4(xyMap(x, u_xmap, xm, xmode), xyMap(y, u_ymap, ym, ymode), 0.0, 1.0); - v_cval = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - v_bary = vertex == 0 ? vec3(1.,0.,0.) : (vertex == 1 ? vec3(0.,1.,0.) : vec3(0.,0.,1.)); - v_rgba = a_rgba; v_style = a_style; v_stroke = a_stroke; -}`,we=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform int u_colorMode; uniform sampler2D u_lut; uniform float u_opacity; -uniform vec4 u_stroke; uniform float u_strokeWidth; uniform int u_strokeMode; uniform float u_strokeOpacity; -in float v_cval; in vec3 v_bary; in vec4 v_rgba; in vec4 v_style; in vec4 v_stroke; -out vec4 outColor; -void main() { - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode == 0 ? u_color : vec4(texture(u_lut, vec2(clamp(v_cval, 0.0, 1.0), 0.5)).rgb, 1.0)); - float alpha = (v_style.y >= 0.0 ? v_style.y : paint.a) * v_style.x * u_opacity; - vec4 fill = vec4(paint.rgb * alpha, alpha); - float strokeWidth = v_style.z >= 0.0 ? v_style.z : u_strokeWidth; - if (strokeWidth > 0.0) { - float edge = min(v_bary.x, min(v_bary.y, v_bary.z)); - float coverage = smoothstep(0.0, max(fwidth(edge) * strokeWidth, 1e-5), edge); - // Both stroke sources ship straight alpha; the per-item alpha stack - // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; - float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; - vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); - outColor = mix(stroke, fill, coverage); - } else { - outColor = fill; - } -}`,Te=` -uniform int u_gradMode; uniform int u_gradDir; uniform int u_gradCount; -uniform float u_gradPos[8]; uniform vec4 u_gradColor[8]; -vec4 xyGradSample(float t) { - vec4 c0 = u_gradColor[0]; float p0 = u_gradPos[0]; - if (t <= p0) return c0; - for (int i = 1; i < 8; i++) { - if (i >= u_gradCount) break; - float p1 = u_gradPos[i]; vec4 c1 = u_gradColor[i]; - if (t <= p1) return mix(c0, c1, (t - p0) / max(p1 - p0, 1e-6)); - p0 = p1; c0 = c1; - } - return c0; -} -float xyGradT(float markT, vec2 res) { - float t; - if (u_gradMode == 2) { - vec2 f = gl_FragCoord.xy / max(res, vec2(1.0)); - t = u_gradDir == 0 ? 1.0 - f.y : u_gradDir == 1 ? f.y : u_gradDir == 2 ? 1.0 - f.x : f.x; - } else { - t = u_gradDir == 0 ? 1.0 - markT : markT; - } - return clamp(t, 0.0, 1.0); -}`,Ee=`#version 300 es -in float ax0; in float ax1; in float ay0; in float ay1; in float ab0; in float ab1; -uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_bmap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform vec2 u_bmeta; -uniform int u_xmode; uniform int u_ymode; -uniform float u_revealProgress; uniform float u_revealSegments; -out float v_top; out float v_base; out float v_pos; -const vec2 corners[4] = vec2[4](vec2(0.,0.), vec2(1.,0.), vec2(0.,1.), vec2(1.,1.)); -${I} -void main() { - vec2 c = corners[gl_VertexID]; - float x0 = xyMap(ax0, u_xmap, u_xmeta, u_xmode); - float x1 = xyMap(ax1, u_xmap, u_xmeta, u_xmode); - float y0 = xyMap(ay0, u_ymap, u_ymeta, u_ymode); - float y1 = xyMap(ay1, u_ymap, u_ymeta, u_ymode); - float b0 = xyMap(ab0, u_bmap, u_bmeta, u_ymode); - float b1 = xyMap(ab1, u_bmap, u_bmeta, u_ymode); - float reveal = clamp(u_revealProgress * u_revealSegments - float(gl_InstanceID), 0.0, 1.0); - x1 = mix(x0, x1, reveal); - y1 = mix(y0, y1, reveal); - b1 = mix(b0, b1, reveal); - float top = mix(y0, y1, c.x); - float base = mix(b0, b1, c.x); - float clipY = mix(base, top, c.y); - // Carry the curve top, baseline, and this fragment's Y *separately* (each is - // linear in x and continuous across segments); the fragment divides them for - // a true per-column height fraction. Interpolating the ratio itself (the old - // c.y) facets over the slanted-top quad and streaks — this doesn't, and the - // fill stays evenly saturated at the curve whatever its height. - v_top = top; - v_base = base; - v_pos = clipY; - gl_Position = vec4(mix(x0, x1, c.x), clipY, 0.0, 1.0); -}`,De=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; -uniform vec2 u_res; -in float v_top; in float v_base; in float v_pos; -out vec4 outColor; -${Te} -void main() { - vec4 premult = vec4(u_color.rgb * u_color.a, u_color.a); - if (u_gradMode != 0) { - // 0 at the baseline, 1 exactly at the curve — even at the curve everywhere. - float denom = v_top - v_base; - float markT = clamp((v_pos - v_base) / (abs(denom) > 1e-6 ? denom : 1e-6), 0.0, 1.0); - // Compose the mark opacity (premultiplied) over the gradient sample. - premult = xyGradSample(xyGradT(markT, u_res)) * u_color.a; - } - if (premult.a <= 0.001) discard; - outColor = premult; -}`,Oe=`#version 300 es -in float ax0; in float ax1; in float ay0; in float ay1; -uniform vec2 u_x0map; uniform vec2 u_x1map; uniform vec2 u_y0map; uniform vec2 u_y1map; -uniform vec2 u_x0meta; uniform vec2 u_x1meta; uniform vec2 u_y0meta; uniform vec2 u_y1meta; -uniform int u_xmode; uniform int u_ymode; -uniform vec4 u_edgePad; -uniform vec2 u_res; -in float a_cval; in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; in vec2 a_radius; -uniform int u_colorMode; -out float v_lutCoord; -out vec2 v_local; out vec2 v_half; out float v_t; -out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; out vec2 v_radius; -const vec2 corners[4] = vec2[4](vec2(0.,0.), vec2(1.,0.), vec2(0.,1.), vec2(1.,1.)); -${I} -void main() { - vec2 c = corners[gl_VertexID]; - float x0 = xyMap(ax0, u_x0map, u_x0meta, u_xmode) + u_edgePad.x; - float x1 = xyMap(ax1, u_x1map, u_x1meta, u_xmode) + u_edgePad.y; - float y0 = xyMap(ay0, u_y0map, u_y0meta, u_ymode) + u_edgePad.z; - float y1 = xyMap(ay1, u_y1map, u_y1meta, u_ymode) + u_edgePad.w; - v_lutCoord = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - // Pixel-space local frame for the rounded-corner/stroke SDF (v_half is - // constant across the quad; v_local interpolates to the fragment offset). - vec2 pA = (vec2(x0, y0) * 0.5 + 0.5) * u_res; - vec2 pB = (vec2(x1, y1) * 0.5 + 0.5) * u_res; - v_half = abs(pB - pA) * 0.5; - v_local = mix(pA, pB, c) - (pA + pB) * 0.5; - v_t = c.y; - v_rgba = a_rgba; v_style = a_style; v_stroke = a_stroke; v_radius = a_radius; - gl_Position = vec4(mix(x0, x1, c.x), mix(y0, y1, c.y), 0.0, 1.0); -}`,ke=`#version 300 es -in float a_pos; in float a_v0; in float a_v1; in float a_cval; -in float a_prevx; in float a_prevy; in float a_prevx1; -in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; in vec2 a_radius; -uniform vec2 u_pmap; uniform vec2 u_v0map; uniform vec2 u_v1map; -uniform vec2 u_pmeta; uniform vec2 u_v0meta; uniform vec2 u_v1meta; -uniform int u_pmode; uniform int u_vmode; -uniform float u_width; uniform int u_orientation; uniform int u_v0Mode; uniform float u_v0Const; -uniform float u_v0EdgePad; -uniform float u_animationProgress; -uniform float u_transitionProgress; uniform int u_transitionActive; uniform float u_prevWidth; -uniform vec2 u_res; -uniform int u_colorMode; -out float v_lutCoord; -out vec2 v_local; out vec2 v_half; out float v_t; -out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; out vec2 v_radius; -const vec2 corners[4] = vec2[4](vec2(0.,0.), vec2(1.,0.), vec2(0.,1.), vec2(1.,1.)); -${I} -void main() { - vec2 c = corners[gl_VertexID]; - float nextP = xyMap(a_pos, u_pmap, u_pmeta, u_pmode); - float nextV0 = u_v0Mode == 0 ? u_v0Const : xyMap(a_v0, u_v0map, u_v0meta, u_vmode); - float nextV1 = xyMap(a_v1, u_v1map, u_v1meta, u_vmode); - float p = nextP; - float v0 = nextV0; - float v1 = nextV1; - float width = u_width; - if (u_transitionActive == 1) { - p = mix(xyMap(a_prevx, u_pmap, u_pmeta, u_pmode), nextP, u_transitionProgress); - // Previous baselines are encoded in the next value column's coordinate - // system, which lets constant and per-row baselines share one attribute. - v0 = mix(xyMap(a_prevx1, u_v1map, u_v1meta, u_vmode), nextV0, u_transitionProgress); - v1 = mix(xyMap(a_prevy, u_v1map, u_v1meta, u_vmode), nextV1, u_transitionProgress); - width = mix(u_prevWidth, u_width, u_transitionProgress); - } - v0 += u_v0EdgePad; - v1 = mix(v0, v1, u_animationProgress); - float halfW = abs(width * u_pmap.x) * 0.5; - v_lutCoord = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - vec2 clipA, clipB; - if (u_orientation == 0) { - clipA = vec2(p - halfW, v0); clipB = vec2(p + halfW, v1); - gl_Position = vec4(mix(clipA.x, clipB.x, c.x), mix(clipA.y, clipB.y, c.y), 0.0, 1.0); - v_t = c.y; - } else { - clipA = vec2(v0, p - halfW); clipB = vec2(v1, p + halfW); - gl_Position = vec4(mix(clipA.x, clipB.x, c.x), mix(clipA.y, clipB.y, c.y), 0.0, 1.0); - v_t = c.x; - } - // Pixel-space local frame for the rounded-corner/stroke SDF; v_t runs along - // the value axis (0 at the base, 1 at the bar tip) for mark-space gradients. - vec2 pA = (clipA * 0.5 + 0.5) * u_res; - vec2 pB = (clipB * 0.5 + 0.5) * u_res; - v_half = abs(pB - pA) * 0.5; - v_local = vec2(mix(pA.x, pB.x, c.x), mix(pA.y, pB.y, c.y)) - (pA + pB) * 0.5; - v_rgba = a_rgba; v_style = a_style; v_stroke = a_stroke; v_radius = a_radius; -}`,Ae=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform int u_colorMode; uniform sampler2D u_lut; -uniform vec2 u_radius; uniform float u_strokeWidth; uniform vec4 u_stroke; -uniform int u_strokeMode; uniform float u_strokeOpacity; -uniform float u_opacity; -uniform vec2 u_res; -in float v_lutCoord; -in vec2 v_local; in vec2 v_half; in float v_t; -in vec4 v_rgba; in vec4 v_style; in vec4 v_stroke; in vec2 v_radius; -out vec4 outColor; -${Te} -void main() { - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode == 0 ? u_color : vec4(texture(u_lut, vec2(clamp(v_lutCoord, 0.0, 1.0), 0.5)).rgb, 1.0)); - float alpha = (v_style.y >= 0.0 ? v_style.y : paint.a) * v_style.x * u_opacity; - vec4 premult = vec4(paint.rgb * alpha, alpha); - if (u_gradMode != 0) { - vec4 gradient = xyGradSample(xyGradT(v_t, u_res)); - float gradientAlpha = (v_style.y >= 0.0 ? v_style.y : gradient.a) * v_style.x * u_opacity; - // Gradient stops are uploaded premultiplied. Recover their straight RGB - // before applying an artist-alpha override, then premultiply the result. - vec3 gradientRgb = gradient.a > 1e-6 ? gradient.rgb / gradient.a : vec3(0.0); - premult = vec4(gradientRgb * gradientAlpha, gradientAlpha); - } - vec2 radius = v_radius.x >= 0.0 ? v_radius : u_radius; - float strokeWidth = v_style.z >= 0.0 ? v_style.z : u_strokeWidth; - if (radius.x > 0.0 || radius.y > 0.0 || strokeWidth > 0.0) { - // u_radius = (tip, base) in mark space: v_t > 0.5 is the tip half, so - // corner_radius=(6, 0) rounds only the value end of the bar. On the - // straight sides the SDF reduces to |local|-half independent of r, so - // differing radii meet with no seam. - float r = min(v_t > 0.5 ? radius.x : radius.y, min(v_half.x, v_half.y)); - vec2 q = abs(v_local) - (v_half - vec2(r)); - float d = length(max(q, vec2(0.0))) + min(max(q.x, q.y), 0.0) - r; - float aa = 0.75; - if (strokeWidth > 0.0) { - // Both stroke sources ship straight alpha; the per-item alpha stack - // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; - float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; - vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); - float inner = 1.0 - smoothstep(-aa, aa, d + strokeWidth); - premult = mix(stroke, premult, inner); - } - premult *= 1.0 - smoothstep(-aa, aa, d); - } - if (premult.a <= 0.001) discard; - outColor = premult; -}`;function je(e,t,n){let r=new Float64Array(n-1),i=new Float64Array(n);for(let i=0;i0?(t[i+1]-t[i])/n:0}i[0]=r[0],i[n-1]=r[n-2];for(let e=1;e9){let o=3/Math.sqrt(a);i[e]=o*t*r[e],i[e+1]=o*n*r[e]}}return i}function Me(e,t,n,r,i){if(r<3)return null;let a=Math.max(1,Math.min(16,Math.floor(i/r)));if(a<=1)return null;for(let i=0;i0&&e[i]0){let e=p*p,a=e*p,c=2*a-3*e+1,l=a-2*e+p,m=-2*a+3*e,h=a-e;u[f]=c*t[i]+l*r*o[i]+m*t[i+1]+h*r*o[i+1],d&&(d[f]=c*n[i]+l*r*s[i]+m*n[i+1]+h*r*s[i+1])}else u[f]=t[i],d&&(d[f]=n[i]);f++}}return l[f]=e[r-1],u[f]=t[r-1],d&&(d[f]=n[r-1]),{x:l,y:u,extra:d,n:c}}var Ne=2e5,Pe=1.15;function L(e,t,n=140){if(t==null||n<=0||e._prefersReducedMotion())return 1;let r=Math.min(1,Math.max(0,(e._now()-t)/n));return r*r*(3-2*r)}function Fe(e,t){let n=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength),r=new Float32Array(n.length),i=Math.log1p(Math.max(0,t||0));if(i>0)for(let e=0;e0&&(r[e]=Math.expm1(n[e]/255*i));return r}function Ie(e){return e.slice?e.slice():new Float32Array(e)}function R(e,t,n,r,i,a){let o=new Uint8Array(n.length),s=Math.log1p(Math.max(0,a||0));if(s>0)for(let e=0;e0&&Number.isFinite(t)&&(o[e]=Math.max(1,Math.min(255,Math.round(255*Math.log1p(t)/s))))}e.bindTexture(e.TEXTURE_2D,t);let c=e.getParameter(e.UNPACK_ALIGNMENT);e.pixelStorei(e.UNPACK_ALIGNMENT,1),e.texImage2D(e.TEXTURE_2D,0,e.R8,r,i,0,e.RED,e.UNSIGNED_BYTE,o),e.pixelStorei(e.UNPACK_ALIGNMENT,c),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)}function Le(e,t){if(!Number.isFinite(t)||t<=0)return e.densityNormMax=0,0;let n=Number.isFinite(e.densityNormMax)&&e.densityNormMax>0?e.densityNormMax:t,r=t>n?n*.3+t*.7:Math.max(t,n*.86);return e.densityNormMax=r,r}function Re(e,t,n,r){if(!t.density||!t.density.grid||!Number.isFinite(r)||r<=0){t._densityNormAnim=null;return}let i=Math.abs(Math.log(Math.max(n,1e-12)/Math.max(r,1e-12)));if(e._prefersReducedMotion()||i<.02){t._densityNormAnim=null,t.density.normMax=r,t.densityNormMax=r,R(e.gl,t.density.tex,t.density.grid,t.density.w,t.density.h,r);return}t._densityNormAnim={start:n,target:r,startedAt:e._now(),duration:r.004||i>=1)&&(r.normMax=o,t.densityNormMax=o,R(e.gl,r.tex,r.grid,r.w,r.h,o)),i<1){e.draw();return}r.normMax=n.target,t.densityNormMax=n.target,t._densityNormAnim=null}function z(e){return Math.abs((e.xRange[1]-e.xRange[0])*(e.yRange[1]-e.yRange[0]))}function Be(e){return e?Math.abs((e.x1-e.x0)*(e.y1-e.y0)):0}function Ve(e,t){if(!e||!t)return!1;let n=(t.x0+t.x1)/2,r=(t.y0+t.y1)/2;return n>=Math.min(e.x0,e.x1)&&n<=Math.max(e.x0,e.x1)&&r>=Math.min(e.y0,e.y1)&&r<=Math.max(e.y0,e.y1)}function He(e,t){let n=t.densityCache||(t.density?[t.density]:[]),r=null,i=null;for(let t of n)!t||!t.tex||((!i||z(t)>z(i))&&(i=t),e._viewInsideRange(t.xRange,t.yRange)&&(!r||z(t)1200||!Ve(n.win,r))return!1;let i=Be(n.win),a=Be(r);if(!Number.isFinite(i)||!Number.isFinite(a)||i<=0)return!1;let o=Number.isFinite(n.visible)?n.visible:n.n;return!Number.isFinite(o)||o<=0?!1:o*Math.max(1,a/i)<=Ne*Pe}function We(e,t){return t===e.density||t===e.prevDensity||t===e._densitySwitchPrev||t===e._shownDensity||t===e._homeDensity}function B(e,t,n){if(!(!n||!n.tex))for(n._stamp=++e._densityStamp,t.densityCache||=[],t.densityCache.includes(n)||t.densityCache.push(n);t.densityCache.length>8;){let n=-1;for(let e=0;en.channels&&n.channels[e],u=Number(o.trace.style&&o.trace.style.artist_alpha);if(l(`opacity`)||l(`artist_alpha`)||l(`stroke_width`)||l(`symbol`)||Number.isFinite(u)){let t=new Float32Array(o.n*4);for(let e=0;e{let s=l(n);if(!s)return;let c=s.dtype===`u8`?e._asU8(r[s.buf]):e._asF32(r[s.buf]),u=s.components||1;for(let e=0;e=i.x0&&t<=i.x1&&u>=i.y0&&u<=i.y1&&(l[e]=1)}else if(i.mode===`poly`&&Array.isArray(i.points)&&i.points.length>=3){let e=i.points;for(let i=0;iu!=s>u&&t<(o-i)*(u-a)/(s-a)+i&&(d=!d)}d&&(l[i]=1)}}else return;e._applySelMask(t,l)}function qe(e,t){let n=t.drill;if(!n)return;let r=e.gl;e._deleteVaos(n);for(let e of[n.xBuf,n.yBuf,n.cBuf,n.rgbaBuf,n.sBuf,n.styleBuf,n.strokeBuf,n.selBuf,n.dBuf])e&&r.deleteBuffer(e);t.drill=null,t._drillFadeStart=null,t._drillExitFadeStart=null,t._drillWasInside=!1,t._drillShownAlpha=null,t._drillDying=!1,t._drillDiedInsideWin=!1,e._hoverId=-1,e._lastRow=null,e._updatePickable()}function Je(e,t){t.drill&&(t._drillDying=!0,t._drillDiedInsideWin=e._viewInside(t.drill.win),Qe(e,t))}function Ye(e,t){(t._drillExitFadeStart===void 0||t._drillExitFadeStart===null)&&(t._drillExitFadeStart=e._now());let n=L(e,t._drillExitFadeStart,V);return n>=1&&(t._drillExitFadeStart=null),n}var Xe=140,V=120;function H(e){return .5-Math.sin(Math.asin(1-2*Math.min(1,Math.max(0,e)))/3)}function Ze(e,t){return t._drillExitFadeStart==null?t._drillFadeStart==null?t._drillShownAlpha==null?+!!t._drillWasInside:t._drillShownAlpha:L(e,t._drillFadeStart,Xe):1-L(e,t._drillExitFadeStart,V)}function U(e,t){let n=Ze(e,t);t._drillShownAlpha=n,t._drillExitFadeStart=null,t._drillFadeStart=n>=1?null:e._now()-Xe*H(n)}function Qe(e,t){if(t._drillExitFadeStart!=null)return;let n=Ze(e,t);t._drillShownAlpha=n,t._drillFadeStart=null,t._drillExitFadeStart=e._now()-V*H(1-n)}function $e(e,t,n,r){Je(e,t);let i=n.density,a=i.enc===`log-u8`?Fe(r[i.buf],i.max):Ie(e._asF32(r[i.buf])),o=Le(t,i.max),s=e._prefersReducedMotion()?i.max:o;t.densityNormMax=s,t.prevDensity=t.density,t._densityFadeStart=e._now(),t.density={w:i.w,h:i.h,max:i.max,normMax:s,colormap:i.colormap||t.density.colormap,color:i.color?b(e.root,i.color,[.3,.47,.66,1]):t.density.color,xRange:i.x_range,yRange:i.y_range,grid:a,tex:e._uploadGrid(a,i.w,i.h,s),lut:t.density.lut},Object.prototype.hasOwnProperty.call(i,`sample`)&&e._applyDensitySample(t,i.sample,r),Re(e,t,s,i.max),B(e,t,t.density)}function et(e,t,n,r=1){if(n!==t._shownDensity){if(n===t._densitySwitchPrev&&t._densitySwitchFadeStart!=null){let n=L(e,t._densitySwitchFadeStart,140);t._densitySwitchFadeStart=e._now()-140*H(1-n)}else t._densitySwitchFadeStart=e._now();t._densitySwitchPrev=t._shownDensity,t._shownDensity=n}let i=t._densitySwitchPrev,a=i&&i.tex?L(e,t._densitySwitchFadeStart,140):1;if(a<1){e._drawDensity(t,i,(1-a)*r),e._drawDensity(t,n,a*r),e.draw();return}a>=1&&(t.prevDensity===t._densitySwitchPrev&&(t.prevDensity=null),t._densitySwitchPrev=null,t._densitySwitchFadeStart=null,n===t.density&&(t._densityFadeStart=null)),e._drawDensity(t,n,r)}function tt(e,t,n,r,i,a){ze(e,t);let o=t.drill;o&&t._drillDying&&!t._drillDiedInsideWin&&e._viewInside(o.win)&&(t._drillDying=!1,U(e,t),t._drillWasInside=!0);let s=o&&!t._drillDying&&e._viewInside(o.win),c=He(e,t);if(s){(!t._drillWasInside||t._drillExitFadeStart!=null)&&U(e,t),t._drillWasInside=!0,t._drillExitFadeStart=null;let s=L(e,t._drillFadeStart);t._drillShownAlpha=s,t._shownDensity=s<1?c:null,t._densitySwitchPrev=null,t._densitySwitchFadeStart=null,s<1&&c&&c.tex?(e._drawDensity(t,c,1-s),e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis),s),e.draw()):(t._drillFadeStart=null,e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis)))}else if(c&&c.tex){if(Ue(e,t,o)){U(e,t);let s=L(e,t._drillFadeStart);t._drillShownAlpha=s,s<1?(e._drawDensity(t,c,1-s),e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis),s),e.draw()):(t._drillFadeStart=null,e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis))),e._viewAnim&&e.draw();return}let s=o&&t._drillWasInside;s&&Qe(e,t);let l=s?Ye(e,t):1;o&&(t._drillShownAlpha=s&&l<1?1-l:0),s&&l<1?(et(e,t,c,l),e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis),1-l),e.draw()):(t._drillDying?qe(e,t):s&&(t._drillWasInside=!1),et(e,t,c),e._drawDensitySample(t,n,r,i,a))}else o&&e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis))}var W={build:(e,t,n,r)=>e._buildRectMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis),o=t.trace.kind===`histogram`?[0,0,e._edgePadForValue(0,i,a,e.canvas.height),0]:[0,0,0,0];e._drawRects(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.x1Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis),e._map(t.y1Meta,i,a,t.yAxis),o)},refreshColor:(e,t)=>{t.colorMode||(t.color=b(e.root,t.trace.style.color,t.color)),e._rectMarkStyleGpu(t,t.trace)}},nt={build:(e,t,n,r)=>e._buildBarMark(t,n,r),draw:(e,t)=>{if(!t.trace.bar){W.draw(e,t);return}let n=t.orientation===1,r=n?t.yAxis:t.xAxis,i=n?t.xAxis:t.yAxis,[a,o]=e._axisRange(r),[s,c]=e._axisRange(i),l=e._map(t.posMeta,a,o,r),u=e._map(t.value1Meta,s,c,i),d=t.value0Mode===1?e._map(t.value0Meta,s,c,i):null,f=t.value0Mode===0?e._mapConst(t.value0Const,s,c,i):null,p=t.value0Mode===0?e._edgePadForValue(t.value0Const,s,c,n?e.canvas.width:e.canvas.height):0;e._drawBars(t,l,u,d,f,p)},refreshColor:(e,t)=>{t.colorMode||(t.color=b(e.root,t.trace.style.color,t.color)),e._rectMarkStyleGpu(t,t.trace)}},G={build:(e,t,n,r)=>e._buildSegmentMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawSegments(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.colorMode||(t.color=b(e.root,t.trace.style.color,t.color))}},rt={build:(e,t,n,r)=>e._buildAreaMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis),o=e._map(t.xMeta,n,r,t.xAxis),s=e._map(t.yMeta,i,a,t.yAxis);if(e._drawArea(t,o,s,e._map(t.baseMeta,i,a,t.yAxis)),(t.trace.style.line_width??0)>0&&(e._drawLine(t,o,s,t.lineColor,t.trace.style.line_width,t.trace.style.line_opacity??1),t.trace.style.stroke_perimeter)){let n=t.yBuf,r=t.yMeta,i=t._dashY;t.yBuf=t.baseBuf,t.yMeta=t.baseMeta,t._dashY=t._cpu.base,e._drawLine(t,o,s,t.lineColor,t.trace.style.line_width,t.trace.style.line_opacity??1),t.yBuf=n,t.yMeta=r,t._dashY=i}},refreshColor:(e,t)=>{t.color=b(e.root,t.trace.style.color,t.color),t.lineColor=b(e.root,t.trace.style.line_color||t.trace.style.color,t.lineColor||t.color),t.grad=e._resolveMarkFill(t.trace.style,t.color)}},K={histogram:W,box:W,violin:W,errorbar:G,stem:G,box_whisker:G,box_median:G,contour:G,segments:G,triangle_mesh:{build:(e,t,n,r)=>e._buildMeshMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawMesh(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.colorMode===0&&t.trace.color&&(t.color=b(e.root,t.trace.color.color,t.color));let n=t.trace.style||{};t.meshStroke=b(e.root,n.stroke||`transparent`,[0,0,0,0])}},error_band:rt,hexbin:{build:(e,t,n,r)=>e._buildHexbinMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawMesh(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.colorMode===0&&t.trace.color&&(t.color=b(e.root,t.trace.color.color,t.color));let n=t.trace.style||{};t.meshStroke=b(e.root,n.stroke||`transparent`,[0,0,0,0])}},bar:nt,column:nt,heatmap:{build:(e,t,n,r)=>e._buildHeatmapMark(t,n,r),draw:(e,t)=>e._drawHeatmap(t)},scatter:{build:(e,t,n,r)=>e._buildScatterMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawPoints(t,e._map(t.xMeta,n,r,t.xAxis),e._map(t.yMeta,i,a,t.yAxis))},pointPick:!0,retainCpu:!0,refreshColor:(e,t)=>{t.colorMode===0&&t.trace.color&&(t.color=b(e.root,t.trace.color.color,t.color)),e._pointMarkStyle(t,t.trace)}},line:{build:(e,t,n,r)=>e._buildLineMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawLine(t,e._map(t.xMeta,n,r,t.xAxis),e._map(t.yMeta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.color=b(e.root,t.trace.style.color,t.color)}},area:rt};function q(e){return K[e]||K.scatter}var J={l:62,r:14,t:10,b:42},Y=18,it=24,at=8,ot=0,X=`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;`,st=new Set([`animation-iteration-count`,`aspect-ratio`,`border-image-outset`,`border-image-slice`,`border-image-width`,`column-count`,`flex`,`flex-grow`,`flex-shrink`,`font-weight`,`line-height`,`opacity`,`order`,`orphans`,`tab-size`,`widows`,`z-index`,`zoom`,`fill-opacity`,`flood-opacity`,`stop-opacity`,`stroke-miterlimit`,`stroke-opacity`]),Z={views:new Set,seq:1,hiddenReleaseChannel:null,hiddenReleaseQueue:[],frameId:null,channel:null,foreign:null,_announcedLive:-1,_crossFrameReady:!1,_rebalanceScheduled:!1,budget(){let e=typeof window<`u`?window.XY_CONTEXT_BUDGET:null;return Number.isFinite(e)&&e>=1?Math.floor(e):12},register(e){this._initCrossFrame(),this.views.add(e)},unregister(e){e._ctxPendingReservation=!1,this.views.delete(e),this._announceLive()},reserve(e){let t=[],n=0;for(let r of this.views)r!==e&&r.gl&&!r._glLost&&!r._destroyed&&t.push(r),r!==e&&r._ctxPendingReservation&&!r._destroyed&&(n+=1);let r=!e._ctxPendingReservation;e._ctxPendingReservation=!0;let i=t.length+n+ +!!r-this.budget();if(i<=0)return;let a=t.filter(e=>!e._ctxVisible).sort((e,t)=>(e._ctxSeenSeq||0)-(t._ctxSeenSeq||0));for(let e of a){if(i<=0)break;e._releaseContext()&&--i}if(i<=0)return;let o=t.filter(e=>e._ctxVisible).sort((e,t)=>(e._ctxSeenSeq||0)-(t._ctxSeenSeq||0));for(let e of o){if(i<=0)break;e._releaseContext()&&--i}},acquired(e){e._ctxPendingReservation=!1,this._rebalance(),this._announceLive()},cancel(e){e._ctxPendingReservation=!1},_initCrossFrame(){if(!this._crossFrameReady&&(this._crossFrameReady=!0,this.foreign=new Map,!(typeof BroadcastChannel>`u`)))try{this.frameId=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,this.channel=new BroadcastChannel(`xy-webgl-context-governor`),this.channel.onmessage=e=>this._onForeignMessage(e.data),this._post({t:`hello`,id:this.frameId}),typeof window<`u`&&window.addEventListener&&(window.addEventListener(`pagehide`,()=>this._post({t:`bye`,id:this.frameId})),window.addEventListener(`pageshow`,e=>{!e||!e.persisted||(this.foreign.clear(),this._announcedLive=-1,this._post({t:`hello`,id:this.frameId}),this._announceLive(!0))}))}catch{this.channel=null}},_post(e){try{this.channel&&this.channel.postMessage(e)}catch{}},_onForeignMessage(e){!e||!this.foreign||e.id===this.frameId||(e.t===`live`?(this.foreign.set(e.id,e.n|0),this._rebalance()):e.t===`hello`?this._announceLive(!0):e.t===`bye`&&this.foreign.delete(e.id))},localLive(){let e=0;for(let t of this.views)t.gl&&!t._glLost&&!t._destroyed&&(e+=1);return e},foreignLive(){let e=0;if(this.foreign)for(let t of this.foreign.values())e+=t;return e},_announceLive(e=!1){if(!this.channel)return;let t=this.localLive();!e&&t===this._announcedLive||(this._announcedLive=t,this._post({t:`live`,id:this.frameId,n:t}))},_rebalance(){if(this.localLive()+this.foreignLive()-this.budget()<=0)return;let e=null;for(let t of this.views)t.gl&&!t._glLost&&!t._destroyed&&!t._ctxVisible&&(!e||(t._ctxSeenSeq||0)<(e._ctxSeenSeq||0))&&(e=t);!e||!e._releaseContext()||this.localLive()+this.foreignLive()-this.budget()>0&&!this._rebalanceScheduled&&(this._rebalanceScheduled=!0,setTimeout(()=>{this._rebalanceScheduled=!1,this._rebalance()},0))},scheduleHiddenReleases(){if(this.hiddenReleaseChannel!==null)return;this.hiddenReleaseQueue=Array.from(this.views);let e=new MessageChannel;this.hiddenReleaseChannel=e,e.port1.onmessage=()=>{if(typeof document>`u`||document.visibilityState!==`hidden`){this.cancelHiddenReleases();return}let t=null;for(;this.hiddenReleaseQueue.length&&!t;){let e=this.hiddenReleaseQueue.shift();!e._destroyed&&e.gl&&!e._glLost&&!e.gl.isContextLost()&&(t=e)}if(!t){this.cancelHiddenReleases();return}t._releaseContext(),e.port2.postMessage(null)},e.port2.postMessage(null)},cancelHiddenReleases(){this.hiddenReleaseChannel?.port1.close(),this.hiddenReleaseChannel?.port2.close(),this.hiddenReleaseChannel=null,this.hiddenReleaseQueue=[]}};function ct(e){if(typeof window>`u`||!e.getBoundingClientRect)return!0;let t=e.getBoundingClientRect();if(!t.width&&!t.height)return!1;let n=window.innerHeight||0,r=window.innerWidth||0;return t.bottom>-.25*n&&t.top<1.25*n&&t.right>-.25*r&&t.left<1.25*r}var Q=class{constructor(e,t,n,r){if(t.protocol!==5)throw e.textContent=`xy: protocol mismatch (client speaks 5, kernel sent ${t.protocol}). Update the xy package and restart the kernel.`,Error(`protocol mismatch`);this.spec=t,this.interaction=t.interaction||{},this.markStyle=t.mark_style||{},this.axes=this._normalizeAxes(t),this.comm=r,this.seq=0,this._densityStamp=0,this._viewRequestBurstStart=null,this._viewAnim=null,this._animRaf=null,this._dataAnim=null,this._dataAnimRaf=null,this._transitionOldTraces=null,this._transitionView=null,this._wheelZoomRaf=null,this._pendingWheelZoom=null,this._lastLabelDraw=null,this._lutCache=new Map,this._listeners=[],this._glPrograms=[],this._progCache=new Map,this._bufSeq=0,this._destroyed=!1,this._resizeRaf=null,this._pendingResize=null,this._resizeNeedsMeasure=!1,this._hoverId=-1,this._hoverTarget=null,this._viewEventRaf=null,this._linkedSource=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,this.dragMode=`none`,this._interactionSeq=0,this.fluid=t.width===`100%`,this.fluidH=t.height===`100%`;let i=this.fluid||this.fluidH?e.getBoundingClientRect():null,a=this.fluid?Math.round(i.width)||640:t.width,o=this.fluidH?Math.round(i.height)||420:t.height;this.size={w:Math.max(this.fluid?120:48,a),h:Math.max(this.fluidH?120:48,o)},this._layout(),this._buildDom(e),this.theme=x(this.root),this._themeStale=!this.root.isConnected,this._payload=n,this._glLost=!1,this._ctxReleasedExt=null,this._ctxReleases=0,this._ctxRecoveries=0,this._ctxLostPending=!1,this._ctxRecoverRequested=!1,this._ctxVisible=ct(e),Z.register(this),this._ctxVisible&&(this._ctxSeenSeq=Z.seq++),this._contextLossCount=0,this._contextRestoreCount=0,this._contextRecoveryError=null;try{this._initGl(n)}catch(e){throw Z.unregister(this),String(e&&e.message||e)===`webgl2 unavailable`&&(this.root.textContent=`xy: WebGL2 unavailable in this browser.`),e}if(this.canvas.dataset.xyCtx=`live`,this.view0=this._clampView({ranges:Object.fromEntries(Object.entries(this.axes).map(([e,t])=>[e,[...t.range]]))}),this.view=this._copyView(this.view0),this.dragMode=this._resolveDefaultDragAction(),this._initA11y(),this.root.dataset.xyContextState=`ready`,this._initContextLossRecovery(),this._armContextVisibilityWatch(),this._initViewState(),this._initInteraction(),this._buildModebar(this.root),this._initAxisBands(),(this.fluid||this.fluidH)&&typeof ResizeObserver<`u`&&(this._ro=new ResizeObserver(e=>{let t=e[e.length-1].contentRect;(t.width||t.height)&&this._queueResize(t.width,t.height)}),this._ro.observe(this.root)),this._armVisibilityResizeWatch(),this._armDprWatch(),this._initLinkedCharts(),this._themeWatch=window.matchMedia(`(prefers-color-scheme: dark)`),this._onScheme=()=>this.refreshTheme(),this._themeWatch.addEventListener?.(`change`,this._onScheme),typeof MutationObserver<`u`){this._themeMutationObserver=new MutationObserver(()=>this.refreshTheme());for(let e=this.root;e;e=e.parentElement)this._themeMutationObserver.observe(e,{attributes:!0,attributeFilter:[`class`,`style`]})}this._unsubscribeComm=r?r.onMessage((e,t)=>this._onKernelMsg(e,t)):null,this._startEntranceAnimation?this._startEntranceAnimation():this.draw()}_layout(){let e=this.size.w<520,t=Array.isArray(this.spec.padding)?this.spec.padding:null,n=this.spec.colorbar,r=n&&n.orientation!==`horizontal`,i=n&&n.orientation===`horizontal`,a=this.fluid&&e&&t,o=t?a?Math.min(t[3],46):t[3]:e?46:J.l;this._compactVerticalColorbar=!!(this.fluid&&e&&r);let s=r?this._compactVerticalColorbar?34:86+(n.label?18:0):0,c=i?38+(n.label?16:0):0,l=(t?a?Math.min(t[1],8):t[1]:e?8:J.r)+s,u=t?t[0]:e?6:J.t,d=(t?t[2]:e?36:J.b)+c,f=Object.values(this.axes||{}).some(e=>e&&String(e.id||``).startsWith(`x`)&&e.side!==`top`&&this._axisTickLabelStrategy(e)!==`none`);this._bottomAxisRoom=f?e?36:J.b:0;let p=Object.values(this.axes||{}).some(e=>e&&String(e.id||``).startsWith(`x`)&&e.side===`top`&&this._axisTickLabelStrategy(e)!==`none`)?e?26:32:0,m=u+(this.spec.title?e?26:30:0)+p,h=Object.values(this.axes||{}).filter(e=>e&&String(e.id||``).startsWith(`y`)&&e.side===`right`&&this._axisTickLabelStrategy(e)!==`none`);this._rightAxisRoom=h.length?e?42:54:0;let g=l+this._rightAxisRoom;this.plot={x:o,y:m,w:Math.max(40,this.size.w-o-g),h:Math.max(40,this.size.h-m-d)}}_normalizeAxes(e){let t={...e.axes||{}};e.x_axis&&(t.x=e.x_axis),e.y_axis&&(t.y=e.y_axis);for(let[e,n]of Object.entries(t))n&&typeof n==`object`&&!n.id&&(n.id=e);return t}_axis(e){let t=e||`x`;return this.axes[t]||(String(t).startsWith(`y`)?this.axes.y:this.axes.x)||{}}_axisDim(e){return String(e||`x`).startsWith(`y`)?`y`:`x`}_axisMode(e){return+(this._axis(e).scale===`log`)}_axisIds(){return Object.keys(this.axes||{})}_copyView(e){let t={};for(let n of this._axisIds()){let r=e?.ranges?.[n]||this._axis(n).range||[0,1];t[n]=[Number(r[0]),Number(r[1])]}let n=t.x||[0,1],r=t.y||[0,1];return{ranges:t,x0:n[0],x1:n[1],y0:r[0],y1:r[1]}}_viewFrom(e,t=this.view){let n={};for(let r of this._axisIds()){let i=e?.ranges?.[r]||(r===`x`&&e?.x0!==void 0?[e.x0,e.x1]:null)||(r===`y`&&e?.y0!==void 0?[e.y0,e.y1]:null)||t?.ranges?.[r]||this._axis(r).range||[0,1];n[r]=[Number(i[0]),Number(i[1])]}return this._copyView({ranges:n})}_axisPolicy(e){let t=this.interaction?.[e];if(!Array.isArray(t)||!t.length)return this._axisIds();let n=new Set(this._axisIds());return[...new Set(t.filter(e=>n.has(e)))]}_resetAxisPolicy(){if(Array.isArray(this.interaction?.reset_axes))return this._axisPolicy(`reset_axes`);let e=[];return this._interactionFlag(`pan`,!0)&&e.push(...this._axisPolicy(`pan_axes`)),this._interactionFlag(`zoom`,!0)&&e.push(...this._axisPolicy(`zoom_axes`)),[...new Set(e)]}_axisContained(e){return!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._axisPolicy(`zoom_axes`).includes(e)?!1:!this._interactionFlag(`pan`,!0)||!this._axisPolicy(`pan_axes`).includes(e)}_resolveDefaultDragAction(){let e=typeof this.interaction?.default_drag_action==`string`?this.interaction.default_drag_action:`auto`,t=this._interactionFlag(`navigation`,!0),n=t&&this._interactionFlag(`pan`,!0),r=t&&this._interactionFlag(`zoom`,!0)&&this._interactionFlag(`box_zoom`,!0),i=this._pickable&&this._interactionFlag(`select`,!0)&&this._interactionFlag(`brush`,!0);return e===`auto`?n?`pan`:r?`zoom`:i?`select`:`none`:e===`pan`?n?`pan`:this._resolveDefaultDragActionFallback():e===`zoom`?r?`zoom`:this._resolveDefaultDragActionFallback():e.startsWith(`select`)?i?e:this._resolveDefaultDragActionFallback():e===`none`?`none`:this._resolveDefaultDragActionFallback()}_resolveDefaultDragActionFallback(){let e=this.interaction.default_drag_action;this.interaction.default_drag_action=`auto`;let t=this._resolveDefaultDragAction();return this.interaction.default_drag_action=e,t}_axisCoord(e,t){let n=Number(t);return Number.isFinite(n)?e&&e.scale===`log`?n>0?Math.log10(n):NaN:n:NaN}_axisValue(e,t){return e&&e.scale===`log`?10**t:t}_axisRange(e,t=this.view){let n=t?.ranges?.[e];if(Array.isArray(n))return[n[0],n[1]];if(e===`x`&&t)return[t.x0,t.x1];if(e===`y`&&t)return[t.y0,t.y1];let r=this._axis(e).range||[0,1];return[Number(r[0]),Number(r[1])]}_axisTicks(e,t){let n=this._axis(e),[r,i]=this._axisRange(e);if(Array.isArray(n.tick_values)){let e=Math.min(r,i),t=Math.max(r,i),a=n.tick_values.map(Number).filter(n=>Number.isFinite(n)&&n>=e&&n<=t);return{ticks:a,labels:a,step:a.length>1?Math.abs(a[1]-a[0]):1}}return n.kind===`time`?ee(r,i,t):n.kind===`category`?k(r,i,n.categories||[],t):n.scale===`log`?O(r,i,t):D(r,i,t)}_axisTickText(e,t,n){if(Array.isArray(e.tick_values)&&Array.isArray(e.tick_labels)){let n=e.tick_values.findIndex(e=>Number(e)===Number(t));if(n>=0&&n0?Math.max(1,Math.min(200,r)):t}_dataPx(e,t){let n=this._axisDim(e),r=this._axis(e),[i,a]=this._axisRange(e),o=this._axisCoord(r,i),s=this._axisCoord(r,a),c=this._axisCoord(r,t);return![o,s,c].every(Number.isFinite)||s===o?NaN:n===`x`?this.plot.x+(c-o)/(s-o)*this.plot.w:this.plot.y+(1-(c-o)/(s-o))*this.plot.h}_listen(e,t,n,r){return e.addEventListener(t,n,r),this._listeners.push({target:e,type:t,handler:n,options:r}),n}_interactionFlag(e,t=!1){let n=this.interaction&&this.interaction[e];return n===void 0?t:n===!0}_eventView(e=`view`){return{ranges:Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),x0:this.view.x0,x1:this.view.x1,y0:this.view.y0,y1:this.view.y1,source:e}}_dispatchChartEvent(e,t){!this.root||typeof CustomEvent!=`function`||this.root.dispatchEvent(new CustomEvent(`xy:${e}`,{detail:t,bubbles:!0,composed:!0}))}_emitViewChange(e=`view`,t={}){if(this._destroyed)return;let n=t.broadcast!==!1;this._pendingViewEvent={source:e,broadcast:n,axes:Array.isArray(t.axes)?[...t.axes]:[],phase:t.phase||`end`,interaction_id:t.interactionId??++this._interactionSeq},!this._viewEventRaf&&(this._viewEventRaf=requestAnimationFrame(()=>{this._viewEventRaf=null;let t=this._pendingViewEvent||{source:e,broadcast:n};this._pendingViewEvent=null;let r={...this._eventView(t.source),axes:t.axes,phase:t.phase,interaction_id:t.interaction_id};this._dispatchChartEvent(`view_change`,r),this.comm&&(t.phase===`end`||!this.comm.wantsViewChange||this.comm.wantsViewChange())&&this.comm.send({type:`view_change`,...r}),t.broadcast&&this._broadcastLinkedView(r)}))}_initLinkedCharts(){let e=this.interaction&&this.interaction.link_group;!e||typeof BroadcastChannel!=`function`||(this._linkAxes=this._axisPolicy(`link_axes`),this._linkChannel=new BroadcastChannel(`xy:${e}`),this._linkChannel.onmessage=e=>{let t=e.data||{};if(t.source===this._linkedSource)return;if(this._interactionFlag(`link_select`)&&t.selection){let e=t.selection;if(e.clear)this._clearSelection({broadcast:!1,dispatch:!1});else if(e.polygon)this._stateSelection={polygon:e.polygon.map(e=>[...e])},this._selectLocalPolygon(e.polygon,{dispatch:!1});else if(e.range){let{x0:t,x1:n,y0:r,y1:i}=e.range;[t,n,r,i].every(Number.isFinite)&&(this._stateSelection={range:{x0:t,x1:n,y0:r,y1:i}},this._selectLocal(t,n,r,i,{dispatch:!1}))}return}if(!t.view||t.source===this._linkedSource)return;let n=t.view.ranges||{},r=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]]));for(let e of this._linkAxes){let i=n[e]||(e===`x`?[t.view.x0,t.view.x1]:null)||(e===`y`?[t.view.y0,t.view.y1]:null);Array.isArray(i)&&i.length===2&&i.every(Number.isFinite)&&(r[e]=[Number(i[0]),Number(i[1])])}this._setView({ranges:r},{animate:!1,source:`linked`,phase:`end`,broadcast:!1})})}_broadcastLinkedView(e){if(!this._linkChannel)return;let t=(e.axes||[]).filter(e=>this._linkAxes.includes(e));if(!t.length)return;let n=Object.fromEntries(t.map(t=>[t,e.ranges[t]]));this._linkChannel.postMessage({source:this._linkedSource,view:{...e,axes:t,ranges:n}})}_broadcastLinkedSelection(e){!this._linkChannel||!this._interactionFlag(`link_select`)||this._linkChannel.postMessage({source:this._linkedSource,selection:e})}setView(e,t={}){return this._setView({ranges:e},{animate:t.animate===!0,source:`programmatic`,phase:`end`,interactionId:++this._interactionSeq,broadcast:t.broadcast===!0})}resetView(e={}){return this._resetView(e.animate!==!1,`reset`)}_applyClass(e,t){if(typeof t==`string`)for(let n of t.split(/\s+/).filter(Boolean))try{e.classList.add(n)}catch{}}_stylePropertyName(e){return e.startsWith(`--`)?e:e.replace(/_/g,`-`).replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}_stylePropertyValue(e,t){return typeof t==`number`?Number.isFinite(t)?e.startsWith(`--`)||st.has(e)?String(t):`${t}px`:null:String(t)}_applyStyle(e,t){if(!(!t||typeof t!=`object`||Array.isArray(t)))for(let[n,r]of Object.entries(t)){if(typeof n!=`string`||typeof r!=`string`&&typeof r!=`number`)continue;let t=this._stylePropertyName(n),i=this._stylePropertyValue(t,r);i!=null&&e.style.setProperty(t,i)}}_applySlot(e,t){e&&e.dataset&&(e.dataset.xySlot=t);let n=this.spec.dom;!n||typeof n!=`object`||(t===`root`&&this._applyClass(e,n.class_name),n.class_names&&typeof n.class_names==`object`&&this._applyClass(e,n.class_names[t]),t===`root`&&this._applyStyle(e,n.style),n.styles&&typeof n.styles==`object`&&this._applyStyle(e,n.styles[t]))}_slotStyleValue(e,t){let n=this.spec.dom?.styles,r=n&&typeof n==`object`?n[e]:null;if(!r||typeof r!=`object`||Array.isArray(r))return null;let i=this._stylePropertyName(t);for(let e of Object.keys(r))if(this._stylePropertyName(e)===i)return r[e];return null}_syncContainerSize(){this._destroyed||!(this.fluid||this.fluidH)||!this.root||this._queueResize(null,null,!0)}_queueResize(e=null,t=null,n=!1){this._destroyed||((e||t)&&(this._pendingResize={cssW:e,cssH:t}),n&&(this._resizeNeedsMeasure=!0),!this._resizeRaf&&(this._resizeRaf=requestAnimationFrame(()=>{this._resizeRaf=null;let e=this._pendingResize;if(this._pendingResize=null,this._resizeNeedsMeasure&&this.root){let t=this.root.getBoundingClientRect();(t.width||t.height)&&(e={cssW:t.width,cssH:t.height})}this._resizeNeedsMeasure=!1,e&&(e.cssW||e.cssH)&&this._resize(e.cssW,e.cssH)})))}_armVisibilityResizeWatch(){if(!(this.fluid||this.fluidH))return;let e=()=>{this._destroyed||this._syncContainerSize()};this._listen(window,`resize`,e),this._listen(window,`pageshow`,e),this._listen(document,`visibilitychange`,e),typeof IntersectionObserver<`u`&&(this._io=new IntersectionObserver(t=>{t.some(e=>e.isIntersecting||e.intersectionRatio>0)&&e()}),this._io.observe(this.root))}_markStateValue(e,t,n=null){let r=this.markStyle&&typeof this.markStyle==`object`?this.markStyle[e]:null;return!r||typeof r!=`object`||Array.isArray(r)?n:Object.prototype.hasOwnProperty.call(r,t)?r[t]:n}_markStateNumber(e,t,n){let r=this._markStateValue(e,t,n);return typeof r!=`number`||!Number.isFinite(r)?n:r}_markStatePaint(e,t,n){let r=this._markStateValue(e,t,n);return typeof r==`string`?r:n}_armDprWatch(){if(typeof window.matchMedia!=`function`)return;this._dprMq?.removeEventListener?.(`change`,this._onDprChange);let e=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);this._onDprChange=()=>{this._destroyed||(this._resize(this.size.w,this.size.h),this._armDprWatch())},e.addEventListener?.(`change`,this._onDprChange,{once:!0}),this._dprMq=e}_initContextLossRecovery(){this._listen(this.canvas,`webglcontextlost`,e=>{if(e.preventDefault(),this._destroyed)return;let t=this.canvas.dataset.xyCtx===`released`;if(this._glLost&&!t)return;this._glLost=!0,this._ctxLostPending=!1,t||(this.canvas.dataset.xyCtx=`lost`),Z._announceLive(),this._contextLossCount+=1,this._contextRecoveryError=null,this.root.dataset.xyContextState=`lost`,this.seq+=1,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._wheelZoomRaf&&cancelAnimationFrame(this._wheelZoomRaf),this._wheelZoomRaf=null,this._pendingWheelZoom=null,clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null,this._wheelGesture=null,this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf),this._dataAnimRaf=null,this._dataAnim&&this._emitAnimationLifecycle?.(`end`,this._dataAnim.phase,{cancelled:!0}),this._dataAnim=null,this._transitionOldTraces=null,this._transitionView=null,this.view0&&(this.view={...this.view0}),this._cancelViewAnimation(),clearTimeout(this._viewTimer),this._viewTimer=null,clearTimeout(this._rebinTimer),this._rebinTimer=null,this._viewRequestBurstStart=null,this._dispatchChartEvent(`context_lost`,{loss_count:this._contextLossCount});let n=typeof document>`u`||!document.visibilityState||document.visibilityState===`visible`;!t&&this._ctxVisible&&n&&setTimeout(()=>{!this._destroyed&&this._glLost&&this.canvas.dataset.xyCtx===`lost`&&this._ctxVisible&&this._recoverContext()},0),t&&this._ctxRecoverRequested&&!this._destroyed&&this._ctxVisible&&(this._ctxRecoverRequested=!1,setTimeout(()=>{!this._destroyed&&this._glLost&&this._ctxVisible&&this._recoverContext()},0))}),this._listen(this.canvas,`webglcontextrestored`,()=>{if(!(this._destroyed||this._contextRecoveryError)){this._lutCache.clear(),this.pickFbo=null,this.pickTex=null;try{this._initGl(this._payload),this._glLost=!1,this._drawNow(),this._assertContextFrameReady(`restore`)}catch(e){if(this._glLost=!0,this.canvas.dataset.xyCtx=`lost`,this.root.dataset.xyContextState=`lost`,!this.gl||this.gl.isContextLost()||String(e&&e.message||e).includes(`shader compile: null`)||String(e&&e.message||e).startsWith(`WebGL error `)){this._contextRecoveryError=null,this._scheduleContextRecovery();return}this._contextRecoveryError=e,this.root.dataset.xyContextState=`failed`;try{this._destroyGlResources()}catch{}this.gl=null,this._dispatchChartEvent(`context_restore_failed`,{loss_count:this._contextLossCount,message:e instanceof Error?e.message:String(e)}),this.root.textContent=`xy: WebGL2 context could not be restored.`;return}this._contextRestoreCount+=1,this._contextRecoveryError=null,this._ctxRecoveryDelay=0,this.canvas.dataset.xyCtx=`live`,this.root.dataset.xyContextState=`ready`,Z._announceLive(),this._scheduleViewRequest(this.view,{delay:0}),this._dropContextSnapshot(),this._dispatchChartEvent(`context_restored`,{loss_count:this._contextLossCount,restore_count:this._contextRestoreCount})}})}_releaseContext(){if(this._destroyed||!this.gl||this._glLost||this.gl.isContextLost())return!1;let e=this.gl.getExtension(`WEBGL_lose_context`);return e?(this._snapshotBeforeRelease(),this._ctxReleasedExt=e,this._ctxReleases+=1,this._glLost=!0,this._ctxLostPending=!0,this.canvas.dataset.xyCtx=`released`,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,e.loseContext(),Z._announceLive(),!0):!1}_snapshotBeforeRelease(){try{this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._rafKeepPick=!0,this._drawNow();let e=this._ctxSnapshot;e||(e=this._ctxSnapshot=document.createElement(`canvas`),e.dataset.xyCtxSnapshot=``),e.width=this.canvas.width,e.height=this.canvas.height,e.style.cssText=this.canvas.style.cssText,e.style.pointerEvents=`none`;let t=this.gl,n=this.canvas.width,r=this.canvas.height;t.finish();let i=new Uint8Array(n*r*4);t.readPixels(0,0,n,r,t.RGBA,t.UNSIGNED_BYTE,i);let a=e.getContext(`2d`),o=a.createImageData(n,r),s=o.data;for(let e=0;e0&&e<255){let t=255/e;n=Math.min(255,Math.round(n*t)),r=Math.min(255,Math.round(r*t)),a=Math.min(255,Math.round(a*t))}s[o]=n,s[o+1]=r,s[o+2]=a,s[o+3]=e}}a.putImageData(o,0,0),this.canvas.before(e),this.canvas.style.visibility=`hidden`}catch{this._dropContextSnapshot()}}_dropContextSnapshot(){this.canvas.style.visibility=``,this._ctxSnapshot&&this._ctxSnapshot.remove(),this._ctxSnapshot=null}_recoverContext(){if(!(this._destroyed||!this._glLost)){if(this._ctxReleasedExt&&this._ctxLostPending){this._ctxRecoverRequested=!0;return}if(this._ctxRecoveries+=1,this._ctxReleasedExt){let e=this._ctxReleasedExt;this._ctxReleasedExt=null;try{Z.reserve(this),e.restoreContext();return}catch{Z.cancel(this)}}this._rebuildEvictedContext()}}_assertContextFrameReady(e){if(!this.gl||(this.gl.finish(),this.gl.isContextLost()))throw Error(`context lost during ${e} draw`);let t=this.gl.getError();if(t!==this.gl.NO_ERROR)throw Error(`WebGL error ${t} during ${e} draw`)}_scheduleContextRecovery(){if(this._ctxRecoveryTimer||this._destroyed||!this._ctxVisible||typeof document<`u`&&document.visibilityState&&document.visibilityState!==`visible`)return;let e=this._ctxRecoveryDelay||50;this._ctxRecoveryDelay=Math.min(1e3,e*2),this._ctxRecoveryTimer=setTimeout(()=>{this._ctxRecoveryTimer=null,this._glLost&&!this._destroyed&&this._ctxVisible&&this._recoverContext()},e)}_rebuildEvictedContext(){if(this.gl&&!this.gl.isContextLost())try{this.gl.getExtension(`WEBGL_lose_context`)?.loseContext()}catch{}let e=this.canvas.cloneNode(!1);for(let t of this._listeners)t.target===this.canvas&&(this.canvas.removeEventListener(t.type,t.handler,t.options),e.addEventListener(t.type,t.handler,t.options),t.target=e);this.canvas.replaceWith(e),this.canvas=e,this._glLost=!1,this._lutCache.clear(),this.pickFbo=null,this.pickTex=null;try{this._initGl(this._payload),this._glLost=!1,this._drawNow(),this._assertContextFrameReady(`rebuild`)}catch{this._glLost=!0,this.canvas.dataset.xyCtx=`lost`,this._scheduleContextRecovery();return}this._ctxRecoveryDelay=0,this.canvas.dataset.xyCtx=`live`,Z._announceLive(),this._scheduleViewRequest(this.view,{delay:0}),this._dropContextSnapshot()}_armContextVisibilityWatch(){if(this._listen(this.root,`pointerenter`,()=>{this._glLost&&!this._destroyed&&this._recoverContext()}),typeof document<`u`&&this._listen(document,`visibilitychange`,()=>{if(document.visibilityState===`hidden`){Z.scheduleHiddenReleases();return}Z.cancelHiddenReleases(),document.visibilityState===`visible`&&this._ctxVisible&&this._glLost&&!this._destroyed&&this._recoverContext()}),typeof IntersectionObserver>`u`){this._ctxVisible=!0;return}this._ctxIo=new IntersectionObserver(e=>{let t=e[e.length-1];this._ctxVisible=t.isIntersecting||t.intersectionRatio>0,this._ctxVisible?(this._ctxSeenSeq=Z.seq++,this._glLost&&!this._destroyed&&this._recoverContext(),this._healStaleTheme()&&this.draw()):this._destroyed||Z._rebalance()},{rootMargin:`25% 0px 25% 0px`}),this._ctxIo.observe(this.root)}_resize(e,t){let n=this.fluid&&e?Math.max(120,Math.round(e)):this.size.w,r=this.fluidH&&t?Math.max(120,Math.round(t)):this.size.h,i=window.devicePixelRatio||1;if(n===this.size.w&&r===this.size.h&&i===this.dpr)return;this.dpr=i,this.size.w=n,this.size.h=r,this._layout();let a=this.plot;this.root.style.setProperty(`--xy-legend-max-width`,Math.max(40,a.w-12)+`px`),this.root.style.setProperty(`--xy-legend-max-height`,Math.max(40,a.h-12)+`px`),this.canvas.style.left=a.x+`px`,this.canvas.style.top=a.y+`px`,this.canvas.style.width=a.w+`px`,this.canvas.style.height=a.h+`px`,this.canvas.width=a.w*this.dpr,this.canvas.height=a.h*this.dpr,this.chrome.style.width=this.size.w+`px`,this.chrome.style.height=this.size.h+`px`,this.chrome.width=this.size.w*this.dpr,this.chrome.height=this.size.h*this.dpr,this.overlay.style.width=this.size.w+`px`,this.overlay.style.height=this.size.h+`px`,this.overlay.width=this.size.w*this.dpr,this.overlay.height=this.size.h*this.dpr;for(let e of this._legends||[])this._positionLegend(e,e.dataset.xyLegendLoc||`upper right`);this._positionReductionBadges(),this._positionColorbar(),this._fitModebar(),this._layoutAxisBands(),this._pickDirty=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._drawNow(),this._scheduleViewRequest()}_buildDom(e){let t=this.spec,n=document.createElement(`div`);n.className=`xy`,n.style.cssText=`position:relative;width:${this.fluid?`100%`:this.size.w+`px`};height:${this.fluidH?`100%`:this.size.h+`px`};--xy-legend-max-width:${Math.max(40,this.plot.w-12)}px;--xy-legend-max-height:${Math.max(40,this.plot.h-12)}px;`+(this.fluidH?`min-height:120px;`:``)+`font:12px system-ui,sans-serif;user-select:none;`,this._applySlot(n,`root`),(n.style.background||n.style.backgroundColor)&&(n.dataset.xyOwnBg=``),e.appendChild(n),this.root=n,w(n);let r;do r=`xy-a11y-${++ot}`;while(document.getElementById(`${r}-summary`)||document.getElementById(`${r}-live`));if(n.setAttribute(`role`,`region`),n.setAttribute(`aria-label`,t.title?`Chart: ${t.title}`:`Interactive chart`),this.a11ySummary=document.createElement(`div`),this.a11ySummary.id=`${r}-summary`,this.a11ySummary.style.cssText=X,n.setAttribute(`aria-describedby`,this.a11ySummary.id),n.appendChild(this.a11ySummary),this.a11yLive=document.createElement(`div`),this.a11yLive.id=`${r}-live`,this.a11yLive.setAttribute(`role`,`status`),this.a11yLive.setAttribute(`aria-live`,`polite`),this.a11yLive.setAttribute(`aria-atomic`,`true`),this.a11yLive.style.cssText=X,n.appendChild(this.a11yLive),t.title){let e=document.createElement(`div`);e.textContent=t.title,e.style.cssText=`position:absolute;top:6px;left:0;right:0;`,this._applySlot(e,`title`),n.appendChild(e)}this.chrome=document.createElement(`canvas`),this.chrome.style.cssText=`position:absolute;inset:0;pointer-events:none;`,this._applySlot(this.chrome,`chrome`),n.appendChild(this.chrome),this.canvas=document.createElement(`canvas`),this.canvas.style.cssText=`position:absolute;left:${this.plot.x}px;top:${this.plot.y}px;width:${this.plot.w}px;height:${this.plot.h}px;touch-action:none;`,this._applySlot(this.canvas,`canvas`),this.canvas.tabIndex=0,this.canvas.setAttribute(`role`,`img`),this.canvas.setAttribute(`aria-describedby`,this.a11ySummary.id),n.appendChild(this.canvas),this.overlay=document.createElement(`canvas`),this.overlay.style.cssText=`position:absolute;inset:0;pointer-events:none;`,n.appendChild(this.overlay),this.labels=document.createElement(`div`),this.labels.style.cssText=`position:absolute;inset:0;pointer-events:none;`,this._applySlot(this.labels,`labels`),n.appendChild(this.labels),this.tooltip=document.createElement(`div`),this.tooltip.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:5;`,this._applySlot(this.tooltip,`tooltip`),this.tooltip.setAttribute(`aria-hidden`,`true`),n.appendChild(this.tooltip),this._buildLegend(n),this._buildColorbar(n),this._buildReductionBadges(n)}_a11yAxisSummary(e,t){let n=this._axis(e),r=n.label?`${t} axis (${n.label})`:`${t} axis`;if(n.kind===`category`){let e=Array.isArray(n.categories)?n.categories:[];if(!e.length)return`${r} uses categories.`;let t=e.slice(0,6).map(e=>String(e)),i=e.length-t.length,a=i>0?`, and ${i} more`:``;return`${r} has ${e.length} categories: ${t.join(`, `)}${a}.`}let i=n.range||[];return i.length<2?null:`${r} ranges from ${N(i[0],n.kind)} to ${N(i[1],n.kind)}.`}_a11ySummaryText(){let e=Array.isArray(this.spec.traces)?this.spec.traces:[],t=[this.spec.title?`${this.spec.title}.`:`Interactive chart.`];t.push(`${e.length} data series.`);let n=e.map(e=>e&&e.name).filter(Boolean).slice(0,6);n.length&&t.push(`Series: ${n.join(`, `)}.`);let r=this._a11yAxisSummary(`x`,`X`),i=this._a11yAxisSummary(`y`,`Y`);return r&&t.push(r),i&&t.push(i),t.join(` `)}_initA11y(){if(!this.a11ySummary||!this.canvas)return;this.a11ySummary.textContent=this._a11ySummaryText();let e=this._pickable?` Use Arrow keys to explore data points in series data order; Home and End jump to the first and last point; Escape closes the readout.`:``;this.canvas.setAttribute(`aria-label`,`Plot area.${e}`)}_compactInt(e){let t=Number(e);return Number.isFinite(t)?Math.round(t).toLocaleString():`0`}_positionReductionBadges(){if(!this._badges)return;let e=this.size.w-(this.plot.x+this.plot.w),t=this.size.h-(this.plot.y+this.plot.h);this._badges.style.right=`${e+6}px`,this._badges.style.bottom=`${t+6}px`}_reductionBadgeItems(){let e=[],t=this.gpuTraces&&this.gpuTraces.length?this.gpuTraces:this.spec.traces||[];for(let n of t){let t=n.trace||n;if(t.tier!==`density`||!t.density)continue;let r=n.sampleOverlay&&n.sampleOverlay.sample?n.sampleOverlay.sample:t.density.sample;r&&Number(r.n)>0&&e.push(`sampled ${this._compactInt(r.n)} of ${this._compactInt(r.visible)}`),n._sampleRebinned&&e.push(`zoom re-binned from sample`),t.density.channels_dropped&&e.push(`aggregated channels`)}return e}_refreshReductionBadges(){if(!this._badges)return;let e=this._reductionBadgeItems();this._badges.textContent=``,this._badges.hidden=e.length===0;for(let t of e){let e=document.createElement(`div`);e.textContent=t,this._applySlot(e,`badge_item`),this._badges.appendChild(e)}this._positionReductionBadges()}_buildReductionBadges(e){let t=this._reductionBadgeItems(),n=(this.spec.traces||[]).some(e=>e.tier===`density`);if(!t.length&&!n)return;let r=document.createElement(`div`);r.style.cssText=`position:absolute;display:flex;flex-direction:column;align-items:flex-end;pointer-events:none;z-index:4;`,this._applySlot(r,`badge`),e.appendChild(r),this._badges=r,this._refreshReductionBadges()}_buildLegend(e){let t=this.spec;this._legends=[];let n=[];if(t.show_legend!==!1){for(let e of t.traces)if(e.tier===`density`)n.push({swatch:`gradient`,cmap:e.density.colormap,name:e.name||`density`});else if(e.color&&e.color.mode===`categorical`)e.color.categories.forEach((t,r)=>n.push({swatch:e.color.palette[r],name:t,symbol:e.kind===`scatter`?e.style?.symbol||`circle`:null,style:e.style||{}}));else if(e.color&&e.color.mode===`continuous`)n.push({swatch:`gradient`,cmap:e.color.colormap,name:e.name||`value`});else if(e.name){let t=e.color&&e.color.color||e.style&&e.style.color,r=[`line`,`segments`,`step`,`stairs`,`errorbar`].includes(e.kind);n.push({swatch:t,name:e.name,symbol:e.kind===`scatter`?e.style?.symbol||`circle`:null,line:r,style:e.style||{}})}n.length&&this._legendBox(e,n,t.legend||{})}for(let n of t.extra_legends||[]){let t=(n.items||[]).map(e=>({swatch:e.style&&e.style.color,name:e.name,symbol:e.kind===`scatter`?e.style?.symbol||`circle`:null,line:[`line`,`segments`,`step`,`stairs`,`errorbar`].includes(e.kind),style:e.style||{}}));t.length&&this._legendBox(e,t,n)}}_legendBox(e,t,n){let r=document.createElement(`div`),i=n.loc||`upper right`,a=Math.max(1,Number(n.ncols)||1),o=a>1;if(r.style.cssText=`position:absolute;display:grid;grid-template-columns:repeat(${o?a:1},max-content);overflow:auto;`,r.dataset.xyLegendLoc=i,this._positionLegend(r,i),this._applySlot(r,`legend`),n.title){let e=document.createElement(`div`);e.textContent=String(n.title),e.style.fontWeight=`600`,e.style.gridColumn=`1 / span ${o?a:1}`,r.appendChild(e)}for(let e of t){let t=document.createElement(`div`);this._applySlot(t,`legend_item`);let n=document.createElement(`span`);n.style.display=`inline-block`,n.style.verticalAlign=`-1px`;let i=e.swatch;if(e.swatch===`gradient`)i=`linear-gradient(90deg,${h(e.cmap).map(e=>`rgb(${e[0]},${e[1]},${e[2]})`).join(`,`)})`,n.style.background=i;else if(e.symbol){let t=`http://www.w3.org/2000/svg`,r=document.createElementNS(t,`svg`);r.setAttribute(`viewBox`,`0 0 18 14`),r.setAttribute(`width`,`18`),r.setAttribute(`height`,`14`);let a=document.createElementNS(t,`path`),o={square:`M4.5 2.5h9v9h-9z`,diamond:`M9 2l5 5-5 5-5-5z`,thin_diamond:`M9 2l3 5-3 5-3-5z`,triangle:`M9 2l-5 10h10z`,triangle_down:`M9 12L4 2h10z`,triangle_left:`M4 7L14 2v10z`,triangle_right:`M14 7L4 2v10z`,plus_line:`M9 2v10M4 7h10`,x_line:`M5 3l8 8M13 3l-8 8`,cross:`M7.5 2h3v3.5H14v3h-3.5V12h-3V8.5H4v-3h3.5z`,x:`M5.5 2L9 5.5 12.5 2 14 3.5 10.5 7 14 10.5 12.5 12 9 8.5 5.5 12 4 10.5 7.5 7 4 3.5z`,pentagon:`M9 2.5L13.28 5.61 11.65 10.64H6.35L4.72 5.61z`,hexagon:`M9 2L13.3 4.5v5L9 12l-4.3-2.5v-5z`,star:`M9 2l1.5 3.1 3.5.5-2.5 2.5.6 3.5L9 10l-3.1 1.6.6-3.5L4 5.6l3.5-.5z`},s=T(this.root,i);e.symbol===`circle`||e.symbol===`point`||e.symbol===`pixel`?e.symbol===`pixel`?a.setAttribute(`d`,`M8.5 6.5h1v1h-1z`):a.setAttribute(`d`,`M9 ${e.symbol===`point`?4.75:2.5}a${e.symbol===`point`?2.25:4.5} ${e.symbol===`point`?2.25:4.5} 0 1 0 0 ${e.symbol===`point`?4.5:9}a${e.symbol===`point`?2.25:4.5} ${e.symbol===`point`?2.25:4.5} 0 1 0 0 -${e.symbol===`point`?4.5:9}`):a.setAttribute(`d`,o[e.symbol]||o.square),a.setAttribute(`fill`,e.symbol.endsWith(`_line`)?`none`:s),a.setAttribute(`stroke`,s),a.setAttribute(`stroke-width`,String(e.style?.stroke_width||1)),r.appendChild(a),n.appendChild(r),n.style.width=`18px`,n.style.height=`14px`}else if(e.line){let t=`http://www.w3.org/2000/svg`,r=document.createElementNS(t,`svg`);r.setAttribute(`viewBox`,`0 0 22 12`),r.setAttribute(`width`,`22`),r.setAttribute(`height`,`12`);let a=document.createElementNS(t,`line`);a.setAttribute(`x1`,`1`),a.setAttribute(`y1`,`6`),a.setAttribute(`x2`,`21`),a.setAttribute(`y2`,`6`),a.setAttribute(`stroke`,T(this.root,i)),a.setAttribute(`stroke-width`,String(e.style?.width??1.5)),e.style?.dash&&e.style.dash.length&&a.setAttribute(`stroke-dasharray`,e.style.dash.join(` `)),r.appendChild(a),n.appendChild(r),n.style.width=`22px`,n.style.height=`12px`}else n.style.background=T(this.root,i);this._applySlot(n,`legend_swatch`),t.appendChild(n),t.appendChild(document.createTextNode(e.name)),r.appendChild(t)}return e.appendChild(r),this._legends.push(r),r}_positionLegend(e,t){if(!e)return;let n=this.size.w-(this.plot.x+this.plot.w),r=t.includes(`left`)?`left`:t.includes(`right`)?`right`:`center`,i=t.includes(`upper`)?`upper`:t.includes(`lower`)?`lower`:`center`,a=r===`left`?this.plot.x+6:r===`center`?this.plot.x+this.plot.w/2:null,o=r===`right`?n+6:null,s=i===`upper`?this.plot.y+6:i===`center`?this.plot.y+this.plot.h/2:null,c=i===`lower`?this.size.h-(this.plot.y+this.plot.h)+6:null;e.style.setProperty(`--xy-legend-left`,a==null?`auto`:a+`px`),e.style.setProperty(`--xy-legend-right`,o==null?`auto`:o+`px`),e.style.setProperty(`--xy-legend-top`,s==null?`auto`:s+`px`),e.style.setProperty(`--xy-legend-bottom`,c==null?`auto`:c+`px`);let l=r===`center`?`-50%`:`0`,u=i===`center`?`-50%`:`0`;e.style.setProperty(`--xy-legend-transform`,`translate(${l},${u})`)}_buildColorbar(e){let t=this.spec.colorbar;if(!t)return;let n=document.createElement(`div`),r=t.orientation===`horizontal`;n.style.cssText=`position:absolute;pointer-events:none;z-index:4;`,this._applySlot(n,`colorbar`);let i=document.createElement(`div`),a=Math.max(0,Number(t.levels)||0),o;if(a>0){let e=g(t.colormap||`viridis`),n=[];for(let t=0;t`rgb(${e[0]},${e[1]},${e[2]})`).join(`,`)})`}i.style.cssText=r?`position:absolute;inset:0 0 auto 0;height:${Y}px;`:`position:absolute;inset:0 auto 0 0;width:${Y}px;`,i.style.setProperty(`--xy-colorbar-gradient`,o),this._applySlot(i,`colorbar_bar`),n.appendChild(i);let s=t.domain||[0,1],c=Number(s[0]),l=Number(s[1]),u=l-c||1,d=D(c,l,8),f=Array.isArray(t.ticks),p=f?t.ticks:d.ticks,m=d.step;for(let e of p){let t=Number(e);if(!Number.isFinite(t)||tMath.max(c,l))continue;let i=document.createElement(`span`);i.textContent=f?re(t):M(t,m);let a=(t-c)/u;i.style.cssText=r?`position:absolute;left:${100*a}%;top:20px;transform:translateX(-50%);white-space:nowrap;`:`position:absolute;left:23px;top:${100*(1-a)}%;transform:translateY(-50%);white-space:nowrap;`,this._applySlot(i,`colorbar_tick`),n.appendChild(i)}if(t.label){let e=document.createElement(`span`);e.textContent=String(t.label),e.style.cssText=r?`position:absolute;left:50%;top:36px;transform:translateX(-50%);white-space:nowrap;`:`position:absolute;left:58px;top:50%;writing-mode:vertical-rl;transform:translateY(-50%) rotate(180deg);white-space:nowrap;`,this._applySlot(e,`colorbar_title`),n.appendChild(e)}n.title=`${t.label?t.label+`: `:``}${s[0]} – ${s[1]}`,e.appendChild(n),this._colorbar=n,this._colorbarHorizontal=r,this._positionColorbar()}_positionColorbar(){if(!this._colorbar)return;let e=this._colorbarHorizontal,t=!e&&this._compactVerticalColorbar,n=t?at:it;this._colorbar.style.left=(e?this.plot.x:this.plot.x+this.plot.w+this._rightAxisRoom+n)+`px`,this._colorbar.style.top=(e?this.plot.y+this.plot.h+(this._bottomAxisRoom||8):this.plot.y)+`px`,this._colorbar.style.width=(e?this.plot.w:t?Y:66)+`px`,this._colorbar.style.height=(e?50:Math.max(24,this.plot.h))+`px`,this._colorbar.dataset.xyCompact=t?`true`:`false`;for(let e of this._colorbar.querySelectorAll(`[data-xy-slot="colorbar_tick"], [data-xy-slot="colorbar_title"]`))e.hidden=t}_initGl(e){let t=window.devicePixelRatio||1;this.dpr=t,this.canvas.width=this.plot.w*t,this.canvas.height=this.plot.h*t,this.chrome.width=this.size.w*t,this.chrome.height=this.size.h*t,this.chrome.style.width=this.size.w+`px`,this.chrome.style.height=this.size.h+`px`,this.overlay.width=this.size.w*t,this.overlay.height=this.size.h*t,this.overlay.style.width=this.size.w+`px`,this.overlay.style.height=this.size.h+`px`,Z.reserve(this);let n=this.canvas.getContext(`webgl2`,{antialias:!1,premultipliedAlpha:!0,alpha:!0});if(!n)throw Z.cancel(this),Error(`webgl2 unavailable`);this.gl=n,Z.acquired(this),n.enable(n.BLEND),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA),this._progCache=new Map,this._glPrograms=this._progCache,this.quad=n.createBuffer(),this.quad._fcId=++this._bufSeq,n.bindBuffer(n.ARRAY_BUFFER,this.quad),n.bufferData(n.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,1,1]),n.STATIC_DRAW),this.quadVao=n.createVertexArray(),n.bindVertexArray(this.quadVao),n.enableVertexAttribArray(P.a_corner),n.vertexAttribPointer(P.a_corner,2,n.FLOAT,!1,0,0),n.vertexAttribDivisor(P.a_corner,0),n.bindVertexArray(null),this.gpuTraces=this.spec.traces.map(t=>this._buildTrace(e,t)),this._updatePickable()}_updatePickable(){this._pickable=this.gpuTraces.some(e=>q(e.trace.kind).pointPick&&(e.tier!==`density`||e.drill)),this._pickable&&!this.pickFbo&&this._initPickTarget(),this._syncModebarSelect?.()}_prog(e,t,n){let r=this._progCache.get(e);return r||(r=le(this.gl,t,n),this._progCache.set(e,r)),r}get pointProg(){return this._prog(`point`,ue,de)}get pointSimpleProg(){return this._prog(`point-simple`,fe,pe)}get lineProg(){return this._prog(`line`,ye,be)}get segmentProg(){return this._prog(`segment`,xe,Se)}get meshProg(){return this._prog(`mesh`,Ce,we)}get areaProg(){return this._prog(`area`,Ee,De)}get rectProg(){return this._prog(`rect`,Oe,Ae)}get barProg(){return this._prog(`bar`,ke,Ae)}get pickProg(){return this._prog(`pick`,me,he)}get densityProg(){return this._prog(`density`,ge,_e)}get heatmapProg(){return this._prog(`heatmap`,ge,ve)}_lut(e){if(this._lutCache.has(e))return this._lutCache.get(e);let t=this.gl,n=t.createTexture();return t.bindTexture(t.TEXTURE_2D,n),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,256,1,0,t.RGBA,t.UNSIGNED_BYTE,g(e)),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),this._lutCache.set(e,n),n}_paletteLut(e){let t=`pal:`+e.join(`,`);if(this._lutCache.has(t))return this._lutCache.get(t);let n=this.gl,r=new Uint8Array(256*4);for(let t=0;t<256;t++){let n=y(e[t%e.length]);r[t*4]=n[0]*255,r[t*4+1]=n[1]*255,r[t*4+2]=n[2]*255,r[t*4+3]=255}let i=n.createTexture();return n.bindTexture(n.TEXTURE_2D,i),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,256,1,0,n.RGBA,n.UNSIGNED_BYTE,r),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.NEAREST),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.NEAREST),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),this._lutCache.set(t,i),i}_buildTrace(e,t){this.gl;let n={trace:t,tier:t.tier,color:[.3,.47,.66,1],xAxis:typeof t.x_axis==`string`?t.x_axis:`x`,yAxis:typeof t.y_axis==`string`?t.y_axis:`y`};if(t.tier===`density`){let r=t.density,i=this.spec.columns[r.buf],a=this._columnView(e,i),o=r.enc===`log-u8`?Fe(a,r.max):a;return n.densityNormMax=r.max,n.density={w:r.w,h:r.h,max:r.max,normMax:r.max,colormap:r.colormap,color:r.color?b(this.root,r.color,[.3,.47,.66,1]):null,xRange:r.x_range,yRange:r.y_range,grid:Ie(o),tex:this._uploadGrid(o,r.w,r.h,r.max),lut:this._lut(r.colormap)},n.sampleOverlay=this._buildDensitySample(t,r.sample,e),n._shownDensity=n.density,B(this,n,n.density),n}if(q(t.kind).build(this,n,t,e),t.keys&&Number.isInteger(t.keys.lo)&&Number.isInteger(t.keys.hi)){let r=this._columnView(e,this.spec.columns[t.keys.lo]),i=this._columnView(e,this.spec.columns[t.keys.hi]),a=Math.min(n.n||0,r.length,i.length);n._transitionKeys=Array(a),n._transitionKeyIndex=new Map;for(let e=0;et.channels&&t.channels[e],a=Number(t.style&&t.style.artist_alpha);if(i(`opacity`)||i(`artist_alpha`)||i(r)||i(`symbol`)||Number.isFinite(a)){let t=new Float32Array(e.n*4);for(let n=0;n{let s=i(r);if(!s)return;let c=this._columnView(n,this.spec.columns[s.buf]);for(let n=0;n1?t[n*r+1]:t[n*r])*this.dpr;e.radiusBuf=this._upload(i)}t.stroke&&t.stroke.mode===`direct_rgba`&&(e.strokeBuf=this._upload(this._columnView(n,this.spec.columns[t.stroke.buf])))}_buildScatterMark(e,t,n){this._buildXY(e,t,n),e.colorMode=0,e.color=b(this.root,t.color&&t.color.color,[.3,.47,.66,1]),t.color&&t.color.mode===`continuous`?(e.colorMode=1,e._cpu.color=this._columnView(n,this.spec.columns[t.color.buf]),e.cBuf=this._upload(e._cpu.color),e.lut=this._lut(t.color.colormap)):t.color&&t.color.mode===`categorical`?(e.colorMode=2,e._cpu.color=this._columnView(n,this.spec.columns[t.color.buf]),e.cBuf=this._upload(e._cpu.color),e.lut=this._paletteLut(t.color.palette)):t.color&&t.color.mode===`direct_rgba`&&(e.colorMode=3,e._cpu.rgba=this._columnView(n,this.spec.columns[t.color.buf]),e.rgbaBuf=this._upload(e._cpu.rgba)),e.sizeMode=0,e.size=t.size&&t.size.size||4,e.sizeRange=[2,18],t.size&&t.size.mode===`continuous`&&(e.sizeMode=1,e._cpu.size=this._columnView(n,this.spec.columns[t.size.buf]),e.sBuf=this._upload(e._cpu.size),e.sizeRange=t.size.range_px),this._buildInstanceStyleChannels(e,t,n,`stroke_width`),this._pointMarkStyle(e,t)}_pointMarkStyle(e,t){let n=t.style||{};e.symbol={circle:0,square:1,diamond:2,triangle:3,cross:4,hexagon:5,pentagon:6,star:7,triangle_down:8,triangle_left:9,triangle_right:10,x:11,point:12,pixel:13,thin_diamond:14,plus_line:15,x_line:16}[n.symbol]||0,e.pointStrokeWidth=Number(n.stroke_width)||0,e.pointStrokeFace=!n.stroke&&(!t.stroke||t.stroke.mode===`match_fill`),e.pointStroke=n.stroke?b(this.root,n.stroke,[e.color[0],e.color[1],e.color[2],1]):null}_sampleTraceSpec(e,t){return{id:e.id,kind:`scatter`,name:e.name,style:t.style||e.style||{},tier:`sampled`,x:t.x&&t.x.col,y:t.y&&t.y.col,x_axis:e.x_axis,y_axis:e.y_axis,color:t.color,size:t.size,stroke:t.stroke,channels:t.channels}}_buildDensitySample(e,t,n){if(!t||!t.x||!t.y||t.x.col===void 0||t.y.col===void 0)return null;let r=this._sampleTraceSpec(e,t),i={trace:r,tier:`sampled`,xAxis:typeof e.x_axis==`string`?e.x_axis:`x`,yAxis:typeof e.y_axis==`string`?e.y_axis:`y`};return this._buildScatterMark(i,r,n),i.win={x0:t.x_range[0],x1:t.x_range[1],y0:t.y_range[0],y1:t.y_range[1]},i.sample={n:t.n,visible:t.visible},i}_destroyDensitySample(e){let t=e&&e.sampleOverlay;if(!(!t||!this.gl)){for(let e of[t.xBuf,t.yBuf,t.cBuf,t.rgbaBuf,t.sBuf,t.styleBuf,t.strokeBuf,t.selBuf,t.dBuf])e&&this.gl.deleteBuffer(e);e.sampleOverlay=null}}_applyDensitySample(e,t,n){if(this._destroyDensitySample(e),!t||!t.x||!t.y||t.x.buf===void 0||t.y.buf===void 0){this._refreshReductionBadges();return}let r=this.gl,i={id:e.trace.id,kind:`scatter`,name:e.trace.name,style:t.style||e.trace.style||{},tier:`sampled`,x_axis:e.trace.x_axis,y_axis:e.trace.y_axis,color:t.color,size:t.size,stroke:t.stroke,channels:t.channels},a={trace:i,tier:`sampled`,xAxis:e.xAxis,yAxis:e.yAxis,xBuf:r.createBuffer(),yBuf:r.createBuffer(),xMeta:{offset:t.x.offset,scale:t.x.scale},yMeta:{offset:t.y.offset,scale:t.y.scale},n:Math.min(t.x.len,t.y.len),win:{x0:t.x_range[0],x1:t.x_range[1],y0:t.y_range[0],y1:t.y_range[1]},sample:{n:t.n,visible:t.visible},selActive:!1,colorMode:0,color:b(this.root,t.color&&t.color.color,[.3,.47,.66,1]),sizeMode:0,size:t.size&&t.size.size||4,sizeRange:[2,18]};if(r.bindBuffer(r.ARRAY_BUFFER,a.xBuf),r.bufferData(r.ARRAY_BUFFER,this._asF32(n[t.x.buf]),r.STATIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,a.yBuf),r.bufferData(r.ARRAY_BUFFER,this._asF32(n[t.y.buf]),r.STATIC_DRAW),t.color&&t.color.buf!==void 0){a.colorMode=t.color.mode===`continuous`?1:t.color.mode===`categorical`?2:3;let e=t.color.dtype===`u8`?this._asU8(n[t.color.buf]):this._asF32(n[t.color.buf]),i=a.colorMode===3?`rgbaBuf`:`cBuf`;a[i]=r.createBuffer(),a[i]._fcType=e instanceof Uint8Array?r.UNSIGNED_BYTE:r.FLOAT,r.bindBuffer(r.ARRAY_BUFFER,a[i]),r.bufferData(r.ARRAY_BUFFER,e,r.STATIC_DRAW),a.colorMode!==3&&(a.lut=t.color.mode===`continuous`?this._lut(t.color.colormap):this._paletteLut(t.color.palette))}t.size&&t.size.mode===`continuous`&&(a.sizeMode=1,a.sBuf=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,a.sBuf),r.bufferData(r.ARRAY_BUFFER,this._asF32(n[t.size.buf]),r.STATIC_DRAW),a.sizeRange=t.size.range_px);let o=e=>t.channels&&t.channels[e],s=Number(i.style&&i.style.artist_alpha);if(o(`opacity`)||o(`artist_alpha`)||o(`stroke_width`)||o(`symbol`)||Number.isFinite(s)){let e=new Float32Array(a.n*4);for(let t=0;t{let s=o(t);if(!s)return;let c=s.dtype===`u8`?this._asU8(n[s.buf]):this._asF32(n[s.buf]),l=s.components||1;for(let t=0;tF(n,e,t);if(!t){n.uniform1i(r(`u_gradMode`),0);return}n.uniform1i(r(`u_gradMode`),t.mode),n.uniform1i(r(`u_gradDir`),t.dir),n.uniform1i(r(`u_gradCount`),t.count),n.uniform1fv(r(`u_gradPos`),t.pos),n.uniform4fv(r(`u_gradColor`),t.colors)}_fillOpacity(e,t=1){return Number(e.opacity??t)*Number(e.fill_opacity??1)}_strokeOpacity(e,t=1){return Number(e.opacity??t)*Number(e.stroke_opacity??1)}_setRectStyleUniforms(e,t){let n=this.gl,r=t=>F(n,e,t);n.uniform2f(r(`u_res`),this.canvas.width,this.canvas.height);let i=t.cornerRadius||[0,0];n.uniform2f(r(`u_radius`),i[0]*this.dpr,i[1]*this.dpr),n.uniform1f(r(`u_strokeWidth`),(t.strokeWidth||0)*this.dpr);let a=t.strokeColor||[0,0,0,0];n.uniform4f(r(`u_stroke`),a[0],a[1],a[2],a[3]),n.uniform1i(r(`u_strokeMode`),+!!t.strokeBuf),n.uniform1f(r(`u_strokeOpacity`),this._strokeOpacity(t.trace.style||{})),this._setGradientUniforms(e,t.grad)}_rectMarkStyleGpu(e,t){let n=t.style||{},r=n.corner_radius;e.cornerRadius=Array.isArray(r)?[Number(r[0])||0,Number(r[1])||0]:[Number(r)||0,Number(r)||0],e.strokeWidth=Number(n.stroke_width)||0;let i=[e.color[0],e.color[1],e.color[2],1];e.strokeColor=n.stroke?b(this.root,n.stroke,i):i,e.grad=this._resolveMarkFill(n,e.color)}_smoothArrays(e,t,n,r,i){return!e.style||e.style.curve!==`smooth`?null:Me(t,n,r||null,i,32768)}_stepArrays(e,t,n,r){let i=e.style&&e.style.step;if(!i||r<2)return null;let a=i===`mid`?3:2,o=1+(r-1)*a,s=new Float32Array(o),c=new Float32Array(o);s[0]=t[0],c[0]=n[0];let l=1;for(let e=1;ethis._columnView(n,this.spec.columns[e])):this._columnView(n,this.spec.columns[r.buf]);e.heatmap={w:r.w,h:r.h,xRange:r.x_range,yRange:r.y_range,colormap:r.colormap,truecolor:i,tex:i?this._uploadRgbaGrid(a,r.w,r.h):this._uploadHeatmapGrid(a,r.w,r.h),lut:i?null:this._lut(r.colormap)},i||(e._cpuHeatmap={grid:a})}_uploadRgbaGrid(e,t,n){let r=this.gl,i=r.createTexture(),a=new Uint8Array(t*n*4);for(let r=0;rr.byteLength)throw RangeError(`column extends past chart payload`);if(c%s!==0)throw RangeError(`column is misaligned`);return t.dtype===`u8`?new Uint8Array(r.buffer,c,o):t.dtype===`u32`?new Uint32Array(r.buffer,c,o):new Float32Array(r.buffer,c,o)}_upload(e){let t=this.gl,n=t.createBuffer();return n._fcId=++this._bufSeq,n._fcType=e instanceof Uint8Array?t.UNSIGNED_BYTE:t.FLOAT,t.bindBuffer(t.ARRAY_BUFFER,n),t.bufferData(t.ARRAY_BUFFER,e,t.STATIC_DRAW),n}_bindVao(e,t,n,r){let i=this.gl;e._vaos||=new Map;let a=n.join(`|`),o=e._vaos.get(t);if(!o||o.sig!==a){o&&i.deleteVertexArray(o.vao);let n=i.createVertexArray();i.bindVertexArray(n),r(),o={vao:n,sig:a},e._vaos.set(t,o)}else i.bindVertexArray(o.vao)}_deleteVaos(e){if(!e||!e._vaos)return;let t=this.gl;if(t)for(let{vao:n}of e._vaos.values())t.deleteVertexArray(n);e._vaos=null}_vaoAttr(e,t,n,r,i=1,a=!1){let o=this.gl;o.bindBuffer(o.ARRAY_BUFFER,t),o.enableVertexAttribArray(e),o.vertexAttribPointer(e,i,t._fcType||o.FLOAT,a,0,n),o.vertexAttribDivisor(e,r)}_initPickTarget(){let e=this.gl;this.pickTex=e.createTexture(),this._allocPickTex(),this.pickFbo=e.createFramebuffer(),e.bindFramebuffer(e.FRAMEBUFFER,this.pickFbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.pickTex,0),e.bindFramebuffer(e.FRAMEBUFFER,null),this._pickDirty=!0}_allocPickTex(){let e=this.gl;e.bindTexture(e.TEXTURE_2D,this.pickTex),e.texImage2D(e.TEXTURE_2D,0,e.RGBA8,this.canvas.width,this.canvas.height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this._pickW=this.canvas.width,this._pickH=this.canvas.height}_map(e,t,n,r=null){if(!r)return[2/((n-t)*e.scale),(e.offset-t)/(n-t)*2-1];let i=this._axis(r),a=this._axisCoord(i,t),o=this._axisCoord(i,n);if(![a,o].every(Number.isFinite)||o===a)return[0,-2];let s=2/(o-a);return[s,-1-a*s]}_mapConst(e,t,n,r=null){if(!r)return(e-t)/(n-t)*2-1;let i=this._axis(r),a=this._axisCoord(i,e),o=this._axisCoord(i,t),s=this._axisCoord(i,n);return![a,o,s].every(Number.isFinite)||s===o?-2:(a-o)/(s-o)*2-1}_edgePadForValue(e,t,n,r){if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n)||n===t)return 0;let i=Math.abs(n-t)*1e-10+1e-12,a=Math.max(1,r||1),o=Math.max(2,Math.ceil(this.dpr||1));return Math.abs(e-t)<=i?-(2*o)/a:Math.abs(e-n)<=i?2*o/a:0}_setAxisUniforms(e,t,n,r){let i=this.gl,a=t=>F(i,e,t);i.uniform2f(a(`${t}meta`),n&&Number.isFinite(n.offset)?n.offset:0,n&&n.scale?n.scale:1),i.uniform1i(a(`${t}mode`),this._axisMode(r))}draw(e=!1){if(!(this._destroyed||this._glLost||!this.gl)){if(this._updateZoomMenuLabel?.(),this._raf){this._rafKeepPick=this._rafKeepPick&&e;return}this._rafKeepPick=e,this._raf=requestAnimationFrame(()=>{this._raf=null,!this._destroyed&&this._drawNow()})}}_drawNow(){if(this._destroyed||!this.gl||this._glLost)return;this._healStaleTheme();let e=this.gl,{x0:t,x1:n,y0:r,y1:i}=this.view;e.bindFramebuffer(e.FRAMEBUFFER,null),e.viewport(0,0,this.canvas.width,this.canvas.height),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT);let a=e=>{if(e.tier===`density`){let[t,n]=this._axisRange(e.xAxis),[r,i]=this._axisRange(e.yAxis);tt(this,e,t,n,r,i);return}q(e.trace.kind).draw(this,e,t,n,r,i)};for(let e of this._transitionOldTraces||[])a(e);for(let e of this.gpuTraces)a(e);this._drawHoverState(),this._repositionTooltip(),this._rafKeepPick||(this._pickDirty=!0),this._rafKeepPick=!1,this._drawChrome(),this._renderLassoSelection?.()}_now(){return performance.now()}_canDrawSimplePoints(e){return e.colorMode===0&&e.sizeMode===0&&!e.selActive&&!e.rgbaBuf&&!e.styleBuf&&!e.strokeBuf&&(e.symbol||0)===0&&(e.pointStrokeWidth||0)<=0&&Math.max(e.lodBlendShown??0,e.lodBlend??0)<=.001}_drawPoints(e,t,n,r=1){r*=e._transitionOpacity??1;let i=e._transitionScale??1;if(this._canDrawSimplePoints(e)){this._drawSimplePoints(e,t,n,r);return}let a=this.gl,o=this.pointProg;a.useProgram(o);let s=e=>F(a,o,e);a.uniform2f(s(`u_xmap`),t[0],t[1]),a.uniform2f(s(`u_ymap`),n[0],n[1]),this._setAxisUniforms(o,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(o,`u_y`,e.yMeta,e.yAxis),a.uniform1f(s(`u_dpr`),this.dpr);let c=!!(e._transitionPrevXBuf&&e._transitionPrevYBuf);a.uniform1i(s(`u_transitionActive`),+!!c),a.uniform1f(s(`u_transitionProgress`),e._transitionPositionProgress??1),a.uniform1f(s(`u_size`),e.size*i),a.uniform1i(s(`u_sizeMode`),e.sizeMode),a.uniform2f(s(`u_sizeRange`),e.sizeRange[0]*i,e.sizeRange[1]*i),a.uniform1i(s(`u_colorMode`),e.colorMode);let l=this._fillOpacity(e.trace.style,.8)*r;a.uniform1f(s(`u_opacity`),l),a.uniform1f(s(`u_selectedOpacity`),this._markStateNumber(`selected`,`opacity`,1)),a.uniform1f(s(`u_unselectedOpacity`),this._markStateNumber(`unselected`,`opacity`,.12));let u=(e,t)=>{let n=t?b(this.root,t,[0,0,0,1]):null;a.uniform4f(e,n?n[0]:0,n?n[1]:0,n?n[2]:0,+!!n)};u(s(`u_selColor`),this._markStateValue(`selected`,`color`)),u(s(`u_unselColor`),this._markStateValue(`unselected`,`color`));let[d,f,p,m]=e.color;a.uniform4f(s(`u_color`),d,f,p,m),a.uniform1i(s(`u_symbol`),e.symbol||0);let h=e.pointStroke;a.uniform1f(s(`u_ptStrokeWidth`),(e.pointStrokeWidth||0)*this.dpr),a.uniform1i(s(`u_ptStrokeFace`),+!!e.pointStrokeFace),a.uniform1i(s(`u_strokeMode`),+!!e.strokeBuf),a.uniform1f(s(`u_strokeOpacity`),this._strokeOpacity(e.trace.style,.8)*r),a.uniform4f(s(`u_ptStroke`),h?h[0]:0,h?h[1]:0,h?h[2]:0,h?h[3]:0),a.uniform1i(s(`u_selActive`),+!!e.selActive);let g=e.colorMode!==0&&e.cBuf,_=e.sizeMode===1&&e.sBuf,v=e.selActive&&e.selBuf,y=e.colorMode===3&&e.rgbaBuf,x=!!e.styleBuf,S=!!e.strokeBuf;e.lut&&(a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,e.lut),a.uniform1i(s(`u_lut`),0));let C=e.lodBlend??0,w=e.lodBlendShown??C;if(Math.abs(w-C)>.005&&!this._prefersReducedMotion()){let t=this._now(),n=e._blendTick?Math.min(100,t-e._blendTick):16;e._blendTick=t,w+=(C-w)*(1-Math.exp(-n/90)),e.lodBlendShown=w,this.draw()}else e.lodBlendShown=w=C,e._blendTick=0;a.uniform1f(s(`u_dblend`),w);let T=w>.001&&e.dBuf&&e.dlut;T&&(a.activeTexture(a.TEXTURE1),a.bindTexture(a.TEXTURE_2D,e.dlut)),a.uniform1i(s(`u_dlut`),1),this._bindVao(e,`points`,[e.xBuf._fcId,e.yBuf._fcId,g?e.cBuf._fcId:0,_?e.sBuf._fcId:0,v?e.selBuf._fcId:0,T?e.dBuf._fcId:0,c?e._transitionPrevXBuf._fcId:0,c?e._transitionPrevYBuf._fcId:0,y?e.rgbaBuf._fcId:0,x?e.styleBuf._fcId:0,S?e.strokeBuf._fcId:0],()=>{this._vaoAttr(P.ax,e.xBuf,0,0),this._vaoAttr(P.ay,e.yBuf,0,0),g&&this._vaoAttr(P.a_cval,e.cBuf,0,0),_&&this._vaoAttr(P.a_sval,e.sBuf,0,0),v&&this._vaoAttr(P.a_sel,e.selBuf,0,0),T&&this._vaoAttr(P.a_dval,e.dBuf,0,0),c&&(this._vaoAttr(P.a_prevx,e._transitionPrevXBuf,0,0),this._vaoAttr(P.a_prevy,e._transitionPrevYBuf,0,0)),y&&this._vaoAttr(P.a_rgba,e.rgbaBuf,0,0,4,!0),x&&this._vaoAttr(P.a_style,e.styleBuf,0,0,4),S&&this._vaoAttr(P.a_stroke,e.strokeBuf,0,0,4,!0)}),g||a.vertexAttrib1f(P.a_cval,0),_||a.vertexAttrib1f(P.a_sval,.5),v||a.vertexAttrib1f(P.a_sel,1),T||a.vertexAttrib1f(P.a_dval,0),y||a.vertexAttrib4f(P.a_rgba,d,f,p,m),x||a.vertexAttrib4f(P.a_style,1,-1,-1,-1),S||a.vertexAttrib4f(P.a_stroke,d,f,p,m),a.drawArrays(a.POINTS,0,e.n)}_drawSimplePoints(e,t,n,r=1){let i=this.gl,a=this.pointSimpleProg;i.useProgram(a);let o=e=>F(i,a,e);i.uniform2f(o(`u_xmap`),t[0],t[1]),i.uniform2f(o(`u_ymap`),n[0],n[1]),this._setAxisUniforms(a,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(a,`u_y`,e.yMeta,e.yAxis),i.uniform1f(o(`u_dpr`),this.dpr);let s=!!(e._transitionPrevXBuf&&e._transitionPrevYBuf);i.uniform1i(o(`u_transitionActive`),+!!s),i.uniform1f(o(`u_transitionProgress`),e._transitionPositionProgress??1),i.uniform1f(o(`u_size`),e.size*(e._transitionScale??1));let[c,l,u,d]=e.color;i.uniform4f(o(`u_color`),c,l,u,d*this._fillOpacity(e.trace.style,.8)*r),this._bindVao(e,`points-simple`,[e.xBuf._fcId,e.yBuf._fcId,s?e._transitionPrevXBuf._fcId:0,s?e._transitionPrevYBuf._fcId:0],()=>{this._vaoAttr(P.ax,e.xBuf,0,0),this._vaoAttr(P.ay,e.yBuf,0,0),s&&(this._vaoAttr(P.a_prevx,e._transitionPrevXBuf,0,0),this._vaoAttr(P.a_prevy,e._transitionPrevYBuf,0,0))}),i.drawArrays(i.POINTS,0,e.n)}_drawHoverState(){let e=this._hoverTarget;if(!e||!e.g)return;let t=e.g;if(t.trace.kind!==`scatter`||t.tier===`density`||!Number.isInteger(e.index)||e.index<0||e.index>=t.n)return;let[n,r]=this._axisRange(t.xAxis),[i,a]=this._axisRange(t.yAxis);this._drawHoverPoint(t,e.index,this._map(t.xMeta,n,r,t.xAxis),this._map(t.yMeta,i,a,t.yAxis))}_drawHoverPoint(e,t,n,r){let i=this.gl,a=this.pointProg;i.useProgram(a);let o=e=>F(i,a,e);i.uniform2f(o(`u_xmap`),n[0],n[1]),i.uniform2f(o(`u_ymap`),r[0],r[1]),this._setAxisUniforms(a,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(a,`u_y`,e.yMeta,e.yAxis);let s=Math.max((e.size||4)*1.75,(e.size||4)+5),c=Math.max(0,this._markStateNumber(`hover`,`size`,s)),l=Math.max(0,Math.min(1,this._markStateNumber(`hover`,`opacity`,.95))),u=b(this.root,this._markStatePaint(`hover`,`color`,`rgba(15,23,42,.92)`),[.06,.09,.16,.92]);i.uniform1f(o(`u_dpr`),this.dpr),i.uniform1f(o(`u_size`),c),i.uniform1i(o(`u_sizeMode`),0),i.uniform2f(o(`u_sizeRange`),c,c),i.uniform1i(o(`u_colorMode`),0),i.uniform1f(o(`u_opacity`),l),i.uniform1f(o(`u_selectedOpacity`),1),i.uniform1f(o(`u_unselectedOpacity`),1),i.uniform4f(o(`u_color`),u[0],u[1],u[2],1),i.uniform1i(o(`u_selActive`),0),i.uniform1f(o(`u_dblend`),0),this._bindVao(e,`hover`,[e.xBuf._fcId,e.yBuf._fcId],()=>{this._vaoAttr(P.ax,e.xBuf,0,0),this._vaoAttr(P.ay,e.yBuf,0,0)}),i.vertexAttrib1f(P.a_cval,0),i.vertexAttrib1f(P.a_sval,.5),i.vertexAttrib1f(P.a_sel,1),i.vertexAttrib1f(P.a_dval,0),i.drawArrays(i.POINTS,t,1)}_drawDensity(e,t,n=1){let r=this.gl,i=t||e.density;if(!i||!i.tex||!r.isTexture(i.tex))return;n*=e._transitionOpacity??1;let a=this.densityProg;r.useProgram(a);let o=e=>F(r,a,e),{x0:s,x1:c,y0:l,y1:u}=this.view,[d,f]=this._axisRange(e.xAxis),[p,m]=this._axisRange(e.yAxis);r.uniform4f(o(`u_view`),d??s,f??c,p??l,m??u),r.uniform1i(o(`u_xmode`),this._axisMode(e.xAxis)),r.uniform1i(o(`u_ymode`),this._axisMode(e.yAxis)),r.uniform4f(o(`u_gridRange`),i.xRange[0],i.xRange[1],i.yRange[0],i.yRange[1]),r.uniform1f(o(`u_opacity`),this._fillOpacity(e.trace.style)*n);let h=i.color;r.uniform1i(o(`u_constantColor`),+!!h),r.uniform4f(o(`u_color`),...h||[1,1,1,1]),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,i.tex),r.uniform1i(o(`u_grid`),0),r.activeTexture(r.TEXTURE1),r.bindTexture(r.TEXTURE_2D,i.lut),r.uniform1i(o(`u_lut`),1),r.bindVertexArray(this.quadVao),r.drawArrays(r.TRIANGLE_STRIP,0,4)}_drawHeatmap(e){let t=e.heatmap;if(!t)return;let n=this.gl,r=this.heatmapProg;n.useProgram(r);let i=e=>F(n,r,e),{x0:a,x1:o,y0:s,y1:c}=this.view,[l,u]=this._axisRange(e.xAxis),[d,f]=this._axisRange(e.yAxis);n.uniform4f(i(`u_view`),l??a,u??o,d??s,f??c),n.uniform1i(i(`u_xmode`),this._axisMode(e.xAxis)),n.uniform1i(i(`u_ymode`),this._axisMode(e.yAxis));let p=(l??a)>(u??o),m=(d??s)>(f??c);n.uniform4f(i(`u_gridRange`),t.xRange[+!!p],t.xRange[+!p],t.yRange[+!!m],t.yRange[+!m]),n.uniform1f(i(`u_opacity`),this._fillOpacity(e.trace.style)*(e._transitionOpacity??1)),n.uniform1i(i(`u_truecolor`),+!!t.truecolor),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,t.tex),n.uniform1i(i(`u_grid`),0),t.truecolor||(n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,t.lut),n.uniform1i(i(`u_lut`),1)),n.bindVertexArray(this.quadVao),n.drawArrays(n.TRIANGLE_STRIP,0,4)}_drawLine(e,t,n,r=null,i=null,a=null){if(e.n<2)return;let o=this.gl;o.useProgram(this.lineProg);let s=e=>F(o,this.lineProg,e);o.uniform2f(s(`u_xmap`),t[0],t[1]),o.uniform2f(s(`u_ymap`),n[0],n[1]),this._setAxisUniforms(this.lineProg,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(this.lineProg,`u_y`,e.yMeta,e.yAxis),o.uniform2f(s(`u_res`),this.canvas.width,this.canvas.height);let c=!!(e._transitionPrevXBuf&&e._transitionPrevYBuf);o.uniform1i(s(`u_transitionActive`),+!!c),o.uniform1f(s(`u_transitionProgress`),e._transitionPositionProgress??1);let l=Math.max(0,Math.min(1,e._transitionReveal??1));o.uniform1f(s(`u_revealProgress`),l),o.uniform1f(s(`u_revealSegments`),e.n-1),o.uniform1f(s(`u_width`),(i??e.trace.style.width??1.5)*this.dpr);let[u,d,f,p]=r||e.color,m=this._strokeOpacity(e.trace.style)*(a??1)*(e._transitionOpacity??1);o.uniform4f(s(`u_color`),u,d,f,p*m);let h=this._lineDash(e);this._bindVao(e,`line`,[e.xBuf._fcId,e.yBuf._fcId,h?e._lenBuf._fcId:0,c?e._transitionPrevXBuf._fcId:0,c?e._transitionPrevYBuf._fcId:0],()=>{this._vaoAttr(P.ax0,e.xBuf,0,1),this._vaoAttr(P.ax1,e.xBuf,4,1),this._vaoAttr(P.ay0,e.yBuf,0,1),this._vaoAttr(P.ay1,e.yBuf,4,1),h&&(this._vaoAttr(P.a_len0,e._lenBuf,0,1),this._vaoAttr(P.a_len1,e._lenBuf,4,1)),c&&(this._vaoAttr(P.a_prevx,e._transitionPrevXBuf,0,1),this._vaoAttr(P.a_prevy,e._transitionPrevYBuf,0,1),this._vaoAttr(P.a_prevx1,e._transitionPrevXBuf,4,1),this._vaoAttr(P.a_prevy1,e._transitionPrevYBuf,4,1))});let g=Math.max(0,Math.min(e.n-1,Math.ceil((e.n-1)*l)));o.drawArraysInstanced(o.TRIANGLE_STRIP,0,4,g)}_drawSegments(e,t,n){if(e.n<1)return;let r=this.gl,i=this.segmentProg;r.useProgram(i);let a=e=>F(r,i,e);r.uniform2f(a(`u_xmap`),t[0],t[1]),r.uniform2f(a(`u_ymap`),n[0],n[1]),this._setAxisUniforms(i,`u_x0`,e.x0Meta,e.xAxis),this._setAxisUniforms(i,`u_x1`,e.x1Meta,e.xAxis),this._setAxisUniforms(i,`u_y0`,e.y0Meta,e.yAxis),this._setAxisUniforms(i,`u_y1`,e.y1Meta,e.yAxis),r.uniform2f(a(`u_res`),this.canvas.width,this.canvas.height),r.uniform1f(a(`u_width`),(e.trace.style.width??1.5)*this.dpr),r.uniform1f(a(`u_animationProgress`),e._transitionScale??1);let[o,s,c,l]=e.color;r.uniform4f(a(`u_color`),o,s,c,l),r.uniform1f(a(`u_opacity`),this._strokeOpacity(e.trace.style)*(e._transitionOpacity??1)),r.uniform1i(a(`u_colorMode`),e.colorMode||0);let u=this._segmentDash(e,i);e.colorMode&&e.lut&&(r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,e.lut),r.uniform1i(a(`u_lut`),0)),this._bindVao(e,`segment`,[e.x0Buf._fcId,e.x1Buf._fcId,e.y0Buf._fcId,e.y1Buf._fcId,e.colorMode&&e.cBuf?e.cBuf._fcId:0,e.rgbaBuf?e.rgbaBuf._fcId:0,e.styleBuf?e.styleBuf._fcId:0,u?e._segmentDashOffsetBuf._fcId:0,u?e._segmentDashDirBuf._fcId:0],()=>{this._vaoAttr(P.ax0,e.x0Buf,0,1),this._vaoAttr(P.ax1,e.x1Buf,0,1),this._vaoAttr(P.ay0,e.y0Buf,0,1),this._vaoAttr(P.ay1,e.y1Buf,0,1),e.colorMode&&e.cBuf&&this._vaoAttr(P.a_cval,e.cBuf,0,1),e.rgbaBuf&&this._vaoAttr(P.a_rgba,e.rgbaBuf,0,1,4,!0),e.styleBuf&&this._vaoAttr(P.a_style,e.styleBuf,0,1,4),u&&(this._vaoAttr(P.a_dash0,e._segmentDashOffsetBuf,0,1),this._vaoAttr(P.a_dashDir,e._segmentDashDirBuf,0,1))}),e.cBuf||r.vertexAttrib1f(P.a_cval,0),e.rgbaBuf||r.vertexAttrib4f(P.a_rgba,o,s,c,l),e.styleBuf||r.vertexAttrib4f(P.a_style,1,-1,-1,-1);let d=Math.max(0,Math.min(e.n,Math.ceil(e.n*(e._transitionReveal??1))));r.drawArraysInstanced(r.TRIANGLE_STRIP,0,4,d)}_segmentDash(e,t){let n=this.gl,r=e=>F(n,t,e),i=e.trace.style&&e.trace.style.dash,a=e._segmentCpu;if(!i||!i.length||!a)return n.uniform1i(r(`u_dashCount`),0),!1;let o=e.n,s=e._segmentDashOffsets?.length===o?e._segmentDashOffsets:e._segmentDashOffsets=new Float32Array(o),c=e._segmentDashDirections?.length===o?e._segmentDashDirections:e._segmentDashDirections=new Float32Array(o),l=Array(o),u=Array(o),d=new Float32Array(o),f=new Map,p=(e,t)=>{let n=f.get(e);n?n.push(t):f.set(e,[t])},m=(e,t)=>`${Math.round(e*1e3)},${Math.round(t*1e3)}`,h=this.dpr;for(let t=0;t{let t=e,n=0;for(;;){let e=(f.get(t)||[]).find(e=>!g[e]);if(e===void 0)break;g[e]=1,l[e]===t?(s[e]=n,c[e]=1,t=u[e]):(s[e]=n+d[e],c[e]=-1,t=l[e]),n+=d[e]}};for(let[e,t]of f)t.length===1&&_(e);for(let e=0;ee?(n.bindBuffer(n.ARRAY_BUFFER,e),n.bufferData(n.ARRAY_BUFFER,t,n.DYNAMIC_DRAW),e):this._upload(t);e._segmentDashOffsetBuf=v(e._segmentDashOffsetBuf,s),e._segmentDashDirBuf=v(e._segmentDashDirBuf,c);let y=new Float32Array(8),b=Math.min(i.length,8),x=0;for(let e=0;eF(r,i,e);r.uniform2f(a(`u_xmap`),t[0],t[1]),r.uniform2f(a(`u_ymap`),n[0],n[1]);for(let t of[`x0`,`x1`,`x2`])this._setAxisUniforms(i,`u_`+t,e[t+`Meta`],e.xAxis);for(let t of[`y0`,`y1`,`y2`])this._setAxisUniforms(i,`u_`+t,e[t+`Meta`],e.yAxis);r.uniform1i(a(`u_colorMode`),e.colorMode||0),r.uniform1f(a(`u_opacity`),this._fillOpacity(e.trace.style)),r.uniform4f(a(`u_color`),e.color[0],e.color[1],e.color[2],e.color[3]);let o=e.meshStroke||[0,0,0,0];r.uniform4f(a(`u_stroke`),o[0],o[1],o[2],o[3]),r.uniform1f(a(`u_strokeWidth`),e.meshStrokeWidth||0),r.uniform1i(a(`u_strokeMode`),+!!e.strokeBuf),r.uniform1f(a(`u_strokeOpacity`),this._strokeOpacity(e.trace.style)),e.colorMode&&e.lut&&(r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,e.lut),r.uniform1i(a(`u_lut`),0));let s=[`x0`,`x1`,`x2`,`y0`,`y1`,`y2`].map(t=>e[t+`Buf`]._fcId);s.push(e.cBuf?e.cBuf._fcId:0,e.rgbaBuf?e.rgbaBuf._fcId:0,e.styleBuf?e.styleBuf._fcId:0,e.strokeBuf?e.strokeBuf._fcId:0),this._bindVao(e,`mesh`,s,()=>{for(let t of[`x0`,`x1`,`x2`,`y0`,`y1`,`y2`])this._vaoAttr(P[`a`+t],e[t+`Buf`],0,1);e.cBuf&&this._vaoAttr(P.a_cval,e.cBuf,0,1),e.rgbaBuf&&this._vaoAttr(P.a_rgba,e.rgbaBuf,0,1,4,!0),e.styleBuf&&this._vaoAttr(P.a_style,e.styleBuf,0,1,4),e.strokeBuf&&this._vaoAttr(P.a_stroke,e.strokeBuf,0,1,4,!0)}),e.cBuf||r.vertexAttrib1f(P.a_cval,0),e.rgbaBuf||r.vertexAttrib4f(P.a_rgba,...e.color),e.styleBuf||r.vertexAttrib4f(P.a_style,1,-1,-1,-1),e.strokeBuf||r.vertexAttrib4f(P.a_stroke,...o),r.drawArraysInstanced(r.TRIANGLES,0,3,e.n)}_lineDash(e){let t=this.gl,n=e=>F(t,this.lineProg,e),r=e.trace.style&&e.trace.style.dash;if(!r||!r.length||!e._dashX)return t.uniform1i(n(`u_dashCount`),0),!1;let i=e.n;(!e._lenArr||e._lenArr.length!==i)&&(e._lenArr=new Float32Array(i));let a=e._lenArr,o=this.dpr,s=this._dataPx(e.xAxis,this._decodeValue(e._dashX,e.xMeta,0)),c=this._dataPx(e.yAxis,this._decodeValue(e._dashY,e.yMeta,0)),l=0;a[0]=0;for(let t=1;tF(i,a,e);i.uniform2f(o(`u_xmap`),t[0],t[1]),i.uniform2f(o(`u_ymap`),n[0],n[1]),i.uniform2f(o(`u_bmap`),r[0],r[1]),this._setAxisUniforms(a,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(a,`u_y`,e.yMeta,e.yAxis),this._setAxisUniforms(a,`u_b`,e.baseMeta,e.yAxis);let s=Math.max(0,Math.min(1,e._transitionReveal??1));i.uniform1f(o(`u_revealProgress`),s),i.uniform1f(o(`u_revealSegments`),e.n-1);let[c,l,u,d]=e.color;i.uniform4f(o(`u_color`),c,l,u,d*this._fillOpacity(e.trace.style,.35)*(e._transitionOpacity??1)),i.uniform2f(o(`u_res`),this.canvas.width,this.canvas.height),this._setGradientUniforms(a,e.grad),this._bindVao(e,`area`,[e.xBuf._fcId,e.yBuf._fcId,e.baseBuf._fcId],()=>{this._vaoAttr(P.ax0,e.xBuf,0,1),this._vaoAttr(P.ax1,e.xBuf,4,1),this._vaoAttr(P.ay0,e.yBuf,0,1),this._vaoAttr(P.ay1,e.yBuf,4,1),this._vaoAttr(P.ab0,e.baseBuf,0,1),this._vaoAttr(P.ab1,e.baseBuf,4,1)});let f=Math.max(0,Math.min(e.n-1,Math.ceil((e.n-1)*s)));i.drawArraysInstanced(i.TRIANGLE_STRIP,0,4,f)}_drawRects(e,t,n,r,i,a=[0,0,0,0]){if(!e.n)return;let o=this.gl,s=this.rectProg;o.useProgram(s);let c=e=>F(o,s,e);o.uniform2f(c(`u_x0map`),t[0],t[1]),o.uniform2f(c(`u_x1map`),n[0],n[1]),o.uniform2f(c(`u_y0map`),r[0],r[1]),o.uniform2f(c(`u_y1map`),i[0],i[1]),this._setAxisUniforms(s,`u_x0`,e.x0Meta,e.xAxis),this._setAxisUniforms(s,`u_x1`,e.x1Meta,e.xAxis),this._setAxisUniforms(s,`u_y0`,e.y0Meta,e.yAxis),this._setAxisUniforms(s,`u_y1`,e.y1Meta,e.yAxis),o.uniform1i(c(`u_xmode`),this._axisMode(e.xAxis)),o.uniform1i(c(`u_ymode`),this._axisMode(e.yAxis)),o.uniform4f(c(`u_edgePad`),a[0],a[1],a[2],a[3]);let[l,u,d,f]=e.color;o.uniform4f(c(`u_color`),l,u,d,f),o.uniform1f(c(`u_opacity`),this._fillOpacity(e.trace.style)*(e._transitionOpacity??1)),o.uniform1i(c(`u_colorMode`),e.colorMode||0),this._setRectStyleUniforms(s,e);let p=!!e.cBuf,m=!!e.rgbaBuf,h=!!e.styleBuf,g=!!e.strokeBuf,_=!!e.radiusBuf;p&&(o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,e.lut),o.uniform1i(c(`u_lut`),0)),this._bindVao(e,`rects`,[e.x0Buf._fcId,e.x1Buf._fcId,e.y0Buf._fcId,e.y1Buf._fcId,p?e.cBuf._fcId:0,m?e.rgbaBuf._fcId:0,h?e.styleBuf._fcId:0,g?e.strokeBuf._fcId:0,_?e.radiusBuf._fcId:0],()=>{this._vaoAttr(P.ax0,e.x0Buf,0,1),this._vaoAttr(P.ax1,e.x1Buf,0,1),this._vaoAttr(P.ay0,e.y0Buf,0,1),this._vaoAttr(P.ay1,e.y1Buf,0,1),p&&this._vaoAttr(P.a_cval,e.cBuf,0,1),m&&this._vaoAttr(P.a_rgba,e.rgbaBuf,0,1,4,!0),h&&this._vaoAttr(P.a_style,e.styleBuf,0,1,4),g&&this._vaoAttr(P.a_stroke,e.strokeBuf,0,1,4,!0),_&&this._vaoAttr(P.a_radius,e.radiusBuf,0,1,2)}),p||o.vertexAttrib1f(P.a_cval,0),m||o.vertexAttrib4f(P.a_rgba,l,u,d,f),h||o.vertexAttrib4f(P.a_style,1,-1,-1,-1),g||o.vertexAttrib4f(P.a_stroke,...e.strokeColor||e.color),_||o.vertexAttrib2f(P.a_radius,-1,-1),o.drawArraysInstanced(o.TRIANGLE_STRIP,0,4,e.n)}_drawBars(e,t,n,r,i,a=0){if(!e.n)return;let o=this.gl,s=this.barProg;o.useProgram(s);let c=e=>F(o,s,e);o.uniform2f(c(`u_pmap`),t[0],t[1]),o.uniform2f(c(`u_v1map`),n[0],n[1]),o.uniform2f(c(`u_v0map`),r?r[0]:1,r?r[1]:0);let l=e.orientation===1?e.yAxis:e.xAxis,u=e.orientation===1?e.xAxis:e.yAxis;this._setAxisUniforms(s,`u_p`,e.posMeta,l),this._setAxisUniforms(s,`u_v1`,e.value1Meta,u),this._setAxisUniforms(s,`u_v0`,e.value0Meta,u),o.uniform1i(c(`u_pmode`),this._axisMode(l)),o.uniform1i(c(`u_vmode`),this._axisMode(u)),o.uniform1f(c(`u_width`),e.width),o.uniform1i(c(`u_orientation`),e.orientation),o.uniform1i(c(`u_v0Mode`),e.value0Mode),o.uniform1f(c(`u_v0Const`),i??0),o.uniform1f(c(`u_v0EdgePad`),a),o.uniform1f(c(`u_animationProgress`),e._transitionGrow??1);let d=!!(e._transitionPrevPosBuf&&e._transitionPrevValue1Buf&&e._transitionPrevValue0Buf);o.uniform1i(c(`u_transitionActive`),+!!d),o.uniform1f(c(`u_transitionProgress`),e._transitionPositionProgress??1),o.uniform1f(c(`u_prevWidth`),e._transitionPrevWidth??e.width);let[f,p,m,h]=e.color;o.uniform4f(c(`u_color`),f,p,m,h),o.uniform1f(c(`u_opacity`),this._fillOpacity(e.trace.style)*(e._transitionOpacity??1)),o.uniform1i(c(`u_colorMode`),e.colorMode||0),this._setRectStyleUniforms(s,e);let g=e.value0Mode===1&&e.value0Buf,_=!!e.cBuf,v=!!e.rgbaBuf,y=!!e.styleBuf,b=!!e.strokeBuf,x=!!e.radiusBuf;_&&(o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,e.lut),o.uniform1i(c(`u_lut`),0)),this._bindVao(e,`bars`,[e.posBuf._fcId,e.value1Buf._fcId,g?e.value0Buf._fcId:0,_?e.cBuf._fcId:0,d?e._transitionPrevPosBuf._fcId:0,d?e._transitionPrevValue1Buf._fcId:0,d?e._transitionPrevValue0Buf._fcId:0,v?e.rgbaBuf._fcId:0,y?e.styleBuf._fcId:0,b?e.strokeBuf._fcId:0,x?e.radiusBuf._fcId:0],()=>{this._vaoAttr(P.a_pos,e.posBuf,0,1),this._vaoAttr(P.a_v1,e.value1Buf,0,1),g&&this._vaoAttr(P.a_v0,e.value0Buf,0,1),_&&this._vaoAttr(P.a_cval,e.cBuf,0,1),d&&(this._vaoAttr(P.a_prevx,e._transitionPrevPosBuf,0,1),this._vaoAttr(P.a_prevy,e._transitionPrevValue1Buf,0,1),this._vaoAttr(P.a_prevx1,e._transitionPrevValue0Buf,0,1)),v&&this._vaoAttr(P.a_rgba,e.rgbaBuf,0,1,4,!0),y&&this._vaoAttr(P.a_style,e.styleBuf,0,1,4),b&&this._vaoAttr(P.a_stroke,e.strokeBuf,0,1,4,!0),x&&this._vaoAttr(P.a_radius,e.radiusBuf,0,1,2)}),g||o.vertexAttrib1f(P.a_v0,0),_||o.vertexAttrib1f(P.a_cval,0),v||o.vertexAttrib4f(P.a_rgba,f,p,m,h),y||o.vertexAttrib4f(P.a_style,1,-1,-1,-1),b||o.vertexAttrib4f(P.a_stroke,...e.strokeColor||e.color),x||o.vertexAttrib2f(P.a_radius,-1,-1),o.drawArraysInstanced(o.TRIANGLE_STRIP,0,4,e.n)}_dataPxX(e){return this._dataPx(`x`,e)}_dataPxY(e){return this._dataPx(`y`,e)}_styleNumber(e,t,n){if(!e||typeof e!=`object`)return n;let r=Number(e[t]);return Number.isFinite(r)?r:n}_axisStyleNumber(e,t,n){return this._styleNumber(e&&e.style,t,n)}_axisStylePaint(e,t,n){let r=e&&typeof e.style==`object`?e.style:null;return T(this.root,r&&r[t],n)}_axisStyleValue(e,t){let n=e&&typeof e.style==`object`?e.style:null;return n&&Object.prototype.hasOwnProperty.call(n,t)?n[t]:void 0}_axisGridDash(e){let t=String(this._axisStyleValue(e,`grid_dash`)||`solid`);return t===`dashed`?[6,4]:t===`dotted`?[1,3]:t===`dashdot`?[6,3,1,3]:[]}_axisTickLabelStrategy(e){let t=String(e&&e.tick_label_strategy||`auto`).replace(/-/g,`_`);return[`auto`,`hide`,`rotate`,`stagger`,`none`,`off`].includes(t)?t:`auto`}_axisTickLabelAnchor(e){let t=e&&e.tick_label_anchor!==void 0?e.tick_label_anchor:this._axisStyleValue(e,`tick_label_anchor`);if(t==null)return null;let n=String(t).toLowerCase();return n===`start`||n===`left`?`start`:n===`end`||n===`right`?`end`:n===`center`||n===`middle`?`center`:null}_axisTickLabelAngle(e){let t=Number(e?e.tick_label_angle:void 0);return Number.isFinite(t)?t:null}_axisTickLabelMinGap(e,t){let n=Number(e?e.tick_label_min_gap:void 0);return Number.isFinite(n)&&n>=0?n:t===`x`?8:4}_estimateTickLabel(e,t){let n=String(e||``);return{w:Math.max(t*.7,n.length*t*.62),h:t*1.2}}_tickLabelExtent(e,t,n){let r=this._estimateTickLabel(e.text,n),i=Math.abs(Number(e.angle||0))*Math.PI/180;return t===`y`?Math.abs(Math.sin(i))*r.w+Math.abs(Math.cos(i))*r.h:Math.abs(Math.cos(i))*r.w+Math.abs(Math.sin(i))*r.h}_tickLabelsCollide(e,t,n,r,i=`center`){let a=new Map;for(let t of e){let e=Number(t.row||0);a.has(e)||a.set(e,[]),a.get(e).push(t)}for(let e of a.values()){if(e.sort((e,t)=>e.pos-t.pos),t===`x`&&i!==`center`){for(let t=1;tt%a===0);if(!this._tickLabelsCollide(o,t,n,r,i))return o}return e.slice(0,1)}_layoutTickLabels(e,t,n){let r=this._axisTickLabelStrategy(e);if(r===`none`||r===`off`)return[];if(n.length<=1){let t=this._axisTickLabelAngle(e);return n.map(e=>({...e,angle:t===null?0:t,row:0}))}let i=Math.max(8,this._axisStyleNumber(e,`tick_label_size`,this._axisStyleNumber(e,`tick_size`,11))),a=this._axisTickLabelMinGap(e,t),o=t===`x`?this._axisTickLabelAnchor(e)??`center`:`center`,s=this._axisTickLabelAngle(e),c=s===null?0:s,l=n.map(e=>({...e,angle:c,row:0})),u=r;if(u===`auto`){if(!this._tickLabelsCollide(l,t,i,a,o))return l;u=t===`x`&&e.kind===`category`&&n.length<=16?`rotate`:t===`x`&&n.length<=24?`stagger`:`hide`}let d=l;if(u===`rotate`&&t===`x`){let t=s===null?e.side===`top`?35:-35:s;d=n.map(e=>({...e,angle:t,row:0}))}else u===`stagger`&&t===`x`&&(d=n.map((e,t)=>({...e,angle:c,row:t%2})));return this._tickLabelsCollide(d,t,i,a,o)&&(d=this._downsampleTickLabels(d,t,i,a,o)),d}_xTickLabelTransform(e,t){let n=Number(t||0),r=e&&e.side===`top`?`top`:`bottom`,i=this._axisTickLabelAnchor(e);if(i){let e=i===`end`?`-100%`:i===`start`?`0%`:`-50%`,t=i===`end`?`right`:i===`start`?`left`:`center`;return{transform:`translateX(${e}) rotate(${n}deg)`,origin:`${t} ${r===`top`?`bottom`:`top`}`}}if(n===0)return{transform:`translateX(-50%)`,origin:r===`top`?`bottom center`:`top center`};let a=r===`bottom`&&n<0||r===`top`&&n>0,o=r===`top`?`bottom`:`top`;return{transform:`${a?`translateX(-100%) `:``}rotate(${n}deg)`,origin:`${o} ${a?`right`:`left`}`}}_axisLabelCss(e,t,n){let r=e&&e.label_position,i=r!=null,a=e&&Number.isFinite(Number(e.label_offset)),o=e&&Number.isFinite(Number(e.label_angle));if(!i&&!a&&!o)return{css:n,style:null};if(r&&typeof r==`object`&&!Array.isArray(r))return{css:`font-weight:500;white-space:nowrap;`,style:r};let s=this.plot,c=String(i?r:`center`).replace(/-/g,`_`),l=c.startsWith(`inside_`),u=l?c.slice(7):c,d=a?Number(e.label_offset):0,f=e&&e.side,p=u===`start`?0:u===`end`?1:.5;if(t===`x`){let t=s.x+s.w*p,n=f===`top`?s.y-34:s.y+s.h+24,r=f===`top`?s.y+12:s.y+s.h-12;return{css:`left:${t}px;top:${(l?r:n)+(f===`top`?l?d:-d:l?-d:d)}px;transform:translateX(${u===`start`?0:u===`end`?-100:-50}%) rotate(${o?Number(e.label_angle):0}deg);transform-origin:center;font-weight:500;white-space:nowrap;`,style:null}}let m=f===`right`?s.x+s.w+40:10,h=f===`right`?s.x+s.w-12:s.x+12;return{css:`left:${(l?h:m)+(f===`right`?l?-d:d:l?d:-d)}px;top:${s.y+s.h*(1-p)}px;transform:translate(-50%,-50%) rotate(${o?Number(e.label_angle):f===`right`?90:-90}deg);transform-origin:center;font-weight:500;white-space:nowrap;`,style:null}}_drawChrome(){let e=this.spec,t=this.dpr,n=this.chrome.getContext(`2d`);n.setTransform(t,0,0,t,0,0),n.clearRect(0,0,this.size.w,this.size.h);let r=this._now(),i=this._viewAnim?80:0,a=i===0||this._lastLabelDraw===null||r-this._lastLabelDraw>=i;a&&(this.labels.textContent=``,this._lastLabelDraw=r);let o=this.plot;this.theme.bg&&(n.fillStyle=S(this.theme.bg),n.fillRect(o.x,o.y,o.w,o.h));let s=this._axis(`x`),c=this._axis(`y`),l=Object.values(this.axes).filter(e=>e&&e.id!==`x`&&String(e.id||``).startsWith(`x`)),u=Object.values(this.axes).filter(e=>e&&e.id!==`y`&&String(e.id||``).startsWith(`y`)),d=this._axisTickLabelStrategy(s)===`none`,f=this._axisTickLabelStrategy(c)===`none`,p=this._axisTicks(`x`,this._axisTickTarget(`x`,Math.max(3,o.w/(s.kind===`time`?90:80)))),m=this._axisTicks(`y`,this._axisTickTarget(`y`,Math.max(3,o.h/45))),h=e=>Math.min(o.x+o.w-.5,Math.max(o.x+.5,Math.round(e)+.5)),g=e=>Math.min(o.y+o.h-.5,Math.max(o.y+.5,Math.round(e)+.5));n.strokeStyle=this._axisStylePaint(s,`grid_color`,this.theme.grid),n.lineWidth=Math.max(.5,this._axisStyleNumber(s,`grid_width`,1)),n.globalAlpha=this._axisStyleNumber(s,`grid_opacity`,1),n.setLineDash(this._axisGridDash(s)),n.beginPath();for(let e of d?[]:p.ticks){let t=this._dataPx(`x`,e);if(!Number.isFinite(t))continue;let r=h(t);n.moveTo(r,o.y),n.lineTo(r,o.y+o.h)}n.stroke(),n.strokeStyle=this._axisStylePaint(c,`grid_color`,this.theme.grid),n.lineWidth=Math.max(.5,this._axisStyleNumber(c,`grid_width`,1)),n.globalAlpha=this._axisStyleNumber(c,`grid_opacity`,1),n.setLineDash(this._axisGridDash(c)),n.beginPath();for(let e of f?[]:m.ticks){let t=this._dataPx(`y`,e);if(!Number.isFinite(t))continue;let r=g(t);n.moveTo(o.x,r),n.lineTo(o.x+o.w,r)}n.stroke(),n.globalAlpha=1,n.setLineDash([]);let _=this.overlay.getContext(`2d`);if(_.setTransform(t,0,0,t,0,0),_.clearRect(0,0,this.size.w,this.size.h),this._drawAnnotationShapes(_),a){let t=(e,t,n,r,i,a=`axis_color`)=>{let o=document.createElement(`div`);o.style.cssText=`position:absolute;left:${t}px;top:${n}px;width:${r}px;height:${i}px;background:${this._axisStylePaint(e,a,this.theme.axis)};pointer-events:none;`,this.labels.appendChild(o)},n=Array.isArray(e.frame_sides)?e.frame_sides:[s.side||`bottom`,c.side||`left`];if(!f){let e=Math.max(1,this._axisStyleNumber(c,`axis_width`,1));n.includes(`left`)&&t(c,o.x,o.y,e,o.h),n.includes(`right`)&&t(c,o.x+o.w-e,o.y,e,o.h)}if(!d){let e=Math.max(1,this._axisStyleNumber(s,`axis_width`,1));n.includes(`top`)&&t(s,o.x,o.y,o.w,e),n.includes(`bottom`)&&t(s,o.x,o.y+o.h-e,o.w,e)}for(let e of l){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=Math.max(1,this._axisStyleNumber(e,`axis_width`,1)),r=e.side===`top`?o.y:o.y+o.h-n;t(e,o.x,r,o.w,n)}for(let e of u){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=Math.max(1,this._axisStyleNumber(e,`axis_width`,1));t(e,e.side===`left`?o.x:o.x+o.w-n,o.y,n,o.h)}let r=e=>{let t=Math.max(0,this._axisStyleNumber(e,`tick_length`,0)),n=Math.max(.5,this._axisStyleNumber(e,`tick_width`,1)),r=String(this._axisStyleValue(e,`tick_direction`)||`out`);return r===`in`?{inward:t,outward:0,width:n}:r===`inout`?{inward:t/2,outward:t/2,width:n}:{inward:0,outward:t,width:n}};if(!d){let e=r(s),n=s.side||`bottom`,i=n===`top`?o.y:o.y+o.h;for(let r of p.ticks){let a=this._dataPx(`x`,r);if(!Number.isFinite(a)||ao.x+o.w+1)continue;let c=n===`top`?i-e.outward:i-e.inward;t(s,a-e.width/2,c,e.width,e.inward+e.outward,`tick_color`)}}if(!f){let e=r(c),n=c.side||`left`,i=n===`right`?o.x+o.w:o.x;for(let r of m.ticks){let a=this._dataPx(`y`,r);!Number.isFinite(a)||ao.y+o.h+1||t(c,n===`right`?i-e.inward:i-e.outward,a-e.width/2,e.inward+e.outward,e.width,`tick_color`)}}for(let e of l){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.w/(e.kind===`time`?90:80)))),i=r(e),a=e.side||`bottom`,s=a===`top`?o.y:o.y+o.h;for(let r of n.ticks){let n=this._dataPx(e.id,r);if(!Number.isFinite(n)||no.x+o.w+1)continue;let c=a===`top`?s-i.outward:s-i.inward;t(e,n-i.width/2,c,i.width,i.inward+i.outward,`tick_color`)}}for(let e of u){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.h/45))),i=r(e),a=e.side||`right`,s=a===`right`?o.x+o.w:o.x;for(let r of n.ticks){let n=this._dataPx(e.id,r);!Number.isFinite(n)||no.y+o.h+1||t(e,a===`right`?s-i.inward:s-i.outward,n-i.width/2,i.inward+i.outward,i.width,`tick_color`)}}}let v=(e,t,n,r=`tick`,i=null)=>{if(!a)return;let o=document.createElement(`div`);o.textContent=e,o.dataset.xyLabelKind=r,o.dataset.xyAxis=n&&n.id!==void 0?String(n.id):``,o.dataset.xyAxisSide=n&&n.side?String(n.side):``;let s=r===`label`?`label_color`:this._axisStyleValue(n,`tick_label_color`)===void 0?`tick_color`:`tick_label_color`,c=r===`label`?`label_size`:this._axisStyleValue(n,`tick_label_size`)===void 0?`tick_size`:`tick_label_size`,l=``;this._axisStyleValue(n,s)!==void 0&&(l=`color:${this._axisStylePaint(n,s,this.theme.label)};`);let u=``;this._axisStyleValue(n,c)!==void 0&&(u=`font-size:${Math.max(8,this._axisStyleNumber(n,c,11))}px;`),o.style.cssText=`position:absolute;line-height:1.2;white-space:nowrap;${l}${u}${t}`,this._applySlot(o,r===`label`?`axis_title`:`tick_label`),this._applyStyle(o,i),this.labels.appendChild(o)},y=[];for(let e of p.labels||p.ticks){let t=this._dataPx(`x`,e);if(to.x+o.w+1)continue;let n=this._axisTickText(s,e,p.step);y.push({pos:t,text:n})}let b=this._axisStyleNumber(s,`tick_label_size`,this._axisStyleNumber(s,`tick_size`,11));for(let e of this._layoutTickLabels(s,`x`,y)){let t=Number(e.row||0)*(Math.max(8,b)+4),n=s.side===`top`?o.y-18-t:o.y+o.h+6+t,r=this._xTickLabelTransform(s,e.angle);v(e.text,`left:${e.pos}px;top:${n}px;transform:${r.transform};transform-origin:${r.origin};`,s)}for(let e of l){let t=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.w/(e.kind===`time`?90:80)))),n=[];for(let r of t.labels||t.ticks){let i=this._dataPx(e.id,r);io.x+o.w+1||n.push({pos:i,text:this._axisTickText(e,r,t.step)})}for(let t of this._layoutTickLabels(e,`x`,n)){let n=this._axisStyleNumber(e,`tick_label_size`,this._axisStyleNumber(e,`tick_size`,11)),r=Number(t.row||0)*(Math.max(8,n)+4),i=e.side===`top`?o.y-18-r:o.y+o.h+6+r,a=this._xTickLabelTransform(e,t.angle);v(t.text,`left:${t.pos}px;top:${i}px;transform:${a.transform};transform-origin:${a.origin};`,e)}if(e.label&&this._axisTickLabelStrategy(e)!==`none`){let t=e.side===`top`?o.y-34:o.y+o.h+24,n=`left:${o.x+o.w/2}px;top:${t}px;transform:translateX(-50%);font-weight:500;`,r=this._axisLabelCss(e,`x`,n);v(e.label,r.css,e,`label`,r.style)}}let x=[];for(let e of m.labels||m.ticks){let t=this._dataPx(`y`,e);if(to.y+o.h+1)continue;let n=this._axisTickText(c,e,m.step);x.push({pos:t,text:n})}let C=(e,t,n)=>{let r=t?o.x+o.w+8:o.x-8,i=this._axisTickLabelAnchor(e)??(t?`start`:`end`),a=i===`end`?`-100%`:i===`start`?`0%`:`-50%`,s=i===`end`?`right`:i===`start`?`left`:`center`;return`left:${r}px;top:${n.pos}px;transform:translate(${a},-50%) rotate(${Number(n.angle||0)}deg);transform-origin:${s} center;`};for(let e of this._layoutTickLabels(c,`y`,x))v(e.text,C(c,c.side===`right`,e),c);for(let e of u){let t=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.h/45))),n=[];for(let r of t.labels||t.ticks){let i=this._dataPx(e.id,r);if(io.y+o.h+1)continue;let a=this._axisTickText(e,r,t.step);n.push({pos:i,text:a})}for(let t of this._layoutTickLabels(e,`y`,n))v(t.text,C(e,e.side!==`left`,t),e);if(e.label&&this._axisTickLabelStrategy(e)!==`none`){let t=e.side===`left`?`left:10px;top:${o.y+o.h/2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:500;`:`left:${o.x+o.w+40}px;top:${o.y+o.h/2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:500;`,n=this._axisLabelCss(e,`y`,t);v(e.label,n.css,e,`label`,n.style)}}if(e.x_axis.label&&!d){let t=s.side===`top`?o.y-34:o.y+o.h+24,n=`left:${o.x+o.w/2}px;top:${t}px;transform:translateX(-50%);font-weight:500;`,r=this._axisLabelCss(s,`x`,n);v(e.x_axis.label,r.css,s,`label`,r.style)}if(e.y_axis.label&&!f){let t=c.side===`right`?`left:${o.x+o.w+40}px;top:${o.y+o.h/2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:500;`:`left:10px;top:${o.y+o.h/2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:500;`,n=this._axisLabelCss(c,`y`,t);v(e.y_axis.label,n.css,c,`label`,n.style)}this._drawAnnotationLabels(a)}_interactionTransitionActive(){let e=e=>e!=null;return!!this._viewAnim||this.gpuTraces.some(t=>e(t._densityFadeStart)||e(t._densitySwitchFadeStart)||e(t._drillFadeStart)||e(t._drillExitFadeStart)||!!t._densityNormAnim)}_renderPick(){let e=this.gl;(this._pickW!==this.canvas.width||this._pickH!==this.canvas.height)&&this._allocPickTex(),e.bindFramebuffer(e.FRAMEBUFFER,this.pickFbo),e.viewport(0,0,this.canvas.width,this.canvas.height),e.disable(e.BLEND),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT);let{x0:t,x1:n,y0:r,y1:i}=this.view,a=this.pickProg;e.useProgram(a);let o=t=>F(e,a,t);e.uniform1f(o(`u_dpr`),this.dpr);let s=1;for(let t of this.gpuTraces){let n=t.tier===`density`?t.drill&&!t._drillDying&&this._viewInside(t.drill.win)?t.drill:null:q(t.trace.kind).pointPick?t:null;if(!n||!n.n||s+n.n>2147483647){t.pickBase=-1,t.pickCount=0;continue}let[r,i]=this._axisRange(n.xAxis||t.xAxis),[c,l]=this._axisRange(n.yAxis||t.yAxis),u=this._map(n.xMeta,r,i,n.xAxis||t.xAxis),d=this._map(n.yMeta,c,l,n.yAxis||t.yAxis);e.uniform2f(o(`u_xmap`),u[0],u[1]),e.uniform2f(o(`u_ymap`),d[0],d[1]),this._setAxisUniforms(a,`u_x`,n.xMeta,n.xAxis||t.xAxis),this._setAxisUniforms(a,`u_y`,n.yMeta,n.yAxis||t.yAxis),e.uniform1f(o(`u_size`),n.size),e.uniform1i(o(`u_sizeMode`),n.sizeMode),e.uniform2f(o(`u_sizeRange`),n.sizeRange[0],n.sizeRange[1]);let f=!!(n._transitionPrevXBuf&&n._transitionPrevYBuf);e.uniform1i(o(`u_transitionActive`),+!!f),e.uniform1f(o(`u_transitionProgress`),n._transitionPositionProgress??1),e.uniform1i(o(`u_pick_base`),s),t.pickBase=s,t.pickCount=n.n;let p=n.sizeMode===1&&n.sBuf;this._bindVao(n,`pick`,[n.xBuf._fcId,n.yBuf._fcId,p?n.sBuf._fcId:0,f?n._transitionPrevXBuf._fcId:0,f?n._transitionPrevYBuf._fcId:0],()=>{this._vaoAttr(P.ax,n.xBuf,0,0),this._vaoAttr(P.ay,n.yBuf,0,0),p&&this._vaoAttr(P.a_sval,n.sBuf,0,0),f&&(this._vaoAttr(P.a_prevx,n._transitionPrevXBuf,0,0),this._vaoAttr(P.a_prevy,n._transitionPrevYBuf,0,0))}),p||e.vertexAttrib1f(P.a_sval,.5),e.drawArrays(e.POINTS,0,n.n),s+=n.n}e.enable(e.BLEND),e.bindFramebuffer(e.FRAMEBUFFER,null),this._pickDirty=!1}_pickAt(e,t){if(!this._pickable||this._glLost||!this.gl||this.gl.isContextLost())return null;if(this._pickDirty)try{this._renderPick()}catch(e){if(!this.gl||this.gl.isContextLost())return null;throw e}let n=this.gl,r=Math.round(e*this.dpr),i=Math.round((this.plot.h-t)*this.dpr);if(r<0||i<0||r>=this.canvas.width||i>=this.canvas.height)return null;let a=new Uint8Array(4);n.bindFramebuffer(n.FRAMEBUFFER,this.pickFbo),n.readPixels(r,i,1,1,n.RGBA,n.UNSIGNED_BYTE,a),n.bindFramebuffer(n.FRAMEBUFFER,null);let o=a[0]+a[1]*256+a[2]*65536+a[3]*16777216;if(o===0)return null;let s=this.gpuTraces.find(e=>e.pickBase>0&&o>=e.pickBase&&o=e.length?NaN:e[n]/(t.scale||1)+t.offset}_dataFromCanvas(e,t,n=`x`,r=`y`){let[i,a]=this._axisRange(n),[o,s]=this._axisRange(r),c=this._axis(n),l=this._axis(r),u=this._axisCoord(c,i),d=this._axisCoord(c,a),f=this._axisCoord(l,o),p=this._axisCoord(l,s);return[u,d,f,p].every(Number.isFinite)?[this._axisValue(c,u+e/this.plot.w*(d-u)),this._axisValue(l,p-t/this.plot.h*(p-f))]:[NaN,NaN]}_nearestCpuIndex(e,t){let n=e&&e._cpu;if(!n||!n.x||!n.x.length)return-1;let r=n.xMeta||e.xMeta,i=this._axis(e.xAxis),a=this._axisCoord(i,t),o=-1,s=1/0,c=Math.min(n.x.length,e.n||n.x.length);for(let t=0;t=l&&t<=u&&Math.abs(n-s)<=e.width/2)return{trace:e.trace.id,index:o,g:e,synthetic:!0}}else if(Math.abs(t-a)<=e.width/2&&n>=l&&n<=u)return{trace:e.trace.id,index:o,g:e,synthetic:!0}}return null}_rectHover(e,t,n){let r=e._cpuRect,i=Math.min(r.x0.length,r.x1.length,r.y0.length,r.y1.length,e.n||r.x0.length);for(let a=0;a=Math.min(i,o)&&t<=Math.max(i,o)&&n>=Math.min(s,c)&&n<=Math.max(s,c))return{trace:e.trace.id,index:a,g:e,synthetic:!0}}return null}_heatmapHover(e,t,n){let r=e.heatmap;if(!r||!e._cpuHeatmap)return null;let[i,a]=r.xRange,[o,s]=r.yRange;if(ta||ns)return null;let[c,l]=this._axisRange(e.xAxis)??[this.view.x0,this.view.x1],[u,d]=this._axisRange(e.yAxis)??[this.view.y0,this.view.y1],f=(c??this.view.x0)>(l??this.view.x1)?a-t:t-i,p=(u??this.view.y0)>(d??this.view.y1)?s-n:n-o,m=Math.min(r.w-1,Math.max(0,Math.floor(f/(a-i)*r.w))),h=Math.min(r.h-1,Math.max(0,Math.floor(p/(s-o)*r.h)));return{trace:e.trace.id,index:h*r.w+m,g:e,heatmap:{row:h,col:m},synthetic:!0}}_drawKeepPick(){this.draw(!0)}_hover(e){if(this._a11yKeyboardReadout=null,this._interactionTransitionActive()){let e=this._hoverId!==-1;this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._pickSeq=(this._pickSeq||0)+1,this._hideTooltip(),e&&this.draw();return}let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top,i=this._pickAt(n,r)||this._hoverAt(n,r);if(!i){let e=this._hoverId!==-1;this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._pickSeq=(this._pickSeq||0)+1,this._hideTooltip(),e&&this._drawKeepPick();return}let a=i.trace*1e9+i.index;if(this._lastHoverXY={clientX:e.clientX,clientY:e.clientY},a===this._hoverId){this._tooltipAnchor||this._renderTooltip(this._lastRow,e.clientX,e.clientY);return}this._hoverId=a,this._hoverTarget=i,this._showTooltip(i,e.clientX,e.clientY),this._drawKeepPick()}_asF32(e){return e instanceof ArrayBuffer?new Float32Array(e):e.byteOffset%4==0?new Float32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4)):new Float32Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength))}_asU8(e){return e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}_asU32(e){return e instanceof ArrayBuffer?new Uint32Array(e):e.byteOffset%4==0?new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4)):new Uint32Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength))}_applyTheme(){this.theme=x(this.root),this._themeStale=!this.root.isConnected;for(let e of this.gpuTraces)q(e.trace.kind).refreshColor?.(this,e)}refreshTheme(){this._destroyed||(this._applyTheme(),this.draw())}_healStaleTheme(){return!this._themeStale||!this.root.isConnected?!1:(this._applyTheme(),!0)}destroy(){if(this._destroyed)return;this._destroyed=!0,this._dataAnim&&this._emitAnimationLifecycle?.(`end`,this._dataAnim.phase,{cancelled:!0}),Z.unregister(this),this._ctxIo?.disconnect(),this._ctxIo=null,clearTimeout(this._ctxRecoveryTimer),this._ctxRecoveryTimer=null,clearTimeout(this._rebinTimer),this._rebinWorker&&=(this._rebinWorker.terminate(),this._rebinWorker._fcUrl&&URL.revokeObjectURL(this._rebinWorker._fcUrl),null),this._ro?.disconnect(),this._io?.disconnect(),this._io=null,this._themeWatch?.removeEventListener?.(`change`,this._onScheme),this._themeMutationObserver?.disconnect(),this._themeMutationObserver=null,this._dprMq?.removeEventListener?.(`change`,this._onDprChange),this._dprMq=null,this._unsubscribeComm?.(),this._unsubscribeComm=null;for(let{target:e,type:t,handler:n,options:r}of this._listeners.splice(0))e.removeEventListener(t,n,r);clearTimeout(this._viewTimer),this._viewTimer=null,this._viewEventRaf&&cancelAnimationFrame(this._viewEventRaf),this._viewEventRaf=null,this._wheelZoomRaf&&cancelAnimationFrame(this._wheelZoomRaf),this._wheelZoomRaf=null,this._pendingWheelZoom=null,clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null,this._wheelGesture=null,this._linkChannel?.close?.(),this._linkChannel=null,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._resizeRaf&&cancelAnimationFrame(this._resizeRaf),this._resizeRaf=null,this._pendingResize=null,this._resizeNeedsMeasure=!1,this._cancelViewAnimation(),this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf),this._dataAnimRaf=null,this._dataAnim=null,this._destroyTransitionOldTraces?.(),this._destroyGlResources();let e=this.gl&&this.gl.getExtension(`WEBGL_lose_context`);e&&e.loseContext(),this.gl=null,this.root.remove()}_deleteBuffers(e,t){let n=this.gl;if(!n||!e)return;let r=new Set;for(let i of t){let t=e[i];t&&!r.has(t)&&(r.add(t),n.deleteBuffer(t)),e[i]=null}}_destroyTraceResources(e,t){if(!e)return;this._destroyDensitySample(e),this._deleteVaos(e),this._deleteVaos(e.drill),this._deleteBuffers(e,[`xBuf`,`yBuf`,`cBuf`,`sBuf`,`selBuf`,`baseBuf`,`x0Buf`,`x1Buf`,`x2Buf`,`y0Buf`,`y1Buf`,`y2Buf`,`posBuf`,`value1Buf`,`value0Buf`,`_transitionPrevXBuf`,`_transitionPrevYBuf`,`_transitionPrevPosBuf`,`_transitionPrevValue1Buf`,`_transitionPrevValue0Buf`]),this._deleteBuffers(e.drill,[`xBuf`,`yBuf`,`cBuf`,`sBuf`,`selBuf`,`dBuf`]);let n=[];e.heatmap&&n.push(e.heatmap.tex);for(let t of e.densityCache||[])n.push(t&&t.tex);e.density&&n.push(e.density.tex),e._shownDensity&&n.push(e._shownDensity.tex);for(let e of n)e&&!t.has(e)&&(t.add(e),this.gl.deleteTexture(e));e.drill=null,e.density=null,e._shownDensity=null,e.densityCache=[],e.heatmap=null,e._cpu=null}_destroyGlResources(){let e=this.gl;if(!e)return;let t=new Set;for(let e of this.gpuTraces||[])this._destroyTraceResources(e,t);for(let n of this._lutCache.values())n&&!t.has(n)&&(t.add(n),e.deleteTexture(n));this._lutCache.clear(),this.pickFbo&&e.deleteFramebuffer(this.pickFbo),this.pickTex&&!t.has(this.pickTex)&&e.deleteTexture(this.pickTex),this.pickFbo=null,this.pickTex=null,this.quad&&e.deleteBuffer(this.quad),this.quad=null,this.quadVao&&e.deleteVertexArray(this.quadVao),this.quadVao=null;for(let t of this._progCache?this._progCache.values():[])t&&e.deleteProgram(t);this._progCache&&this._progCache.clear(),this._glPrograms=this._progCache,this.gpuTraces=[]}},lt=new Set([`color`,`label_color`,`label_opacity`,`opacity`,`width`,`head_size`,`head_style`,`tail_style`,`shaft_width_start`,`shaft_width_end`,`curve`,`angle_a`,`angle_b`,`gap_start`,`gap_end`,`start_offset`,`label_clear`,`dash`,`span_start`,`span_end`,`size`,`symbol`,`stroke_color`,`stroke_width`,`coordinate_space`]);function ut(e,t){if(typeof e.label_clear!=`string`)return 0;let n=e.label_clear.split(`,`).map(Number);if(n.length!==4||n.some(e=>!Number.isFinite(e)||e<0))return 0;let[r,i,a,o]=n,[s,c]=t,l=s>1e-9?i/s:s<-1e-9?r/-s:1/0,u=c>1e-9?o/c:c<-1e-9?a/-c:1/0,d=Math.min(l,u);return Number.isFinite(d)?d:0}function dt(e,t,n,r,i){let a=e=>Number.isFinite(Number(e))?Number(e):null;if(typeof i.start_offset==`string`){let n=i.start_offset.split(`,`).map(Number);n.length===2&&n.every(Number.isFinite)&&(e+=n[0],t+=n[1])}let o=a(i.angle_a),s=a(i.angle_b),c=a(i.curve),l=null,u=null;if(o!==null&&s!==null){let i=-o*Math.PI/180,a=-s*Math.PI/180,c=Math.cos(i)*Math.sin(a)-Math.sin(i)*Math.cos(a);if(Math.abs(c)>1e-6){let o=((n-e)*Math.sin(a)-(r-t)*Math.cos(a))/c;l=e+o*Math.cos(i),u=t+o*Math.sin(i)}}else if(c){let i=n-e,a=r-t;l=(e+n)/2+c*a,u=(t+r)/2-c*i}let d=(e,t,n,r)=>{let i=Math.hypot(n-e,r-t)||1;return[(n-e)/i,(r-t)/i]},f=l===null?d(e,t,n,r):d(e,t,l,u),p=l===null?d(n,r,e,t):d(n,r,l,u),m=Math.max(0,a(i.gap_start)||0,ut(i,f)),h=Math.max(0,a(i.gap_end)||0),g=Math.hypot(n-e,r-t),_=m+h0)||e.length<2)return e;let n=e.slice(),r=t;for(;n.length>=2;){let[e,t]=n[n.length-2],[i,a]=n[n.length-1],o=Math.hypot(i-e,a-t);if(o>r){let s=1-r/o;return n[n.length-1]=[e+s*(i-e),t+s*(a-t)],n}r-=o,n.pop()}return n}function mt(e,t,n){let r=[],i=[],a=e.length;for(let o=0;o0&&e.stroke(),e.restore()},_drawArrowLine(e,t,n,r,i,a){if(![t,n,r,i].every(Number.isFinite))return;let o=dt(t,n,r,i,a);e.save(),e.globalAlpha=this._styleNumber(a,`opacity`,1),e.strokeStyle=this._annotationPaint(a,[.4,.44,.52,1]),e.fillStyle=e.strokeStyle,e.lineWidth=Math.max(.5,this._styleNumber(a,`width`,1.5)),e.setLineDash(Array.isArray(a.dash)?a.dash:typeof a.dash==`string`?a.dash.split(`,`).map(Number):[]);let s=Number(a.shaft_width_start),c=Number(a.shaft_width_end),l=a.head_style||`triangle`,u=Math.max(4,this._styleNumber(a,`head_size`,8));if(Number.isFinite(s)||Number.isFinite(c)){let t=ft(o);l===`triangle`&&(t=pt(t,u*Math.cos(Math.PI/6)));let n=mt(t,Number.isFinite(s)?s:1,Number.isFinite(c)?c:1);e.beginPath(),e.moveTo(n[0][0],n[0][1]);for(let t=1;t[a-i*Math.cos(s-e*Math.PI/6),o-i*Math.sin(s-e*Math.PI/6)],[l,u]=c(1),[d,f]=c(-1);if(r===`v`){e.moveTo(l,u),e.lineTo(a,o),e.lineTo(d,f),e.stroke();return}e.moveTo(a,o),e.lineTo(l,u),e.lineTo(d,f),e.closePath(),e.fill()},_drawAnnotationShapes(e){let t=Array.isArray(this.spec.annotations)?this.spec.annotations:[];if(!t.length)return;let n=this.plot;e.save(),e.beginPath(),e.rect(n.x,n.y,n.w,n.h),e.clip();for(let r of t){let t=r&&typeof r.style==`object`?r.style:{};if(r.kind===`band`){let i=r.axis===`x`,a=i?this._dataPxX(Number(r.start)):this._dataPxY(Number(r.start)),o=i?this._dataPxX(Number(r.end)):this._dataPxY(Number(r.end));if(!Number.isFinite(a)||!Number.isFinite(o))continue;let s=Math.max(i?n.x:n.y,Math.min(a,o)),c=Math.min(i?n.x+n.w:n.y+n.h,Math.max(a,o));if(c<=s)continue;e.save(),e.globalAlpha=this._styleNumber(t,`opacity`,.14),e.fillStyle=this._annotationPaint(t,[.39,.45,.55,1]);let l=Math.max(0,Math.min(1,Number(t.span_start)||0)),u=t.span_end===void 0?1:Number(t.span_end),d=Math.max(l,Math.min(1,Number.isFinite(u)?u:1));i?e.fillRect(s,n.y+(1-d)*n.h,c-s,(d-l)*n.h):e.fillRect(n.x+l*n.w,s,(d-l)*n.w,c-s),e.restore()}else if(r.kind===`rule`){let i=r.axis===`x`,a=i?this._dataPxX(Number(r.value)):this._dataPxY(Number(r.value));if(!Number.isFinite(a)||i&&(an.x+n.w+1)||!i&&(an.y+n.h+1))continue;let o=Math.round(a)+.5;e.save(),e.globalAlpha=this._styleNumber(t,`opacity`,1),e.strokeStyle=this._annotationPaint(t,[.4,.44,.52,1]),e.lineWidth=Math.max(.5,this._styleNumber(t,`width`,1.5)),e.setLineDash(Array.isArray(t.dash)?t.dash:typeof t.dash==`string`?t.dash.split(`,`).map(Number):[]),e.beginPath();let s=Math.max(0,Math.min(1,Number(t.span_start)||0)),c=t.span_end===void 0?1:Number(t.span_end),l=Math.max(s,Math.min(1,Number.isFinite(c)?c:1));i?(e.moveTo(o,n.y+(1-l)*n.h),e.lineTo(o,n.y+(1-s)*n.h)):(e.moveTo(n.x+s*n.w,o),e.lineTo(n.x+l*n.w,o)),e.stroke(),e.restore()}else if(r.kind===`arrow`)this._drawArrowLine(e,this._dataPxX(Number(r.x0)),this._dataPxY(Number(r.y0)),this._dataPxX(Number(r.x1)),this._dataPxY(Number(r.y1)),t);else if(r.kind===`callout`){let n=this._dataPxX(Number(r.x)),i=this._dataPxY(Number(r.y)),a=Number.isFinite(Number(r.dx))?Number(r.dx):0,o=Number.isFinite(Number(r.dy))?Number(r.dy):0;this._drawArrowLine(e,n+a,i+o,n,i,t)}else r.kind===`marker`&&this._drawAnnotationMarker(e,this._dataPxX(Number(r.x)),this._dataPxY(Number(r.y)),t,r)}e.restore()},_drawAnnotationLabels(e){if(!e)return;let t=Array.isArray(this.spec.annotations)?this.spec.annotations:[];if(!t.length)return;let n=this.plot;for(let e of t){let t=typeof e.text==`string`?e.text:``;if(!t)continue;let r=e&&typeof e.style==`object`?e.style:{},i=null,a=null,o=null;if(e.kind===`text`)r.coordinate_space===`axes_fraction`?(i=n.x+Number(e.x)*n.w,a=n.y+(1-Number(e.y))*n.h):r.coordinate_space===`figure_fraction`?(i=Number(e.x)*this.size.w,a=(1-Number(e.y))*this.size.h):r.coordinate_space===`yaxis_transform`?(i=n.x+Number(e.x)*n.w,a=this._dataPxY(Number(e.y))):r.coordinate_space===`xaxis_transform`?(i=this._dataPxX(Number(e.x)),a=n.y+(1-Number(e.y))*n.h):(i=this._dataPxX(Number(e.x)),a=this._dataPxY(Number(e.y)));else if(e.kind===`rule`)e.axis===`x`?(i=this._dataPxX(Number(e.value)),a=n.y+6):(i=n.x+n.w-6,a=this._dataPxY(Number(e.value)));else if(e.kind===`band`)e.axis===`x`?(i=(this._dataPxX(Number(e.start))+this._dataPxX(Number(e.end)))/2,a=n.y+6):(i=n.x+n.w-6,a=(this._dataPxY(Number(e.start))+this._dataPxY(Number(e.end)))/2);else if(e.kind===`arrow`){let t=this._dataPxX(Number(e.x0)),n=this._dataPxY(Number(e.y0)),r=this._dataPxX(Number(e.x1)),s=this._dataPxY(Number(e.y1));i=(t+r)/2,a=(n+s)/2;let c=Math.hypot(r-t,s-n);c>1e-6&&(o=[-(s-n)/c,(r-t)/c],o[1]>0&&(o=[-o[0],-o[1]]))}else(e.kind===`callout`||e.kind===`marker`)&&(i=this._dataPxX(Number(e.x)),a=this._dataPxY(Number(e.y)));if(!Number.isFinite(i)||!Number.isFinite(a)||in.x+n.w+24||an.y+n.h+24)continue;let s=document.createElement(`div`);s.textContent=t;let c=Number.isFinite(Number(e.dx))?Number(e.dx):0,l=Number.isFinite(Number(e.dy))?Number(e.dy):0,u=e.anchor,d=String(r.vertical_align||``);e.kind===`rule`||e.kind===`band`?e.axis===`x`?(!u&&e.kind===`band`&&(u=`middle`),d||=`top`):(u||=`end`,!d&&e.kind===`band`&&(d=`middle`)):e.kind===`arrow`&&(u||=`middle`,d||=`middle`);let f=u===`middle`?`-50%`:u===`end`?`-100%`:`0px`,p=Number.isFinite(Number(r.rotation))?(Number(r.rotation)%360+360)%360:0,m=d===`center`||d===`middle`?`-50%`:d===`bottom`?`-100%`:d===`top`?`0px`:`calc(-100% + 0.35em)`,h=`translate(${f},${m})`;if(p===90||p===270){let e=p===270;h=`rotate(${e?90:-90}deg) translate(${d===`center`||d===`middle`?`-50%`:d===`top`?e?`0`:`-100%`:d===`bottom`?e?`-100%`:`0`:e?`0`:`-100%`},${u===`middle`?`-50%`:u===`end`?e?`0`:`-100%`:e?`-100%`:`0`})`}else p&&(h=`rotate(${-p}deg) translate(${f},${m})`);s.style.cssText=`position:absolute;left:${i+c}px;top:${a+l}px;transform:${h};transform-origin:0 0;pointer-events:none;white-space:pre-line;text-align:center;width:max-content;`,this._applySlot(s,`annotation_label`),this._applyClass(s,e.class_name);let g=e.kind!==`text`&&e.kind!==`callout`,_={};for(let[t,n]of Object.entries(r)){if(t===`opacity`&&e.kind===`text`){_[t]=n;continue}lt.has(t)||g&&t===`opacity`||(_[t]=n)}if(this._applyStyle(s,_),r&&(r.label_color||r.color)&&(s.style.color=this._annotationLabelPaint(r,this.theme.label)),r&&r.label_opacity!==void 0){let e=Number(r.label_opacity);Number.isFinite(e)&&(s.style.opacity=String(Math.max(0,Math.min(1,e))))}this.labels.appendChild(s);let v=getComputedStyle(s),y=(e,t)=>(parseFloat(e)||0)+(parseFloat(t)||0),b=y(v.paddingLeft,v.borderLeftWidth),x=y(v.paddingRight,v.borderRightWidth),S=y(v.paddingTop,v.borderTopWidth),C=y(v.paddingBottom,v.borderBottomWidth);if((b||x||S||C)&&p!==90&&p!==270){let e=f===`-100%`?x:f===`-50%`?0:-b,t=m===`-50%`?0:m===`0px`?-S:C;s.style.transform=`${p?`rotate(${-p}deg) `:``}translate(calc(${f} + ${e}px), calc(${m} + ${t}px))`}let w=o&&this.labels.getBoundingClientRect();if(o&&w.width>0){let e=w.width/this.size.w,t=s.getBoundingClientRect(),n=t.width/e/2*Math.abs(o[0])+t.height/e/2*Math.abs(o[1])+3;i+=o[0]*n,a+=o[1]*n,s.style.left=`${i+c}px`,s.style.top=`${a+l}px`}let T=this.labels.getBoundingClientRect();if(T.width>0){let e=T.width/this.size.w,t=s.getBoundingClientRect(),n=t.right>T.right?T.right-t.right:t.leftT.bottom?T.bottom-t.bottom:t.top=0&&t=0&&tt.trace===e.trace)||r[0];if(!t||!Number.isFinite(Number(t.trace)))continue;let i=this.gpuTraces.find(e=>e.trace.id===t.trace);if(!i)continue;let a=Number.isInteger(e.index)&&t.trace===e.trace?e.index:-1;!i._cpuHeatmap&&(a<0||!i._cpu||!i._cpu.x||a>=i._cpu.x.length)&&(a=this._nearestCpuIndex(i,e.x));let[o,s]=this._sourceValue(i,t,a);o!==void 0&&(e[n]=o,s!==void 0&&(e[`${n}_kind`]=s))}},_denormalizeUnit(e,t){let n=Number(e);if(!Number.isFinite(n)||!Array.isArray(t)||t.length<2)return n;let r=Number(t[0]),i=Number(t[1]);return!Number.isFinite(r)||!Number.isFinite(i)?n:r+n*(i-r)},_defaultTooltipLines(e){let t=[];return e.x!==void 0&&t.push(`x: ${N(e.x,e.x_kind)}`),e.y!==void 0&&t.push(`y: ${N(e.y,e.y_kind)}`),e.color_value!==void 0&&t.push(`color: ${N(e.color_value)}`),e.color_category!==void 0&&t.push(`${e.color_category}`),e.size_value!==void 0&&t.push(`size: ${N(e.size_value)}`),t.length||t.push(`#${e.index}`),t},_tooltipLookup(e,t){let n=this.spec.tooltip&&this.spec.tooltip.aliases||{},r=e[t]===void 0?n[t]:t;return!r||e[r]===void 0?[void 0,void 0]:[e[r],e[`${r}_kind`]]},_formatTooltipValue(e,t,n){let r=ae(e,n);return r===null?N(e,t):r},_tooltipLines(e){let t=this.spec.tooltip||{};if(!t.title&&!Array.isArray(t.fields))return this._defaultTooltipLines(e);let n=t.format||{},r=[];if(typeof t.title==`string`){let i=t.title.replace(/\{([^}]+)\}/g,(t,r)=>{let[i,a]=this._tooltipLookup(e,r);return i===void 0?``:this._formatTooltipValue(i,a,n[r])});i&&r.push(i)}if(Array.isArray(t.fields))for(let i of t.fields){if(typeof i!=`string`)continue;let[t,a]=this._tooltipLookup(e,i);t!==void 0&&r.push(`${i}: ${this._formatTooltipValue(t,a,n[i])}`)}return r.length?r:this._defaultTooltipLines(e)},_setTooltipAnchor(e,t,n,r){let i=e.g;if(!i){this._tooltipAnchor=null;return}let a=i.xAxis||`x`,o=i.yAxis||`y`,s=t.x,c=t.y;if(!Number.isFinite(s)||!Number.isFinite(c)){let e=this.canvas.getBoundingClientRect();[s,c]=this._dataFromCanvas(n-e.left,r-e.top,a,o)}this._tooltipAnchor=Number.isFinite(s)&&Number.isFinite(c)?{xAxis:a,yAxis:o,x:s,y:c}:null,this._tooltipAnchor&&!this._tooltipAnchorPx()&&(this._tooltipAnchor=null)},_tooltipAnchorPx(){let e=this._tooltipAnchor;if(!e)return null;let t=this._dataPx(e.xAxis,e.x),n=this._dataPx(e.yAxis,e.y),r=this.plot;return!Number.isFinite(t)||!Number.isFinite(n)||tr.x+r.w||nr.y+r.h?null:{lx:t,ly:n}},_hideTooltip(){this.tooltip.style.display=`none`,this._tooltipAnchor=null},_repositionTooltip(){if(!this._tooltipAnchor)return;let e=this._tooltipAnchorPx();if(!e){this.tooltip.style.display=`none`;return}this.tooltip.style.display=`block`,this._placeTooltip(e.lx,e.ly)},_placeTooltip(e,t){let n=this.tooltip.offsetWidth,r=this.tooltip.offsetHeight,i=Math.max(4,this.size.w-n-4),a=Math.max(4,Math.min(e+12,i)),o=t+12,s=t-r-12,c=o+r<=this.size.h-4?o:Math.max(4,s);this.tooltip.style.left=a+`px`,this.tooltip.style.top=c+`px`},_renderTooltip(e,t,n,r={}){if(!e||this.spec.show_tooltip===!1){this._hideTooltip();return}let i=this._tooltipLines(e);if(this._customTooltip||(this.tooltip.textContent=``,i.forEach((e,t)=>{t&&this.tooltip.appendChild(document.createElement(`br`)),this.tooltip.appendChild(document.createTextNode(e))})),this.a11yLive&&r.announce!==!1){let e=this._a11yKeyboardReadout,t=i.join(`, `),n=e?`Point ${e.flat+1} of ${e.total}. ${t}`:t;this.a11yLive.textContent!==n&&(this.a11yLive.textContent=n)}this.tooltip.style.display=`block`;let a=this._tooltipAnchorPx();if(a)this._placeTooltip(a.lx,a.ly);else if(this._tooltipAnchor)this.tooltip.style.display=`none`;else{let e=this.root.getBoundingClientRect();this._placeTooltip(t-e.left,n-e.top)}}}),Object.assign(Q.prototype,{_initInteraction(){let e=this.canvas,t=null,n=null;this.selRect=document.createElement(`div`),this.selRect.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:4;`,this._applySlot(this.selRect,`selection`),this.root.appendChild(this.selRect),this.selLasso=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`),this.selLasso.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:4;overflow:visible;`,this.selLasso.dataset.xySelectionLassoOverlay=``,this.selLassoPath=document.createElementNS(`http://www.w3.org/2000/svg`,`path`),this.selLassoPath.dataset.xySelectionLasso=``,this.selLasso.appendChild(this.selLassoPath),this.selLassoHandles=document.createElementNS(`http://www.w3.org/2000/svg`,`g`),this.selLassoHandles.dataset.xySelectionLassoHandles=``,this.selLasso.appendChild(this.selLassoHandles),this.root.appendChild(this.selLasso),this._lassoPolygon=null;let r=null,i=t=>{if(!r||t.pointerId!==r.pointerId||!this._lassoPolygon)return;let n=e.getBoundingClientRect(),i=Math.max(0,Math.min(n.width,t.clientX-n.left)),a=Math.max(0,Math.min(n.height,t.clientY-n.top));this._lassoPolygon[r.index]=this._dataFromCanvas(i,a),this._renderLassoSelection(),t.preventDefault(),t.stopPropagation()};this._listen(this.selLasso,`pointerdown`,e=>{let t=e.target.closest?.(`[data-xy-selection-lasso-handle]`);if(!t||!this._lassoPolygon)return;let n=Number(t.dataset.xySelectionLassoHandle);if(!(!Number.isInteger(n)||!this._lassoPolygon[n])){r={index:n,pointerId:e.pointerId,original:[...this._lassoPolygon[n]],handle:t},t.dataset.xyActive=``,this._hideTooltip();try{this.selLasso.setPointerCapture(e.pointerId)}catch{}e.preventDefault(),e.stopPropagation()}}),this._listen(this.selLasso,`pointermove`,i),this._listen(this.selLasso,`pointerup`,e=>{if(!r||e.pointerId!==r.pointerId)return;i(e);let t=r.handle;r=null,delete t.dataset.xyActive,this._lassoPolygon&&this._sendSelectPolygon(this._lassoPolygon)}),this._listen(this.selLasso,`pointercancel`,e=>{!r||e.pointerId!==r.pointerId||(this._lassoPolygon&&(this._lassoPolygon[r.index]=r.original),delete r.handle.dataset.xyActive,r=null,this._lassoPolygon&&this._renderLassoSelection(),e.stopPropagation())}),this._interactionFlag(`crosshair`)&&(this.crosshairX=document.createElement(`div`),this.crosshairX.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:3;width:1px;`,this._applySlot(this.crosshairX,`crosshair_x`),this.root.appendChild(this.crosshairX),this.crosshairY=document.createElement(`div`),this.crosshairY.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:3;height:1px;`,this._applySlot(this.crosshairY,`crosshair_y`),this.root.appendChild(this.crosshairY));let a=(t,n)=>{let r=e.getBoundingClientRect();return this._dataFromCanvas(t-r.left,n-r.top)},o=(t,n)=>{let r=e.getBoundingClientRect(),i=Math.max(0,Math.min(r.width,t-r.left)),a=Math.max(0,Math.min(r.height,n-r.top));return{x:r.left+i,y:r.top+a,data:this._dataFromCanvas(i,a)}};this._listen(e,`pointerdown`,r=>{this._cancelViewAnimation();let i=this._interactionFlag(`pan`,!0),s=this._interactionFlag(`zoom`,!0),c=this._interactionFlag(`navigation`,!0),l=this._interactionFlag(`box_zoom`,!0),u=this._interactionFlag(`brush`,!0)&&this._interactionFlag(`select`,!0),d=this.dragMode.startsWith(`select`)?this.dragMode:null,f=(r.shiftKey||d)&&u&&this._pickable?r.shiftKey?`select`:d:this.dragMode===`zoom`&&c&&s&&l?`zoom`:null;if(f){let t=f.startsWith(`select`)&&this._lassoPolygon?this._lassoPolygon.map(e=>[...e]):null;f.startsWith(`select`)&&this._clearLassoOverlay();let i=f===`select-lasso`?o(r.clientX,r.clientY):null,s=i?i.data:a(r.clientX,r.clientY);n={mode:f,sx:r.clientX,sy:r.clientY,d0:s,points:i?[i]:null,previousLasso:t};try{e.setPointerCapture(r.pointerId)}catch{}this._hideTooltip();return}if(this.dragMode===`pan`&&c&&i){t={px:r.clientX,py:r.clientY,view:this._copyView(this.view),moved:!1,interactionId:++this._interactionSeq,axes:[...new Set([...this._axisPolicy(`pan_axes`),...this._axisIds().filter(e=>this._axisContained(e))])],changedAxes:[]};try{e.setPointerCapture(r.pointerId)}catch{}this._hideTooltip()}}),this._listen(e,`pointermove`,e=>{if(n){this._updateBand(n,e);return}if(t){t.moved=!0;let n=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,t.view)]]));for(let r of t.axes){let i=this._axis(r),[a,o]=this._axisRange(r,t.view),s=this._axisCoord(i,a),c=this._axisCoord(i,o);if(![s,c].every(Number.isFinite)||s===c)continue;let l=this._axisDim(r),u=l===`x`?this.plot.w:this.plot.h,d=(l===`x`?e.clientX-t.px:e.clientY-t.py)/u*(c-s),f=l===`x`?-d:d;n[r]=[this._axisValue(i,s+f),this._axisValue(i,c+f)]}let r=this._setView({ranges:n},{source:`pan_drag`,phase:`update`,interactionId:t.interactionId});t.changedAxes=[...new Set([...t.changedAxes,...r])];return}this._updateCrosshair(e),this._hover(e)}),this._listen(e,`pointerup`,e=>{if(n){n.mode===`select-lasso`&&this._updateBand(n,e),this.selRect.style.display=`none`,this.selLasso.style.display=`none`;let t=a(e.clientX,e.clientY);if(n.mode===`select-lasso`?n.points.length>=3:Math.abs(e.clientX-n.sx)>3||Math.abs(e.clientY-n.sy)>3){if(n.mode===`zoom`&&this._interactionFlag(`zoom`,!0))this._zoomToBox(n.d0,t,!0,{source:`box_zoom`,phase:`end`,interactionId:++this._interactionSeq});else if(n.mode===`select-lasso`)if(n.points.length>=3){let e=this._simplifyLassoPoints(n.points);this._sendSelectPolygon(e.map(e=>e.data))}else n.previousLasso&&(this._lassoPolygon=n.previousLasso,this._renderLassoSelection());else{let e=n.d0;n.mode===`select-x`?(e=[n.d0[0],this.view.y0],t[1]=this.view.y1):n.mode===`select-y`&&(e=[this.view.x0,n.d0[1]],t[0]=this.view.x1),this._sendSelect(e,t)}this._ignoreNextClick=!0}else n.previousLasso&&(this._lassoPolygon=n.previousLasso,this._renderLassoSelection());n=null;return}t&&t.moved&&(this._ignoreNextClick=!0,t.changedAxes.length&&this._emitViewChange(`pan_drag`,{axes:t.changedAxes,phase:`end`,interactionId:t.interactionId})),t&&!t.moved&&this._hideTooltip(),t=null}),this._listen(e,`pointercancel`,()=>{this.selRect.style.display=`none`,this.selLasso.style.display=`none`,n?.previousLasso&&(this._lassoPolygon=n.previousLasso,this._renderLassoSelection()),n=null,t=null}),this._listen(e,`pointerleave`,()=>this._pointerHoverExit()),this._listen(document,`pointerover`,e=>{!this._lastHoverXY||this._a11yKeyboardReadout||this.root.contains(e.target)||this._pointerHoverExit()}),this._listen(e,`click`,e=>this._click(e)),this._listen(e,`wheel`,t=>{if(!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._interactionFlag(`wheel_zoom`,!0))return;t.preventDefault();let n=1.0015**t.deltaY,r=e.getBoundingClientRect(),i=(t.clientX-r.left)/r.width,a=1-(t.clientY-r.top)/r.height;this._queueWheelZoom(n,i,a)},{passive:!1}),this._listen(e,`dblclick`,()=>{this._interactionFlag(`navigation`,!0)&&this._interactionFlag(`double_click_reset`,!0)&&this._resetView(!0,`reset`)}),this._listen(e,`keydown`,e=>{e.key===`Escape`&&(n||t)&&(this.selRect.style.display=`none`,this.selLasso.style.display=`none`,n=null,t=null,e.preventDefault(),e.stopImmediatePropagation())}),this._listen(e,`keydown`,e=>this._onA11yKey(e))},_pointerHoverExit(){let e=this._hoverId!==-1;this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._a11yKeyboardReadout=null,this._pickSeq=(this._pickSeq||0)+1,this._hideTooltip(),this._hideCrosshair(),this._interactionFlag(`hover`)&&this._dispatchChartEvent(`leave`,{view:this._eventView(`leave`),active:!1}),e&&this._drawKeepPick()},_a11yPointGroups(){return(this.gpuTraces||[]).filter(e=>q(e.trace.kind).pointPick&&e.tier!==`density`&&e._cpu&&e._cpu.x&&e._cpu.y&&Math.min(e._cpu.x.length,e._cpu.y.length)>0)},_onA11yKey(e){let t={ArrowRight:1,ArrowDown:1,ArrowLeft:-1,ArrowUp:-1}[e.key],n=e.key===`Enter`||e.key===` `;if(t===void 0&&e.key!==`Home`&&e.key!==`End`&&e.key!==`Escape`&&!n)return;if(n){if(!this._interactionFlag(`click`)||!this._hoverTarget)return;e.preventDefault();let t=this._hoverTarget,n=this.canvas.getBoundingClientRect(),r=this._lastHoverXY?.clientX??n.left,i=this._lastHoverXY?.clientY??n.top,a={x:r-n.left,y:i-n.top},o={shift:e.shiftKey===!0,alt:e.altKey===!0,ctrl:e.ctrlKey===!0,meta:e.metaKey===!0},s={row:this._localRow?this._localRow(t):null,trace:t.trace,index:t.index,screen:a,modifiers:o,view:this._eventView(`click`)};if(this._dispatchChartEvent(`click`,s),this.comm){let e={type:`click`,trace:t.trace,index:t.index,screen:a,modifiers:o},n=t.g;n&&n.tier===`density`&&n.drill&&n.drill.seq!==void 0&&(e.drill_seq=n.drill.seq),this.comm.send(e)}return}if(e.key===`Escape`){e.preventDefault();let t=this._hoverId!==-1;this._hideTooltip(),this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._a11yKeyboardReadout=null,this._pickSeq=(this._pickSeq||0)+1,this.a11yLive&&(this.a11yLive.textContent=`Readout closed.`),t&&this._interactionFlag(`hover`)&&this._dispatchChartEvent(`leave`,{view:this._eventView(`leave`),active:!1}),t&&this._drawKeepPick();return}if(e.preventDefault(),this._interactionTransitionActive())return;let r=this._a11yPointGroups(),i=r.reduce((e,t)=>e+Math.min(t._cpu.x.length,t._cpu.y.length),0);if(!i)return;let a=Number.isInteger(this._a11yPointIndex)?this._a11yPointIndex:-1;a=e.key===`Home`?0:e.key===`End`?i-1:a<0?t>0?0:i-1:Math.max(0,Math.min(i-1,a+t)),this._a11yPointIndex=a;let o=a,s=r[0];for(let e of r){let t=Math.min(e._cpu.x.length,e._cpu.y.length);if(ot.width||i<0||i>t.height){this._hideCrosshair();return}let a=e.clientX-n.left,o=e.clientY-n.top;this.crosshairX.style.display=`block`,this.crosshairX.style.left=a+`px`,this.crosshairX.style.top=this.plot.y+`px`,this.crosshairX.style.height=this.plot.h+`px`,this.crosshairY.style.display=`block`,this.crosshairY.style.left=this.plot.x+`px`,this.crosshairY.style.top=o+`px`,this.crosshairY.style.width=this.plot.w+`px`},_hideCrosshair(){this.crosshairX&&(this.crosshairX.style.display=`none`),this.crosshairY&&(this.crosshairY.style.display=`none`)},_click(e){if(this._ignoreNextClick){this._ignoreNextClick=!1;return}if(!this._interactionFlag(`click`))return;let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top,[i,a]=this._dataFromCanvas(n,r),o=this._pickAt(n,r)||this._hoverAt(n,r),s={x:i,y:a,view:this._eventView(`click`),row:o&&this._localRow?this._localRow(o):null,trace:o?o.trace:null,index:o?o.index:null};if(this._dispatchChartEvent(`click`,s),o&&this.comm){let t={type:`click`,trace:o.trace,index:o.index,screen:{x:n,y:r},modifiers:{shift:e.shiftKey===!0,alt:e.altKey===!0,ctrl:e.ctrlKey===!0,meta:e.metaKey===!0}},i=o.g;i&&i.tier===`density`&&i.drill&&i.drill.seq!==void 0&&(t.drill_seq=i.drill.seq),this.comm.send(t)}},_updateBand(e,t){let n=this.canvas.getBoundingClientRect(),r=this.root.getBoundingClientRect();if(e.mode===`select-lasso`){let i=e.points[e.points.length-1],a=Math.max(0,Math.min(n.width,t.clientX-n.left)),o=Math.max(0,Math.min(n.height,t.clientY-n.top)),s=n.left+a,c=n.top+o;e.points.length<2048&&Math.hypot(s-i.x,c-i.y)>=3&&e.points.push({x:s,y:c,data:this._dataFromCanvas(a,o)});let l=e.points.map(e=>[Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,e.x-r.left)),Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,e.y-r.top))]);this.selLasso.style.display=`block`,this.selLasso.style.inset=`0`,this.selLasso.setAttribute(`width`,String(this.root.clientWidth)),this.selLasso.setAttribute(`height`,String(this.root.clientHeight)),this.selLassoPath.setAttribute(`d`,l.map((e,t)=>`${t?`L`:`M`}${e[0]} ${e[1]}`).join(` `)+` Z`);return}let i=Math.min(e.sx,t.clientX)-r.left,a=Math.min(e.sy,t.clientY)-r.top,o=Math.abs(t.clientX-e.sx),s=Math.abs(t.clientY-e.sy),c=this.plot.x,l=this.plot.y,u=Math.min(i+o,c+this.plot.w),d=Math.min(a+s,l+this.plot.h),f=Math.max(i,c),p=Math.max(a,l),m=u,h=d;e.mode===`select-x`&&(p=l,h=l+this.plot.h),e.mode===`select-y`&&(f=c,m=c+this.plot.w),this.selRect.dataset.xyBand=e.mode===`zoom`?`zoom`:`select`,this.selRect.style.display=`block`,this.selRect.style.left=f+`px`,this.selRect.style.top=p+`px`,this.selRect.style.width=Math.max(0,m-f)+`px`,this.selRect.style.height=Math.max(0,h-p)+`px`},_simplifyLassoPoints(e,t=6,n=16){let r=e.filter(e=>e&&Number.isFinite(e.x)&&Number.isFinite(e.y));if(r.length>3){let e=r[0],n=r[r.length-1];Math.hypot(e.x-n.x,e.y-n.y)<=t&&r.pop()}if(r.length<=3)return r.slice();let i=(e,t,n)=>{let r=n.x-t.x,i=n.y-t.y;if(r===0&&i===0)return(e.x-t.x)**2+(e.y-t.y)**2;let a=Math.max(0,Math.min(1,((e.x-t.x)*r+(e.y-t.y)*i)/(r*r+i*i))),o=t.x+a*r,s=t.y+a*i;return(e.x-o)**2+(e.y-s)**2},a=e=>{let t=new Uint8Array(r.length);t[0]=1,t[r.length-1]=1;let n=[[0,r.length-1]],a=e*e;for(;n.length;){let[e,o]=n.pop(),s=-1,c=a;for(let t=e+1;tc&&(s=t,c=n)}s>=0&&(t[s]=1,n.push([e,s],[s,o]))}return r.filter((e,n)=>t[n])},o=a(t);if(o.length<3&&(o=[r[0],r[Math.floor(r.length/2)],r[r.length-1]]),o.length>n){let e=t,i=Math.max(t,1);for(let t=0;t<16&&o.length>n;t++)e=i,i*=2,o=a(i);for(let t=0;t<12;t++){let t=(e+i)/2,r=a(t);r.length>n?e=t:(i=t,o=r)}o.length<3&&(o=[r[0],r[Math.floor(r.length/2)],r[r.length-1]])}return o},_clearLassoOverlay(){this._lassoPolygon=null,this.selLasso&&(this.selLasso.style.display=`none`,this.selLassoPath?.removeAttribute(`d`),this.selLassoHandles?.replaceChildren())},_renderLassoSelection(){let e=this._lassoPolygon;if(!this.selLasso||!this.selLassoPath||!this.selLassoHandles||!Array.isArray(e)||e.length<3)return;let[t,n]=this._axisRange(`x`),[r,i]=this._axisRange(`y`),a=this._axis(`x`),o=this._axis(`y`),s=this._axisCoord(a,t),c=this._axisCoord(a,n),l=this._axisCoord(o,r),u=this._axisCoord(o,i);if(![s,c,l,u].every(Number.isFinite)||s===c||l===u)return;let d=e.map(e=>{let t=this._axisCoord(a,e[0]),n=this._axisCoord(o,e[1]),r=this.plot.x+(t-s)/(c-s)*this.plot.w,i=this.plot.y+(u-n)/(u-l)*this.plot.h;return[Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,r)),Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,i))]});if(d.flat().every(Number.isFinite)){for(this.selLasso.style.display=`block`,this.selLasso.style.inset=`0`,this.selLasso.setAttribute(`width`,String(this.root.clientWidth)),this.selLasso.setAttribute(`height`,String(this.root.clientHeight)),this.selLassoPath.setAttribute(`d`,d.map((e,t)=>`${t?`L`:`M`}${e[0]} ${e[1]}`).join(` `)+` Z`);this.selLassoHandles.childElementCountd.length;)this.selLassoHandles.lastElementChild.remove();[...this.selLassoHandles.children].forEach((e,t)=>{e.dataset.xySelectionLassoHandle=String(t),e.setAttribute(`cx`,String(d[t][0])),e.setAttribute(`cy`,String(d[t][1])),e.setAttribute(`aria-label`,`Lasso point ${t+1}`)})}},_sendSelect(e,t,n={}){this._clearLassoOverlay();let r=Math.min(e[0],t[0]),i=Math.max(e[0],t[0]),a=Math.min(e[1],t[1]),o=Math.max(e[1],t[1]),s={x0:r,x1:i,y0:a,y1:o};this._historyRecord({source:n.source,interactionId:n.interactionId,history:n.history}),this._stateSelection={range:{...s}},this._lastBrush={mode:`box`,x0:r,x1:i,y0:a,y1:o},this._broadcastLinkedSelection({range:s}),this._dispatchChartEvent(`brush`,{range:s,view:this._eventView(`brush`)}),this.comm?this.comm.send({type:`select`,x0:r,x1:i,y0:a,y1:o}):this._selectLocal(r,i,a,o)},_sendSelectPolygon(e,t={}){if(!Array.isArray(e)||e.length<3)return;let n=e.map(e=>[e[0],e[1]]);n.every(e=>e.every(Number.isFinite))&&(this._historyRecord({source:t.source,interactionId:t.interactionId,history:t.history}),this._stateSelection={polygon:n.map(e=>[...e])},this._lassoPolygon=n,this._lastBrush={mode:`poly`,points:n},this._broadcastLinkedSelection({polygon:n}),this._renderLassoSelection(),this._dispatchChartEvent(`brush`,{polygon:n,view:this._eventView(`brush`)}),this.comm?this.comm.send({type:`select_polygon`,points:n}):this._selectLocalPolygon(n))},_selectLocalPolygon(e,t={}){let n=e.map(e=>e[0]),r=e.map(e=>e[1]),i=Math.min(...n),a=Math.max(...n),o=Math.min(...r),s=Math.max(...r),c=(t,n)=>{let r=!1;for(let i=0,a=e.length-1;in!=l>n&&t<(c-o)*(n-s)/(l-s)+o&&(r=!r)}return r},l=0;for(let e of this.gpuTraces){if(!e._cpu||e.tier===`density`)continue;let t=e._cpu.x,n=e._cpu.y,r=e._cpu.xMeta||e.xMeta,u=e._cpu.yMeta||e.yMeta,d=r.offset,f=r.scale||1,p=u.offset,m=u.scale||1,h=new Float32Array(e.n),g=0;for(let r=0;r=i&&e<=a&&l>=o&&l<=s&&c(e,l)&&(h[r]=1,g++)}this._applySelMask(e,h),l+=g}this._selectionCount=l,this.draw(),t.dispatch!==!1&&this._dispatchChartEvent(`select`,{total:l,polygon:e,view:this._eventView(`select`)})},_selectLocal(e,t,n,r,i={}){let a=0;for(let i of this.gpuTraces){if(!i._cpu||i.tier===`density`)continue;let o=i._cpu.x,s=i._cpu.y,c=i._cpu.xMeta||i.xMeta,l=i._cpu.yMeta||i.yMeta,u=c.offset,d=c.scale||1,f=l.offset,p=l.scale||1,m=new Float32Array(i.n),h=0;for(let a=0;a=e&&i<=t&&c>=n&&c<=r&&(m[a]=1,h++)}this._applySelMask(i,m),a+=h}this._selectionCount=a,this.draw(),i.dispatch!==!1&&this._dispatchChartEvent(`select`,{total:a,range:{x0:e,x1:t,y0:n,y1:r},view:this._eventView(`select`)})},_applySelMask(e,t){let n=this.gl;e.selBuf||=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,e.selBuf),n.bufferData(n.ARRAY_BUFFER,t,n.STATIC_DRAW),e.selActive=!0},_clearSelection(e={}){this._clearLassoOverlay(),e.dispatch!==!1&&this._stateSelection!==null&&this._stateSelection!==void 0&&this._historyRecord({source:e.source,interactionId:e.interactionId,history:e.history}),this._stateSelection=null;for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);this._selectionCount=0,this._lastBrush=null,e.broadcast!==!1&&this._broadcastLinkedSelection({clear:!0}),e.dispatch!==!1&&this._interactionFlag(`select`,!0)&&(this.comm&&this.comm.send({type:`select_clear`}),this._dispatchChartEvent(`select`,{total:0,view:this._eventView(`select_clear`)}))},_clampModebar(e,t){let n=this._modebar;if(!n||!this.root)return;let r=e??(Number.parseFloat(n.style.left)||0),i=t??(Number.parseFloat(n.style.top)||0),a=Math.max(0,this.root.clientWidth-n.offsetWidth),o=Math.max(0,this.root.clientHeight-n.offsetHeight);n.style.left=`${Math.max(0,Math.min(a,r))}px`,n.style.top=`${Math.max(0,Math.min(o,i))}px`},_buildModebar(e){if(this.spec.show_modebar===!1)return;let t=document.createElement(`div`);t.style.cssText=`position:absolute;top:${this.plot.y+4}px;left:${this.plot.x+4}px;z-index:6;display:flex;opacity:0;pointer-events:none;transition:opacity .15s;`,this._applySlot(t,`modebar`),t.setAttribute(`role`,`toolbar`),t.setAttribute(`aria-label`,`Chart controls`),this._modebar=t,this._modeBtns={},this._modebarMoved=!1;let n=()=>{},r=()=>{},i=()=>{},a=e=>{let n=e||this._modebarDragging||t.contains(document.activeElement);t.style.opacity=n?`1`:`0`,t.style.pointerEvents=n?`auto`:`none`};this._listen(e,`pointerenter`,()=>a(!0)),this._listen(e,`pointerleave`,()=>{a(!1),n(!1),r(!1),i(!1)}),this._listen(t,`focusin`,()=>a(!0)),this._listen(t,`focusout`,n=>{!t.contains(n.relatedTarget)&&!e.matches(`:hover`)&&a(!1)});let o=document.createElement(`button`);o.type=`button`,o.title=`Click for toolbar options; drag to move`,o.setAttribute(`aria-label`,`Toolbar options`),o.setAttribute(`aria-haspopup`,`menu`),o.setAttribute(`aria-expanded`,`false`),o.dataset.xyModebarDragHandle=``,o.dataset.xyModebarExport=``,o.dataset.xyModebarExportTrigger=``,o.innerHTML=this._icon(`drag`),o.style.cssText=`display:flex;align-items:center;justify-content:center;pointer-events:auto;touch-action:none;`,this._applySlot(o,`modebar_button`),t.appendChild(o);let s=null,c=0;this._listen(o,`pointerdown`,e=>{if(e.pointerType===`mouse`&&e.button!==0)return;e.stopPropagation();let n=t.getBoundingClientRect();s={pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,dx:e.clientX-n.left,dy:e.clientY-n.top,moved:!1};try{o.setPointerCapture(e.pointerId)}catch{}a(!0)}),this._listen(o,`pointermove`,a=>{if(!s||a.pointerId!==s.pointerId)return;let o=Math.hypot(a.clientX-s.startX,a.clientY-s.startY);if(!s.moved){if(o<6)return;s.moved=!0,this._modebarDragging=!0,this._modebarMoved=!0,t.style.transition=`none`,n(!1),r(!1),i(!1)}let c=e.getBoundingClientRect(),l=a.clientX-c.left-s.dx,u=a.clientY-c.top-s.dy;this._clampModebar(l,u)});let l=n=>{if(!s||n.pointerId!==s.pointerId)return;let r=s.moved,i=n.type===`pointercancel`;s=null,this._modebarDragging=!1,t.style.transition=`opacity .15s`,a(e.matches(`:hover`)),(r||i)&&(c=performance.now()+100)};this._listen(o,`pointerup`,l),this._listen(o,`pointercancel`,l),this._listen(o,`click`,e=>{if(e.stopPropagation(),performance.now()<=c){c=0;return}i(!this._exportMenuOpen)});let u=(e,n,r,i)=>{let a=document.createElement(`button`);return a.type=`button`,a.title=n,a.setAttribute(`aria-label`,n),i&&a.setAttribute(`aria-pressed`,`false`),a.innerHTML=this._icon(e),a.style.cssText=`display:flex;align-items:center;justify-content:center;pointer-events:auto;`,this._applySlot(a,`modebar_button`),this._listen(a,`pointerdown`,e=>e.stopPropagation()),this._listen(a,`click`,e=>{e.stopPropagation(),r()}),t.appendChild(a),i&&(this._modeBtns[i]=a),a},d=this._interactionFlag(`navigation`,!0),f=d&&this._interactionFlag(`pan`,!0),p=d&&this._interactionFlag(`zoom`,!0),m=p&&this._interactionFlag(`zoom_buttons`,!0),h=p&&this._interactionFlag(`box_zoom`,!0),g=d&&this._resetAxisPolicy().length>0,_=m||h||g,v=null,y=null;if(this._zoomMenuButton=null,this._zoomMenuLabel=null,_){v=u(`zoommenu`,`Zoom controls`,()=>{n(!this._zoomMenuOpen)}),this._zoomMenuButton=v,v.dataset.xyModebarMenuTrigger=``,v.replaceChildren();let e=document.createElement(`span`);e.dataset.xyModebarZoomPercent=``,e.textContent=`100%`,v.appendChild(e),y=document.createElement(`span`),y.dataset.xyModebarMenuIndicator=``,y.innerHTML=this._icon(`chevrondown`),v.appendChild(y),this._zoomMenuLabel=e,v.setAttribute(`aria-haspopup`,`menu`),v.setAttribute(`aria-expanded`,`false`)}let b=this._interactionFlag(`brush`,!0)&&this._interactionFlag(`select`,!0),x=null,S=null,C=null;b&&(x=u(`select`,`Selection controls`,()=>{r(!this._selectMenuOpen)}),x.dataset.xyModebarSelect=``,x.dataset.xyModebarSelectTrigger=``,x.setAttribute(`aria-haspopup`,`menu`),x.setAttribute(`aria-expanded`,`false`),x.replaceChildren(),C=document.createElement(`span`),C.dataset.xyModebarSelectIcon=``,C.innerHTML=this._icon(`select`),x.appendChild(C),S=document.createElement(`span`),S.dataset.xyModebarMenuIndicator=``,S.innerHTML=this._icon(`chevrondown`),x.appendChild(S),this._selectMenuButton=x,this._selectMenuIcon=C),f&&u(`pan`,`Pan`,()=>this._setDragMode(`pan`),`pan`),d&&this._historyEnabled()&&(this._historyBackBtn=u(`historyback`,`Back to previous view`,()=>this._historyBack()),this._historyBackBtn.dataset.xyModebarHistory=`back`,this._historyForwardBtn=u(`historyforward`,`Forward to next view`,()=>this._historyForward()),this._historyForwardBtn.dataset.xyModebarHistory=`forward`,this._updateHistoryButtons());let w=null;_&&(w=document.createElement(`div`),w.dataset.xyModebarMenu=``,w.setAttribute(`role`,`menu`),w.setAttribute(`aria-label`,`Zoom controls`),w.style.cssText=`position:absolute;display:none;flex-direction:column;z-index:7;pointer-events:auto;`,t.appendChild(w));let T=[],E=(e,t,r,i,a=!1)=>{let o=document.createElement(`button`);o.type=`button`,o.tabIndex=-1,o.dataset.xyModebarMenuItem=e,a&&(o.dataset.xySeparator=``),o.setAttribute(`role`,`menuitem`),o.style.cssText=`display:flex;align-items:center;pointer-events:auto;`,this._applySlot(o,`modebar_button`);let s=document.createElement(`span`);s.dataset.xyModebarMenuIcon=``,s.innerHTML=this._icon(e),o.appendChild(s);let c=document.createElement(`span`);return c.textContent=t,o.appendChild(c),this._listen(o,`pointerdown`,e=>e.stopPropagation()),this._listen(o,`click`,e=>{e.stopPropagation(),n(!1,!0),r()}),w.appendChild(o),T.push(o),i&&(this._modeBtns[i]=o),o};_&&(m&&(E(`zoomin`,this._actionLabel(`Zoom In`,this._axisPolicy(`zoom_axes`)),()=>this._zoomBy(.5,!0,`zoom_in`)),E(`zoomout`,this._actionLabel(`Zoom Out`,this._axisPolicy(`zoom_axes`)),()=>this._zoomBy(2,!0,`zoom_out`))),h&&E(`zoom`,this._actionLabel(`Box Zoom`,this._axisPolicy(`zoom_axes`)),()=>this._setDragMode(`zoom`),`zoom`),g&&E(`reset`,this._actionLabel(`Reset View`,this._resetAxisPolicy()),()=>this._resetView(!0,`reset`),null,m||h));let D=document.createElement(`div`);D.dataset.xyModebarMenu=``,D.dataset.xyModebarSelectMenu=``,D.setAttribute(`role`,`menu`),D.setAttribute(`aria-label`,`Selection controls`),D.style.cssText=`position:absolute;display:none;flex-direction:column;z-index:7;pointer-events:auto;`,t.appendChild(D);let O=[],k=(e,t,n)=>{let i=document.createElement(`button`);i.type=`button`,i.tabIndex=-1,i.dataset.xyModebarMenuItem=e,i.dataset.xyModebarSelectItem=n,i.setAttribute(`role`,`menuitem`),i.style.cssText=`display:flex;align-items:center;pointer-events:auto;`,this._applySlot(i,`modebar_button`);let a=document.createElement(`span`);a.dataset.xyModebarMenuIcon=``,a.innerHTML=this._icon(e),i.appendChild(a);let o=document.createElement(`span`);o.textContent=t,i.appendChild(o),this._listen(i,`pointerdown`,e=>e.stopPropagation()),this._listen(i,`click`,e=>{e.stopPropagation(),r(!1,!0),this._setDragMode(n)}),D.appendChild(i),O.push(i),this._modeBtns[n]=i};b&&(k(`select`,`Box Select`,`select`),k(`lasso`,`Lasso Select`,`select-lasso`),k(`selectx`,`X Range`,`select-x`),k(`selecty`,`Y Range`,`select-y`));let A=document.createElement(`div`);A.dataset.xyModebarMenu=``,A.dataset.xyModebarExportMenu=``,A.setAttribute(`role`,`menu`),A.setAttribute(`aria-label`,`Toolbar options`),A.style.cssText=`position:absolute;display:none;flex-direction:column;z-index:7;pointer-events:auto;`,t.appendChild(A);let j=[],ee=(e,t,n,r=!1)=>{let a=document.createElement(`button`);a.type=`button`,a.tabIndex=-1,a.dataset.xyModebarMenuItem=e,a.dataset.xyModebarExportItem=e,r&&(a.dataset.xySeparator=``),a.setAttribute(`role`,`menuitem`),a.style.cssText=`display:flex;align-items:center;pointer-events:auto;`,this._applySlot(a,`modebar_button`);let o=document.createElement(`span`);o.dataset.xyModebarMenuIcon=``,o.innerHTML=this._icon(e),a.appendChild(o);let s=document.createElement(`span`);return s.textContent=t,a.appendChild(s),this._listen(a,`pointerdown`,e=>e.stopPropagation()),this._listen(a,`click`,e=>{e.stopPropagation(),i(!1,!0),Promise.resolve(n()).catch(e=>console.error(`xy: ${t} failed`,e))}),A.appendChild(a),j.push(a),a},te={png:[`Export PNG`,()=>this._exportRaster(`png`)],jpeg:[`Export JPEG`,()=>this._exportRaster(`jpeg`)],webp:[`Export WebP`,()=>this._exportRaster(`webp`)],svg:[`Export SVG`,()=>this._exportSvg()],csv:[`Export CSV`,()=>this._exportCsv()]},ne=Array.isArray(this._exportConfig().formats)?this._exportConfig().formats:[`png`,`svg`,`csv`];for(let e of ne){let t=te[e];t&&ee(e,t[0],t[1])}v&&(n=(n,a=!1)=>{let o=!!n;if(o&&(r(!1),i(!1)),this._zoomMenuOpen=o,v.setAttribute(`aria-expanded`,String(o)),!o){w.style.display=`none`,y.style.transform=`none`,a&&v.focus();return}w.style.display=`flex`,w.style.visibility=`hidden`;let s=e.getBoundingClientRect(),c=t.getBoundingClientRect(),l=c.left-s.left,u=c.top-s.top,d=t.offsetHeight+6,f=-w.offsetHeight-6,p=c.bottom+6+w.offsetHeight<=s.bottom?d:f;y.style.transform=p===f?`rotate(180deg)`:`none`;let m=e.clientWidth-l-w.offsetWidth,h=e.clientHeight-u-w.offsetHeight;w.style.left=`${Math.max(-l,Math.min(m,v.offsetLeft))}px`,w.style.top=`${Math.max(-u,Math.min(h,p))}px`,w.style.visibility=`visible`}),r=(r,a=!1)=>{if(!x)return;let o=!!r;if(o&&(n(!1),i(!1)),this._selectMenuOpen=o,x.setAttribute(`aria-expanded`,String(o)),!o){D.style.display=`none`,S.style.transform=`none`,a&&x.focus();return}D.style.display=`flex`,D.style.visibility=`hidden`;let s=e.getBoundingClientRect(),c=t.getBoundingClientRect(),l=c.left-s.left,u=c.top-s.top,d=t.offsetHeight+6,f=-D.offsetHeight-6,p=c.bottom+6+D.offsetHeight<=s.bottom?d:f;S.style.transform=p===f?`rotate(180deg)`:`none`;let m=e.clientWidth-l-D.offsetWidth,h=e.clientHeight-u-D.offsetHeight;D.style.left=`${Math.max(-l,Math.min(m,x.offsetLeft))}px`,D.style.top=`${Math.max(-u,Math.min(h,p))}px`,D.style.visibility=`visible`},i=(i,a=!1)=>{let s=!!i&&j.length>0;if(s&&(n(!1),r(!1)),this._exportMenuOpen=s,o.setAttribute(`aria-expanded`,String(s)),!s){A.style.display=`none`,a&&o.focus();return}A.style.display=`flex`,A.style.visibility=`hidden`;let c=e.getBoundingClientRect(),l=t.getBoundingClientRect(),u=l.left-c.left,d=l.top-c.top,f=t.offsetHeight+6,p=-A.offsetHeight-6,m=l.bottom+6+A.offsetHeight<=c.bottom?f:p,h=e.clientWidth-u-A.offsetWidth,g=e.clientHeight-d-A.offsetHeight;A.style.left=`${Math.max(-u,Math.min(h,o.offsetLeft))}px`,A.style.top=`${Math.max(-d,Math.min(g,m))}px`,A.style.visibility=`visible`},this._closeModebarMenu=()=>{n(!1),r(!1),i(!1)},this._syncModebarSelect=()=>{if(!x)return;let e=!!this._pickable;e||(r(!1),this.dragMode.startsWith(`select`)&&this._setDragMode(`pan`)),x.style.display=e?`flex`:`none`},this._syncModebarSelect(),this._listen(document,`pointerdown`,e=>{this._zoomMenuOpen&&!t.contains(e.target)&&n(!1),this._selectMenuOpen&&!t.contains(e.target)&&r(!1),this._exportMenuOpen&&!t.contains(e.target)&&i(!1)}),v&&(this._listen(v,`keydown`,e=>{if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`)return;e.preventDefault(),e.stopPropagation(),n(!0);let t=e.key===`ArrowDown`?0:T.length-1;T[t].focus()}),this._listen(w,`keydown`,e=>{if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),n(!1,!0);return}if(![`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key))return;e.preventDefault();let t=T.indexOf(document.activeElement),r=e.key===`Home`?0:e.key===`End`?T.length-1:t;e.key===`ArrowDown`&&(r=(t+1)%T.length),e.key===`ArrowUp`&&(r=(t-1+T.length)%T.length),T[r].focus()})),x&&(this._listen(x,`keydown`,e=>{if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`)return;e.preventDefault(),e.stopPropagation(),r(!0);let t=e.key===`ArrowDown`?0:O.length-1;O[t].focus()}),this._listen(D,`keydown`,e=>{if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),r(!1,!0);return}if(![`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key))return;e.preventDefault();let t=O.indexOf(document.activeElement),n=e.key===`Home`?0:e.key===`End`?O.length-1:t;e.key===`ArrowDown`&&(n=(t+1)%O.length),e.key===`ArrowUp`&&(n=(t-1+O.length)%O.length),O[n].focus()})),this._listen(o,`keydown`,e=>{if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`||!j.length)return;e.preventDefault(),e.stopPropagation(),i(!0);let t=e.key===`ArrowDown`?0:j.length-1;j[t].focus()}),this._listen(A,`keydown`,e=>{if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),i(!1,!0);return}if(![`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key))return;e.preventDefault();let t=j.indexOf(document.activeElement),n=e.key===`Home`?0:e.key===`End`?j.length-1:t;e.key===`ArrowDown`&&(n=(t+1)%j.length),e.key===`ArrowUp`&&(n=(t-1+j.length)%j.length),j[n].focus()}),e.appendChild(t),this._fitModebar(),a(e.matches(`:hover`)),this._setDragMode(this.dragMode)},_fitModebar(){let e=this._modebar;if(e){if(this._closeModebarMenu?.(),this._modebarMoved||(e.style.top=`${this.plot.y+4}px`,e.style.left=`${this.plot.x+4}px`),e.style.display=`flex`,!(e.offsetWidth+8<=this.plot.w&&e.offsetHeight+8<=this.plot.h)){e.style.display=`none`;return}this._clampModebar()}},_setDragMode(e){this.dragMode=e,this.canvas&&(this.canvas.dataset.xyDragmode=e);for(let[t,n]of Object.entries(this._modeBtns||{}))n.classList.toggle(`xy-active`,t===e),n.setAttribute(`aria-pressed`,String(t===e));this._zoomMenuButton?.classList.toggle(`xy-active`,e===`zoom`),this._selectMenuButton?.classList.toggle(`xy-active`,e.startsWith(`select`));let t={select:[`select`,`Box Select`],"select-lasso":[`lasso`,`Lasso Select`],"select-x":[`selectx`,`X Range`],"select-y":[`selecty`,`Y Range`]}[e];if(t&&this._selectMenuButton&&this._selectMenuIcon){let[e,n]=t;this._selectMenuIcon.innerHTML=this._icon(e),this._selectMenuButton.title=`Selection controls: ${n}`,this._selectMenuButton.setAttribute(`aria-label`,`Selection controls: ${n}`)}},_actionLabel(e,t){let n=Array.isArray(t)?t:[...t||[]];return n.length?`${e} on ${n.join(` and `)} ${n.length===1?`axis`:`axes`}`:e},_updateZoomMenuLabel(){if(!this._zoomMenuLabel||!this.view||!this.view0)return;let e=(e,t,n,r,i)=>{let a=this._axis(e),o=Math.abs(this._axisCoord(a,n)-this._axisCoord(a,t)),s=Math.abs(this._axisCoord(a,i)-this._axisCoord(a,r));return Number.isFinite(o)&&o>0&&Number.isFinite(s)&&s>0?s/o*100:null},t=[...this._zoomAxes()].map(t=>{let[n,r]=this._axisRange(t),[i,a]=this._axisRange(t,this.view0);return[t,e(t,n,r,i,a)]}).filter(e=>e[1]!==null),n=t[0]?.[1]??100,r=Math.round(n),i=n<1?`<1%`:`${r}%`,a=r>999?`${String(r).slice(0,3)}…%`:i;if(this._zoomMenuLabel.dataset.xyZoomExact===i&&this._zoomMenuLabel.textContent===a)return;this._zoomMenuLabel.textContent=a,this._zoomMenuLabel.dataset.xyZoomExact=i;let o=t.map(([e,t])=>`${e} ${Math.round(t)}%`).join(`, `);this._zoomMenuButton.title=`Zoom controls (${o||i})`,this._zoomMenuButton.setAttribute(`aria-label`,`Zoom controls, ${o||i}`)},_prefersReducedMotion(){return window.matchMedia?.(`(prefers-reduced-motion: reduce)`)?.matches===!0},_cancelViewAnimation(){this._animRaf&&cancelAnimationFrame(this._animRaf),this._animRaf=null,this._viewAnim=null},_setView(e,t={}){if(this._destroyed)return[];let n=this._clampView(this._viewFrom(e),{anchors:t.anchors}),r=this._axisIds().filter(e=>{let t=this._axisRange(e),r=this._axisRange(e,n);return t[0]!==r[0]||t[1]!==r[1]});if(!r.length)return[];this._viewAnim||this._historyRecord({source:t.source||`programmatic`,interactionId:t.interactionId,history:t.history});let i=t.animate===!0&&!this._prefersReducedMotion(),a=t.duration||180;if(!i||a<=0)return this._cancelViewAnimation(),this.view=n,this.draw(),t.request!==!1&&this._scheduleViewRequest(),this._emitViewChange(t.source||`programmatic`,{axes:r,phase:t.phase||`end`,interactionId:t.interactionId,broadcast:t.broadcast}),r;clearTimeout(this._viewTimer),this.seq+=1;let o=t.request!==!1,s=t.requestDelay??Math.min(55,Math.max(24,a*.35)),c=t.requestMaxWait??130;o&&this._scheduleViewRequest(n,{seq:this.seq,delay:s,maxWait:c});let l=this._now(),u=Math.max(18,a/5);if(this._viewAnim)return Object.assign(this._viewAnim,{target:n,tau:u,changedAxes:[...new Set([...this._viewAnim.changedAxes,...r])],source:t.source||`programmatic`,phase:t.phase||`end`,interactionId:t.interactionId,broadcast:t.broadcast}),r;this._viewAnim={target:n,last:l,tau:u,changedAxes:r,source:t.source||`programmatic`,phase:t.phase||`end`,interactionId:t.interactionId,broadcast:t.broadcast};let d=(e,t,n)=>e+(t-e)*n,f=e=>Math.max(...this._axisIds().map(t=>{let[n,r]=this._axisRange(t,e);return Math.abs(r-n)}),1e-12),p=(e,t)=>{let n=f(t)*1e-4;return Math.max(...this._axisIds().flatMap(n=>{let r=this._axisRange(n,e),i=this._axisRange(n,t);return[Math.abs(r[0]-i[0]),Math.abs(r[1]-i[1])]}))<=n},m=e=>{if(this._destroyed){this._animRaf=null;return}let t=this._viewAnim;if(!t){this._animRaf=null;return}let n=Math.max(0,Math.min(64,e-t.last));t.last=e;let r=1-Math.exp(-n/t.tau),i=p(this.view,t.target)?1:r,a={};for(let e of this._axisIds()){let n=this._axisRange(e),r=this._axisRange(e,t.target);a[e]=[d(n[0],r[0],i),d(n[1],r[1],i)]}this.view=this._copyView({ranges:a}),i<1?(this.draw(),this._animRaf=requestAnimationFrame(m)):(this._animRaf=null,this._viewAnim=null,this.view=t.target,this._lastLabelDraw=null,this.draw(),this._emitViewChange(t.source,{axes:t.changedAxes,phase:t.phase,interactionId:t.interactionId,broadcast:t.broadcast}))};return this._animRaf=requestAnimationFrame(m),r},_zoomLimitForAxis(e){if(!this._axisPolicy(`zoom_axes`).includes(e))return[null,null];let t=this.interaction?.zoom_limits;if(t&&typeof t==`object`&&!Array.isArray(t)){let n=t[e];if(Array.isArray(n)&&n.length===2)return n}return[1,null]},_clampAxisRange(e,t,n,r=.5){let i=this._axis(e),a=this._axisCoord(i,t),o=this._axisCoord(i,n);if(![a,o].every(Number.isFinite)||a===o)return this._axisRange(e,this.view0);let s=this.view0?.ranges?.[e];if(s){let t=this._axisCoord(i,s[0]),n=this._axisCoord(i,s[1]),c=Math.abs(n-t),[l,u]=this._zoomLimitForAxis(e),d=Number(l),f=Number(u),p=Number.isFinite(d)&&d>0?c/d:1/0,m=Number.isFinite(f)&&f>0?c/f:0,h=Math.abs(o-a),g=Math.max(m,Math.min(p,h));if(Number.isFinite(g)&&g>0&&g!==h){let e=o=l-c)d=c,f=l;else{let e=Math.max(c-d,Math.min(l-f,0));d+=e,f+=e}let p=u?f:d,m=u?d:f;return[this._axisValue(i,p),this._axisValue(i,m)]},_clampView(e,t={}){let n=this._viewFrom(e,this.view0),r={};for(let e of this._axisIds()){let[i,a]=this._axisRange(e,n);r[e]=this._clampAxisRange(e,i,a,t.anchors?.[e]??.5)}return this._copyView({ranges:r})},_zoomAxes(){return new Set(this._axisPolicy(`zoom_axes`))},_zoomBy(e,t=!1,n=e<1?`zoom_in`:`zoom_out`){let r=this._viewAnim?this._viewAnim.target:this.view,i=this._zoomAxes(),a=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,r)]]));for(let t of i){let[n,r]=a[t],i=this._zoomAxisRange(t,n,r,e,.5);i&&(a[t]=i)}this._setView({ranges:a},{animate:t,source:n,phase:`end`,interactionId:++this._interactionSeq})},_zoomAxisRange(e,t,n,r,i){let a=this._axis(e),o=this._axisCoord(a,t),s=this._axisCoord(a,n);if(![o,s].every(Number.isFinite)||o===s)return null;let c=o+i*(s-o);if(r<1){let e=Math.max(Math.abs(c),1e-30)*1e-12;if(Math.abs((s-o)*r)1&&this.view0){let t=this._axisRange(e,this.view0),n=this._axisCoord(a,t[0]),r=this._axisCoord(a,t[1]),o=Math.abs(r-n);if([n,r].every(Number.isFinite)&&o>0&&Math.abs(u-l)>o){let e=o*Math.sign(u-l);return[this._axisValue(a,c-i*e),this._axisValue(a,c+(1-i)*e)]}}return[this._axisValue(a,l),this._axisValue(a,u)]},_zoomAt(e,t,n,r=!1,i=120,a={}){let o=this._viewAnim?this._viewAnim.target:this.view,s=Array.isArray(a.axes)?new Set(a.axes.filter(e=>this._zoomAxes().has(e))):this._zoomAxes(),c=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,o)]])),l={};for(let r of s){let i=this._axisDim(r)===`x`?t:n,[a,o]=c[r],s=this._zoomAxisRange(r,a,o,e,i);s&&(c[r]=s),l[r]=i}return this._setView({ranges:c},{animate:r,duration:i,anchors:l,source:a.source||`wheel_zoom`,phase:a.phase||`update`,interactionId:a.interactionId})},_queueWheelZoom(e,t,n,r=null){if(!Number.isFinite(e)||e<=0)return;clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null;let i=Array.isArray(r)?r.join(`,`):``;if(this._wheelGesture&&this._wheelGesture.scopeKey!==i){let e=this._wheelGesture;this._wheelGesture=null,e.axes.size&&this._emitViewChange(`wheel_zoom`,{axes:[...e.axes],phase:`end`,interactionId:e.interactionId})}this._wheelGesture||={interactionId:++this._interactionSeq,axes:new Set,scopeKey:i},this._pendingWheelZoom||={factor:1,fx:t,fy:n,interactionId:this._wheelGesture.interactionId,axes:[],axesScope:r},this._pendingWheelZoom.factor*=e,this._pendingWheelZoom.fx=t,this._pendingWheelZoom.fy=n,this._pendingWheelZoom.axesScope=r,!this._wheelZoomRaf&&(this._wheelZoomRaf=requestAnimationFrame(()=>{this._wheelZoomRaf=null;let e=this._pendingWheelZoom;if(this._pendingWheelZoom=null,!(!e||this._destroyed)){e.axes=this._zoomAt(e.factor,e.fx,e.fy,!1,120,{source:`wheel_zoom`,phase:`update`,interactionId:e.interactionId,axes:e.axesScope||void 0})||[];for(let t of e.axes)this._wheelGesture?.axes.add(t);clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=setTimeout(()=>{let e=this._wheelGesture;this._wheelGesture=null,!(this._destroyed||!e||!e.axes.size)&&this._emitViewChange(`wheel_zoom`,{axes:[...e.axes],phase:`end`,interactionId:e.interactionId})},90)}}))},_zoomToBox(e,t,n=!1,r={}){let i=this._zoomAxes(),a={};for(let n of[`x`,`y`]){let r=this._axis(n),[i,o]=this._axisRange(n),s=this._axisCoord(r,i),c=this._axisCoord(r,o),l=this._axisCoord(r,e[n===`x`?0:1]),u=this._axisCoord(r,t[n===`x`?0:1]);if(![s,c,l,u].every(Number.isFinite)||s===c)return[];a[n]=[(l-s)/(c-s),(u-s)/(c-s)]}let o=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),s={};for(let e of i){let t=this._axis(e),[n,r]=o[e],i=this._axisCoord(t,n),c=this._axisCoord(t,r),[l,u]=a[this._axisDim(e)],d=i+l*(c-i),f=i+u*(c-i),p=Math.max(Math.abs(d),Math.abs(f),1e-30)*1e-12;if(!Number.isFinite(d)||!Number.isFinite(f)||Math.abs(f-d)[e,[...this._axisRange(e)]]));for(let e of n||this._resetAxisPolicy())r[e]=[...this._axisRange(e,this.view0)];return this._setView({ranges:r},{animate:e,source:t,phase:`end`,interactionId:++this._interactionSeq})},_exportConfig(){let e=this.spec&&this.spec.export;return e&&typeof e==`object`?e:{}},_exportFilename(e){let t=this._exportConfig().filename;return typeof t==`string`&&t?`${t}.${e}`:`${String(this.spec.title||`xy-chart`).trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`xy-chart`}.${e}`},_downloadExport(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,r.style.display=`none`,document.body.appendChild(r),r.click(),r.remove(),setTimeout(()=>URL.revokeObjectURL(n),0)},_exportSvgMarkup(){this._drawNow?.(),this.gl?.finish?.();let e=this.size.w,t=this.size.h,n=this.root.cloneNode(!0);n.style.width=`${e}px`,n.style.height=`${t}px`,n.style.margin=`0`,n.setAttribute(`xmlns`,`http://www.w3.org/1999/xhtml`);let r=getComputedStyle(this.root),i=[`color`,`font-family`,`font-size`,`font-style`,`font-weight`,`letter-spacing`,`line-height`],a=[`--chart-bg`,`--chart-text`,`--chart-grid`,`--chart-axis`,`--chart-tooltip-bg`,`--chart-tooltip-text`,`--chart-legend-bg`,`--chart-badge-bg`,`--chart-badge-text`,`--chart-modebar-bg`,`--chart-modebar-active`,`--chart-selection`,`--chart-selection-fill`,`--chart-zoom-selection`,`--chart-zoom-selection-fill`,`--chart-crosshair`,`--chart-annotation-text`,`--chart-cursor`,`--chart-cursor-pan`];for(let e=0;ee.remove());let c=document.createElement(`style`);return c.textContent=C,n.prepend(c),`${new XMLSerializer().serializeToString(n)}`},_exportSvg(){let e=this._exportSvgMarkup();this._downloadExport(new Blob([e],{type:`image/svg+xml;charset=utf-8`}),this._exportFilename(`svg`))},_exportPng(){return this._exportRaster(`png`)},_exportRaster(e){let t=this._exportSvgMarkup(),n=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`,r=new Image,i=this._exportConfig(),a={png:`image/png`,jpeg:`image/jpeg`,webp:`image/webp`}[e];return a?new Promise((t,o)=>{r.onload=()=>{let n=Number.isFinite(i.scale)&&i.scale>0?i.scale:Math.max(1,window.devicePixelRatio||1),s=document.createElement(`canvas`);s.width=Math.round(this.size.w*n),s.height=Math.round(this.size.h*n);let c=s.getContext(`2d`),l=typeof i.background==`string`&&i.background!==`auto`?i.background:null,u=l===`transparent`||l===`none`;e===`jpeg`?(c.fillStyle=l&&!u?l:`#ffffff`,c.fillRect(0,0,s.width,s.height)):l&&!u&&(c.fillStyle=l,c.fillRect(0,0,s.width,s.height)),c.scale(n,n),c.drawImage(r,0,0,this.size.w,this.size.h);let d=Number.isFinite(i.quality)?Math.min(1,Math.max(.01,i.quality/100)):.9;s.toBlob(n=>{if(!n){o(Error(`${e.toUpperCase()} encoding returned no data`));return}let r=n.type===`image/jpeg`?`jpg`:n.type===`image/webp`?`webp`:`png`;this._downloadExport(n,this._exportFilename(r)),t()},a,e===`png`?void 0:d)},r.onerror=()=>{o(Error(`chart SVG could not be rasterized`))},r.src=n}):Promise.reject(Error(`unsupported raster export ${e}`))},_exportCsvText(){let e=[[`trace`,`name`,`kind`,`index`,`x`,`y`,`x0`,`x1`,`y0`,`y1`,`value`]],t=e=>Number.isFinite(e)?e:``;for(let n of this.gpuTraces||[]){let r=n.trace||{},i=[r.id??``,r.name??``,r.kind??``];if(n._cpuRect){let r=n._cpuRect,a=Math.min(r.x0.length,r.x1.length,r.y0.length,r.y1.length);for(let n=0;n{let t=String(e??``),n=t.split(`"`).join(`""`);return t.includes(`,`)||t.includes(`"`)||t.includes(`\r`)||t.includes(` -`)?`"${n}"`:t};return e.map(e=>e.map(n).join(`,`)).join(`\r -`)+`\r -`},_exportCsv(){this._downloadExport(new Blob([this._exportCsvText()],{type:`text/csv;charset=utf-8`}),this._exportFilename(`csv`))},_icon(e){let t=e=>`${e}`;switch(e){case`zoomin`:return t(``);case`zoomout`:return t(``);case`pan`:return t(``);case`zoom`:return t(``);case`select`:return t(``);case`lasso`:return t(``);case`selectx`:return t(``);case`selecty`:return t(``);case`chevrondown`:return t(``);case`collapse`:return t(``);case`expand`:return t(``);case`png`:return t(``);case`jpeg`:return t(``);case`webp`:return t(``);case`svg`:return t(``);case`csv`:return t(``);case`reset`:return t(``);case`historyback`:return t(``);case`historyforward`:return t(``);case`drag`:return t(``);default:return t(``)}}});var ht=` -const DATA = new Map(); -self.onmessage = (e) => { - const m = e.data; - if (m.type === "init") { - DATA.set(m.trace, { x: new Float64Array(m.x), y: new Float64Array(m.y) }); - return; - } - const d = DATA.get(m.trace); - if (!d) return; - const w = m.w, h = m.h; - const grid = new Float32Array(w * h); - const sx = w / ((m.x1 - m.x0) || 1); - const sy = h / ((m.y1 - m.y0) || 1); - let max = 0; - const X = d.x, Y = d.y, n = X.length; - for (let i = 0; i < n; i++) { - const cx = (X[i] - m.x0) * sx; - const cy = (Y[i] - m.y0) * sy; - if (cx < 0 || cy < 0 || cx >= w || cy >= h) continue; - const v = ++grid[(cy | 0) * w + (cx | 0)]; - if (v > max) max = v; - } - self.postMessage( - { type: "grid", seq: m.seq, trace: m.trace, w, h, max, - x0: m.x0, x1: m.x1, y0: m.y0, y1: m.y1, grid: grid.buffer }, - [grid.buffer] - ); -}; -`;function gt(){try{let e=URL.createObjectURL(new Blob([ht],{type:`application/javascript`})),t=new Worker(e);return t._fcUrl=e,t}catch{return null}}Object.assign(Q.prototype,{_scheduleViewRequest(e=this.view,t={}){if(this._destroyed||this._glLost)return;if(!this.comm){this._scheduleSampleRebin(e,t);return}let n=this.spec.traces.some(e=>e.tier===`decimated`),r=this.gpuTraces.some(e=>e.tier===`density`);if(!n&&!r)return;let i=t.seq??++this.seq,a=this._copyView(e),o=Math.round(this.plot.w),s=Math.round(this.plot.h);if(r){let e=this._now();for(let t of this.gpuTraces)t.tier===`density`&&(t._lodPendingView=a,t._lodPendingSeq=i,t._lodPendingAt=e)}let c=t.delay??120;if(t.maxWait!==void 0&&t.maxWait!==null){let e=this._now();(this._viewRequestBurstStart===void 0||this._viewRequestBurstStart===null)&&(this._viewRequestBurstStart=e);let n=t.maxWait-(e-this._viewRequestBurstStart);c=n<=0?0:Math.min(c,n)}else this._viewRequestBurstStart=null;clearTimeout(this._viewTimer);let l=()=>{if(!this._destroyed&&(this._viewRequestBurstStart=null,i===this.seq&&(n&&this.comm.send({type:`view`,seq:i,x0:Math.min(a.x0,a.x1),x1:Math.max(a.x0,a.x1),px:o}),r)))for(let e of this.gpuTraces){if(e.tier!==`density`)continue;let[t,n]=this._axisRange(e.xAxis,a),[r,c]=this._axisRange(e.yAxis,a);this.comm.send({type:`density_view`,seq:i,trace:e.trace.id,x0:Math.min(t,n),x1:Math.max(t,n),y0:Math.min(r,c),y1:Math.max(r,c),w:o,h:s})}};return c<=0?l():this._viewTimer=setTimeout(l,c),i},_scheduleSampleRebin(e=this.view,t={}){if(this._destroyed||this._glLost||this._sampleRebinDisabled)return;let n=(this.gpuTraces||[]).filter(e=>e.tier===`density`&&e.sampleOverlay&&e.sampleOverlay._cpu);if(!n.length)return;let r=t.seq??++this.seq,i=this._copyView(e);clearTimeout(this._rebinTimer),this._rebinTimer=setTimeout(()=>{if(!(this._destroyed||r!==this.seq))for(let e of n)this._requestSampleRebin(e,i,r)},t.delay??120)},_requestSampleRebin(e,t,n){e._homeDensity||=e.density;let[r,i]=this._axisRange(e.xAxis,t),[a,o]=this._axisRange(e.yAxis,t),[s,c]=this._axisRange(e.xAxis,this.view0),[l,u]=this._axisRange(e.yAxis,this.view0),d=Math.max(Math.abs(c-s),1e-300),f=Math.max(Math.abs(u-l),1e-300),p=Math.abs(i-r),m=Math.abs(o-a);if(p>=d*.999999&&m>=f*.999999){if(e.density!==e._homeDensity){let t=e._homeDensity;this._applySampleRebinGrid(e,{...t,tex:this._uploadGrid(t.grid,t.w,t.h,t.normMax||t.max||1)},!1)}return}if(!this._sampleRebinDisabled){if(!this._rebinWorker){if(this._rebinWorker=gt(),!this._rebinWorker){this._sampleRebinDisabled=!0;return}this._rebinWorker.onmessage=e=>this._onRebinResult(e.data),this._rebinInit=new Set}if(!this._rebinInit.has(e.trace.id)){let t=e.sampleOverlay._cpu,n=Math.min(t.x.length,t.y.length),r=new Float64Array(n),i=new Float64Array(n);for(let e=0;et.trace.id===e.trace&&t.tier===`density`);if(!t)return;let n=new Float32Array(e.grid);this._applySampleRebinGrid(t,{w:e.w,h:e.h,max:e.max,normMax:e.max,colormap:t.density.colormap,xRange:[e.x0,e.x1],yRange:[e.y0,e.y1],grid:n,tex:this._uploadGrid(n,e.w,e.h,e.max||1),lut:t.density.lut},!0)},_applySampleRebinGrid(e,t,n){e.prevDensity=e.density,e._densityFadeStart=this._now(),e.densityNormMax=t.normMax||t.max,e.density=t,e._sampleRebinned=!!n,B(this,e,e.density),this._refreshReductionBadges(),this.draw()},_applyAppend(e,t){let n=e.spec;if(!n||!n.traces)return;let r=n.buffer_layout===`split`?t:t&&t[0];if(r==null)return;let i=c(n,r),a=(e,t)=>Math.max(Math.abs(t-e),1e-300)*1e-9,o=a(this.view0.x0,this.view0.x1),s=a(this.view0.y0,this.view0.y1),l=Math.abs(this.view.x0-this.view0.x0)<=o&&Math.abs(this.view.x1-this.view0.x1)<=o&&Math.abs(this.view.y0-this.view0.y0)<=s&&Math.abs(this.view.y1-this.view0.y1)<=s,u=!l&&Math.abs(this.view.x1-this.view0.x1)<=o,d={x0:n.x_axis.range[0],x1:n.x_axis.range[1],y0:n.y_axis.range[0],y1:n.y_axis.range[1]},f={...this.view};if(l)f={...d};else if(u){let e=this.view.x1-this.view.x0;f={...this.view,x1:d.x1,x0:d.x1-e}}if((n.animation||n.traces.some(e=>!!e.animation))&&!this._glLost&&this.gl&&this.updatePayload(n,i)){this._transitionView?this._transitionView.to={...f}:this.view={...f},this._scheduleViewRequest(f,{delay:0});return}if(this.spec=n,this.axes=this._normalizeAxes(n),this._payload=i,this.view0=this._copyView({ranges:Object.fromEntries(Object.entries(this.axes).map(([e,t])=>[e,[...t.range]]))}),l)this.view=this._copyView(this.view0);else if(u){let e=this.view.x1-this.view.x0;this.view=this._viewFrom({x1:this.view0.x1,x0:this.view0.x1-e})}if(this._glLost||!this.gl)return;let p=new Set;for(let t of e.affected||[]){let e=this.gpuTraces.findIndex(e=>e.trace.id===t),r=n.traces.find(e=>e.id===t);e<0||!r||(this._destroyTraceResources(this.gpuTraces[e],p),this.gpuTraces[e]=this._buildTrace(i,r))}this._updatePickable(),this._scheduleViewRequest(this.view,{delay:0}),this.draw()},_onKernelMsg(e,t){if(!this._destroyed&&e&&!(this._glLost&&e.type!==`append`&&e.type!==`pick_result`))if(e.type===`tier_update`){if(e.seq!==this.seq)return;for(let n of e.traces){let e=this.gpuTraces.find(e=>e.trace.id===n.id);if(!e)continue;let r=this.gl,i=this._asF32(t[n.x.buf]),a=this._asF32(t[n.y.buf]),o=n.base&&e.baseBuf?this._asF32(t[n.base.buf]):null,s=Math.min(n.x.len,n.y.len);o&&(s=Math.min(s,n.base.len));let c=this._smoothArrays(e.trace,i,a,o,s),l=c||{x:i,y:a,n:s},u=this._stepArrays(e.trace,l.x,l.y,l.n);r.bindBuffer(r.ARRAY_BUFFER,e.xBuf),r.bufferData(r.ARRAY_BUFFER,u?u.x:l.x,r.STATIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,e.yBuf),r.bufferData(r.ARRAY_BUFFER,u?u.y:l.y,r.STATIC_DRAW),e.xMeta={...e.xMeta,offset:n.x.offset,scale:n.x.scale},e.yMeta={...e.yMeta,offset:n.y.offset,scale:n.y.scale},e._dashX=u?u.x:l.x,e._dashY=u?u.y:l.y,o&&(r.bindBuffer(r.ARRAY_BUFFER,e.baseBuf),r.bufferData(r.ARRAY_BUFFER,c?c.extra:o,r.STATIC_DRAW),e.baseMeta={...e.baseMeta,offset:n.base.offset,scale:n.base.scale}),e.n=u?u.n:l.n}this.draw()}else if(e.type===`density_update`){if(e.seq!==void 0&&e.seq!==this.seq)return;let n=e.traces||[],r=new Set(n.map(e=>Number(e.id)));r.size===0&&e.trace!==void 0&&r.add(Number(e.trace));let i=r.size===0&&e.stale,a=t=>{e.seq!==void 0&&t._lodPendingSeq!==e.seq||(t._lodPendingView=null,t._lodPendingSeq=null,t._lodPendingAt=null)};if(r.size||i)for(let e of this.gpuTraces)e.tier===`density`&&(!i&&!r.has(e.trace.id)||a(e));for(let e of n){let n=this.gpuTraces.find(t=>t.trace.id===e.id&&t.tier===`density`);if(n){if(a(n),e.mode===`points`){this._applyDrill(n,e,t);continue}$e(this,n,e,t)}}this._updatePickable(),this.draw()}else if(e.type===`append`)this._applyAppend(e,t);else if(e.type===`pick_result`){if(e.seq!==void 0&&e.seq!==this._pickSeq)return;if(!e.row){this._hideTooltip();return}let t=this._lastRow;if(t&&t.trace===e.row.trace&&t.index===e.row.index)for(let[n,r]of Object.entries(t))e.row[n]===void 0&&(e.row[n]=r);this._applySharedTooltipFields(e.row),this._lastRow=e.row,this._tooltipAnchor&&Number.isFinite(e.row.x)&&Number.isFinite(e.row.y)&&(this._tooltipAnchor.x=e.row.x,this._tooltipAnchor.y=e.row.y);let n=this._lastHoverXY;if(n&&this._renderTooltip(e.row,n.clientX,n.clientY,{announce:!this._a11yKeyboardReadout}),this._interactionFlag(`hover`)){let t={row:e.row,trace:e.row.trace,index:e.row.index,exact:!0,view:this._eventView(`hover`)};n&&Object.assign(t,this._hoverPayload(e.row,this._hoverTarget,n.clientX,n.clientY,!0)),this._dispatchChartEvent(`hover`,t)}}else e.type===`selection`?(e.bounds?this._lastBrush={mode:`box`,...e.bounds}:e.polygon&&(this._lastBrush={mode:`poly`,points:e.polygon}),(!e.traces||!e.traces.length)&&(this._lastBrush=null),this._applySelectionBuffers(e,t),this._selectionCount=e.total||0,this.draw(),this._interactionFlag(`select`,!0)&&this._dispatchChartEvent(`select`,{total:this._selectionCount,view:this._eventView(`select`)})):e.type===`state_patch`?this._applyStatePatch(e.state,{source:`api`,animate:e.animate===!0,history:e.history!==!1}):e.type===`view_nav`?e.op===`reset`&&this._navReset(e.axes):e.type===`selection_rows`&&this._applyRowsSelection(e,t)},_applySelectionBuffers(e,t){if(!e.traces||!e.traces.length){for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);return}for(let n of e.traces){let e=this.gpuTraces.find(e=>e.trace.id===n.id);if(!e)continue;let r=e.tier===`density`?e.drill:e;if(!r||!r.n||e.tier===`density`&&n.drill_seq!==void 0&&r.seq!==void 0&&n.drill_seq!==r.seq)continue;let i=this._asU32(t[n.buf]),a=new Float32Array(r.n);for(let e=0;e=d-a&&c<=f+a&&l>=p-o&&u<=m+o},_viewOverlaps(e){if(!e)return!1;let{x0:t,x1:n,y0:r,y1:i}=this.view,a=Math.min(t,n),o=Math.max(t,n),s=Math.min(r,i),c=Math.max(r,i),l=Math.min(e.x0,e.x1),u=Math.max(e.x0,e.x1),d=Math.min(e.y0,e.y1),f=Math.max(e.y0,e.y1);return a<=u&&o>=l&&s<=f&&c>=d},_viewInsideRange(e,t){return!e||!t?!1:this._viewInside({x0:e[0],x1:e[1],y0:t[0],y1:t[1]})}});var _t={linear:[0,0,1,1],ease:[.25,.1,.25,1],"ease-in":[.42,0,1,1],"ease-out":[0,0,.58,1],"ease-in-out":[.42,0,.58,1]};function vt(e,t){let n=Number(t[0]),r=Number(t[1]),i=Number(t[2]),a=Number(t[3]),o=(e,t,n)=>{let r=1-e;return 3*r*r*e*t+3*r*e*e*n+e*e*e},s=(e,t,n)=>{let r=1-e;return 3*r*r*t+6*r*e*(n-t)+3*e*e*(1-n)},c=e;for(let t=0;t<5;t++){let t=s(c,n,i);if(Math.abs(t)<1e-6)break;c=Math.max(0,Math.min(1,c-(o(c,n,i)-e)/t))}let l=0,u=1;for(let t=0;t<8;t++)o(c,n,i){let t=e*6/a;if(o<1){let e=a*Math.sqrt(1-o*o);return 1-Math.exp(-o*a*t)*(Math.cos(e*t)+o*a/e*Math.sin(e*t))}return 1-Math.exp(-a*t)*(1+a*t)},c=s(1),l=Math.abs(c)>1e-9?s(e)/c:e;return Math.max(0,Math.min(1.15,l))}function $(e,t){return t&&typeof t==`object`&&!Array.isArray(t)&&t.type===`spring`?yt(e,t):vt(e,Array.isArray(t)?t:_t[t]||_t[`ease-out`])}Object.assign(Q.prototype,{_resolvedAnimation(e){return{...this.spec.animation||{},...e&&e.animation||{},_present:!!this.spec.animation||!!(e&&e.animation)}},_animationEnabled(e){return!e._present||e.enabled===!1?!1:e.enabled===!0||!this._prefersReducedMotion()},_defaultEntrance(e){return e===`line`||e===`area`||e===`error_band`?`reveal`:e===`bar`||e===`column`?`grow`:e===`scatter`||e===`errorbar`?`scale`:`none`},_setTransitionVisual(e,t,n,r){let i=Math.max(0,Math.min(1,n));if(e._transitionOpacity=1,e._transitionScale=1,e._transitionReveal=1,e._transitionGrow=1,t===`exit`){e._transitionOpacity=0;return}if(t===`update`){e._transitionPositionProgress=i;return}let a=r.enter||`auto`;a===`auto`&&(a=this._defaultEntrance(e.trace.kind)),a!==`none`&&(a===`scale`&&(e.trace.kind===`scatter`||e.trace.kind===`errorbar`?e._transitionScale=i:e.trace.kind===`bar`||e.trace.kind===`column`?e._transitionGrow=i:(e.trace.kind===`line`||e.trace.kind===`area`||e.trace.kind===`error_band`)&&(e._transitionReveal=i)),a===`reveal`&&(e._transitionReveal=i),a===`grow`&&(e._transitionGrow=i))},_clearTransitionVisual(e){delete e._transitionOpacity,delete e._transitionScale,delete e._transitionReveal,delete e._transitionGrow,delete e._transitionPositionProgress,delete e._transitionPhase,delete e._transitionPrevXValues,delete e._transitionPrevYValues,delete e._transitionPrevPosValues,delete e._transitionPrevValue1Values,delete e._transitionPrevValue0Values,delete e._transitionPrevWidth,delete e._transitionPositionInterpolated,this._deleteBuffers(e,[`_transitionPrevXBuf`,`_transitionPrevYBuf`,`_transitionPrevPosBuf`,`_transitionPrevValue1Buf`,`_transitionPrevValue0Buf`])},_emitAnimationLifecycle(e,t,n={}){let r={stage:e,phase:t,...n,view:this._eventView(`animation_${e}`)};this._dispatchChartEvent(`animation_${e}`,r),this.comm?.send?.({type:`animation_${e}`,phase:t,...n})},_runDataAnimation(e,t,n=[]){this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf);let r=(this._dataAnimEpoch||0)+1;this._dataAnimEpoch=r;let i=[];for(let n of t){let t=this._resolvedAnimation(n.trace),r=n._transitionPhase||e;if(!this._animationEnabled(t)||r===`enter`&&t.enter===`none`||r===`update`&&t.update===`none`){this._clearTransitionVisual(n);continue}i.push({g:n,config:t,phase:r,delay:Number(t.delay)||0,duration:Math.max(0,Number(t.duration)||0)})}for(let e of n)e._transitionOpacity=0;if(!i.length){for(let e of t)this._clearTransitionVisual(e);return this._transitionView&&=(this.view={...this._transitionView.to},null),this._destroyTransitionOldTraces(),this.draw(),!1}let a=this._now();this._dataAnim={epoch:r,phase:e,start:a},this._emitAnimationLifecycle(`start`,e);let o=()=>{if(this._destroyed||!this._dataAnim||this._dataAnim.epoch!==r)return;let t=this._now(),n=!1,s=0;for(let e of i){let r=e.duration<=0?+(t>=a+e.delay):Math.max(0,Math.min(1,(t-a-e.delay)/e.duration));this._transitionView&&(s=Math.max(s,r));let i=$(r,e.config.easing);this._setTransitionVisual(e.g,e.phase,i,e.config),r<1&&(n=!0)}if(this._transitionView){let e=$(s,(this.spec.animation||{}).easing),t=this._transitionView.from,n=this._transitionView.to;this.view={x0:t.x0+(n.x0-t.x0)*e,x1:t.x1+(n.x1-t.x1)*e,y0:t.y0+(n.y0-t.y0)*e,y1:t.y1+(n.y1-t.y1)*e}}if(this.draw(),n)this._dataAnimRaf=requestAnimationFrame(o);else{this._dataAnimRaf=null;for(let e of i)this._clearTransitionVisual(e.g);this._finishDataAnimation(e)}};return this._dataAnimRaf=requestAnimationFrame(o),!0},_finishDataAnimation(e){this._dataAnim=null,this._transitionView&&=(this.view={...this._transitionView.to},null),this._destroyTransitionOldTraces(),this._emitAnimationLifecycle(`end`,e)},_startEntranceAnimation(){let e=Number(this.spec.animation_capture_progress);if(Number.isFinite(e)&&e>=0&&e<=1){for(let t of this.gpuTraces||[]){let n=this._resolvedAnimation(t.trace);n._present&&n.enabled!==!1&&n.enter!==`none`?this._setTransitionVisual(t,`enter`,$(e,n.easing),n):this._clearTransitionVisual(t)}this.draw();return}this._runDataAnimation(`enter`,this.gpuTraces||[])},_destroyTransitionOldTraces(){if(!this._transitionOldTraces||!this.gl){this._transitionOldTraces=null;return}let e=new Set;for(let t of this._transitionOldTraces)this._destroyTraceResources(t,e);this._transitionOldTraces=null},_transitionMatches(e,t,n){let r=n.match||`index`,i=[],a=t.trace.animation_fallback||null;if((e.n||0)>2e5||(t.n||0)>2e5)return{strategy:`snap`,pairs:i,fallback:a||`snap:${r}-match-limit`};if(r===`key`)if(e._transitionKeyIndex&&t._transitionKeys)for(let n=0;n(e-(Number(t.offset)||0))*(Number(t.scale)||1),c=(t,n)=>{let r=e._cpu[t],i=e[t===`x`?`_transitionPrevXValues`:`_transitionPrevYValues`],a=e._transitionPositionProgress;if(!i||!Number.isFinite(a))return this._decodeValue(r,e[`${t}Meta`],n);let o=i[n]+(r[n]-i[n])*a,s=e[`${t}Meta`];return o/(s.scale||1)+s.offset};for(let[e,n]of r.pairs){let r=c(`x`,e),i=c(`y`,e);Number.isFinite(r)&&Number.isFinite(i)&&(a[n]=s(r,t.xMeta),o[n]=s(i,t.yMeta))}return t._transitionPrevXBuf=this._upload(a),t._transitionPrevYBuf=this._upload(o),t._transitionPrevXValues=a,t._transitionPrevYValues=o,t._transitionPositionProgress=0,t._transitionPositionInterpolated=!0,e._transitionSkipExit=!0,!0},_prepareBarPositionInterpolation(e,t,n){let r=e._cpuBar,i=t._cpuBar;if(!r||!i||e.orientation!==t.orientation||t.n!==i.pos.length||e.n!==r.pos.length)return n.fallback||=`snap:layout-mismatch`,!1;let a=new Float32Array(i.pos),o=new Float32Array(i.value1),s=new Float32Array(t.n),c=(e,t)=>(e-(Number(t.offset)||0))*(Number(t.scale)||1),l=(e,t)=>e/(Number(t.scale)||1)+(Number(t.offset)||0),u=(e,t)=>e.value0?l(e.value0[t],e.value0Meta):Number(e.value0Const)||0,d=(t,n,r,i)=>{let a=e._transitionPositionProgress;return l(!t||!Number.isFinite(a)?n[i]:t[i]+(n[i]-t[i])*a,r)},f=t=>{let n=e._transitionPrevValue0Values,i=e._transitionPositionProgress,a=u(r,t);if(!n||!Number.isFinite(i))return a;let o=l(n[t],r.value1Meta);return o+(a-o)*i};for(let e=0;e[e,[...t.range]]))});let i={...this.view0};if(this._glLost||!this.gl)return this.view={...i},!0;this.gpuTraces=e.traces.map(e=>this._buildTrace(t,e));for(let e of this.gpuTraces){let t=n.find(t=>t.trace.id===e.trace.id&&t.trace.kind===e.trace.kind);if(t){let n=this._resolvedAnimation(e.trace);t._transitionExitTrace=e.trace,this._animationEnabled(n)&&n.update!==`none`&&(e._transitionMatch=this._transitionMatches(t,e,n),this._preparePositionInterpolation(t,e,n),t._transitionSkipExit=!0,this._recordAnimationFallback(e.trace,e._transitionMatch.fallback))}else e._transitionPhase=`enter`}this._transitionOldTraces=n;let a=this.gpuTraces.some(e=>{let t=this._resolvedAnimation(e.trace);return this._animationEnabled(t)&&t.update===`interpolate`&&(t.interpolate||[]).includes(`domain`)});return this._transitionView=a?{from:r,to:i}:null,a||(this.view={...i}),this._updatePickable(),this._runDataAnimation(`update`,this.gpuTraces,n)||(this.view={...i},this._transitionView=null),!0}});var bt=64;Object.assign(Q.prototype,{_initViewState(){this._historyPast=[],this._historyFuture=[],this._historyLastInteractionId=null,this._stateSelection=null,this._customTooltip=null,this.root.xy={applyState:(e,t={})=>this._applyStatePatch(e,{source:`api`,animate:t.animate===!0,history:t.history!==!1}),state:()=>this._durableState(),back:()=>this._historyBack(),forward:()=>this._historyForward()}},_durableState(){let e=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),t=this._stateSelection;return{v:1,ranges:e,selection:t==null?null:t.rows?{rows:!0}:t.range?{range:{...t.range}}:{polygon:t.polygon.map(e=>[...e])}}},_validateStatePatch(e){if(!e||typeof e!=`object`||Array.isArray(e))return`state patch must be an object`;if(e.v!==void 0&&e.v!==1)return`unsupported state version ${e.v}`;for(let t of Object.keys(e))if(![`v`,`ranges`,`selection`].includes(t))return`unknown key ${t}`;if(e.ranges!==void 0){if(!e.ranges||typeof e.ranges!=`object`||Array.isArray(e.ranges))return`ranges must be an object`;let t=new Set(this._axisIds());for(let[n,r]of Object.entries(e.ranges)){if(!t.has(n))return`unknown axis ${n}`;if(!Array.isArray(r)||r.length!==2||!r.every(e=>Number.isFinite(e))||r[0]===r[1])return`invalid range for axis ${n}`}}if(e.selection!==void 0&&e.selection!==null){let t=e.selection;if(typeof t!=`object`||Array.isArray(t))return`invalid selection`;let n=Object.keys(t);if(n.length!==1)return`invalid selection`;if(n[0]===`range`){let e=t.range;if(!e||typeof e!=`object`||![`x0`,`x1`,`y0`,`y1`].every(t=>Number.isFinite(e[t])))return`invalid selection range`}else if(n[0]===`polygon`){let e=t.polygon;if(!Array.isArray(e)||e.length<3||!e.every(e=>Array.isArray(e)&&e.length===2&&e.every(Number.isFinite)))return`invalid selection polygon`}else if(n[0]===`rows`)return`rows selections are not applicable state`;else return`invalid selection`}return null},_applyStatePatch(e,t={}){if(this._destroyed)return!1;let n=this._validateStatePatch(e);if(n)return typeof console<`u`&&console.warn&&console.warn(`xy: state patch rejected: ${n}`),!1;let r=t.source||`api`,i=++this._interactionSeq;if(e.ranges!==void 0){let n=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]]));for(let[t,r]of Object.entries(e.ranges))n[t]=[Number(r[0]),Number(r[1])];this._setView({ranges:n},{animate:t.animate===!0,source:r,phase:`end`,interactionId:i,history:t.history})}if(e.selection!==void 0){let n=e.selection,a={history:t.history,interactionId:i,source:r};if(n===null)this._clearSelection(a);else if(n.range){let{x0:e,x1:t,y0:r,y1:i}=n.range;this._sendSelect([e,r],[t,i],a)}else n.polygon&&this._sendSelectPolygon(n.polygon.map(e=>[...e]),a)}return!0},_historyEnabled(){return this._interactionFlag(`history`,!0)},_historyRecord(e={}){if(!this._historyPast||!this._historyEnabled()||this._destroyed||e.history===!1||e.source===`linked`||e.source===`history`)return;let t=e.interactionId;t!=null&&t===this._historyLastInteractionId||(this._historyLastInteractionId=t===void 0?null:t,this._historyPast.push(this._durableState()),this._historyPast.length>bt&&this._historyPast.shift(),this._historyFuture.length=0,this._updateHistoryButtons())},_historyBack(){if(!this._historyEnabled()||!this._historyPast.length)return!1;let e=this._historyPast.pop();return this._historyFuture.push(this._durableState()),this._historyApply(e),!0},_historyForward(){if(!this._historyEnabled()||!this._historyFuture.length)return!1;let e=this._historyFuture.pop();return this._historyPast.push(this._durableState()),this._historyApply(e),!0},_historyApply(e){let t={v:1,ranges:e.ranges};(!e.selection||!e.selection.rows)&&(t.selection=e.selection??null),this._applyStatePatch(t,{source:`history`,animate:!0,history:!1}),this._historyLastInteractionId=null,this._updateHistoryButtons()},_updateHistoryButtons(){let e=(e,t)=>{e&&(e.disabled=!t,e.setAttribute(`aria-disabled`,String(!t)),e.style.opacity=t?``:`0.4`)};e(this._historyBackBtn,this._historyPast.length>0),e(this._historyForwardBtn,this._historyFuture.length>0)},_navReset(e){let t=Array.isArray(e)?e.filter(e=>this._axisIds().includes(e)):null;this._resetView(!0,`reset`,t)},_applyRowsSelection(e,t){this._clearLassoOverlay();for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);this._lastBrush=null,this._applySelectionBuffers(e,t),this._stateSelection={rows:!0},this._selectionCount=e.total||0,this.draw(),this._interactionFlag(`select`,!0)&&this._dispatchChartEvent(`select`,{total:this._selectionCount,view:this._eventView(`select`)})},_axisBandNavigable(e){if(!this._interactionFlag(`navigation`,!0))return!1;let t=this._interactionFlag(`pan`,!0)&&this._axisPolicy(`pan_axes`).includes(e),n=this._interactionFlag(`zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(e);return t||n},_axisBandCursor(e,t){return this._interactionFlag(`zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(e)?t===`x`?`ew-resize`:`ns-resize`:`grab`},_initAxisBands(){if(this.root){this._axisBands={};for(let e of this._axisIds()){if(!this._axisBandNavigable(e))continue;let t=this._axisDim(e),n=document.createElement(`div`);n.dataset.xyAxisBand=e,n.style.cssText=`position:absolute;z-index:2;touch-action:none;cursor:${this._axisBandCursor(e,t)};`,this.root.appendChild(n),this._axisBands[e]=n,this._bindAxisBand(n,e,t)}this._layoutAxisBands()}},_layoutAxisBands(){if(this._axisBands)for(let[e,t]of Object.entries(this._axisBands)){let n=this._axisDim(e),r=this._axis(e).side;n===`x`?(t.style.left=`${this.plot.x}px`,t.style.width=`${this.plot.w}px`,r===`top`?(t.style.top=`${Math.max(0,this.plot.y-24)}px`,t.style.height=`30px`):(t.style.top=`${this.plot.y+this.plot.h-6}px`,t.style.height=`30px`)):(t.style.top=`${this.plot.y}px`,t.style.height=`${this.plot.h}px`,r===`right`?(t.style.left=`${this.plot.x+this.plot.w-6}px`,t.style.width=`30px`):(t.style.left=`${Math.max(0,this.plot.x-24)}px`,t.style.width=`30px`))}},_axisBandValue(e,t,n){let r=this.canvas.getBoundingClientRect();if(this._axisDim(e)===`x`){let n=Math.max(0,Math.min(r.width,t-r.left));return this._dataFromCanvas(n,0,e,`y`)[0]}let i=Math.max(0,Math.min(r.height,n-r.top));return this._dataFromCanvas(0,i,`x`,e)[1]},_bindAxisBand(e,t,n){let r=null;this._listen(e,`wheel`,e=>{if(!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._interactionFlag(`wheel_zoom`,!0)||!this._axisPolicy(`zoom_axes`).includes(t))return;e.preventDefault();let n=1.0015**e.deltaY,r=this.canvas.getBoundingClientRect(),i=(e.clientX-r.left)/r.width,a=1-(e.clientY-r.top)/r.height;this._queueWheelZoom(n,i,a,[t])},{passive:!1}),this._listen(e,`pointerdown`,n=>{if(!(n.pointerType===`mouse`&&n.button!==0)&&this._interactionFlag(`navigation`,!0)){this._cancelViewAnimation(),r={pointerId:n.pointerId,sx:n.clientX,sy:n.clientY,view:this._copyView(this.view),d0:this._axisBandValue(t,n.clientX,n.clientY),mode:null,interactionId:++this._interactionSeq,changedAxes:[]};try{e.setPointerCapture(n.pointerId)}catch{}this.tooltip.style.display=`none`,n.preventDefault()}});let i=()=>this._interactionFlag(`pan`,!0)&&this._axisPolicy(`pan_axes`).includes(t)?!0:this._axisContained(t),a=()=>this._interactionFlag(`zoom`,!0)&&this._interactionFlag(`box_zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(t);this._listen(e,`pointermove`,o=>{if(!r||o.pointerId!==r.pointerId)return;let s=o.clientX-r.sx,c=o.clientY-r.sy;if(!r.mode){if(Math.hypot(s,c)<=3)return;r.mode=Math.abs(n===`x`?s:c)>=Math.abs(n===`x`?c:s)?i()?`pan`:a()?`span`:`none`:a()?`span`:i()?`pan`:`none`,r.mode===`pan`&&(e.style.cursor=`grabbing`)}if(r.mode===`pan`){let e=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,r.view)]])),i=this._axis(t),[a,o]=this._axisRange(t,r.view),l=this._axisCoord(i,a),u=this._axisCoord(i,o);if(![l,u].every(Number.isFinite)||l===u)return;let d=n===`x`?this.plot.w:this.plot.h,f=(n===`x`?s:c)/d*(u-l),p=n===`x`?-f:f;e[t]=[this._axisValue(i,l+p),this._axisValue(i,u+p)];let m=this._setView({ranges:e},{source:`pan_drag`,phase:`update`,interactionId:r.interactionId});r.changedAxes=[...new Set([...r.changedAxes,...m])]}else if(r.mode===`span`){let e=this.root.getBoundingClientRect();if(this.selRect.dataset.xyBand=`zoom`,this.selRect.style.display=`block`,n===`x`){let t=Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,Math.min(r.sx,o.clientX)-e.left)),n=Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,Math.max(r.sx,o.clientX)-e.left));this.selRect.style.left=`${t}px`,this.selRect.style.width=`${Math.max(0,n-t)}px`,this.selRect.style.top=`${this.plot.y}px`,this.selRect.style.height=`${this.plot.h}px`}else{let t=Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,Math.min(r.sy,o.clientY)-e.top)),n=Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,Math.max(r.sy,o.clientY)-e.top));this.selRect.style.top=`${t}px`,this.selRect.style.height=`${Math.max(0,n-t)}px`,this.selRect.style.left=`${this.plot.x}px`,this.selRect.style.width=`${this.plot.w}px`}}o.preventDefault()});let o=i=>{if(!r||i.pointerId!==r.pointerId)return;let a=r;if(r=null,e.style.cursor=this._axisBandCursor(t,n),a.mode===`span`&&(this.selRect.style.display=`none`),i.type!==`pointercancel`){if(a.mode===`pan`&&a.changedAxes.length)this._emitViewChange(`pan_drag`,{axes:a.changedAxes,phase:`end`,interactionId:a.interactionId});else if(a.mode===`span`){let e=this._axisBandValue(t,i.clientX,i.clientY),n=this._axis(t),r=this._axisCoord(n,a.d0),o=this._axisCoord(n,e),s=Math.max(Math.abs(r),Math.abs(o),1e-30)*1e-12;if(![r,o].every(Number.isFinite)||Math.abs(o-r)[e,[...this._axisRange(e)]]));p[t]=[this._axisValue(n,u?f:d),this._axisValue(n,u?d:f)],this._setView({ranges:p},{animate:!0,anchors:{[t]:.5},source:`box_zoom`,phase:`end`,interactionId:a.interactionId})}}};this._listen(e,`pointerup`,o),this._listen(e,`pointercancel`,o)},_seriesColorCss(e){let t=e&&e.color;if(!Array.isArray(t)||t.length<3)return null;let n=e=>Math.max(0,Math.min(255,Math.round(Number(e)*255)));return`rgb(${n(t[0])}, ${n(t[1])}, ${n(t[2])})`},_hoverPayload(e,t,n,r,i=!1){let a=this.root.getBoundingClientRect(),o=this.canvas.getBoundingClientRect(),s=Math.max(0,Math.min(o.width,n-o.left)),c=Math.max(0,Math.min(o.height,r-o.top)),l={};for(let e of this._axisIds()){let t=this._axisDim(e),[n,r]=this._dataFromCanvas(s,c,t===`x`?e:`x`,t===`y`?e:`y`);l[e]=t===`x`?n:r}let u=t&&t.g,d=e?[{trace:u&&u.trace&&u.trace.name||e.trace,index:e.index,row:e,x_axis:u&&u.xAxis||`x`,y_axis:u&&u.yAxis||`y`,color:this._seriesColorCss(u)}]:[],f={active:!0,cursor:{px:[n-a.left,r-a.top],data:l},points:d};return i&&(f.exact=!0),f},setCustomTooltip(e){if(this.tooltip){if(!e){this._customTooltip=null,delete this.tooltip.dataset.xyCustomTooltip,this.tooltip.style.background=``,this.tooltip.style.border=``,this.tooltip.style.padding=``,this.tooltip.replaceChildren(),this.tooltip.style.display=`none`;return}this._customTooltip=e,this.tooltip.dataset.xyCustomTooltip=``,this.tooltip.style.background=`transparent`,this.tooltip.style.border=`none`,this.tooltip.style.padding=`0`,e.style.display=``,this.tooltip.replaceChildren(e)}}});function xt({model:e,el:t}){let n=e.get(`spec`),r=new Q(t,n,c(n,e.get(`buffers`)),{send:t=>e.send(t),wantsViewChange:()=>e.get(`spec`)?.interaction?._transport_view_change===!0,onMessage:t=>{let n=(e,n)=>t(e,n);return e.on(`msg:custom`,n),()=>e.off?.(`msg:custom`,n)}}),i={seq:n.append?.seq??null,buffers:e.get(`buffers`)},a=()=>{let t=e.get(`spec`),n=t?.append;if(!n)return;let a=e.get(`buffers`);n.seq===i.seq&&a===i.buffers||s(t,a)&&(i.seq=n.seq,i.buffers=a,r._applyAppend({type:`append`,affected:n.affected,spec:t},a))};return e.on(`change:spec`,a),e.on(`change:buffers`,a),()=>{e.off?.(`change:spec`,a),e.off?.(`change:buffers`,a),r.destroy()}}function St(e,t,n){let r=o(n),i=new Q(e,t,r,null),a=e=>i._columnView(r,t.columns[e]);for(let e of i.gpuTraces)q(e.trace.kind).retainCpu&&e.tier!==`density`&&(e._cpu={x:a(e.trace.x),y:a(e.trace.y),xMeta:e.xMeta,yMeta:e.yMeta},e.trace.color&&Number.isInteger(e.trace.color.buf)&&(e._cpu.color=a(e.trace.color.buf)),e.trace.size&&Number.isInteger(e.trace.size.buf)&&(e._cpu.size=a(e.trace.size.buf)));return i}var Ct={render:xt,decodeFrame:p};export{Q as ChartView,K as MARK_KINDS,p as decodeFrame,Ct as default,q as markOf,xt as render,St as renderStandalone}; \ No newline at end of file diff --git a/python/xy/static/standalone.js b/python/xy/static/standalone.js deleted file mode 100644 index 2abff415..00000000 --- a/python/xy/static/standalone.js +++ /dev/null @@ -1,770 +0,0 @@ -var xy=(function(e){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var t=[88,89,66,70],n=1,r=24,i=8,a=Object.freeze({maxFrameBytes:512*1024*1024,maxMetadataBytes:8*1024*1024,maxBuffers:4096,maxBufferBytes:256*1024*1024});function o(e,t=`buffer`){if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw TypeError(`${t} must be an ArrayBuffer or ArrayBuffer view`)}function s(e){let t=o(e,`chart payload`);return t.byteOffset%4==0?t:new Uint8Array(t)}function c(e,t){let n=e?.columns;if(!Array.isArray(n))return!1;let r=e=>e.dtype===`u8`?1:4;return e.buffer_layout===`split`?Array.isArray(t)?n.every(e=>{if(!Number.isInteger(e.buf))return!0;let n=t[e.buf];return!!n&&e.len*r(e)<=n.byteLength}):!1:Array.isArray(t)||!t?!1:n.every(e=>e.byte_offset+e.len*r(e)<=t.byteLength)}function l(e,t){if(e.buffer_layout===`split`){if(!Array.isArray(t))throw Error(`xy: spec says buffer_layout=split but the transport delivered one buffer`);return t.map(s)}if(Array.isArray(t))throw Error(`xy: transport delivered a buffer list but the spec is not split-layout`);return s(t)}function u(e,t){let n=a[t],r=e&&e[t]!=null?e[t]:n;if(!Number.isSafeInteger(r)||r<=0)throw RangeError(`${t} must be a positive safe integer`);return r}function d(e){return Math.ceil(e/i)*i}function f(e,t,n){let r=e.getBigUint64(t,!0);if(r>BigInt(2**53-1))throw RangeError(`${n} exceeds JavaScript's safe integer range`);return Number(r)}function p(e,t,n,r){if(n>e.byteLength)throw RangeError(`truncated ${r} padding`);for(let i=t;ic)throw RangeError(`maxMetadataBytes cannot exceed maxFrameBytes`);if(h>c)throw RangeError(`maxBufferBytes cannot exceed maxFrameBytes`);if(s.byteOffset%i!==0)throw RangeError(`frame body must start on an 8-byte boundary`);if(s.byteLength>c)throw RangeError(`frame length ${s.byteLength} exceeds limit ${c}`);if(s.byteLengthl)throw RangeError(`metadata length ${b} exceeds limit ${l}`);if(x>m)throw RangeError(`buffer count ${x} exceeds limit ${m}`);let C=r+b;if(C>s.byteLength)throw RangeError(`truncated frame metadata`);let w;try{let e=new Uint8Array(s.buffer,s.byteOffset+r,b);w=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(e))}catch(e){throw RangeError(`invalid frame metadata JSON: ${e}`)}if(!w||Array.isArray(w)||typeof w!=`object`)throw RangeError(`frame metadata must decode to an object`);let T=d(C);p(s,C,T,`metadata`);let E=[];for(let e=0;es.byteLength)throw RangeError(`truncated buffer ${e} length`);let t=f(g,T,`buffer ${e} length`);if(T+=8,t>h)throw RangeError(`buffer ${e} length ${t} exceeds limit ${h}`);let n=T+t;if(n>s.byteLength)throw RangeError(`truncated buffer ${e}`);let r=s.byteOffset+T;if(r%i!==0)throw RangeError(`buffer ${e} is not 8-byte aligned`);E.push(new Uint8Array(s.buffer,r,t));let a=d(n);p(s,n,a,`buffer ${e}`),T=a}if(T!==s.byteLength)throw RangeError(`frame has ${s.byteLength-T} trailing bytes`);return{message:w,buffers:E,version:n,byteLength:s.byteLength}}var h={binary:[[255,255,255],[0,0,0]],gray:[[0,0,0],[25,25,25],[51,51,51],[76,76,76],[102,102,102],[128,128,128],[153,153,153],[179,179,179],[204,204,204],[230,230,230],[255,255,255]],viridis:[[68,1,84],[72,36,117],[65,68,135],[53,95,141],[42,120,142],[33,145,140],[34,168,132],[68,191,112],[122,209,81],[189,223,38],[253,231,37]],plasma:[[13,8,135],[65,4,157],[106,0,168],[143,13,164],[177,42,144],[204,71,120],[225,100,98],[242,132,75],[252,166,54],[252,206,37],[240,249,33]],inferno:[[0,0,4],[22,11,57],[66,10,104],[106,23,110],[147,38,103],[188,55,84],[221,81,58],[243,120,25],[252,165,10],[246,215,70],[252,255,164]],magma:[[0,0,4],[20,14,54],[59,15,112],[100,26,128],[140,41,129],[183,55,121],[222,73,104],[247,112,92],[254,159,109],[254,207,146],[252,253,191]],cividis:[[0,34,78],[8,51,112],[53,69,108],[79,87,108],[102,105,112],[125,124,120],[148,142,119],[174,163,113],[200,184,102],[229,207,82],[254,232,56]],coolwarm:[[59,76,192],[89,119,227],[123,159,249],[158,190,255],[192,212,245],[221,220,220],[242,203,183],[247,172,142],[238,132,104],[214,82,68],[180,4,38]],turbo:[[48,18,59],[69,89,203],[62,155,254],[25,213,205],[70,248,132],[164,252,60],[225,221,55],[254,164,49],[240,91,18],[195,37,3],[122,4,3]],rainbow:[[128,0,255],[78,77,252],[25,150,243],[24,205,228],[77,243,206],[128,255,180],[178,243,150],[230,205,115],[255,150,79],[255,77,39],[255,0,0]],jet:[[0,0,128],[0,0,241],[0,76,255],[0,176,255],[41,255,206],[125,255,122],[206,255,41],[255,196,0],[255,104,0],[241,8,0],[128,0,0]],rdgy:[[103,0,31],[177,24,43],[214,96,77],[243,164,129],[253,219,199],[254,254,254],[224,224,224],[185,185,185],[135,135,135],[76,76,76],[26,26,26]],rdbu:[[103,0,31],[177,24,43],[214,96,77],[243,164,129],[253,219,199],[246,247,247],[209,229,240],[144,196,221],[67,147,195],[32,101,171],[5,48,97]],blues:[[247,251,255],[227,238,249],[208,225,242],[183,212,234],[148,196,223],[106,174,214],[74,152,201],[46,126,188],[23,100,171],[8,74,145],[8,48,107]],purples:[[252,251,253],[242,240,247],[226,226,239],[206,207,229],[182,182,216],[158,154,200],[134,131,189],[114,98,172],[97,64,155],[79,31,139],[63,0,125]],pubu:[[255,247,251],[240,234,244],[219,218,235],[192,201,226],[156,185,217],[115,169,207],[66,149,195],[24,124,182],[5,103,162],[4,83,130],[2,56,88]],piyg:[[142,1,82],[196,26,124],[222,119,174],[241,181,217],[253,224,239],[247,247,246],[230,245,208],[183,224,133],[127,188,65],[76,145,33],[39,100,25]],prgn:[[64,0,75],[117,41,130],[153,112,171],[193,164,206],[231,212,232],[246,247,246],[217,240,211],[165,218,159],[90,174,97],[26,119,54],[0,68,27]],rdylgn:[[165,0,38],[214,47,39],[244,109,67],[253,173,96],[254,224,139],[254,255,190],[217,239,139],[165,216,106],[102,189,99],[25,151,80],[0,104,55]],spectral:[[158,1,66],[212,61,79],[244,109,67],[253,173,96],[254,224,139],[255,255,190],[230,245,152],[170,220,164],[102,194,165],[51,135,188],[94,79,162]]};function g(e){let t=typeof e==`string`&&e.endsWith(`_r`),n=h[t?e.slice(0,-2):e]||h.viridis;return t?[...n].reverse():n}function _(e){let t=g(e),n=new Uint8Array(256*4);for(let e=0;e<256;e++){let r=e/255*(t.length-1),i=Math.floor(r),a=Math.min(i+1,t.length-1),o=r-i;for(let r=0;r<3;r++)n[e*4+r]=Math.round(t[i][r]*(1-o)+t[a][r]*o);n[e*4+3]=255}return n}function v(e,t){let n=document.createElement(`span`);n.style.display=`none`,n.style.color=t,e.appendChild(n);let r=getComputedStyle(n).color;e.removeChild(n);let i=r.match(/rgba?\(([^)]+)\)/);if(!i)return null;let[a,o,s,c=1]=i[1].split(/[,/\s]+/).filter(Boolean).map(Number);return[a/255,o/255,s/255,c]}function y(e,t){return getComputedStyle(e).getPropertyValue(t).trim()||null}function b(e){let t=e.replace(`#`,``);if(!/^(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(t))return null;let n=t.length===3||t.length===4?[...t].map(e=>e+e).join(``):t,r=parseInt(n.slice(0,6),16),i=n.length===8?parseInt(n.slice(6,8),16)/255:1;return[(r>>16&255)/255,(r>>8&255)/255,(r&255)/255,i]}function x(e,t,n){if(!t||typeof t!=`string`)return n;let r=t.trim();return r?(r.startsWith(`#`)?b(r):v(e,r))||(typeof console<`u`&&console.warn&&console.warn(`xy: unresolvable color ${JSON.stringify(r)}; using fallback`),n):n}function S(e){let t=v(e,`currentColor`)||[.2,.2,.2,1],n=(e,t)=>[e[0],e[1],e[2],t],r=t=>{let n=y(e,t);return n&&v(e,n)||null};return{bg:r(`--chart-bg`),grid:r(`--chart-grid`)||n(t,.14),axis:r(`--chart-axis`)||n(t,.55),label:r(`--chart-text`)||n(t,.85)}}function C([e,t,n,r]){return`rgba(${Math.round(e*255)},${Math.round(t*255)},${Math.round(n*255)},${r})`}var w=` -@layer base{ -:where(.xy [data-xy-slot="title"]){text-align:center;font-size:14px;font-weight:600;color:var(--chart-text,inherit)} -:where(.xy [data-xy-slot="tooltip"]){max-width:calc(100% - 8px);max-height:calc(100% - 8px);box-sizing:border-box;white-space:normal;overflow-wrap:anywhere;overflow:auto;background:var(--chart-tooltip-bg,rgba(20,24,33,.92));color:var(--chart-tooltip-text,#fff);padding:5px 8px;border-radius:4px;font-size:11px;line-height:1.35;box-shadow:0 2px 8px rgba(0,0,0,.3)} -:where(.xy [data-xy-slot="legend"]){left:var(--xy-legend-left,auto);right:var(--xy-legend-right,auto);top:var(--xy-legend-top,auto);bottom:var(--xy-legend-bottom,auto);transform:var(--xy-legend-transform,none);max-width:var(--xy-legend-max-width);max-height:var(--xy-legend-max-height);gap:2px;font-size:11px;background:var(--chart-legend-bg,rgba(128,128,128,.08));border-radius:4px;padding:4px 8px;color:var(--chart-text,inherit)} -:where(.xy [data-xy-slot="legend_swatch"]){width:12px;height:10px;border-radius:2px;margin-right:5px} -:where(.xy [data-xy-slot="colorbar"]){color:var(--chart-text,inherit);font-size:10px} -:where(.xy [data-xy-slot="colorbar_bar"]){background:var(--xy-colorbar-gradient);border:1px solid currentColor;box-sizing:border-box} -:where(.xy [data-xy-slot="colorbar_title"]){font-weight:500} -:where(.xy [data-xy-slot="badge"]){gap:3px;font-size:11px;line-height:1.2} -:where(.xy [data-xy-slot="badge_item"]){padding:3px 6px;border-radius:4px;color:var(--chart-badge-text,var(--xy-badge-text));background:var(--chart-badge-bg,var(--xy-badge-bg));box-shadow:var(--xy-badge-shadow)} -:where(.xy){--xy-badge-text:#0f172a;--xy-badge-bg:rgba(255,255,255,.82);--xy-badge-shadow:0 1px 4px rgba(15,23,42,.14);--xy-modebar-bg:rgba(255,255,255,.78);--xy-modebar-menu-bg:rgba(255,255,255,.94);--xy-modebar-border:rgba(128,128,128,.18);--xy-modebar-menu-border:rgba(128,128,128,.22);--xy-modebar-active:rgba(128,128,128,.2);--xy-modebar-shadow:0 1px 4px rgba(0,0,0,.08);--xy-modebar-menu-shadow:0 5px 18px rgba(15,23,42,.18)} -:where(.dark .xy,.xy.dark){--xy-badge-text:#f8fafc;--xy-badge-bg:rgba(30,35,44,.88);--xy-badge-shadow:0 1px 4px rgba(0,0,0,.5);--xy-modebar-bg:rgba(37,42,52,.9);--xy-modebar-menu-bg:rgba(30,35,44,.97);--xy-modebar-border:rgba(255,255,255,.14);--xy-modebar-menu-border:rgba(255,255,255,.16);--xy-modebar-active:rgba(255,255,255,.16);--xy-modebar-shadow:0 1px 4px rgba(0,0,0,.5);--xy-modebar-menu-shadow:0 8px 24px rgba(0,0,0,.6)} -:where(.xy [data-xy-slot="modebar"]){gap:1px;background:var(--chart-modebar-bg,var(--xy-modebar-bg));border:1px solid var(--xy-modebar-border);border-radius:4px;padding:1px;box-shadow:var(--xy-modebar-shadow)} -:where(.xy [data-xy-slot="modebar_button"]){width:24px;height:24px;padding:0;border:none;background:transparent;border-radius:3px;color:var(--chart-text,currentColor);cursor:pointer} -:where(.xy [data-xy-modebar-drag-handle]){position:relative;width:22px;margin-right:4px;cursor:move} -:where(.xy [data-xy-modebar-drag-handle])::after{content:"";position:absolute;top:4px;right:-3px;bottom:4px;width:1px;background:rgba(128,128,128,.28);pointer-events:none} -:where(.xy [data-xy-modebar-menu-trigger]){width:auto;min-width:48px;gap:1px;padding:0 4px;font-size:11px;font-variant-numeric:tabular-nums} -:where(.xy [data-xy-modebar-select-trigger]){width:auto;min-width:42px;gap:2px;padding:0 4px} -:where(.xy [data-xy-modebar-select-icon]){display:flex;flex:0 0 auto} -:where(.xy [data-xy-modebar-menu-indicator]){display:flex;flex:0 0 auto;transition:transform .15s} -:where(.xy [data-xy-modebar-menu-indicator] svg){width:11px;height:11px} -:where(.xy [data-xy-modebar-menu]){min-width:148px;gap:1px;padding:4px;background:var(--chart-modebar-bg,var(--xy-modebar-menu-bg));border:1px solid var(--xy-modebar-menu-border);border-radius:7px;box-shadow:var(--xy-modebar-menu-shadow);backdrop-filter:blur(8px)} -:where(.xy [data-xy-modebar-menu-item]){width:100%;height:28px;justify-content:flex-start;padding:0 9px;border-radius:4px;text-align:left;white-space:nowrap} -:where(.xy [data-xy-modebar-menu-item]:hover,.xy [data-xy-modebar-menu-item]:focus-visible){background:var(--chart-modebar-active,var(--xy-modebar-active));outline:none} -:where(.xy [data-xy-modebar-menu-item][data-xy-separator]){margin-top:3px;border-top:1px solid rgba(128,128,128,.2);border-radius:0 0 4px 4px} -:where(.xy [data-xy-modebar-menu-icon]){display:flex;width:16px;margin-right:7px} -:where(.xy [data-xy-modebar-menu-icon] svg){width:14px;height:14px} -:where(.xy [data-xy-slot="modebar_button"].xy-active){background:var(--chart-modebar-active,var(--xy-modebar-active))} -:where(.xy [data-xy-slot="selection"]){border:1px solid var(--chart-selection,rgba(90,140,240,.9));background:var(--chart-selection-fill,rgba(90,140,240,.15))} -:where(.xy [data-xy-slot="selection"][data-xy-band="zoom"]){border-color:var(--chart-zoom-selection,rgba(120,120,120,.9));background:var(--chart-zoom-selection-fill,rgba(120,120,120,.12))} -:where(.xy [data-xy-selection-lasso]){fill:var(--chart-selection-fill,rgba(90,140,240,.15));stroke:var(--chart-selection,rgba(90,140,240,.9));stroke-width:1.5;stroke-linejoin:round;pointer-events:none} -:where(.xy [data-xy-selection-lasso-handle]){fill:var(--chart-bg,#fff);stroke:var(--chart-selection,rgba(90,140,240,.9));stroke-width:1.5;cursor:grab;pointer-events:all} -:where(.xy [data-xy-selection-lasso-handle][data-xy-active]){cursor:grabbing;fill:var(--chart-selection,rgba(90,140,240,.9))} -:where(.xy [data-xy-slot="crosshair_x"],.xy [data-xy-slot="crosshair_y"]){background:var(--chart-crosshair,rgba(15,23,42,.42))} -:where(.xy [data-xy-slot="tick_label"]){color:var(--chart-text,inherit)} -:where(.xy [data-xy-slot="axis_title"]){color:var(--chart-text,inherit);font-size:12px} -:where(.xy [data-xy-slot="annotation_label"]){font-size:11px;line-height:1.2;font-weight:500;color:var(--chart-annotation-text,var(--chart-text,inherit))} -:where(.xy [data-xy-slot="canvas"]){cursor:var(--chart-cursor,crosshair)} -:where(.xy [data-xy-slot="canvas"][data-xy-dragmode="pan"]){cursor:var(--chart-cursor-pan,grab)} -:where(.xy [data-xy-slot="canvas"]:focus-visible,.xy [data-xy-slot="modebar_button"]:focus-visible){outline:2px solid var(--chart-focus,#2563eb);outline-offset:2px} -@media (prefers-reduced-motion:reduce){:where(.xy [data-xy-slot="modebar"]){transition-duration:0s!important}} -@media (forced-colors:active){:where(.xy [data-xy-slot="modebar"],.xy [data-xy-slot="tooltip"]){border:1px solid CanvasText}:where(.xy [data-xy-slot="modebar_button"].xy-active){outline:2px solid Highlight}:where(.xy [data-xy-slot="canvas"]:focus){outline:2px solid Highlight}} -} -/* VS Code's Jupyter webview wraps ipywidget outputs in an opaque white card so - widgets that assume a light page stay legible on dark editor themes — the - same role as matplotlib's always-opaque white figure patch, so unthemed - charts keep it. A chart that brings its own background (theme(background=), - marked data-xy-own-bg) would sit in a white frame instead, so only those - outputs drop the backdrop. !important because the host rule this overrides - carries higher specificity; it stays outside the base layer because it - overrides host CSS rather than providing an overridable default. */ -.cell-output-ipywidget-background:has(.xy[data-xy-own-bg]){background:transparent!important} -`;function T(e){let t=e&&e.getRootNode?e.getRootNode():document,n=typeof ShadowRoot<`u`&&t instanceof ShadowRoot;!n&&!(t instanceof Document)&&(t=document);let r=n?t:t.head||document.head||t.documentElement;if(!r||!r.querySelector||r.querySelector(`style[data-xy-chrome]`))return;let i=document.createElement(`style`);i.setAttribute(`data-xy-chrome`,``),i.textContent=w,r.appendChild(i)}function E(e,t,n=[.5,.5,.5,1]){let r=x(e,t,n);return C(Array.isArray(r)&&r.length>=4&&r.every(Number.isFinite)?r:n)}function D(e){if(e=Math.abs(e),!Number.isFinite(e)||e<=0)return 1;let t=10**Math.floor(Math.log10(e));for(let n of[1,2,2.5,5,10])if(e<=n*t*1.000000000001)return n*t;return 10*t}function O(e,t,n=6){if(!Number.isFinite(e)||!Number.isFinite(t))return{ticks:[],step:1};let r=Math.min(e,t),i=Math.max(e,t);if(r===i)return{ticks:[r],step:1};let a=D((i-r)/n),o=Math.ceil(r/a)*a,s=[];for(let e=o;e<=i+a*1e-9&&s.length<200;e+=a)s.push(Math.abs(e)=r*.999999999999&&o<=i*1.000000000001&&(c.push(o),n===1&&(e-a)%u===0&&l.push(o)),c.length>=200)break}}return{ticks:c,labels:l.length?l:c,step:1,log:!0}}function A(e,t,n,r=6){if(!n||!n.length)return{ticks:[],step:1};let i=Math.max(0,Math.ceil(Math.min(e,t))),a=Math.min(n.length-1,Math.floor(Math.max(e,t)));if(a14*j.d)return te(r,i,a);let o=M[M.length-1];for(let e of M)if(e>=a){o=e;break}let s=Math.ceil(r/o)*o,c=[];for(let e=s;e<=i&&c.length<200;e+=o)c.push(e);return{ticks:c,step:o}}function te(e,t,n){let r=n/(30*j.d),i=[1,2,3,6,12,24,60,120],a=i[i.length-1];for(let e of i)if(e>=r){a=e;break}let o=new Date(e),s=o.getUTCFullYear(),c=o.getUTCMonth();c=Math.ceil(c/a)*a;let l=[];for(;;){let n=Date.UTC(s+Math.floor(c/12),c%12,1);if(n>t||(n>=e&&l.push(n),c+=a,l.length>1e3))break}return{ticks:l,step:a*30*j.d}}function ne(e,t){let n=new Date(e),r=(e,t=2)=>String(e).padStart(t,`0`);return t>=28*j.d?n.getUTCMonth()===0?String(n.getUTCFullYear()):`${n.toLocaleString(`en`,{month:`short`,timeZone:`UTC`})} ${n.getUTCFullYear()}`:t>=j.d?`${n.toLocaleString(`en`,{month:`short`,timeZone:`UTC`})} ${r(n.getUTCDate())}`:t>=j.m?`${r(n.getUTCHours())}:${r(n.getUTCMinutes())}`:t>=j.s?`${r(n.getUTCHours())}:${r(n.getUTCMinutes())}:${r(n.getUTCSeconds())}`:`${r(n.getUTCMinutes())}:${r(n.getUTCSeconds())}.${r(n.getUTCMilliseconds(),3)}`}function N(e,t){let n=Math.abs(e);if(n>=1e6||n!==0&&n<1e-4)return e.toExponential(1).replace(`e+`,`e`);let r=t?Math.max(0,Math.ceil(-Math.log10(Math.abs(t)))):0;for(;r<8&&Math.abs(Number(t.toFixed(r))-t)>Math.abs(t)/1e3;)r++;return e.toFixed(Math.min(r,8))}function re(e,t=6){let n=Number(e);if(!Number.isFinite(n))return String(e);if(n===0)return Object.is(n,-0)?`-0`:`0`;let[r,i]=n.toExponential(t-1).split(`e`),a=Number(i);if(a<-4||a>=t)return r=r.replace(/0+$/,``).replace(/\.$/,``),`${r}e${a>=0?`+`:`-`}${String(Math.abs(a)).padStart(2,`0`)}`;let o=Math.max(0,t-a-1),s=Number(n.toPrecision(t)).toFixed(o);return s.includes(`.`)&&(s=s.replace(/0+$/,``).replace(/\.$/,``)),s}function ie(e,t){let n=Math.round(e);return n>=0&&nString(e).padStart(t,`0`),i=n.toLocaleString(`en`,{month:`short`,timeZone:`UTC`}),a=n.toLocaleString(`en`,{month:`long`,timeZone:`UTC`});return t.replace(/%[YmdHMSbB]/g,e=>{switch(e){case`%Y`:return String(n.getUTCFullYear());case`%m`:return r(n.getUTCMonth()+1);case`%d`:return r(n.getUTCDate());case`%H`:return r(n.getUTCHours());case`%M`:return r(n.getUTCMinutes());case`%S`:return r(n.getUTCSeconds());case`%b`:return i;case`%B`:return a;default:return e}})}function se(e,t,n){if(e&&e.kind===`category`)return ie(t,e.categories||[]);if(e&&e.kind===`time`)return oe(t,e.format)||ne(t,n);let r=ae(t,e&&e.format);return e&&e.scale===`log`&&Number(t)>0&&Number(t)<1&&r===`0`?N(t,n):r||N(t,n)}function P(e,t){if(t===`time_ms`)return new Date(e).toISOString().replace(`T`,` `).replace(`.000Z`,`Z`);if(typeof e==`string`)return e;let n=Number(e);if(!Number.isFinite(n))return String(e);if(n===0)return`0`;let r=Math.abs(n);return r>=1e6||r<1e-4?n.toExponential(3):(Math.round(n*1e4)/1e4).toString()}function ce(e,t,n){let r=e.createShader(t);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw Error(`shader compile: `+e.getShaderInfoLog(r)+` -`+n);return r}var F={ax:0,ay:1,ax0:0,ax1:1,ay0:2,ay1:3,ax2:4,ay2:5,ab0:4,ab1:5,a_pos:0,a_v1:1,a_v0:2,a_corner:0,a_cval:6,a_sval:7,a_sel:8,a_dval:9,a_len0:10,a_len1:11,a_dash0:10,a_dashDir:11,a_prevx:4,a_prevy:5,a_prevx1:7,a_prevy1:8,a_rgba:12,a_style:13,a_stroke:14,a_radius:15};function le(e,t,n){let r=e.createProgram(),i=ce(e,e.VERTEX_SHADER,t),a=ce(e,e.FRAGMENT_SHADER,n);e.attachShader(r,i),e.attachShader(r,a);for(let[t,n]of Object.entries(F))e.bindAttribLocation(r,n,t);e.linkProgram(r);let o=e.getProgramParameter(r,e.LINK_STATUS),s=e.getProgramInfoLog(r);if(e.detachShader(r,i),e.detachShader(r,a),e.deleteShader(i),e.deleteShader(a),!o)throw e.deleteProgram(r),Error(`program link: `+s);return r._u=Object.create(null),r}function I(e,t,n){let r=t._u[n];return r===void 0&&(r=e.getUniformLocation(t,n),t._u[n]=r),r}var L=` -float xyDecode(float encoded, vec2 meta) { - return encoded / max(abs(meta.y), 1e-30) + meta.x; -} -float xyAxisCoord(float encoded, vec2 meta, int mode) { - float value = xyDecode(encoded, meta); - if (mode == 1) return value > 0.0 ? log(value) / log(10.0) : -1e30; - return value; -} -float xyMap(float encoded, vec2 map, vec2 meta, int mode) { - return xyAxisCoord(encoded, meta, mode) * map.x + map.y; -} -float xyViewCoord(float value, int mode) { - if (mode == 1) return value > 0.0 ? log(value) / log(10.0) : -1e30; - return value; -} -float xyViewValue(float coord, int mode) { - if (mode == 1) return pow(10.0, coord); - return coord; -} -`,ue=`#version 300 es -in float ax; in float ay; in float a_prevx; in float a_prevy; -in float a_cval; in float a_sval; in float a_sel; in float a_dval; -in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -uniform float u_size; uniform int u_sizeMode; uniform vec2 u_sizeRange; -uniform int u_colorMode; uniform float u_dpr; uniform int u_selActive; -uniform float u_selectedOpacity; uniform float u_unselectedOpacity; -uniform float u_transitionProgress; uniform int u_transitionActive; -out float v_lutCoord; out float v_dim; out float v_dval; out float v_ptSize; out float v_sel; -out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; -${L} -void main() { - float x = u_transitionActive == 1 ? mix(a_prevx, ax, u_transitionProgress) : ax; - float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; - gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode), xyMap(y, u_ymap, u_ymeta, u_ymode), 0.0, 1.0); - float sz = u_sizeMode == 1 ? mix(u_sizeRange.x, u_sizeRange.y, a_sval) : u_size; - gl_PointSize = sz * u_dpr; - v_ptSize = sz * u_dpr; - v_sel = a_sel; - v_rgba = a_rgba; - v_style = a_style; - v_stroke = a_stroke; - // continuous: coord = value in [0,1]; categorical: center of texel a_cval. - v_lutCoord = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - // Local log-density LUT coord (drill handoff, §5): lets freshly drilled - // points wear the density colormap so the texture->points swap is seamless. - v_dval = a_dval; - // Unselected marks dim when a selection is active (§34 selected/unselected styling). - v_dim = u_selActive == 1 ? mix(u_unselectedOpacity, u_selectedOpacity, step(0.5, a_sel)) : 1.0; -}`,de=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform int u_colorMode; uniform sampler2D u_lut; uniform float u_opacity; -uniform sampler2D u_dlut; uniform float u_dblend; -uniform int u_symbol; uniform vec4 u_ptStroke; uniform float u_ptStrokeWidth; uniform int u_ptStrokeFace; -uniform int u_strokeMode; uniform float u_strokeOpacity; -uniform int u_selActive; uniform vec4 u_selColor; uniform vec4 u_unselColor; -in float v_lutCoord; in float v_dim; in float v_dval; in float v_ptSize; in float v_sel; -in vec4 v_rgba; in vec4 v_style; in vec4 v_stroke; -out vec4 outColor; - -float xySegmentDistance(vec2 p, vec2 a, vec2 b) { - vec2 e = b - a; - return length(p - a - e * clamp(dot(p - a, e) / dot(e, e), 0.0, 1.0)); -} -float xyTriangleDistance(vec2 p, vec2 a, vec2 b, vec2 c) { - float dist = min(xySegmentDistance(p, a, b), - min(xySegmentDistance(p, b, c), xySegmentDistance(p, c, a))); - float c0 = (b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x); - float c1 = (c.x-b.x)*(p.y-b.y) - (c.y-b.y)*(p.x-b.x); - float c2 = (a.x-c.x)*(p.y-c.y) - (a.y-c.y)*(p.x-c.x); - bool inside = (c0 >= 0.0 && c1 >= 0.0 && c2 >= 0.0) || - (c0 <= 0.0 && c1 <= 0.0 && c2 <= 0.0); - return inside ? -dist : dist; -} -float xyPentagonDistance(vec2 p) { - // Path.unit_regular_polygon(5), then Matplotlib's 0.5 marker transform. - vec2 a = vec2(0.0, -0.5); - vec2 b = vec2(-0.475528258, -0.154508497); - vec2 c = vec2(-0.293892626, 0.404508497); - vec2 d = vec2(0.293892626, 0.404508497); - vec2 e = vec2(0.475528258, -0.154508497); - float dist = min(min(xySegmentDistance(p, a, b), xySegmentDistance(p, b, c)), - min(min(xySegmentDistance(p, c, d), xySegmentDistance(p, d, e)), - xySegmentDistance(p, e, a))); - float c0 = (b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x); - float c1 = (c.x-b.x)*(p.y-b.y) - (c.y-b.y)*(p.x-b.x); - float c2 = (d.x-c.x)*(p.y-c.y) - (d.y-c.y)*(p.x-c.x); - float c3 = (e.x-d.x)*(p.y-d.y) - (e.y-d.y)*(p.x-d.x); - float c4 = (a.x-e.x)*(p.y-e.y) - (a.y-e.y)*(p.x-e.x); - bool inside = (c0 >= 0.0 && c1 >= 0.0 && c2 >= 0.0 && c3 >= 0.0 && c4 >= 0.0) || - (c0 <= 0.0 && c1 <= 0.0 && c2 <= 0.0 && c3 <= 0.0 && c4 <= 0.0); - return inside ? -dist : dist; -} -float xyMarkerSdf(vec2 d, int shape) { - if (shape == 1) return max(abs(d.x), abs(d.y)) - 0.5; // square - if (shape == 2) return (abs(d.x) + abs(d.y)) - 0.5; // diamond - if (shape == 4) { // cross / plus - vec2 a = abs(d); - return min(max(a.x - 0.17, a.y - 0.5), max(a.x - 0.5, a.y - 0.17)); - } - if (shape == 5) { // regular hexagon (pointy top) - const vec3 k = vec3(-0.866025404, 0.5, 0.577350269); - vec2 p = abs(vec2(d.y, d.x)); - p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy; - p -= vec2(clamp(p.x, -k.z * 0.5, k.z * 0.5), 0.5); - return length(p) * sign(p.y); - } - if (shape == 6) return xyPentagonDistance(d); // exact regular pentagon - if (shape == 7) { // five-pointed star (apex up) - const float rf = 0.45; - const vec2 k1 = vec2(0.809016994, -0.587785252); - const vec2 k2 = vec2(-k1.x, k1.y); - vec2 p = vec2(abs(d.x), -d.y); - p -= 2.0 * max(dot(k1, p), 0.0) * k1; - p -= 2.0 * max(dot(k2, p), 0.0) * k2; - p = vec2(abs(p.x), p.y - 0.5); - vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0); - float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, 0.5); - return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y); - } - if (shape == 3 || shape == 8 || shape == 9 || shape == 10) { // Matplotlib triangle path - vec2 q = d; - if (shape == 8) q = -d; - if (shape == 9) q = vec2(d.y, -d.x); - if (shape == 10) q = vec2(-d.y, d.x); - return xyTriangleDistance(q, vec2(0.0, -0.5), vec2(-0.5, 0.5), vec2(0.5, 0.5)); - } - if (shape == 11) { // diagonal x - vec2 q = vec2(d.x + d.y, d.y - d.x) * 0.707106781; - vec2 a = abs(q); - return min(max(a.x - 0.17, a.y - 0.5), max(a.x - 0.5, a.y - 0.17)); - } - if (shape == 13) return max(abs(d.x), abs(d.y)) - 0.5; // snapped pixel - if (shape == 14) return (abs(d.x) / 0.6 + abs(d.y)) - 0.5; // thin diamond - return length(d) - 0.5; // circle -} -void main() { - vec2 d = gl_PointCoord - 0.5; - float sd; - int symbol = v_style.w >= 0.0 ? int(v_style.w + 0.5) : u_symbol; - bool lineMarker = symbol == 15 || symbol == 16; - if (lineMarker) { - vec2 q = symbol == 16 ? vec2(d.x + d.y, d.y - d.x) * 0.707106781 : d; - float itemStrokeWidth = v_style.z >= 0.0 ? v_style.z : u_ptStrokeWidth; - float halfWidth = max(itemStrokeWidth, 1.0) / (2.0 * max(v_ptSize, 1.0)); - vec2 a = abs(q); - sd = min(max(a.x - 0.5, a.y - halfWidth), max(a.y - 0.5, a.x - halfWidth)); - } else { - // Scalar-only equivalent: xyMarkerSdf(d, u_symbol). The resolved symbol - // also permits a per-item glyph override from v_style.w. - sd = xyMarkerSdf(d, symbol); - } - float aa = fwidth(sd) + 1e-4; - float shapeCov = clamp(0.5 - sd / aa, 0.0, 1.0); - if (shapeCov <= 0.001) discard; - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode == 0 ? u_color : vec4(texture(u_lut, vec2(clamp(v_lutCoord, 0.0, 1.0), 0.5)).rgb, 1.0)); - vec3 rgb = paint.rgb; - // Drill handoff (§5): near the density boundary, paint by local density with - // the density ramp; ease into native colors as the zoom deepens (u_dblend->0). - if (u_dblend > 0.001) { - vec3 drgb = texture(u_dlut, vec2(clamp(v_dval, 0.0, 1.0), 0.5)).rgb; - rgb = mix(rgb, drgb, u_dblend); - } - // §34 selected/unselected recolor: when a selection is active, tint each point - // toward its state color (.a is the mix weight; 0 = keep native color). - if (u_selActive == 1) { - vec4 sc = v_sel > 0.5 ? u_selColor : u_unselColor; - rgb = mix(rgb, sc.rgb, sc.a); - } - float intrinsicAlpha = paint.a; - float fillAlpha = (v_style.y >= 0.0 ? v_style.y : intrinsicAlpha) * v_style.x * u_opacity; - vec4 px = vec4(rgb * fillAlpha, fillAlpha); // premultiplied fill - // Uniform (u_ptStroke) and per-item (v_stroke) stroke paint ship straight - // alpha and go through the same artist-alpha/opacity stack, so a scalar - // CSS edge fades under alpha overrides exactly like SVG/PNG export. - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_ptStroke; - float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; - vec4 strokePx = u_ptStrokeFace == 1 ? px : vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); - if (lineMarker) { - outColor = strokePx * (shapeCov * v_dim); - return; - } - float itemStrokeWidth = v_style.z >= 0.0 ? v_style.z : u_ptStrokeWidth; - if (itemStrokeWidth > 0.0) { - float sw = itemStrokeWidth / max(v_ptSize, 1.0); // px -> gl_PointCoord units - // The supplied point size includes the edge. Recover Matplotlib's path - // boundary half a stroke inside it, then source-over the centered stroke. - float pathCov = clamp(0.5 - (sd + sw * 0.5) / aa, 0.0, 1.0); - float innerCov = clamp(0.5 - (sd + sw) / aa, 0.0, 1.0); - float strokeCov = max(shapeCov - innerCov, 0.0); - vec4 fillLayer = px * pathCov; - vec4 strokeLayer = strokePx * strokeCov; - px = strokeLayer + fillLayer * (1.0 - strokeLayer.a); - outColor = px * v_dim; - return; - } - outColor = px * (shapeCov * v_dim); -}`,fe=`#version 300 es -in float ax; in float ay; in float a_prevx; in float a_prevy; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -uniform float u_size; uniform float u_dpr; -uniform float u_transitionProgress; uniform int u_transitionActive; -${L} -void main() { - float x = u_transitionActive == 1 ? mix(a_prevx, ax, u_transitionProgress) : ax; - float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; - gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode), xyMap(y, u_ymap, u_ymeta, u_ymode), 0.0, 1.0); - gl_PointSize = u_size * u_dpr; -}`,pe=`#version 300 es -precision highp float; -uniform vec4 u_color; -out vec4 outColor; -void main() { - float sd = length(gl_PointCoord - 0.5) - 0.5; - float aa = fwidth(sd) + 1e-4; - float coverage = clamp(0.5 - sd / aa, 0.0, 1.0); - if (coverage <= 0.001) discard; - outColor = vec4(u_color.rgb * u_color.a, u_color.a) * coverage; -}`,me=`#version 300 es -in float ax; in float ay; in float a_prevx; in float a_prevy; in float a_sval; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -uniform float u_size; uniform int u_sizeMode; uniform vec2 u_sizeRange; uniform float u_dpr; -uniform float u_transitionProgress; uniform int u_transitionActive; -flat out int v_id; -${L} -void main() { - float x = u_transitionActive == 1 ? mix(a_prevx, ax, u_transitionProgress) : ax; - float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; - gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode), xyMap(y, u_ymap, u_ymeta, u_ymode), 0.0, 1.0); - float sz = u_sizeMode == 1 ? mix(u_sizeRange.x, u_sizeRange.y, a_sval) : u_size; - gl_PointSize = max(sz, 6.0) * u_dpr; // enlarge hit target - v_id = gl_VertexID; -}`,he=`#version 300 es -precision highp float; precision highp int; -uniform int u_pick_base; -flat in int v_id; -out vec4 outColor; -void main() { - vec2 d = gl_PointCoord - 0.5; - if (length(d) > 0.5) discard; - int id = u_pick_base + v_id; - outColor = vec4( - float(id & 255) / 255.0, - float((id >> 8) & 255) / 255.0, - float((id >> 16) & 255) / 255.0, - float((id >> 24) & 255) / 255.0 - ); -}`,ge=`#version 300 es -in vec2 a_corner; -uniform vec4 u_view; // x0,x1,y0,y1 -uniform int u_xmode; uniform int u_ymode; -out vec2 v_data; -${L} -void main() { - gl_Position = vec4(a_corner * 2.0 - 1.0, 0.0, 1.0); - float x = mix(xyViewCoord(u_view.x, u_xmode), xyViewCoord(u_view.y, u_xmode), a_corner.x); - float y = mix(xyViewCoord(u_view.z, u_ymode), xyViewCoord(u_view.w, u_ymode), a_corner.y); - v_data = vec2(xyViewValue(x, u_xmode), xyViewValue(y, u_ymode)); -}`,_e=`#version 300 es -precision highp float; -uniform sampler2D u_grid; uniform sampler2D u_lut; -uniform vec4 u_gridRange; // gx0,gx1,gy0,gy1 -uniform float u_opacity; uniform vec4 u_color; uniform int u_constantColor; -in vec2 v_data; -out vec4 outColor; -void main() { - vec2 uv = vec2((v_data.x - u_gridRange.x) / (u_gridRange.y - u_gridRange.x), - (v_data.y - u_gridRange.z) / (u_gridRange.w - u_gridRange.z)); - if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) discard; - float t = texture(u_grid, uv).r; - if (t <= 0.0) discard; - vec4 paint = u_constantColor == 1 - ? u_color - : texture(u_lut, vec2(clamp(t, 0.0, 1.0), 0.5)); - vec3 rgb = paint.rgb; - float alpha = u_opacity * paint.a * clamp(t * 1.35, 0.0, 1.0); - if (alpha <= 0.01) discard; - outColor = vec4(rgb * alpha, alpha); -}`,ve=`#version 300 es -precision highp float; -uniform sampler2D u_grid; uniform sampler2D u_lut; -uniform vec4 u_gridRange; // gx0,gx1,gy0,gy1 -uniform float u_opacity; -uniform int u_truecolor; -in vec2 v_data; -out vec4 outColor; -void main() { - vec2 uv = vec2((v_data.x - u_gridRange.x) / (u_gridRange.y - u_gridRange.x), - (v_data.y - u_gridRange.z) / (u_gridRange.w - u_gridRange.z)); - if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) discard; - vec4 sampled = texture(u_grid, uv); - if (u_truecolor == 1) { - float alpha = sampled.a * u_opacity; - if (alpha <= 0.0) discard; - outColor = vec4(sampled.rgb * alpha, alpha); - return; - } - float raw = sampled.r; - if (raw <= 0.0) discard; - float t = clamp((raw * 255.0 - 1.0) / 254.0, 0.0, 1.0); - vec3 rgb = texture(u_lut, vec2(t, 0.5)).rgb; - outColor = vec4(rgb * u_opacity, u_opacity); -}`,ye=`#version 300 es -in float ax0; in float ay0; in float ax1; in float ay1; -in float a_prevx; in float a_prevy; in float a_prevx1; in float a_prevy1; -uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_res; uniform float u_width; -uniform int u_colorMode; -uniform float u_transitionProgress; uniform int u_transitionActive; -uniform float u_revealProgress; uniform float u_revealSegments; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform int u_ymode; -in float a_len0; in float a_len1; -out float v_off; out float v_dash; -const vec2 corners[4] = vec2[4](vec2(0.,-1.), vec2(0.,1.), vec2(1.,-1.), vec2(1.,1.)); -${L} -void main() { - float px0 = u_transitionActive == 1 ? mix(a_prevx, ax0, u_transitionProgress) : ax0; - float py0 = u_transitionActive == 1 ? mix(a_prevy, ay0, u_transitionProgress) : ay0; - float px1 = u_transitionActive == 1 ? mix(a_prevx1, ax1, u_transitionProgress) : ax1; - float py1 = u_transitionActive == 1 ? mix(a_prevy1, ay1, u_transitionProgress) : ay1; - vec2 p0 = vec2(xyMap(px0, u_xmap, u_xmeta, u_xmode), xyMap(py0, u_ymap, u_ymeta, u_ymode)); - vec2 p1 = vec2(xyMap(px1, u_xmap, u_xmeta, u_xmode), xyMap(py1, u_ymap, u_ymeta, u_ymode)); - float reveal = clamp(u_revealProgress * u_revealSegments - float(gl_InstanceID), 0.0, 1.0); - p1 = mix(p0, p1, reveal); - vec2 pix0 = (p0 * 0.5 + 0.5) * u_res; - vec2 pix1 = (p1 * 0.5 + 0.5) * u_res; - vec2 dir = pix1 - pix0; - float len = max(length(dir), 1e-6); - dir /= len; - vec2 n = vec2(-dir.y, dir.x); - vec2 c = corners[gl_VertexID]; - float half_w = u_width * 0.5 + 0.5; - vec2 pos = mix(pix0, pix1, c.x) + dir * (c.x * 2.0 - 1.0) * 0.5 + n * c.y * half_w; - gl_Position = vec4(pos / u_res * 2.0 - 1.0, 0.0, 1.0); - v_off = c.y * half_w; - // Cumulative screen-space arc length at this fragment (device px), fed from - // CPU-computed per-vertex lengths so dashes stay continuous across segments - // and constant on screen through zoom. - v_dash = mix(a_len0, mix(a_len0, a_len1, reveal), c.x); -}`,be=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform float u_width; -uniform int u_dashCount; uniform float u_dashArr[8]; uniform float u_dashPeriod; -in float v_off; in float v_dash; -out vec4 outColor; -void main() { - float half_w = u_width * 0.5; - float alpha = (1.0 - smoothstep(half_w - 0.5, half_w + 0.5, abs(v_off))) * u_color.a; - if (u_dashCount > 0) { - float m = mod(v_dash, u_dashPeriod); - float acc = 0.0; - float on = 0.0; - for (int i = 0; i < 8; i++) { - if (i >= u_dashCount) break; - float next = acc + u_dashArr[i]; - if (m < next) { - // 0.6px feather at each dash start/end so edges aren't aliased. - float d = min(m - acc, next - m); - on = (i % 2 == 0) ? clamp(d + 0.6, 0.0, 1.0) : 1.0 - clamp(d + 0.6, 0.0, 1.0); - break; - } - acc = next; - } - alpha *= on; - } - if (alpha <= 0.001) discard; - outColor = vec4(u_color.rgb * alpha, alpha); -}`,xe=`#version 300 es -in float ax0; in float ay0; in float ax1; in float ay1; in float a_cval; in vec4 a_rgba; in vec4 a_style; -in float a_dash0; in float a_dashDir; -uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_res; uniform float u_width; -uniform float u_animationProgress; -uniform int u_colorMode; -uniform vec2 u_x0meta; uniform vec2 u_x1meta; uniform vec2 u_y0meta; uniform vec2 u_y1meta; -uniform int u_x0mode; uniform int u_x1mode; uniform int u_y0mode; uniform int u_y1mode; -out float v_off; out float v_cval; out float v_dash; out vec4 v_rgba; out vec4 v_style; -const vec2 corners[4] = vec2[4](vec2(0.,-1.), vec2(0.,1.), vec2(1.,-1.), vec2(1.,1.)); -${L} -void main() { - vec2 p0 = vec2(xyMap(ax0, u_xmap, u_x0meta, u_x0mode), xyMap(ay0, u_ymap, u_y0meta, u_y0mode)); - vec2 p1 = vec2(xyMap(ax1, u_xmap, u_x1meta, u_x1mode), xyMap(ay1, u_ymap, u_y1meta, u_y1mode)); - vec2 center = (p0 + p1) * 0.5; - p0 = mix(center, p0, u_animationProgress); - p1 = mix(center, p1, u_animationProgress); - vec2 pix0 = (p0 * 0.5 + 0.5) * u_res; - vec2 pix1 = (p1 * 0.5 + 0.5) * u_res; - vec2 dir = pix1 - pix0; - float len = max(length(dir), 1e-6); - dir /= len; - vec2 n = vec2(-dir.y, dir.x); - vec2 c = corners[gl_VertexID]; - float itemWidth = a_style.z >= 0.0 ? a_style.z : u_width; - float half_w = itemWidth * 0.5 + 0.5; - vec2 pos = mix(pix0, pix1, c.x) + dir * (c.x * 2.0 - 1.0) * 0.5 + n * c.y * half_w; - gl_Position = vec4(pos / u_res * 2.0 - 1.0, 0.0, 1.0); - v_off = c.y * half_w; - v_cval = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - v_dash = a_dash0 + c.x * len * a_dashDir; - v_rgba = a_rgba; v_style = a_style; -}`,Se=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform float u_width; uniform int u_colorMode; uniform sampler2D u_lut; uniform float u_opacity; -uniform int u_dashCount; uniform float u_dashArr[8]; uniform float u_dashPeriod; -in float v_off; in float v_cval; in float v_dash; in vec4 v_rgba; in vec4 v_style; -out vec4 outColor; -void main() { - float itemWidth = v_style.z >= 0.0 ? v_style.z : u_width; - float half_w = itemWidth * 0.5; - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode != 0 ? vec4(texture(u_lut, vec2(clamp(v_cval, 0.0, 1.0), 0.5)).rgb, 1.0) : u_color); - vec3 rgb = paint.rgb; - float paintAlpha = (v_style.y >= 0.0 ? v_style.y : paint.a) * v_style.x * u_opacity; - float alpha = (1.0 - smoothstep(half_w - 0.5, half_w + 0.5, abs(v_off))) * paintAlpha; - if (u_dashCount > 0) { - float m = mod(v_dash, u_dashPeriod); - float acc = 0.0; - float on = 0.0; - for (int i = 0; i < 8; i++) { - if (i >= u_dashCount) break; - float next = acc + u_dashArr[i]; - if (m < next) { on = (i % 2 == 0) ? 1.0 : 0.0; break; } - acc = next; - } - alpha *= on; - } - if (alpha <= 0.001) discard; - outColor = vec4(rgb * alpha, alpha); -}`,Ce=`#version 300 es -in float ax0; in float ay0; in float ax1; in float ay1; in float ax2; in float ay2; in float a_cval; -in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; -uniform vec2 u_xmap; uniform vec2 u_ymap; -uniform vec2 u_x0meta; uniform vec2 u_x1meta; uniform vec2 u_x2meta; -uniform vec2 u_y0meta; uniform vec2 u_y1meta; uniform vec2 u_y2meta; -uniform int u_x0mode; uniform int u_x1mode; uniform int u_x2mode; -uniform int u_y0mode; uniform int u_y1mode; uniform int u_y2mode; -uniform int u_colorMode; -out float v_cval; out vec3 v_bary; out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; -${L} -void main() { - int vertex = gl_VertexID % 3; - float x = vertex == 0 ? ax0 : (vertex == 1 ? ax1 : ax2); - float y = vertex == 0 ? ay0 : (vertex == 1 ? ay1 : ay2); - vec2 xm = vertex == 0 ? u_x0meta : (vertex == 1 ? u_x1meta : u_x2meta); - vec2 ym = vertex == 0 ? u_y0meta : (vertex == 1 ? u_y1meta : u_y2meta); - int xmode = vertex == 0 ? u_x0mode : (vertex == 1 ? u_x1mode : u_x2mode); - int ymode = vertex == 0 ? u_y0mode : (vertex == 1 ? u_y1mode : u_y2mode); - gl_Position = vec4(xyMap(x, u_xmap, xm, xmode), xyMap(y, u_ymap, ym, ymode), 0.0, 1.0); - v_cval = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - v_bary = vertex == 0 ? vec3(1.,0.,0.) : (vertex == 1 ? vec3(0.,1.,0.) : vec3(0.,0.,1.)); - v_rgba = a_rgba; v_style = a_style; v_stroke = a_stroke; -}`,we=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform int u_colorMode; uniform sampler2D u_lut; uniform float u_opacity; -uniform vec4 u_stroke; uniform float u_strokeWidth; uniform int u_strokeMode; uniform float u_strokeOpacity; -in float v_cval; in vec3 v_bary; in vec4 v_rgba; in vec4 v_style; in vec4 v_stroke; -out vec4 outColor; -void main() { - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode == 0 ? u_color : vec4(texture(u_lut, vec2(clamp(v_cval, 0.0, 1.0), 0.5)).rgb, 1.0)); - float alpha = (v_style.y >= 0.0 ? v_style.y : paint.a) * v_style.x * u_opacity; - vec4 fill = vec4(paint.rgb * alpha, alpha); - float strokeWidth = v_style.z >= 0.0 ? v_style.z : u_strokeWidth; - if (strokeWidth > 0.0) { - float edge = min(v_bary.x, min(v_bary.y, v_bary.z)); - float coverage = smoothstep(0.0, max(fwidth(edge) * strokeWidth, 1e-5), edge); - // Both stroke sources ship straight alpha; the per-item alpha stack - // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; - float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; - vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); - outColor = mix(stroke, fill, coverage); - } else { - outColor = fill; - } -}`,Te=` -uniform int u_gradMode; uniform int u_gradDir; uniform int u_gradCount; -uniform float u_gradPos[8]; uniform vec4 u_gradColor[8]; -vec4 xyGradSample(float t) { - vec4 c0 = u_gradColor[0]; float p0 = u_gradPos[0]; - if (t <= p0) return c0; - for (int i = 1; i < 8; i++) { - if (i >= u_gradCount) break; - float p1 = u_gradPos[i]; vec4 c1 = u_gradColor[i]; - if (t <= p1) return mix(c0, c1, (t - p0) / max(p1 - p0, 1e-6)); - p0 = p1; c0 = c1; - } - return c0; -} -float xyGradT(float markT, vec2 res) { - float t; - if (u_gradMode == 2) { - vec2 f = gl_FragCoord.xy / max(res, vec2(1.0)); - t = u_gradDir == 0 ? 1.0 - f.y : u_gradDir == 1 ? f.y : u_gradDir == 2 ? 1.0 - f.x : f.x; - } else { - t = u_gradDir == 0 ? 1.0 - markT : markT; - } - return clamp(t, 0.0, 1.0); -}`,Ee=`#version 300 es -in float ax0; in float ax1; in float ay0; in float ay1; in float ab0; in float ab1; -uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_bmap; -uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform vec2 u_bmeta; -uniform int u_xmode; uniform int u_ymode; -uniform float u_revealProgress; uniform float u_revealSegments; -out float v_top; out float v_base; out float v_pos; -const vec2 corners[4] = vec2[4](vec2(0.,0.), vec2(1.,0.), vec2(0.,1.), vec2(1.,1.)); -${L} -void main() { - vec2 c = corners[gl_VertexID]; - float x0 = xyMap(ax0, u_xmap, u_xmeta, u_xmode); - float x1 = xyMap(ax1, u_xmap, u_xmeta, u_xmode); - float y0 = xyMap(ay0, u_ymap, u_ymeta, u_ymode); - float y1 = xyMap(ay1, u_ymap, u_ymeta, u_ymode); - float b0 = xyMap(ab0, u_bmap, u_bmeta, u_ymode); - float b1 = xyMap(ab1, u_bmap, u_bmeta, u_ymode); - float reveal = clamp(u_revealProgress * u_revealSegments - float(gl_InstanceID), 0.0, 1.0); - x1 = mix(x0, x1, reveal); - y1 = mix(y0, y1, reveal); - b1 = mix(b0, b1, reveal); - float top = mix(y0, y1, c.x); - float base = mix(b0, b1, c.x); - float clipY = mix(base, top, c.y); - // Carry the curve top, baseline, and this fragment's Y *separately* (each is - // linear in x and continuous across segments); the fragment divides them for - // a true per-column height fraction. Interpolating the ratio itself (the old - // c.y) facets over the slanted-top quad and streaks — this doesn't, and the - // fill stays evenly saturated at the curve whatever its height. - v_top = top; - v_base = base; - v_pos = clipY; - gl_Position = vec4(mix(x0, x1, c.x), clipY, 0.0, 1.0); -}`,De=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; -uniform vec2 u_res; -in float v_top; in float v_base; in float v_pos; -out vec4 outColor; -${Te} -void main() { - vec4 premult = vec4(u_color.rgb * u_color.a, u_color.a); - if (u_gradMode != 0) { - // 0 at the baseline, 1 exactly at the curve — even at the curve everywhere. - float denom = v_top - v_base; - float markT = clamp((v_pos - v_base) / (abs(denom) > 1e-6 ? denom : 1e-6), 0.0, 1.0); - // Compose the mark opacity (premultiplied) over the gradient sample. - premult = xyGradSample(xyGradT(markT, u_res)) * u_color.a; - } - if (premult.a <= 0.001) discard; - outColor = premult; -}`,Oe=`#version 300 es -in float ax0; in float ax1; in float ay0; in float ay1; -uniform vec2 u_x0map; uniform vec2 u_x1map; uniform vec2 u_y0map; uniform vec2 u_y1map; -uniform vec2 u_x0meta; uniform vec2 u_x1meta; uniform vec2 u_y0meta; uniform vec2 u_y1meta; -uniform int u_xmode; uniform int u_ymode; -uniform vec4 u_edgePad; -uniform vec2 u_res; -in float a_cval; in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; in vec2 a_radius; -uniform int u_colorMode; -out float v_lutCoord; -out vec2 v_local; out vec2 v_half; out float v_t; -out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; out vec2 v_radius; -const vec2 corners[4] = vec2[4](vec2(0.,0.), vec2(1.,0.), vec2(0.,1.), vec2(1.,1.)); -${L} -void main() { - vec2 c = corners[gl_VertexID]; - float x0 = xyMap(ax0, u_x0map, u_x0meta, u_xmode) + u_edgePad.x; - float x1 = xyMap(ax1, u_x1map, u_x1meta, u_xmode) + u_edgePad.y; - float y0 = xyMap(ay0, u_y0map, u_y0meta, u_ymode) + u_edgePad.z; - float y1 = xyMap(ay1, u_y1map, u_y1meta, u_ymode) + u_edgePad.w; - v_lutCoord = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - // Pixel-space local frame for the rounded-corner/stroke SDF (v_half is - // constant across the quad; v_local interpolates to the fragment offset). - vec2 pA = (vec2(x0, y0) * 0.5 + 0.5) * u_res; - vec2 pB = (vec2(x1, y1) * 0.5 + 0.5) * u_res; - v_half = abs(pB - pA) * 0.5; - v_local = mix(pA, pB, c) - (pA + pB) * 0.5; - v_t = c.y; - v_rgba = a_rgba; v_style = a_style; v_stroke = a_stroke; v_radius = a_radius; - gl_Position = vec4(mix(x0, x1, c.x), mix(y0, y1, c.y), 0.0, 1.0); -}`,ke=`#version 300 es -in float a_pos; in float a_v0; in float a_v1; in float a_cval; -in float a_prevx; in float a_prevy; in float a_prevx1; -in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; in vec2 a_radius; -uniform vec2 u_pmap; uniform vec2 u_v0map; uniform vec2 u_v1map; -uniform vec2 u_pmeta; uniform vec2 u_v0meta; uniform vec2 u_v1meta; -uniform int u_pmode; uniform int u_vmode; -uniform float u_width; uniform int u_orientation; uniform int u_v0Mode; uniform float u_v0Const; -uniform float u_v0EdgePad; -uniform float u_animationProgress; -uniform float u_transitionProgress; uniform int u_transitionActive; uniform float u_prevWidth; -uniform vec2 u_res; -uniform int u_colorMode; -out float v_lutCoord; -out vec2 v_local; out vec2 v_half; out float v_t; -out vec4 v_rgba; out vec4 v_style; out vec4 v_stroke; out vec2 v_radius; -const vec2 corners[4] = vec2[4](vec2(0.,0.), vec2(1.,0.), vec2(0.,1.), vec2(1.,1.)); -${L} -void main() { - vec2 c = corners[gl_VertexID]; - float nextP = xyMap(a_pos, u_pmap, u_pmeta, u_pmode); - float nextV0 = u_v0Mode == 0 ? u_v0Const : xyMap(a_v0, u_v0map, u_v0meta, u_vmode); - float nextV1 = xyMap(a_v1, u_v1map, u_v1meta, u_vmode); - float p = nextP; - float v0 = nextV0; - float v1 = nextV1; - float width = u_width; - if (u_transitionActive == 1) { - p = mix(xyMap(a_prevx, u_pmap, u_pmeta, u_pmode), nextP, u_transitionProgress); - // Previous baselines are encoded in the next value column's coordinate - // system, which lets constant and per-row baselines share one attribute. - v0 = mix(xyMap(a_prevx1, u_v1map, u_v1meta, u_vmode), nextV0, u_transitionProgress); - v1 = mix(xyMap(a_prevy, u_v1map, u_v1meta, u_vmode), nextV1, u_transitionProgress); - width = mix(u_prevWidth, u_width, u_transitionProgress); - } - v0 += u_v0EdgePad; - v1 = mix(v0, v1, u_animationProgress); - float halfW = abs(width * u_pmap.x) * 0.5; - v_lutCoord = u_colorMode == 2 ? (a_cval + 0.5) / 256.0 : a_cval; - vec2 clipA, clipB; - if (u_orientation == 0) { - clipA = vec2(p - halfW, v0); clipB = vec2(p + halfW, v1); - gl_Position = vec4(mix(clipA.x, clipB.x, c.x), mix(clipA.y, clipB.y, c.y), 0.0, 1.0); - v_t = c.y; - } else { - clipA = vec2(v0, p - halfW); clipB = vec2(v1, p + halfW); - gl_Position = vec4(mix(clipA.x, clipB.x, c.x), mix(clipA.y, clipB.y, c.y), 0.0, 1.0); - v_t = c.x; - } - // Pixel-space local frame for the rounded-corner/stroke SDF; v_t runs along - // the value axis (0 at the base, 1 at the bar tip) for mark-space gradients. - vec2 pA = (clipA * 0.5 + 0.5) * u_res; - vec2 pB = (clipB * 0.5 + 0.5) * u_res; - v_half = abs(pB - pA) * 0.5; - v_local = vec2(mix(pA.x, pB.x, c.x), mix(pA.y, pB.y, c.y)) - (pA + pB) * 0.5; - v_rgba = a_rgba; v_style = a_style; v_stroke = a_stroke; v_radius = a_radius; -}`,Ae=`#version 300 es -precision highp float; precision highp int; -uniform vec4 u_color; uniform int u_colorMode; uniform sampler2D u_lut; -uniform vec2 u_radius; uniform float u_strokeWidth; uniform vec4 u_stroke; -uniform int u_strokeMode; uniform float u_strokeOpacity; -uniform float u_opacity; -uniform vec2 u_res; -in float v_lutCoord; -in vec2 v_local; in vec2 v_half; in float v_t; -in vec4 v_rgba; in vec4 v_style; in vec4 v_stroke; in vec2 v_radius; -out vec4 outColor; -${Te} -void main() { - vec4 paint = u_colorMode == 3 ? v_rgba : (u_colorMode == 0 ? u_color : vec4(texture(u_lut, vec2(clamp(v_lutCoord, 0.0, 1.0), 0.5)).rgb, 1.0)); - float alpha = (v_style.y >= 0.0 ? v_style.y : paint.a) * v_style.x * u_opacity; - vec4 premult = vec4(paint.rgb * alpha, alpha); - if (u_gradMode != 0) { - vec4 gradient = xyGradSample(xyGradT(v_t, u_res)); - float gradientAlpha = (v_style.y >= 0.0 ? v_style.y : gradient.a) * v_style.x * u_opacity; - // Gradient stops are uploaded premultiplied. Recover their straight RGB - // before applying an artist-alpha override, then premultiply the result. - vec3 gradientRgb = gradient.a > 1e-6 ? gradient.rgb / gradient.a : vec3(0.0); - premult = vec4(gradientRgb * gradientAlpha, gradientAlpha); - } - vec2 radius = v_radius.x >= 0.0 ? v_radius : u_radius; - float strokeWidth = v_style.z >= 0.0 ? v_style.z : u_strokeWidth; - if (radius.x > 0.0 || radius.y > 0.0 || strokeWidth > 0.0) { - // u_radius = (tip, base) in mark space: v_t > 0.5 is the tip half, so - // corner_radius=(6, 0) rounds only the value end of the bar. On the - // straight sides the SDF reduces to |local|-half independent of r, so - // differing radii meet with no seam. - float r = min(v_t > 0.5 ? radius.x : radius.y, min(v_half.x, v_half.y)); - vec2 q = abs(v_local) - (v_half - vec2(r)); - float d = length(max(q, vec2(0.0))) + min(max(q.x, q.y), 0.0) - r; - float aa = 0.75; - if (strokeWidth > 0.0) { - // Both stroke sources ship straight alpha; the per-item alpha stack - // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; - float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; - vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); - float inner = 1.0 - smoothstep(-aa, aa, d + strokeWidth); - premult = mix(stroke, premult, inner); - } - premult *= 1.0 - smoothstep(-aa, aa, d); - } - if (premult.a <= 0.001) discard; - outColor = premult; -}`;function je(e,t,n){let r=new Float64Array(n-1),i=new Float64Array(n);for(let i=0;i0?(t[i+1]-t[i])/n:0}i[0]=r[0],i[n-1]=r[n-2];for(let e=1;e9){let o=3/Math.sqrt(a);i[e]=o*t*r[e],i[e+1]=o*n*r[e]}}return i}function Me(e,t,n,r,i){if(r<3)return null;let a=Math.max(1,Math.min(16,Math.floor(i/r)));if(a<=1)return null;for(let i=0;i0&&e[i]0){let e=p*p,a=e*p,c=2*a-3*e+1,l=a-2*e+p,m=-2*a+3*e,h=a-e;u[f]=c*t[i]+l*r*o[i]+m*t[i+1]+h*r*o[i+1],d&&(d[f]=c*n[i]+l*r*s[i]+m*n[i+1]+h*r*s[i+1])}else u[f]=t[i],d&&(d[f]=n[i]);f++}}return l[f]=e[r-1],u[f]=t[r-1],d&&(d[f]=n[r-1]),{x:l,y:u,extra:d,n:c}}var Ne=2e5,Pe=1.15;function R(e,t,n=140){if(t==null||n<=0||e._prefersReducedMotion())return 1;let r=Math.min(1,Math.max(0,(e._now()-t)/n));return r*r*(3-2*r)}function Fe(e,t){let n=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength),r=new Float32Array(n.length),i=Math.log1p(Math.max(0,t||0));if(i>0)for(let e=0;e0&&(r[e]=Math.expm1(n[e]/255*i));return r}function Ie(e){return e.slice?e.slice():new Float32Array(e)}function z(e,t,n,r,i,a){let o=new Uint8Array(n.length),s=Math.log1p(Math.max(0,a||0));if(s>0)for(let e=0;e0&&Number.isFinite(t)&&(o[e]=Math.max(1,Math.min(255,Math.round(255*Math.log1p(t)/s))))}e.bindTexture(e.TEXTURE_2D,t);let c=e.getParameter(e.UNPACK_ALIGNMENT);e.pixelStorei(e.UNPACK_ALIGNMENT,1),e.texImage2D(e.TEXTURE_2D,0,e.R8,r,i,0,e.RED,e.UNSIGNED_BYTE,o),e.pixelStorei(e.UNPACK_ALIGNMENT,c),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)}function Le(e,t){if(!Number.isFinite(t)||t<=0)return e.densityNormMax=0,0;let n=Number.isFinite(e.densityNormMax)&&e.densityNormMax>0?e.densityNormMax:t,r=t>n?n*.3+t*.7:Math.max(t,n*.86);return e.densityNormMax=r,r}function Re(e,t,n,r){if(!t.density||!t.density.grid||!Number.isFinite(r)||r<=0){t._densityNormAnim=null;return}let i=Math.abs(Math.log(Math.max(n,1e-12)/Math.max(r,1e-12)));if(e._prefersReducedMotion()||i<.02){t._densityNormAnim=null,t.density.normMax=r,t.densityNormMax=r,z(e.gl,t.density.tex,t.density.grid,t.density.w,t.density.h,r);return}t._densityNormAnim={start:n,target:r,startedAt:e._now(),duration:r.004||i>=1)&&(r.normMax=o,t.densityNormMax=o,z(e.gl,r.tex,r.grid,r.w,r.h,o)),i<1){e.draw();return}r.normMax=n.target,t.densityNormMax=n.target,t._densityNormAnim=null}function B(e){return Math.abs((e.xRange[1]-e.xRange[0])*(e.yRange[1]-e.yRange[0]))}function Be(e){return e?Math.abs((e.x1-e.x0)*(e.y1-e.y0)):0}function Ve(e,t){if(!e||!t)return!1;let n=(t.x0+t.x1)/2,r=(t.y0+t.y1)/2;return n>=Math.min(e.x0,e.x1)&&n<=Math.max(e.x0,e.x1)&&r>=Math.min(e.y0,e.y1)&&r<=Math.max(e.y0,e.y1)}function He(e,t){let n=t.densityCache||(t.density?[t.density]:[]),r=null,i=null;for(let t of n)!t||!t.tex||((!i||B(t)>B(i))&&(i=t),e._viewInsideRange(t.xRange,t.yRange)&&(!r||B(t)1200||!Ve(n.win,r))return!1;let i=Be(n.win),a=Be(r);if(!Number.isFinite(i)||!Number.isFinite(a)||i<=0)return!1;let o=Number.isFinite(n.visible)?n.visible:n.n;return!Number.isFinite(o)||o<=0?!1:o*Math.max(1,a/i)<=Ne*Pe}function We(e,t){return t===e.density||t===e.prevDensity||t===e._densitySwitchPrev||t===e._shownDensity||t===e._homeDensity}function V(e,t,n){if(!(!n||!n.tex))for(n._stamp=++e._densityStamp,t.densityCache||=[],t.densityCache.includes(n)||t.densityCache.push(n);t.densityCache.length>8;){let n=-1;for(let e=0;en.channels&&n.channels[e],u=Number(o.trace.style&&o.trace.style.artist_alpha);if(l(`opacity`)||l(`artist_alpha`)||l(`stroke_width`)||l(`symbol`)||Number.isFinite(u)){let t=new Float32Array(o.n*4);for(let e=0;e{let s=l(n);if(!s)return;let c=s.dtype===`u8`?e._asU8(r[s.buf]):e._asF32(r[s.buf]),u=s.components||1;for(let e=0;e=i.x0&&t<=i.x1&&u>=i.y0&&u<=i.y1&&(l[e]=1)}else if(i.mode===`poly`&&Array.isArray(i.points)&&i.points.length>=3){let e=i.points;for(let i=0;iu!=s>u&&t<(o-i)*(u-a)/(s-a)+i&&(d=!d)}d&&(l[i]=1)}}else return;e._applySelMask(t,l)}function qe(e,t){let n=t.drill;if(!n)return;let r=e.gl;e._deleteVaos(n);for(let e of[n.xBuf,n.yBuf,n.cBuf,n.rgbaBuf,n.sBuf,n.styleBuf,n.strokeBuf,n.selBuf,n.dBuf])e&&r.deleteBuffer(e);t.drill=null,t._drillFadeStart=null,t._drillExitFadeStart=null,t._drillWasInside=!1,t._drillShownAlpha=null,t._drillDying=!1,t._drillDiedInsideWin=!1,e._hoverId=-1,e._lastRow=null,e._updatePickable()}function Je(e,t){t.drill&&(t._drillDying=!0,t._drillDiedInsideWin=e._viewInside(t.drill.win),Qe(e,t))}function Ye(e,t){(t._drillExitFadeStart===void 0||t._drillExitFadeStart===null)&&(t._drillExitFadeStart=e._now());let n=R(e,t._drillExitFadeStart,H);return n>=1&&(t._drillExitFadeStart=null),n}var Xe=140,H=120;function U(e){return .5-Math.sin(Math.asin(1-2*Math.min(1,Math.max(0,e)))/3)}function Ze(e,t){return t._drillExitFadeStart==null?t._drillFadeStart==null?t._drillShownAlpha==null?+!!t._drillWasInside:t._drillShownAlpha:R(e,t._drillFadeStart,Xe):1-R(e,t._drillExitFadeStart,H)}function W(e,t){let n=Ze(e,t);t._drillShownAlpha=n,t._drillExitFadeStart=null,t._drillFadeStart=n>=1?null:e._now()-Xe*U(n)}function Qe(e,t){if(t._drillExitFadeStart!=null)return;let n=Ze(e,t);t._drillShownAlpha=n,t._drillFadeStart=null,t._drillExitFadeStart=e._now()-H*U(1-n)}function $e(e,t,n,r){Je(e,t);let i=n.density,a=i.enc===`log-u8`?Fe(r[i.buf],i.max):Ie(e._asF32(r[i.buf])),o=Le(t,i.max),s=e._prefersReducedMotion()?i.max:o;t.densityNormMax=s,t.prevDensity=t.density,t._densityFadeStart=e._now(),t.density={w:i.w,h:i.h,max:i.max,normMax:s,colormap:i.colormap||t.density.colormap,color:i.color?x(e.root,i.color,[.3,.47,.66,1]):t.density.color,xRange:i.x_range,yRange:i.y_range,grid:a,tex:e._uploadGrid(a,i.w,i.h,s),lut:t.density.lut},Object.prototype.hasOwnProperty.call(i,`sample`)&&e._applyDensitySample(t,i.sample,r),Re(e,t,s,i.max),V(e,t,t.density)}function et(e,t,n,r=1){if(n!==t._shownDensity){if(n===t._densitySwitchPrev&&t._densitySwitchFadeStart!=null){let n=R(e,t._densitySwitchFadeStart,140);t._densitySwitchFadeStart=e._now()-140*U(1-n)}else t._densitySwitchFadeStart=e._now();t._densitySwitchPrev=t._shownDensity,t._shownDensity=n}let i=t._densitySwitchPrev,a=i&&i.tex?R(e,t._densitySwitchFadeStart,140):1;if(a<1){e._drawDensity(t,i,(1-a)*r),e._drawDensity(t,n,a*r),e.draw();return}a>=1&&(t.prevDensity===t._densitySwitchPrev&&(t.prevDensity=null),t._densitySwitchPrev=null,t._densitySwitchFadeStart=null,n===t.density&&(t._densityFadeStart=null)),e._drawDensity(t,n,r)}function tt(e,t,n,r,i,a){ze(e,t);let o=t.drill;o&&t._drillDying&&!t._drillDiedInsideWin&&e._viewInside(o.win)&&(t._drillDying=!1,W(e,t),t._drillWasInside=!0);let s=o&&!t._drillDying&&e._viewInside(o.win),c=He(e,t);if(s){(!t._drillWasInside||t._drillExitFadeStart!=null)&&W(e,t),t._drillWasInside=!0,t._drillExitFadeStart=null;let s=R(e,t._drillFadeStart);t._drillShownAlpha=s,t._shownDensity=s<1?c:null,t._densitySwitchPrev=null,t._densitySwitchFadeStart=null,s<1&&c&&c.tex?(e._drawDensity(t,c,1-s),e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis),s),e.draw()):(t._drillFadeStart=null,e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis)))}else if(c&&c.tex){if(Ue(e,t,o)){W(e,t);let s=R(e,t._drillFadeStart);t._drillShownAlpha=s,s<1?(e._drawDensity(t,c,1-s),e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis),s),e.draw()):(t._drillFadeStart=null,e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis))),e._viewAnim&&e.draw();return}let s=o&&t._drillWasInside;s&&Qe(e,t);let l=s?Ye(e,t):1;o&&(t._drillShownAlpha=s&&l<1?1-l:0),s&&l<1?(et(e,t,c,l),e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis),1-l),e.draw()):(t._drillDying?qe(e,t):s&&(t._drillWasInside=!1),et(e,t,c),e._drawDensitySample(t,n,r,i,a))}else o&&e._drawPoints(o,e._map(o.xMeta,n,r,o.xAxis),e._map(o.yMeta,i,a,o.yAxis))}var G={build:(e,t,n,r)=>e._buildRectMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis),o=t.trace.kind===`histogram`?[0,0,e._edgePadForValue(0,i,a,e.canvas.height),0]:[0,0,0,0];e._drawRects(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.x1Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis),e._map(t.y1Meta,i,a,t.yAxis),o)},refreshColor:(e,t)=>{t.colorMode||(t.color=x(e.root,t.trace.style.color,t.color)),e._rectMarkStyleGpu(t,t.trace)}},nt={build:(e,t,n,r)=>e._buildBarMark(t,n,r),draw:(e,t)=>{if(!t.trace.bar){G.draw(e,t);return}let n=t.orientation===1,r=n?t.yAxis:t.xAxis,i=n?t.xAxis:t.yAxis,[a,o]=e._axisRange(r),[s,c]=e._axisRange(i),l=e._map(t.posMeta,a,o,r),u=e._map(t.value1Meta,s,c,i),d=t.value0Mode===1?e._map(t.value0Meta,s,c,i):null,f=t.value0Mode===0?e._mapConst(t.value0Const,s,c,i):null,p=t.value0Mode===0?e._edgePadForValue(t.value0Const,s,c,n?e.canvas.width:e.canvas.height):0;e._drawBars(t,l,u,d,f,p)},refreshColor:(e,t)=>{t.colorMode||(t.color=x(e.root,t.trace.style.color,t.color)),e._rectMarkStyleGpu(t,t.trace)}},K={build:(e,t,n,r)=>e._buildSegmentMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawSegments(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.colorMode||(t.color=x(e.root,t.trace.style.color,t.color))}},rt={build:(e,t,n,r)=>e._buildAreaMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis),o=e._map(t.xMeta,n,r,t.xAxis),s=e._map(t.yMeta,i,a,t.yAxis);if(e._drawArea(t,o,s,e._map(t.baseMeta,i,a,t.yAxis)),(t.trace.style.line_width??0)>0&&(e._drawLine(t,o,s,t.lineColor,t.trace.style.line_width,t.trace.style.line_opacity??1),t.trace.style.stroke_perimeter)){let n=t.yBuf,r=t.yMeta,i=t._dashY;t.yBuf=t.baseBuf,t.yMeta=t.baseMeta,t._dashY=t._cpu.base,e._drawLine(t,o,s,t.lineColor,t.trace.style.line_width,t.trace.style.line_opacity??1),t.yBuf=n,t.yMeta=r,t._dashY=i}},refreshColor:(e,t)=>{t.color=x(e.root,t.trace.style.color,t.color),t.lineColor=x(e.root,t.trace.style.line_color||t.trace.style.color,t.lineColor||t.color),t.grad=e._resolveMarkFill(t.trace.style,t.color)}},q={histogram:G,box:G,violin:G,errorbar:K,stem:K,box_whisker:K,box_median:K,contour:K,segments:K,triangle_mesh:{build:(e,t,n,r)=>e._buildMeshMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawMesh(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.colorMode===0&&t.trace.color&&(t.color=x(e.root,t.trace.color.color,t.color));let n=t.trace.style||{};t.meshStroke=x(e.root,n.stroke||`transparent`,[0,0,0,0])}},error_band:rt,hexbin:{build:(e,t,n,r)=>e._buildHexbinMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawMesh(t,e._map(t.x0Meta,n,r,t.xAxis),e._map(t.y0Meta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.colorMode===0&&t.trace.color&&(t.color=x(e.root,t.trace.color.color,t.color));let n=t.trace.style||{};t.meshStroke=x(e.root,n.stroke||`transparent`,[0,0,0,0])}},bar:nt,column:nt,heatmap:{build:(e,t,n,r)=>e._buildHeatmapMark(t,n,r),draw:(e,t)=>e._drawHeatmap(t)},scatter:{build:(e,t,n,r)=>e._buildScatterMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawPoints(t,e._map(t.xMeta,n,r,t.xAxis),e._map(t.yMeta,i,a,t.yAxis))},pointPick:!0,retainCpu:!0,refreshColor:(e,t)=>{t.colorMode===0&&t.trace.color&&(t.color=x(e.root,t.trace.color.color,t.color)),e._pointMarkStyle(t,t.trace)}},line:{build:(e,t,n,r)=>e._buildLineMark(t,n,r),draw:(e,t)=>{let[n,r]=e._axisRange(t.xAxis),[i,a]=e._axisRange(t.yAxis);e._drawLine(t,e._map(t.xMeta,n,r,t.xAxis),e._map(t.yMeta,i,a,t.yAxis))},refreshColor:(e,t)=>{t.color=x(e.root,t.trace.style.color,t.color)}},area:rt};function J(e){return q[e]||q.scatter}var Y={l:62,r:14,t:10,b:42},X=18,it=24,at=8,ot=0,st=`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;`,ct=new Set([`animation-iteration-count`,`aspect-ratio`,`border-image-outset`,`border-image-slice`,`border-image-width`,`column-count`,`flex`,`flex-grow`,`flex-shrink`,`font-weight`,`line-height`,`opacity`,`order`,`orphans`,`tab-size`,`widows`,`z-index`,`zoom`,`fill-opacity`,`flood-opacity`,`stop-opacity`,`stroke-miterlimit`,`stroke-opacity`]),Z={views:new Set,seq:1,hiddenReleaseChannel:null,hiddenReleaseQueue:[],frameId:null,channel:null,foreign:null,_announcedLive:-1,_crossFrameReady:!1,_rebalanceScheduled:!1,budget(){let e=typeof window<`u`?window.XY_CONTEXT_BUDGET:null;return Number.isFinite(e)&&e>=1?Math.floor(e):12},register(e){this._initCrossFrame(),this.views.add(e)},unregister(e){e._ctxPendingReservation=!1,this.views.delete(e),this._announceLive()},reserve(e){let t=[],n=0;for(let r of this.views)r!==e&&r.gl&&!r._glLost&&!r._destroyed&&t.push(r),r!==e&&r._ctxPendingReservation&&!r._destroyed&&(n+=1);let r=!e._ctxPendingReservation;e._ctxPendingReservation=!0;let i=t.length+n+ +!!r-this.budget();if(i<=0)return;let a=t.filter(e=>!e._ctxVisible).sort((e,t)=>(e._ctxSeenSeq||0)-(t._ctxSeenSeq||0));for(let e of a){if(i<=0)break;e._releaseContext()&&--i}if(i<=0)return;let o=t.filter(e=>e._ctxVisible).sort((e,t)=>(e._ctxSeenSeq||0)-(t._ctxSeenSeq||0));for(let e of o){if(i<=0)break;e._releaseContext()&&--i}},acquired(e){e._ctxPendingReservation=!1,this._rebalance(),this._announceLive()},cancel(e){e._ctxPendingReservation=!1},_initCrossFrame(){if(!this._crossFrameReady&&(this._crossFrameReady=!0,this.foreign=new Map,!(typeof BroadcastChannel>`u`)))try{this.frameId=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,this.channel=new BroadcastChannel(`xy-webgl-context-governor`),this.channel.onmessage=e=>this._onForeignMessage(e.data),this._post({t:`hello`,id:this.frameId}),typeof window<`u`&&window.addEventListener&&(window.addEventListener(`pagehide`,()=>this._post({t:`bye`,id:this.frameId})),window.addEventListener(`pageshow`,e=>{!e||!e.persisted||(this.foreign.clear(),this._announcedLive=-1,this._post({t:`hello`,id:this.frameId}),this._announceLive(!0))}))}catch{this.channel=null}},_post(e){try{this.channel&&this.channel.postMessage(e)}catch{}},_onForeignMessage(e){!e||!this.foreign||e.id===this.frameId||(e.t===`live`?(this.foreign.set(e.id,e.n|0),this._rebalance()):e.t===`hello`?this._announceLive(!0):e.t===`bye`&&this.foreign.delete(e.id))},localLive(){let e=0;for(let t of this.views)t.gl&&!t._glLost&&!t._destroyed&&(e+=1);return e},foreignLive(){let e=0;if(this.foreign)for(let t of this.foreign.values())e+=t;return e},_announceLive(e=!1){if(!this.channel)return;let t=this.localLive();!e&&t===this._announcedLive||(this._announcedLive=t,this._post({t:`live`,id:this.frameId,n:t}))},_rebalance(){if(this.localLive()+this.foreignLive()-this.budget()<=0)return;let e=null;for(let t of this.views)t.gl&&!t._glLost&&!t._destroyed&&!t._ctxVisible&&(!e||(t._ctxSeenSeq||0)<(e._ctxSeenSeq||0))&&(e=t);!e||!e._releaseContext()||this.localLive()+this.foreignLive()-this.budget()>0&&!this._rebalanceScheduled&&(this._rebalanceScheduled=!0,setTimeout(()=>{this._rebalanceScheduled=!1,this._rebalance()},0))},scheduleHiddenReleases(){if(this.hiddenReleaseChannel!==null)return;this.hiddenReleaseQueue=Array.from(this.views);let e=new MessageChannel;this.hiddenReleaseChannel=e,e.port1.onmessage=()=>{if(typeof document>`u`||document.visibilityState!==`hidden`){this.cancelHiddenReleases();return}let t=null;for(;this.hiddenReleaseQueue.length&&!t;){let e=this.hiddenReleaseQueue.shift();!e._destroyed&&e.gl&&!e._glLost&&!e.gl.isContextLost()&&(t=e)}if(!t){this.cancelHiddenReleases();return}t._releaseContext(),e.port2.postMessage(null)},e.port2.postMessage(null)},cancelHiddenReleases(){this.hiddenReleaseChannel?.port1.close(),this.hiddenReleaseChannel?.port2.close(),this.hiddenReleaseChannel=null,this.hiddenReleaseQueue=[]}};function lt(e){if(typeof window>`u`||!e.getBoundingClientRect)return!0;let t=e.getBoundingClientRect();if(!t.width&&!t.height)return!1;let n=window.innerHeight||0,r=window.innerWidth||0;return t.bottom>-.25*n&&t.top<1.25*n&&t.right>-.25*r&&t.left<1.25*r}var Q=class{constructor(e,t,n,r){if(t.protocol!==5)throw e.textContent=`xy: protocol mismatch (client speaks 5, kernel sent ${t.protocol}). Update the xy package and restart the kernel.`,Error(`protocol mismatch`);this.spec=t,this.interaction=t.interaction||{},this.markStyle=t.mark_style||{},this.axes=this._normalizeAxes(t),this.comm=r,this.seq=0,this._densityStamp=0,this._viewRequestBurstStart=null,this._viewAnim=null,this._animRaf=null,this._dataAnim=null,this._dataAnimRaf=null,this._transitionOldTraces=null,this._transitionView=null,this._wheelZoomRaf=null,this._pendingWheelZoom=null,this._lastLabelDraw=null,this._lutCache=new Map,this._listeners=[],this._glPrograms=[],this._progCache=new Map,this._bufSeq=0,this._destroyed=!1,this._resizeRaf=null,this._pendingResize=null,this._resizeNeedsMeasure=!1,this._hoverId=-1,this._hoverTarget=null,this._viewEventRaf=null,this._linkedSource=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,this.dragMode=`none`,this._interactionSeq=0,this.fluid=t.width===`100%`,this.fluidH=t.height===`100%`;let i=this.fluid||this.fluidH?e.getBoundingClientRect():null,a=this.fluid?Math.round(i.width)||640:t.width,o=this.fluidH?Math.round(i.height)||420:t.height;this.size={w:Math.max(this.fluid?120:48,a),h:Math.max(this.fluidH?120:48,o)},this._layout(),this._buildDom(e),this.theme=S(this.root),this._themeStale=!this.root.isConnected,this._payload=n,this._glLost=!1,this._ctxReleasedExt=null,this._ctxReleases=0,this._ctxRecoveries=0,this._ctxLostPending=!1,this._ctxRecoverRequested=!1,this._ctxVisible=lt(e),Z.register(this),this._ctxVisible&&(this._ctxSeenSeq=Z.seq++),this._contextLossCount=0,this._contextRestoreCount=0,this._contextRecoveryError=null;try{this._initGl(n)}catch(e){throw Z.unregister(this),String(e&&e.message||e)===`webgl2 unavailable`&&(this.root.textContent=`xy: WebGL2 unavailable in this browser.`),e}if(this.canvas.dataset.xyCtx=`live`,this.view0=this._clampView({ranges:Object.fromEntries(Object.entries(this.axes).map(([e,t])=>[e,[...t.range]]))}),this.view=this._copyView(this.view0),this.dragMode=this._resolveDefaultDragAction(),this._initA11y(),this.root.dataset.xyContextState=`ready`,this._initContextLossRecovery(),this._armContextVisibilityWatch(),this._initViewState(),this._initInteraction(),this._buildModebar(this.root),this._initAxisBands(),(this.fluid||this.fluidH)&&typeof ResizeObserver<`u`&&(this._ro=new ResizeObserver(e=>{let t=e[e.length-1].contentRect;(t.width||t.height)&&this._queueResize(t.width,t.height)}),this._ro.observe(this.root)),this._armVisibilityResizeWatch(),this._armDprWatch(),this._initLinkedCharts(),this._themeWatch=window.matchMedia(`(prefers-color-scheme: dark)`),this._onScheme=()=>this.refreshTheme(),this._themeWatch.addEventListener?.(`change`,this._onScheme),typeof MutationObserver<`u`){this._themeMutationObserver=new MutationObserver(()=>this.refreshTheme());for(let e=this.root;e;e=e.parentElement)this._themeMutationObserver.observe(e,{attributes:!0,attributeFilter:[`class`,`style`]})}this._unsubscribeComm=r?r.onMessage((e,t)=>this._onKernelMsg(e,t)):null,this._startEntranceAnimation?this._startEntranceAnimation():this.draw()}_layout(){let e=this.size.w<520,t=Array.isArray(this.spec.padding)?this.spec.padding:null,n=this.spec.colorbar,r=n&&n.orientation!==`horizontal`,i=n&&n.orientation===`horizontal`,a=this.fluid&&e&&t,o=t?a?Math.min(t[3],46):t[3]:e?46:Y.l;this._compactVerticalColorbar=!!(this.fluid&&e&&r);let s=r?this._compactVerticalColorbar?34:86+(n.label?18:0):0,c=i?38+(n.label?16:0):0,l=(t?a?Math.min(t[1],8):t[1]:e?8:Y.r)+s,u=t?t[0]:e?6:Y.t,d=(t?t[2]:e?36:Y.b)+c,f=Object.values(this.axes||{}).some(e=>e&&String(e.id||``).startsWith(`x`)&&e.side!==`top`&&this._axisTickLabelStrategy(e)!==`none`);this._bottomAxisRoom=f?e?36:Y.b:0;let p=Object.values(this.axes||{}).some(e=>e&&String(e.id||``).startsWith(`x`)&&e.side===`top`&&this._axisTickLabelStrategy(e)!==`none`)?e?26:32:0,m=u+(this.spec.title?e?26:30:0)+p,h=Object.values(this.axes||{}).filter(e=>e&&String(e.id||``).startsWith(`y`)&&e.side===`right`&&this._axisTickLabelStrategy(e)!==`none`);this._rightAxisRoom=h.length?e?42:54:0;let g=l+this._rightAxisRoom;this.plot={x:o,y:m,w:Math.max(40,this.size.w-o-g),h:Math.max(40,this.size.h-m-d)}}_normalizeAxes(e){let t={...e.axes||{}};e.x_axis&&(t.x=e.x_axis),e.y_axis&&(t.y=e.y_axis);for(let[e,n]of Object.entries(t))n&&typeof n==`object`&&!n.id&&(n.id=e);return t}_axis(e){let t=e||`x`;return this.axes[t]||(String(t).startsWith(`y`)?this.axes.y:this.axes.x)||{}}_axisDim(e){return String(e||`x`).startsWith(`y`)?`y`:`x`}_axisMode(e){return+(this._axis(e).scale===`log`)}_axisIds(){return Object.keys(this.axes||{})}_copyView(e){let t={};for(let n of this._axisIds()){let r=e?.ranges?.[n]||this._axis(n).range||[0,1];t[n]=[Number(r[0]),Number(r[1])]}let n=t.x||[0,1],r=t.y||[0,1];return{ranges:t,x0:n[0],x1:n[1],y0:r[0],y1:r[1]}}_viewFrom(e,t=this.view){let n={};for(let r of this._axisIds()){let i=e?.ranges?.[r]||(r===`x`&&e?.x0!==void 0?[e.x0,e.x1]:null)||(r===`y`&&e?.y0!==void 0?[e.y0,e.y1]:null)||t?.ranges?.[r]||this._axis(r).range||[0,1];n[r]=[Number(i[0]),Number(i[1])]}return this._copyView({ranges:n})}_axisPolicy(e){let t=this.interaction?.[e];if(!Array.isArray(t)||!t.length)return this._axisIds();let n=new Set(this._axisIds());return[...new Set(t.filter(e=>n.has(e)))]}_resetAxisPolicy(){if(Array.isArray(this.interaction?.reset_axes))return this._axisPolicy(`reset_axes`);let e=[];return this._interactionFlag(`pan`,!0)&&e.push(...this._axisPolicy(`pan_axes`)),this._interactionFlag(`zoom`,!0)&&e.push(...this._axisPolicy(`zoom_axes`)),[...new Set(e)]}_axisContained(e){return!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._axisPolicy(`zoom_axes`).includes(e)?!1:!this._interactionFlag(`pan`,!0)||!this._axisPolicy(`pan_axes`).includes(e)}_resolveDefaultDragAction(){let e=typeof this.interaction?.default_drag_action==`string`?this.interaction.default_drag_action:`auto`,t=this._interactionFlag(`navigation`,!0),n=t&&this._interactionFlag(`pan`,!0),r=t&&this._interactionFlag(`zoom`,!0)&&this._interactionFlag(`box_zoom`,!0),i=this._pickable&&this._interactionFlag(`select`,!0)&&this._interactionFlag(`brush`,!0);return e===`auto`?n?`pan`:r?`zoom`:i?`select`:`none`:e===`pan`?n?`pan`:this._resolveDefaultDragActionFallback():e===`zoom`?r?`zoom`:this._resolveDefaultDragActionFallback():e.startsWith(`select`)?i?e:this._resolveDefaultDragActionFallback():e===`none`?`none`:this._resolveDefaultDragActionFallback()}_resolveDefaultDragActionFallback(){let e=this.interaction.default_drag_action;this.interaction.default_drag_action=`auto`;let t=this._resolveDefaultDragAction();return this.interaction.default_drag_action=e,t}_axisCoord(e,t){let n=Number(t);return Number.isFinite(n)?e&&e.scale===`log`?n>0?Math.log10(n):NaN:n:NaN}_axisValue(e,t){return e&&e.scale===`log`?10**t:t}_axisRange(e,t=this.view){let n=t?.ranges?.[e];if(Array.isArray(n))return[n[0],n[1]];if(e===`x`&&t)return[t.x0,t.x1];if(e===`y`&&t)return[t.y0,t.y1];let r=this._axis(e).range||[0,1];return[Number(r[0]),Number(r[1])]}_axisTicks(e,t){let n=this._axis(e),[r,i]=this._axisRange(e);if(Array.isArray(n.tick_values)){let e=Math.min(r,i),t=Math.max(r,i),a=n.tick_values.map(Number).filter(n=>Number.isFinite(n)&&n>=e&&n<=t);return{ticks:a,labels:a,step:a.length>1?Math.abs(a[1]-a[0]):1}}return n.kind===`time`?ee(r,i,t):n.kind===`category`?A(r,i,n.categories||[],t):n.scale===`log`?k(r,i,t):O(r,i,t)}_axisTickText(e,t,n){if(Array.isArray(e.tick_values)&&Array.isArray(e.tick_labels)){let n=e.tick_values.findIndex(e=>Number(e)===Number(t));if(n>=0&&n0?Math.max(1,Math.min(200,r)):t}_dataPx(e,t){let n=this._axisDim(e),r=this._axis(e),[i,a]=this._axisRange(e),o=this._axisCoord(r,i),s=this._axisCoord(r,a),c=this._axisCoord(r,t);return![o,s,c].every(Number.isFinite)||s===o?NaN:n===`x`?this.plot.x+(c-o)/(s-o)*this.plot.w:this.plot.y+(1-(c-o)/(s-o))*this.plot.h}_listen(e,t,n,r){return e.addEventListener(t,n,r),this._listeners.push({target:e,type:t,handler:n,options:r}),n}_interactionFlag(e,t=!1){let n=this.interaction&&this.interaction[e];return n===void 0?t:n===!0}_eventView(e=`view`){return{ranges:Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),x0:this.view.x0,x1:this.view.x1,y0:this.view.y0,y1:this.view.y1,source:e}}_dispatchChartEvent(e,t){!this.root||typeof CustomEvent!=`function`||this.root.dispatchEvent(new CustomEvent(`xy:${e}`,{detail:t,bubbles:!0,composed:!0}))}_emitViewChange(e=`view`,t={}){if(this._destroyed)return;let n=t.broadcast!==!1;this._pendingViewEvent={source:e,broadcast:n,axes:Array.isArray(t.axes)?[...t.axes]:[],phase:t.phase||`end`,interaction_id:t.interactionId??++this._interactionSeq},!this._viewEventRaf&&(this._viewEventRaf=requestAnimationFrame(()=>{this._viewEventRaf=null;let t=this._pendingViewEvent||{source:e,broadcast:n};this._pendingViewEvent=null;let r={...this._eventView(t.source),axes:t.axes,phase:t.phase,interaction_id:t.interaction_id};this._dispatchChartEvent(`view_change`,r),this.comm&&(t.phase===`end`||!this.comm.wantsViewChange||this.comm.wantsViewChange())&&this.comm.send({type:`view_change`,...r}),t.broadcast&&this._broadcastLinkedView(r)}))}_initLinkedCharts(){let e=this.interaction&&this.interaction.link_group;!e||typeof BroadcastChannel!=`function`||(this._linkAxes=this._axisPolicy(`link_axes`),this._linkChannel=new BroadcastChannel(`xy:${e}`),this._linkChannel.onmessage=e=>{let t=e.data||{};if(t.source===this._linkedSource)return;if(this._interactionFlag(`link_select`)&&t.selection){let e=t.selection;if(e.clear)this._clearSelection({broadcast:!1,dispatch:!1});else if(e.polygon)this._stateSelection={polygon:e.polygon.map(e=>[...e])},this._selectLocalPolygon(e.polygon,{dispatch:!1});else if(e.range){let{x0:t,x1:n,y0:r,y1:i}=e.range;[t,n,r,i].every(Number.isFinite)&&(this._stateSelection={range:{x0:t,x1:n,y0:r,y1:i}},this._selectLocal(t,n,r,i,{dispatch:!1}))}return}if(!t.view||t.source===this._linkedSource)return;let n=t.view.ranges||{},r=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]]));for(let e of this._linkAxes){let i=n[e]||(e===`x`?[t.view.x0,t.view.x1]:null)||(e===`y`?[t.view.y0,t.view.y1]:null);Array.isArray(i)&&i.length===2&&i.every(Number.isFinite)&&(r[e]=[Number(i[0]),Number(i[1])])}this._setView({ranges:r},{animate:!1,source:`linked`,phase:`end`,broadcast:!1})})}_broadcastLinkedView(e){if(!this._linkChannel)return;let t=(e.axes||[]).filter(e=>this._linkAxes.includes(e));if(!t.length)return;let n=Object.fromEntries(t.map(t=>[t,e.ranges[t]]));this._linkChannel.postMessage({source:this._linkedSource,view:{...e,axes:t,ranges:n}})}_broadcastLinkedSelection(e){!this._linkChannel||!this._interactionFlag(`link_select`)||this._linkChannel.postMessage({source:this._linkedSource,selection:e})}setView(e,t={}){return this._setView({ranges:e},{animate:t.animate===!0,source:`programmatic`,phase:`end`,interactionId:++this._interactionSeq,broadcast:t.broadcast===!0})}resetView(e={}){return this._resetView(e.animate!==!1,`reset`)}_applyClass(e,t){if(typeof t==`string`)for(let n of t.split(/\s+/).filter(Boolean))try{e.classList.add(n)}catch{}}_stylePropertyName(e){return e.startsWith(`--`)?e:e.replace(/_/g,`-`).replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}_stylePropertyValue(e,t){return typeof t==`number`?Number.isFinite(t)?e.startsWith(`--`)||ct.has(e)?String(t):`${t}px`:null:String(t)}_applyStyle(e,t){if(!(!t||typeof t!=`object`||Array.isArray(t)))for(let[n,r]of Object.entries(t)){if(typeof n!=`string`||typeof r!=`string`&&typeof r!=`number`)continue;let t=this._stylePropertyName(n),i=this._stylePropertyValue(t,r);i!=null&&e.style.setProperty(t,i)}}_applySlot(e,t){e&&e.dataset&&(e.dataset.xySlot=t);let n=this.spec.dom;!n||typeof n!=`object`||(t===`root`&&this._applyClass(e,n.class_name),n.class_names&&typeof n.class_names==`object`&&this._applyClass(e,n.class_names[t]),t===`root`&&this._applyStyle(e,n.style),n.styles&&typeof n.styles==`object`&&this._applyStyle(e,n.styles[t]))}_slotStyleValue(e,t){let n=this.spec.dom?.styles,r=n&&typeof n==`object`?n[e]:null;if(!r||typeof r!=`object`||Array.isArray(r))return null;let i=this._stylePropertyName(t);for(let e of Object.keys(r))if(this._stylePropertyName(e)===i)return r[e];return null}_syncContainerSize(){this._destroyed||!(this.fluid||this.fluidH)||!this.root||this._queueResize(null,null,!0)}_queueResize(e=null,t=null,n=!1){this._destroyed||((e||t)&&(this._pendingResize={cssW:e,cssH:t}),n&&(this._resizeNeedsMeasure=!0),!this._resizeRaf&&(this._resizeRaf=requestAnimationFrame(()=>{this._resizeRaf=null;let e=this._pendingResize;if(this._pendingResize=null,this._resizeNeedsMeasure&&this.root){let t=this.root.getBoundingClientRect();(t.width||t.height)&&(e={cssW:t.width,cssH:t.height})}this._resizeNeedsMeasure=!1,e&&(e.cssW||e.cssH)&&this._resize(e.cssW,e.cssH)})))}_armVisibilityResizeWatch(){if(!(this.fluid||this.fluidH))return;let e=()=>{this._destroyed||this._syncContainerSize()};this._listen(window,`resize`,e),this._listen(window,`pageshow`,e),this._listen(document,`visibilitychange`,e),typeof IntersectionObserver<`u`&&(this._io=new IntersectionObserver(t=>{t.some(e=>e.isIntersecting||e.intersectionRatio>0)&&e()}),this._io.observe(this.root))}_markStateValue(e,t,n=null){let r=this.markStyle&&typeof this.markStyle==`object`?this.markStyle[e]:null;return!r||typeof r!=`object`||Array.isArray(r)?n:Object.prototype.hasOwnProperty.call(r,t)?r[t]:n}_markStateNumber(e,t,n){let r=this._markStateValue(e,t,n);return typeof r!=`number`||!Number.isFinite(r)?n:r}_markStatePaint(e,t,n){let r=this._markStateValue(e,t,n);return typeof r==`string`?r:n}_armDprWatch(){if(typeof window.matchMedia!=`function`)return;this._dprMq?.removeEventListener?.(`change`,this._onDprChange);let e=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);this._onDprChange=()=>{this._destroyed||(this._resize(this.size.w,this.size.h),this._armDprWatch())},e.addEventListener?.(`change`,this._onDprChange,{once:!0}),this._dprMq=e}_initContextLossRecovery(){this._listen(this.canvas,`webglcontextlost`,e=>{if(e.preventDefault(),this._destroyed)return;let t=this.canvas.dataset.xyCtx===`released`;if(this._glLost&&!t)return;this._glLost=!0,this._ctxLostPending=!1,t||(this.canvas.dataset.xyCtx=`lost`),Z._announceLive(),this._contextLossCount+=1,this._contextRecoveryError=null,this.root.dataset.xyContextState=`lost`,this.seq+=1,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._wheelZoomRaf&&cancelAnimationFrame(this._wheelZoomRaf),this._wheelZoomRaf=null,this._pendingWheelZoom=null,clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null,this._wheelGesture=null,this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf),this._dataAnimRaf=null,this._dataAnim&&this._emitAnimationLifecycle?.(`end`,this._dataAnim.phase,{cancelled:!0}),this._dataAnim=null,this._transitionOldTraces=null,this._transitionView=null,this.view0&&(this.view={...this.view0}),this._cancelViewAnimation(),clearTimeout(this._viewTimer),this._viewTimer=null,clearTimeout(this._rebinTimer),this._rebinTimer=null,this._viewRequestBurstStart=null,this._dispatchChartEvent(`context_lost`,{loss_count:this._contextLossCount});let n=typeof document>`u`||!document.visibilityState||document.visibilityState===`visible`;!t&&this._ctxVisible&&n&&setTimeout(()=>{!this._destroyed&&this._glLost&&this.canvas.dataset.xyCtx===`lost`&&this._ctxVisible&&this._recoverContext()},0),t&&this._ctxRecoverRequested&&!this._destroyed&&this._ctxVisible&&(this._ctxRecoverRequested=!1,setTimeout(()=>{!this._destroyed&&this._glLost&&this._ctxVisible&&this._recoverContext()},0))}),this._listen(this.canvas,`webglcontextrestored`,()=>{if(!(this._destroyed||this._contextRecoveryError)){this._lutCache.clear(),this.pickFbo=null,this.pickTex=null;try{this._initGl(this._payload),this._glLost=!1,this._drawNow(),this._assertContextFrameReady(`restore`)}catch(e){if(this._glLost=!0,this.canvas.dataset.xyCtx=`lost`,this.root.dataset.xyContextState=`lost`,!this.gl||this.gl.isContextLost()||String(e&&e.message||e).includes(`shader compile: null`)||String(e&&e.message||e).startsWith(`WebGL error `)){this._contextRecoveryError=null,this._scheduleContextRecovery();return}this._contextRecoveryError=e,this.root.dataset.xyContextState=`failed`;try{this._destroyGlResources()}catch{}this.gl=null,this._dispatchChartEvent(`context_restore_failed`,{loss_count:this._contextLossCount,message:e instanceof Error?e.message:String(e)}),this.root.textContent=`xy: WebGL2 context could not be restored.`;return}this._contextRestoreCount+=1,this._contextRecoveryError=null,this._ctxRecoveryDelay=0,this.canvas.dataset.xyCtx=`live`,this.root.dataset.xyContextState=`ready`,Z._announceLive(),this._scheduleViewRequest(this.view,{delay:0}),this._dropContextSnapshot(),this._dispatchChartEvent(`context_restored`,{loss_count:this._contextLossCount,restore_count:this._contextRestoreCount})}})}_releaseContext(){if(this._destroyed||!this.gl||this._glLost||this.gl.isContextLost())return!1;let e=this.gl.getExtension(`WEBGL_lose_context`);return e?(this._snapshotBeforeRelease(),this._ctxReleasedExt=e,this._ctxReleases+=1,this._glLost=!0,this._ctxLostPending=!0,this.canvas.dataset.xyCtx=`released`,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,e.loseContext(),Z._announceLive(),!0):!1}_snapshotBeforeRelease(){try{this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._rafKeepPick=!0,this._drawNow();let e=this._ctxSnapshot;e||(e=this._ctxSnapshot=document.createElement(`canvas`),e.dataset.xyCtxSnapshot=``),e.width=this.canvas.width,e.height=this.canvas.height,e.style.cssText=this.canvas.style.cssText,e.style.pointerEvents=`none`;let t=this.gl,n=this.canvas.width,r=this.canvas.height;t.finish();let i=new Uint8Array(n*r*4);t.readPixels(0,0,n,r,t.RGBA,t.UNSIGNED_BYTE,i);let a=e.getContext(`2d`),o=a.createImageData(n,r),s=o.data;for(let e=0;e0&&e<255){let t=255/e;n=Math.min(255,Math.round(n*t)),r=Math.min(255,Math.round(r*t)),a=Math.min(255,Math.round(a*t))}s[o]=n,s[o+1]=r,s[o+2]=a,s[o+3]=e}}a.putImageData(o,0,0),this.canvas.before(e),this.canvas.style.visibility=`hidden`}catch{this._dropContextSnapshot()}}_dropContextSnapshot(){this.canvas.style.visibility=``,this._ctxSnapshot&&this._ctxSnapshot.remove(),this._ctxSnapshot=null}_recoverContext(){if(!(this._destroyed||!this._glLost)){if(this._ctxReleasedExt&&this._ctxLostPending){this._ctxRecoverRequested=!0;return}if(this._ctxRecoveries+=1,this._ctxReleasedExt){let e=this._ctxReleasedExt;this._ctxReleasedExt=null;try{Z.reserve(this),e.restoreContext();return}catch{Z.cancel(this)}}this._rebuildEvictedContext()}}_assertContextFrameReady(e){if(!this.gl||(this.gl.finish(),this.gl.isContextLost()))throw Error(`context lost during ${e} draw`);let t=this.gl.getError();if(t!==this.gl.NO_ERROR)throw Error(`WebGL error ${t} during ${e} draw`)}_scheduleContextRecovery(){if(this._ctxRecoveryTimer||this._destroyed||!this._ctxVisible||typeof document<`u`&&document.visibilityState&&document.visibilityState!==`visible`)return;let e=this._ctxRecoveryDelay||50;this._ctxRecoveryDelay=Math.min(1e3,e*2),this._ctxRecoveryTimer=setTimeout(()=>{this._ctxRecoveryTimer=null,this._glLost&&!this._destroyed&&this._ctxVisible&&this._recoverContext()},e)}_rebuildEvictedContext(){if(this.gl&&!this.gl.isContextLost())try{this.gl.getExtension(`WEBGL_lose_context`)?.loseContext()}catch{}let e=this.canvas.cloneNode(!1);for(let t of this._listeners)t.target===this.canvas&&(this.canvas.removeEventListener(t.type,t.handler,t.options),e.addEventListener(t.type,t.handler,t.options),t.target=e);this.canvas.replaceWith(e),this.canvas=e,this._glLost=!1,this._lutCache.clear(),this.pickFbo=null,this.pickTex=null;try{this._initGl(this._payload),this._glLost=!1,this._drawNow(),this._assertContextFrameReady(`rebuild`)}catch{this._glLost=!0,this.canvas.dataset.xyCtx=`lost`,this._scheduleContextRecovery();return}this._ctxRecoveryDelay=0,this.canvas.dataset.xyCtx=`live`,Z._announceLive(),this._scheduleViewRequest(this.view,{delay:0}),this._dropContextSnapshot()}_armContextVisibilityWatch(){if(this._listen(this.root,`pointerenter`,()=>{this._glLost&&!this._destroyed&&this._recoverContext()}),typeof document<`u`&&this._listen(document,`visibilitychange`,()=>{if(document.visibilityState===`hidden`){Z.scheduleHiddenReleases();return}Z.cancelHiddenReleases(),document.visibilityState===`visible`&&this._ctxVisible&&this._glLost&&!this._destroyed&&this._recoverContext()}),typeof IntersectionObserver>`u`){this._ctxVisible=!0;return}this._ctxIo=new IntersectionObserver(e=>{let t=e[e.length-1];this._ctxVisible=t.isIntersecting||t.intersectionRatio>0,this._ctxVisible?(this._ctxSeenSeq=Z.seq++,this._glLost&&!this._destroyed&&this._recoverContext(),this._healStaleTheme()&&this.draw()):this._destroyed||Z._rebalance()},{rootMargin:`25% 0px 25% 0px`}),this._ctxIo.observe(this.root)}_resize(e,t){let n=this.fluid&&e?Math.max(120,Math.round(e)):this.size.w,r=this.fluidH&&t?Math.max(120,Math.round(t)):this.size.h,i=window.devicePixelRatio||1;if(n===this.size.w&&r===this.size.h&&i===this.dpr)return;this.dpr=i,this.size.w=n,this.size.h=r,this._layout();let a=this.plot;this.root.style.setProperty(`--xy-legend-max-width`,Math.max(40,a.w-12)+`px`),this.root.style.setProperty(`--xy-legend-max-height`,Math.max(40,a.h-12)+`px`),this.canvas.style.left=a.x+`px`,this.canvas.style.top=a.y+`px`,this.canvas.style.width=a.w+`px`,this.canvas.style.height=a.h+`px`,this.canvas.width=a.w*this.dpr,this.canvas.height=a.h*this.dpr,this.chrome.style.width=this.size.w+`px`,this.chrome.style.height=this.size.h+`px`,this.chrome.width=this.size.w*this.dpr,this.chrome.height=this.size.h*this.dpr,this.overlay.style.width=this.size.w+`px`,this.overlay.style.height=this.size.h+`px`,this.overlay.width=this.size.w*this.dpr,this.overlay.height=this.size.h*this.dpr;for(let e of this._legends||[])this._positionLegend(e,e.dataset.xyLegendLoc||`upper right`);this._positionReductionBadges(),this._positionColorbar(),this._fitModebar(),this._layoutAxisBands(),this._pickDirty=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._drawNow(),this._scheduleViewRequest()}_buildDom(e){let t=this.spec,n=document.createElement(`div`);n.className=`xy`,n.style.cssText=`position:relative;width:${this.fluid?`100%`:this.size.w+`px`};height:${this.fluidH?`100%`:this.size.h+`px`};--xy-legend-max-width:${Math.max(40,this.plot.w-12)}px;--xy-legend-max-height:${Math.max(40,this.plot.h-12)}px;`+(this.fluidH?`min-height:120px;`:``)+`font:12px system-ui,sans-serif;user-select:none;`,this._applySlot(n,`root`),(n.style.background||n.style.backgroundColor)&&(n.dataset.xyOwnBg=``),e.appendChild(n),this.root=n,T(n);let r;do r=`xy-a11y-${++ot}`;while(document.getElementById(`${r}-summary`)||document.getElementById(`${r}-live`));if(n.setAttribute(`role`,`region`),n.setAttribute(`aria-label`,t.title?`Chart: ${t.title}`:`Interactive chart`),this.a11ySummary=document.createElement(`div`),this.a11ySummary.id=`${r}-summary`,this.a11ySummary.style.cssText=st,n.setAttribute(`aria-describedby`,this.a11ySummary.id),n.appendChild(this.a11ySummary),this.a11yLive=document.createElement(`div`),this.a11yLive.id=`${r}-live`,this.a11yLive.setAttribute(`role`,`status`),this.a11yLive.setAttribute(`aria-live`,`polite`),this.a11yLive.setAttribute(`aria-atomic`,`true`),this.a11yLive.style.cssText=st,n.appendChild(this.a11yLive),t.title){let e=document.createElement(`div`);e.textContent=t.title,e.style.cssText=`position:absolute;top:6px;left:0;right:0;`,this._applySlot(e,`title`),n.appendChild(e)}this.chrome=document.createElement(`canvas`),this.chrome.style.cssText=`position:absolute;inset:0;pointer-events:none;`,this._applySlot(this.chrome,`chrome`),n.appendChild(this.chrome),this.canvas=document.createElement(`canvas`),this.canvas.style.cssText=`position:absolute;left:${this.plot.x}px;top:${this.plot.y}px;width:${this.plot.w}px;height:${this.plot.h}px;touch-action:none;`,this._applySlot(this.canvas,`canvas`),this.canvas.tabIndex=0,this.canvas.setAttribute(`role`,`img`),this.canvas.setAttribute(`aria-describedby`,this.a11ySummary.id),n.appendChild(this.canvas),this.overlay=document.createElement(`canvas`),this.overlay.style.cssText=`position:absolute;inset:0;pointer-events:none;`,n.appendChild(this.overlay),this.labels=document.createElement(`div`),this.labels.style.cssText=`position:absolute;inset:0;pointer-events:none;`,this._applySlot(this.labels,`labels`),n.appendChild(this.labels),this.tooltip=document.createElement(`div`),this.tooltip.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:5;`,this._applySlot(this.tooltip,`tooltip`),this.tooltip.setAttribute(`aria-hidden`,`true`),n.appendChild(this.tooltip),this._buildLegend(n),this._buildColorbar(n),this._buildReductionBadges(n)}_a11yAxisSummary(e,t){let n=this._axis(e),r=n.label?`${t} axis (${n.label})`:`${t} axis`;if(n.kind===`category`){let e=Array.isArray(n.categories)?n.categories:[];if(!e.length)return`${r} uses categories.`;let t=e.slice(0,6).map(e=>String(e)),i=e.length-t.length,a=i>0?`, and ${i} more`:``;return`${r} has ${e.length} categories: ${t.join(`, `)}${a}.`}let i=n.range||[];return i.length<2?null:`${r} ranges from ${P(i[0],n.kind)} to ${P(i[1],n.kind)}.`}_a11ySummaryText(){let e=Array.isArray(this.spec.traces)?this.spec.traces:[],t=[this.spec.title?`${this.spec.title}.`:`Interactive chart.`];t.push(`${e.length} data series.`);let n=e.map(e=>e&&e.name).filter(Boolean).slice(0,6);n.length&&t.push(`Series: ${n.join(`, `)}.`);let r=this._a11yAxisSummary(`x`,`X`),i=this._a11yAxisSummary(`y`,`Y`);return r&&t.push(r),i&&t.push(i),t.join(` `)}_initA11y(){if(!this.a11ySummary||!this.canvas)return;this.a11ySummary.textContent=this._a11ySummaryText();let e=this._pickable?` Use Arrow keys to explore data points in series data order; Home and End jump to the first and last point; Escape closes the readout.`:``;this.canvas.setAttribute(`aria-label`,`Plot area.${e}`)}_compactInt(e){let t=Number(e);return Number.isFinite(t)?Math.round(t).toLocaleString():`0`}_positionReductionBadges(){if(!this._badges)return;let e=this.size.w-(this.plot.x+this.plot.w),t=this.size.h-(this.plot.y+this.plot.h);this._badges.style.right=`${e+6}px`,this._badges.style.bottom=`${t+6}px`}_reductionBadgeItems(){let e=[],t=this.gpuTraces&&this.gpuTraces.length?this.gpuTraces:this.spec.traces||[];for(let n of t){let t=n.trace||n;if(t.tier!==`density`||!t.density)continue;let r=n.sampleOverlay&&n.sampleOverlay.sample?n.sampleOverlay.sample:t.density.sample;r&&Number(r.n)>0&&e.push(`sampled ${this._compactInt(r.n)} of ${this._compactInt(r.visible)}`),n._sampleRebinned&&e.push(`zoom re-binned from sample`),t.density.channels_dropped&&e.push(`aggregated channels`)}return e}_refreshReductionBadges(){if(!this._badges)return;let e=this._reductionBadgeItems();this._badges.textContent=``,this._badges.hidden=e.length===0;for(let t of e){let e=document.createElement(`div`);e.textContent=t,this._applySlot(e,`badge_item`),this._badges.appendChild(e)}this._positionReductionBadges()}_buildReductionBadges(e){let t=this._reductionBadgeItems(),n=(this.spec.traces||[]).some(e=>e.tier===`density`);if(!t.length&&!n)return;let r=document.createElement(`div`);r.style.cssText=`position:absolute;display:flex;flex-direction:column;align-items:flex-end;pointer-events:none;z-index:4;`,this._applySlot(r,`badge`),e.appendChild(r),this._badges=r,this._refreshReductionBadges()}_buildLegend(e){let t=this.spec;this._legends=[];let n=[];if(t.show_legend!==!1){for(let e of t.traces)if(e.tier===`density`)n.push({swatch:`gradient`,cmap:e.density.colormap,name:e.name||`density`});else if(e.color&&e.color.mode===`categorical`)e.color.categories.forEach((t,r)=>n.push({swatch:e.color.palette[r],name:t,symbol:e.kind===`scatter`?e.style?.symbol||`circle`:null,style:e.style||{}}));else if(e.color&&e.color.mode===`continuous`)n.push({swatch:`gradient`,cmap:e.color.colormap,name:e.name||`value`});else if(e.name){let t=e.color&&e.color.color||e.style&&e.style.color,r=[`line`,`segments`,`step`,`stairs`,`errorbar`].includes(e.kind);n.push({swatch:t,name:e.name,symbol:e.kind===`scatter`?e.style?.symbol||`circle`:null,line:r,style:e.style||{}})}n.length&&this._legendBox(e,n,t.legend||{})}for(let n of t.extra_legends||[]){let t=(n.items||[]).map(e=>({swatch:e.style&&e.style.color,name:e.name,symbol:e.kind===`scatter`?e.style?.symbol||`circle`:null,line:[`line`,`segments`,`step`,`stairs`,`errorbar`].includes(e.kind),style:e.style||{}}));t.length&&this._legendBox(e,t,n)}}_legendBox(e,t,n){let r=document.createElement(`div`),i=n.loc||`upper right`,a=Math.max(1,Number(n.ncols)||1),o=a>1;if(r.style.cssText=`position:absolute;display:grid;grid-template-columns:repeat(${o?a:1},max-content);overflow:auto;`,r.dataset.xyLegendLoc=i,this._positionLegend(r,i),this._applySlot(r,`legend`),n.title){let e=document.createElement(`div`);e.textContent=String(n.title),e.style.fontWeight=`600`,e.style.gridColumn=`1 / span ${o?a:1}`,r.appendChild(e)}for(let e of t){let t=document.createElement(`div`);this._applySlot(t,`legend_item`);let n=document.createElement(`span`);n.style.display=`inline-block`,n.style.verticalAlign=`-1px`;let i=e.swatch;if(e.swatch===`gradient`)i=`linear-gradient(90deg,${g(e.cmap).map(e=>`rgb(${e[0]},${e[1]},${e[2]})`).join(`,`)})`,n.style.background=i;else if(e.symbol){let t=`http://www.w3.org/2000/svg`,r=document.createElementNS(t,`svg`);r.setAttribute(`viewBox`,`0 0 18 14`),r.setAttribute(`width`,`18`),r.setAttribute(`height`,`14`);let a=document.createElementNS(t,`path`),o={square:`M4.5 2.5h9v9h-9z`,diamond:`M9 2l5 5-5 5-5-5z`,thin_diamond:`M9 2l3 5-3 5-3-5z`,triangle:`M9 2l-5 10h10z`,triangle_down:`M9 12L4 2h10z`,triangle_left:`M4 7L14 2v10z`,triangle_right:`M14 7L4 2v10z`,plus_line:`M9 2v10M4 7h10`,x_line:`M5 3l8 8M13 3l-8 8`,cross:`M7.5 2h3v3.5H14v3h-3.5V12h-3V8.5H4v-3h3.5z`,x:`M5.5 2L9 5.5 12.5 2 14 3.5 10.5 7 14 10.5 12.5 12 9 8.5 5.5 12 4 10.5 7.5 7 4 3.5z`,pentagon:`M9 2.5L13.28 5.61 11.65 10.64H6.35L4.72 5.61z`,hexagon:`M9 2L13.3 4.5v5L9 12l-4.3-2.5v-5z`,star:`M9 2l1.5 3.1 3.5.5-2.5 2.5.6 3.5L9 10l-3.1 1.6.6-3.5L4 5.6l3.5-.5z`},s=E(this.root,i);e.symbol===`circle`||e.symbol===`point`||e.symbol===`pixel`?e.symbol===`pixel`?a.setAttribute(`d`,`M8.5 6.5h1v1h-1z`):a.setAttribute(`d`,`M9 ${e.symbol===`point`?4.75:2.5}a${e.symbol===`point`?2.25:4.5} ${e.symbol===`point`?2.25:4.5} 0 1 0 0 ${e.symbol===`point`?4.5:9}a${e.symbol===`point`?2.25:4.5} ${e.symbol===`point`?2.25:4.5} 0 1 0 0 -${e.symbol===`point`?4.5:9}`):a.setAttribute(`d`,o[e.symbol]||o.square),a.setAttribute(`fill`,e.symbol.endsWith(`_line`)?`none`:s),a.setAttribute(`stroke`,s),a.setAttribute(`stroke-width`,String(e.style?.stroke_width||1)),r.appendChild(a),n.appendChild(r),n.style.width=`18px`,n.style.height=`14px`}else if(e.line){let t=`http://www.w3.org/2000/svg`,r=document.createElementNS(t,`svg`);r.setAttribute(`viewBox`,`0 0 22 12`),r.setAttribute(`width`,`22`),r.setAttribute(`height`,`12`);let a=document.createElementNS(t,`line`);a.setAttribute(`x1`,`1`),a.setAttribute(`y1`,`6`),a.setAttribute(`x2`,`21`),a.setAttribute(`y2`,`6`),a.setAttribute(`stroke`,E(this.root,i)),a.setAttribute(`stroke-width`,String(e.style?.width??1.5)),e.style?.dash&&e.style.dash.length&&a.setAttribute(`stroke-dasharray`,e.style.dash.join(` `)),r.appendChild(a),n.appendChild(r),n.style.width=`22px`,n.style.height=`12px`}else n.style.background=E(this.root,i);this._applySlot(n,`legend_swatch`),t.appendChild(n),t.appendChild(document.createTextNode(e.name)),r.appendChild(t)}return e.appendChild(r),this._legends.push(r),r}_positionLegend(e,t){if(!e)return;let n=this.size.w-(this.plot.x+this.plot.w),r=t.includes(`left`)?`left`:t.includes(`right`)?`right`:`center`,i=t.includes(`upper`)?`upper`:t.includes(`lower`)?`lower`:`center`,a=r===`left`?this.plot.x+6:r===`center`?this.plot.x+this.plot.w/2:null,o=r===`right`?n+6:null,s=i===`upper`?this.plot.y+6:i===`center`?this.plot.y+this.plot.h/2:null,c=i===`lower`?this.size.h-(this.plot.y+this.plot.h)+6:null;e.style.setProperty(`--xy-legend-left`,a==null?`auto`:a+`px`),e.style.setProperty(`--xy-legend-right`,o==null?`auto`:o+`px`),e.style.setProperty(`--xy-legend-top`,s==null?`auto`:s+`px`),e.style.setProperty(`--xy-legend-bottom`,c==null?`auto`:c+`px`);let l=r===`center`?`-50%`:`0`,u=i===`center`?`-50%`:`0`;e.style.setProperty(`--xy-legend-transform`,`translate(${l},${u})`)}_buildColorbar(e){let t=this.spec.colorbar;if(!t)return;let n=document.createElement(`div`),r=t.orientation===`horizontal`;n.style.cssText=`position:absolute;pointer-events:none;z-index:4;`,this._applySlot(n,`colorbar`);let i=document.createElement(`div`),a=Math.max(0,Number(t.levels)||0),o;if(a>0){let e=_(t.colormap||`viridis`),n=[];for(let t=0;t`rgb(${e[0]},${e[1]},${e[2]})`).join(`,`)})`}i.style.cssText=r?`position:absolute;inset:0 0 auto 0;height:${X}px;`:`position:absolute;inset:0 auto 0 0;width:${X}px;`,i.style.setProperty(`--xy-colorbar-gradient`,o),this._applySlot(i,`colorbar_bar`),n.appendChild(i);let s=t.domain||[0,1],c=Number(s[0]),l=Number(s[1]),u=l-c||1,d=O(c,l,8),f=Array.isArray(t.ticks),p=f?t.ticks:d.ticks,m=d.step;for(let e of p){let t=Number(e);if(!Number.isFinite(t)||tMath.max(c,l))continue;let i=document.createElement(`span`);i.textContent=f?re(t):N(t,m);let a=(t-c)/u;i.style.cssText=r?`position:absolute;left:${100*a}%;top:20px;transform:translateX(-50%);white-space:nowrap;`:`position:absolute;left:23px;top:${100*(1-a)}%;transform:translateY(-50%);white-space:nowrap;`,this._applySlot(i,`colorbar_tick`),n.appendChild(i)}if(t.label){let e=document.createElement(`span`);e.textContent=String(t.label),e.style.cssText=r?`position:absolute;left:50%;top:36px;transform:translateX(-50%);white-space:nowrap;`:`position:absolute;left:58px;top:50%;writing-mode:vertical-rl;transform:translateY(-50%) rotate(180deg);white-space:nowrap;`,this._applySlot(e,`colorbar_title`),n.appendChild(e)}n.title=`${t.label?t.label+`: `:``}${s[0]} – ${s[1]}`,e.appendChild(n),this._colorbar=n,this._colorbarHorizontal=r,this._positionColorbar()}_positionColorbar(){if(!this._colorbar)return;let e=this._colorbarHorizontal,t=!e&&this._compactVerticalColorbar,n=t?at:it;this._colorbar.style.left=(e?this.plot.x:this.plot.x+this.plot.w+this._rightAxisRoom+n)+`px`,this._colorbar.style.top=(e?this.plot.y+this.plot.h+(this._bottomAxisRoom||8):this.plot.y)+`px`,this._colorbar.style.width=(e?this.plot.w:t?X:66)+`px`,this._colorbar.style.height=(e?50:Math.max(24,this.plot.h))+`px`,this._colorbar.dataset.xyCompact=t?`true`:`false`;for(let e of this._colorbar.querySelectorAll(`[data-xy-slot="colorbar_tick"], [data-xy-slot="colorbar_title"]`))e.hidden=t}_initGl(e){let t=window.devicePixelRatio||1;this.dpr=t,this.canvas.width=this.plot.w*t,this.canvas.height=this.plot.h*t,this.chrome.width=this.size.w*t,this.chrome.height=this.size.h*t,this.chrome.style.width=this.size.w+`px`,this.chrome.style.height=this.size.h+`px`,this.overlay.width=this.size.w*t,this.overlay.height=this.size.h*t,this.overlay.style.width=this.size.w+`px`,this.overlay.style.height=this.size.h+`px`,Z.reserve(this);let n=this.canvas.getContext(`webgl2`,{antialias:!1,premultipliedAlpha:!0,alpha:!0});if(!n)throw Z.cancel(this),Error(`webgl2 unavailable`);this.gl=n,Z.acquired(this),n.enable(n.BLEND),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA),this._progCache=new Map,this._glPrograms=this._progCache,this.quad=n.createBuffer(),this.quad._fcId=++this._bufSeq,n.bindBuffer(n.ARRAY_BUFFER,this.quad),n.bufferData(n.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,1,1]),n.STATIC_DRAW),this.quadVao=n.createVertexArray(),n.bindVertexArray(this.quadVao),n.enableVertexAttribArray(F.a_corner),n.vertexAttribPointer(F.a_corner,2,n.FLOAT,!1,0,0),n.vertexAttribDivisor(F.a_corner,0),n.bindVertexArray(null),this.gpuTraces=this.spec.traces.map(t=>this._buildTrace(e,t)),this._updatePickable()}_updatePickable(){this._pickable=this.gpuTraces.some(e=>J(e.trace.kind).pointPick&&(e.tier!==`density`||e.drill)),this._pickable&&!this.pickFbo&&this._initPickTarget(),this._syncModebarSelect?.()}_prog(e,t,n){let r=this._progCache.get(e);return r||(r=le(this.gl,t,n),this._progCache.set(e,r)),r}get pointProg(){return this._prog(`point`,ue,de)}get pointSimpleProg(){return this._prog(`point-simple`,fe,pe)}get lineProg(){return this._prog(`line`,ye,be)}get segmentProg(){return this._prog(`segment`,xe,Se)}get meshProg(){return this._prog(`mesh`,Ce,we)}get areaProg(){return this._prog(`area`,Ee,De)}get rectProg(){return this._prog(`rect`,Oe,Ae)}get barProg(){return this._prog(`bar`,ke,Ae)}get pickProg(){return this._prog(`pick`,me,he)}get densityProg(){return this._prog(`density`,ge,_e)}get heatmapProg(){return this._prog(`heatmap`,ge,ve)}_lut(e){if(this._lutCache.has(e))return this._lutCache.get(e);let t=this.gl,n=t.createTexture();return t.bindTexture(t.TEXTURE_2D,n),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,256,1,0,t.RGBA,t.UNSIGNED_BYTE,_(e)),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),this._lutCache.set(e,n),n}_paletteLut(e){let t=`pal:`+e.join(`,`);if(this._lutCache.has(t))return this._lutCache.get(t);let n=this.gl,r=new Uint8Array(256*4);for(let t=0;t<256;t++){let n=b(e[t%e.length]);r[t*4]=n[0]*255,r[t*4+1]=n[1]*255,r[t*4+2]=n[2]*255,r[t*4+3]=255}let i=n.createTexture();return n.bindTexture(n.TEXTURE_2D,i),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,256,1,0,n.RGBA,n.UNSIGNED_BYTE,r),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.NEAREST),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.NEAREST),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),this._lutCache.set(t,i),i}_buildTrace(e,t){this.gl;let n={trace:t,tier:t.tier,color:[.3,.47,.66,1],xAxis:typeof t.x_axis==`string`?t.x_axis:`x`,yAxis:typeof t.y_axis==`string`?t.y_axis:`y`};if(t.tier===`density`){let r=t.density,i=this.spec.columns[r.buf],a=this._columnView(e,i),o=r.enc===`log-u8`?Fe(a,r.max):a;return n.densityNormMax=r.max,n.density={w:r.w,h:r.h,max:r.max,normMax:r.max,colormap:r.colormap,color:r.color?x(this.root,r.color,[.3,.47,.66,1]):null,xRange:r.x_range,yRange:r.y_range,grid:Ie(o),tex:this._uploadGrid(o,r.w,r.h,r.max),lut:this._lut(r.colormap)},n.sampleOverlay=this._buildDensitySample(t,r.sample,e),n._shownDensity=n.density,V(this,n,n.density),n}if(J(t.kind).build(this,n,t,e),t.keys&&Number.isInteger(t.keys.lo)&&Number.isInteger(t.keys.hi)){let r=this._columnView(e,this.spec.columns[t.keys.lo]),i=this._columnView(e,this.spec.columns[t.keys.hi]),a=Math.min(n.n||0,r.length,i.length);n._transitionKeys=Array(a),n._transitionKeyIndex=new Map;for(let e=0;et.channels&&t.channels[e],a=Number(t.style&&t.style.artist_alpha);if(i(`opacity`)||i(`artist_alpha`)||i(r)||i(`symbol`)||Number.isFinite(a)){let t=new Float32Array(e.n*4);for(let n=0;n{let s=i(r);if(!s)return;let c=this._columnView(n,this.spec.columns[s.buf]);for(let n=0;n1?t[n*r+1]:t[n*r])*this.dpr;e.radiusBuf=this._upload(i)}t.stroke&&t.stroke.mode===`direct_rgba`&&(e.strokeBuf=this._upload(this._columnView(n,this.spec.columns[t.stroke.buf])))}_buildScatterMark(e,t,n){this._buildXY(e,t,n),e.colorMode=0,e.color=x(this.root,t.color&&t.color.color,[.3,.47,.66,1]),t.color&&t.color.mode===`continuous`?(e.colorMode=1,e._cpu.color=this._columnView(n,this.spec.columns[t.color.buf]),e.cBuf=this._upload(e._cpu.color),e.lut=this._lut(t.color.colormap)):t.color&&t.color.mode===`categorical`?(e.colorMode=2,e._cpu.color=this._columnView(n,this.spec.columns[t.color.buf]),e.cBuf=this._upload(e._cpu.color),e.lut=this._paletteLut(t.color.palette)):t.color&&t.color.mode===`direct_rgba`&&(e.colorMode=3,e._cpu.rgba=this._columnView(n,this.spec.columns[t.color.buf]),e.rgbaBuf=this._upload(e._cpu.rgba)),e.sizeMode=0,e.size=t.size&&t.size.size||4,e.sizeRange=[2,18],t.size&&t.size.mode===`continuous`&&(e.sizeMode=1,e._cpu.size=this._columnView(n,this.spec.columns[t.size.buf]),e.sBuf=this._upload(e._cpu.size),e.sizeRange=t.size.range_px),this._buildInstanceStyleChannels(e,t,n,`stroke_width`),this._pointMarkStyle(e,t)}_pointMarkStyle(e,t){let n=t.style||{};e.symbol={circle:0,square:1,diamond:2,triangle:3,cross:4,hexagon:5,pentagon:6,star:7,triangle_down:8,triangle_left:9,triangle_right:10,x:11,point:12,pixel:13,thin_diamond:14,plus_line:15,x_line:16}[n.symbol]||0,e.pointStrokeWidth=Number(n.stroke_width)||0,e.pointStrokeFace=!n.stroke&&(!t.stroke||t.stroke.mode===`match_fill`),e.pointStroke=n.stroke?x(this.root,n.stroke,[e.color[0],e.color[1],e.color[2],1]):null}_sampleTraceSpec(e,t){return{id:e.id,kind:`scatter`,name:e.name,style:t.style||e.style||{},tier:`sampled`,x:t.x&&t.x.col,y:t.y&&t.y.col,x_axis:e.x_axis,y_axis:e.y_axis,color:t.color,size:t.size,stroke:t.stroke,channels:t.channels}}_buildDensitySample(e,t,n){if(!t||!t.x||!t.y||t.x.col===void 0||t.y.col===void 0)return null;let r=this._sampleTraceSpec(e,t),i={trace:r,tier:`sampled`,xAxis:typeof e.x_axis==`string`?e.x_axis:`x`,yAxis:typeof e.y_axis==`string`?e.y_axis:`y`};return this._buildScatterMark(i,r,n),i.win={x0:t.x_range[0],x1:t.x_range[1],y0:t.y_range[0],y1:t.y_range[1]},i.sample={n:t.n,visible:t.visible},i}_destroyDensitySample(e){let t=e&&e.sampleOverlay;if(!(!t||!this.gl)){for(let e of[t.xBuf,t.yBuf,t.cBuf,t.rgbaBuf,t.sBuf,t.styleBuf,t.strokeBuf,t.selBuf,t.dBuf])e&&this.gl.deleteBuffer(e);e.sampleOverlay=null}}_applyDensitySample(e,t,n){if(this._destroyDensitySample(e),!t||!t.x||!t.y||t.x.buf===void 0||t.y.buf===void 0){this._refreshReductionBadges();return}let r=this.gl,i={id:e.trace.id,kind:`scatter`,name:e.trace.name,style:t.style||e.trace.style||{},tier:`sampled`,x_axis:e.trace.x_axis,y_axis:e.trace.y_axis,color:t.color,size:t.size,stroke:t.stroke,channels:t.channels},a={trace:i,tier:`sampled`,xAxis:e.xAxis,yAxis:e.yAxis,xBuf:r.createBuffer(),yBuf:r.createBuffer(),xMeta:{offset:t.x.offset,scale:t.x.scale},yMeta:{offset:t.y.offset,scale:t.y.scale},n:Math.min(t.x.len,t.y.len),win:{x0:t.x_range[0],x1:t.x_range[1],y0:t.y_range[0],y1:t.y_range[1]},sample:{n:t.n,visible:t.visible},selActive:!1,colorMode:0,color:x(this.root,t.color&&t.color.color,[.3,.47,.66,1]),sizeMode:0,size:t.size&&t.size.size||4,sizeRange:[2,18]};if(r.bindBuffer(r.ARRAY_BUFFER,a.xBuf),r.bufferData(r.ARRAY_BUFFER,this._asF32(n[t.x.buf]),r.STATIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,a.yBuf),r.bufferData(r.ARRAY_BUFFER,this._asF32(n[t.y.buf]),r.STATIC_DRAW),t.color&&t.color.buf!==void 0){a.colorMode=t.color.mode===`continuous`?1:t.color.mode===`categorical`?2:3;let e=t.color.dtype===`u8`?this._asU8(n[t.color.buf]):this._asF32(n[t.color.buf]),i=a.colorMode===3?`rgbaBuf`:`cBuf`;a[i]=r.createBuffer(),a[i]._fcType=e instanceof Uint8Array?r.UNSIGNED_BYTE:r.FLOAT,r.bindBuffer(r.ARRAY_BUFFER,a[i]),r.bufferData(r.ARRAY_BUFFER,e,r.STATIC_DRAW),a.colorMode!==3&&(a.lut=t.color.mode===`continuous`?this._lut(t.color.colormap):this._paletteLut(t.color.palette))}t.size&&t.size.mode===`continuous`&&(a.sizeMode=1,a.sBuf=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,a.sBuf),r.bufferData(r.ARRAY_BUFFER,this._asF32(n[t.size.buf]),r.STATIC_DRAW),a.sizeRange=t.size.range_px);let o=e=>t.channels&&t.channels[e],s=Number(i.style&&i.style.artist_alpha);if(o(`opacity`)||o(`artist_alpha`)||o(`stroke_width`)||o(`symbol`)||Number.isFinite(s)){let e=new Float32Array(a.n*4);for(let t=0;t{let s=o(t);if(!s)return;let c=s.dtype===`u8`?this._asU8(n[s.buf]):this._asF32(n[s.buf]),l=s.components||1;for(let t=0;tI(n,e,t);if(!t){n.uniform1i(r(`u_gradMode`),0);return}n.uniform1i(r(`u_gradMode`),t.mode),n.uniform1i(r(`u_gradDir`),t.dir),n.uniform1i(r(`u_gradCount`),t.count),n.uniform1fv(r(`u_gradPos`),t.pos),n.uniform4fv(r(`u_gradColor`),t.colors)}_fillOpacity(e,t=1){return Number(e.opacity??t)*Number(e.fill_opacity??1)}_strokeOpacity(e,t=1){return Number(e.opacity??t)*Number(e.stroke_opacity??1)}_setRectStyleUniforms(e,t){let n=this.gl,r=t=>I(n,e,t);n.uniform2f(r(`u_res`),this.canvas.width,this.canvas.height);let i=t.cornerRadius||[0,0];n.uniform2f(r(`u_radius`),i[0]*this.dpr,i[1]*this.dpr),n.uniform1f(r(`u_strokeWidth`),(t.strokeWidth||0)*this.dpr);let a=t.strokeColor||[0,0,0,0];n.uniform4f(r(`u_stroke`),a[0],a[1],a[2],a[3]),n.uniform1i(r(`u_strokeMode`),+!!t.strokeBuf),n.uniform1f(r(`u_strokeOpacity`),this._strokeOpacity(t.trace.style||{})),this._setGradientUniforms(e,t.grad)}_rectMarkStyleGpu(e,t){let n=t.style||{},r=n.corner_radius;e.cornerRadius=Array.isArray(r)?[Number(r[0])||0,Number(r[1])||0]:[Number(r)||0,Number(r)||0],e.strokeWidth=Number(n.stroke_width)||0;let i=[e.color[0],e.color[1],e.color[2],1];e.strokeColor=n.stroke?x(this.root,n.stroke,i):i,e.grad=this._resolveMarkFill(n,e.color)}_smoothArrays(e,t,n,r,i){return!e.style||e.style.curve!==`smooth`?null:Me(t,n,r||null,i,32768)}_stepArrays(e,t,n,r){let i=e.style&&e.style.step;if(!i||r<2)return null;let a=i===`mid`?3:2,o=1+(r-1)*a,s=new Float32Array(o),c=new Float32Array(o);s[0]=t[0],c[0]=n[0];let l=1;for(let e=1;ethis._columnView(n,this.spec.columns[e])):this._columnView(n,this.spec.columns[r.buf]);e.heatmap={w:r.w,h:r.h,xRange:r.x_range,yRange:r.y_range,colormap:r.colormap,truecolor:i,tex:i?this._uploadRgbaGrid(a,r.w,r.h):this._uploadHeatmapGrid(a,r.w,r.h),lut:i?null:this._lut(r.colormap)},i||(e._cpuHeatmap={grid:a})}_uploadRgbaGrid(e,t,n){let r=this.gl,i=r.createTexture(),a=new Uint8Array(t*n*4);for(let r=0;rr.byteLength)throw RangeError(`column extends past chart payload`);if(c%s!==0)throw RangeError(`column is misaligned`);return t.dtype===`u8`?new Uint8Array(r.buffer,c,a):t.dtype===`u32`?new Uint32Array(r.buffer,c,a):new Float32Array(r.buffer,c,a)}_upload(e){let t=this.gl,n=t.createBuffer();return n._fcId=++this._bufSeq,n._fcType=e instanceof Uint8Array?t.UNSIGNED_BYTE:t.FLOAT,t.bindBuffer(t.ARRAY_BUFFER,n),t.bufferData(t.ARRAY_BUFFER,e,t.STATIC_DRAW),n}_bindVao(e,t,n,r){let i=this.gl;e._vaos||=new Map;let a=n.join(`|`),o=e._vaos.get(t);if(!o||o.sig!==a){o&&i.deleteVertexArray(o.vao);let n=i.createVertexArray();i.bindVertexArray(n),r(),o={vao:n,sig:a},e._vaos.set(t,o)}else i.bindVertexArray(o.vao)}_deleteVaos(e){if(!e||!e._vaos)return;let t=this.gl;if(t)for(let{vao:n}of e._vaos.values())t.deleteVertexArray(n);e._vaos=null}_vaoAttr(e,t,n,r,i=1,a=!1){let o=this.gl;o.bindBuffer(o.ARRAY_BUFFER,t),o.enableVertexAttribArray(e),o.vertexAttribPointer(e,i,t._fcType||o.FLOAT,a,0,n),o.vertexAttribDivisor(e,r)}_initPickTarget(){let e=this.gl;this.pickTex=e.createTexture(),this._allocPickTex(),this.pickFbo=e.createFramebuffer(),e.bindFramebuffer(e.FRAMEBUFFER,this.pickFbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.pickTex,0),e.bindFramebuffer(e.FRAMEBUFFER,null),this._pickDirty=!0}_allocPickTex(){let e=this.gl;e.bindTexture(e.TEXTURE_2D,this.pickTex),e.texImage2D(e.TEXTURE_2D,0,e.RGBA8,this.canvas.width,this.canvas.height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this._pickW=this.canvas.width,this._pickH=this.canvas.height}_map(e,t,n,r=null){if(!r)return[2/((n-t)*e.scale),(e.offset-t)/(n-t)*2-1];let i=this._axis(r),a=this._axisCoord(i,t),o=this._axisCoord(i,n);if(![a,o].every(Number.isFinite)||o===a)return[0,-2];let s=2/(o-a);return[s,-1-a*s]}_mapConst(e,t,n,r=null){if(!r)return(e-t)/(n-t)*2-1;let i=this._axis(r),a=this._axisCoord(i,e),o=this._axisCoord(i,t),s=this._axisCoord(i,n);return![a,o,s].every(Number.isFinite)||s===o?-2:(a-o)/(s-o)*2-1}_edgePadForValue(e,t,n,r){if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n)||n===t)return 0;let i=Math.abs(n-t)*1e-10+1e-12,a=Math.max(1,r||1),o=Math.max(2,Math.ceil(this.dpr||1));return Math.abs(e-t)<=i?-(2*o)/a:Math.abs(e-n)<=i?2*o/a:0}_setAxisUniforms(e,t,n,r){let i=this.gl,a=t=>I(i,e,t);i.uniform2f(a(`${t}meta`),n&&Number.isFinite(n.offset)?n.offset:0,n&&n.scale?n.scale:1),i.uniform1i(a(`${t}mode`),this._axisMode(r))}draw(e=!1){if(!(this._destroyed||this._glLost||!this.gl)){if(this._updateZoomMenuLabel?.(),this._raf){this._rafKeepPick=this._rafKeepPick&&e;return}this._rafKeepPick=e,this._raf=requestAnimationFrame(()=>{this._raf=null,!this._destroyed&&this._drawNow()})}}_drawNow(){if(this._destroyed||!this.gl||this._glLost)return;this._healStaleTheme();let e=this.gl,{x0:t,x1:n,y0:r,y1:i}=this.view;e.bindFramebuffer(e.FRAMEBUFFER,null),e.viewport(0,0,this.canvas.width,this.canvas.height),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT);let a=e=>{if(e.tier===`density`){let[t,n]=this._axisRange(e.xAxis),[r,i]=this._axisRange(e.yAxis);tt(this,e,t,n,r,i);return}J(e.trace.kind).draw(this,e,t,n,r,i)};for(let e of this._transitionOldTraces||[])a(e);for(let e of this.gpuTraces)a(e);this._drawHoverState(),this._repositionTooltip(),this._rafKeepPick||(this._pickDirty=!0),this._rafKeepPick=!1,this._drawChrome(),this._renderLassoSelection?.()}_now(){return performance.now()}_canDrawSimplePoints(e){return e.colorMode===0&&e.sizeMode===0&&!e.selActive&&!e.rgbaBuf&&!e.styleBuf&&!e.strokeBuf&&(e.symbol||0)===0&&(e.pointStrokeWidth||0)<=0&&Math.max(e.lodBlendShown??0,e.lodBlend??0)<=.001}_drawPoints(e,t,n,r=1){r*=e._transitionOpacity??1;let i=e._transitionScale??1;if(this._canDrawSimplePoints(e)){this._drawSimplePoints(e,t,n,r);return}let a=this.gl,o=this.pointProg;a.useProgram(o);let s=e=>I(a,o,e);a.uniform2f(s(`u_xmap`),t[0],t[1]),a.uniform2f(s(`u_ymap`),n[0],n[1]),this._setAxisUniforms(o,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(o,`u_y`,e.yMeta,e.yAxis),a.uniform1f(s(`u_dpr`),this.dpr);let c=!!(e._transitionPrevXBuf&&e._transitionPrevYBuf);a.uniform1i(s(`u_transitionActive`),+!!c),a.uniform1f(s(`u_transitionProgress`),e._transitionPositionProgress??1),a.uniform1f(s(`u_size`),e.size*i),a.uniform1i(s(`u_sizeMode`),e.sizeMode),a.uniform2f(s(`u_sizeRange`),e.sizeRange[0]*i,e.sizeRange[1]*i),a.uniform1i(s(`u_colorMode`),e.colorMode);let l=this._fillOpacity(e.trace.style,.8)*r;a.uniform1f(s(`u_opacity`),l),a.uniform1f(s(`u_selectedOpacity`),this._markStateNumber(`selected`,`opacity`,1)),a.uniform1f(s(`u_unselectedOpacity`),this._markStateNumber(`unselected`,`opacity`,.12));let u=(e,t)=>{let n=t?x(this.root,t,[0,0,0,1]):null;a.uniform4f(e,n?n[0]:0,n?n[1]:0,n?n[2]:0,+!!n)};u(s(`u_selColor`),this._markStateValue(`selected`,`color`)),u(s(`u_unselColor`),this._markStateValue(`unselected`,`color`));let[d,f,p,m]=e.color;a.uniform4f(s(`u_color`),d,f,p,m),a.uniform1i(s(`u_symbol`),e.symbol||0);let h=e.pointStroke;a.uniform1f(s(`u_ptStrokeWidth`),(e.pointStrokeWidth||0)*this.dpr),a.uniform1i(s(`u_ptStrokeFace`),+!!e.pointStrokeFace),a.uniform1i(s(`u_strokeMode`),+!!e.strokeBuf),a.uniform1f(s(`u_strokeOpacity`),this._strokeOpacity(e.trace.style,.8)*r),a.uniform4f(s(`u_ptStroke`),h?h[0]:0,h?h[1]:0,h?h[2]:0,h?h[3]:0),a.uniform1i(s(`u_selActive`),+!!e.selActive);let g=e.colorMode!==0&&e.cBuf,_=e.sizeMode===1&&e.sBuf,v=e.selActive&&e.selBuf,y=e.colorMode===3&&e.rgbaBuf,b=!!e.styleBuf,S=!!e.strokeBuf;e.lut&&(a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,e.lut),a.uniform1i(s(`u_lut`),0));let C=e.lodBlend??0,w=e.lodBlendShown??C;if(Math.abs(w-C)>.005&&!this._prefersReducedMotion()){let t=this._now(),n=e._blendTick?Math.min(100,t-e._blendTick):16;e._blendTick=t,w+=(C-w)*(1-Math.exp(-n/90)),e.lodBlendShown=w,this.draw()}else e.lodBlendShown=w=C,e._blendTick=0;a.uniform1f(s(`u_dblend`),w);let T=w>.001&&e.dBuf&&e.dlut;T&&(a.activeTexture(a.TEXTURE1),a.bindTexture(a.TEXTURE_2D,e.dlut)),a.uniform1i(s(`u_dlut`),1),this._bindVao(e,`points`,[e.xBuf._fcId,e.yBuf._fcId,g?e.cBuf._fcId:0,_?e.sBuf._fcId:0,v?e.selBuf._fcId:0,T?e.dBuf._fcId:0,c?e._transitionPrevXBuf._fcId:0,c?e._transitionPrevYBuf._fcId:0,y?e.rgbaBuf._fcId:0,b?e.styleBuf._fcId:0,S?e.strokeBuf._fcId:0],()=>{this._vaoAttr(F.ax,e.xBuf,0,0),this._vaoAttr(F.ay,e.yBuf,0,0),g&&this._vaoAttr(F.a_cval,e.cBuf,0,0),_&&this._vaoAttr(F.a_sval,e.sBuf,0,0),v&&this._vaoAttr(F.a_sel,e.selBuf,0,0),T&&this._vaoAttr(F.a_dval,e.dBuf,0,0),c&&(this._vaoAttr(F.a_prevx,e._transitionPrevXBuf,0,0),this._vaoAttr(F.a_prevy,e._transitionPrevYBuf,0,0)),y&&this._vaoAttr(F.a_rgba,e.rgbaBuf,0,0,4,!0),b&&this._vaoAttr(F.a_style,e.styleBuf,0,0,4),S&&this._vaoAttr(F.a_stroke,e.strokeBuf,0,0,4,!0)}),g||a.vertexAttrib1f(F.a_cval,0),_||a.vertexAttrib1f(F.a_sval,.5),v||a.vertexAttrib1f(F.a_sel,1),T||a.vertexAttrib1f(F.a_dval,0),y||a.vertexAttrib4f(F.a_rgba,d,f,p,m),b||a.vertexAttrib4f(F.a_style,1,-1,-1,-1),S||a.vertexAttrib4f(F.a_stroke,d,f,p,m),a.drawArrays(a.POINTS,0,e.n)}_drawSimplePoints(e,t,n,r=1){let i=this.gl,a=this.pointSimpleProg;i.useProgram(a);let o=e=>I(i,a,e);i.uniform2f(o(`u_xmap`),t[0],t[1]),i.uniform2f(o(`u_ymap`),n[0],n[1]),this._setAxisUniforms(a,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(a,`u_y`,e.yMeta,e.yAxis),i.uniform1f(o(`u_dpr`),this.dpr);let s=!!(e._transitionPrevXBuf&&e._transitionPrevYBuf);i.uniform1i(o(`u_transitionActive`),+!!s),i.uniform1f(o(`u_transitionProgress`),e._transitionPositionProgress??1),i.uniform1f(o(`u_size`),e.size*(e._transitionScale??1));let[c,l,u,d]=e.color;i.uniform4f(o(`u_color`),c,l,u,d*this._fillOpacity(e.trace.style,.8)*r),this._bindVao(e,`points-simple`,[e.xBuf._fcId,e.yBuf._fcId,s?e._transitionPrevXBuf._fcId:0,s?e._transitionPrevYBuf._fcId:0],()=>{this._vaoAttr(F.ax,e.xBuf,0,0),this._vaoAttr(F.ay,e.yBuf,0,0),s&&(this._vaoAttr(F.a_prevx,e._transitionPrevXBuf,0,0),this._vaoAttr(F.a_prevy,e._transitionPrevYBuf,0,0))}),i.drawArrays(i.POINTS,0,e.n)}_drawHoverState(){let e=this._hoverTarget;if(!e||!e.g)return;let t=e.g;if(t.trace.kind!==`scatter`||t.tier===`density`||!Number.isInteger(e.index)||e.index<0||e.index>=t.n)return;let[n,r]=this._axisRange(t.xAxis),[i,a]=this._axisRange(t.yAxis);this._drawHoverPoint(t,e.index,this._map(t.xMeta,n,r,t.xAxis),this._map(t.yMeta,i,a,t.yAxis))}_drawHoverPoint(e,t,n,r){let i=this.gl,a=this.pointProg;i.useProgram(a);let o=e=>I(i,a,e);i.uniform2f(o(`u_xmap`),n[0],n[1]),i.uniform2f(o(`u_ymap`),r[0],r[1]),this._setAxisUniforms(a,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(a,`u_y`,e.yMeta,e.yAxis);let s=Math.max((e.size||4)*1.75,(e.size||4)+5),c=Math.max(0,this._markStateNumber(`hover`,`size`,s)),l=Math.max(0,Math.min(1,this._markStateNumber(`hover`,`opacity`,.95))),u=x(this.root,this._markStatePaint(`hover`,`color`,`rgba(15,23,42,.92)`),[.06,.09,.16,.92]);i.uniform1f(o(`u_dpr`),this.dpr),i.uniform1f(o(`u_size`),c),i.uniform1i(o(`u_sizeMode`),0),i.uniform2f(o(`u_sizeRange`),c,c),i.uniform1i(o(`u_colorMode`),0),i.uniform1f(o(`u_opacity`),l),i.uniform1f(o(`u_selectedOpacity`),1),i.uniform1f(o(`u_unselectedOpacity`),1),i.uniform4f(o(`u_color`),u[0],u[1],u[2],1),i.uniform1i(o(`u_selActive`),0),i.uniform1f(o(`u_dblend`),0),this._bindVao(e,`hover`,[e.xBuf._fcId,e.yBuf._fcId],()=>{this._vaoAttr(F.ax,e.xBuf,0,0),this._vaoAttr(F.ay,e.yBuf,0,0)}),i.vertexAttrib1f(F.a_cval,0),i.vertexAttrib1f(F.a_sval,.5),i.vertexAttrib1f(F.a_sel,1),i.vertexAttrib1f(F.a_dval,0),i.drawArrays(i.POINTS,t,1)}_drawDensity(e,t,n=1){let r=this.gl,i=t||e.density;if(!i||!i.tex||!r.isTexture(i.tex))return;n*=e._transitionOpacity??1;let a=this.densityProg;r.useProgram(a);let o=e=>I(r,a,e),{x0:s,x1:c,y0:l,y1:u}=this.view,[d,f]=this._axisRange(e.xAxis),[p,m]=this._axisRange(e.yAxis);r.uniform4f(o(`u_view`),d??s,f??c,p??l,m??u),r.uniform1i(o(`u_xmode`),this._axisMode(e.xAxis)),r.uniform1i(o(`u_ymode`),this._axisMode(e.yAxis)),r.uniform4f(o(`u_gridRange`),i.xRange[0],i.xRange[1],i.yRange[0],i.yRange[1]),r.uniform1f(o(`u_opacity`),this._fillOpacity(e.trace.style)*n);let h=i.color;r.uniform1i(o(`u_constantColor`),+!!h),r.uniform4f(o(`u_color`),...h||[1,1,1,1]),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,i.tex),r.uniform1i(o(`u_grid`),0),r.activeTexture(r.TEXTURE1),r.bindTexture(r.TEXTURE_2D,i.lut),r.uniform1i(o(`u_lut`),1),r.bindVertexArray(this.quadVao),r.drawArrays(r.TRIANGLE_STRIP,0,4)}_drawHeatmap(e){let t=e.heatmap;if(!t)return;let n=this.gl,r=this.heatmapProg;n.useProgram(r);let i=e=>I(n,r,e),{x0:a,x1:o,y0:s,y1:c}=this.view,[l,u]=this._axisRange(e.xAxis),[d,f]=this._axisRange(e.yAxis);n.uniform4f(i(`u_view`),l??a,u??o,d??s,f??c),n.uniform1i(i(`u_xmode`),this._axisMode(e.xAxis)),n.uniform1i(i(`u_ymode`),this._axisMode(e.yAxis));let p=(l??a)>(u??o),m=(d??s)>(f??c);n.uniform4f(i(`u_gridRange`),t.xRange[+!!p],t.xRange[+!p],t.yRange[+!!m],t.yRange[+!m]),n.uniform1f(i(`u_opacity`),this._fillOpacity(e.trace.style)*(e._transitionOpacity??1)),n.uniform1i(i(`u_truecolor`),+!!t.truecolor),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,t.tex),n.uniform1i(i(`u_grid`),0),t.truecolor||(n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,t.lut),n.uniform1i(i(`u_lut`),1)),n.bindVertexArray(this.quadVao),n.drawArrays(n.TRIANGLE_STRIP,0,4)}_drawLine(e,t,n,r=null,i=null,a=null){if(e.n<2)return;let o=this.gl;o.useProgram(this.lineProg);let s=e=>I(o,this.lineProg,e);o.uniform2f(s(`u_xmap`),t[0],t[1]),o.uniform2f(s(`u_ymap`),n[0],n[1]),this._setAxisUniforms(this.lineProg,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(this.lineProg,`u_y`,e.yMeta,e.yAxis),o.uniform2f(s(`u_res`),this.canvas.width,this.canvas.height);let c=!!(e._transitionPrevXBuf&&e._transitionPrevYBuf);o.uniform1i(s(`u_transitionActive`),+!!c),o.uniform1f(s(`u_transitionProgress`),e._transitionPositionProgress??1);let l=Math.max(0,Math.min(1,e._transitionReveal??1));o.uniform1f(s(`u_revealProgress`),l),o.uniform1f(s(`u_revealSegments`),e.n-1),o.uniform1f(s(`u_width`),(i??e.trace.style.width??1.5)*this.dpr);let[u,d,f,p]=r||e.color,m=this._strokeOpacity(e.trace.style)*(a??1)*(e._transitionOpacity??1);o.uniform4f(s(`u_color`),u,d,f,p*m);let h=this._lineDash(e);this._bindVao(e,`line`,[e.xBuf._fcId,e.yBuf._fcId,h?e._lenBuf._fcId:0,c?e._transitionPrevXBuf._fcId:0,c?e._transitionPrevYBuf._fcId:0],()=>{this._vaoAttr(F.ax0,e.xBuf,0,1),this._vaoAttr(F.ax1,e.xBuf,4,1),this._vaoAttr(F.ay0,e.yBuf,0,1),this._vaoAttr(F.ay1,e.yBuf,4,1),h&&(this._vaoAttr(F.a_len0,e._lenBuf,0,1),this._vaoAttr(F.a_len1,e._lenBuf,4,1)),c&&(this._vaoAttr(F.a_prevx,e._transitionPrevXBuf,0,1),this._vaoAttr(F.a_prevy,e._transitionPrevYBuf,0,1),this._vaoAttr(F.a_prevx1,e._transitionPrevXBuf,4,1),this._vaoAttr(F.a_prevy1,e._transitionPrevYBuf,4,1))});let g=Math.max(0,Math.min(e.n-1,Math.ceil((e.n-1)*l)));o.drawArraysInstanced(o.TRIANGLE_STRIP,0,4,g)}_drawSegments(e,t,n){if(e.n<1)return;let r=this.gl,i=this.segmentProg;r.useProgram(i);let a=e=>I(r,i,e);r.uniform2f(a(`u_xmap`),t[0],t[1]),r.uniform2f(a(`u_ymap`),n[0],n[1]),this._setAxisUniforms(i,`u_x0`,e.x0Meta,e.xAxis),this._setAxisUniforms(i,`u_x1`,e.x1Meta,e.xAxis),this._setAxisUniforms(i,`u_y0`,e.y0Meta,e.yAxis),this._setAxisUniforms(i,`u_y1`,e.y1Meta,e.yAxis),r.uniform2f(a(`u_res`),this.canvas.width,this.canvas.height),r.uniform1f(a(`u_width`),(e.trace.style.width??1.5)*this.dpr),r.uniform1f(a(`u_animationProgress`),e._transitionScale??1);let[o,s,c,l]=e.color;r.uniform4f(a(`u_color`),o,s,c,l),r.uniform1f(a(`u_opacity`),this._strokeOpacity(e.trace.style)*(e._transitionOpacity??1)),r.uniform1i(a(`u_colorMode`),e.colorMode||0);let u=this._segmentDash(e,i);e.colorMode&&e.lut&&(r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,e.lut),r.uniform1i(a(`u_lut`),0)),this._bindVao(e,`segment`,[e.x0Buf._fcId,e.x1Buf._fcId,e.y0Buf._fcId,e.y1Buf._fcId,e.colorMode&&e.cBuf?e.cBuf._fcId:0,e.rgbaBuf?e.rgbaBuf._fcId:0,e.styleBuf?e.styleBuf._fcId:0,u?e._segmentDashOffsetBuf._fcId:0,u?e._segmentDashDirBuf._fcId:0],()=>{this._vaoAttr(F.ax0,e.x0Buf,0,1),this._vaoAttr(F.ax1,e.x1Buf,0,1),this._vaoAttr(F.ay0,e.y0Buf,0,1),this._vaoAttr(F.ay1,e.y1Buf,0,1),e.colorMode&&e.cBuf&&this._vaoAttr(F.a_cval,e.cBuf,0,1),e.rgbaBuf&&this._vaoAttr(F.a_rgba,e.rgbaBuf,0,1,4,!0),e.styleBuf&&this._vaoAttr(F.a_style,e.styleBuf,0,1,4),u&&(this._vaoAttr(F.a_dash0,e._segmentDashOffsetBuf,0,1),this._vaoAttr(F.a_dashDir,e._segmentDashDirBuf,0,1))}),e.cBuf||r.vertexAttrib1f(F.a_cval,0),e.rgbaBuf||r.vertexAttrib4f(F.a_rgba,o,s,c,l),e.styleBuf||r.vertexAttrib4f(F.a_style,1,-1,-1,-1);let d=Math.max(0,Math.min(e.n,Math.ceil(e.n*(e._transitionReveal??1))));r.drawArraysInstanced(r.TRIANGLE_STRIP,0,4,d)}_segmentDash(e,t){let n=this.gl,r=e=>I(n,t,e),i=e.trace.style&&e.trace.style.dash,a=e._segmentCpu;if(!i||!i.length||!a)return n.uniform1i(r(`u_dashCount`),0),!1;let o=e.n,s=e._segmentDashOffsets?.length===o?e._segmentDashOffsets:e._segmentDashOffsets=new Float32Array(o),c=e._segmentDashDirections?.length===o?e._segmentDashDirections:e._segmentDashDirections=new Float32Array(o),l=Array(o),u=Array(o),d=new Float32Array(o),f=new Map,p=(e,t)=>{let n=f.get(e);n?n.push(t):f.set(e,[t])},m=(e,t)=>`${Math.round(e*1e3)},${Math.round(t*1e3)}`,h=this.dpr;for(let t=0;t{let t=e,n=0;for(;;){let e=(f.get(t)||[]).find(e=>!g[e]);if(e===void 0)break;g[e]=1,l[e]===t?(s[e]=n,c[e]=1,t=u[e]):(s[e]=n+d[e],c[e]=-1,t=l[e]),n+=d[e]}};for(let[e,t]of f)t.length===1&&_(e);for(let e=0;ee?(n.bindBuffer(n.ARRAY_BUFFER,e),n.bufferData(n.ARRAY_BUFFER,t,n.DYNAMIC_DRAW),e):this._upload(t);e._segmentDashOffsetBuf=v(e._segmentDashOffsetBuf,s),e._segmentDashDirBuf=v(e._segmentDashDirBuf,c);let y=new Float32Array(8),b=Math.min(i.length,8),x=0;for(let e=0;eI(r,i,e);r.uniform2f(a(`u_xmap`),t[0],t[1]),r.uniform2f(a(`u_ymap`),n[0],n[1]);for(let t of[`x0`,`x1`,`x2`])this._setAxisUniforms(i,`u_`+t,e[t+`Meta`],e.xAxis);for(let t of[`y0`,`y1`,`y2`])this._setAxisUniforms(i,`u_`+t,e[t+`Meta`],e.yAxis);r.uniform1i(a(`u_colorMode`),e.colorMode||0),r.uniform1f(a(`u_opacity`),this._fillOpacity(e.trace.style)),r.uniform4f(a(`u_color`),e.color[0],e.color[1],e.color[2],e.color[3]);let o=e.meshStroke||[0,0,0,0];r.uniform4f(a(`u_stroke`),o[0],o[1],o[2],o[3]),r.uniform1f(a(`u_strokeWidth`),e.meshStrokeWidth||0),r.uniform1i(a(`u_strokeMode`),+!!e.strokeBuf),r.uniform1f(a(`u_strokeOpacity`),this._strokeOpacity(e.trace.style)),e.colorMode&&e.lut&&(r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,e.lut),r.uniform1i(a(`u_lut`),0));let s=[`x0`,`x1`,`x2`,`y0`,`y1`,`y2`].map(t=>e[t+`Buf`]._fcId);s.push(e.cBuf?e.cBuf._fcId:0,e.rgbaBuf?e.rgbaBuf._fcId:0,e.styleBuf?e.styleBuf._fcId:0,e.strokeBuf?e.strokeBuf._fcId:0),this._bindVao(e,`mesh`,s,()=>{for(let t of[`x0`,`x1`,`x2`,`y0`,`y1`,`y2`])this._vaoAttr(F[`a`+t],e[t+`Buf`],0,1);e.cBuf&&this._vaoAttr(F.a_cval,e.cBuf,0,1),e.rgbaBuf&&this._vaoAttr(F.a_rgba,e.rgbaBuf,0,1,4,!0),e.styleBuf&&this._vaoAttr(F.a_style,e.styleBuf,0,1,4),e.strokeBuf&&this._vaoAttr(F.a_stroke,e.strokeBuf,0,1,4,!0)}),e.cBuf||r.vertexAttrib1f(F.a_cval,0),e.rgbaBuf||r.vertexAttrib4f(F.a_rgba,...e.color),e.styleBuf||r.vertexAttrib4f(F.a_style,1,-1,-1,-1),e.strokeBuf||r.vertexAttrib4f(F.a_stroke,...o),r.drawArraysInstanced(r.TRIANGLES,0,3,e.n)}_lineDash(e){let t=this.gl,n=e=>I(t,this.lineProg,e),r=e.trace.style&&e.trace.style.dash;if(!r||!r.length||!e._dashX)return t.uniform1i(n(`u_dashCount`),0),!1;let i=e.n;(!e._lenArr||e._lenArr.length!==i)&&(e._lenArr=new Float32Array(i));let a=e._lenArr,o=this.dpr,s=this._dataPx(e.xAxis,this._decodeValue(e._dashX,e.xMeta,0)),c=this._dataPx(e.yAxis,this._decodeValue(e._dashY,e.yMeta,0)),l=0;a[0]=0;for(let t=1;tI(i,a,e);i.uniform2f(o(`u_xmap`),t[0],t[1]),i.uniform2f(o(`u_ymap`),n[0],n[1]),i.uniform2f(o(`u_bmap`),r[0],r[1]),this._setAxisUniforms(a,`u_x`,e.xMeta,e.xAxis),this._setAxisUniforms(a,`u_y`,e.yMeta,e.yAxis),this._setAxisUniforms(a,`u_b`,e.baseMeta,e.yAxis);let s=Math.max(0,Math.min(1,e._transitionReveal??1));i.uniform1f(o(`u_revealProgress`),s),i.uniform1f(o(`u_revealSegments`),e.n-1);let[c,l,u,d]=e.color;i.uniform4f(o(`u_color`),c,l,u,d*this._fillOpacity(e.trace.style,.35)*(e._transitionOpacity??1)),i.uniform2f(o(`u_res`),this.canvas.width,this.canvas.height),this._setGradientUniforms(a,e.grad),this._bindVao(e,`area`,[e.xBuf._fcId,e.yBuf._fcId,e.baseBuf._fcId],()=>{this._vaoAttr(F.ax0,e.xBuf,0,1),this._vaoAttr(F.ax1,e.xBuf,4,1),this._vaoAttr(F.ay0,e.yBuf,0,1),this._vaoAttr(F.ay1,e.yBuf,4,1),this._vaoAttr(F.ab0,e.baseBuf,0,1),this._vaoAttr(F.ab1,e.baseBuf,4,1)});let f=Math.max(0,Math.min(e.n-1,Math.ceil((e.n-1)*s)));i.drawArraysInstanced(i.TRIANGLE_STRIP,0,4,f)}_drawRects(e,t,n,r,i,a=[0,0,0,0]){if(!e.n)return;let o=this.gl,s=this.rectProg;o.useProgram(s);let c=e=>I(o,s,e);o.uniform2f(c(`u_x0map`),t[0],t[1]),o.uniform2f(c(`u_x1map`),n[0],n[1]),o.uniform2f(c(`u_y0map`),r[0],r[1]),o.uniform2f(c(`u_y1map`),i[0],i[1]),this._setAxisUniforms(s,`u_x0`,e.x0Meta,e.xAxis),this._setAxisUniforms(s,`u_x1`,e.x1Meta,e.xAxis),this._setAxisUniforms(s,`u_y0`,e.y0Meta,e.yAxis),this._setAxisUniforms(s,`u_y1`,e.y1Meta,e.yAxis),o.uniform1i(c(`u_xmode`),this._axisMode(e.xAxis)),o.uniform1i(c(`u_ymode`),this._axisMode(e.yAxis)),o.uniform4f(c(`u_edgePad`),a[0],a[1],a[2],a[3]);let[l,u,d,f]=e.color;o.uniform4f(c(`u_color`),l,u,d,f),o.uniform1f(c(`u_opacity`),this._fillOpacity(e.trace.style)*(e._transitionOpacity??1)),o.uniform1i(c(`u_colorMode`),e.colorMode||0),this._setRectStyleUniforms(s,e);let p=!!e.cBuf,m=!!e.rgbaBuf,h=!!e.styleBuf,g=!!e.strokeBuf,_=!!e.radiusBuf;p&&(o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,e.lut),o.uniform1i(c(`u_lut`),0)),this._bindVao(e,`rects`,[e.x0Buf._fcId,e.x1Buf._fcId,e.y0Buf._fcId,e.y1Buf._fcId,p?e.cBuf._fcId:0,m?e.rgbaBuf._fcId:0,h?e.styleBuf._fcId:0,g?e.strokeBuf._fcId:0,_?e.radiusBuf._fcId:0],()=>{this._vaoAttr(F.ax0,e.x0Buf,0,1),this._vaoAttr(F.ax1,e.x1Buf,0,1),this._vaoAttr(F.ay0,e.y0Buf,0,1),this._vaoAttr(F.ay1,e.y1Buf,0,1),p&&this._vaoAttr(F.a_cval,e.cBuf,0,1),m&&this._vaoAttr(F.a_rgba,e.rgbaBuf,0,1,4,!0),h&&this._vaoAttr(F.a_style,e.styleBuf,0,1,4),g&&this._vaoAttr(F.a_stroke,e.strokeBuf,0,1,4,!0),_&&this._vaoAttr(F.a_radius,e.radiusBuf,0,1,2)}),p||o.vertexAttrib1f(F.a_cval,0),m||o.vertexAttrib4f(F.a_rgba,l,u,d,f),h||o.vertexAttrib4f(F.a_style,1,-1,-1,-1),g||o.vertexAttrib4f(F.a_stroke,...e.strokeColor||e.color),_||o.vertexAttrib2f(F.a_radius,-1,-1),o.drawArraysInstanced(o.TRIANGLE_STRIP,0,4,e.n)}_drawBars(e,t,n,r,i,a=0){if(!e.n)return;let o=this.gl,s=this.barProg;o.useProgram(s);let c=e=>I(o,s,e);o.uniform2f(c(`u_pmap`),t[0],t[1]),o.uniform2f(c(`u_v1map`),n[0],n[1]),o.uniform2f(c(`u_v0map`),r?r[0]:1,r?r[1]:0);let l=e.orientation===1?e.yAxis:e.xAxis,u=e.orientation===1?e.xAxis:e.yAxis;this._setAxisUniforms(s,`u_p`,e.posMeta,l),this._setAxisUniforms(s,`u_v1`,e.value1Meta,u),this._setAxisUniforms(s,`u_v0`,e.value0Meta,u),o.uniform1i(c(`u_pmode`),this._axisMode(l)),o.uniform1i(c(`u_vmode`),this._axisMode(u)),o.uniform1f(c(`u_width`),e.width),o.uniform1i(c(`u_orientation`),e.orientation),o.uniform1i(c(`u_v0Mode`),e.value0Mode),o.uniform1f(c(`u_v0Const`),i??0),o.uniform1f(c(`u_v0EdgePad`),a),o.uniform1f(c(`u_animationProgress`),e._transitionGrow??1);let d=!!(e._transitionPrevPosBuf&&e._transitionPrevValue1Buf&&e._transitionPrevValue0Buf);o.uniform1i(c(`u_transitionActive`),+!!d),o.uniform1f(c(`u_transitionProgress`),e._transitionPositionProgress??1),o.uniform1f(c(`u_prevWidth`),e._transitionPrevWidth??e.width);let[f,p,m,h]=e.color;o.uniform4f(c(`u_color`),f,p,m,h),o.uniform1f(c(`u_opacity`),this._fillOpacity(e.trace.style)*(e._transitionOpacity??1)),o.uniform1i(c(`u_colorMode`),e.colorMode||0),this._setRectStyleUniforms(s,e);let g=e.value0Mode===1&&e.value0Buf,_=!!e.cBuf,v=!!e.rgbaBuf,y=!!e.styleBuf,b=!!e.strokeBuf,x=!!e.radiusBuf;_&&(o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,e.lut),o.uniform1i(c(`u_lut`),0)),this._bindVao(e,`bars`,[e.posBuf._fcId,e.value1Buf._fcId,g?e.value0Buf._fcId:0,_?e.cBuf._fcId:0,d?e._transitionPrevPosBuf._fcId:0,d?e._transitionPrevValue1Buf._fcId:0,d?e._transitionPrevValue0Buf._fcId:0,v?e.rgbaBuf._fcId:0,y?e.styleBuf._fcId:0,b?e.strokeBuf._fcId:0,x?e.radiusBuf._fcId:0],()=>{this._vaoAttr(F.a_pos,e.posBuf,0,1),this._vaoAttr(F.a_v1,e.value1Buf,0,1),g&&this._vaoAttr(F.a_v0,e.value0Buf,0,1),_&&this._vaoAttr(F.a_cval,e.cBuf,0,1),d&&(this._vaoAttr(F.a_prevx,e._transitionPrevPosBuf,0,1),this._vaoAttr(F.a_prevy,e._transitionPrevValue1Buf,0,1),this._vaoAttr(F.a_prevx1,e._transitionPrevValue0Buf,0,1)),v&&this._vaoAttr(F.a_rgba,e.rgbaBuf,0,1,4,!0),y&&this._vaoAttr(F.a_style,e.styleBuf,0,1,4),b&&this._vaoAttr(F.a_stroke,e.strokeBuf,0,1,4,!0),x&&this._vaoAttr(F.a_radius,e.radiusBuf,0,1,2)}),g||o.vertexAttrib1f(F.a_v0,0),_||o.vertexAttrib1f(F.a_cval,0),v||o.vertexAttrib4f(F.a_rgba,f,p,m,h),y||o.vertexAttrib4f(F.a_style,1,-1,-1,-1),b||o.vertexAttrib4f(F.a_stroke,...e.strokeColor||e.color),x||o.vertexAttrib2f(F.a_radius,-1,-1),o.drawArraysInstanced(o.TRIANGLE_STRIP,0,4,e.n)}_dataPxX(e){return this._dataPx(`x`,e)}_dataPxY(e){return this._dataPx(`y`,e)}_styleNumber(e,t,n){if(!e||typeof e!=`object`)return n;let r=Number(e[t]);return Number.isFinite(r)?r:n}_axisStyleNumber(e,t,n){return this._styleNumber(e&&e.style,t,n)}_axisStylePaint(e,t,n){let r=e&&typeof e.style==`object`?e.style:null;return E(this.root,r&&r[t],n)}_axisStyleValue(e,t){let n=e&&typeof e.style==`object`?e.style:null;return n&&Object.prototype.hasOwnProperty.call(n,t)?n[t]:void 0}_axisGridDash(e){let t=String(this._axisStyleValue(e,`grid_dash`)||`solid`);return t===`dashed`?[6,4]:t===`dotted`?[1,3]:t===`dashdot`?[6,3,1,3]:[]}_axisTickLabelStrategy(e){let t=String(e&&e.tick_label_strategy||`auto`).replace(/-/g,`_`);return[`auto`,`hide`,`rotate`,`stagger`,`none`,`off`].includes(t)?t:`auto`}_axisTickLabelAnchor(e){let t=e&&e.tick_label_anchor!==void 0?e.tick_label_anchor:this._axisStyleValue(e,`tick_label_anchor`);if(t==null)return null;let n=String(t).toLowerCase();return n===`start`||n===`left`?`start`:n===`end`||n===`right`?`end`:n===`center`||n===`middle`?`center`:null}_axisTickLabelAngle(e){let t=Number(e?e.tick_label_angle:void 0);return Number.isFinite(t)?t:null}_axisTickLabelMinGap(e,t){let n=Number(e?e.tick_label_min_gap:void 0);return Number.isFinite(n)&&n>=0?n:t===`x`?8:4}_estimateTickLabel(e,t){let n=String(e||``);return{w:Math.max(t*.7,n.length*t*.62),h:t*1.2}}_tickLabelExtent(e,t,n){let r=this._estimateTickLabel(e.text,n),i=Math.abs(Number(e.angle||0))*Math.PI/180;return t===`y`?Math.abs(Math.sin(i))*r.w+Math.abs(Math.cos(i))*r.h:Math.abs(Math.cos(i))*r.w+Math.abs(Math.sin(i))*r.h}_tickLabelsCollide(e,t,n,r,i=`center`){let a=new Map;for(let t of e){let e=Number(t.row||0);a.has(e)||a.set(e,[]),a.get(e).push(t)}for(let e of a.values()){if(e.sort((e,t)=>e.pos-t.pos),t===`x`&&i!==`center`){for(let t=1;tt%a===0);if(!this._tickLabelsCollide(o,t,n,r,i))return o}return e.slice(0,1)}_layoutTickLabels(e,t,n){let r=this._axisTickLabelStrategy(e);if(r===`none`||r===`off`)return[];if(n.length<=1){let t=this._axisTickLabelAngle(e);return n.map(e=>({...e,angle:t===null?0:t,row:0}))}let i=Math.max(8,this._axisStyleNumber(e,`tick_label_size`,this._axisStyleNumber(e,`tick_size`,11))),a=this._axisTickLabelMinGap(e,t),o=t===`x`?this._axisTickLabelAnchor(e)??`center`:`center`,s=this._axisTickLabelAngle(e),c=s===null?0:s,l=n.map(e=>({...e,angle:c,row:0})),u=r;if(u===`auto`){if(!this._tickLabelsCollide(l,t,i,a,o))return l;u=t===`x`&&e.kind===`category`&&n.length<=16?`rotate`:t===`x`&&n.length<=24?`stagger`:`hide`}let d=l;if(u===`rotate`&&t===`x`){let t=s===null?e.side===`top`?35:-35:s;d=n.map(e=>({...e,angle:t,row:0}))}else u===`stagger`&&t===`x`&&(d=n.map((e,t)=>({...e,angle:c,row:t%2})));return this._tickLabelsCollide(d,t,i,a,o)&&(d=this._downsampleTickLabels(d,t,i,a,o)),d}_xTickLabelTransform(e,t){let n=Number(t||0),r=e&&e.side===`top`?`top`:`bottom`,i=this._axisTickLabelAnchor(e);if(i){let e=i===`end`?`-100%`:i===`start`?`0%`:`-50%`,t=i===`end`?`right`:i===`start`?`left`:`center`;return{transform:`translateX(${e}) rotate(${n}deg)`,origin:`${t} ${r===`top`?`bottom`:`top`}`}}if(n===0)return{transform:`translateX(-50%)`,origin:r===`top`?`bottom center`:`top center`};let a=r===`bottom`&&n<0||r===`top`&&n>0,o=r===`top`?`bottom`:`top`;return{transform:`${a?`translateX(-100%) `:``}rotate(${n}deg)`,origin:`${o} ${a?`right`:`left`}`}}_axisLabelCss(e,t,n){let r=e&&e.label_position,i=r!=null,a=e&&Number.isFinite(Number(e.label_offset)),o=e&&Number.isFinite(Number(e.label_angle));if(!i&&!a&&!o)return{css:n,style:null};if(r&&typeof r==`object`&&!Array.isArray(r))return{css:`font-weight:500;white-space:nowrap;`,style:r};let s=this.plot,c=String(i?r:`center`).replace(/-/g,`_`),l=c.startsWith(`inside_`),u=l?c.slice(7):c,d=a?Number(e.label_offset):0,f=e&&e.side,p=u===`start`?0:u===`end`?1:.5;if(t===`x`){let t=s.x+s.w*p,n=f===`top`?s.y-34:s.y+s.h+24,r=f===`top`?s.y+12:s.y+s.h-12;return{css:`left:${t}px;top:${(l?r:n)+(f===`top`?l?d:-d:l?-d:d)}px;transform:translateX(${u===`start`?0:u===`end`?-100:-50}%) rotate(${o?Number(e.label_angle):0}deg);transform-origin:center;font-weight:500;white-space:nowrap;`,style:null}}let m=f===`right`?s.x+s.w+40:10,h=f===`right`?s.x+s.w-12:s.x+12;return{css:`left:${(l?h:m)+(f===`right`?l?-d:d:l?d:-d)}px;top:${s.y+s.h*(1-p)}px;transform:translate(-50%,-50%) rotate(${o?Number(e.label_angle):f===`right`?90:-90}deg);transform-origin:center;font-weight:500;white-space:nowrap;`,style:null}}_drawChrome(){let e=this.spec,t=this.dpr,n=this.chrome.getContext(`2d`);n.setTransform(t,0,0,t,0,0),n.clearRect(0,0,this.size.w,this.size.h);let r=this._now(),i=this._viewAnim?80:0,a=i===0||this._lastLabelDraw===null||r-this._lastLabelDraw>=i;a&&(this.labels.textContent=``,this._lastLabelDraw=r);let o=this.plot;this.theme.bg&&(n.fillStyle=C(this.theme.bg),n.fillRect(o.x,o.y,o.w,o.h));let s=this._axis(`x`),c=this._axis(`y`),l=Object.values(this.axes).filter(e=>e&&e.id!==`x`&&String(e.id||``).startsWith(`x`)),u=Object.values(this.axes).filter(e=>e&&e.id!==`y`&&String(e.id||``).startsWith(`y`)),d=this._axisTickLabelStrategy(s)===`none`,f=this._axisTickLabelStrategy(c)===`none`,p=this._axisTicks(`x`,this._axisTickTarget(`x`,Math.max(3,o.w/(s.kind===`time`?90:80)))),m=this._axisTicks(`y`,this._axisTickTarget(`y`,Math.max(3,o.h/45))),h=e=>Math.min(o.x+o.w-.5,Math.max(o.x+.5,Math.round(e)+.5)),g=e=>Math.min(o.y+o.h-.5,Math.max(o.y+.5,Math.round(e)+.5));n.strokeStyle=this._axisStylePaint(s,`grid_color`,this.theme.grid),n.lineWidth=Math.max(.5,this._axisStyleNumber(s,`grid_width`,1)),n.globalAlpha=this._axisStyleNumber(s,`grid_opacity`,1),n.setLineDash(this._axisGridDash(s)),n.beginPath();for(let e of d?[]:p.ticks){let t=this._dataPx(`x`,e);if(!Number.isFinite(t))continue;let r=h(t);n.moveTo(r,o.y),n.lineTo(r,o.y+o.h)}n.stroke(),n.strokeStyle=this._axisStylePaint(c,`grid_color`,this.theme.grid),n.lineWidth=Math.max(.5,this._axisStyleNumber(c,`grid_width`,1)),n.globalAlpha=this._axisStyleNumber(c,`grid_opacity`,1),n.setLineDash(this._axisGridDash(c)),n.beginPath();for(let e of f?[]:m.ticks){let t=this._dataPx(`y`,e);if(!Number.isFinite(t))continue;let r=g(t);n.moveTo(o.x,r),n.lineTo(o.x+o.w,r)}n.stroke(),n.globalAlpha=1,n.setLineDash([]);let _=this.overlay.getContext(`2d`);if(_.setTransform(t,0,0,t,0,0),_.clearRect(0,0,this.size.w,this.size.h),this._drawAnnotationShapes(_),a){let t=(e,t,n,r,i,a=`axis_color`)=>{let o=document.createElement(`div`);o.style.cssText=`position:absolute;left:${t}px;top:${n}px;width:${r}px;height:${i}px;background:${this._axisStylePaint(e,a,this.theme.axis)};pointer-events:none;`,this.labels.appendChild(o)},n=Array.isArray(e.frame_sides)?e.frame_sides:[s.side||`bottom`,c.side||`left`];if(!f){let e=Math.max(1,this._axisStyleNumber(c,`axis_width`,1));n.includes(`left`)&&t(c,o.x,o.y,e,o.h),n.includes(`right`)&&t(c,o.x+o.w-e,o.y,e,o.h)}if(!d){let e=Math.max(1,this._axisStyleNumber(s,`axis_width`,1));n.includes(`top`)&&t(s,o.x,o.y,o.w,e),n.includes(`bottom`)&&t(s,o.x,o.y+o.h-e,o.w,e)}for(let e of l){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=Math.max(1,this._axisStyleNumber(e,`axis_width`,1)),r=e.side===`top`?o.y:o.y+o.h-n;t(e,o.x,r,o.w,n)}for(let e of u){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=Math.max(1,this._axisStyleNumber(e,`axis_width`,1));t(e,e.side===`left`?o.x:o.x+o.w-n,o.y,n,o.h)}let r=e=>{let t=Math.max(0,this._axisStyleNumber(e,`tick_length`,0)),n=Math.max(.5,this._axisStyleNumber(e,`tick_width`,1)),r=String(this._axisStyleValue(e,`tick_direction`)||`out`);return r===`in`?{inward:t,outward:0,width:n}:r===`inout`?{inward:t/2,outward:t/2,width:n}:{inward:0,outward:t,width:n}};if(!d){let e=r(s),n=s.side||`bottom`,i=n===`top`?o.y:o.y+o.h;for(let r of p.ticks){let a=this._dataPx(`x`,r);if(!Number.isFinite(a)||ao.x+o.w+1)continue;let c=n===`top`?i-e.outward:i-e.inward;t(s,a-e.width/2,c,e.width,e.inward+e.outward,`tick_color`)}}if(!f){let e=r(c),n=c.side||`left`,i=n===`right`?o.x+o.w:o.x;for(let r of m.ticks){let a=this._dataPx(`y`,r);!Number.isFinite(a)||ao.y+o.h+1||t(c,n===`right`?i-e.inward:i-e.outward,a-e.width/2,e.inward+e.outward,e.width,`tick_color`)}}for(let e of l){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.w/(e.kind===`time`?90:80)))),i=r(e),a=e.side||`bottom`,s=a===`top`?o.y:o.y+o.h;for(let r of n.ticks){let n=this._dataPx(e.id,r);if(!Number.isFinite(n)||no.x+o.w+1)continue;let c=a===`top`?s-i.outward:s-i.inward;t(e,n-i.width/2,c,i.width,i.inward+i.outward,`tick_color`)}}for(let e of u){if(this._axisTickLabelStrategy(e)===`none`)continue;let n=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.h/45))),i=r(e),a=e.side||`right`,s=a===`right`?o.x+o.w:o.x;for(let r of n.ticks){let n=this._dataPx(e.id,r);!Number.isFinite(n)||no.y+o.h+1||t(e,a===`right`?s-i.inward:s-i.outward,n-i.width/2,i.inward+i.outward,i.width,`tick_color`)}}}let v=(e,t,n,r=`tick`,i=null)=>{if(!a)return;let o=document.createElement(`div`);o.textContent=e,o.dataset.xyLabelKind=r,o.dataset.xyAxis=n&&n.id!==void 0?String(n.id):``,o.dataset.xyAxisSide=n&&n.side?String(n.side):``;let s=r===`label`?`label_color`:this._axisStyleValue(n,`tick_label_color`)===void 0?`tick_color`:`tick_label_color`,c=r===`label`?`label_size`:this._axisStyleValue(n,`tick_label_size`)===void 0?`tick_size`:`tick_label_size`,l=``;this._axisStyleValue(n,s)!==void 0&&(l=`color:${this._axisStylePaint(n,s,this.theme.label)};`);let u=``;this._axisStyleValue(n,c)!==void 0&&(u=`font-size:${Math.max(8,this._axisStyleNumber(n,c,11))}px;`),o.style.cssText=`position:absolute;line-height:1.2;white-space:nowrap;${l}${u}${t}`,this._applySlot(o,r===`label`?`axis_title`:`tick_label`),this._applyStyle(o,i),this.labels.appendChild(o)},y=[];for(let e of p.labels||p.ticks){let t=this._dataPx(`x`,e);if(to.x+o.w+1)continue;let n=this._axisTickText(s,e,p.step);y.push({pos:t,text:n})}let b=this._axisStyleNumber(s,`tick_label_size`,this._axisStyleNumber(s,`tick_size`,11));for(let e of this._layoutTickLabels(s,`x`,y)){let t=Number(e.row||0)*(Math.max(8,b)+4),n=s.side===`top`?o.y-18-t:o.y+o.h+6+t,r=this._xTickLabelTransform(s,e.angle);v(e.text,`left:${e.pos}px;top:${n}px;transform:${r.transform};transform-origin:${r.origin};`,s)}for(let e of l){let t=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.w/(e.kind===`time`?90:80)))),n=[];for(let r of t.labels||t.ticks){let i=this._dataPx(e.id,r);io.x+o.w+1||n.push({pos:i,text:this._axisTickText(e,r,t.step)})}for(let t of this._layoutTickLabels(e,`x`,n)){let n=this._axisStyleNumber(e,`tick_label_size`,this._axisStyleNumber(e,`tick_size`,11)),r=Number(t.row||0)*(Math.max(8,n)+4),i=e.side===`top`?o.y-18-r:o.y+o.h+6+r,a=this._xTickLabelTransform(e,t.angle);v(t.text,`left:${t.pos}px;top:${i}px;transform:${a.transform};transform-origin:${a.origin};`,e)}if(e.label&&this._axisTickLabelStrategy(e)!==`none`){let t=e.side===`top`?o.y-34:o.y+o.h+24,n=`left:${o.x+o.w/2}px;top:${t}px;transform:translateX(-50%);font-weight:500;`,r=this._axisLabelCss(e,`x`,n);v(e.label,r.css,e,`label`,r.style)}}let x=[];for(let e of m.labels||m.ticks){let t=this._dataPx(`y`,e);if(to.y+o.h+1)continue;let n=this._axisTickText(c,e,m.step);x.push({pos:t,text:n})}let S=(e,t,n)=>{let r=t?o.x+o.w+8:o.x-8,i=this._axisTickLabelAnchor(e)??(t?`start`:`end`),a=i===`end`?`-100%`:i===`start`?`0%`:`-50%`,s=i===`end`?`right`:i===`start`?`left`:`center`;return`left:${r}px;top:${n.pos}px;transform:translate(${a},-50%) rotate(${Number(n.angle||0)}deg);transform-origin:${s} center;`};for(let e of this._layoutTickLabels(c,`y`,x))v(e.text,S(c,c.side===`right`,e),c);for(let e of u){let t=this._axisTicks(e.id,this._axisTickTarget(e.id,Math.max(3,o.h/45))),n=[];for(let r of t.labels||t.ticks){let i=this._dataPx(e.id,r);if(io.y+o.h+1)continue;let a=this._axisTickText(e,r,t.step);n.push({pos:i,text:a})}for(let t of this._layoutTickLabels(e,`y`,n))v(t.text,S(e,e.side!==`left`,t),e);if(e.label&&this._axisTickLabelStrategy(e)!==`none`){let t=e.side===`left`?`left:10px;top:${o.y+o.h/2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:500;`:`left:${o.x+o.w+40}px;top:${o.y+o.h/2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:500;`,n=this._axisLabelCss(e,`y`,t);v(e.label,n.css,e,`label`,n.style)}}if(e.x_axis.label&&!d){let t=s.side===`top`?o.y-34:o.y+o.h+24,n=`left:${o.x+o.w/2}px;top:${t}px;transform:translateX(-50%);font-weight:500;`,r=this._axisLabelCss(s,`x`,n);v(e.x_axis.label,r.css,s,`label`,r.style)}if(e.y_axis.label&&!f){let t=c.side===`right`?`left:${o.x+o.w+40}px;top:${o.y+o.h/2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:500;`:`left:10px;top:${o.y+o.h/2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:500;`,n=this._axisLabelCss(c,`y`,t);v(e.y_axis.label,n.css,c,`label`,n.style)}this._drawAnnotationLabels(a)}_interactionTransitionActive(){let e=e=>e!=null;return!!this._viewAnim||this.gpuTraces.some(t=>e(t._densityFadeStart)||e(t._densitySwitchFadeStart)||e(t._drillFadeStart)||e(t._drillExitFadeStart)||!!t._densityNormAnim)}_renderPick(){let e=this.gl;(this._pickW!==this.canvas.width||this._pickH!==this.canvas.height)&&this._allocPickTex(),e.bindFramebuffer(e.FRAMEBUFFER,this.pickFbo),e.viewport(0,0,this.canvas.width,this.canvas.height),e.disable(e.BLEND),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT);let{x0:t,x1:n,y0:r,y1:i}=this.view,a=this.pickProg;e.useProgram(a);let o=t=>I(e,a,t);e.uniform1f(o(`u_dpr`),this.dpr);let s=1;for(let t of this.gpuTraces){let n=t.tier===`density`?t.drill&&!t._drillDying&&this._viewInside(t.drill.win)?t.drill:null:J(t.trace.kind).pointPick?t:null;if(!n||!n.n||s+n.n>2147483647){t.pickBase=-1,t.pickCount=0;continue}let[r,i]=this._axisRange(n.xAxis||t.xAxis),[c,l]=this._axisRange(n.yAxis||t.yAxis),u=this._map(n.xMeta,r,i,n.xAxis||t.xAxis),d=this._map(n.yMeta,c,l,n.yAxis||t.yAxis);e.uniform2f(o(`u_xmap`),u[0],u[1]),e.uniform2f(o(`u_ymap`),d[0],d[1]),this._setAxisUniforms(a,`u_x`,n.xMeta,n.xAxis||t.xAxis),this._setAxisUniforms(a,`u_y`,n.yMeta,n.yAxis||t.yAxis),e.uniform1f(o(`u_size`),n.size),e.uniform1i(o(`u_sizeMode`),n.sizeMode),e.uniform2f(o(`u_sizeRange`),n.sizeRange[0],n.sizeRange[1]);let f=!!(n._transitionPrevXBuf&&n._transitionPrevYBuf);e.uniform1i(o(`u_transitionActive`),+!!f),e.uniform1f(o(`u_transitionProgress`),n._transitionPositionProgress??1),e.uniform1i(o(`u_pick_base`),s),t.pickBase=s,t.pickCount=n.n;let p=n.sizeMode===1&&n.sBuf;this._bindVao(n,`pick`,[n.xBuf._fcId,n.yBuf._fcId,p?n.sBuf._fcId:0,f?n._transitionPrevXBuf._fcId:0,f?n._transitionPrevYBuf._fcId:0],()=>{this._vaoAttr(F.ax,n.xBuf,0,0),this._vaoAttr(F.ay,n.yBuf,0,0),p&&this._vaoAttr(F.a_sval,n.sBuf,0,0),f&&(this._vaoAttr(F.a_prevx,n._transitionPrevXBuf,0,0),this._vaoAttr(F.a_prevy,n._transitionPrevYBuf,0,0))}),p||e.vertexAttrib1f(F.a_sval,.5),e.drawArrays(e.POINTS,0,n.n),s+=n.n}e.enable(e.BLEND),e.bindFramebuffer(e.FRAMEBUFFER,null),this._pickDirty=!1}_pickAt(e,t){if(!this._pickable||this._glLost||!this.gl||this.gl.isContextLost())return null;if(this._pickDirty)try{this._renderPick()}catch(e){if(!this.gl||this.gl.isContextLost())return null;throw e}let n=this.gl,r=Math.round(e*this.dpr),i=Math.round((this.plot.h-t)*this.dpr);if(r<0||i<0||r>=this.canvas.width||i>=this.canvas.height)return null;let a=new Uint8Array(4);n.bindFramebuffer(n.FRAMEBUFFER,this.pickFbo),n.readPixels(r,i,1,1,n.RGBA,n.UNSIGNED_BYTE,a),n.bindFramebuffer(n.FRAMEBUFFER,null);let o=a[0]+a[1]*256+a[2]*65536+a[3]*16777216;if(o===0)return null;let s=this.gpuTraces.find(e=>e.pickBase>0&&o>=e.pickBase&&o=e.length?NaN:e[n]/(t.scale||1)+t.offset}_dataFromCanvas(e,t,n=`x`,r=`y`){let[i,a]=this._axisRange(n),[o,s]=this._axisRange(r),c=this._axis(n),l=this._axis(r),u=this._axisCoord(c,i),d=this._axisCoord(c,a),f=this._axisCoord(l,o),p=this._axisCoord(l,s);return[u,d,f,p].every(Number.isFinite)?[this._axisValue(c,u+e/this.plot.w*(d-u)),this._axisValue(l,p-t/this.plot.h*(p-f))]:[NaN,NaN]}_nearestCpuIndex(e,t){let n=e&&e._cpu;if(!n||!n.x||!n.x.length)return-1;let r=n.xMeta||e.xMeta,i=this._axis(e.xAxis),a=this._axisCoord(i,t),o=-1,s=1/0,c=Math.min(n.x.length,e.n||n.x.length);for(let t=0;t=l&&t<=u&&Math.abs(n-s)<=e.width/2)return{trace:e.trace.id,index:o,g:e,synthetic:!0}}else if(Math.abs(t-a)<=e.width/2&&n>=l&&n<=u)return{trace:e.trace.id,index:o,g:e,synthetic:!0}}return null}_rectHover(e,t,n){let r=e._cpuRect,i=Math.min(r.x0.length,r.x1.length,r.y0.length,r.y1.length,e.n||r.x0.length);for(let a=0;a=Math.min(i,o)&&t<=Math.max(i,o)&&n>=Math.min(s,c)&&n<=Math.max(s,c))return{trace:e.trace.id,index:a,g:e,synthetic:!0}}return null}_heatmapHover(e,t,n){let r=e.heatmap;if(!r||!e._cpuHeatmap)return null;let[i,a]=r.xRange,[o,s]=r.yRange;if(ta||ns)return null;let[c,l]=this._axisRange(e.xAxis)??[this.view.x0,this.view.x1],[u,d]=this._axisRange(e.yAxis)??[this.view.y0,this.view.y1],f=(c??this.view.x0)>(l??this.view.x1)?a-t:t-i,p=(u??this.view.y0)>(d??this.view.y1)?s-n:n-o,m=Math.min(r.w-1,Math.max(0,Math.floor(f/(a-i)*r.w))),h=Math.min(r.h-1,Math.max(0,Math.floor(p/(s-o)*r.h)));return{trace:e.trace.id,index:h*r.w+m,g:e,heatmap:{row:h,col:m},synthetic:!0}}_drawKeepPick(){this.draw(!0)}_hover(e){if(this._a11yKeyboardReadout=null,this._interactionTransitionActive()){let e=this._hoverId!==-1;this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._pickSeq=(this._pickSeq||0)+1,this._hideTooltip(),e&&this.draw();return}let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top,i=this._pickAt(n,r)||this._hoverAt(n,r);if(!i){let e=this._hoverId!==-1;this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._pickSeq=(this._pickSeq||0)+1,this._hideTooltip(),e&&this._drawKeepPick();return}let a=i.trace*1e9+i.index;if(this._lastHoverXY={clientX:e.clientX,clientY:e.clientY},a===this._hoverId){this._tooltipAnchor||this._renderTooltip(this._lastRow,e.clientX,e.clientY);return}this._hoverId=a,this._hoverTarget=i,this._showTooltip(i,e.clientX,e.clientY),this._drawKeepPick()}_asF32(e){return e instanceof ArrayBuffer?new Float32Array(e):e.byteOffset%4==0?new Float32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4)):new Float32Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength))}_asU8(e){return e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}_asU32(e){return e instanceof ArrayBuffer?new Uint32Array(e):e.byteOffset%4==0?new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4)):new Uint32Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength))}_applyTheme(){this.theme=S(this.root),this._themeStale=!this.root.isConnected;for(let e of this.gpuTraces)J(e.trace.kind).refreshColor?.(this,e)}refreshTheme(){this._destroyed||(this._applyTheme(),this.draw())}_healStaleTheme(){return!this._themeStale||!this.root.isConnected?!1:(this._applyTheme(),!0)}destroy(){if(this._destroyed)return;this._destroyed=!0,this._dataAnim&&this._emitAnimationLifecycle?.(`end`,this._dataAnim.phase,{cancelled:!0}),Z.unregister(this),this._ctxIo?.disconnect(),this._ctxIo=null,clearTimeout(this._ctxRecoveryTimer),this._ctxRecoveryTimer=null,clearTimeout(this._rebinTimer),this._rebinWorker&&=(this._rebinWorker.terminate(),this._rebinWorker._fcUrl&&URL.revokeObjectURL(this._rebinWorker._fcUrl),null),this._ro?.disconnect(),this._io?.disconnect(),this._io=null,this._themeWatch?.removeEventListener?.(`change`,this._onScheme),this._themeMutationObserver?.disconnect(),this._themeMutationObserver=null,this._dprMq?.removeEventListener?.(`change`,this._onDprChange),this._dprMq=null,this._unsubscribeComm?.(),this._unsubscribeComm=null;for(let{target:e,type:t,handler:n,options:r}of this._listeners.splice(0))e.removeEventListener(t,n,r);clearTimeout(this._viewTimer),this._viewTimer=null,this._viewEventRaf&&cancelAnimationFrame(this._viewEventRaf),this._viewEventRaf=null,this._wheelZoomRaf&&cancelAnimationFrame(this._wheelZoomRaf),this._wheelZoomRaf=null,this._pendingWheelZoom=null,clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null,this._wheelGesture=null,this._linkChannel?.close?.(),this._linkChannel=null,this._raf&&cancelAnimationFrame(this._raf),this._raf=null,this._resizeRaf&&cancelAnimationFrame(this._resizeRaf),this._resizeRaf=null,this._pendingResize=null,this._resizeNeedsMeasure=!1,this._cancelViewAnimation(),this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf),this._dataAnimRaf=null,this._dataAnim=null,this._destroyTransitionOldTraces?.(),this._destroyGlResources();let e=this.gl&&this.gl.getExtension(`WEBGL_lose_context`);e&&e.loseContext(),this.gl=null,this.root.remove()}_deleteBuffers(e,t){let n=this.gl;if(!n||!e)return;let r=new Set;for(let i of t){let t=e[i];t&&!r.has(t)&&(r.add(t),n.deleteBuffer(t)),e[i]=null}}_destroyTraceResources(e,t){if(!e)return;this._destroyDensitySample(e),this._deleteVaos(e),this._deleteVaos(e.drill),this._deleteBuffers(e,[`xBuf`,`yBuf`,`cBuf`,`sBuf`,`selBuf`,`baseBuf`,`x0Buf`,`x1Buf`,`x2Buf`,`y0Buf`,`y1Buf`,`y2Buf`,`posBuf`,`value1Buf`,`value0Buf`,`_transitionPrevXBuf`,`_transitionPrevYBuf`,`_transitionPrevPosBuf`,`_transitionPrevValue1Buf`,`_transitionPrevValue0Buf`]),this._deleteBuffers(e.drill,[`xBuf`,`yBuf`,`cBuf`,`sBuf`,`selBuf`,`dBuf`]);let n=[];e.heatmap&&n.push(e.heatmap.tex);for(let t of e.densityCache||[])n.push(t&&t.tex);e.density&&n.push(e.density.tex),e._shownDensity&&n.push(e._shownDensity.tex);for(let e of n)e&&!t.has(e)&&(t.add(e),this.gl.deleteTexture(e));e.drill=null,e.density=null,e._shownDensity=null,e.densityCache=[],e.heatmap=null,e._cpu=null}_destroyGlResources(){let e=this.gl;if(!e)return;let t=new Set;for(let e of this.gpuTraces||[])this._destroyTraceResources(e,t);for(let n of this._lutCache.values())n&&!t.has(n)&&(t.add(n),e.deleteTexture(n));this._lutCache.clear(),this.pickFbo&&e.deleteFramebuffer(this.pickFbo),this.pickTex&&!t.has(this.pickTex)&&e.deleteTexture(this.pickTex),this.pickFbo=null,this.pickTex=null,this.quad&&e.deleteBuffer(this.quad),this.quad=null,this.quadVao&&e.deleteVertexArray(this.quadVao),this.quadVao=null;for(let t of this._progCache?this._progCache.values():[])t&&e.deleteProgram(t);this._progCache&&this._progCache.clear(),this._glPrograms=this._progCache,this.gpuTraces=[]}},ut=new Set([`color`,`label_color`,`label_opacity`,`opacity`,`width`,`head_size`,`head_style`,`tail_style`,`shaft_width_start`,`shaft_width_end`,`curve`,`angle_a`,`angle_b`,`gap_start`,`gap_end`,`start_offset`,`label_clear`,`dash`,`span_start`,`span_end`,`size`,`symbol`,`stroke_color`,`stroke_width`,`coordinate_space`]);function dt(e,t){if(typeof e.label_clear!=`string`)return 0;let n=e.label_clear.split(`,`).map(Number);if(n.length!==4||n.some(e=>!Number.isFinite(e)||e<0))return 0;let[r,i,a,o]=n,[s,c]=t,l=s>1e-9?i/s:s<-1e-9?r/-s:1/0,u=c>1e-9?o/c:c<-1e-9?a/-c:1/0,d=Math.min(l,u);return Number.isFinite(d)?d:0}function ft(e,t,n,r,i){let a=e=>Number.isFinite(Number(e))?Number(e):null;if(typeof i.start_offset==`string`){let n=i.start_offset.split(`,`).map(Number);n.length===2&&n.every(Number.isFinite)&&(e+=n[0],t+=n[1])}let o=a(i.angle_a),s=a(i.angle_b),c=a(i.curve),l=null,u=null;if(o!==null&&s!==null){let i=-o*Math.PI/180,a=-s*Math.PI/180,c=Math.cos(i)*Math.sin(a)-Math.sin(i)*Math.cos(a);if(Math.abs(c)>1e-6){let o=((n-e)*Math.sin(a)-(r-t)*Math.cos(a))/c;l=e+o*Math.cos(i),u=t+o*Math.sin(i)}}else if(c){let i=n-e,a=r-t;l=(e+n)/2+c*a,u=(t+r)/2-c*i}let d=(e,t,n,r)=>{let i=Math.hypot(n-e,r-t)||1;return[(n-e)/i,(r-t)/i]},f=l===null?d(e,t,n,r):d(e,t,l,u),p=l===null?d(n,r,e,t):d(n,r,l,u),m=Math.max(0,a(i.gap_start)||0,dt(i,f)),h=Math.max(0,a(i.gap_end)||0),g=Math.hypot(n-e,r-t),_=m+h0)||e.length<2)return e;let n=e.slice(),r=t;for(;n.length>=2;){let[e,t]=n[n.length-2],[i,a]=n[n.length-1],o=Math.hypot(i-e,a-t);if(o>r){let s=1-r/o;return n[n.length-1]=[e+s*(i-e),t+s*(a-t)],n}r-=o,n.pop()}return n}function ht(e,t,n){let r=[],i=[],a=e.length;for(let o=0;o0&&e.stroke(),e.restore()},_drawArrowLine(e,t,n,r,i,a){if(![t,n,r,i].every(Number.isFinite))return;let o=ft(t,n,r,i,a);e.save(),e.globalAlpha=this._styleNumber(a,`opacity`,1),e.strokeStyle=this._annotationPaint(a,[.4,.44,.52,1]),e.fillStyle=e.strokeStyle,e.lineWidth=Math.max(.5,this._styleNumber(a,`width`,1.5)),e.setLineDash(Array.isArray(a.dash)?a.dash:typeof a.dash==`string`?a.dash.split(`,`).map(Number):[]);let s=Number(a.shaft_width_start),c=Number(a.shaft_width_end),l=a.head_style||`triangle`,u=Math.max(4,this._styleNumber(a,`head_size`,8));if(Number.isFinite(s)||Number.isFinite(c)){let t=pt(o);l===`triangle`&&(t=mt(t,u*Math.cos(Math.PI/6)));let n=ht(t,Number.isFinite(s)?s:1,Number.isFinite(c)?c:1);e.beginPath(),e.moveTo(n[0][0],n[0][1]);for(let t=1;t[a-i*Math.cos(s-e*Math.PI/6),o-i*Math.sin(s-e*Math.PI/6)],[l,u]=c(1),[d,f]=c(-1);if(r===`v`){e.moveTo(l,u),e.lineTo(a,o),e.lineTo(d,f),e.stroke();return}e.moveTo(a,o),e.lineTo(l,u),e.lineTo(d,f),e.closePath(),e.fill()},_drawAnnotationShapes(e){let t=Array.isArray(this.spec.annotations)?this.spec.annotations:[];if(!t.length)return;let n=this.plot;e.save(),e.beginPath(),e.rect(n.x,n.y,n.w,n.h),e.clip();for(let r of t){let t=r&&typeof r.style==`object`?r.style:{};if(r.kind===`band`){let i=r.axis===`x`,a=i?this._dataPxX(Number(r.start)):this._dataPxY(Number(r.start)),o=i?this._dataPxX(Number(r.end)):this._dataPxY(Number(r.end));if(!Number.isFinite(a)||!Number.isFinite(o))continue;let s=Math.max(i?n.x:n.y,Math.min(a,o)),c=Math.min(i?n.x+n.w:n.y+n.h,Math.max(a,o));if(c<=s)continue;e.save(),e.globalAlpha=this._styleNumber(t,`opacity`,.14),e.fillStyle=this._annotationPaint(t,[.39,.45,.55,1]);let l=Math.max(0,Math.min(1,Number(t.span_start)||0)),u=t.span_end===void 0?1:Number(t.span_end),d=Math.max(l,Math.min(1,Number.isFinite(u)?u:1));i?e.fillRect(s,n.y+(1-d)*n.h,c-s,(d-l)*n.h):e.fillRect(n.x+l*n.w,s,(d-l)*n.w,c-s),e.restore()}else if(r.kind===`rule`){let i=r.axis===`x`,a=i?this._dataPxX(Number(r.value)):this._dataPxY(Number(r.value));if(!Number.isFinite(a)||i&&(an.x+n.w+1)||!i&&(an.y+n.h+1))continue;let o=Math.round(a)+.5;e.save(),e.globalAlpha=this._styleNumber(t,`opacity`,1),e.strokeStyle=this._annotationPaint(t,[.4,.44,.52,1]),e.lineWidth=Math.max(.5,this._styleNumber(t,`width`,1.5)),e.setLineDash(Array.isArray(t.dash)?t.dash:typeof t.dash==`string`?t.dash.split(`,`).map(Number):[]),e.beginPath();let s=Math.max(0,Math.min(1,Number(t.span_start)||0)),c=t.span_end===void 0?1:Number(t.span_end),l=Math.max(s,Math.min(1,Number.isFinite(c)?c:1));i?(e.moveTo(o,n.y+(1-l)*n.h),e.lineTo(o,n.y+(1-s)*n.h)):(e.moveTo(n.x+s*n.w,o),e.lineTo(n.x+l*n.w,o)),e.stroke(),e.restore()}else if(r.kind===`arrow`)this._drawArrowLine(e,this._dataPxX(Number(r.x0)),this._dataPxY(Number(r.y0)),this._dataPxX(Number(r.x1)),this._dataPxY(Number(r.y1)),t);else if(r.kind===`callout`){let n=this._dataPxX(Number(r.x)),i=this._dataPxY(Number(r.y)),a=Number.isFinite(Number(r.dx))?Number(r.dx):0,o=Number.isFinite(Number(r.dy))?Number(r.dy):0;this._drawArrowLine(e,n+a,i+o,n,i,t)}else r.kind===`marker`&&this._drawAnnotationMarker(e,this._dataPxX(Number(r.x)),this._dataPxY(Number(r.y)),t,r)}e.restore()},_drawAnnotationLabels(e){if(!e)return;let t=Array.isArray(this.spec.annotations)?this.spec.annotations:[];if(!t.length)return;let n=this.plot;for(let e of t){let t=typeof e.text==`string`?e.text:``;if(!t)continue;let r=e&&typeof e.style==`object`?e.style:{},i=null,a=null,o=null;if(e.kind===`text`)r.coordinate_space===`axes_fraction`?(i=n.x+Number(e.x)*n.w,a=n.y+(1-Number(e.y))*n.h):r.coordinate_space===`figure_fraction`?(i=Number(e.x)*this.size.w,a=(1-Number(e.y))*this.size.h):r.coordinate_space===`yaxis_transform`?(i=n.x+Number(e.x)*n.w,a=this._dataPxY(Number(e.y))):r.coordinate_space===`xaxis_transform`?(i=this._dataPxX(Number(e.x)),a=n.y+(1-Number(e.y))*n.h):(i=this._dataPxX(Number(e.x)),a=this._dataPxY(Number(e.y)));else if(e.kind===`rule`)e.axis===`x`?(i=this._dataPxX(Number(e.value)),a=n.y+6):(i=n.x+n.w-6,a=this._dataPxY(Number(e.value)));else if(e.kind===`band`)e.axis===`x`?(i=(this._dataPxX(Number(e.start))+this._dataPxX(Number(e.end)))/2,a=n.y+6):(i=n.x+n.w-6,a=(this._dataPxY(Number(e.start))+this._dataPxY(Number(e.end)))/2);else if(e.kind===`arrow`){let t=this._dataPxX(Number(e.x0)),n=this._dataPxY(Number(e.y0)),r=this._dataPxX(Number(e.x1)),s=this._dataPxY(Number(e.y1));i=(t+r)/2,a=(n+s)/2;let c=Math.hypot(r-t,s-n);c>1e-6&&(o=[-(s-n)/c,(r-t)/c],o[1]>0&&(o=[-o[0],-o[1]]))}else(e.kind===`callout`||e.kind===`marker`)&&(i=this._dataPxX(Number(e.x)),a=this._dataPxY(Number(e.y)));if(!Number.isFinite(i)||!Number.isFinite(a)||in.x+n.w+24||an.y+n.h+24)continue;let s=document.createElement(`div`);s.textContent=t;let c=Number.isFinite(Number(e.dx))?Number(e.dx):0,l=Number.isFinite(Number(e.dy))?Number(e.dy):0,u=e.anchor,d=String(r.vertical_align||``);e.kind===`rule`||e.kind===`band`?e.axis===`x`?(!u&&e.kind===`band`&&(u=`middle`),d||=`top`):(u||=`end`,!d&&e.kind===`band`&&(d=`middle`)):e.kind===`arrow`&&(u||=`middle`,d||=`middle`);let f=u===`middle`?`-50%`:u===`end`?`-100%`:`0px`,p=Number.isFinite(Number(r.rotation))?(Number(r.rotation)%360+360)%360:0,m=d===`center`||d===`middle`?`-50%`:d===`bottom`?`-100%`:d===`top`?`0px`:`calc(-100% + 0.35em)`,h=`translate(${f},${m})`;if(p===90||p===270){let e=p===270;h=`rotate(${e?90:-90}deg) translate(${d===`center`||d===`middle`?`-50%`:d===`top`?e?`0`:`-100%`:d===`bottom`?e?`-100%`:`0`:e?`0`:`-100%`},${u===`middle`?`-50%`:u===`end`?e?`0`:`-100%`:e?`-100%`:`0`})`}else p&&(h=`rotate(${-p}deg) translate(${f},${m})`);s.style.cssText=`position:absolute;left:${i+c}px;top:${a+l}px;transform:${h};transform-origin:0 0;pointer-events:none;white-space:pre-line;text-align:center;width:max-content;`,this._applySlot(s,`annotation_label`),this._applyClass(s,e.class_name);let g=e.kind!==`text`&&e.kind!==`callout`,_={};for(let[t,n]of Object.entries(r)){if(t===`opacity`&&e.kind===`text`){_[t]=n;continue}ut.has(t)||g&&t===`opacity`||(_[t]=n)}if(this._applyStyle(s,_),r&&(r.label_color||r.color)&&(s.style.color=this._annotationLabelPaint(r,this.theme.label)),r&&r.label_opacity!==void 0){let e=Number(r.label_opacity);Number.isFinite(e)&&(s.style.opacity=String(Math.max(0,Math.min(1,e))))}this.labels.appendChild(s);let v=getComputedStyle(s),y=(e,t)=>(parseFloat(e)||0)+(parseFloat(t)||0),b=y(v.paddingLeft,v.borderLeftWidth),x=y(v.paddingRight,v.borderRightWidth),S=y(v.paddingTop,v.borderTopWidth),C=y(v.paddingBottom,v.borderBottomWidth);if((b||x||S||C)&&p!==90&&p!==270){let e=f===`-100%`?x:f===`-50%`?0:-b,t=m===`-50%`?0:m===`0px`?-S:C;s.style.transform=`${p?`rotate(${-p}deg) `:``}translate(calc(${f} + ${e}px), calc(${m} + ${t}px))`}let w=o&&this.labels.getBoundingClientRect();if(o&&w.width>0){let e=w.width/this.size.w,t=s.getBoundingClientRect(),n=t.width/e/2*Math.abs(o[0])+t.height/e/2*Math.abs(o[1])+3;i+=o[0]*n,a+=o[1]*n,s.style.left=`${i+c}px`,s.style.top=`${a+l}px`}let T=this.labels.getBoundingClientRect();if(T.width>0){let e=T.width/this.size.w,t=s.getBoundingClientRect(),n=t.right>T.right?T.right-t.right:t.leftT.bottom?T.bottom-t.bottom:t.top=0&&t=0&&tt.trace===e.trace)||r[0];if(!t||!Number.isFinite(Number(t.trace)))continue;let i=this.gpuTraces.find(e=>e.trace.id===t.trace);if(!i)continue;let a=Number.isInteger(e.index)&&t.trace===e.trace?e.index:-1;!i._cpuHeatmap&&(a<0||!i._cpu||!i._cpu.x||a>=i._cpu.x.length)&&(a=this._nearestCpuIndex(i,e.x));let[o,s]=this._sourceValue(i,t,a);o!==void 0&&(e[n]=o,s!==void 0&&(e[`${n}_kind`]=s))}},_denormalizeUnit(e,t){let n=Number(e);if(!Number.isFinite(n)||!Array.isArray(t)||t.length<2)return n;let r=Number(t[0]),i=Number(t[1]);return!Number.isFinite(r)||!Number.isFinite(i)?n:r+n*(i-r)},_defaultTooltipLines(e){let t=[];return e.x!==void 0&&t.push(`x: ${P(e.x,e.x_kind)}`),e.y!==void 0&&t.push(`y: ${P(e.y,e.y_kind)}`),e.color_value!==void 0&&t.push(`color: ${P(e.color_value)}`),e.color_category!==void 0&&t.push(`${e.color_category}`),e.size_value!==void 0&&t.push(`size: ${P(e.size_value)}`),t.length||t.push(`#${e.index}`),t},_tooltipLookup(e,t){let n=this.spec.tooltip&&this.spec.tooltip.aliases||{},r=e[t]===void 0?n[t]:t;return!r||e[r]===void 0?[void 0,void 0]:[e[r],e[`${r}_kind`]]},_formatTooltipValue(e,t,n){let r=ae(e,n);return r===null?P(e,t):r},_tooltipLines(e){let t=this.spec.tooltip||{};if(!t.title&&!Array.isArray(t.fields))return this._defaultTooltipLines(e);let n=t.format||{},r=[];if(typeof t.title==`string`){let i=t.title.replace(/\{([^}]+)\}/g,(t,r)=>{let[i,a]=this._tooltipLookup(e,r);return i===void 0?``:this._formatTooltipValue(i,a,n[r])});i&&r.push(i)}if(Array.isArray(t.fields))for(let i of t.fields){if(typeof i!=`string`)continue;let[t,a]=this._tooltipLookup(e,i);t!==void 0&&r.push(`${i}: ${this._formatTooltipValue(t,a,n[i])}`)}return r.length?r:this._defaultTooltipLines(e)},_setTooltipAnchor(e,t,n,r){let i=e.g;if(!i){this._tooltipAnchor=null;return}let a=i.xAxis||`x`,o=i.yAxis||`y`,s=t.x,c=t.y;if(!Number.isFinite(s)||!Number.isFinite(c)){let e=this.canvas.getBoundingClientRect();[s,c]=this._dataFromCanvas(n-e.left,r-e.top,a,o)}this._tooltipAnchor=Number.isFinite(s)&&Number.isFinite(c)?{xAxis:a,yAxis:o,x:s,y:c}:null,this._tooltipAnchor&&!this._tooltipAnchorPx()&&(this._tooltipAnchor=null)},_tooltipAnchorPx(){let e=this._tooltipAnchor;if(!e)return null;let t=this._dataPx(e.xAxis,e.x),n=this._dataPx(e.yAxis,e.y),r=this.plot;return!Number.isFinite(t)||!Number.isFinite(n)||tr.x+r.w||nr.y+r.h?null:{lx:t,ly:n}},_hideTooltip(){this.tooltip.style.display=`none`,this._tooltipAnchor=null},_repositionTooltip(){if(!this._tooltipAnchor)return;let e=this._tooltipAnchorPx();if(!e){this.tooltip.style.display=`none`;return}this.tooltip.style.display=`block`,this._placeTooltip(e.lx,e.ly)},_placeTooltip(e,t){let n=this.tooltip.offsetWidth,r=this.tooltip.offsetHeight,i=Math.max(4,this.size.w-n-4),a=Math.max(4,Math.min(e+12,i)),o=t+12,s=t-r-12,c=o+r<=this.size.h-4?o:Math.max(4,s);this.tooltip.style.left=a+`px`,this.tooltip.style.top=c+`px`},_renderTooltip(e,t,n,r={}){if(!e||this.spec.show_tooltip===!1){this._hideTooltip();return}let i=this._tooltipLines(e);if(this._customTooltip||(this.tooltip.textContent=``,i.forEach((e,t)=>{t&&this.tooltip.appendChild(document.createElement(`br`)),this.tooltip.appendChild(document.createTextNode(e))})),this.a11yLive&&r.announce!==!1){let e=this._a11yKeyboardReadout,t=i.join(`, `),n=e?`Point ${e.flat+1} of ${e.total}. ${t}`:t;this.a11yLive.textContent!==n&&(this.a11yLive.textContent=n)}this.tooltip.style.display=`block`;let a=this._tooltipAnchorPx();if(a)this._placeTooltip(a.lx,a.ly);else if(this._tooltipAnchor)this.tooltip.style.display=`none`;else{let e=this.root.getBoundingClientRect();this._placeTooltip(t-e.left,n-e.top)}}}),Object.assign(Q.prototype,{_initInteraction(){let e=this.canvas,t=null,n=null;this.selRect=document.createElement(`div`),this.selRect.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:4;`,this._applySlot(this.selRect,`selection`),this.root.appendChild(this.selRect),this.selLasso=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`),this.selLasso.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:4;overflow:visible;`,this.selLasso.dataset.xySelectionLassoOverlay=``,this.selLassoPath=document.createElementNS(`http://www.w3.org/2000/svg`,`path`),this.selLassoPath.dataset.xySelectionLasso=``,this.selLasso.appendChild(this.selLassoPath),this.selLassoHandles=document.createElementNS(`http://www.w3.org/2000/svg`,`g`),this.selLassoHandles.dataset.xySelectionLassoHandles=``,this.selLasso.appendChild(this.selLassoHandles),this.root.appendChild(this.selLasso),this._lassoPolygon=null;let r=null,i=t=>{if(!r||t.pointerId!==r.pointerId||!this._lassoPolygon)return;let n=e.getBoundingClientRect(),i=Math.max(0,Math.min(n.width,t.clientX-n.left)),a=Math.max(0,Math.min(n.height,t.clientY-n.top));this._lassoPolygon[r.index]=this._dataFromCanvas(i,a),this._renderLassoSelection(),t.preventDefault(),t.stopPropagation()};this._listen(this.selLasso,`pointerdown`,e=>{let t=e.target.closest?.(`[data-xy-selection-lasso-handle]`);if(!t||!this._lassoPolygon)return;let n=Number(t.dataset.xySelectionLassoHandle);if(!(!Number.isInteger(n)||!this._lassoPolygon[n])){r={index:n,pointerId:e.pointerId,original:[...this._lassoPolygon[n]],handle:t},t.dataset.xyActive=``,this._hideTooltip();try{this.selLasso.setPointerCapture(e.pointerId)}catch{}e.preventDefault(),e.stopPropagation()}}),this._listen(this.selLasso,`pointermove`,i),this._listen(this.selLasso,`pointerup`,e=>{if(!r||e.pointerId!==r.pointerId)return;i(e);let t=r.handle;r=null,delete t.dataset.xyActive,this._lassoPolygon&&this._sendSelectPolygon(this._lassoPolygon)}),this._listen(this.selLasso,`pointercancel`,e=>{!r||e.pointerId!==r.pointerId||(this._lassoPolygon&&(this._lassoPolygon[r.index]=r.original),delete r.handle.dataset.xyActive,r=null,this._lassoPolygon&&this._renderLassoSelection(),e.stopPropagation())}),this._interactionFlag(`crosshair`)&&(this.crosshairX=document.createElement(`div`),this.crosshairX.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:3;width:1px;`,this._applySlot(this.crosshairX,`crosshair_x`),this.root.appendChild(this.crosshairX),this.crosshairY=document.createElement(`div`),this.crosshairY.style.cssText=`position:absolute;display:none;pointer-events:none;z-index:3;height:1px;`,this._applySlot(this.crosshairY,`crosshair_y`),this.root.appendChild(this.crosshairY));let a=(t,n)=>{let r=e.getBoundingClientRect();return this._dataFromCanvas(t-r.left,n-r.top)},o=(t,n)=>{let r=e.getBoundingClientRect(),i=Math.max(0,Math.min(r.width,t-r.left)),a=Math.max(0,Math.min(r.height,n-r.top));return{x:r.left+i,y:r.top+a,data:this._dataFromCanvas(i,a)}};this._listen(e,`pointerdown`,r=>{this._cancelViewAnimation();let i=this._interactionFlag(`pan`,!0),s=this._interactionFlag(`zoom`,!0),c=this._interactionFlag(`navigation`,!0),l=this._interactionFlag(`box_zoom`,!0),u=this._interactionFlag(`brush`,!0)&&this._interactionFlag(`select`,!0),d=this.dragMode.startsWith(`select`)?this.dragMode:null,f=(r.shiftKey||d)&&u&&this._pickable?r.shiftKey?`select`:d:this.dragMode===`zoom`&&c&&s&&l?`zoom`:null;if(f){let t=f.startsWith(`select`)&&this._lassoPolygon?this._lassoPolygon.map(e=>[...e]):null;f.startsWith(`select`)&&this._clearLassoOverlay();let i=f===`select-lasso`?o(r.clientX,r.clientY):null,s=i?i.data:a(r.clientX,r.clientY);n={mode:f,sx:r.clientX,sy:r.clientY,d0:s,points:i?[i]:null,previousLasso:t};try{e.setPointerCapture(r.pointerId)}catch{}this._hideTooltip();return}if(this.dragMode===`pan`&&c&&i){t={px:r.clientX,py:r.clientY,view:this._copyView(this.view),moved:!1,interactionId:++this._interactionSeq,axes:[...new Set([...this._axisPolicy(`pan_axes`),...this._axisIds().filter(e=>this._axisContained(e))])],changedAxes:[]};try{e.setPointerCapture(r.pointerId)}catch{}this._hideTooltip()}}),this._listen(e,`pointermove`,e=>{if(n){this._updateBand(n,e);return}if(t){t.moved=!0;let n=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,t.view)]]));for(let r of t.axes){let i=this._axis(r),[a,o]=this._axisRange(r,t.view),s=this._axisCoord(i,a),c=this._axisCoord(i,o);if(![s,c].every(Number.isFinite)||s===c)continue;let l=this._axisDim(r),u=l===`x`?this.plot.w:this.plot.h,d=(l===`x`?e.clientX-t.px:e.clientY-t.py)/u*(c-s),f=l===`x`?-d:d;n[r]=[this._axisValue(i,s+f),this._axisValue(i,c+f)]}let r=this._setView({ranges:n},{source:`pan_drag`,phase:`update`,interactionId:t.interactionId});t.changedAxes=[...new Set([...t.changedAxes,...r])];return}this._updateCrosshair(e),this._hover(e)}),this._listen(e,`pointerup`,e=>{if(n){n.mode===`select-lasso`&&this._updateBand(n,e),this.selRect.style.display=`none`,this.selLasso.style.display=`none`;let t=a(e.clientX,e.clientY);if(n.mode===`select-lasso`?n.points.length>=3:Math.abs(e.clientX-n.sx)>3||Math.abs(e.clientY-n.sy)>3){if(n.mode===`zoom`&&this._interactionFlag(`zoom`,!0))this._zoomToBox(n.d0,t,!0,{source:`box_zoom`,phase:`end`,interactionId:++this._interactionSeq});else if(n.mode===`select-lasso`)if(n.points.length>=3){let e=this._simplifyLassoPoints(n.points);this._sendSelectPolygon(e.map(e=>e.data))}else n.previousLasso&&(this._lassoPolygon=n.previousLasso,this._renderLassoSelection());else{let e=n.d0;n.mode===`select-x`?(e=[n.d0[0],this.view.y0],t[1]=this.view.y1):n.mode===`select-y`&&(e=[this.view.x0,n.d0[1]],t[0]=this.view.x1),this._sendSelect(e,t)}this._ignoreNextClick=!0}else n.previousLasso&&(this._lassoPolygon=n.previousLasso,this._renderLassoSelection());n=null;return}t&&t.moved&&(this._ignoreNextClick=!0,t.changedAxes.length&&this._emitViewChange(`pan_drag`,{axes:t.changedAxes,phase:`end`,interactionId:t.interactionId})),t&&!t.moved&&this._hideTooltip(),t=null}),this._listen(e,`pointercancel`,()=>{this.selRect.style.display=`none`,this.selLasso.style.display=`none`,n?.previousLasso&&(this._lassoPolygon=n.previousLasso,this._renderLassoSelection()),n=null,t=null}),this._listen(e,`pointerleave`,()=>this._pointerHoverExit()),this._listen(document,`pointerover`,e=>{!this._lastHoverXY||this._a11yKeyboardReadout||this.root.contains(e.target)||this._pointerHoverExit()}),this._listen(e,`click`,e=>this._click(e)),this._listen(e,`wheel`,t=>{if(!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._interactionFlag(`wheel_zoom`,!0))return;t.preventDefault();let n=1.0015**t.deltaY,r=e.getBoundingClientRect(),i=(t.clientX-r.left)/r.width,a=1-(t.clientY-r.top)/r.height;this._queueWheelZoom(n,i,a)},{passive:!1}),this._listen(e,`dblclick`,()=>{this._interactionFlag(`navigation`,!0)&&this._interactionFlag(`double_click_reset`,!0)&&this._resetView(!0,`reset`)}),this._listen(e,`keydown`,e=>{e.key===`Escape`&&(n||t)&&(this.selRect.style.display=`none`,this.selLasso.style.display=`none`,n=null,t=null,e.preventDefault(),e.stopImmediatePropagation())}),this._listen(e,`keydown`,e=>this._onA11yKey(e))},_pointerHoverExit(){let e=this._hoverId!==-1;this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._a11yKeyboardReadout=null,this._pickSeq=(this._pickSeq||0)+1,this._hideTooltip(),this._hideCrosshair(),this._interactionFlag(`hover`)&&this._dispatchChartEvent(`leave`,{view:this._eventView(`leave`),active:!1}),e&&this._drawKeepPick()},_a11yPointGroups(){return(this.gpuTraces||[]).filter(e=>J(e.trace.kind).pointPick&&e.tier!==`density`&&e._cpu&&e._cpu.x&&e._cpu.y&&Math.min(e._cpu.x.length,e._cpu.y.length)>0)},_onA11yKey(e){let t={ArrowRight:1,ArrowDown:1,ArrowLeft:-1,ArrowUp:-1}[e.key],n=e.key===`Enter`||e.key===` `;if(t===void 0&&e.key!==`Home`&&e.key!==`End`&&e.key!==`Escape`&&!n)return;if(n){if(!this._interactionFlag(`click`)||!this._hoverTarget)return;e.preventDefault();let t=this._hoverTarget,n=this.canvas.getBoundingClientRect(),r=this._lastHoverXY?.clientX??n.left,i=this._lastHoverXY?.clientY??n.top,a={x:r-n.left,y:i-n.top},o={shift:e.shiftKey===!0,alt:e.altKey===!0,ctrl:e.ctrlKey===!0,meta:e.metaKey===!0},s={row:this._localRow?this._localRow(t):null,trace:t.trace,index:t.index,screen:a,modifiers:o,view:this._eventView(`click`)};if(this._dispatchChartEvent(`click`,s),this.comm){let e={type:`click`,trace:t.trace,index:t.index,screen:a,modifiers:o},n=t.g;n&&n.tier===`density`&&n.drill&&n.drill.seq!==void 0&&(e.drill_seq=n.drill.seq),this.comm.send(e)}return}if(e.key===`Escape`){e.preventDefault();let t=this._hoverId!==-1;this._hideTooltip(),this._hoverId=-1,this._hoverTarget=null,this._lastHoverXY=null,this._a11yKeyboardReadout=null,this._pickSeq=(this._pickSeq||0)+1,this.a11yLive&&(this.a11yLive.textContent=`Readout closed.`),t&&this._interactionFlag(`hover`)&&this._dispatchChartEvent(`leave`,{view:this._eventView(`leave`),active:!1}),t&&this._drawKeepPick();return}if(e.preventDefault(),this._interactionTransitionActive())return;let r=this._a11yPointGroups(),i=r.reduce((e,t)=>e+Math.min(t._cpu.x.length,t._cpu.y.length),0);if(!i)return;let a=Number.isInteger(this._a11yPointIndex)?this._a11yPointIndex:-1;a=e.key===`Home`?0:e.key===`End`?i-1:a<0?t>0?0:i-1:Math.max(0,Math.min(i-1,a+t)),this._a11yPointIndex=a;let o=a,s=r[0];for(let e of r){let t=Math.min(e._cpu.x.length,e._cpu.y.length);if(ot.width||i<0||i>t.height){this._hideCrosshair();return}let a=e.clientX-n.left,o=e.clientY-n.top;this.crosshairX.style.display=`block`,this.crosshairX.style.left=a+`px`,this.crosshairX.style.top=this.plot.y+`px`,this.crosshairX.style.height=this.plot.h+`px`,this.crosshairY.style.display=`block`,this.crosshairY.style.left=this.plot.x+`px`,this.crosshairY.style.top=o+`px`,this.crosshairY.style.width=this.plot.w+`px`},_hideCrosshair(){this.crosshairX&&(this.crosshairX.style.display=`none`),this.crosshairY&&(this.crosshairY.style.display=`none`)},_click(e){if(this._ignoreNextClick){this._ignoreNextClick=!1;return}if(!this._interactionFlag(`click`))return;let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top,[i,a]=this._dataFromCanvas(n,r),o=this._pickAt(n,r)||this._hoverAt(n,r),s={x:i,y:a,view:this._eventView(`click`),row:o&&this._localRow?this._localRow(o):null,trace:o?o.trace:null,index:o?o.index:null};if(this._dispatchChartEvent(`click`,s),o&&this.comm){let t={type:`click`,trace:o.trace,index:o.index,screen:{x:n,y:r},modifiers:{shift:e.shiftKey===!0,alt:e.altKey===!0,ctrl:e.ctrlKey===!0,meta:e.metaKey===!0}},i=o.g;i&&i.tier===`density`&&i.drill&&i.drill.seq!==void 0&&(t.drill_seq=i.drill.seq),this.comm.send(t)}},_updateBand(e,t){let n=this.canvas.getBoundingClientRect(),r=this.root.getBoundingClientRect();if(e.mode===`select-lasso`){let i=e.points[e.points.length-1],a=Math.max(0,Math.min(n.width,t.clientX-n.left)),o=Math.max(0,Math.min(n.height,t.clientY-n.top)),s=n.left+a,c=n.top+o;e.points.length<2048&&Math.hypot(s-i.x,c-i.y)>=3&&e.points.push({x:s,y:c,data:this._dataFromCanvas(a,o)});let l=e.points.map(e=>[Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,e.x-r.left)),Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,e.y-r.top))]);this.selLasso.style.display=`block`,this.selLasso.style.inset=`0`,this.selLasso.setAttribute(`width`,String(this.root.clientWidth)),this.selLasso.setAttribute(`height`,String(this.root.clientHeight)),this.selLassoPath.setAttribute(`d`,l.map((e,t)=>`${t?`L`:`M`}${e[0]} ${e[1]}`).join(` `)+` Z`);return}let i=Math.min(e.sx,t.clientX)-r.left,a=Math.min(e.sy,t.clientY)-r.top,o=Math.abs(t.clientX-e.sx),s=Math.abs(t.clientY-e.sy),c=this.plot.x,l=this.plot.y,u=Math.min(i+o,c+this.plot.w),d=Math.min(a+s,l+this.plot.h),f=Math.max(i,c),p=Math.max(a,l),m=u,h=d;e.mode===`select-x`&&(p=l,h=l+this.plot.h),e.mode===`select-y`&&(f=c,m=c+this.plot.w),this.selRect.dataset.xyBand=e.mode===`zoom`?`zoom`:`select`,this.selRect.style.display=`block`,this.selRect.style.left=f+`px`,this.selRect.style.top=p+`px`,this.selRect.style.width=Math.max(0,m-f)+`px`,this.selRect.style.height=Math.max(0,h-p)+`px`},_simplifyLassoPoints(e,t=6,n=16){let r=e.filter(e=>e&&Number.isFinite(e.x)&&Number.isFinite(e.y));if(r.length>3){let e=r[0],n=r[r.length-1];Math.hypot(e.x-n.x,e.y-n.y)<=t&&r.pop()}if(r.length<=3)return r.slice();let i=(e,t,n)=>{let r=n.x-t.x,i=n.y-t.y;if(r===0&&i===0)return(e.x-t.x)**2+(e.y-t.y)**2;let a=Math.max(0,Math.min(1,((e.x-t.x)*r+(e.y-t.y)*i)/(r*r+i*i))),o=t.x+a*r,s=t.y+a*i;return(e.x-o)**2+(e.y-s)**2},a=e=>{let t=new Uint8Array(r.length);t[0]=1,t[r.length-1]=1;let n=[[0,r.length-1]],a=e*e;for(;n.length;){let[e,o]=n.pop(),s=-1,c=a;for(let t=e+1;tc&&(s=t,c=n)}s>=0&&(t[s]=1,n.push([e,s],[s,o]))}return r.filter((e,n)=>t[n])},o=a(t);if(o.length<3&&(o=[r[0],r[Math.floor(r.length/2)],r[r.length-1]]),o.length>n){let e=t,i=Math.max(t,1);for(let t=0;t<16&&o.length>n;t++)e=i,i*=2,o=a(i);for(let t=0;t<12;t++){let t=(e+i)/2,r=a(t);r.length>n?e=t:(i=t,o=r)}o.length<3&&(o=[r[0],r[Math.floor(r.length/2)],r[r.length-1]])}return o},_clearLassoOverlay(){this._lassoPolygon=null,this.selLasso&&(this.selLasso.style.display=`none`,this.selLassoPath?.removeAttribute(`d`),this.selLassoHandles?.replaceChildren())},_renderLassoSelection(){let e=this._lassoPolygon;if(!this.selLasso||!this.selLassoPath||!this.selLassoHandles||!Array.isArray(e)||e.length<3)return;let[t,n]=this._axisRange(`x`),[r,i]=this._axisRange(`y`),a=this._axis(`x`),o=this._axis(`y`),s=this._axisCoord(a,t),c=this._axisCoord(a,n),l=this._axisCoord(o,r),u=this._axisCoord(o,i);if(![s,c,l,u].every(Number.isFinite)||s===c||l===u)return;let d=e.map(e=>{let t=this._axisCoord(a,e[0]),n=this._axisCoord(o,e[1]),r=this.plot.x+(t-s)/(c-s)*this.plot.w,i=this.plot.y+(u-n)/(u-l)*this.plot.h;return[Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,r)),Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,i))]});if(d.flat().every(Number.isFinite)){for(this.selLasso.style.display=`block`,this.selLasso.style.inset=`0`,this.selLasso.setAttribute(`width`,String(this.root.clientWidth)),this.selLasso.setAttribute(`height`,String(this.root.clientHeight)),this.selLassoPath.setAttribute(`d`,d.map((e,t)=>`${t?`L`:`M`}${e[0]} ${e[1]}`).join(` `)+` Z`);this.selLassoHandles.childElementCountd.length;)this.selLassoHandles.lastElementChild.remove();[...this.selLassoHandles.children].forEach((e,t)=>{e.dataset.xySelectionLassoHandle=String(t),e.setAttribute(`cx`,String(d[t][0])),e.setAttribute(`cy`,String(d[t][1])),e.setAttribute(`aria-label`,`Lasso point ${t+1}`)})}},_sendSelect(e,t,n={}){this._clearLassoOverlay();let r=Math.min(e[0],t[0]),i=Math.max(e[0],t[0]),a=Math.min(e[1],t[1]),o=Math.max(e[1],t[1]),s={x0:r,x1:i,y0:a,y1:o};this._historyRecord({source:n.source,interactionId:n.interactionId,history:n.history}),this._stateSelection={range:{...s}},this._lastBrush={mode:`box`,x0:r,x1:i,y0:a,y1:o},this._broadcastLinkedSelection({range:s}),this._dispatchChartEvent(`brush`,{range:s,view:this._eventView(`brush`)}),this.comm?this.comm.send({type:`select`,x0:r,x1:i,y0:a,y1:o}):this._selectLocal(r,i,a,o)},_sendSelectPolygon(e,t={}){if(!Array.isArray(e)||e.length<3)return;let n=e.map(e=>[e[0],e[1]]);n.every(e=>e.every(Number.isFinite))&&(this._historyRecord({source:t.source,interactionId:t.interactionId,history:t.history}),this._stateSelection={polygon:n.map(e=>[...e])},this._lassoPolygon=n,this._lastBrush={mode:`poly`,points:n},this._broadcastLinkedSelection({polygon:n}),this._renderLassoSelection(),this._dispatchChartEvent(`brush`,{polygon:n,view:this._eventView(`brush`)}),this.comm?this.comm.send({type:`select_polygon`,points:n}):this._selectLocalPolygon(n))},_selectLocalPolygon(e,t={}){let n=e.map(e=>e[0]),r=e.map(e=>e[1]),i=Math.min(...n),a=Math.max(...n),o=Math.min(...r),s=Math.max(...r),c=(t,n)=>{let r=!1;for(let i=0,a=e.length-1;in!=l>n&&t<(c-o)*(n-s)/(l-s)+o&&(r=!r)}return r},l=0;for(let e of this.gpuTraces){if(!e._cpu||e.tier===`density`)continue;let t=e._cpu.x,n=e._cpu.y,r=e._cpu.xMeta||e.xMeta,u=e._cpu.yMeta||e.yMeta,d=r.offset,f=r.scale||1,p=u.offset,m=u.scale||1,h=new Float32Array(e.n),g=0;for(let r=0;r=i&&e<=a&&l>=o&&l<=s&&c(e,l)&&(h[r]=1,g++)}this._applySelMask(e,h),l+=g}this._selectionCount=l,this.draw(),t.dispatch!==!1&&this._dispatchChartEvent(`select`,{total:l,polygon:e,view:this._eventView(`select`)})},_selectLocal(e,t,n,r,i={}){let a=0;for(let i of this.gpuTraces){if(!i._cpu||i.tier===`density`)continue;let o=i._cpu.x,s=i._cpu.y,c=i._cpu.xMeta||i.xMeta,l=i._cpu.yMeta||i.yMeta,u=c.offset,d=c.scale||1,f=l.offset,p=l.scale||1,m=new Float32Array(i.n),h=0;for(let a=0;a=e&&i<=t&&c>=n&&c<=r&&(m[a]=1,h++)}this._applySelMask(i,m),a+=h}this._selectionCount=a,this.draw(),i.dispatch!==!1&&this._dispatchChartEvent(`select`,{total:a,range:{x0:e,x1:t,y0:n,y1:r},view:this._eventView(`select`)})},_applySelMask(e,t){let n=this.gl;e.selBuf||=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,e.selBuf),n.bufferData(n.ARRAY_BUFFER,t,n.STATIC_DRAW),e.selActive=!0},_clearSelection(e={}){this._clearLassoOverlay(),e.dispatch!==!1&&this._stateSelection!==null&&this._stateSelection!==void 0&&this._historyRecord({source:e.source,interactionId:e.interactionId,history:e.history}),this._stateSelection=null;for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);this._selectionCount=0,this._lastBrush=null,e.broadcast!==!1&&this._broadcastLinkedSelection({clear:!0}),e.dispatch!==!1&&this._interactionFlag(`select`,!0)&&(this.comm&&this.comm.send({type:`select_clear`}),this._dispatchChartEvent(`select`,{total:0,view:this._eventView(`select_clear`)}))},_clampModebar(e,t){let n=this._modebar;if(!n||!this.root)return;let r=e??(Number.parseFloat(n.style.left)||0),i=t??(Number.parseFloat(n.style.top)||0),a=Math.max(0,this.root.clientWidth-n.offsetWidth),o=Math.max(0,this.root.clientHeight-n.offsetHeight);n.style.left=`${Math.max(0,Math.min(a,r))}px`,n.style.top=`${Math.max(0,Math.min(o,i))}px`},_buildModebar(e){if(this.spec.show_modebar===!1)return;let t=document.createElement(`div`);t.style.cssText=`position:absolute;top:${this.plot.y+4}px;left:${this.plot.x+4}px;z-index:6;display:flex;opacity:0;pointer-events:none;transition:opacity .15s;`,this._applySlot(t,`modebar`),t.setAttribute(`role`,`toolbar`),t.setAttribute(`aria-label`,`Chart controls`),this._modebar=t,this._modeBtns={},this._modebarMoved=!1;let n=()=>{},r=()=>{},i=()=>{},a=e=>{let n=e||this._modebarDragging||t.contains(document.activeElement);t.style.opacity=n?`1`:`0`,t.style.pointerEvents=n?`auto`:`none`};this._listen(e,`pointerenter`,()=>a(!0)),this._listen(e,`pointerleave`,()=>{a(!1),n(!1),r(!1),i(!1)}),this._listen(t,`focusin`,()=>a(!0)),this._listen(t,`focusout`,n=>{!t.contains(n.relatedTarget)&&!e.matches(`:hover`)&&a(!1)});let o=document.createElement(`button`);o.type=`button`,o.title=`Click for toolbar options; drag to move`,o.setAttribute(`aria-label`,`Toolbar options`),o.setAttribute(`aria-haspopup`,`menu`),o.setAttribute(`aria-expanded`,`false`),o.dataset.xyModebarDragHandle=``,o.dataset.xyModebarExport=``,o.dataset.xyModebarExportTrigger=``,o.innerHTML=this._icon(`drag`),o.style.cssText=`display:flex;align-items:center;justify-content:center;pointer-events:auto;touch-action:none;`,this._applySlot(o,`modebar_button`),t.appendChild(o);let s=null,c=0;this._listen(o,`pointerdown`,e=>{if(e.pointerType===`mouse`&&e.button!==0)return;e.stopPropagation();let n=t.getBoundingClientRect();s={pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,dx:e.clientX-n.left,dy:e.clientY-n.top,moved:!1};try{o.setPointerCapture(e.pointerId)}catch{}a(!0)}),this._listen(o,`pointermove`,a=>{if(!s||a.pointerId!==s.pointerId)return;let o=Math.hypot(a.clientX-s.startX,a.clientY-s.startY);if(!s.moved){if(o<6)return;s.moved=!0,this._modebarDragging=!0,this._modebarMoved=!0,t.style.transition=`none`,n(!1),r(!1),i(!1)}let c=e.getBoundingClientRect(),l=a.clientX-c.left-s.dx,u=a.clientY-c.top-s.dy;this._clampModebar(l,u)});let l=n=>{if(!s||n.pointerId!==s.pointerId)return;let r=s.moved,i=n.type===`pointercancel`;s=null,this._modebarDragging=!1,t.style.transition=`opacity .15s`,a(e.matches(`:hover`)),(r||i)&&(c=performance.now()+100)};this._listen(o,`pointerup`,l),this._listen(o,`pointercancel`,l),this._listen(o,`click`,e=>{if(e.stopPropagation(),performance.now()<=c){c=0;return}i(!this._exportMenuOpen)});let u=(e,n,r,i)=>{let a=document.createElement(`button`);return a.type=`button`,a.title=n,a.setAttribute(`aria-label`,n),i&&a.setAttribute(`aria-pressed`,`false`),a.innerHTML=this._icon(e),a.style.cssText=`display:flex;align-items:center;justify-content:center;pointer-events:auto;`,this._applySlot(a,`modebar_button`),this._listen(a,`pointerdown`,e=>e.stopPropagation()),this._listen(a,`click`,e=>{e.stopPropagation(),r()}),t.appendChild(a),i&&(this._modeBtns[i]=a),a},d=this._interactionFlag(`navigation`,!0),f=d&&this._interactionFlag(`pan`,!0),p=d&&this._interactionFlag(`zoom`,!0),m=p&&this._interactionFlag(`zoom_buttons`,!0),h=p&&this._interactionFlag(`box_zoom`,!0),g=d&&this._resetAxisPolicy().length>0,_=m||h||g,v=null,y=null;if(this._zoomMenuButton=null,this._zoomMenuLabel=null,_){v=u(`zoommenu`,`Zoom controls`,()=>{n(!this._zoomMenuOpen)}),this._zoomMenuButton=v,v.dataset.xyModebarMenuTrigger=``,v.replaceChildren();let e=document.createElement(`span`);e.dataset.xyModebarZoomPercent=``,e.textContent=`100%`,v.appendChild(e),y=document.createElement(`span`),y.dataset.xyModebarMenuIndicator=``,y.innerHTML=this._icon(`chevrondown`),v.appendChild(y),this._zoomMenuLabel=e,v.setAttribute(`aria-haspopup`,`menu`),v.setAttribute(`aria-expanded`,`false`)}let b=this._interactionFlag(`brush`,!0)&&this._interactionFlag(`select`,!0),x=null,S=null,C=null;b&&(x=u(`select`,`Selection controls`,()=>{r(!this._selectMenuOpen)}),x.dataset.xyModebarSelect=``,x.dataset.xyModebarSelectTrigger=``,x.setAttribute(`aria-haspopup`,`menu`),x.setAttribute(`aria-expanded`,`false`),x.replaceChildren(),C=document.createElement(`span`),C.dataset.xyModebarSelectIcon=``,C.innerHTML=this._icon(`select`),x.appendChild(C),S=document.createElement(`span`),S.dataset.xyModebarMenuIndicator=``,S.innerHTML=this._icon(`chevrondown`),x.appendChild(S),this._selectMenuButton=x,this._selectMenuIcon=C),f&&u(`pan`,`Pan`,()=>this._setDragMode(`pan`),`pan`),d&&this._historyEnabled()&&(this._historyBackBtn=u(`historyback`,`Back to previous view`,()=>this._historyBack()),this._historyBackBtn.dataset.xyModebarHistory=`back`,this._historyForwardBtn=u(`historyforward`,`Forward to next view`,()=>this._historyForward()),this._historyForwardBtn.dataset.xyModebarHistory=`forward`,this._updateHistoryButtons());let w=null;_&&(w=document.createElement(`div`),w.dataset.xyModebarMenu=``,w.setAttribute(`role`,`menu`),w.setAttribute(`aria-label`,`Zoom controls`),w.style.cssText=`position:absolute;display:none;flex-direction:column;z-index:7;pointer-events:auto;`,t.appendChild(w));let T=[],E=(e,t,r,i,a=!1)=>{let o=document.createElement(`button`);o.type=`button`,o.tabIndex=-1,o.dataset.xyModebarMenuItem=e,a&&(o.dataset.xySeparator=``),o.setAttribute(`role`,`menuitem`),o.style.cssText=`display:flex;align-items:center;pointer-events:auto;`,this._applySlot(o,`modebar_button`);let s=document.createElement(`span`);s.dataset.xyModebarMenuIcon=``,s.innerHTML=this._icon(e),o.appendChild(s);let c=document.createElement(`span`);return c.textContent=t,o.appendChild(c),this._listen(o,`pointerdown`,e=>e.stopPropagation()),this._listen(o,`click`,e=>{e.stopPropagation(),n(!1,!0),r()}),w.appendChild(o),T.push(o),i&&(this._modeBtns[i]=o),o};_&&(m&&(E(`zoomin`,this._actionLabel(`Zoom In`,this._axisPolicy(`zoom_axes`)),()=>this._zoomBy(.5,!0,`zoom_in`)),E(`zoomout`,this._actionLabel(`Zoom Out`,this._axisPolicy(`zoom_axes`)),()=>this._zoomBy(2,!0,`zoom_out`))),h&&E(`zoom`,this._actionLabel(`Box Zoom`,this._axisPolicy(`zoom_axes`)),()=>this._setDragMode(`zoom`),`zoom`),g&&E(`reset`,this._actionLabel(`Reset View`,this._resetAxisPolicy()),()=>this._resetView(!0,`reset`),null,m||h));let D=document.createElement(`div`);D.dataset.xyModebarMenu=``,D.dataset.xyModebarSelectMenu=``,D.setAttribute(`role`,`menu`),D.setAttribute(`aria-label`,`Selection controls`),D.style.cssText=`position:absolute;display:none;flex-direction:column;z-index:7;pointer-events:auto;`,t.appendChild(D);let O=[],k=(e,t,n)=>{let i=document.createElement(`button`);i.type=`button`,i.tabIndex=-1,i.dataset.xyModebarMenuItem=e,i.dataset.xyModebarSelectItem=n,i.setAttribute(`role`,`menuitem`),i.style.cssText=`display:flex;align-items:center;pointer-events:auto;`,this._applySlot(i,`modebar_button`);let a=document.createElement(`span`);a.dataset.xyModebarMenuIcon=``,a.innerHTML=this._icon(e),i.appendChild(a);let o=document.createElement(`span`);o.textContent=t,i.appendChild(o),this._listen(i,`pointerdown`,e=>e.stopPropagation()),this._listen(i,`click`,e=>{e.stopPropagation(),r(!1,!0),this._setDragMode(n)}),D.appendChild(i),O.push(i),this._modeBtns[n]=i};b&&(k(`select`,`Box Select`,`select`),k(`lasso`,`Lasso Select`,`select-lasso`),k(`selectx`,`X Range`,`select-x`),k(`selecty`,`Y Range`,`select-y`));let A=document.createElement(`div`);A.dataset.xyModebarMenu=``,A.dataset.xyModebarExportMenu=``,A.setAttribute(`role`,`menu`),A.setAttribute(`aria-label`,`Toolbar options`),A.style.cssText=`position:absolute;display:none;flex-direction:column;z-index:7;pointer-events:auto;`,t.appendChild(A);let j=[],M=(e,t,n,r=!1)=>{let a=document.createElement(`button`);a.type=`button`,a.tabIndex=-1,a.dataset.xyModebarMenuItem=e,a.dataset.xyModebarExportItem=e,r&&(a.dataset.xySeparator=``),a.setAttribute(`role`,`menuitem`),a.style.cssText=`display:flex;align-items:center;pointer-events:auto;`,this._applySlot(a,`modebar_button`);let o=document.createElement(`span`);o.dataset.xyModebarMenuIcon=``,o.innerHTML=this._icon(e),a.appendChild(o);let s=document.createElement(`span`);return s.textContent=t,a.appendChild(s),this._listen(a,`pointerdown`,e=>e.stopPropagation()),this._listen(a,`click`,e=>{e.stopPropagation(),i(!1,!0),Promise.resolve(n()).catch(e=>console.error(`xy: ${t} failed`,e))}),A.appendChild(a),j.push(a),a},ee={png:[`Export PNG`,()=>this._exportRaster(`png`)],jpeg:[`Export JPEG`,()=>this._exportRaster(`jpeg`)],webp:[`Export WebP`,()=>this._exportRaster(`webp`)],svg:[`Export SVG`,()=>this._exportSvg()],csv:[`Export CSV`,()=>this._exportCsv()]},te=Array.isArray(this._exportConfig().formats)?this._exportConfig().formats:[`png`,`svg`,`csv`];for(let e of te){let t=ee[e];t&&M(e,t[0],t[1])}v&&(n=(n,a=!1)=>{let o=!!n;if(o&&(r(!1),i(!1)),this._zoomMenuOpen=o,v.setAttribute(`aria-expanded`,String(o)),!o){w.style.display=`none`,y.style.transform=`none`,a&&v.focus();return}w.style.display=`flex`,w.style.visibility=`hidden`;let s=e.getBoundingClientRect(),c=t.getBoundingClientRect(),l=c.left-s.left,u=c.top-s.top,d=t.offsetHeight+6,f=-w.offsetHeight-6,p=c.bottom+6+w.offsetHeight<=s.bottom?d:f;y.style.transform=p===f?`rotate(180deg)`:`none`;let m=e.clientWidth-l-w.offsetWidth,h=e.clientHeight-u-w.offsetHeight;w.style.left=`${Math.max(-l,Math.min(m,v.offsetLeft))}px`,w.style.top=`${Math.max(-u,Math.min(h,p))}px`,w.style.visibility=`visible`}),r=(r,a=!1)=>{if(!x)return;let o=!!r;if(o&&(n(!1),i(!1)),this._selectMenuOpen=o,x.setAttribute(`aria-expanded`,String(o)),!o){D.style.display=`none`,S.style.transform=`none`,a&&x.focus();return}D.style.display=`flex`,D.style.visibility=`hidden`;let s=e.getBoundingClientRect(),c=t.getBoundingClientRect(),l=c.left-s.left,u=c.top-s.top,d=t.offsetHeight+6,f=-D.offsetHeight-6,p=c.bottom+6+D.offsetHeight<=s.bottom?d:f;S.style.transform=p===f?`rotate(180deg)`:`none`;let m=e.clientWidth-l-D.offsetWidth,h=e.clientHeight-u-D.offsetHeight;D.style.left=`${Math.max(-l,Math.min(m,x.offsetLeft))}px`,D.style.top=`${Math.max(-u,Math.min(h,p))}px`,D.style.visibility=`visible`},i=(i,a=!1)=>{let s=!!i&&j.length>0;if(s&&(n(!1),r(!1)),this._exportMenuOpen=s,o.setAttribute(`aria-expanded`,String(s)),!s){A.style.display=`none`,a&&o.focus();return}A.style.display=`flex`,A.style.visibility=`hidden`;let c=e.getBoundingClientRect(),l=t.getBoundingClientRect(),u=l.left-c.left,d=l.top-c.top,f=t.offsetHeight+6,p=-A.offsetHeight-6,m=l.bottom+6+A.offsetHeight<=c.bottom?f:p,h=e.clientWidth-u-A.offsetWidth,g=e.clientHeight-d-A.offsetHeight;A.style.left=`${Math.max(-u,Math.min(h,o.offsetLeft))}px`,A.style.top=`${Math.max(-d,Math.min(g,m))}px`,A.style.visibility=`visible`},this._closeModebarMenu=()=>{n(!1),r(!1),i(!1)},this._syncModebarSelect=()=>{if(!x)return;let e=!!this._pickable;e||(r(!1),this.dragMode.startsWith(`select`)&&this._setDragMode(`pan`)),x.style.display=e?`flex`:`none`},this._syncModebarSelect(),this._listen(document,`pointerdown`,e=>{this._zoomMenuOpen&&!t.contains(e.target)&&n(!1),this._selectMenuOpen&&!t.contains(e.target)&&r(!1),this._exportMenuOpen&&!t.contains(e.target)&&i(!1)}),v&&(this._listen(v,`keydown`,e=>{if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`)return;e.preventDefault(),e.stopPropagation(),n(!0);let t=e.key===`ArrowDown`?0:T.length-1;T[t].focus()}),this._listen(w,`keydown`,e=>{if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),n(!1,!0);return}if(![`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key))return;e.preventDefault();let t=T.indexOf(document.activeElement),r=e.key===`Home`?0:e.key===`End`?T.length-1:t;e.key===`ArrowDown`&&(r=(t+1)%T.length),e.key===`ArrowUp`&&(r=(t-1+T.length)%T.length),T[r].focus()})),x&&(this._listen(x,`keydown`,e=>{if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`)return;e.preventDefault(),e.stopPropagation(),r(!0);let t=e.key===`ArrowDown`?0:O.length-1;O[t].focus()}),this._listen(D,`keydown`,e=>{if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),r(!1,!0);return}if(![`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key))return;e.preventDefault();let t=O.indexOf(document.activeElement),n=e.key===`Home`?0:e.key===`End`?O.length-1:t;e.key===`ArrowDown`&&(n=(t+1)%O.length),e.key===`ArrowUp`&&(n=(t-1+O.length)%O.length),O[n].focus()})),this._listen(o,`keydown`,e=>{if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`||!j.length)return;e.preventDefault(),e.stopPropagation(),i(!0);let t=e.key===`ArrowDown`?0:j.length-1;j[t].focus()}),this._listen(A,`keydown`,e=>{if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),i(!1,!0);return}if(![`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key))return;e.preventDefault();let t=j.indexOf(document.activeElement),n=e.key===`Home`?0:e.key===`End`?j.length-1:t;e.key===`ArrowDown`&&(n=(t+1)%j.length),e.key===`ArrowUp`&&(n=(t-1+j.length)%j.length),j[n].focus()}),e.appendChild(t),this._fitModebar(),a(e.matches(`:hover`)),this._setDragMode(this.dragMode)},_fitModebar(){let e=this._modebar;if(e){if(this._closeModebarMenu?.(),this._modebarMoved||(e.style.top=`${this.plot.y+4}px`,e.style.left=`${this.plot.x+4}px`),e.style.display=`flex`,!(e.offsetWidth+8<=this.plot.w&&e.offsetHeight+8<=this.plot.h)){e.style.display=`none`;return}this._clampModebar()}},_setDragMode(e){this.dragMode=e,this.canvas&&(this.canvas.dataset.xyDragmode=e);for(let[t,n]of Object.entries(this._modeBtns||{}))n.classList.toggle(`xy-active`,t===e),n.setAttribute(`aria-pressed`,String(t===e));this._zoomMenuButton?.classList.toggle(`xy-active`,e===`zoom`),this._selectMenuButton?.classList.toggle(`xy-active`,e.startsWith(`select`));let t={select:[`select`,`Box Select`],"select-lasso":[`lasso`,`Lasso Select`],"select-x":[`selectx`,`X Range`],"select-y":[`selecty`,`Y Range`]}[e];if(t&&this._selectMenuButton&&this._selectMenuIcon){let[e,n]=t;this._selectMenuIcon.innerHTML=this._icon(e),this._selectMenuButton.title=`Selection controls: ${n}`,this._selectMenuButton.setAttribute(`aria-label`,`Selection controls: ${n}`)}},_actionLabel(e,t){let n=Array.isArray(t)?t:[...t||[]];return n.length?`${e} on ${n.join(` and `)} ${n.length===1?`axis`:`axes`}`:e},_updateZoomMenuLabel(){if(!this._zoomMenuLabel||!this.view||!this.view0)return;let e=(e,t,n,r,i)=>{let a=this._axis(e),o=Math.abs(this._axisCoord(a,n)-this._axisCoord(a,t)),s=Math.abs(this._axisCoord(a,i)-this._axisCoord(a,r));return Number.isFinite(o)&&o>0&&Number.isFinite(s)&&s>0?s/o*100:null},t=[...this._zoomAxes()].map(t=>{let[n,r]=this._axisRange(t),[i,a]=this._axisRange(t,this.view0);return[t,e(t,n,r,i,a)]}).filter(e=>e[1]!==null),n=t[0]?.[1]??100,r=Math.round(n),i=n<1?`<1%`:`${r}%`,a=r>999?`${String(r).slice(0,3)}…%`:i;if(this._zoomMenuLabel.dataset.xyZoomExact===i&&this._zoomMenuLabel.textContent===a)return;this._zoomMenuLabel.textContent=a,this._zoomMenuLabel.dataset.xyZoomExact=i;let o=t.map(([e,t])=>`${e} ${Math.round(t)}%`).join(`, `);this._zoomMenuButton.title=`Zoom controls (${o||i})`,this._zoomMenuButton.setAttribute(`aria-label`,`Zoom controls, ${o||i}`)},_prefersReducedMotion(){return window.matchMedia?.(`(prefers-reduced-motion: reduce)`)?.matches===!0},_cancelViewAnimation(){this._animRaf&&cancelAnimationFrame(this._animRaf),this._animRaf=null,this._viewAnim=null},_setView(e,t={}){if(this._destroyed)return[];let n=this._clampView(this._viewFrom(e),{anchors:t.anchors}),r=this._axisIds().filter(e=>{let t=this._axisRange(e),r=this._axisRange(e,n);return t[0]!==r[0]||t[1]!==r[1]});if(!r.length)return[];this._viewAnim||this._historyRecord({source:t.source||`programmatic`,interactionId:t.interactionId,history:t.history});let i=t.animate===!0&&!this._prefersReducedMotion(),a=t.duration||180;if(!i||a<=0)return this._cancelViewAnimation(),this.view=n,this.draw(),t.request!==!1&&this._scheduleViewRequest(),this._emitViewChange(t.source||`programmatic`,{axes:r,phase:t.phase||`end`,interactionId:t.interactionId,broadcast:t.broadcast}),r;clearTimeout(this._viewTimer),this.seq+=1;let o=t.request!==!1,s=t.requestDelay??Math.min(55,Math.max(24,a*.35)),c=t.requestMaxWait??130;o&&this._scheduleViewRequest(n,{seq:this.seq,delay:s,maxWait:c});let l=this._now(),u=Math.max(18,a/5);if(this._viewAnim)return Object.assign(this._viewAnim,{target:n,tau:u,changedAxes:[...new Set([...this._viewAnim.changedAxes,...r])],source:t.source||`programmatic`,phase:t.phase||`end`,interactionId:t.interactionId,broadcast:t.broadcast}),r;this._viewAnim={target:n,last:l,tau:u,changedAxes:r,source:t.source||`programmatic`,phase:t.phase||`end`,interactionId:t.interactionId,broadcast:t.broadcast};let d=(e,t,n)=>e+(t-e)*n,f=e=>Math.max(...this._axisIds().map(t=>{let[n,r]=this._axisRange(t,e);return Math.abs(r-n)}),1e-12),p=(e,t)=>{let n=f(t)*1e-4;return Math.max(...this._axisIds().flatMap(n=>{let r=this._axisRange(n,e),i=this._axisRange(n,t);return[Math.abs(r[0]-i[0]),Math.abs(r[1]-i[1])]}))<=n},m=e=>{if(this._destroyed){this._animRaf=null;return}let t=this._viewAnim;if(!t){this._animRaf=null;return}let n=Math.max(0,Math.min(64,e-t.last));t.last=e;let r=1-Math.exp(-n/t.tau),i=p(this.view,t.target)?1:r,a={};for(let e of this._axisIds()){let n=this._axisRange(e),r=this._axisRange(e,t.target);a[e]=[d(n[0],r[0],i),d(n[1],r[1],i)]}this.view=this._copyView({ranges:a}),i<1?(this.draw(),this._animRaf=requestAnimationFrame(m)):(this._animRaf=null,this._viewAnim=null,this.view=t.target,this._lastLabelDraw=null,this.draw(),this._emitViewChange(t.source,{axes:t.changedAxes,phase:t.phase,interactionId:t.interactionId,broadcast:t.broadcast}))};return this._animRaf=requestAnimationFrame(m),r},_zoomLimitForAxis(e){if(!this._axisPolicy(`zoom_axes`).includes(e))return[null,null];let t=this.interaction?.zoom_limits;if(t&&typeof t==`object`&&!Array.isArray(t)){let n=t[e];if(Array.isArray(n)&&n.length===2)return n}return[1,null]},_clampAxisRange(e,t,n,r=.5){let i=this._axis(e),a=this._axisCoord(i,t),o=this._axisCoord(i,n);if(![a,o].every(Number.isFinite)||a===o)return this._axisRange(e,this.view0);let s=this.view0?.ranges?.[e];if(s){let t=this._axisCoord(i,s[0]),n=this._axisCoord(i,s[1]),c=Math.abs(n-t),[l,u]=this._zoomLimitForAxis(e),d=Number(l),f=Number(u),p=Number.isFinite(d)&&d>0?c/d:1/0,m=Number.isFinite(f)&&f>0?c/f:0,h=Math.abs(o-a),g=Math.max(m,Math.min(p,h));if(Number.isFinite(g)&&g>0&&g!==h){let e=o=l-c)d=c,f=l;else{let e=Math.max(c-d,Math.min(l-f,0));d+=e,f+=e}let p=u?f:d,m=u?d:f;return[this._axisValue(i,p),this._axisValue(i,m)]},_clampView(e,t={}){let n=this._viewFrom(e,this.view0),r={};for(let e of this._axisIds()){let[i,a]=this._axisRange(e,n);r[e]=this._clampAxisRange(e,i,a,t.anchors?.[e]??.5)}return this._copyView({ranges:r})},_zoomAxes(){return new Set(this._axisPolicy(`zoom_axes`))},_zoomBy(e,t=!1,n=e<1?`zoom_in`:`zoom_out`){let r=this._viewAnim?this._viewAnim.target:this.view,i=this._zoomAxes(),a=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,r)]]));for(let t of i){let[n,r]=a[t],i=this._zoomAxisRange(t,n,r,e,.5);i&&(a[t]=i)}this._setView({ranges:a},{animate:t,source:n,phase:`end`,interactionId:++this._interactionSeq})},_zoomAxisRange(e,t,n,r,i){let a=this._axis(e),o=this._axisCoord(a,t),s=this._axisCoord(a,n);if(![o,s].every(Number.isFinite)||o===s)return null;let c=o+i*(s-o);if(r<1){let e=Math.max(Math.abs(c),1e-30)*1e-12;if(Math.abs((s-o)*r)1&&this.view0){let t=this._axisRange(e,this.view0),n=this._axisCoord(a,t[0]),r=this._axisCoord(a,t[1]),o=Math.abs(r-n);if([n,r].every(Number.isFinite)&&o>0&&Math.abs(u-l)>o){let e=o*Math.sign(u-l);return[this._axisValue(a,c-i*e),this._axisValue(a,c+(1-i)*e)]}}return[this._axisValue(a,l),this._axisValue(a,u)]},_zoomAt(e,t,n,r=!1,i=120,a={}){let o=this._viewAnim?this._viewAnim.target:this.view,s=Array.isArray(a.axes)?new Set(a.axes.filter(e=>this._zoomAxes().has(e))):this._zoomAxes(),c=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,o)]])),l={};for(let r of s){let i=this._axisDim(r)===`x`?t:n,[a,o]=c[r],s=this._zoomAxisRange(r,a,o,e,i);s&&(c[r]=s),l[r]=i}return this._setView({ranges:c},{animate:r,duration:i,anchors:l,source:a.source||`wheel_zoom`,phase:a.phase||`update`,interactionId:a.interactionId})},_queueWheelZoom(e,t,n,r=null){if(!Number.isFinite(e)||e<=0)return;clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null;let i=Array.isArray(r)?r.join(`,`):``;if(this._wheelGesture&&this._wheelGesture.scopeKey!==i){let e=this._wheelGesture;this._wheelGesture=null,e.axes.size&&this._emitViewChange(`wheel_zoom`,{axes:[...e.axes],phase:`end`,interactionId:e.interactionId})}this._wheelGesture||={interactionId:++this._interactionSeq,axes:new Set,scopeKey:i},this._pendingWheelZoom||={factor:1,fx:t,fy:n,interactionId:this._wheelGesture.interactionId,axes:[],axesScope:r},this._pendingWheelZoom.factor*=e,this._pendingWheelZoom.fx=t,this._pendingWheelZoom.fy=n,this._pendingWheelZoom.axesScope=r,!this._wheelZoomRaf&&(this._wheelZoomRaf=requestAnimationFrame(()=>{this._wheelZoomRaf=null;let e=this._pendingWheelZoom;if(this._pendingWheelZoom=null,!(!e||this._destroyed)){e.axes=this._zoomAt(e.factor,e.fx,e.fy,!1,120,{source:`wheel_zoom`,phase:`update`,interactionId:e.interactionId,axes:e.axesScope||void 0})||[];for(let t of e.axes)this._wheelGesture?.axes.add(t);clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=setTimeout(()=>{let e=this._wheelGesture;this._wheelGesture=null,!(this._destroyed||!e||!e.axes.size)&&this._emitViewChange(`wheel_zoom`,{axes:[...e.axes],phase:`end`,interactionId:e.interactionId})},90)}}))},_zoomToBox(e,t,n=!1,r={}){let i=this._zoomAxes(),a={};for(let n of[`x`,`y`]){let r=this._axis(n),[i,o]=this._axisRange(n),s=this._axisCoord(r,i),c=this._axisCoord(r,o),l=this._axisCoord(r,e[n===`x`?0:1]),u=this._axisCoord(r,t[n===`x`?0:1]);if(![s,c,l,u].every(Number.isFinite)||s===c)return[];a[n]=[(l-s)/(c-s),(u-s)/(c-s)]}let o=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),s={};for(let e of i){let t=this._axis(e),[n,r]=o[e],i=this._axisCoord(t,n),c=this._axisCoord(t,r),[l,u]=a[this._axisDim(e)],d=i+l*(c-i),f=i+u*(c-i),p=Math.max(Math.abs(d),Math.abs(f),1e-30)*1e-12;if(!Number.isFinite(d)||!Number.isFinite(f)||Math.abs(f-d)[e,[...this._axisRange(e)]]));for(let e of n||this._resetAxisPolicy())r[e]=[...this._axisRange(e,this.view0)];return this._setView({ranges:r},{animate:e,source:t,phase:`end`,interactionId:++this._interactionSeq})},_exportConfig(){let e=this.spec&&this.spec.export;return e&&typeof e==`object`?e:{}},_exportFilename(e){let t=this._exportConfig().filename;return typeof t==`string`&&t?`${t}.${e}`:`${String(this.spec.title||`xy-chart`).trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`xy-chart`}.${e}`},_downloadExport(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,r.style.display=`none`,document.body.appendChild(r),r.click(),r.remove(),setTimeout(()=>URL.revokeObjectURL(n),0)},_exportSvgMarkup(){this._drawNow?.(),this.gl?.finish?.();let e=this.size.w,t=this.size.h,n=this.root.cloneNode(!0);n.style.width=`${e}px`,n.style.height=`${t}px`,n.style.margin=`0`,n.setAttribute(`xmlns`,`http://www.w3.org/1999/xhtml`);let r=getComputedStyle(this.root),i=[`color`,`font-family`,`font-size`,`font-style`,`font-weight`,`letter-spacing`,`line-height`],a=[`--chart-bg`,`--chart-text`,`--chart-grid`,`--chart-axis`,`--chart-tooltip-bg`,`--chart-tooltip-text`,`--chart-legend-bg`,`--chart-badge-bg`,`--chart-badge-text`,`--chart-modebar-bg`,`--chart-modebar-active`,`--chart-selection`,`--chart-selection-fill`,`--chart-zoom-selection`,`--chart-zoom-selection-fill`,`--chart-crosshair`,`--chart-annotation-text`,`--chart-cursor`,`--chart-cursor-pan`];for(let e=0;ee.remove());let c=document.createElement(`style`);return c.textContent=w,n.prepend(c),`${new XMLSerializer().serializeToString(n)}`},_exportSvg(){let e=this._exportSvgMarkup();this._downloadExport(new Blob([e],{type:`image/svg+xml;charset=utf-8`}),this._exportFilename(`svg`))},_exportPng(){return this._exportRaster(`png`)},_exportRaster(e){let t=this._exportSvgMarkup(),n=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`,r=new Image,i=this._exportConfig(),a={png:`image/png`,jpeg:`image/jpeg`,webp:`image/webp`}[e];return a?new Promise((t,o)=>{r.onload=()=>{let n=Number.isFinite(i.scale)&&i.scale>0?i.scale:Math.max(1,window.devicePixelRatio||1),s=document.createElement(`canvas`);s.width=Math.round(this.size.w*n),s.height=Math.round(this.size.h*n);let c=s.getContext(`2d`),l=typeof i.background==`string`&&i.background!==`auto`?i.background:null,u=l===`transparent`||l===`none`;e===`jpeg`?(c.fillStyle=l&&!u?l:`#ffffff`,c.fillRect(0,0,s.width,s.height)):l&&!u&&(c.fillStyle=l,c.fillRect(0,0,s.width,s.height)),c.scale(n,n),c.drawImage(r,0,0,this.size.w,this.size.h);let d=Number.isFinite(i.quality)?Math.min(1,Math.max(.01,i.quality/100)):.9;s.toBlob(n=>{if(!n){o(Error(`${e.toUpperCase()} encoding returned no data`));return}let r=n.type===`image/jpeg`?`jpg`:n.type===`image/webp`?`webp`:`png`;this._downloadExport(n,this._exportFilename(r)),t()},a,e===`png`?void 0:d)},r.onerror=()=>{o(Error(`chart SVG could not be rasterized`))},r.src=n}):Promise.reject(Error(`unsupported raster export ${e}`))},_exportCsvText(){let e=[[`trace`,`name`,`kind`,`index`,`x`,`y`,`x0`,`x1`,`y0`,`y1`,`value`]],t=e=>Number.isFinite(e)?e:``;for(let n of this.gpuTraces||[]){let r=n.trace||{},i=[r.id??``,r.name??``,r.kind??``];if(n._cpuRect){let r=n._cpuRect,a=Math.min(r.x0.length,r.x1.length,r.y0.length,r.y1.length);for(let n=0;n{let t=String(e??``),n=t.split(`"`).join(`""`);return t.includes(`,`)||t.includes(`"`)||t.includes(`\r`)||t.includes(` -`)?`"${n}"`:t};return e.map(e=>e.map(n).join(`,`)).join(`\r -`)+`\r -`},_exportCsv(){this._downloadExport(new Blob([this._exportCsvText()],{type:`text/csv;charset=utf-8`}),this._exportFilename(`csv`))},_icon(e){let t=e=>`${e}`;switch(e){case`zoomin`:return t(``);case`zoomout`:return t(``);case`pan`:return t(``);case`zoom`:return t(``);case`select`:return t(``);case`lasso`:return t(``);case`selectx`:return t(``);case`selecty`:return t(``);case`chevrondown`:return t(``);case`collapse`:return t(``);case`expand`:return t(``);case`png`:return t(``);case`jpeg`:return t(``);case`webp`:return t(``);case`svg`:return t(``);case`csv`:return t(``);case`reset`:return t(``);case`historyback`:return t(``);case`historyforward`:return t(``);case`drag`:return t(``);default:return t(``)}}});var gt=` -const DATA = new Map(); -self.onmessage = (e) => { - const m = e.data; - if (m.type === "init") { - DATA.set(m.trace, { x: new Float64Array(m.x), y: new Float64Array(m.y) }); - return; - } - const d = DATA.get(m.trace); - if (!d) return; - const w = m.w, h = m.h; - const grid = new Float32Array(w * h); - const sx = w / ((m.x1 - m.x0) || 1); - const sy = h / ((m.y1 - m.y0) || 1); - let max = 0; - const X = d.x, Y = d.y, n = X.length; - for (let i = 0; i < n; i++) { - const cx = (X[i] - m.x0) * sx; - const cy = (Y[i] - m.y0) * sy; - if (cx < 0 || cy < 0 || cx >= w || cy >= h) continue; - const v = ++grid[(cy | 0) * w + (cx | 0)]; - if (v > max) max = v; - } - self.postMessage( - { type: "grid", seq: m.seq, trace: m.trace, w, h, max, - x0: m.x0, x1: m.x1, y0: m.y0, y1: m.y1, grid: grid.buffer }, - [grid.buffer] - ); -}; -`;function _t(){try{let e=URL.createObjectURL(new Blob([gt],{type:`application/javascript`})),t=new Worker(e);return t._fcUrl=e,t}catch{return null}}Object.assign(Q.prototype,{_scheduleViewRequest(e=this.view,t={}){if(this._destroyed||this._glLost)return;if(!this.comm){this._scheduleSampleRebin(e,t);return}let n=this.spec.traces.some(e=>e.tier===`decimated`),r=this.gpuTraces.some(e=>e.tier===`density`);if(!n&&!r)return;let i=t.seq??++this.seq,a=this._copyView(e),o=Math.round(this.plot.w),s=Math.round(this.plot.h);if(r){let e=this._now();for(let t of this.gpuTraces)t.tier===`density`&&(t._lodPendingView=a,t._lodPendingSeq=i,t._lodPendingAt=e)}let c=t.delay??120;if(t.maxWait!==void 0&&t.maxWait!==null){let e=this._now();(this._viewRequestBurstStart===void 0||this._viewRequestBurstStart===null)&&(this._viewRequestBurstStart=e);let n=t.maxWait-(e-this._viewRequestBurstStart);c=n<=0?0:Math.min(c,n)}else this._viewRequestBurstStart=null;clearTimeout(this._viewTimer);let l=()=>{if(!this._destroyed&&(this._viewRequestBurstStart=null,i===this.seq&&(n&&this.comm.send({type:`view`,seq:i,x0:Math.min(a.x0,a.x1),x1:Math.max(a.x0,a.x1),px:o}),r)))for(let e of this.gpuTraces){if(e.tier!==`density`)continue;let[t,n]=this._axisRange(e.xAxis,a),[r,c]=this._axisRange(e.yAxis,a);this.comm.send({type:`density_view`,seq:i,trace:e.trace.id,x0:Math.min(t,n),x1:Math.max(t,n),y0:Math.min(r,c),y1:Math.max(r,c),w:o,h:s})}};return c<=0?l():this._viewTimer=setTimeout(l,c),i},_scheduleSampleRebin(e=this.view,t={}){if(this._destroyed||this._glLost||this._sampleRebinDisabled)return;let n=(this.gpuTraces||[]).filter(e=>e.tier===`density`&&e.sampleOverlay&&e.sampleOverlay._cpu);if(!n.length)return;let r=t.seq??++this.seq,i=this._copyView(e);clearTimeout(this._rebinTimer),this._rebinTimer=setTimeout(()=>{if(!(this._destroyed||r!==this.seq))for(let e of n)this._requestSampleRebin(e,i,r)},t.delay??120)},_requestSampleRebin(e,t,n){e._homeDensity||=e.density;let[r,i]=this._axisRange(e.xAxis,t),[a,o]=this._axisRange(e.yAxis,t),[s,c]=this._axisRange(e.xAxis,this.view0),[l,u]=this._axisRange(e.yAxis,this.view0),d=Math.max(Math.abs(c-s),1e-300),f=Math.max(Math.abs(u-l),1e-300),p=Math.abs(i-r),m=Math.abs(o-a);if(p>=d*.999999&&m>=f*.999999){if(e.density!==e._homeDensity){let t=e._homeDensity;this._applySampleRebinGrid(e,{...t,tex:this._uploadGrid(t.grid,t.w,t.h,t.normMax||t.max||1)},!1)}return}if(!this._sampleRebinDisabled){if(!this._rebinWorker){if(this._rebinWorker=_t(),!this._rebinWorker){this._sampleRebinDisabled=!0;return}this._rebinWorker.onmessage=e=>this._onRebinResult(e.data),this._rebinInit=new Set}if(!this._rebinInit.has(e.trace.id)){let t=e.sampleOverlay._cpu,n=Math.min(t.x.length,t.y.length),r=new Float64Array(n),i=new Float64Array(n);for(let e=0;et.trace.id===e.trace&&t.tier===`density`);if(!t)return;let n=new Float32Array(e.grid);this._applySampleRebinGrid(t,{w:e.w,h:e.h,max:e.max,normMax:e.max,colormap:t.density.colormap,xRange:[e.x0,e.x1],yRange:[e.y0,e.y1],grid:n,tex:this._uploadGrid(n,e.w,e.h,e.max||1),lut:t.density.lut},!0)},_applySampleRebinGrid(e,t,n){e.prevDensity=e.density,e._densityFadeStart=this._now(),e.densityNormMax=t.normMax||t.max,e.density=t,e._sampleRebinned=!!n,V(this,e,e.density),this._refreshReductionBadges(),this.draw()},_applyAppend(e,t){let n=e.spec;if(!n||!n.traces)return;let r=n.buffer_layout===`split`?t:t&&t[0];if(r==null)return;let i=l(n,r),a=(e,t)=>Math.max(Math.abs(t-e),1e-300)*1e-9,o=a(this.view0.x0,this.view0.x1),s=a(this.view0.y0,this.view0.y1),c=Math.abs(this.view.x0-this.view0.x0)<=o&&Math.abs(this.view.x1-this.view0.x1)<=o&&Math.abs(this.view.y0-this.view0.y0)<=s&&Math.abs(this.view.y1-this.view0.y1)<=s,u=!c&&Math.abs(this.view.x1-this.view0.x1)<=o,d={x0:n.x_axis.range[0],x1:n.x_axis.range[1],y0:n.y_axis.range[0],y1:n.y_axis.range[1]},f={...this.view};if(c)f={...d};else if(u){let e=this.view.x1-this.view.x0;f={...this.view,x1:d.x1,x0:d.x1-e}}if((n.animation||n.traces.some(e=>!!e.animation))&&!this._glLost&&this.gl&&this.updatePayload(n,i)){this._transitionView?this._transitionView.to={...f}:this.view={...f},this._scheduleViewRequest(f,{delay:0});return}if(this.spec=n,this.axes=this._normalizeAxes(n),this._payload=i,this.view0=this._copyView({ranges:Object.fromEntries(Object.entries(this.axes).map(([e,t])=>[e,[...t.range]]))}),c)this.view=this._copyView(this.view0);else if(u){let e=this.view.x1-this.view.x0;this.view=this._viewFrom({x1:this.view0.x1,x0:this.view0.x1-e})}if(this._glLost||!this.gl)return;let p=new Set;for(let t of e.affected||[]){let e=this.gpuTraces.findIndex(e=>e.trace.id===t),r=n.traces.find(e=>e.id===t);e<0||!r||(this._destroyTraceResources(this.gpuTraces[e],p),this.gpuTraces[e]=this._buildTrace(i,r))}this._updatePickable(),this._scheduleViewRequest(this.view,{delay:0}),this.draw()},_onKernelMsg(e,t){if(!this._destroyed&&e&&!(this._glLost&&e.type!==`append`&&e.type!==`pick_result`))if(e.type===`tier_update`){if(e.seq!==this.seq)return;for(let n of e.traces){let e=this.gpuTraces.find(e=>e.trace.id===n.id);if(!e)continue;let r=this.gl,i=this._asF32(t[n.x.buf]),a=this._asF32(t[n.y.buf]),o=n.base&&e.baseBuf?this._asF32(t[n.base.buf]):null,s=Math.min(n.x.len,n.y.len);o&&(s=Math.min(s,n.base.len));let c=this._smoothArrays(e.trace,i,a,o,s),l=c||{x:i,y:a,n:s},u=this._stepArrays(e.trace,l.x,l.y,l.n);r.bindBuffer(r.ARRAY_BUFFER,e.xBuf),r.bufferData(r.ARRAY_BUFFER,u?u.x:l.x,r.STATIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,e.yBuf),r.bufferData(r.ARRAY_BUFFER,u?u.y:l.y,r.STATIC_DRAW),e.xMeta={...e.xMeta,offset:n.x.offset,scale:n.x.scale},e.yMeta={...e.yMeta,offset:n.y.offset,scale:n.y.scale},e._dashX=u?u.x:l.x,e._dashY=u?u.y:l.y,o&&(r.bindBuffer(r.ARRAY_BUFFER,e.baseBuf),r.bufferData(r.ARRAY_BUFFER,c?c.extra:o,r.STATIC_DRAW),e.baseMeta={...e.baseMeta,offset:n.base.offset,scale:n.base.scale}),e.n=u?u.n:l.n}this.draw()}else if(e.type===`density_update`){if(e.seq!==void 0&&e.seq!==this.seq)return;let n=e.traces||[],r=new Set(n.map(e=>Number(e.id)));r.size===0&&e.trace!==void 0&&r.add(Number(e.trace));let i=r.size===0&&e.stale,a=t=>{e.seq!==void 0&&t._lodPendingSeq!==e.seq||(t._lodPendingView=null,t._lodPendingSeq=null,t._lodPendingAt=null)};if(r.size||i)for(let e of this.gpuTraces)e.tier===`density`&&(!i&&!r.has(e.trace.id)||a(e));for(let e of n){let n=this.gpuTraces.find(t=>t.trace.id===e.id&&t.tier===`density`);if(n){if(a(n),e.mode===`points`){this._applyDrill(n,e,t);continue}$e(this,n,e,t)}}this._updatePickable(),this.draw()}else if(e.type===`append`)this._applyAppend(e,t);else if(e.type===`pick_result`){if(e.seq!==void 0&&e.seq!==this._pickSeq)return;if(!e.row){this._hideTooltip();return}let t=this._lastRow;if(t&&t.trace===e.row.trace&&t.index===e.row.index)for(let[n,r]of Object.entries(t))e.row[n]===void 0&&(e.row[n]=r);this._applySharedTooltipFields(e.row),this._lastRow=e.row,this._tooltipAnchor&&Number.isFinite(e.row.x)&&Number.isFinite(e.row.y)&&(this._tooltipAnchor.x=e.row.x,this._tooltipAnchor.y=e.row.y);let n=this._lastHoverXY;if(n&&this._renderTooltip(e.row,n.clientX,n.clientY,{announce:!this._a11yKeyboardReadout}),this._interactionFlag(`hover`)){let t={row:e.row,trace:e.row.trace,index:e.row.index,exact:!0,view:this._eventView(`hover`)};n&&Object.assign(t,this._hoverPayload(e.row,this._hoverTarget,n.clientX,n.clientY,!0)),this._dispatchChartEvent(`hover`,t)}}else e.type===`selection`?(e.bounds?this._lastBrush={mode:`box`,...e.bounds}:e.polygon&&(this._lastBrush={mode:`poly`,points:e.polygon}),(!e.traces||!e.traces.length)&&(this._lastBrush=null),this._applySelectionBuffers(e,t),this._selectionCount=e.total||0,this.draw(),this._interactionFlag(`select`,!0)&&this._dispatchChartEvent(`select`,{total:this._selectionCount,view:this._eventView(`select`)})):e.type===`state_patch`?this._applyStatePatch(e.state,{source:`api`,animate:e.animate===!0,history:e.history!==!1}):e.type===`view_nav`?e.op===`reset`&&this._navReset(e.axes):e.type===`selection_rows`&&this._applyRowsSelection(e,t)},_applySelectionBuffers(e,t){if(!e.traces||!e.traces.length){for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);return}for(let n of e.traces){let e=this.gpuTraces.find(e=>e.trace.id===n.id);if(!e)continue;let r=e.tier===`density`?e.drill:e;if(!r||!r.n||e.tier===`density`&&n.drill_seq!==void 0&&r.seq!==void 0&&n.drill_seq!==r.seq)continue;let i=this._asU32(t[n.buf]),a=new Float32Array(r.n);for(let e=0;e=d-a&&c<=f+a&&l>=p-o&&u<=m+o},_viewOverlaps(e){if(!e)return!1;let{x0:t,x1:n,y0:r,y1:i}=this.view,a=Math.min(t,n),o=Math.max(t,n),s=Math.min(r,i),c=Math.max(r,i),l=Math.min(e.x0,e.x1),u=Math.max(e.x0,e.x1),d=Math.min(e.y0,e.y1),f=Math.max(e.y0,e.y1);return a<=u&&o>=l&&s<=f&&c>=d},_viewInsideRange(e,t){return!e||!t?!1:this._viewInside({x0:e[0],x1:e[1],y0:t[0],y1:t[1]})}});var vt={linear:[0,0,1,1],ease:[.25,.1,.25,1],"ease-in":[.42,0,1,1],"ease-out":[0,0,.58,1],"ease-in-out":[.42,0,.58,1]};function yt(e,t){let n=Number(t[0]),r=Number(t[1]),i=Number(t[2]),a=Number(t[3]),o=(e,t,n)=>{let r=1-e;return 3*r*r*e*t+3*r*e*e*n+e*e*e},s=(e,t,n)=>{let r=1-e;return 3*r*r*t+6*r*e*(n-t)+3*e*e*(1-n)},c=e;for(let t=0;t<5;t++){let t=s(c,n,i);if(Math.abs(t)<1e-6)break;c=Math.max(0,Math.min(1,c-(o(c,n,i)-e)/t))}let l=0,u=1;for(let t=0;t<8;t++)o(c,n,i){let t=e*6/a;if(o<1){let e=a*Math.sqrt(1-o*o);return 1-Math.exp(-o*a*t)*(Math.cos(e*t)+o*a/e*Math.sin(e*t))}return 1-Math.exp(-a*t)*(1+a*t)},c=s(1),l=Math.abs(c)>1e-9?s(e)/c:e;return Math.max(0,Math.min(1.15,l))}function $(e,t){return t&&typeof t==`object`&&!Array.isArray(t)&&t.type===`spring`?bt(e,t):yt(e,Array.isArray(t)?t:vt[t]||vt[`ease-out`])}Object.assign(Q.prototype,{_resolvedAnimation(e){return{...this.spec.animation||{},...e&&e.animation||{},_present:!!this.spec.animation||!!(e&&e.animation)}},_animationEnabled(e){return!e._present||e.enabled===!1?!1:e.enabled===!0||!this._prefersReducedMotion()},_defaultEntrance(e){return e===`line`||e===`area`||e===`error_band`?`reveal`:e===`bar`||e===`column`?`grow`:e===`scatter`||e===`errorbar`?`scale`:`none`},_setTransitionVisual(e,t,n,r){let i=Math.max(0,Math.min(1,n));if(e._transitionOpacity=1,e._transitionScale=1,e._transitionReveal=1,e._transitionGrow=1,t===`exit`){e._transitionOpacity=0;return}if(t===`update`){e._transitionPositionProgress=i;return}let a=r.enter||`auto`;a===`auto`&&(a=this._defaultEntrance(e.trace.kind)),a!==`none`&&(a===`scale`&&(e.trace.kind===`scatter`||e.trace.kind===`errorbar`?e._transitionScale=i:e.trace.kind===`bar`||e.trace.kind===`column`?e._transitionGrow=i:(e.trace.kind===`line`||e.trace.kind===`area`||e.trace.kind===`error_band`)&&(e._transitionReveal=i)),a===`reveal`&&(e._transitionReveal=i),a===`grow`&&(e._transitionGrow=i))},_clearTransitionVisual(e){delete e._transitionOpacity,delete e._transitionScale,delete e._transitionReveal,delete e._transitionGrow,delete e._transitionPositionProgress,delete e._transitionPhase,delete e._transitionPrevXValues,delete e._transitionPrevYValues,delete e._transitionPrevPosValues,delete e._transitionPrevValue1Values,delete e._transitionPrevValue0Values,delete e._transitionPrevWidth,delete e._transitionPositionInterpolated,this._deleteBuffers(e,[`_transitionPrevXBuf`,`_transitionPrevYBuf`,`_transitionPrevPosBuf`,`_transitionPrevValue1Buf`,`_transitionPrevValue0Buf`])},_emitAnimationLifecycle(e,t,n={}){let r={stage:e,phase:t,...n,view:this._eventView(`animation_${e}`)};this._dispatchChartEvent(`animation_${e}`,r),this.comm?.send?.({type:`animation_${e}`,phase:t,...n})},_runDataAnimation(e,t,n=[]){this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf);let r=(this._dataAnimEpoch||0)+1;this._dataAnimEpoch=r;let i=[];for(let n of t){let t=this._resolvedAnimation(n.trace),r=n._transitionPhase||e;if(!this._animationEnabled(t)||r===`enter`&&t.enter===`none`||r===`update`&&t.update===`none`){this._clearTransitionVisual(n);continue}i.push({g:n,config:t,phase:r,delay:Number(t.delay)||0,duration:Math.max(0,Number(t.duration)||0)})}for(let e of n)e._transitionOpacity=0;if(!i.length){for(let e of t)this._clearTransitionVisual(e);return this._transitionView&&=(this.view={...this._transitionView.to},null),this._destroyTransitionOldTraces(),this.draw(),!1}let a=this._now();this._dataAnim={epoch:r,phase:e,start:a},this._emitAnimationLifecycle(`start`,e);let o=()=>{if(this._destroyed||!this._dataAnim||this._dataAnim.epoch!==r)return;let t=this._now(),n=!1,s=0;for(let e of i){let r=e.duration<=0?+(t>=a+e.delay):Math.max(0,Math.min(1,(t-a-e.delay)/e.duration));this._transitionView&&(s=Math.max(s,r));let i=$(r,e.config.easing);this._setTransitionVisual(e.g,e.phase,i,e.config),r<1&&(n=!0)}if(this._transitionView){let e=$(s,(this.spec.animation||{}).easing),t=this._transitionView.from,n=this._transitionView.to;this.view={x0:t.x0+(n.x0-t.x0)*e,x1:t.x1+(n.x1-t.x1)*e,y0:t.y0+(n.y0-t.y0)*e,y1:t.y1+(n.y1-t.y1)*e}}if(this.draw(),n)this._dataAnimRaf=requestAnimationFrame(o);else{this._dataAnimRaf=null;for(let e of i)this._clearTransitionVisual(e.g);this._finishDataAnimation(e)}};return this._dataAnimRaf=requestAnimationFrame(o),!0},_finishDataAnimation(e){this._dataAnim=null,this._transitionView&&=(this.view={...this._transitionView.to},null),this._destroyTransitionOldTraces(),this._emitAnimationLifecycle(`end`,e)},_startEntranceAnimation(){let e=Number(this.spec.animation_capture_progress);if(Number.isFinite(e)&&e>=0&&e<=1){for(let t of this.gpuTraces||[]){let n=this._resolvedAnimation(t.trace);n._present&&n.enabled!==!1&&n.enter!==`none`?this._setTransitionVisual(t,`enter`,$(e,n.easing),n):this._clearTransitionVisual(t)}this.draw();return}this._runDataAnimation(`enter`,this.gpuTraces||[])},_destroyTransitionOldTraces(){if(!this._transitionOldTraces||!this.gl){this._transitionOldTraces=null;return}let e=new Set;for(let t of this._transitionOldTraces)this._destroyTraceResources(t,e);this._transitionOldTraces=null},_transitionMatches(e,t,n){let r=n.match||`index`,i=[],a=t.trace.animation_fallback||null;if((e.n||0)>2e5||(t.n||0)>2e5)return{strategy:`snap`,pairs:i,fallback:a||`snap:${r}-match-limit`};if(r===`key`)if(e._transitionKeyIndex&&t._transitionKeys)for(let n=0;n(e-(Number(t.offset)||0))*(Number(t.scale)||1),c=(t,n)=>{let r=e._cpu[t],i=e[t===`x`?`_transitionPrevXValues`:`_transitionPrevYValues`],a=e._transitionPositionProgress;if(!i||!Number.isFinite(a))return this._decodeValue(r,e[`${t}Meta`],n);let o=i[n]+(r[n]-i[n])*a,s=e[`${t}Meta`];return o/(s.scale||1)+s.offset};for(let[e,n]of r.pairs){let r=c(`x`,e),i=c(`y`,e);Number.isFinite(r)&&Number.isFinite(i)&&(a[n]=s(r,t.xMeta),o[n]=s(i,t.yMeta))}return t._transitionPrevXBuf=this._upload(a),t._transitionPrevYBuf=this._upload(o),t._transitionPrevXValues=a,t._transitionPrevYValues=o,t._transitionPositionProgress=0,t._transitionPositionInterpolated=!0,e._transitionSkipExit=!0,!0},_prepareBarPositionInterpolation(e,t,n){let r=e._cpuBar,i=t._cpuBar;if(!r||!i||e.orientation!==t.orientation||t.n!==i.pos.length||e.n!==r.pos.length)return n.fallback||=`snap:layout-mismatch`,!1;let a=new Float32Array(i.pos),o=new Float32Array(i.value1),s=new Float32Array(t.n),c=(e,t)=>(e-(Number(t.offset)||0))*(Number(t.scale)||1),l=(e,t)=>e/(Number(t.scale)||1)+(Number(t.offset)||0),u=(e,t)=>e.value0?l(e.value0[t],e.value0Meta):Number(e.value0Const)||0,d=(t,n,r,i)=>{let a=e._transitionPositionProgress;return l(!t||!Number.isFinite(a)?n[i]:t[i]+(n[i]-t[i])*a,r)},f=t=>{let n=e._transitionPrevValue0Values,i=e._transitionPositionProgress,a=u(r,t);if(!n||!Number.isFinite(i))return a;let o=l(n[t],r.value1Meta);return o+(a-o)*i};for(let e=0;e[e,[...t.range]]))});let i={...this.view0};if(this._glLost||!this.gl)return this.view={...i},!0;this.gpuTraces=e.traces.map(e=>this._buildTrace(t,e));for(let e of this.gpuTraces){let t=n.find(t=>t.trace.id===e.trace.id&&t.trace.kind===e.trace.kind);if(t){let n=this._resolvedAnimation(e.trace);t._transitionExitTrace=e.trace,this._animationEnabled(n)&&n.update!==`none`&&(e._transitionMatch=this._transitionMatches(t,e,n),this._preparePositionInterpolation(t,e,n),t._transitionSkipExit=!0,this._recordAnimationFallback(e.trace,e._transitionMatch.fallback))}else e._transitionPhase=`enter`}this._transitionOldTraces=n;let a=this.gpuTraces.some(e=>{let t=this._resolvedAnimation(e.trace);return this._animationEnabled(t)&&t.update===`interpolate`&&(t.interpolate||[]).includes(`domain`)});return this._transitionView=a?{from:r,to:i}:null,a||(this.view={...i}),this._updatePickable(),this._runDataAnimation(`update`,this.gpuTraces,n)||(this.view={...i},this._transitionView=null),!0}});var xt=64;Object.assign(Q.prototype,{_initViewState(){this._historyPast=[],this._historyFuture=[],this._historyLastInteractionId=null,this._stateSelection=null,this._customTooltip=null,this.root.xy={applyState:(e,t={})=>this._applyStatePatch(e,{source:`api`,animate:t.animate===!0,history:t.history!==!1}),state:()=>this._durableState(),back:()=>this._historyBack(),forward:()=>this._historyForward()}},_durableState(){let e=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),t=this._stateSelection;return{v:1,ranges:e,selection:t==null?null:t.rows?{rows:!0}:t.range?{range:{...t.range}}:{polygon:t.polygon.map(e=>[...e])}}},_validateStatePatch(e){if(!e||typeof e!=`object`||Array.isArray(e))return`state patch must be an object`;if(e.v!==void 0&&e.v!==1)return`unsupported state version ${e.v}`;for(let t of Object.keys(e))if(![`v`,`ranges`,`selection`].includes(t))return`unknown key ${t}`;if(e.ranges!==void 0){if(!e.ranges||typeof e.ranges!=`object`||Array.isArray(e.ranges))return`ranges must be an object`;let t=new Set(this._axisIds());for(let[n,r]of Object.entries(e.ranges)){if(!t.has(n))return`unknown axis ${n}`;if(!Array.isArray(r)||r.length!==2||!r.every(e=>Number.isFinite(e))||r[0]===r[1])return`invalid range for axis ${n}`}}if(e.selection!==void 0&&e.selection!==null){let t=e.selection;if(typeof t!=`object`||Array.isArray(t))return`invalid selection`;let n=Object.keys(t);if(n.length!==1)return`invalid selection`;if(n[0]===`range`){let e=t.range;if(!e||typeof e!=`object`||![`x0`,`x1`,`y0`,`y1`].every(t=>Number.isFinite(e[t])))return`invalid selection range`}else if(n[0]===`polygon`){let e=t.polygon;if(!Array.isArray(e)||e.length<3||!e.every(e=>Array.isArray(e)&&e.length===2&&e.every(Number.isFinite)))return`invalid selection polygon`}else if(n[0]===`rows`)return`rows selections are not applicable state`;else return`invalid selection`}return null},_applyStatePatch(e,t={}){if(this._destroyed)return!1;let n=this._validateStatePatch(e);if(n)return typeof console<`u`&&console.warn&&console.warn(`xy: state patch rejected: ${n}`),!1;let r=t.source||`api`,i=++this._interactionSeq;if(e.ranges!==void 0){let n=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]]));for(let[t,r]of Object.entries(e.ranges))n[t]=[Number(r[0]),Number(r[1])];this._setView({ranges:n},{animate:t.animate===!0,source:r,phase:`end`,interactionId:i,history:t.history})}if(e.selection!==void 0){let n=e.selection,a={history:t.history,interactionId:i,source:r};if(n===null)this._clearSelection(a);else if(n.range){let{x0:e,x1:t,y0:r,y1:i}=n.range;this._sendSelect([e,r],[t,i],a)}else n.polygon&&this._sendSelectPolygon(n.polygon.map(e=>[...e]),a)}return!0},_historyEnabled(){return this._interactionFlag(`history`,!0)},_historyRecord(e={}){if(!this._historyPast||!this._historyEnabled()||this._destroyed||e.history===!1||e.source===`linked`||e.source===`history`)return;let t=e.interactionId;t!=null&&t===this._historyLastInteractionId||(this._historyLastInteractionId=t===void 0?null:t,this._historyPast.push(this._durableState()),this._historyPast.length>xt&&this._historyPast.shift(),this._historyFuture.length=0,this._updateHistoryButtons())},_historyBack(){if(!this._historyEnabled()||!this._historyPast.length)return!1;let e=this._historyPast.pop();return this._historyFuture.push(this._durableState()),this._historyApply(e),!0},_historyForward(){if(!this._historyEnabled()||!this._historyFuture.length)return!1;let e=this._historyFuture.pop();return this._historyPast.push(this._durableState()),this._historyApply(e),!0},_historyApply(e){let t={v:1,ranges:e.ranges};(!e.selection||!e.selection.rows)&&(t.selection=e.selection??null),this._applyStatePatch(t,{source:`history`,animate:!0,history:!1}),this._historyLastInteractionId=null,this._updateHistoryButtons()},_updateHistoryButtons(){let e=(e,t)=>{e&&(e.disabled=!t,e.setAttribute(`aria-disabled`,String(!t)),e.style.opacity=t?``:`0.4`)};e(this._historyBackBtn,this._historyPast.length>0),e(this._historyForwardBtn,this._historyFuture.length>0)},_navReset(e){let t=Array.isArray(e)?e.filter(e=>this._axisIds().includes(e)):null;this._resetView(!0,`reset`,t)},_applyRowsSelection(e,t){this._clearLassoOverlay();for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);this._lastBrush=null,this._applySelectionBuffers(e,t),this._stateSelection={rows:!0},this._selectionCount=e.total||0,this.draw(),this._interactionFlag(`select`,!0)&&this._dispatchChartEvent(`select`,{total:this._selectionCount,view:this._eventView(`select`)})},_axisBandNavigable(e){if(!this._interactionFlag(`navigation`,!0))return!1;let t=this._interactionFlag(`pan`,!0)&&this._axisPolicy(`pan_axes`).includes(e),n=this._interactionFlag(`zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(e);return t||n},_axisBandCursor(e,t){return this._interactionFlag(`zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(e)?t===`x`?`ew-resize`:`ns-resize`:`grab`},_initAxisBands(){if(this.root){this._axisBands={};for(let e of this._axisIds()){if(!this._axisBandNavigable(e))continue;let t=this._axisDim(e),n=document.createElement(`div`);n.dataset.xyAxisBand=e,n.style.cssText=`position:absolute;z-index:2;touch-action:none;cursor:${this._axisBandCursor(e,t)};`,this.root.appendChild(n),this._axisBands[e]=n,this._bindAxisBand(n,e,t)}this._layoutAxisBands()}},_layoutAxisBands(){if(this._axisBands)for(let[e,t]of Object.entries(this._axisBands)){let n=this._axisDim(e),r=this._axis(e).side;n===`x`?(t.style.left=`${this.plot.x}px`,t.style.width=`${this.plot.w}px`,r===`top`?(t.style.top=`${Math.max(0,this.plot.y-24)}px`,t.style.height=`30px`):(t.style.top=`${this.plot.y+this.plot.h-6}px`,t.style.height=`30px`)):(t.style.top=`${this.plot.y}px`,t.style.height=`${this.plot.h}px`,r===`right`?(t.style.left=`${this.plot.x+this.plot.w-6}px`,t.style.width=`30px`):(t.style.left=`${Math.max(0,this.plot.x-24)}px`,t.style.width=`30px`))}},_axisBandValue(e,t,n){let r=this.canvas.getBoundingClientRect();if(this._axisDim(e)===`x`){let n=Math.max(0,Math.min(r.width,t-r.left));return this._dataFromCanvas(n,0,e,`y`)[0]}let i=Math.max(0,Math.min(r.height,n-r.top));return this._dataFromCanvas(0,i,`x`,e)[1]},_bindAxisBand(e,t,n){let r=null;this._listen(e,`wheel`,e=>{if(!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._interactionFlag(`wheel_zoom`,!0)||!this._axisPolicy(`zoom_axes`).includes(t))return;e.preventDefault();let n=1.0015**e.deltaY,r=this.canvas.getBoundingClientRect(),i=(e.clientX-r.left)/r.width,a=1-(e.clientY-r.top)/r.height;this._queueWheelZoom(n,i,a,[t])},{passive:!1}),this._listen(e,`pointerdown`,n=>{if(!(n.pointerType===`mouse`&&n.button!==0)&&this._interactionFlag(`navigation`,!0)){this._cancelViewAnimation(),r={pointerId:n.pointerId,sx:n.clientX,sy:n.clientY,view:this._copyView(this.view),d0:this._axisBandValue(t,n.clientX,n.clientY),mode:null,interactionId:++this._interactionSeq,changedAxes:[]};try{e.setPointerCapture(n.pointerId)}catch{}this.tooltip.style.display=`none`,n.preventDefault()}});let i=()=>this._interactionFlag(`pan`,!0)&&this._axisPolicy(`pan_axes`).includes(t)?!0:this._axisContained(t),a=()=>this._interactionFlag(`zoom`,!0)&&this._interactionFlag(`box_zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(t);this._listen(e,`pointermove`,o=>{if(!r||o.pointerId!==r.pointerId)return;let s=o.clientX-r.sx,c=o.clientY-r.sy;if(!r.mode){if(Math.hypot(s,c)<=3)return;r.mode=Math.abs(n===`x`?s:c)>=Math.abs(n===`x`?c:s)?i()?`pan`:a()?`span`:`none`:a()?`span`:i()?`pan`:`none`,r.mode===`pan`&&(e.style.cursor=`grabbing`)}if(r.mode===`pan`){let e=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,r.view)]])),i=this._axis(t),[a,o]=this._axisRange(t,r.view),l=this._axisCoord(i,a),u=this._axisCoord(i,o);if(![l,u].every(Number.isFinite)||l===u)return;let d=n===`x`?this.plot.w:this.plot.h,f=(n===`x`?s:c)/d*(u-l),p=n===`x`?-f:f;e[t]=[this._axisValue(i,l+p),this._axisValue(i,u+p)];let m=this._setView({ranges:e},{source:`pan_drag`,phase:`update`,interactionId:r.interactionId});r.changedAxes=[...new Set([...r.changedAxes,...m])]}else if(r.mode===`span`){let e=this.root.getBoundingClientRect();if(this.selRect.dataset.xyBand=`zoom`,this.selRect.style.display=`block`,n===`x`){let t=Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,Math.min(r.sx,o.clientX)-e.left)),n=Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,Math.max(r.sx,o.clientX)-e.left));this.selRect.style.left=`${t}px`,this.selRect.style.width=`${Math.max(0,n-t)}px`,this.selRect.style.top=`${this.plot.y}px`,this.selRect.style.height=`${this.plot.h}px`}else{let t=Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,Math.min(r.sy,o.clientY)-e.top)),n=Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,Math.max(r.sy,o.clientY)-e.top));this.selRect.style.top=`${t}px`,this.selRect.style.height=`${Math.max(0,n-t)}px`,this.selRect.style.left=`${this.plot.x}px`,this.selRect.style.width=`${this.plot.w}px`}}o.preventDefault()});let o=i=>{if(!r||i.pointerId!==r.pointerId)return;let a=r;if(r=null,e.style.cursor=this._axisBandCursor(t,n),a.mode===`span`&&(this.selRect.style.display=`none`),i.type!==`pointercancel`){if(a.mode===`pan`&&a.changedAxes.length)this._emitViewChange(`pan_drag`,{axes:a.changedAxes,phase:`end`,interactionId:a.interactionId});else if(a.mode===`span`){let e=this._axisBandValue(t,i.clientX,i.clientY),n=this._axis(t),r=this._axisCoord(n,a.d0),o=this._axisCoord(n,e),s=Math.max(Math.abs(r),Math.abs(o),1e-30)*1e-12;if(![r,o].every(Number.isFinite)||Math.abs(o-r)[e,[...this._axisRange(e)]]));p[t]=[this._axisValue(n,u?f:d),this._axisValue(n,u?d:f)],this._setView({ranges:p},{animate:!0,anchors:{[t]:.5},source:`box_zoom`,phase:`end`,interactionId:a.interactionId})}}};this._listen(e,`pointerup`,o),this._listen(e,`pointercancel`,o)},_seriesColorCss(e){let t=e&&e.color;if(!Array.isArray(t)||t.length<3)return null;let n=e=>Math.max(0,Math.min(255,Math.round(Number(e)*255)));return`rgb(${n(t[0])}, ${n(t[1])}, ${n(t[2])})`},_hoverPayload(e,t,n,r,i=!1){let a=this.root.getBoundingClientRect(),o=this.canvas.getBoundingClientRect(),s=Math.max(0,Math.min(o.width,n-o.left)),c=Math.max(0,Math.min(o.height,r-o.top)),l={};for(let e of this._axisIds()){let t=this._axisDim(e),[n,r]=this._dataFromCanvas(s,c,t===`x`?e:`x`,t===`y`?e:`y`);l[e]=t===`x`?n:r}let u=t&&t.g,d=e?[{trace:u&&u.trace&&u.trace.name||e.trace,index:e.index,row:e,x_axis:u&&u.xAxis||`x`,y_axis:u&&u.yAxis||`y`,color:this._seriesColorCss(u)}]:[],f={active:!0,cursor:{px:[n-a.left,r-a.top],data:l},points:d};return i&&(f.exact=!0),f},setCustomTooltip(e){if(this.tooltip){if(!e){this._customTooltip=null,delete this.tooltip.dataset.xyCustomTooltip,this.tooltip.style.background=``,this.tooltip.style.border=``,this.tooltip.style.padding=``,this.tooltip.replaceChildren(),this.tooltip.style.display=`none`;return}this._customTooltip=e,this.tooltip.dataset.xyCustomTooltip=``,this.tooltip.style.background=`transparent`,this.tooltip.style.border=`none`,this.tooltip.style.padding=`0`,e.style.display=``,this.tooltip.replaceChildren(e)}}});function St({model:e,el:t}){let n=e.get(`spec`),r=new Q(t,n,l(n,e.get(`buffers`)),{send:t=>e.send(t),wantsViewChange:()=>e.get(`spec`)?.interaction?._transport_view_change===!0,onMessage:t=>{let n=(e,n)=>t(e,n);return e.on(`msg:custom`,n),()=>e.off?.(`msg:custom`,n)}}),i={seq:n.append?.seq??null,buffers:e.get(`buffers`)},a=()=>{let t=e.get(`spec`),n=t?.append;if(!n)return;let a=e.get(`buffers`);n.seq===i.seq&&a===i.buffers||c(t,a)&&(i.seq=n.seq,i.buffers=a,r._applyAppend({type:`append`,affected:n.affected,spec:t},a))};return e.on(`change:spec`,a),e.on(`change:buffers`,a),()=>{e.off?.(`change:spec`,a),e.off?.(`change:buffers`,a),r.destroy()}}function Ct(e,t,n){let r=s(n),i=new Q(e,t,r,null),a=e=>i._columnView(r,t.columns[e]);for(let e of i.gpuTraces)J(e.trace.kind).retainCpu&&e.tier!==`density`&&(e._cpu={x:a(e.trace.x),y:a(e.trace.y),xMeta:e.xMeta,yMeta:e.yMeta},e.trace.color&&Number.isInteger(e.trace.color.buf)&&(e._cpu.color=a(e.trace.color.buf)),e.trace.size&&Number.isInteger(e.trace.size.buf)&&(e._cpu.size=a(e.trace.size.buf)));return i}var wt={render:St,decodeFrame:m};return e.ChartView=Q,e.MARK_KINDS=q,e.decodeFrame=m,e.default=wt,e.markOf=J,e.render=St,e.renderStandalone=Ct,e})({}); \ No newline at end of file diff --git a/tests/pyplot/test_matplotlib_mismatch_regressions.py b/tests/pyplot/test_matplotlib_mismatch_regressions.py new file mode 100644 index 00000000..3dde0532 --- /dev/null +++ b/tests/pyplot/test_matplotlib_mismatch_regressions.py @@ -0,0 +1,110 @@ +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt +from xy._figure import Figure + + +def test_axis_equal_before_fill_keeps_data_autoscaling() -> None: + _fig, ax = plt.subplots() + ax.axis("equal") + ax.fill([-3.0, 4.0, 1.0], [-2.0, 0.0, 5.0]) + + assert "domain" not in ax._axis["x"] + assert "domain" not in ax._axis["y"] + assert ax._entry_extent("x") == (-3.0, 4.0) + assert ax._entry_extent("y") == (-2.0, 5.0) + assert ax._aspect_bounds == pytest.approx((-3.0, 4.0, -2.0, 5.0)) + + +def test_barh_error_components_stay_on_the_requested_axes() -> None: + _fig, ax = plt.subplots() + ax.barh([0.0, 1.0], [3.0, 4.0], xerr=[0.2, 0.3], yerr=[0.4, 0.5]) + + errorbar = next(entry for entry in ax._entries if entry.get("factory") == "errorbar") + np.testing.assert_allclose(errorbar["kwargs"]["xerr"], [0.2, 0.3]) + np.testing.assert_allclose(errorbar["kwargs"]["yerr"], [0.4, 0.5]) + + +def test_direct_bar_and_mesh_strokes_match_each_face_without_extra_color_data() -> None: + rgba = np.array([[1.0, 0.0, 0.0, 0.4], [0.0, 0.0, 1.0, 0.8]]) + bars = Figure().bar([0.0, 1.0], [2.0, 3.0], color=rgba, stroke_width=[1.0, 2.0]) + bar_spec = bars.build_payload()[0]["traces"][0] + assert bar_spec["stroke"] == {"mode": "match_fill"} + bar_svg = bars.to_svg() + assert 'stroke="rgb(255,0,0)"' in bar_svg + assert 'stroke="rgb(0,0,255)"' in bar_svg + + mesh = Figure().triangle_mesh( + [0.0, 2.0], + [0.0, 0.0], + [1.0, 3.0], + [0.0, 0.0], + [0.0, 2.0], + [1.0, 1.0], + color=rgba, + stroke_width=[1.0, 2.0], + ) + mesh_spec = mesh.build_payload()[0]["traces"][0] + assert mesh_spec["stroke"] == {"mode": "match_fill"} + mesh_svg = mesh.to_svg() + assert 'stroke="rgb(255,0,0)"' in mesh_svg + assert 'stroke="rgb(0,0,255)"' in mesh_svg + + +def test_imshow_interpolates_truecolor_and_honors_rgba_stage() -> None: + _fig, ax = plt.subplots() + rgb = np.zeros((2, 2, 3), dtype=float) + rgb[0, 0] = 1.0 + truecolor = ax.imshow(rgb, interpolation="bilinear") + assert np.asarray(truecolor._entry["z"]).shape == (512, 512, 3) + + _fig, (data_ax, rgba_ax) = plt.subplots(1, 2) + values = np.array([[0.0, 1.0], [1.0, 0.0]]) + data_image = data_ax.imshow( + values, cmap="viridis", interpolation="bilinear", interpolation_stage="data" + ) + rgba_image = rgba_ax.imshow( + values, cmap="viridis", interpolation="bilinear", interpolation_stage="rgba" + ) + assert np.asarray(data_image._entry["z"]).shape == (512, 512) + assert np.asarray(rgba_image._entry["z"]).shape == (512, 512, 4) + + +def test_named_imshow_filters_are_not_all_bilinear_aliases() -> None: + values = np.array([[0.0, 0.0, 0.0, 0.0], [0.0, 1.0, 1.0, 0.0]] * 2) + _fig, (linear_ax, lanczos_ax) = plt.subplots(1, 2) + linear = np.asarray(linear_ax.imshow(values, interpolation="bilinear")._entry["z"]) + lanczos = np.asarray(lanczos_ax.imshow(values, interpolation="lanczos")._entry["z"]) + assert not np.allclose(linear, lanczos) + + +def test_imshow_interpolation_does_not_spread_one_nan_over_the_image() -> None: + values = np.arange(9.0).reshape(3, 3) + values[0, 0] = np.nan + _fig, ax = plt.subplots() + interpolated = np.asarray(ax.imshow(values, interpolation="bilinear")._entry["z"]) + assert np.isfinite(interpolated).any() + assert np.isfinite(interpolated[-1, -1]) + + +def test_regular_gouraud_pcolormesh_uses_a_smooth_scalar_surface() -> None: + _fig, ax = plt.subplots() + values = np.arange(15.0).reshape(3, 5) + artist = ax.pcolormesh( + np.arange(5.0), + np.arange(3.0), + values, + shading="gouraud", + vmin=0.0, + vmax=14.0, + ) + assert artist._entry["factory"] == "heatmap" + smooth = np.asarray(artist._entry["args"][0]) + assert smooth.shape == (256, 256) + assert np.unique(smooth).size > values.size + + with pytest.raises(ValueError, match="matching shapes"): + ax.pcolormesh(np.arange(6.0), np.arange(4.0), values, shading="gouraud") diff --git a/tests/pyplot/test_p3_option_contracts.py b/tests/pyplot/test_p3_option_contracts.py index 3b78f346..1eee66e4 100644 --- a/tests/pyplot/test_p3_option_contracts.py +++ b/tests/pyplot/test_p3_option_contracts.py @@ -36,7 +36,6 @@ def test_plot_marker_styles_and_markevery_reach_marker_entry() -> None: (lambda ax: ax.fill_betweenx([0, 1], [0, 1], step="pre"), "step"), (lambda ax: ax.arrow(0, 0, 1, 1, shape="left"), "head shape"), (lambda ax: ax.errorbar([0], [1], yerr=0.2, barsabove=True), "barsabove"), - (lambda ax: ax.imshow([[1]], interpolation_stage="rgba"), "interpolation_stage"), (lambda ax: ax.psd([1, 2, 3], window=np.ones(3)), "window"), ], )