From 1b4897ae0eb6a62c0265bff221bb813b0cad28c2 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Mon, 19 Oct 2026 18:34:59 -0700 Subject: [PATCH 1/9] feat: add memorygraph viewer with live polling and portable snapshot reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the memorygraph side tool: a cosmos.gl constellation of the agent memory vault. The builder can serve a live view that refreshes as memory grows, or freeze the current graph into a single self-contained HTML report for sharing. Generated graph data and reports hold raw memory entries and stay git-ignored. ஃ Generated with Phosphor --- tools/memorygraph/.gitignore | 5 + tools/memorygraph/README.md | 41 + tools/memorygraph/_check.py | 6 + tools/memorygraph/_cosmos3.d.ts | 1034 ++++++++ tools/memorygraph/_cosmos_check.js | 3530 ++++++++++++++++++++++++++++ tools/memorygraph/build_graph.py | 225 ++ tools/memorygraph/view.html | 950 ++++++++ 7 files changed, 5791 insertions(+) create mode 100644 tools/memorygraph/.gitignore create mode 100644 tools/memorygraph/README.md create mode 100644 tools/memorygraph/_check.py create mode 100644 tools/memorygraph/_cosmos3.d.ts create mode 100644 tools/memorygraph/_cosmos_check.js create mode 100644 tools/memorygraph/build_graph.py create mode 100644 tools/memorygraph/view.html diff --git a/tools/memorygraph/.gitignore b/tools/memorygraph/.gitignore new file mode 100644 index 0000000..964a29b --- /dev/null +++ b/tools/memorygraph/.gitignore @@ -0,0 +1,5 @@ +# generated graph data and snapshot reports contain raw memory +# entries — never commit them +graph.json +report*.html +__pycache__/ diff --git a/tools/memorygraph/README.md b/tools/memorygraph/README.md new file mode 100644 index 0000000..afc3f7d --- /dev/null +++ b/tools/memorygraph/README.md @@ -0,0 +1,41 @@ +# memorygraph + +Visualization of the phosphor agent memory store (`.phosphor/memory/.phosphor-index/memory.db`). +The builder reads the SQLite vault read-only and clusters entries by thread and tag. + +## Usage + +Live view (polling server — the page self-refreshes as memory grows): + +``` +python build_graph.py --serve +# open http://127.0.0.1:8642/view.html +``` + +Portable snapshot report (single self-contained HTML file, data embedded): + +``` +python build_graph.py --report report.html +``` + +The report opens offline with no server and no polling; ship it as-is. + +Plain static mode (one-shot load, no polling): + +``` +python build_graph.py # writes graph.json +python -m http.server 8642 # then open view.html +``` + +All modes accept an explicit `memory.db` path as the first argument; otherwise +the vault is auto-discovered by walking up from the current directory and +checking the usual per-user phosphor data locations. + +## Notes + +- The viewer renders with cosmos.gl 3.5.1 (GPU force graph) via CDN; only + thread/tag hub nodes carry text labels. +- `graph.json` and `report*.html` hold raw memory entries and are git-ignored. +- Plan of record: replace this Python builder with serving from the phosphor + Go binary itself, plus a JS chat app so the web GUI is an alternative + front-end to the TUI. \ No newline at end of file diff --git a/tools/memorygraph/_check.py b/tools/memorygraph/_check.py new file mode 100644 index 0000000..2035f35 --- /dev/null +++ b/tools/memorygraph/_check.py @@ -0,0 +1,6 @@ +import io, re +s = io.open('tools/memorygraph/_cosmos_check.js', encoding='utf-8').read() +for pat in ['inputMasses', 'pointMasses', 'setPointMasses', 'masses']: + hits = re.findall(r'.{40}' + pat + r'.{40}', s) + print(pat, len(hits)) + for h in hits[:2]: print(' ', repr(h)) \ No newline at end of file diff --git a/tools/memorygraph/_cosmos3.d.ts b/tools/memorygraph/_cosmos3.d.ts new file mode 100644 index 0000000..8530dff --- /dev/null +++ b/tools/memorygraph/_cosmos3.d.ts @@ -0,0 +1,1034 @@ +import { Device, RenderPass } from '@luma.gl/core'; +import { GraphConfigInterface, GraphConfig } from './config'; +import { GraphData } from './modules/GraphData'; +import { GraphSimulation, PointPositionTexture, PositionTextureSource, PositionsReadOptions } from './simulation'; +export declare class Graph implements PositionTextureSource { + /** Current graph configuration. Always fully populated with default values for any unset properties. */ + config: GraphConfigInterface; + /** The data model holding the ingested input arrays (owned by the simulation). */ + readonly graph: GraphData; + /** Promise that resolves when the graph is fully initialized and ready to use */ + readonly ready: Promise; + /** Whether the graph has completed initialization */ + isReady: boolean; + /** + * The force simulation behind this graph. It owns the device, the data model, + * the point positions and the forces. `Graph` adds rendering, the view and + * user input on top of it. + * + * It is the same `GraphSimulation` an app can run on its own. Apps that embed + * cosmos.gl use it to reach what `Graph` does not expose: the device, the + * seeded random generator in `store`, and the data model. + */ + readonly simulation: GraphSimulation; + /** The graph's one tracker, following the set given to `trackPointPositionsByIndices`. */ + private tracker; + /** Canvas element, assigned asynchronously during device initialization */ + private canvas; + private attributionDivElement; + private canvasD3Selection; + private device; + private requestAnimationFrameId; + /** + * Detects canvas element resizes: + * resize → `_shouldSyncScreenSize` + `requestRender()` → `syncScreenSize()` next frame. + * The work always runs in-frame, so resizing behaves the same whether the + * loop was running or idle. + */ + private resizeObserver; + /** Set by the ResizeObserver; the next frame applies it via syncScreenSize(). */ + private _shouldSyncScreenSize; + private isRightClickMouse; + /** + * Touch/pen long-press timer. Set on pointerdown for non-mouse pointers and + * cancelled on pointerup, pointercancel, or movement past + * LONG_PRESS_MOVE_THRESHOLD_PX. When it fires, the contextmenu callback chain + * runs and the synthesized click is suppressed. + */ + private _longPressTimerId; + private _longPressStartX; + private _longPressStartY; + /** + * Set when long-press fires contextmenu (or a browser-dispatched contextmenu + * handles itself) so the synthesized click that follows the same touch is + * dropped instead of routed to onPointClick/onBackgroundClick/onLinkClick. + * Consumed by onClick; also cleared on next pointerdown. + */ + private _shouldSuppressNextClick; + /** + * Namespaces the listeners this instance registers on `document`. With a + * shared namespace, instances replace each other's handlers and one + * instance's destroy() removes another's. + */ + private readonly _instanceId; + /** The simulation's store — shared so both halves observe one engine state. */ + private readonly store; + /** The simulation's position engine — aliased for the render/interaction code. */ + private points; + private lines; + private readonly zoomInstance; + private readonly transition; + private readonly dragInstance; + private fpsMonitor; + private currentEvent; + /** + * The value of `_findHoveredItemExecutionCount` is incremented by 1 on each animation frame. + * When the counter reaches MAX_HOVER_DETECTION_DELAY (default 4), it is reset to 0 and hover detection runs. + */ + private _findHoveredItemExecutionCount; + /** + * If no pointer is over the Canvas, hover detection will not be executed. + */ + private _isPointerOnCanvas; + /** + * Last mouse position for detecting significant mouse movement + */ + private _lastMouseX; + private _lastMouseY; + /** + * Last checked mouse position for hover detection + */ + private _lastCheckedMouseX; + private _lastCheckedMouseY; + /** + * Force hover detection on next frame, bypassing mouse movement check. + * Set when scene changes but mouse stays still (after simulation or zoom ends). + */ + private _shouldForceHoverDetection; + /** + * View transform the picking buffer was last validated against; a change + * (zoom, resize) marks the buffer stale (see updatePickingBufferStaleness). + */ + private _lastPickingMatrix; + /** + * After setting data and render graph at a first time, the fit logic will run + * */ + private _isFirstRenderAfterInit; + private _fitViewOnInitTimeoutID; + private isPointColorUpdateNeeded; + private isPointShapeUpdateNeeded; + private isPointImageIndicesUpdateNeeded; + private isLinksUpdateNeeded; + private isLinkColorUpdateNeeded; + private isLinkWidthUpdateNeeded; + private isLinkArrowUpdateNeeded; + private isLinkStyleUpdateNeeded; + private isPointImageSizesUpdateNeeded; + private _isDestroyed; + /** + * Simulation-only instance (constructed without a `div`): owns no canvas, installs + * no input handlers, never schedules frames, and never clears or submits the device. + */ + private readonly _isHeadless; + /** + * Create a new Graph instance. + * @param div - Container element for the graph canvas. Pass `null` (or `undefined`) + * to create a **headless** simulation-only instance: no canvas is adopted or + * reparented, no zoom/drag/pointer/keyboard listeners are installed, no internal + * render loop runs, and an externally supplied device is never cleared, submitted, + * resized, or reparented. Drive the simulation with `step()` and read results via + * `getPointPositions*()` or `getPointPositionTexture()`. View-dependent APIs + * (zoom, fit, screen-space queries) are inert, and transitions snap instead of + * animating (nothing advances them without a render loop). + * @param config - Optional configuration. Unset properties use default values. + */ + constructor(div: HTMLDivElement | null | undefined, config?: GraphConfig, devicePromise?: Promise); + /** + * Returns the current simulation progress + */ + get progress(): number; + /** + * A value that gives information about the running simulation status. + */ + get isSimulationRunning(): boolean; + /** + * The maximum point size. + * This value is the maximum size of the `gl.POINTS` primitive that WebGL can render on the user's hardware. + */ + get maxPointSize(): number; + /** + * Apply a new configuration. Changes take effect immediately. + * + * **Important:** Every call fully resets the configuration to defaults first, + * then applies the provided values on top. Properties not included in `config` + * will revert to their default values — they are not preserved from the previous call. + * + * @param config - Configuration object. Only include the properties you want to set. + */ + setConfig(config: GraphConfig): void; + /** + * Partially updates the graph configuration. Only the provided properties + * will be changed; all other properties retain their current values. + * + * Properties set to `undefined` will be reset to their default values. + * + * @param config - A partial configuration object with the properties to update. + */ + setConfigPartial(config: GraphConfig): void; + /** + * Sets the positions for the graph points. + * + * @param {Float32Array} pointPositions - A Float32Array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn], + * where `n` is the index of the point. + * Example: `new Float32Array([1, 2, 3, 4, 5, 6])` sets the first point to (1, 2), the second point to (3, 4), and so on. + * @param {boolean | undefined} dontRescale - For this call only, don't rescale the points. + * - `true`: Don't rescale. + * - `false` or `undefined` (default): Use the behavior defined by `config.rescalePositions`. + * @note If `transitionDuration > 0` and the simulation is running, the simulation is automatically + * paused for the transition and remains paused afterwards. Call `unpause()` to resume it. + * @note A point whose position is `NaN` (either coordinate) is treated as **absent**: it fades out in place while every + * other point keeps its index and on-screen position (no array compaction, no slide). Set a point to + * `NaN` to remove it, and back to a real position to add one — both animate. By default an absent point + * fades to nothing; pass per-point `setPointSizes` / `setPointColors` to customize the exit look. + * Absent points are excluded from the force layout, so this is safe with the simulation on or off. + * cosmos.gl does not auto-compact the gaps — drop them yourself and snap the renumber with + * `render(undefined, 0)`. + */ + setPointPositions(pointPositions: Float32Array, dontRescale?: boolean | undefined): void; + /** + * Sets the colors for the graph points. + * + * @param {Float32Array} pointColors - A Float32Array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], + * where each color is represented in RGBA format. + * Example: `new Float32Array([1, 0, 0, 1, 0, 1, 0, 1])` sets the first point to red and the second point to green. + * An array whose length does not match the point count is ignored: every channel then + * resolves as `NaN` does (see the note). Pass an empty array to go back to the defaults. + * @note A `NaN` channel resolves to the config default for a normal point, or to the exit default + * (transparent) for an **absent** point (one whose position is `NaN`) — letting you control how a + * removed point fades out (see `setPointPositions`). + */ + setPointColors(pointColors: Float32Array): void; + /** + * Gets the current colors of the graph points, with `NaN` channels + * resolved to the config default (or the exit default for an absent point). + * + * @returns {Float32Array} A **new** Float32Array (a snapshot — safe to mutate, computed on + * each call) of point colors in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], + * where each color is in RGBA format. Returns an empty Float32Array if no point colors are set. + */ + getPointColors(): Float32Array; + /** + * Sets the sizes for the graph points. + * + * @param {Float32Array} pointSizes - A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen], + * where `n` is the index of the point. + * Example: `new Float32Array([10, 20, 30])` sets the first point to size 10, the second point to size 20, and the third point to size 30. + * An array whose length does not match the point count is ignored: every size then + * resolves as `NaN` does (see the note). Pass an empty array to go back to the defaults. + * @note A `NaN` size resolves to the config default for a normal point, or to the exit default (`0`) + * for an **absent** point (one whose position is `NaN`) — letting you control how a removed point + * fades out (see `setPointPositions`). + */ + setPointSizes(pointSizes: Float32Array): void; + /** + * Sets the shapes for the graph points. + * + * @param {Float32Array} pointShapes - A Float32Array representing the shapes of points in the format [shape1, shape2, ..., shapen], + * where `n` is the index of the point and each shape value corresponds to a PointShape enum: + * 0 = Circle, 1 = Square, 2 = Triangle, 3 = Diamond, 4 = Pentagon, 5 = Hexagon, 6 = Star, 7 = Cross, 8 = None. + * Example: `new Float32Array([0, 1, 2])` sets the first point to Circle, the second point to Square, and the third point to Triangle. + * Images are rendered above shapes. + */ + setPointShapes(pointShapes: Float32Array): void; + /** + * Sets the images for the graph points using ImageData objects. + * Images are rendered above shapes. + * To use images, provide image indices via setPointImageIndices(). + * A list whose images all have zero width or height cannot be packed into an atlas: it is + * rejected with a console warning and the previous images stay in use. + * + * @param {ImageData[]} imageDataArray - Array of ImageData objects to use as point images. + * Example: `setImageData([imageData1, imageData2, imageData3])` + */ + setImageData(imageDataArray: ImageData[]): void; + /** + * Sets which image each point should use from the images array. + * Images are rendered above shapes. + * + * @param {Float32Array} imageIndices - A Float32Array representing which image each point uses in the format [index1, index2, ..., indexn], + * where `n` is the index of the point and each value is an index into the images array provided to `setImageData`. + * Example: `new Float32Array([0, 1, 0])` sets the first point to use image 0, second point to use image 1, third point to use image 0. + */ + setPointImageIndices(imageIndices: Float32Array): void; + /** + * Sets the sizes for the point images. + * + * @param {Float32Array} imageSizes - A Float32Array representing the sizes of point images in the format [size1, size2, ..., sizen], + * where `n` is the index of the point. + * Example: `new Float32Array([10, 20, 30])` sets the first image to size 10, the second image to size 20, and the third image to size 30. + * @note A size counts only for a point that draws an image (see `setPointImageIndices`); for any other point it is kept but ignored. + */ + setPointImageSizes(imageSizes: Float32Array): void; + /** + * Gets the current sizes of the graph points, with `NaN` sizes + * resolved to the config default (or the exit default for an absent point). + * While point sizes transition, these are the targets; `getPointRadiusByIndex` moves with them. + * + * @returns {Float32Array} A **new** Float32Array (a snapshot — safe to mutate, computed on + * each call) of point sizes in the format [size1, size2, ..., sizen], + * where `n` is the index of the point. Returns an empty Float32Array if no point sizes are set. + */ + getPointSizes(): Float32Array; + /** + * Sets the links for the graph. + * + * @param {Float32Array} links - A Float32Array representing the links between points + * in the format [source1, target1, source2, target2, ..., sourcen, targetn], + * where `source` and `target` are the indices of the points being linked. + * Example: `new Float32Array([0, 1, 1, 2])` creates a link from point 0 to point 1 and another link from point 1 to point 2. + */ + setLinks(links: Float32Array): void; + /** + * Sets the colors for the graph links. + * + * @param {Float32Array} linkColors - A Float32Array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], + * where each color is in RGBA format. + * Example: `new Float32Array([1, 0, 0, 1, 0, 1, 0, 1])` sets the first link to red and the second link to green. + * An array whose length does not match the link count is ignored: every link draws + * `config.linkDefaultColor`. Pass an empty array to go back to the default. + */ + setLinkColors(linkColors: Float32Array): void; + /** + * Gets the current colors of the graph links. + * + * @returns {Float32Array} A Float32Array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], + * where each color is in RGBA format. Returns an empty Float32Array if no link colors are set. + */ + getLinkColors(): Float32Array; + /** + * Sets the widths for the graph links. + * + * @param {Float32Array} linkWidths - A Float32Array representing the widths of links in the format [width1, width2, ..., widthn], + * where `n` is the index of the link. + * Example: `new Float32Array([1, 2, 3])` sets the first link to width 1, the second link to width 2, and the third link to width 3. + * An array whose length does not match the link count is ignored: every link draws + * `config.linkDefaultWidth`. Pass an empty array to go back to the default. + */ + setLinkWidths(linkWidths: Float32Array): void; + /** + * Gets the current widths of the graph links. + * While link widths transition, these are the targets; `getLinkWidthByIndex` moves with them. + * + * @returns {Float32Array} A Float32Array representing the widths of links in the format [width1, width2, ..., widthn], + * where `n` is the index of the link. Returns an empty Float32Array if no link widths are set. + */ + getLinkWidths(): Float32Array; + /** + * Gets a link's width by its index, as drawn: while link widths transition, it moves with them. + * + * @param {number} index - The index of the link. + * @returns {number | undefined} The width, or `undefined` for an index outside the links. + */ + getLinkWidthByIndex(index: number): number | undefined; + /** + * Sets the arrows for the graph links. + * + * @param {boolean[]} linkArrows - An array of booleans indicating whether each link should have an arrow, + * in the format [arrow1, arrow2, ..., arrown], where `n` is the index of the link. + * Example: `[true, false, true]` sets arrows on the first and third links, but not on the second link. + */ + setLinkArrows(linkArrows: boolean[]): void; + /** + * Sets the styles (stroke patterns) for the graph links. + * + * @param {Float32Array} linkStyles - A Float32Array representing the style of each link in the format [style1, style2, ..., stylen], + * where `n` is the index of the link. Each value is a `LinkStyle` enum value: `0` = Solid, `1` = Dashed, `2` = Dotted. + * Example: `new Float32Array([0, 1, 2])` sets the first link to solid, the second to dashed, and the third to dotted. + * Invalid values fall back to the `linkDefaultStyle` config value. + * Dash length and gap are controlled globally via the `linkDashLength` and `linkDashGap` config options. + */ + setLinkStyles(linkStyles: Float32Array): void; + /** + * Gets the current styles of the graph links. + * + * @returns {Float32Array} A Float32Array representing the style of each link in the format [style1, style2, ..., stylen], + * where `n` is the index of the link. Returns an empty Float32Array if no link styles are set. + */ + getLinkStyles(): Float32Array; + /** + * Sets the strength for the graph links. + * + * @param {Float32Array} linkStrength - A Float32Array representing the strength of each link in the format [strength1, strength2, ..., strengthn], + * where `n` is the index of the link. + * Example: `new Float32Array([1, 2, 3])` sets the first link to strength 1, the second link to strength 2, and the third link to strength 3. + */ + setLinkStrength(linkStrength: Float32Array): void; + /** + * Sets the point clusters for the graph. + * + * @param {(number | undefined)[]} pointClusters - Array of cluster indices for each point in the graph. + * - Index: Each index corresponds to a point. + * - Values: Integers starting from 0; `undefined` indicates that a point does not belong to any cluster and will not be affected by cluster forces. + * @example + * `[0, 1, 0, 2, undefined, 1]` maps points to clusters: point 0 and 2 to cluster 0, point 1 to cluster 1, and point 3 to cluster 2. + * Points 4 is unclustered. + * @note Clusters without specified positions via `setClusterPositions` will be positioned at their centermass by default. + */ + setPointClusters(pointClusters: (number | undefined)[]): void; + /** + * Sets the positions of the point clusters for the graph. + * + * @param {(number | undefined)[]} clusterPositions - Array of cluster positions. + * - Every two elements represent the x and y coordinates for a cluster position. + * - `undefined` means the cluster's position is not defined and will use centermass positioning instead. + * @example + * `[10, 20, 30, 40, undefined, undefined]` places the first cluster at (10, 20) and the second at (30, 40); + * the third cluster will be positioned at its centermass automatically. + */ + setClusterPositions(clusterPositions: (number | undefined)[]): void; + /** + * Sets the force strength coefficients for clustering points in the graph. + * + * This method allows you to customize the forces acting on individual points during the clustering process. + * The force coefficients determine the strength of the forces applied to each point. + * + * @param {Float32Array} clusterStrength - A Float32Array of force strength coefficients for each point in the format [coeff1, coeff2, ..., coeffn], + * where `n` is the index of the point. + * Example: `new Float32Array([1, 0.4, 0.3])` sets the force coefficient for point 0 to 1, point 1 to 0.4, and point 2 to 0.3. + */ + setPointClusterStrength(clusterStrength: Float32Array): void; + /** + * Sets which points are pinned (fixed) in position. + * + * Pinned points: + * - Do not move due to physics forces (gravity, repulsion, link forces, etc.) + * - Still participate in force calculations (other nodes are attracted to/repelled by them) + * - Can still be dragged by the user if `enableDrag` is true + * + * @param {number[] | null} pinnedIndices - Array of point indices to pin. Set to `[]` or `null` to unpin all points. + * @example + * // Pin points 0 and 5 + * graph.setPinnedPoints([0, 5]) + * + * // Unpin all points + * graph.setPinnedPoints([]) + * graph.setPinnedPoints(null) + */ + setPinnedPoints(pinnedIndices: number[] | null): void; + /** + * Pins or unpins a single point without replacing the whole pinned set — + * a one-texel GPU write instead of the full rebuild `setPinnedPoints` performs. + * Designed for interactive hosts that pin a point on drag start and unpin it + * on drag end (pair with `setPointPosition` to move it while pinned; check + * `isPointPinned` first to restore a deliberate pin on release). + * See `setPinnedPoints` for what pinning means. + * + * @param index - The index of the point. + * @param pinned - `true` to pin, `false` to unpin. + * @note Each call clones the tracked pinned set to keep later full rebuilds + * in sync — fine at gesture rate; to change many pins at once, use + * `setPinnedPoints`. + */ + setPinnedPoint(index: number, pinned: boolean): void; + /** + * Whether a point index is currently pinned. Lets a host that pins during a + * drag gesture restore the point's deliberate pinned state on release. + */ + isPointPinned(index: number): boolean; + /** + * Moves a single point to a new position with a one-texel GPU write — no + * full-array upload, no `render()` round trip. Together with the batched + * `setPointPositionsByIndices` this is the API for mapping host-driven drag + * interactions onto a live simulation. + * + * The write targets the **live** simulation state, like an interactive drag: + * it does not modify the input array passed to `setPointPositions`, so a later + * full data update starts from the input positions again. While the simulation + * is running, forces move the point on the next tick unless it is pinned + * (`setPinnedPoint`). While positions animate after `setPointPositions`, the + * point stays where the write put it and the other points finish their + * animation. A `setPointPositions` applied by a later `render()` moves it to + * the position in that array. + * + * @param index - The index of the point. + * @param x - New X coordinate, in space coordinates (as returned by `getPointPositions`). + * @param y - New Y coordinate, in space coordinates. + * @note An **absent** point (NaN position — see `setPointPositions`) is not a valid + * target: the call is a no-op. No-op before the first `render()` call as well. + */ + setPointPosition(index: number, x: number, y: number): void; + /** + * Batched form of `setPointPosition`: moves a sparse set of points in one call. + * @param indices - Indices of the points to move. + * @param positions - New positions aligned with `indices`, flat `[x0, y0, x1, y1, …]` + * in space coordinates. + * @note Intended for interactive updates of a few points per frame. Bulk position + * changes should go through `setPointPositions()` + `render()`, which upload one + * texture instead of one texel per point. + */ + setPointPositionsByIndices(indices: number[], positions: number[] | Float32Array): void; + /** + * Applies pending data changes and renders the graph. + * Does not start or stop the simulation — use start(), stop(), pause(), unpause() for that. + * Two exceptions: the `simulationAlpha` argument sets the alpha when provided, and a position + * transition started with a positive `transitionDuration` (or its `config.transitionDuration` + * fallback) pauses a running simulation (see `setPointPositions`). + * + * @param {number} [simulationAlpha] - Optional alpha value to set. + * - If 0: Sets alpha to 0, simulation stops after one frame (graph becomes static). + * - If positive: Sets alpha to that value. + * - If undefined: Keeps current alpha value. + * @param {number} [transitionDuration] - Duration in milliseconds for any transition started by + * this render (from a preceding `setPointPositions` / `setPointColors` / … update), for this call + * only. `0` snaps with no animation; `undefined` (default) uses `config.transitionDuration`. + * To snap without changing the alpha, pass `render(undefined, 0)`. + */ + render(simulationAlpha?: number, transitionDuration?: number): void; + /** + * Center the view on a point and zoom in, by point index. + * @param index The index of the point in the array of points. + * @param duration Duration of the animation transition in milliseconds (`700` by default). + * @param scale Scale value to zoom in or out (`3` by default). + * @param canZoomOut Set to `false` to prevent zooming out from the point (`true` by default). + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + * @note An **absent** point (removed via a `NaN` position — see `setPointPositions`) is not a + * zoom target: the call is a no-op, same as hover and selection never landing on one. + */ + zoomToPointByIndex(index: number, duration?: number, scale?: number, canZoomOut?: boolean, enableSimulation?: boolean): void; + /** + * Zoom the view in or out to the specified zoom level. + * @param value Zoom level + * @param duration Duration of the zoom in/out transition. + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + */ + zoom(value: number, duration?: number, enableSimulation?: boolean): void; + /** + * Zoom the view in or out to the specified zoom level. + * @param value Zoom level + * @param duration Duration of the zoom in/out transition. + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + */ + setZoomLevel(value: number, duration?: number, enableSimulation?: boolean): void; + /** + * Get zoom level. + * @returns Zoom level value of the view. + */ + getZoomLevel(): number; + /** + * Get current X and Y coordinates of the points. + * @returns Array of point positions. + * @note Reads the GPU synchronously — the call stalls until the GPU has drained + * all pending work. For polling positions during a running simulation prefer + * `getPointPositionsAsync()` (no stall) or, for GPU-side consumers, + * `getPointPositionTexture()` (no readback at all). + * @note An **absent** point (removed via a `NaN` position — see `setPointPositions`) reads back + * as `NaN`, mirroring the input — not as its last on-screen coordinate. This keeps removal + * detectable from the read-back and keeps absent points out of `fitView`. + */ + getPointPositions(): number[]; + /** + * Get current X and Y coordinates of the points as a `Float32Array` in + * `[x0, y0, x1, y1, …]` order — same data as `getPointPositions()` without the + * `number[]` conversion. + * @param out - Optional destination array. Reused when it holds at least + * `2 × pointCount` values (extra tail values are left untouched); otherwise a + * new array is allocated and returned. + * @returns The filled destination array (empty when there is nothing to read). + * @note Reads the GPU synchronously — see `getPointPositions()`. Prefer + * `getPointPositionsAsync()` while the simulation is running. + */ + getPointPositionsArray(out?: Float32Array): Float32Array; + /** + * Asynchronous variant of `getPointPositionsArray()`: the pixel copy runs on the + * GPU timeline and the promise resolves when it completes, so the CPU never + * stalls waiting for in-flight simulation work. + * @param out - Optional destination array, as in `getPointPositionsArray()`. + * @returns Promise of the filled destination array (empty when there is nothing to read, + * or when a data rebuild changed the point count while the copy was in flight). + */ + getPointPositionsAsync(out?: Float32Array): Promise; + /** + * Get a read-only view of the GPU position texture, for hosts that sample point + * positions directly on the GPU (e.g. a custom deck.gl layer) instead of reading + * them back to the CPU. See `PointPositionTexture` for the texel layout and the + * ping-pong/version contract. + * @returns The texture view, or `undefined` before the first `render()` call. + */ + getPointPositionTexture(): PointPositionTexture | undefined; + /** + * Get current X and Y coordinates of the clusters. + * @param options Use `{ nonBlocking: true }` to take the latest positions the GPU has handed + * back without stalling for the current ones. + * @returns Array of cluster positions in `[x0, y0, x1, y1, ...]` order. Do not mutate the returned array. + */ + getClusterPositions(options?: PositionsReadOptions): Readonly; + /** + * Center and zoom in/out the view to fit all points in the scene. + * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default). + * @param padding Padding around the viewport in percentage (`0.1` by default). + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + */ + fitView(duration?: number, padding?: number, enableSimulation?: boolean): void; + /** + * Center and zoom in/out the view to fit points by their indices in the scene. + * @param indices Point indices to fit in the view. + * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default). + * @param padding Padding around the viewport in percentage (`0.1` by default). + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + */ + fitViewByPointIndices(indices: number[], duration?: number, padding?: number, enableSimulation?: boolean): void; + /** + * Center and zoom in/out the view to fit points by their positions in the scene. + * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]`. + * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default). + * @param padding Padding around the viewport in percentage (`0.1` by default). + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + */ + fitViewByPointPositions(positions: number[], duration?: number, padding?: number, enableSimulation?: boolean): void; + /** + * Sets the zoom transform so that the given point positions fit in the viewport, with optional animation. + * + * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]`. + * @param duration Animation duration in milliseconds. Default `250`. + * @param scale Optional scale factor; if omitted, scale is chosen to fit the positions. + * @param padding Padding around the viewport as a fraction (e.g. `0.1` = 10%). Default `0.1`. + * @param enableSimulation Whether to run the simulation during the zoom transition (`true` by default). + */ + setZoomTransformByPointPositions(positions: Float32Array, duration?: number, scale?: number, padding?: number, enableSimulation?: boolean): void; + /** + * Find point indices inside a rectangular area. + * + * **Important:** This method is synchronous and must only be called when the graph is ready. + * Ensure `await graph.ready` has resolved (or use the result inside `graph.ready.then(...)`) before + * calling. If called before initialization completes, returns an empty array. + * + * @param rect - Array of two corner points `[[left, top], [right, bottom]]`. + * The coordinates should be from 0 to the width/height of the canvas. + * @returns Array of point indices inside the rectangle. + */ + findPointsInRect(rect: [[number, number], [number, number]]): number[]; + /** + * Find point indices inside a polygon area. + * + * **Important:** This method is synchronous and must only be called when the graph is ready. + * Ensure `await graph.ready` has resolved (or use the result inside `graph.ready.then(...)`) before + * calling. If called before initialization completes, returns an empty array. + * + * @param polygonPath - Array of points `[[x1, y1], [x2, y2], ..., [xn, yn]]` that defines the polygon. + * The coordinates should be from 0 to the width/height of the canvas. + * @returns Array of point indices inside the polygon. + */ + findPointsInPolygon(polygonPath: [number, number][]): number[]; + /** + * Get point indices that are neighbors of the given point(s) — connected by a link in either direction. + * @param pointIndices A single point index or an array of point indices. + * @returns Deduplicated array of neighboring point indices. + */ + getNeighboringPointIndices(pointIndices: number | number[]): number[]; + /** + * Get link indices where both endpoints are within the given point(s). + * @param pointIndices A single point index or an array of point indices. + * @returns Deduplicated array of link indices connecting points within the provided set. + */ + getConnectedLinkIndices(pointIndices: number | number[]): number[]; + /** + * Get point indices at the endpoints of the given link(s). + * @param linkIndices A single link index or an array of link indices. + * @returns Deduplicated array of point indices at the ends of the provided links. + */ + getConnectedPointIndices(linkIndices: number | number[]): number[]; + /** + * Converts the X and Y point coordinates from the space coordinate system to the screen coordinate system. + * @param spacePosition Array of x and y coordinates in the space coordinate system. + * @returns Array of x and y coordinates in the screen coordinate system. + */ + spaceToScreenPosition(spacePosition: [number, number]): [number, number]; + /** + * Converts the X and Y point coordinates from the screen coordinate system to the space coordinate system. + * @param screenPosition Array of x and y coordinates in the screen coordinate system. + * @returns Array of x and y coordinates in the space coordinate system. + */ + screenToSpacePosition(screenPosition: [number, number]): [number, number]; + /** + * Converts the point radius value from the space coordinate system to the screen coordinate system. + * @param spaceRadius Radius of point in the space coordinate system. + * @returns Radius of point in the screen coordinate system. + */ + spaceToScreenRadius(spaceRadius: number): number; + /** + * Get point radius by its index, as drawn: the point size, or the image size when the + * point draws an image and that is larger. While point sizes transition, it moves with them. + * @param index Index of the point. + * @returns Radius of the point. + */ + getPointRadiusByIndex(index: number): number | undefined; + /** + * Track multiple point positions by their indices on each Cosmos tick. + * + * The tracked set is declarative: an index follows its point whenever that + * point exists. Growing or shrinking the point count later keeps tracking + * correct — an index past the current count simply reports nothing until the + * count grows to include it. Tracking may also be set up before the first + * `setPointPositions` call. + * @param indices Array of points indices. + */ + trackPointPositionsByIndices(indices: number[]): void; + /** + * Get current X and Y coordinates of the tracked points. + * Do not mutate the returned map - it may affect future calls. + * @param options Use `{ nonBlocking: true }` to take the latest positions the GPU has handed + * back without stalling for the current ones. + * @returns A ReadonlyMap where keys are point indices and values are their corresponding X and Y coordinates in the [number, number] format. + * @see trackPointPositionsByIndices To set which points should be tracked + * @note An **absent** tracked point (removed via a `NaN` position — see `setPointPositions`) is + * omitted from the map — a missing key means "this point is gone". React to absence yourself + * (e.g. hide its label); the entry disappears as soon as the point is removed, even while its + * fade-out is still playing. A tracked index with no point behind it (at or past the current + * point count) is omitted the same way, and reappears if the count grows to include it. + */ + getTrackedPointPositionsMap(options?: PositionsReadOptions): ReadonlyMap; + /** + * Get current X and Y coordinates of the tracked points as an array. + * @returns Array of point positions in the format [x1, y1, x2, y2, ..., xn, yn] for tracked points only. + * The positions are ordered by the tracking indices (same order as provided to trackPointPositionsByIndices). + * Returns an empty array if no points are being tracked. + * @note An **absent** tracked point (removed via a `NaN` position) reads back as `NaN` — the slot + * is kept so positions stay aligned with the tracked indices. + */ + getTrackedPointPositionsArray(): number[]; + /** + * For the points that are currently visible on the screen, get a sample of point indices with their coordinates. + * The resulting number of points will depend on the `pointSamplingDistance` configuration property, + * and the sampled points will be evenly distributed. + * @returns A Map object where keys are the index of the points and values are their corresponding X and Y coordinates in the [number, number] format. + */ + getSampledPointPositionsMap(): Map; + /** + * For the points that are currently visible on the screen, get a sample of point indices and positions. + * The resulting number of points will depend on the `pointSamplingDistance` configuration property, + * and the sampled points will be evenly distributed. + * @returns An object containing arrays of point indices and positions. + */ + getSampledPoints(): { + indices: number[]; + positions: number[]; + }; + /** + * For the links that are currently visible on the screen, get a sample of link indices with their midpoint coordinates and angle. + * The resulting number of links will depend on the `linkSamplingDistance` configuration property, + * and the sampled links will be evenly distributed (one link per grid cell, based on link midpoint in screen space). + * Each value is [x, y, angle]: position in data space; angle in radians for screen-space rotation (0 = right, positive = clockwise, e.g. for CSS rotation). + */ + getSampledLinkPositionsMap(): Map; + /** + * For the links that are currently visible on the screen, get a sample of link indices, midpoint positions, and angles. + * The resulting number of links will depend on the `linkSamplingDistance` configuration property, + * and the sampled links will be evenly distributed. + * Positions are in data space; angles are in radians for screen-space rotation (0 = right, positive = clockwise, e.g. for CSS rotation). + */ + getSampledLinks(): { + indices: number[]; + positions: number[]; + angles: number[]; + }; + /** + * Gets the X-axis of rescaling function. + * + * This scale is automatically created when position rescaling is enabled. + */ + getScaleX(): ((x: number) => number) | undefined; + /** + * Gets the Y-axis of rescaling function. + * + * This scale is automatically created when position rescaling is enabled. + */ + getScaleY(): ((y: number) => number) | undefined; + /** + * Start the simulation. Data ingest and the initial render belong to `render()`; + * this method sets the simulation running and requests frames to drive it. + * An active position transition is ended immediately (`onTransitionEnd` + * fires with `interrupted: true`). + * If the simulation is already running, calling `start(alpha)` reheats it by + * resetting `alpha` and `simulationProgress` without firing + * `onSimulationStart` again. + * @param alpha Value from 0 to 1. The higher the value, the more initial energy the simulation will get. + */ + start(alpha?: number): void; + /** + * Stop the simulation. This stops the simulation and resets its state. + * Use start() to begin a new simulation cycle. + */ + stop(): void; + /** + * Pause the simulation. When paused, the simulation stops running + * but preserves its current state (progress, alpha). + * Can be resumed using the unpause method. + */ + pause(): void; + /** + * Unpause the simulation. This method resumes a paused + * simulation and continues its execution. + * An active position transition is ended immediately (`onTransitionEnd` + * fires with `interrupted: true`). + */ + unpause(): void; + /** + * Run one step of the simulation manually. + * Works even when the simulation is paused. + */ + step(): void; + /** + * Sets the view directly, bypassing the interactive zoom behavior — for hosts + * (deck.gl layers, map renderers) that own the camera and want cosmos.gl's full + * rendering (`drawToRenderPass`) to follow it. Updates everything the zoom + * gesture would: the shader projection matrix, picking, point-radius zoom + * scaling, and the space↔screen conversion methods. + * + * The transform follows the d3-zoom convention. With `S = spaceSize` (adjusted), + * `[w, h] = screenSize` in CSS pixels, a point at space position + * `(spaceX, spaceY)` lands on screen (y down) at: + * ``` + * screenX = k * (spaceX + (w - S) / 2) + x + * screenY = k * ((S - spaceY) + (h - S) / 2) + y + * ``` + * (cosmos space y points up; screen y points down.) + * + * @param transform - View transform: `k` scale (screen pixels per space unit), + * `x`/`y` translation in screen pixels. + * @param screenSize - Viewport size in CSS pixels. Required for headless + * instances (they have no canvas to measure); ignored when omitted on a + * non-headless instance, whose canvas remains the source of truth. + */ + setViewTransform(transform: { + k: number; + x: number; + y: number; + }, screenSize?: [number, number]): void; + /** + * Records the point and link draws into a render pass owned by the host, + * without clearing, ending, or submitting it. Lets an embedding application + * (deck.gl layer, map renderer) compose cosmos.gl's rendering into its own + * frame: begin a pass, call this, draw other content, end and submit. + * + * Draws with cosmos.gl's current view transform and screen size. A headless + * instance has no view of its own — the host supplies one through + * `setViewTransform()` before drawing (or samples `getPointPositionTexture()` + * with its own shaders instead). No-op until data has been provided and + * `render()` called. + * + * With `picking`, the pass draws picking colors instead of the graph: every fragment a + * point or link covers carries its index + 1 as RGB bytes (point `i` as `i + 1`, link + * `j` as `linkIndexOffset + j + 1`) and `picking.alpha`, with hard edges and no blending. + * That is the encoding deck.gl decodes — a deck layer records this in deck's pick pass + * with the pass's constant alpha — and most hosts can. Decode as + * `r + g * 256 + b * 65536 - 1`; 0 is "nothing here". Dash gaps count as covered, as in + * the engine's own hover picking. + * + * @param renderPass - The host's open render pass to record into. + * @param options - Set `points` or `links` to `false` to draw only the other; `picking` + * draws picking colors with the given `alpha`, links offset by `linkIndexOffset`. + */ + drawToRenderPass(renderPass: RenderPass, options?: { + points?: boolean; + links?: boolean; + picking?: { + alpha: number; + linkIndexOffset?: number; + }; + }): void; + /** + * Hover a point that a host found with its own picking, such as deck.gl's pick pass. + * The point gets the hover ring (`hoveredPointRingColor`), whatever + * `renderHoveredPointRing` says — that flag gates only cosmos.gl's own pointer hover. + * Kept apart from the pointer hover: no mouse callbacks fire, and focus is not touched. + * A config update keeps it. + * @param index - The point to hover, or `undefined` to clear. + */ + setHostHoveredPoint(index?: number): void; + /** + * Hover a link that a host found with its own picking. The link gets the hovered-link + * width and color (`hoveredLinkWidthIncrease`, `hoveredLinkColor`); while set, it is the + * hovered link cosmos.gl draws. Same rules as `setHostHoveredPoint`. + * @param index - The link to hover, or `undefined` to clear. + */ + setHostHoveredLink(index?: number): void; + /** + * Render a single frame immediately, without scheduling any further frames. + * Intended for hosts that drive cosmos.gl from their own scheduler + * (`enableRenderLoop: false`): call `renderOneFrame()` from the host's frame + * callback. Performs the same per-frame work as the internal loop — screen-size + * sync, transitions, hover detection, one simulation step (when the simulation + * is running), and the draw — including the simulation-end check. + * No-op on headless instances (they own no canvas to draw into). + */ + renderOneFrame(): void; + /** + * Destroy this Cosmos instance. + */ + destroy(): void; + /** + * Uploads the processed data to the GPU for every channel whose update flag is set + * (positions, colors, sizes, shapes, images, links, forces, clusters) and requests a redraw. + * An internal stage of the render pipeline: it does not ingest new input arrays, so data + * passed to `setPointPositions`, `setPointColors`, `setLinks`, etc. takes effect only on + * the next `render()`. To apply new data while keeping the current alpha, call + * `render(undefined)` — or `render(undefined, 0)` to also snap instead of animating. + */ + create(): void; + /** + * Converts an array of tuple positions to a single array containing all coordinates sequentially + * @param pointPositions An array of tuple positions + * @returns A flatten array of coordinates + */ + flatten(pointPositions: [number, number][]): number[]; + /** + * Converts a flat array of point positions to a tuple pairs representing coordinates + * @param pointPositions A flattened array of coordinates + * @returns An array of tuple positions + */ + pair(pointPositions: number[]): [number, number][]; + /** + * Restores init-only fields (`initialZoomLevel`, `randomSeed`, `attribution`) + * to their pre-update values, preventing runtime changes via setConfig/setConfigPartial. + */ + private preserveInitOnlyFields; + private getFitViewPositions; + /** + * Compares the previous config snapshot with the current `this.config` and + * applies any necessary side effects (updating renderers, store, behaviors, etc.). + */ + private updateStateFromConfig; + /** + * Applies `enableSimulation` lifecycle changes triggered by config updates. + */ + private applyEnableSimulationConfigChange; + /** + * Ensures device is initialized before executing a method. + * If device is not ready, queues the method to run after initialization. + * @param callback - Function to execute once device is ready + * @returns true if device was not ready and operation was queued, false if device is ready + */ + private ensureDevice; + /** + * Installs the pointer/keyboard/zoom/drag handlers on the canvas and document. + * Never called for headless instances — they own no canvas and no input. + */ + private initInteractions; + /** + * Validates that a device has the required HTMLCanvasElement canvas context. + * Cosmos requires an HTMLCanvasElement canvas context and does not support + * OffscreenCanvas or compute-only devices. + * @param device - The device to validate + * @returns The validated canvas context (guaranteed to be non-null and HTMLCanvasElement type) + * @throws Error if the device does not meet Cosmos requirements + */ + private validateDevice; + /** + * Updates and recreates the graph visualization based on pending changes. + * + * @param simulationAlpha - Optional alpha value to set. If not provided, keeps current alpha. + */ + private update; + /** + * Runs one step of the simulation (forces, position updates, alpha decay). + * This is the core simulation logic that can be called by step() or during rendering. + * + * @param forceExecution - Controls whether to run the simulation step when paused. + * - If true: Always runs the simulation step, even when isSimulationRunning is false. + * Used by step() to allow manual stepping while the simulation is paused. + * - If false: Only runs if isSimulationRunning is true. Used during rendering + * to respect pause/unpause state. + */ + private runSimulationStep; + private initPrograms; + /** + * Schedules a frame if none is pending. The RAF callback renders once and + * reschedules only while `shouldKeepRendering()` — when the scene is static, + * no frames run at all. + */ + private frame; + /** + * Request a redraw. No-op if a frame is already scheduled. All internal + * events that can change visual state funnel through this. + */ + private requestRender; + /** + * Whether the loop must continue past the current frame — true while any + * continuous activity can still change visual state. + */ + private shouldKeepRendering; + /** + * Whether findHoveredItem() still has work to do. Keeps the loop alive + * through the hover throttle (up to MAX_HOVER_DETECTION_DELAY frames) until + * detection actually executes — which updates _lastCheckedMouseX/Y and + * consumes _shouldForceHoverDetection, turning this false. + */ + private hasPendingHoverWork; + /** + * Renders a single frame. This does NOT schedule the next frame. + * On an external device the frame runs under cosmos's GL state and hands the + * host its own back afterwards. + */ + private renderFrame; + /** The actual rendering logic of a frame. */ + private drawFrame; + private stopFrames; + /** + * Called automatically when simulation completes (alpha < ALPHA_MIN). + * Rendering continues after this is called (for rendering/interaction). + */ + private end; + private onClick; + private updateMousePosition; + private onContextMenu; + /** Clear the pending touch/pen long-press timer, if any. */ + private cancelLongPress; + /** + * Dispatch the contextmenu callback chain — shared between the desktop + * `contextmenu` handler and the touch/pen long-press timer. + */ + private fireContextMenu; + /** + * Updates cosmos state to match the canvas's CSS size: + * - `store.screenSize` + * - the zoom transform — re-centered so the view keeps looking at the same spot + * - the screen-sized sampling grids and picking FBOs + * + * Does NOT touch `canvas.width`/`canvas.height` — the drawing buffer belongs + * to luma.gl's autoResize. + * + * Skips the work when the CSS size is unchanged. Pass `force` when state must + * be rebuilt at the same size (e.g. `spaceSize` remaps the world). + */ + private syncScreenSize; + private updateZoomDragBehaviors; + /** + * Only steal touch gestures when cosmos uses them. With both flags off + * the page can scroll over the canvas. + */ + private updateCanvasTouchAction; + private findHoveredItem; + /** Marks both picking buffers stale when the view transform changed since the last check. */ + private updatePickingBufferStaleness; + /** + * Marks the point and link picking buffers stale — the scene they were + * rasterized from (positions, sizes/widths, status, view transform) changed. + */ + private markPickingBuffersStale; + /** Applies the results of async picks once the GPU readbacks complete. */ + private resolvePendingPick; + /** + * Applies point and link pick results and fires the hover callbacks — + * `undefined` for either means "no new information, keep the current state". + * On the async path the pointer event that triggered the picks is already + * gone, so `currentEvent` may be undefined — same as for detections forced + * without a fresh event. + */ + private processHoverResult; + /** Applies a picked point to the store. Returns flags for deferred callback firing. */ + private applyPickedPoint; + /** Applies a picked link to the store. Returns flags for deferred callback firing. */ + private applyPickedLink; + private updateCanvasCursor; + private addAttribution; +} +export type { GraphConfig, GraphSimulationConfig, GraphSimulationConfigInterface } from './config'; +export { GraphSimulation } from './simulation'; +export type { PointPositionTexture, PositionTextureSource } from './simulation'; +export type { PositionsReadOptions } from './simulation'; +export type { PointTracker } from './modules/Points/point-tracker'; +export { PointShape, LinkStyle } from './modules/GraphData'; +export type { LinksByPoint } from './modules/GraphData'; +export { TransitionEasing } from './modules/Transition'; +export * from './variables'; +export * from './helper'; diff --git a/tools/memorygraph/_cosmos_check.js b/tools/memorygraph/_cosmos_check.js new file mode 100644 index 0000000..552a528 --- /dev/null +++ b/tools/memorygraph/_cosmos_check.js @@ -0,0 +1,3530 @@ +(function(K,Re){typeof exports=="object"&&typeof module<"u"?Re(exports):typeof define=="function"&&define.amd?define(["exports"],Re):(K=typeof globalThis<"u"?globalThis:K||self,Re(K.Cosmos={}))})(this,function(K){"use strict";var nP=Object.defineProperty;var rP=(K,Re,Et)=>Re in K?nP(K,Re,{enumerable:!0,configurable:!0,writable:!0,value:Et}):K[Re]=Et;var f=(K,Re,Et)=>rP(K,typeof Re!="symbol"?Re+"":Re,Et);var Re="http://www.w3.org/1999/xhtml";const Et={svg:"http://www.w3.org/2000/svg",xhtml:Re,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function cn(e){var t=e+="",i=t.indexOf(":");return i>=0&&(t=e.slice(0,i))!=="xmlns"&&(e=e.slice(i+1)),Et.hasOwnProperty(t)?{space:Et[t],local:e}:e}function Qd(e){return function(){var t=this.ownerDocument,i=this.namespaceURI;return i===Re&&t.documentElement.namespaceURI===Re?t.createElement(e):t.createElementNS(i,e)}}function Jd(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function ha(e){var t=cn(e);return(t.local?Jd:Qd)(t)}function eh(){}function qr(e){return e==null?eh:function(){return this.querySelector(e)}}function th(e){typeof e!="function"&&(e=qr(e));for(var t=this._groups,i=t.length,n=new Array(i),r=0;r=I&&(I=P+1);!(v=T[I])&&++I=0;)(o=n[r])&&(s&&o.compareDocumentPosition(s)^4&&s.parentNode.insertBefore(o,s),s=o);return this}function Ah(e){e||(e=Rh);function t(d,h){return d&&h?e(d.__data__,h.__data__):!d-!h}for(var i=this._groups,n=i.length,r=new Array(n),s=0;st?1:e>=t?0:NaN}function wh(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function Eh(){return Array.from(this)}function Ih(){for(var e=this._groups,t=0,i=e.length;t1?this.each((t==null?Wh:typeof t=="function"?Hh:Vh)(e,t,i??"")):Ht(this.node(),e)}function Ht(e,t){return e.style.getPropertyValue(t)||xa(e).getComputedStyle(e,null).getPropertyValue(t)}function Xh(e){return function(){delete this[e]}}function Yh(e,t){return function(){this[e]=t}}function jh(e,t){return function(){var i=t.apply(this,arguments);i==null?delete this[e]:this[e]=i}}function Kh(e,t){return arguments.length>1?this.each((t==null?Xh:typeof t=="function"?jh:Yh)(e,t)):this.node()[e]}function Sa(e){return e.trim().split(/^|\s+/)}function Gr(e){return e.classList||new ya(e)}function ya(e){this._node=e,this._names=Sa(e.getAttribute("class")||"")}ya.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function _a(e,t){for(var i=Gr(e),n=-1,r=t.length;++n=0&&(i=t.slice(n+1),t=t.slice(0,n)),{type:t,name:i}})}function vf(e){return function(){var t=this.__on;if(t){for(var i=0,n=-1,r=t.length,s;i{}};function dn(){for(var e=0,t=arguments.length,i={},n;e=0&&(n=i.slice(r+1),i=i.slice(0,r)),i&&!t.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:n}})}hn.prototype=dn.prototype={constructor:hn,on:function(e,t){var i=this._,n=Ff(e+"",i),r,s=-1,o=n.length;if(arguments.length<2){for(;++s0)for(var i=new Array(r),n=0,r,s;n=0&&e._call.call(null,t),e=e._next;--$t}function wa(){It=(pn=Ri.now())+gn,$t=Pi=0;try{Bf()}finally{$t=0,Uf(),It=0}}function Of(){var e=Ri.now(),t=e-pn;t>Ca&&(gn-=t,pn=e)}function Uf(){for(var e,t=fn,i,n=1/0;t;)t._call?(n>t._time&&(n=t._time),e=t,t=t._next):(i=t._next,t._next=null,t=e?e._next=i:fn=i);Ai=e,Qr(n)}function Qr(e){if(!$t){Pi&&(Pi=clearTimeout(Pi));var t=e-It;t>24?(e<1/0&&(Pi=setTimeout(wa,e-Ri.now()-gn)),Ci&&(Ci=clearInterval(Ci))):(Ci||(pn=Ri.now(),Ci=setInterval(Of,Ca)),$t=1,Aa(wa))}}function Ea(e,t,i){var n=new mn;return t=t==null?0:+t,n.restart(r=>{n.stop(),e(r+t)},t,i),n}var zf=dn("start","end","cancel","interrupt"),Lf=[],Ia=0,ka=1,Jr=2,xn=3,Da=4,es=5,Sn=6;function yn(e,t,i,n,r,s){var o=e.__transition;if(!o)e.__transition={};else if(i in o)return;Wf(e,i,{name:t,index:n,group:r,on:zf,tween:Lf,time:s.time,delay:s.delay,duration:s.duration,ease:s.ease,timer:null,state:Ia})}function ts(e,t){var i=Ye(e,t);if(i.state>Ia)throw new Error("too late; already scheduled");return i}function tt(e,t){var i=Ye(e,t);if(i.state>xn)throw new Error("too late; already running");return i}function Ye(e,t){var i=e.__transition;if(!i||!(i=i[t]))throw new Error("transition not found");return i}function Wf(e,t,i){var n=e.__transition,r;n[t]=i,i.timer=Ra(s,0,i.time);function s(c){i.state=ka,i.timer.restart(o,i.delay,i.time),i.delay<=c&&o(c-i.delay)}function o(c){var u,d,h,p;if(i.state!==ka)return l();for(u in n)if(p=n[u],p.name===i.name){if(p.state===xn)return Ea(o);p.state===Da?(p.state=Sn,p.timer.stop(),p.on.call("interrupt",e,e.__data__,p.index,p.group),delete n[u]):+uJr&&n.state>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):i===8?Tn(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):i===4?Tn(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=$f.exec(e))?new ke(t[1],t[2],t[3],1):(t=Xf.exec(e))?new ke(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=Yf.exec(e))?Tn(t[1],t[2],t[3],t[4]):(t=jf.exec(e))?Tn(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=Kf.exec(e))?La(t[1],t[2]/100,t[3]/100,1):(t=qf.exec(e))?La(t[1],t[2]/100,t[3]/100,t[4]):Ma.hasOwnProperty(e)?Oa(Ma[e]):e==="transparent"?new ke(NaN,NaN,NaN,0):null}function Oa(e){return new ke(e>>16&255,e>>8&255,e&255,1)}function Tn(e,t,i,n){return n<=0&&(e=t=i=NaN),new ke(e,t,i,n)}function Qf(e){return e instanceof wi||(e=mt(e)),e?(e=e.rgb(),new ke(e.r,e.g,e.b,e.opacity)):new ke}function ns(e,t,i,n){return arguments.length===1?Qf(e):new ke(e,t,i,n??1)}function ke(e,t,i,n){this.r=+e,this.g=+t,this.b=+i,this.opacity=+n}is(ke,ns,Fa(wi,{brighter(e){return e=e==null?bn:Math.pow(bn,e),new ke(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Ei:Math.pow(Ei,e),new ke(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new ke(kt(this.r),kt(this.g),kt(this.b),vn(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Ua,formatHex:Ua,formatHex8:Jf,formatRgb:za,toString:za}));function Ua(){return`#${Dt(this.r)}${Dt(this.g)}${Dt(this.b)}`}function Jf(){return`#${Dt(this.r)}${Dt(this.g)}${Dt(this.b)}${Dt((isNaN(this.opacity)?1:this.opacity)*255)}`}function za(){const e=vn(this.opacity);return`${e===1?"rgb(":"rgba("}${kt(this.r)}, ${kt(this.g)}, ${kt(this.b)}${e===1?")":`, ${e})`}`}function vn(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function kt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Dt(e){return e=kt(e),(e<16?"0":"")+e.toString(16)}function La(e,t,i,n){return n<=0?e=t=i=NaN:i<=0||i>=1?e=t=NaN:t<=0&&(e=NaN),new je(e,t,i,n)}function Wa(e){if(e instanceof je)return new je(e.h,e.s,e.l,e.opacity);if(e instanceof wi||(e=mt(e)),!e)return new je;if(e instanceof je)return e;e=e.rgb();var t=e.r/255,i=e.g/255,n=e.b/255,r=Math.min(t,i,n),s=Math.max(t,i,n),o=NaN,a=s-r,l=(s+r)/2;return a?(t===s?o=(i-n)/a+(i0&&l<1?0:o,new je(o,a,l,e.opacity)}function ep(e,t,i,n){return arguments.length===1?Wa(e):new je(e,t,i,n??1)}function je(e,t,i,n){this.h=+e,this.s=+t,this.l=+i,this.opacity=+n}is(je,ep,Fa(wi,{brighter(e){return e=e==null?bn:Math.pow(bn,e),new je(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Ei:Math.pow(Ei,e),new je(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,i=this.l,n=i+(i<.5?i:1-i)*t,r=2*i-n;return new ke(rs(e>=240?e-240:e+120,r,n),rs(e,r,n),rs(e<120?e+240:e-120,r,n),this.opacity)},clamp(){return new je(Va(this.h),Pn(this.s),Pn(this.l),vn(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=vn(this.opacity);return`${e===1?"hsl(":"hsla("}${Va(this.h)}, ${Pn(this.s)*100}%, ${Pn(this.l)*100}%${e===1?")":`, ${e})`}`}}));function Va(e){return e=(e||0)%360,e<0?e+360:e}function Pn(e){return Math.max(0,Math.min(1,e||0))}function rs(e,t,i){return(e<60?t+(i-t)*e/60:e<180?i:e<240?t+(i-t)*(240-e)/60:t)*255}const ss=e=>()=>e;function tp(e,t){return function(i){return e+i*t}}function ip(e,t,i){return e=Math.pow(e,i),t=Math.pow(t,i)-e,i=1/i,function(n){return Math.pow(e+n*t,i)}}function np(e){return(e=+e)==1?Ha:function(t,i){return i-t?ip(t,i,e):ss(isNaN(t)?i:t)}}function Ha(e,t){var i=t-e;return i?tp(e,i):ss(isNaN(e)?t:e)}const Cn=function e(t){var i=np(t);function n(r,s){var o=i((r=ns(r)).r,(s=ns(s)).r),a=i(r.g,s.g),l=i(r.b,s.b),c=Ha(r.opacity,s.opacity);return function(u){return r.r=o(u),r.g=a(u),r.b=l(u),r.opacity=c(u),r+""}}return n.gamma=e,n}(1);function rp(e,t){t||(t=[]);var i=e?Math.min(t.length,e.length):0,n=t.slice(),r;return function(s){for(r=0;ri&&(s=t.slice(i,s),a[o]?a[o]+=s:a[++o]=s),(n=n[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:Ke(n,r)})),i=as.lastIndex;return i180?u+=360:u-c>180&&(c+=360),h.push({i:d.push(r(d)+"rotate(",null,n)-2,x:Ke(c,u)})):u&&d.push(r(d)+"rotate("+u+n)}function a(c,u,d,h){c!==u?h.push({i:d.push(r(d)+"skewX(",null,n)-2,x:Ke(c,u)}):u&&d.push(r(d)+"skewX("+u+n)}function l(c,u,d,h,p,g){if(c!==d||u!==h){var x=p.push(r(p)+"scale(",null,",",null,")");g.push({i:x-4,x:Ke(c,d)},{i:x-2,x:Ke(u,h)})}else(d!==1||h!==1)&&p.push(r(p)+"scale("+d+","+h+")")}return function(c,u){var d=[],h=[];return c=e(c),u=e(u),s(c.translateX,c.translateY,u.translateX,u.translateY,d,h),o(c.rotate,u.rotate,d,h),a(c.skewX,u.skewX,d,h),l(c.scaleX,c.scaleY,u.scaleX,u.scaleY,d,h),c=u=null,function(p){for(var g=-1,x=h.length,T;++g=0&&(t=t.slice(0,i)),!t||t==="start"})}function Kp(e,t,i){var n,r,s=jp(t)?ts:tt;return function(){var o=s(this,e),a=o.on;a!==n&&(r=(n=a).copy()).on(t,i),o.on=r}}function qp(e,t){var i=this._id;return arguments.length<2?Ye(this.node(),i).on.on(e):this.each(Kp(i,e,t))}function Gp(e){return function(){var t=this.parentNode;for(var i in this.__transition)if(+i!==e)return;t&&t.removeChild(this)}}function Zp(){return this.on("end.remove",Gp(this._id))}function Qp(e){var t=this._name,i=this._id;typeof e!="function"&&(e=qr(e));for(var n=this._groups,r=n.length,s=new Array(r),o=0;o+e;function Ja(e){return e*e}function el(e){return e*(2-e)}function tl(e){return((e*=2)<=1?e*e:--e*(2-e)+1)/2}function yg(e){return e*e*e}function _g(e){return--e*e*e+1}function il(e){return((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2}var nl=Math.PI,rl=nl/2;function bg(e){return+e==1?1:1-Math.cos(e*rl)}function Tg(e){return Math.sin(e*rl)}function vg(e){return(1-Math.cos(nl*e))/2}function Rn(e){return(Math.pow(2,-10*e)-.0009765625)*1.0009775171065494}function Pg(e){return Rn(1-+e)}function Cg(e){return 1-Rn(e)}function Ag(e){return((e*=2)<=1?Rn(1-e):2-Rn(e-1))/2}function Rg(e){return 1-Math.sqrt(1-e*e)}function wg(e){return Math.sqrt(1- --e*e)}function Eg(e){return((e*=2)<=1?1-Math.sqrt(1-e*e):Math.sqrt(1-(e-=2)*e)+1)/2}var Ig={time:null,delay:0,duration:250,ease:il};function kg(e,t){for(var i;!(i=e.__transition)||!(i=i[t]);)if(!(e=e.parentNode))throw new Error(`transition ${t} not found`);return i}function Dg(e){var t,i;e instanceof ut?(t=e._id,e=e._name):(t=Za(),(i=Ig).time=Zr(),e=e==null?null:e+"");for(var n=this._groups,r=n.length,s=0;s()=>e;function hs(e,{sourceEvent:t,subject:i,target:n,identifier:r,active:s,x:o,y:a,dx:l,dy:c,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:i,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},identifier:{value:r,enumerable:!0,configurable:!0},active:{value:s,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:a,enumerable:!0,configurable:!0},dx:{value:l,enumerable:!0,configurable:!0},dy:{value:c,enumerable:!0,configurable:!0},_:{value:u}})}hs.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function Mg(e){return!e.ctrlKey&&!e.button}function Ng(){return this.parentNode}function Bg(e,t){return t??{x:e.x,y:e.y}}function Og(){return navigator.maxTouchPoints||"ontouchstart"in this}function Ug(){var e=Mg,t=Ng,i=Bg,n=Og,r={},s=dn("start","drag","end"),o=0,a,l,c,u,d=0;function h(y){y.on("mousedown.drag",p).filter(n).on("touchstart.drag",T).on("touchmove.drag",S,Fg).on("touchend.drag touchcancel.drag",P).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function p(y,v){if(!(u||!e.call(this,y,v))){var E=I(this,t.call(this,y,v),y,v,"mouse");E&&(ye(y.view).on("mousemove.drag",g,ki).on("mouseup.drag",x,ki),sl(y.view),ds(y),c=!1,a=y.clientX,l=y.clientY,E("start",y))}}function g(y){if(Yt(y),!c){var v=y.clientX-a,E=y.clientY-l;c=v*v+E*E>d}r.mouse("drag",y)}function x(y){ye(y.view).on("mousemove.drag mouseup.drag",null),ol(y.view,c),Yt(y),r.mouse("end",y)}function T(y,v){if(e.call(this,y,v)){var E=y.changedTouches,R=t.call(this,y,v),D=E.length,z,$;for(z=0;z()=>e;function zg(e,{sourceEvent:t,target:i,transform:n,dispatch:r}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:i,enumerable:!0,configurable:!0},transform:{value:n,enumerable:!0,configurable:!0},_:{value:r}})}function ht(e,t,i){this.k=e,this.x=t,this.y=i}ht.prototype={constructor:ht,scale:function(e){return e===1?this:new ht(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new ht(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var jt=new ht(1,0,0);ht.prototype;function fs(e){e.stopImmediatePropagation()}function Di(e){e.preventDefault(),e.stopImmediatePropagation()}function Lg(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function Wg(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function al(){return this.__zoom||jt}function Vg(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function Hg(){return navigator.maxTouchPoints||"ontouchstart"in this}function $g(e,t,i){var n=e.invertX(t[0][0])-i[0][0],r=e.invertX(t[1][0])-i[1][0],s=e.invertY(t[0][1])-i[0][1],o=e.invertY(t[1][1])-i[1][1];return e.translate(r>n?(n+r)/2:Math.min(0,n)||Math.max(0,r),o>s?(s+o)/2:Math.min(0,s)||Math.max(0,o))}function Xg(){var e=Lg,t=Wg,i=$g,n=Vg,r=Hg,s=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],a=250,l=yp,c=dn("start","zoom","end"),u,d,h,p=500,g=150,x=0,T=10;function S(b){b.property("__zoom",al).on("wheel.zoom",D,{passive:!1}).on("mousedown.zoom",z).on("dblclick.zoom",$).filter(r).on("touchstart.zoom",F).on("touchmove.zoom",Q).on("touchend.zoom touchcancel.zoom",X).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}S.transform=function(b,N,A,O){var V=b.selection?b.selection():b;V.property("__zoom",al),b!==V?v(b,N,A,O):V.interrupt().each(function(){E(this,arguments).event(O).start().zoom(null,typeof N=="function"?N.apply(this,arguments):N).end()})},S.scaleBy=function(b,N,A,O){S.scaleTo(b,function(){var V=this.__zoom.k,L=typeof N=="function"?N.apply(this,arguments):N;return V*L},A,O)},S.scaleTo=function(b,N,A,O){S.transform(b,function(){var V=t.apply(this,arguments),L=this.__zoom,Y=A==null?y(V):typeof A=="function"?A.apply(this,arguments):A,J=L.invert(Y),H=typeof N=="function"?N.apply(this,arguments):N;return i(I(P(L,H),Y,J),V,o)},A,O)},S.translateBy=function(b,N,A,O){S.transform(b,function(){return i(this.__zoom.translate(typeof N=="function"?N.apply(this,arguments):N,typeof A=="function"?A.apply(this,arguments):A),t.apply(this,arguments),o)},null,O)},S.translateTo=function(b,N,A,O,V){S.transform(b,function(){var L=t.apply(this,arguments),Y=this.__zoom,J=O==null?y(L):typeof O=="function"?O.apply(this,arguments):O;return i(jt.translate(J[0],J[1]).scale(Y.k).translate(typeof N=="function"?-N.apply(this,arguments):-N,typeof A=="function"?-A.apply(this,arguments):-A),L,o)},O,V)};function P(b,N){return N=Math.max(s[0],Math.min(s[1],N)),N===b.k?b:new ht(N,b.x,b.y)}function I(b,N,A){var O=N[0]-A[0]*b.k,V=N[1]-A[1]*b.k;return O===b.x&&V===b.y?b:new ht(b.k,O,V)}function y(b){return[(+b[0][0]+ +b[1][0])/2,(+b[0][1]+ +b[1][1])/2]}function v(b,N,A,O){b.on("start.zoom",function(){E(this,arguments).event(O).start()}).on("interrupt.zoom end.zoom",function(){E(this,arguments).event(O).end()}).tween("zoom",function(){var V=this,L=arguments,Y=E(V,L).event(O),J=t.apply(V,L),H=A==null?y(J):typeof A=="function"?A.apply(V,L):A,Xe=Math.max(J[1][0]-J[0][0],J[1][1]-J[0][1]),Se=V.__zoom,ze=typeof N=="function"?N.apply(V,L):N,Je=l(Se.invert(H).concat(Xe/Se.k),ze.invert(H).concat(Xe/ze.k));return function(Le){if(Le===1)Le=ze;else{var et=Je(Le),xi=Xe/et[2];Le=new ht(xi,H[0]-et[0]*xi,H[1]-et[1]*xi)}Y.zoom(null,Le)}})}function E(b,N,A){return!A&&b.__zooming||new R(b,N)}function R(b,N){this.that=b,this.args=N,this.active=0,this.sourceEvent=null,this.extent=t.apply(b,N),this.taps=0}R.prototype={event:function(b){return b&&(this.sourceEvent=b),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(b,N){return this.mouse&&b!=="mouse"&&(this.mouse[1]=N.invert(this.mouse[0])),this.touch0&&b!=="touch"&&(this.touch0[1]=N.invert(this.touch0[0])),this.touch1&&b!=="touch"&&(this.touch1[1]=N.invert(this.touch1[0])),this.that.__zoom=N,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(b){var N=ye(this.that).datum();c.call(b,this.that,new zg(b,{sourceEvent:this.sourceEvent,target:S,transform:this.that.__zoom,dispatch:c}),N)}};function D(b,...N){if(!e.apply(this,arguments))return;var A=E(this,N).event(b),O=this.__zoom,V=Math.max(s[0],Math.min(s[1],O.k*Math.pow(2,n.apply(this,arguments)))),L=ct(b);if(A.wheel)(A.mouse[0][0]!==L[0]||A.mouse[0][1]!==L[1])&&(A.mouse[1]=O.invert(A.mouse[0]=L)),clearTimeout(A.wheel);else{if(O.k===V)return;A.mouse=[L,O.invert(L)],_n(this),A.start()}Di(b),A.wheel=setTimeout(Y,g),A.zoom("mouse",i(I(P(O,V),A.mouse[0],A.mouse[1]),A.extent,o));function Y(){A.wheel=null,A.end()}}function z(b,...N){if(h||!e.apply(this,arguments))return;var A=b.currentTarget,O=E(this,N,!0).event(b),V=ye(b.view).on("mousemove.zoom",H,!0).on("mouseup.zoom",Xe,!0),L=ct(b,A),Y=b.clientX,J=b.clientY;sl(b.view),fs(b),O.mouse=[L,this.__zoom.invert(L)],_n(this),O.start();function H(Se){if(Di(Se),!O.moved){var ze=Se.clientX-Y,Je=Se.clientY-J;O.moved=ze*ze+Je*Je>x}O.event(Se).zoom("mouse",i(I(O.that.__zoom,O.mouse[0]=ct(Se,A),O.mouse[1]),O.extent,o))}function Xe(Se){V.on("mousemove.zoom mouseup.zoom",null),ol(Se.view,O.moved),Di(Se),O.event(Se).end()}}function $(b,...N){if(e.apply(this,arguments)){var A=this.__zoom,O=ct(b.changedTouches?b.changedTouches[0]:b,this),V=A.invert(O),L=A.k*(b.shiftKey?.5:2),Y=i(I(P(A,L),O,V),t.apply(this,N),o);Di(b),a>0?ye(this).transition().duration(a).call(v,Y,O,b):ye(this).call(S.transform,Y,O,b)}}function F(b,...N){if(e.apply(this,arguments)){var A=b.touches,O=A.length,V=E(this,N,b.changedTouches.length===O).event(b),L,Y,J,H;for(fs(b),Y=0;Ye.length)&&(t=e.length);for(var i=0,n=Array(t);i2?n-2:0),s=2;s1?i-1:0),r=1;r"u"?null:me(BigInt.prototype.toString),ml=typeof Symbol>"u"?null:me(Symbol.prototype.toString),_e=me(Object.prototype.hasOwnProperty),Ni=me(Object.prototype.toString),be=me(RegExp.prototype.test),Ft=sm(TypeError);function me(e){return function(t){t instanceof RegExp&&(t.lastIndex=0);for(var i=arguments.length,n=new Array(i>1?i-1:0),r=1;r2&&arguments[2]!==void 0?arguments[2]:Fi;if(ul&&ul(e,null),!xt(t))return e;let n=t.length;for(;n--;){let r=t[n];if(typeof r=="string"){const s=i(r);s!==r&&(Zg(t)||(t[n]=s),r=s)}e[r]=!0}return e}function om(e){for(let t=0;t/g),fm=ve(/\${[\w\W]*/g),pm=ve(/^data-[\-\w.\u00B7-\uFFFF]+$/),gm=ve(/^aria-[\-\w]+$/),bl=ve(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),mm=ve(/^(?:\w+script|data):/i),xm=ve(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Sm=ve(/^html$/i),ym=ve(/^[a-z][.\w]*(-[.\w]+)+$/i),Tl=ve(/<[/\w!]/g),vl=ve(/<[/\w]/g),_m=ve(/<\/no(script|embed|frames)/i),bm=ve(/\/>/i),Oe={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,processingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},Tm=function(){return typeof window>"u"?null:window},vm=function(t,i){if(typeof t!="object"||typeof t.createPolicy!="function")return null;let n=null;const r="data-tt-policy-suffix";i&&i.hasAttribute(r)&&(n=i.getAttribute(r));const s="dompurify"+(n?"#"+n:"");try{return t.createPolicy(s,{createHTML(o){return o},createScriptURL(o){return o}})}catch{return console.warn("TrustedTypes policy "+s+" could not be created."),null}},Pl=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},St=function(t,i,n,r){return _e(t,i)&&xt(t[i])?G(r.base?Ce(r.base):{},t[i],r.transform):n};function Cl(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Tm();const t=k=>Cl(k);if(t.version="3.4.13",t.removed=[],!e||!e.document||e.document.nodeType!==Oe.document||!e.Element)return t.isSupported=!1,t;let i=e.document;const n=i,r=n.currentScript;e.DocumentFragment;const s=e.HTMLTemplateElement,o=e.Node,a=e.Element,l=e.NodeFilter,c=e.NamedNodeMap;c===void 0&&(e.NamedNodeMap||e.MozNamedAttrMap),e.HTMLFormElement;const u=e.DOMParser,d=e.trustedTypes,h=a.prototype,p=qe(h,"cloneNode"),g=qe(h,"remove"),x=qe(h,"nextSibling"),T=qe(h,"childNodes"),S=qe(h,"parentNode"),P=qe(h,"shadowRoot"),I=qe(h,"attributes"),y=o&&o.prototype?qe(o.prototype,"nodeType"):null,v=o&&o.prototype?qe(o.prototype,"nodeName"):null,E=o&&o.prototype?qe(o.prototype,"ownerDocument"):null;if(typeof s=="function"){const k=i.createElement("template");k.content&&k.content.ownerDocument&&(i=k.content.ownerDocument)}let R,D="",z,$=!1,F=0;const Q=function(){if(F>0)throw Ft('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},X=function(m){Q(),F++;try{return R.createHTML(m)}finally{F--}},b=function(m){Q(),F++;try{return R.createScriptURL(m)}finally{F--}},N=function(){return $||(z=vm(d,r),$=!0),z},A=i,O=A.implementation,V=A.createNodeIterator,L=A.createDocumentFragment,Y=A.getElementsByTagName,J=n.importNode;let H=Pl();t.isSupported=typeof cl=="function"&&typeof S=="function"&&O&&O.createHTMLDocument!==void 0;const Xe=dm,Se=hm,ze=fm,Je=pm,Le=gm,et=mm,xi=xm,Lv=ym;let Ed=bl,ce=null;const Go=G({},[...xl,...xs,...Ss,...ys,...Sl]);let ue=null;const Zo=G({},[...yl,..._s,..._l,...In]);let pe=Object.seal(Kt(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),sn=null,Id=null;const Ct=Object.seal(Kt(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let kd=!0,Qo=!0,Dd=!1,Fd=!0,At=!1,Rt=!0,Wt=!1,Jo=!1,Ur=null,zr=null,ea=!1,Si=!1,Lr=!1,Wr=!1,Md=!0,Nd=!1;const Bd="user-content-";let ta=!0,Vr=!1,yi={},ot=null;const ia=G({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let Od=null;const Ud=G({},["audio","video","img","source","image","track"]);let na=null;const zd=G({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Hr="http://www.w3.org/1998/Math/MathML",$r="http://www.w3.org/2000/svg",at="http://www.w3.org/1999/xhtml";let _i=at,ra=!1,sa=null;const Wv=G({},[Hr,$r,at],ms),Ld=Te(["mi","mo","mn","ms","mtext"]);let oa=G({},Ld);const Wd=Te(["annotation-xml"]);let aa=G({},Wd);const Vv=G({},["title","style","font","a","script"]);let on=null;const Hv=["application/xhtml+xml","text/html"],$v="text/html";let de=null,bi=null;const Xv=i.createElement("form"),Vd=function(m){return m instanceof RegExp||m instanceof Function},la=function(){let m=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(bi&&bi===m)return;(!m||typeof m!="object")&&(m={}),m=Ce(m),on=Hv.indexOf(m.PARSER_MEDIA_TYPE)===-1?$v:m.PARSER_MEDIA_TYPE,de=on==="application/xhtml+xml"?ms:Fi,ce=St(m,"ALLOWED_TAGS",Go,{transform:de}),ue=St(m,"ALLOWED_ATTR",Zo,{transform:de}),sa=St(m,"ALLOWED_NAMESPACES",Wv,{transform:ms}),na=St(m,"ADD_URI_SAFE_ATTR",zd,{transform:de,base:zd}),Od=St(m,"ADD_DATA_URI_TAGS",Ud,{transform:de,base:Ud}),ot=St(m,"FORBID_CONTENTS",ia,{transform:de}),sn=St(m,"FORBID_TAGS",Ce({}),{transform:de}),Id=St(m,"FORBID_ATTR",Ce({}),{transform:de}),yi=_e(m,"USE_PROFILES")?m.USE_PROFILES&&typeof m.USE_PROFILES=="object"?Ce(m.USE_PROFILES):m.USE_PROFILES:!1,kd=m.ALLOW_ARIA_ATTR!==!1,Qo=m.ALLOW_DATA_ATTR!==!1,Dd=m.ALLOW_UNKNOWN_PROTOCOLS||!1,Fd=m.ALLOW_SELF_CLOSE_IN_ATTR!==!1,At=m.SAFE_FOR_TEMPLATES||!1,Rt=m.SAFE_FOR_XML!==!1,Wt=m.WHOLE_DOCUMENT||!1,Si=m.RETURN_DOM||!1,Lr=m.RETURN_DOM_FRAGMENT||!1,Wr=m.RETURN_TRUSTED_TYPE||!1,ea=m.FORCE_BODY||!1,Md=m.SANITIZE_DOM!==!1,Nd=m.SANITIZE_NAMED_PROPS||!1,ta=m.KEEP_CONTENT!==!1,Vr=m.IN_PLACE||!1,Ed=lm(m.ALLOWED_URI_REGEXP)?m.ALLOWED_URI_REGEXP:bl,_i=typeof m.NAMESPACE=="string"?m.NAMESPACE:at,oa=_e(m,"MATHML_TEXT_INTEGRATION_POINTS")&&m.MATHML_TEXT_INTEGRATION_POINTS&&typeof m.MATHML_TEXT_INTEGRATION_POINTS=="object"?Ce(m.MATHML_TEXT_INTEGRATION_POINTS):G({},Ld),aa=_e(m,"HTML_INTEGRATION_POINTS")&&m.HTML_INTEGRATION_POINTS&&typeof m.HTML_INTEGRATION_POINTS=="object"?Ce(m.HTML_INTEGRATION_POINTS):G({},Wd);const _=_e(m,"CUSTOM_ELEMENT_HANDLING")&&m.CUSTOM_ELEMENT_HANDLING&&typeof m.CUSTOM_ELEMENT_HANDLING=="object"?Ce(m.CUSTOM_ELEMENT_HANDLING):Kt(null);if(pe=Kt(null),_e(_,"tagNameCheck")&&Vd(_.tagNameCheck)&&(pe.tagNameCheck=_.tagNameCheck),_e(_,"attributeNameCheck")&&Vd(_.attributeNameCheck)&&(pe.attributeNameCheck=_.attributeNameCheck),_e(_,"allowCustomizedBuiltInElements")&&typeof _.allowCustomizedBuiltInElements=="boolean"&&(pe.allowCustomizedBuiltInElements=_.allowCustomizedBuiltInElements),ve(pe),At&&(Qo=!1),Lr&&(Si=!0),yi&&(ce=G({},Sl),ue=Kt(null),yi.html===!0&&(G(ce,xl),G(ue,yl)),yi.svg===!0&&(G(ce,xs),G(ue,_s),G(ue,In)),yi.svgFilters===!0&&(G(ce,Ss),G(ue,_s),G(ue,In)),yi.mathMl===!0&&(G(ce,ys),G(ue,_l),G(ue,In))),Ct.tagCheck=null,Ct.attributeCheck=null,_e(m,"ADD_TAGS")&&(typeof m.ADD_TAGS=="function"?Ct.tagCheck=m.ADD_TAGS:xt(m.ADD_TAGS)&&(ce===Go&&(ce=Ce(ce)),G(ce,m.ADD_TAGS,de))),_e(m,"ADD_ATTR")&&(typeof m.ADD_ATTR=="function"?Ct.attributeCheck=m.ADD_ATTR:xt(m.ADD_ATTR)&&(ue===Zo&&(ue=Ce(ue)),G(ue,m.ADD_ATTR,de))),_e(m,"ADD_URI_SAFE_ATTR")&&xt(m.ADD_URI_SAFE_ATTR)&&G(na,m.ADD_URI_SAFE_ATTR,de),_e(m,"FORBID_CONTENTS")&&xt(m.FORBID_CONTENTS)&&(ot===ia&&(ot=Ce(ot)),G(ot,m.FORBID_CONTENTS,de)),_e(m,"ADD_FORBID_CONTENTS")&&xt(m.ADD_FORBID_CONTENTS)&&(ot===ia&&(ot=Ce(ot)),G(ot,m.ADD_FORBID_CONTENTS,de)),ta&&(ce["#text"]=!0),Wt&&G(ce,["html","head","body"]),ce.table&&(G(ce,["tbody"]),delete sn.tbody),m.TRUSTED_TYPES_POLICY){if(typeof m.TRUSTED_TYPES_POLICY.createHTML!="function")throw Ft('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof m.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw Ft('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const w=R;R=m.TRUSTED_TYPES_POLICY;try{D=X("")}catch(U){throw R=w,U}}else m.TRUSTED_TYPES_POLICY===null?(R=void 0,D=""):(R===void 0&&(R=N()),R&&typeof D=="string"&&(D=X("")));Te&&Te(m),bi=m},Hd=G({},[...xs,...Ss,...cm]),$d=G({},[...ys,...um]),Yv=function(m,_,w){return _.namespaceURI===at?m==="svg":_.namespaceURI===Hr?m==="svg"&&(w==="annotation-xml"||oa[w]):!!Hd[m]},jv=function(m,_,w){return _.namespaceURI===at?m==="math":_.namespaceURI===$r?m==="math"&&aa[w]:!!$d[m]},Kv=function(m,_,w){return _.namespaceURI===$r&&!aa[w]||_.namespaceURI===Hr&&!oa[w]?!1:!$d[m]&&(Vv[m]||!Hd[m])},qv=function(m){let _=S(m);(!_||!_.tagName)&&(_={namespaceURI:_i,tagName:"template"});const w=Fi(m.tagName),U=Fi(_.tagName);return sa[m.namespaceURI]?m.namespaceURI===$r?Yv(w,_,U):m.namespaceURI===Hr?jv(w,_,U):m.namespaceURI===at?Kv(w,_,U):!!(on==="application/xhtml+xml"&&sa[m.namespaceURI]):!1},wt=function(m){Gt(t.removed,{element:m});try{S(m).removeChild(m)}catch{if(g(m),!S(m))throw Ft("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Xr=function(m){an(m);const _=T(m);if(_){const U=[];qt(_,W=>{Gt(U,W)}),qt(U,W=>{try{g(W)}catch{}})}const w=I(m);if(w)for(let U=w.length-1;U>=0;--U){const W=w[U],j=W&&W.name;if(typeof j=="string")try{m.removeAttribute(j)}catch{}}},Vt=function(m,_){try{Gt(t.removed,{attribute:_.getAttributeNode(m),from:_})}catch{Gt(t.removed,{attribute:null,from:_})}if(_.removeAttribute(m),m==="is")if(Si||Lr)try{wt(_)}catch{}else try{_.setAttribute(m,"")}catch{}},Gv=function(m){const _=I(m);if(_)for(let w=_.length-1;w>=0;--w){const U=_[w],W=U&&U.name;if(!(typeof W!="string"||ue[de(W)]))try{m.removeAttribute(W)}catch{}}},an=function(m){const _=[m];for(;_.length>0;){const w=_.pop();(y?y(w):w.nodeType)===Oe.element&&Gv(w);const W=T(w);if(W)for(let j=W.length-1;j>=0;--j)_.push(W[j])}},Zv=function(m){if(!Rt)return;const _=[m];for(;_.length>0;){const w=_.pop(),U=y?y(w):w.nodeType;if(U===Oe.processingInstruction||U===Oe.comment&&be(vl,w.data)){try{g(w)}catch{}continue}if(U===Oe.element){const j=w,re=de(v?v(w):w.nodeName);try{j.hasAttribute&&j.hasAttribute("patchsrc")&&j.removeAttribute("patchsrc"),j.hasAttribute&&j.hasAttribute("for")&&re!=="label"&&re!=="output"&&j.removeAttribute("for")}catch{}}const W=T(w);if(W)for(let j=W.length-1;j>=0;--j)_.push(W[j])}},Xd=function(m){let _=null,w=null;if(ea)m=""+m;else{const j=fl(m,/^[\r\n\t ]+/);w=j&&j[0]}on==="application/xhtml+xml"&&_i===at&&(m=''+m+"");const U=R?X(m):m;if(_i===at)try{_=new u().parseFromString(U,on)}catch{}if(!_||!_.documentElement){_=O.createDocument(_i,"template",null);try{_.documentElement.innerHTML=ra?D:U}catch{}}const W=_.body||_.documentElement;return m&&w&&W.insertBefore(i.createTextNode(w),W.childNodes[0]||null),_i===at?Y.call(_,Wt?"html":"body")[0]:Wt?_.documentElement:W},Yd=function(m){const _=E?E(m):m.ownerDocument;return V.call(_||m,m,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},Yr=function(m){return m=Mi(m,Xe," "),m=Mi(m,Se," "),m=Mi(m,ze," "),m},ca=function(m){var _;m.normalize();const w=E?E(m):m.ownerDocument,U=V.call(w||m,m,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let W=U.nextNode();for(;W;)W.data=Yr(W.data),W=U.nextNode();const j=(_=m.querySelectorAll)===null||_===void 0?void 0:_.call(m,"template");j&&qt(j,re=>{Ti(re.content)&&ca(re.content)})},jr=function(m){const _=v?v(m):null;return typeof _!="string"||de(_)!=="form"?!1:typeof m.nodeName!="string"||typeof m.textContent!="string"||typeof m.removeChild!="function"||m.attributes!==I(m)||typeof m.removeAttribute!="function"||typeof m.setAttribute!="function"||typeof m.namespaceURI!="string"||typeof m.insertBefore!="function"||typeof m.hasChildNodes!="function"||m.nodeType!==y(m)||m.childNodes!==T(m)},Ti=function(m){if(!y||typeof m!="object"||m===null)return!1;try{return y(m)===Oe.documentFragment}catch{return!1}},ln=function(m){if(!y||typeof m!="object"||m===null)return!1;try{return typeof y(m)=="number"}catch{return!1}};function lt(k,m,_){k.length!==0&&qt(k,w=>{w.call(t,m,_,bi)})}const Qv=function(m,_){return!!(Rt&&m.hasChildNodes()&&!ln(m.firstElementChild)&&be(Tl,m.textContent)&&be(Tl,m.innerHTML)||Rt&&m.namespaceURI===at&&_==="style"&&ln(m.firstElementChild)||m.nodeType===Oe.processingInstruction||Rt&&m.nodeType===Oe.comment&&be(vl,m.data))},Jv=function(m,_,w){if(!sn[_]&&Gd(_)&&(pe.tagNameCheck instanceof RegExp&&be(pe.tagNameCheck,_)||pe.tagNameCheck instanceof Function&&pe.tagNameCheck(_)))return!1;if(ta&&!ot[_]){const U=S(m),W=T(m);if(W&&U){const j=W.length;for(let re=j-1;re>=0;--re){const he=m===w?p(W[re],!0):W[re];U.insertBefore(he,x(m))}}}return wt(m),!0},jd=function(m,_,w,U){return m.length===0?_:_===w||_===U?Ce(_):_},Kd=function(m,_){if(lt(H.beforeSanitizeElements,m,null),m!==_&&S(m)===null)return Vr&&an(m),!0;if(jr(m))return wt(m),!0;const w=de(v?v(m):m.nodeName);if(ce=jd(H.uponSanitizeElement,ce,Go,Ur),lt(H.uponSanitizeElement,m,{tagName:w,allowedTags:ce}),m!==_&&S(m)===null)return Vr&&an(m),!0;if(Qv(m,w))return wt(m),!0;if(sn[w]||!(Ct.tagCheck instanceof Function&&Ct.tagCheck(w))&&!ce[w]){const W=Jv(m,w,_);return W===!1&<(H.afterSanitizeElements,m,null),W}if((y?y(m):m.nodeType)===Oe.element&&!qv(m)||(w==="noscript"||w==="noembed"||w==="noframes")&&be(_m,m.innerHTML))return wt(m),!0;if(At&&m.nodeType===Oe.text){const W=Yr(m.textContent);m.textContent!==W&&(Gt(t.removed,{element:m.cloneNode()}),m.textContent=W)}return lt(H.afterSanitizeElements,m,null),!1},qd=function(m,_,w){if(Id[_]||Rt&&_==="patchsrc"||Rt&&_==="for"&&m!=="label"&&m!=="output"||Md&&(_==="id"||_==="name")&&(w in i||w in Xv))return!1;const U=ue[_]||Ct.attributeCheck instanceof Function&&Ct.attributeCheck(_,m);if(!(Qo&&be(Je,_))){if(!(kd&&be(Le,_))){if(U){if(!na[_]){if(!be(Ed,Mi(w,xi,""))){if(!((_==="src"||_==="xlink:href"||_==="href")&&m!=="script"&&pl(w,"data:")===0&&Od[m])){if(!(Dd&&!be(et,Mi(w,xi,"")))){if(w)return!1}}}}}else if(!(Gd(m)&&(pe.tagNameCheck instanceof RegExp&&be(pe.tagNameCheck,m)||pe.tagNameCheck instanceof Function&&pe.tagNameCheck(m))&&(pe.attributeNameCheck instanceof RegExp&&be(pe.attributeNameCheck,_)||pe.attributeNameCheck instanceof Function&&pe.attributeNameCheck(_,m))||_==="is"&&pe.allowCustomizedBuiltInElements&&(pe.tagNameCheck instanceof RegExp&&be(pe.tagNameCheck,w)||pe.tagNameCheck instanceof Function&&pe.tagNameCheck(w))))return!1}}return!0},eP=G({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),Gd=function(m){return!eP[Fi(m)]&&be(Lv,m)},tP=function(m,_,w,U){if(R&&typeof d=="object"&&typeof d.getAttributeType=="function"&&!w)switch(d.getAttributeType(m,_)){case"TrustedHTML":return X(U);case"TrustedScriptURL":return b(U)}return U},iP=function(m,_,w,U){try{w?m.setAttributeNS(w,_,U):m.setAttribute(_,U),jr(m)?wt(m):hl(t.removed)}catch{Vt(_,m)}},Zd=function(m){lt(H.beforeSanitizeAttributes,m,null);const _=m.attributes;if(!_||jr(m))return;ue=jd(H.uponSanitizeAttribute,ue,Zo,zr);const w={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:ue,forceKeepAttr:void 0};let U=_.length;const W=de(m.nodeName);for(;U--;){const j=_[U],re=j.name,he=j.namespaceURI,Me=j.value,Ne=de(re),da=Me;let Ie=re==="value"?da:im(da);if(w.attrName=Ne,w.attrValue=Ie,w.keepAttr=!0,w.forceKeepAttr=void 0,lt(H.uponSanitizeAttribute,m,w),Ie=w.attrValue,Nd&&(Ne==="id"||Ne==="name")&&pl(Ie,Bd)!==0&&(Vt(re,m),Ie=Bd+Ie),Rt&&be(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,Ie)){Vt(re,m);continue}if(Ne==="attributename"&&fl(Ie,"href")){Vt(re,m);continue}if(!w.forceKeepAttr){if(!w.keepAttr){Vt(re,m);continue}if(!Fd&&be(bm,Ie)){Vt(re,m);continue}if(At&&(Ie=Yr(Ie)),!qd(W,Ne,Ie)){Vt(re,m);continue}Ie=tP(W,Ne,he,Ie),Ie!==da&&iP(m,re,he,Ie)}}lt(H.afterSanitizeAttributes,m,null)},Kr=function(m){let _=null;const w=Yd(m);for(lt(H.beforeSanitizeShadowDOM,m,null);_=w.nextNode();)if(lt(H.uponSanitizeShadowNode,_,null),Kd(_,m),Zd(_),Ti(_.content)&&Kr(_.content),(y?y(_):_.nodeType)===Oe.element){const W=P(_);Ti(W)&&(ua(W),Kr(W))}lt(H.afterSanitizeShadowDOM,m,null)},ua=function(m){const _=[{node:m,shadow:null}];for(;_.length>0;){const w=_.pop();if(w.shadow){Kr(w.shadow);continue}const U=w.node,j=(y?y(U):U.nodeType)===Oe.element,re=T(U);if(re)for(let he=re.length-1;he>=0;--he)_.push({node:re[he],shadow:null});if(j){const he=v?v(U):null;if(typeof he=="string"&&de(he)==="template"){const Me=U.content;Ti(Me)&&_.push({node:Me,shadow:null})}}if(j){const he=P(U);Ti(he)&&_.push({node:null,shadow:he},{node:he,shadow:null})}}};return t.sanitize=function(k){let m=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_=null,w=null,U=null,W=null;if(ra=!k,ra&&(k=""),typeof k!="string"&&!ln(k)&&(k=am(k),typeof k!="string"))throw Ft("dirty is not a string, aborting");if(!t.isSupported)return k;Jo?(ce=Ur,ue=zr):la(m),(H.uponSanitizeElement.length>0||H.uponSanitizeAttribute.length>0)&&(ce=Ce(ce)),H.uponSanitizeAttribute.length>0&&(ue=Ce(ue)),t.removed=[];const j=Vr&&typeof k!="string"&&ln(k);if(j){Zv(k);const Me=v?v(k):k.nodeName;if(typeof Me=="string"){const Ne=de(Me);if(!ce[Ne]||sn[Ne])throw Xr(k),Ft("root node is forbidden and cannot be sanitized in-place")}if(jr(k))throw Xr(k),Ft("root node is clobbered and cannot be sanitized in-place");try{ua(k)}catch(Ne){throw Xr(k),Ne}}else if(ln(k))_=Xd(""),w=_.ownerDocument.importNode(k,!0),w.nodeType===Oe.element&&w.nodeName==="BODY"||w.nodeName==="HTML"?_=w:_.appendChild(w),ua(w);else{if(!Si&&!At&&!Wt&&k.indexOf("<")===-1)return R&&Wr?X(k):k;if(_=Xd(k),!_)return Si?null:Wr?D:""}_&&ea&&wt(_.firstChild);const re=j?k:_;try{const Me=Yd(re);for(;U=Me.nextNode();)Kd(U,re),Zd(U),Ti(U.content)&&Kr(U.content)}catch(Me){throw j&&(Xr(k),qt(t.removed,Ne=>{Ne.element&&an(Ne.element)})),Me}if(j)return qt(t.removed,Me=>{Me.element&&an(Me.element)}),At&&ca(k),k;if(Si){if(At&&ca(_),Lr)for(W=L.call(_.ownerDocument);_.firstChild;)W.appendChild(_.firstChild);else W=_;return(ue.shadowroot||ue.shadowrootmode)&&(W=J.call(n,W,!0)),W}let he=Wt?_.outerHTML:_.innerHTML;return Wt&&ce["!doctype"]&&_.ownerDocument&&_.ownerDocument.doctype&&_.ownerDocument.doctype.name&&be(Sm,_.ownerDocument.doctype.name)&&(he=" +`+he),At&&(he=Yr(he)),R&&Wr?X(he):he},t.setConfig=function(){let k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};la(k),Jo=!0,Ur=ce,zr=ue},t.clearConfig=function(){bi=null,Jo=!1,Ur=null,zr=null,R=z,D=""},t.isValidAttribute=function(k,m,_){bi||la({});const w=de(k),U=de(m);return qd(w,U,_)},t.addHook=function(k,m){typeof m=="function"&&_e(H,k)&&Gt(H[k],m)},t.removeHook=function(k,m){if(_e(H,k)){if(m!==void 0){const _=em(H[k],m);return _===-1?void 0:tm(H[k],_,1)[0]}return hl(H[k])}},t.removeHooks=function(k){_e(H,k)&&(H[k]=[])},t.removeAllHooks=function(){H=Pl()},t}var Pm=Cl();function kn(e,t){return e==null||t==null?NaN:et?1:e>=t?0:NaN}function Cm(e,t){return e==null||t==null?NaN:te?1:t>=e?0:NaN}function Al(e){let t,i,n;e.length!==2?(t=kn,i=(a,l)=>kn(e(a),l),n=(a,l)=>e(a)-l):(t=e===kn||e===Cm?e:Am,i=e,n=e);function r(a,l,c=0,u=a.length){if(c>>1;i(a[d],l)<0?c=d+1:u=d}while(c>>1;i(a[d],l)<=0?c=d+1:u=d}while(cc&&n(a[d-1],l)>-n(a[d],l)?d-1:d}return{left:r,center:o,right:s}}function Am(){return 0}function Rm(e){return e===null?NaN:+e}const wm=Al(kn).right;Al(Rm).center;var bs=Math.sqrt(50),Ts=Math.sqrt(10),vs=Math.sqrt(2);function Em(e,t,i){var n,r=-1,s,o,a;if(t=+t,e=+e,i=+i,e===t&&i>0)return[e];if((n=t0){let l=Math.round(e/a),c=Math.round(t/a);for(l*at&&--c,o=new Array(s=c-l+1);++rt&&--c,o=new Array(s=c-l+1);++r=0?(s>=bs?10:s>=Ts?5:s>=vs?2:1)*Math.pow(10,r):-Math.pow(10,-r)/(s>=bs?10:s>=Ts?5:s>=vs?2:1)}function Im(e,t,i){var n=Math.abs(t-e)/Math.max(0,i),r=Math.pow(10,Math.floor(Math.log(n)/Math.LN10)),s=n/r;return s>=bs?r*=10:s>=Ts?r*=5:s>=vs&&(r*=2),tt&&(i=e,e=t,t=i),function(n){return Math.max(e,Math.min(t,n))}}function Nm(e,t,i){var n=e[0],r=e[1],s=t[0],o=t[1];return r2?Bm:Nm,l=c=null,d}function d(h){return h==null||isNaN(h=+h)?s:(l||(l=a(e.map(n),t,i)))(n(o(h)))}return d.invert=function(h){return o(r((c||(c=a(t,e.map(n),Ke)))(h)))},d.domain=function(h){return arguments.length?(e=Array.from(h,Fm),u()):e.slice()},d.range=function(h){return arguments.length?(t=Array.from(h),u()):t.slice()},d.rangeRound=function(h){return t=Array.from(h),i=dp,u()},d.clamp=function(h){return arguments.length?(o=h?!0:nt,u()):o!==nt},d.interpolate=function(h){return arguments.length?(i=h,u()):i},d.unknown=function(h){return arguments.length?(s=h,d):s},function(h,p){return n=h,r=p,u()}}function Om(){return kl()(nt,nt)}function Um(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function Dn(e,t){if((i=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var i,n=e.slice(0,i);return[n.length>1?n[0]+n.slice(2):n,+e.slice(i+1)]}function Zt(e){return e=Dn(Math.abs(e)),e?e[1]:NaN}function zm(e,t){return function(i,n){for(var r=i.length,s=[],o=0,a=e[0],l=0;r>0&&a>0&&(l+a+1>n&&(a=Math.max(1,n-l)),s.push(i.substring(r-=a,r+a)),!((l+=a+1)>n));)a=e[o=(o+1)%e.length];return s.reverse().join(t)}}function Lm(e){return function(t){return t.replace(/[0-9]/g,function(i){return e[+i]})}}var Wm=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Fn(e){if(!(t=Wm.exec(e)))throw new Error("invalid format: "+e);var t;return new Cs({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}Fn.prototype=Cs.prototype;function Cs(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}Cs.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function Vm(e){e:for(var t=e.length,i=1,n=-1,r;i0&&(n=0);break}return n>0?e.slice(0,n)+e.slice(r+1):e}var Dl;function Hm(e,t){var i=Dn(e,t);if(!i)return e+"";var n=i[0],r=i[1],s=r-(Dl=Math.max(-8,Math.min(8,Math.floor(r/3)))*3)+1,o=n.length;return s===o?n:s>o?n+new Array(s-o+1).join("0"):s>0?n.slice(0,s)+"."+n.slice(s):"0."+new Array(1-s).join("0")+Dn(e,Math.max(0,t+s-1))[0]}function Fl(e,t){var i=Dn(e,t);if(!i)return e+"";var n=i[0],r=i[1];return r<0?"0."+new Array(-r).join("0")+n:n.length>r+1?n.slice(0,r+1)+"."+n.slice(r+1):n+new Array(r-n.length+2).join("0")}const Ml={"%":(e,t)=>(e*100).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:Um,e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>Fl(e*100,t),r:Fl,s:Hm,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function Nl(e){return e}var Bl=Array.prototype.map,Ol=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function $m(e){var t=e.grouping===void 0||e.thousands===void 0?Nl:zm(Bl.call(e.grouping,Number),e.thousands+""),i=e.currency===void 0?"":e.currency[0]+"",n=e.currency===void 0?"":e.currency[1]+"",r=e.decimal===void 0?".":e.decimal+"",s=e.numerals===void 0?Nl:Lm(Bl.call(e.numerals,String)),o=e.percent===void 0?"%":e.percent+"",a=e.minus===void 0?"−":e.minus+"",l=e.nan===void 0?"NaN":e.nan+"";function c(d){d=Fn(d);var h=d.fill,p=d.align,g=d.sign,x=d.symbol,T=d.zero,S=d.width,P=d.comma,I=d.precision,y=d.trim,v=d.type;v==="n"?(P=!0,v="g"):Ml[v]||(I===void 0&&(I=12),y=!0,v="g"),(T||h==="0"&&p==="=")&&(T=!0,h="0",p="=");var E=x==="$"?i:x==="#"&&/[boxX]/.test(v)?"0"+v.toLowerCase():"",R=x==="$"?n:/[%p]/.test(v)?o:"",D=Ml[v],z=/[defgprs%]/.test(v);I=I===void 0?6:/[gprs]/.test(v)?Math.max(1,Math.min(21,I)):Math.max(0,Math.min(20,I));function $(F){var Q=E,X=R,b,N,A;if(v==="c")X=D(F)+X,F="";else{F=+F;var O=F<0||1/F<0;if(F=isNaN(F)?l:D(Math.abs(F),I),y&&(F=Vm(F)),O&&+F==0&&g!=="+"&&(O=!1),Q=(O?g==="("?g:a:g==="-"||g==="("?"":g)+Q,X=(v==="s"?Ol[8+Dl/3]:"")+X+(O&&g==="("?")":""),z){for(b=-1,N=F.length;++bA||A>57){X=(A===46?r+F.slice(b+1):F.slice(b))+X,F=F.slice(0,b);break}}}P&&!T&&(F=t(F,1/0));var V=Q.length+F.length+X.length,L=V>1)+Q+F+X+L.slice(V);break;default:F=L+Q+F+X;break}return s(F)}return $.toString=function(){return d+""},$}function u(d,h){var p=c((d=Fn(d),d.type="f",d)),g=Math.max(-8,Math.min(8,Math.floor(Zt(h)/3)))*3,x=Math.pow(10,-g),T=Ol[8+g/3];return function(S){return p(x*S)+T}}return{format:c,formatPrefix:u}}var Mn,Ul,zl;Xm({thousands:",",grouping:[3],currency:["$",""]});function Xm(e){return Mn=$m(e),Ul=Mn.format,zl=Mn.formatPrefix,Mn}function Ym(e){return Math.max(0,-Zt(Math.abs(e)))}function jm(e,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Zt(t)/3)))*3-Zt(Math.abs(e)))}function Km(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,Zt(t)-Zt(e))+1}function qm(e,t,i,n){var r=Im(e,t,i),s;switch(n=Fn(n??",f"),n.type){case"s":{var o=Math.max(Math.abs(e),Math.abs(t));return n.precision==null&&!isNaN(s=jm(r,o))&&(n.precision=s),zl(n,o)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(s=Km(r,Math.max(Math.abs(e),Math.abs(t))))&&(n.precision=s-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(s=Ym(r))&&(n.precision=s-(n.type==="%")*2);break}}return Ul(n)}function Ll(e){var t=e.domain;return e.ticks=function(i){var n=t();return Em(n[0],n[n.length-1],i??10)},e.tickFormat=function(i,n){var r=t();return qm(r[0],r[r.length-1],i??10,n)},e.nice=function(i){i==null&&(i=10);var n=t(),r=0,s=n.length-1,o=n[r],a=n[s],l,c,u=10;for(a0;){if(c=Rl(o,a,i),c===l)return n[r]=o,n[s]=a,t(n);if(c>0)o=Math.floor(o/c)*c,a=Math.ceil(a/c)*c;else if(c<0)o=Math.ceil(o*c)/c,a=Math.floor(a*c)/c;else break;l=c}return e},e}function As(){var e=Om();return e.copy=function(){return Il(e,As())},wl.apply(e,arguments),Ll(e)}function Wl(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function Gm(e){return e<0?-Math.sqrt(-e):Math.sqrt(e)}function Zm(e){return e<0?-e*e:e*e}function Qm(e){var t=e(nt,nt),i=1;function n(){return i===1?e(nt,nt):i===.5?e(Gm,Zm):e(Wl(i),Wl(1/i))}return t.exponent=function(r){return arguments.length?(i=+r,n()):i},Ll(t)}function Vl(){var e=Qm(kl());return e.copy=function(){return Il(e,Vl()).exponent(e.exponent())},wl.apply(e,arguments),e}var Hl=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)});function Jm(){var e=new Hl(9);return Hl!=Float32Array&&(e[1]=0,e[2]=0,e[3]=0,e[5]=0,e[6]=0,e[7]=0),e[0]=1,e[4]=1,e[8]=1,e}function $l(e,t,i){var n=t[0],r=t[1],s=t[2],o=t[3],a=t[4],l=t[5],c=t[6],u=t[7],d=t[8],h=i[0],p=i[1];return e[0]=n,e[1]=r,e[2]=s,e[3]=o,e[4]=a,e[5]=l,e[6]=h*n+p*o+c,e[7]=h*r+p*a+u,e[8]=h*s+p*l+d,e}function Rs(e,t,i){var n=i[0],r=i[1];return e[0]=n*t[0],e[1]=n*t[1],e[2]=n*t[2],e[3]=r*t[3],e[4]=r*t[4],e[5]=r*t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e}function ex(e,t,i){return e[0]=2/t,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/i,e[5]=0,e[6]=-1,e[7]=1,e[8]=1,e}function tx(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function ix(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if(typeof t=="function"){var i=function n(){return this instanceof n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};i.prototype=t.prototype}else i={};return Object.defineProperty(i,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(i,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}),i}var Nn={exports:{}},nx=Nn.exports,Xl;function rx(){return Xl||(Xl=1,function(e){(function(t,i,n){function r(l){var c=this,u=a();c.next=function(){var d=2091639*c.s0+c.c*23283064365386963e-26;return c.s0=c.s1,c.s1=c.s2,c.s2=d-(c.c=d|0)},c.c=1,c.s0=u(" "),c.s1=u(" "),c.s2=u(" "),c.s0-=u(l),c.s0<0&&(c.s0+=1),c.s1-=u(l),c.s1<0&&(c.s1+=1),c.s2-=u(l),c.s2<0&&(c.s2+=1),u=null}function s(l,c){return c.c=l.c,c.s0=l.s0,c.s1=l.s1,c.s2=l.s2,c}function o(l,c){var u=new r(l),d=c&&c.state,h=u.next;return h.int32=function(){return u.next()*4294967296|0},h.double=function(){return h()+(h()*2097152|0)*11102230246251565e-32},h.quick=h,d&&(typeof d=="object"&&s(d,u),h.state=function(){return s(u,{})}),h}function a(){var l=4022871197,c=function(u){u=String(u);for(var d=0;d>>0,h-=l,h*=l,l=h>>>0,h-=l,l+=h*4294967296}return(l>>>0)*23283064365386963e-26};return c}i&&i.exports?i.exports=o:this.alea=o})(nx,e)}(Nn)),Nn.exports}var Bn={exports:{}},sx=Bn.exports,Yl;function ox(){return Yl||(Yl=1,function(e){(function(t,i,n){function r(a){var l=this,c="";l.x=0,l.y=0,l.z=0,l.w=0,l.next=function(){var d=l.x^l.x<<11;return l.x=l.y,l.y=l.z,l.z=l.w,l.w^=l.w>>>19^d^d>>>8},a===(a|0)?l.x=a:c+=a;for(var u=0;u>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(typeof u=="object"&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xor128=o})(sx,e)}(Bn)),Bn.exports}var On={exports:{}},ax=On.exports,jl;function lx(){return jl||(jl=1,function(e){(function(t,i,n){function r(a){var l=this,c="";l.next=function(){var d=l.x^l.x>>>2;return l.x=l.y,l.y=l.z,l.z=l.w,l.w=l.v,(l.d=l.d+362437|0)+(l.v=l.v^l.v<<4^(d^d<<1))|0},l.x=0,l.y=0,l.z=0,l.w=0,l.v=0,a===(a|0)?l.x=a:c+=a;for(var u=0;u>>4),l.next()}function s(a,l){return l.x=a.x,l.y=a.y,l.z=a.z,l.w=a.w,l.v=a.v,l.d=a.d,l}function o(a,l){var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(typeof u=="object"&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xorwow=o})(ax,e)}(On)),On.exports}var Un={exports:{}},cx=Un.exports,Kl;function ux(){return Kl||(Kl=1,function(e){(function(t,i,n){function r(a){var l=this;l.next=function(){var u=l.x,d=l.i,h,p;return h=u[d],h^=h>>>7,p=h^h<<24,h=u[d+1&7],p^=h^h>>>10,h=u[d+3&7],p^=h^h>>>3,h=u[d+4&7],p^=h^h<<7,h=u[d+7&7],h=h^h<<13,p^=h^h<<9,u[d]=p,l.i=d+1&7,p};function c(u,d){var h,p=[];if(d===(d|0))p[0]=d;else for(d=""+d,h=0;h0;--h)u.next()}c(l,a)}function s(a,l){return l.x=a.x.slice(),l.i=a.i,l}function o(a,l){a==null&&(a=+new Date);var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(u.x&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xorshift7=o})(cx,e)}(Un)),Un.exports}var zn={exports:{}},dx=zn.exports,ql;function hx(){return ql||(ql=1,function(e){(function(t,i,n){function r(a){var l=this;l.next=function(){var u=l.w,d=l.X,h=l.i,p,g;return l.w=u=u+1640531527|0,g=d[h+34&127],p=d[h=h+1&127],g^=g<<13,p^=p<<17,g^=g>>>15,p^=p>>>12,g=d[h]=g^p,l.i=h,g+(u^u>>>16)|0};function c(u,d){var h,p,g,x,T,S=[],P=128;for(d===(d|0)?(p=d,d=null):(d=d+"\0",p=0,P=Math.max(P,d.length)),g=0,x=-32;x>>15,p^=p<<4,p^=p>>>13,x>=0&&(T=T+1640531527|0,h=S[x&127]^=p+T,g=h==0?g+1:0);for(g>=128&&(S[(d&&d.length||0)&127]=-1),g=127,x=4*128;x>0;--x)p=S[g+34&127],h=S[g=g+1&127],p^=p<<13,h^=h<<17,p^=p>>>15,h^=h>>>12,S[g]=p^h;u.w=T,u.X=S,u.i=g}c(l,a)}function s(a,l){return l.i=a.i,l.w=a.w,l.X=a.X.slice(),l}function o(a,l){a==null&&(a=+new Date);var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(u.X&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xor4096=o})(dx,e)}(zn)),zn.exports}var Ln={exports:{}},fx=Ln.exports,Gl;function px(){return Gl||(Gl=1,function(e){(function(t,i,n){function r(a){var l=this,c="";l.next=function(){var d=l.b,h=l.c,p=l.d,g=l.a;return d=d<<25^d>>>7^h,h=h-p|0,p=p<<24^p>>>8^g,g=g-d|0,l.b=d=d<<20^d>>>12^h,l.c=h=h-p|0,l.d=p<<16^h>>>16^g,l.a=g-d|0},l.a=0,l.b=0,l.c=-1640531527,l.d=1367130551,a===Math.floor(a)?(l.a=a/4294967296|0,l.b=a|0):c+=a;for(var u=0;u>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(typeof u=="object"&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.tychei=o})(fx,e)}(Ln)),Ln.exports}var Wn={exports:{}};const gx=ix(Object.freeze(Object.defineProperty({__proto__:null,default:{}},Symbol.toStringTag,{value:"Module"})));var mx=Wn.exports,Zl;function xx(){return Zl||(Zl=1,function(e){(function(t,i,n){var r=256,s=6,o=52,a="random",l=n.pow(r,s),c=n.pow(2,o),u=c*2,d=r-1,h;function p(y,v,E){var R=[];v=v==!0?{entropy:!0}:v||{};var D=S(T(v.entropy?[y,I(i)]:y??P(),3),R),z=new g(R),$=function(){for(var F=z.g(s),Q=l,X=0;F=u;)F/=2,Q/=2,X>>>=1;return(F+X)/Q};return $.int32=function(){return z.g(4)|0},$.quick=function(){return z.g(4)/4294967296},$.double=$,S(I(z.S),i),(v.pass||E||function(F,Q,X,b){return b&&(b.S&&x(b,z),F.state=function(){return x(z,{})}),X?(n[a]=F,Q):F})($,D,"global"in v?v.global:this==n,v.state)}function g(y){var v,E=y.length,R=this,D=0,z=R.i=R.j=0,$=R.S=[];for(E||(y=[E++]);D0)return i;throw new Error("Expected number to be positive, got "+i.n)},this.lessThan=function(n){if(i.n=n)return i;throw new Error("Expected number to be greater than or equal to "+n+", got "+i.n)},this.greaterThan=function(n){if(i.n>n)return i;throw new Error("Expected number to be greater than "+n+", got "+i.n)},this.n=t},Ax=function(e,t,i){return t===void 0&&(t=0),i===void 0&&(i=1),i===void 0&&(i=t===void 0?1:t,t=0),Ge(t).isInt(),Ge(i).isInt(),function(){return Math.floor(e.next()*(i-t+1)+t)}},Rx=function(e){return function(){return e.next()>=.5}},wx=function(e,t,i){return t===void 0&&(t=0),i===void 0&&(i=1),function(){var n,r,s;do n=e.next()*2-1,r=e.next()*2-1,s=n*n+r*r;while(!s||s>1);return t+i*r*Math.sqrt(-2*Math.log(s)/s)}},Ex=function(e,t,i){t===void 0&&(t=0),i===void 0&&(i=1);var n=e.normal(t,i);return function(){return Math.exp(n())}},Ix=function(e,t){return t===void 0&&(t=.5),Ge(t).greaterThanOrEqual(0).lessThan(1),function(){return Math.floor(e.next()+t)}},kx=function(e,t,i){return t===void 0&&(t=1),i===void 0&&(i=.5),Ge(t).isInt().isPositive(),Ge(i).greaterThanOrEqual(0).lessThan(1),function(){for(var n=0,r=0;n++l;)u=u-l,l=t*l/++c;return c}}else{var n=Math.sqrt(t),r=.931+2.53*n,s=-.059+.02483*r,o=1.1239+1.1328/(r-3.4),a=.9277-3.6224/(r-2);return function(){for(;;){var l=void 0,c=e.next();if(c<=.86*a)return l=c/a-.43,Math.floor((2*s/(.5-Math.abs(l))+r)*l+t+.445);c>=a?l=e.next()-.5:(l=c/a-.93,l=(l<0?-.5:.5)-l,c=e.next()*a);var u=.5-Math.abs(l);if(!(u<.013&&c>u)){var d=Math.floor((2*s/u+r)*l+t+.445);if(c=c*o/(s/(u*u)+r),d>=10){var h=(d+.5)*Math.log(t/d)-t-Nx+d-(.08333333333333333-(.002777777777777778-1/(1260*d*d))/(d*d))/d;if(Math.log(c*n)<=h)return d}else if(d>=0){var p,g=(p=Mx(d))!=null?p:0;if(Math.log(c)<=d*Math.log(t)-t-g)return d}}}}}},Ox=function(e,t){return t===void 0&&(t=1),Ge(t).isPositive(),function(){return-Math.log(1-e.next())/t}},Ux=function(e,t){return t===void 0&&(t=1),Ge(t).isInt().greaterThanOrEqual(0),function(){for(var i=0,n=0;n0){var s=this.uniformInt(0,r-1)();return n[s]}else return},t._memoize=function(n,r){var s=[].slice.call(arguments,2),o=""+s.join(";"),a=this._cache[n];return(a===void 0||a.key!==o)&&(a={key:o,distribution:r.apply(void 0,[this].concat(s))},this._cache[n]=a),a.distribution},Es(e,[{key:"rng",get:function(){return this._rng}}]),e}();new ic;const Qt=.001,Hn=64,Vx=4,$n=2;class Hx{constructor(){this.pointsTextureSize=0,this.linksTextureSize=0,this.alpha=1,this.transform=Jm(),this.screenSize=[0,0],this.mousePosition=[0,0],this.screenMousePosition=[0,0],this.searchArea=[[0,0],[0,0]],this.isSimulationRunning=!1,this.simulationProgress=0,this.maxPointSize=Hn,this.hoveredPoint=void 0,this.focusedPoint=void 0,this.draggingPointIndex=void 0,this.hoveredLinkIndex=void 0,this.hostHoveredPointIndex=void 0,this.hostHoveredLinkIndex=void 0,this.adjustedSpaceSize=Ze.spaceSize,this.isSpaceKeyPressed=!1,this.webglMaxTextureSize=16384,this.hoveredPointRingColor=[1,1,1,dc],this.focusedPointRingColor=[1,1,1,hc],this.outlinedPointRingColor=[1,1,1,1],this.highlightedPointSet=void 0,this.outlinedPointSet=void 0,this.hoveredLinkColor=[-1,-1,-1,-1],this.greyoutPointColor=[-1,-1,-1,-1],this.isDarkenGreyout=!1,this.isLinkHoveringEnabled=!1,this.alphaTarget=0,this.scalePointX=As(),this.scalePointY=As(),this.random=new ic,this._backgroundColor=[0,0,0,0],this.alphaDecay=t=>1-Math.pow(Qt,1/t)}get backgroundColor(){return this._backgroundColor}get transformationMatrix4x4(){const t=this.transform;if(t.length!==9)throw new Error(`Transform must be a 9-element array (3x3 matrix), got ${t.length} elements`);return[t[0],t[1],t[2],0,t[3],t[4],t[5],0,t[6],t[7],t[8],0,0,0,0,1]}set backgroundColor(t){this._backgroundColor=t;const i=oc(t[0],t[1],t[2]);if(this.div){const n=i>.65?"black":"white";this.div.style.setProperty("--cosmosgl-attribution-color",n),this.div.style.setProperty("--cosmosgl-error-message-color",n),this.div.style.backgroundColor=`rgba(${t[0]*255}, ${t[1]*255}, ${t[2]*255}, ${t[3]})`}this.isDarkenGreyout=i<.65}addRandomSeed(t){this.random=this.random.clone(t)}getRandomFloat(t,i){return this.random.float(t,i)}adjustSpaceSize(t,i){(t<=0||!isFinite(t))&&(console.error(`Invalid spaceSize value: ${t}. Using default value of ${Ze.spaceSize}`),t=Ze.spaceSize);const n=2;if(t=i?(this.adjustedSpaceSize=Math.max(i/2,n),console.warn(`The \`spaceSize\` has been reduced to ${this.adjustedSpaceSize} due to WebGL limits`)):this.adjustedSpaceSize=t}setWebGLMaxTextureSize(t){this.webglMaxTextureSize=t}updateScreenSize(t,i){const{adjustedSpaceSize:n}=this;this.screenSize=[t,i],this.scalePointX.domain([0,n]).range([(t-n)/2,(t+n)/2]),this.scalePointY.domain([n,0]).range([(i-n)/2,(i+n)/2])}scaleX(t){return this.scalePointX(t)}scaleY(t){return this.scalePointY(t)}setHoveredPointRingColor(t){const i=We(t);this.hoveredPointRingColor[0]=i[0],this.hoveredPointRingColor[1]=i[1],this.hoveredPointRingColor[2]=i[2]}setFocusedPointRingColor(t){const i=We(t);this.focusedPointRingColor[0]=i[0],this.focusedPointRingColor[1]=i[1],this.focusedPointRingColor[2]=i[2]}setOutlinedPointRingColor(t){const i=We(t);this.outlinedPointRingColor[0]=i[0],this.outlinedPointRingColor[1]=i[1],this.outlinedPointRingColor[2]=i[2],this.outlinedPointRingColor[3]=i[3]}setHighlightedPointSet(t){this.highlightedPointSet=t?new Set(t):void 0}setOutlinedPointSet(t){this.outlinedPointSet=t?new Set(t):void 0}setGreyoutPointColor(t){if(t===void 0){this.greyoutPointColor=[-1,-1,-1,-1];return}const i=We(t);this.greyoutPointColor[0]=i[0],this.greyoutPointColor[1]=i[1],this.greyoutPointColor[2]=i[2],this.greyoutPointColor[3]=i[3]}updateLinkHoveringEnabled(t){this.isLinkHoveringEnabled=!!(t.onLinkClick||t.onLinkContextMenu||t.onLinkMouseOver||t.onLinkMouseOut),this.isLinkHoveringEnabled||(this.hoveredLinkIndex=void 0)}setHoveredLinkColor(t){if(t===void 0){this.hoveredLinkColor=[-1,-1,-1,-1];return}const i=We(t);this.hoveredLinkColor[0]=i[0],this.hoveredLinkColor[1]=i[1],this.hoveredLinkColor[2]=i[2],this.hoveredLinkColor[3]=i[3]}setFocusedPoint(t){t!==void 0?this.focusedPoint={index:t}:this.focusedPoint=void 0}addAlpha(t){return(this.alphaTarget-this.alpha)*this.alphaDecay(t)}}const nc=e=>typeof e=="function",ks=e=>Array.isArray(e),rc=e=>e instanceof Object,sc=e=>e instanceof Object?e.constructor.name!=="Function"&&e.constructor.name!=="Object":!1,$x=e=>rc(e)&&!ks(e)&&!nc(e)&&!sc(e);function We(e){let t;if(ks(e))t=e;else{const i=mt(e),n=i==null?void 0:i.rgb();t=[((n==null?void 0:n.r)??0)/255,((n==null?void 0:n.g)??0)/255,((n==null?void 0:n.b)??0)/255,(i==null?void 0:i.opacity)??1]}return t}function oc(e,t,i){return .2126*e+.7152*t+.0722*i}function we(e,t,i=0,n=0,r,s){return e.readPixelsToArrayWebGL(t,{sourceX:i,sourceY:n,sourceWidth:r,sourceHeight:s})}function ac(){const e=new Uint32Array(2);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(7,"0")).join("")}function Ds(e,t){const i=[],n=Math.min(e.length/4,t??1/0);for(let r=0;r(e[e.Circle=0]="Circle",e[e.Square=1]="Square",e[e.Triangle=2]="Triangle",e[e.Diamond=3]="Diamond",e[e.Pentagon=4]="Pentagon",e[e.Hexagon=5]="Hexagon",e[e.Star=6]="Star",e[e.Cross=7]="Cross",e[e.None=8]="None",e))(Ms||{}),Ns=(e=>(e[e.Solid=0]="Solid",e[e.Dashed=1]="Dashed",e[e.Dotted=2]="Dotted",e))(Ns||{});const uc=e=>{if(!e)return;const{offsets:t,neighbors:i,linkIndices:n}=e,r=new Array(t.length-1).fill(void 0);for(let s=0;s=0&&i<=8?i:Ze.pointDefaultShape;if(this.inputPointShapes===void 0||this.inputPointShapes.length!==this.pointsNumber)this.pointShapes=new Float32Array(this.pointsNumber).fill(n);else{this.pointShapes=new Float32Array(this.inputPointShapes);const r=this.pointShapes;for(let s=0;s8)&&(r[s]=n)}}}updatePointImageIndices(){if(this.pointsNumber===void 0){this.pointImageIndices=void 0;return}if(this.inputPointImageIndices===void 0||this.inputPointImageIndices.length!==this.pointsNumber)this.pointImageIndices=new Float32Array(this.pointsNumber).fill(-1);else{const t=new Float32Array(this.inputPointImageIndices);for(let i=0;i=0&&i<(((r=this.inputImageData)==null?void 0:r.length)??0)}getResolvedPointFootprint(t,i){var r;const n=this.pointDrawsImage(t)?(r=this.pointImageSizes)==null?void 0:r[t]:void 0;return Math.max(i??this.getResolvedPointSize(t),n??0)}isPointIndex(t){return t!==void 0&&Number.isInteger(t)&&t>=0&&t<(this.pointsNumber??0)}updateLinks(){this.inputLinks!==void 0&&this.inputLinks.length%2!==0&&(console.warn(`Invalid links length: ${this.inputLinks.length}. The array must hold [source, target] pairs — the trailing value was ignored.`),this.inputLinks=this.inputLinks.subarray(0,this.inputLinks.length-1)),this.links=this.inputLinks}updateLinkColor(){if(this.linksNumber===void 0){this.linkColors=void 0;return}const t=We(this._config.linkDefaultColor);if(this.inputLinkColors===void 0||this.inputLinkColors.length/4!==this.linksNumber){this.linkColors=new Float32Array(this.linksNumber*4);for(let i=0;i=0&&i<=2?i:Ze.linkDefaultStyle;if(this.inputLinkStyles===void 0||this.inputLinkStyles.length!==this.linksNumber)this.linkStyles=new Float32Array(this.linksNumber).fill(n);else{this.linkStyles=new Float32Array(this.inputLinkStyles);const r=this.linkStyles;for(let s=0;s2)&&(r[s]=n)}}}updateArrows(){if(this.linksNumber===void 0){this.linkArrows=void 0;return}const t=this._config.linkDefaultArrows;this.linkArrowsBoolean===void 0||this.linkArrowsBoolean.length!==this.linksNumber?this.linkArrows=new Array(this.linksNumber).fill(+t):this.linkArrows=this.linkArrowsBoolean.map(i=>+i)}updateLinkStrength(){this.linksNumber===void 0&&(this.linkStrength=void 0),this.inputLinkStrength===void 0||this.inputLinkStrength.length!==this.linksNumber?this.linkStrength=void 0:this.linkStrength=this.inputLinkStrength}updateClusters(){if(this.pointsNumber===void 0){this.pointClusters=void 0,this.clusterPositions=void 0;return}this.inputPointClusters===void 0||this.inputPointClusters.length!==this.pointsNumber?this.pointClusters=void 0:this.pointClusters=this.inputPointClusters,this.inputClusterPositions===void 0?this.clusterPositions=void 0:this.clusterPositions=this.inputClusterPositions,this.inputClusterStrength===void 0||this.inputClusterStrength.length!==this.pointsNumber?this.clusterStrength=void 0:this.clusterStrength=this.inputClusterStrength}update(){this.updatePoints(),this.updatePointColor(),this.updatePointSize(),this.updatePointShape(),this.updatePointImageIndices(),this.updatePointImageSizes(),this.updateLinks(),this.updateLinkColor(),this.updateLinkWidth(),this.updateArrows(),this.updateLinkStyles(),this.updateLinkStrength(),this.updateClusters(),(this._isLinkGroupingStale||this._linkGroupingPointsNumber!==this.pointsNumber)&&(this._groupLinksByPoint(),this._calculateDegrees())}getNeighboringPointIndices(t){const i=Array.isArray(t)?t:[t],n=new Set,r=[this.linksBySource,this.linksByTarget];for(const s of i)if(this.isPointIndex(s))for(const o of r){if(!o)continue;const{offsets:a,neighbors:l}=o,c=a[s+1];for(let u=a[s];u=r)continue;const o=this.links[s*2],a=this.links[s*2+1];!this.isPointIndex(o)||!this.isPointIndex(a)||(n.add(o),n.add(a))}return[...n]}_groupLinksByPoint(){const{links:t,linksNumber:i,pointsNumber:n}=this;if(this._isLinkGroupingStale=!1,this._linkGroupingPointsNumber=n,this._sourceIndexToTargetIndices=void 0,this._targetIndexToSourceIndices=void 0,t===void 0||i===void 0||n===void 0){this.linksBySource=void 0,this.linksByTarget=void 0;return}const r=new Uint32Array(n+1),s=new Uint32Array(n+1);for(let d=0;d(e.Positions="positions",e.PointColors="pointColors",e.PointSizes="pointSizes",e.LinkColors="linkColors",e.LinkWidths="linkWidths",e))(le||{}),Bs=(e=>(e.Linear="linear",e.QuadIn="quad-in",e.QuadOut="quad-out",e.QuadInOut="quad-in-out",e.CubicIn="cubic-in",e.CubicOut="cubic-out",e.CubicInOut="cubic-in-out",e.SinIn="sin-in",e.SinOut="sin-out",e.SinInOut="sin-in-out",e.ExpIn="exp-in",e.ExpOut="exp-out",e.ExpInOut="exp-in-out",e.CircleIn="circle-in",e.CircleOut="circle-out",e.CircleInOut="circle-in-out",e))(Bs||{});const Yx={linear:Qa,"quad-in":Ja,"quad-out":el,"quad-in-out":tl,"cubic-in":yg,"cubic-out":_g,"cubic-in-out":il,"sin-in":bg,"sin-out":Tg,"sin-in-out":vg,"exp-in":Pg,"exp-out":Cg,"exp-in-out":Ag,"circle-in":Rg,"circle-out":wg,"circle-in-out":Eg};class jx{constructor(t){this.progress=1,this.startTime=0,this.pendingProperties=new Set,this.activeProperties=new Set,this.activeDuration=0,this.config=t}get duration(){return this.overrideDuration??this.config.transitionDuration}get isPending(){return this.pendingProperties.size>0}get isActive(){return this.activeProperties.size>0}setDurationOverride(t){this.overrideDuration=t!==void 0&&Number.isFinite(t)?t:void 0}isPendingFor(t){return this.pendingProperties.has(t)}isActiveFor(t){return this.activeProperties.has(t)}queue(t){this.pendingProperties.add(t)}dequeue(t){this.pendingProperties.delete(t)}start(){var i,n,r,s;const t=this.duration;if(this.overrideDuration=void 0,!!this.isPending){if(t<=0){const o=this.isActive;this.pendingProperties.clear(),this.clearActiveCycle(),o&&((n=(i=this.config).onTransitionEnd)==null||n.call(i,!0));return}this.isActive&&this.end(!0),this.activeDuration=t,this.startTime=performance.now(),this.progress=0,this.activeProperties=new Set(this.pendingProperties),this.pendingProperties.clear(),(s=(r=this.config).onTransitionStart)==null||s.call(r)}}step(){var r,s;if(!this.isActive)return;const t=this.activeDuration;if(t<=0){this.end(!0);return}const i=Math.min((performance.now()-this.startTime)/t,1),n=this.applyEasing(i);this.progress=n,(s=(r=this.config).onTransition)==null||s.call(r,n),i>=1&&this.end(!1)}end(t){var i,n;this.isActive&&(this.clearActiveCycle(),(n=(i=this.config).onTransitionEnd)==null||n.call(i,t))}abort(){this.pendingProperties.clear(),this.overrideDuration=void 0,this.clearActiveCycle()}applyEasing(t){return(Yx[this.config.transitionEasing]??Qa)(t)}clearActiveCycle(){this.startTime=0,this.progress=1,this.activeProperties.clear()}}const Ze={enableSimulation:!0,enableRenderLoop:!0,transitionDuration:800,transitionEasing:Bs.CubicInOut,backgroundColor:"#222222",spaceSize:4096,pointDefaultColor:"#b3b3b3",pointDefaultSize:4,pointDefaultShape:Ms.Circle,pointOpacity:1,pointGreyoutOpacity:void 0,pointGreyoutColor:void 0,pointSizeScale:1,pointOcclusionCulling:!0,scalePointsOnZoom:!1,hoveredPointCursor:"auto",renderHoveredPointRing:!1,hoveredPointRingColor:"white",focusedPointRingColor:"white",focusedPointIndex:void 0,highlightedPointIndices:void 0,outlinedPointIndices:void 0,outlinedPointRingColor:"white",renderLinks:!0,linkDefaultColor:"#666666",linkDefaultWidth:1,linkDefaultStyle:Ns.Solid,linkDashLength:8,linkDashGap:4,linkColorInterpolateFromEndpoints:!1,linkOpacity:1,linkGreyoutOpacity:.1,linkWidthScale:1,scaleLinksOnZoom:!1,linkBlending:!0,curvedLinks:!1,curvedLinkSegments:19,curvedLinkWeight:.8,curvedLinkControlPointDistance:.5,linkDefaultArrows:!1,linkArrowsSizeScale:1,linkVisibilityDistanceRange:[50,150],linkVisibilityMinTransparency:.25,hoveredLinkCursor:"auto",hoveredLinkColor:void 0,hoveredLinkWidthIncrease:5,highlightedLinkIndices:void 0,focusedLinkIndex:void 0,focusedLinkWidthIncrease:5,simulationDecay:5e3,simulationGravity:.25,simulationCenter:0,simulationRepulsion:1,simulationRepulsionTheta:1.15,simulationLinkSpring:1,simulationLinkDistance:10,simulationLinkDistRandomVariationRange:[1,1.2],simulationRepulsionFromMouse:2,simulationFriction:.85,simulationCluster:.1,simulationCollision:0,simulationCollisionRadius:void 0,simulationCollisionPadding:0,enableRightClickRepulsion:!1,onSimulationStart:void 0,onSimulationTick:void 0,onSimulationEnd:void 0,onSimulationPause:void 0,onSimulationUnpause:void 0,onTransitionStart:void 0,onTransition:void 0,onTransitionEnd:void 0,onClick:void 0,onPointClick:void 0,onLinkClick:void 0,onBackgroundClick:void 0,onContextMenu:void 0,onPointContextMenu:void 0,onLinkContextMenu:void 0,onBackgroundContextMenu:void 0,onMouseMove:void 0,onPointMouseOver:void 0,onPointMouseOut:void 0,onLinkMouseOver:void 0,onLinkMouseOut:void 0,onZoomStart:void 0,onZoom:void 0,onZoomEnd:void 0,onDragStart:void 0,onDrag:void 0,onDragEnd:void 0,showFPSMonitor:!1,pixelRatio:typeof window<"u"&&window.devicePixelRatio||2,enableZoom:!0,enableSimulationDuringZoom:!1,initialZoomLevel:void 0,enableDrag:!1,fitViewOnInit:!0,fitViewDelay:250,fitViewPadding:.1,fitViewDuration:250,fitViewByPointsInRect:void 0,fitViewByPointIndices:void 0,pointSamplingDistance:100,linkSamplingDistance:100,randomSeed:void 0,rescalePositions:void 0,attribution:""},dc=.7,hc=.95,Os=0,Xn=0,Us=1,fc=1.3;function zs(){const e={};for(const[t,i]of Object.entries(Ze))e[t]=Array.isArray(i)?[...i]:i;return e}function Kx(e){Object.assign(e,zs())}function Bi(e,t,i=!1){const n={};for(const[r,s]of Object.entries(t))if(s!==void 0)n[r]=s;else if(i){const o=Ze[r];n[r]=Array.isArray(o)?[...o]:o}Object.assign(e,n)}var qx=`
+ + 00 FPS + + + + + + + + + + + + + + +
`,Gx=`#gl-bench { + position:absolute; + left:0; + top:0; + z-index:1000; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +#gl-bench div { + position: relative; + display: block; + margin: 4px; + padding: 0 7px 0 10px; + background: #6c6; + border-radius: 15px; + cursor: pointer; + opacity: 0.9; +} + +#gl-bench svg { + height: 60px; + margin: 0 -1px; +} + +#gl-bench text { + font-size: 12px; + font-family: Helvetica,Arial,sans-serif; + font-weight: 700; + dominant-baseline: middle; + text-anchor: middle; +} + +#gl-bench .gl-mem { + font-size: 9px; +} + +#gl-bench line { + stroke-width: 5; + stroke: #112211; + stroke-linecap: round; +} + +#gl-bench polyline { + fill: none; + stroke: #112211; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 3.5; +} + +#gl-bench rect { + fill: #448844; +} + +#gl-bench .opacity { + stroke: #448844; +} +`;class Zx{constructor(t,i={}){this.css=Gx,this.svg=qx,this.paramLogger=()=>{},this.chartLogger=()=>{},this.chartLen=20,this.chartHz=20,this.names=[],this.cpuAccums=[],this.gpuAccums=[],this.activeAccums=[],this.chart=new Array(this.chartLen),this.now=()=>performance&&performance.now?performance.now():Date.now(),this.updateUI=()=>{[].forEach.call(this.nodes["gl-gpu-svg"],a=>{a.style.display=this.trackGPU?"inline":"none"})},Object.assign(this,i),this.detected=0,this.finished=[],this.isFramebuffer=0,this.frameId=0;let n,r=0,s,o=a=>{++r<20?n=requestAnimationFrame(o):(this.detected=Math.ceil(1e3*r/(a-s)/70),cancelAnimationFrame(n)),s||(s=a)};if(requestAnimationFrame(o),t){const a=async(c,u)=>Promise.resolve(setTimeout(()=>{t.getError();const d=this.now()-c;u.forEach((h,p)=>{h&&(this.gpuAccums[p]+=d)})},0)),l=(c,u,d)=>function(){const h=u.now();c.apply(d,arguments),u.trackGPU&&u.finished.push(a(h,u.activeAccums.slice(0)))};["drawArrays","drawElements","drawArraysInstanced","drawBuffers","drawElementsInstanced","drawRangeElements"].forEach(c=>{t[c]&&(t[c]=l(t[c],this,t))}),t.getExtension=((c,u)=>function(){let d=c.apply(t,arguments);return d&&["drawElementsInstancedANGLE","drawBuffersWEBGL"].forEach(h=>{d[h]&&(d[h]=l(d[h],u,d))}),d})(t.getExtension,this)}if(!this.withoutUI){this.dom||(this.dom=document.body);let a=document.createElement("div");a.id="gl-bench",this.dom.appendChild(a),this.dom.insertAdjacentHTML("afterbegin",'"),this.dom=a,this.dom.addEventListener("click",()=>{this.trackGPU=!this.trackGPU,this.updateUI()}),this.paramLogger=((l,c,u)=>{const d=["gl-cpu","gl-gpu","gl-mem","gl-fps","gl-gpu-svg","gl-chart"],h=Object.assign({},d);return d.forEach(p=>h[p]=c.getElementsByClassName(p)),this.nodes=h,(p,g,x,T,S,P,I)=>{h["gl-cpu"][p].style.strokeDasharray=(g*.27).toFixed(0)+" 100",h["gl-gpu"][p].style.strokeDasharray=(x*.27).toFixed(0)+" 100",h["gl-mem"][p].innerHTML=u[p]?u[p]:T?"mem: "+T.toFixed(0)+"mb":"",h["gl-fps"][p].innerHTML=S.toFixed(0)+" FPS",l(u[p],g,x,T,S,P,I)}})(this.paramLogger,this.dom,this.names),this.chartLogger=((l,c)=>{let u={"gl-chart":c.getElementsByClassName("gl-chart")};return(d,h,p)=>{let g="",x=h.length;for(let T=0;T=1e3){const r=this.frameId-this.paramFrame,s=r/n*1e3;for(let o=0;o{this.gpuAccums[o]=0,this.finished=[]})}this.paramFrame=this.frameId,this.paramTime=i}}if(!this.detected||!this.chartFrame)this.chartFrame=this.frameId,this.chartTime=i,this.circularId=0;else{let n=i-this.chartTime,r=this.chartHz*n/1e3;for(;--r>0&&this.detected;){const o=(this.frameId-this.chartFrame)/n*1e3;this.chart[this.circularId%this.chartLen]=o;for(let a=0;a #gl-bench"))==null||t.remove(),(i=this.container.querySelector(":scope > #gl-bench-style"))==null||i.remove()}}function gc(){let e;if(typeof window<"u"&&window.performance)e=window.performance.now();else if(typeof process<"u"&&process.hrtime){const t=process.hrtime();e=t[0]*1e3+t[1]/1e6}else e=Date.now();return e}class mc{constructor(t,i){this.sampleSize=1,this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this.name=t,this.type=i,this.reset()}reset(){return this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this}setSampleSize(t){return this.sampleSize=t,this}incrementCount(){return this.addCount(1),this}decrementCount(){return this.subtractCount(1),this}addCount(t){return this._count+=t,this._samples++,this._checkSampling(),this}subtractCount(t){return this._count-=t,this._samples++,this._checkSampling(),this}addTime(t){return this._time+=t,this.lastTiming=t,this._samples++,this._checkSampling(),this}timeStart(){return this._startTime=gc(),this._timerPending=!0,this}timeEnd(){return this._timerPending?(this.addTime(gc()-this._startTime),this._timerPending=!1,this._checkSampling(),this):this}getSampleAverageCount(){return this.sampleSize>0?this.lastSampleCount/this.sampleSize:0}getSampleAverageTime(){return this.sampleSize>0?this.lastSampleTime/this.sampleSize:0}getSampleHz(){return this.lastSampleTime>0?this.sampleSize/(this.lastSampleTime/1e3):0}getAverageCount(){return this.samples>0?this.count/this.samples:0}getAverageTime(){return this.samples>0?this.time/this.samples:0}getHz(){return this.time>0?this.samples/(this.time/1e3):0}_checkSampling(){this._samples===this.sampleSize&&(this.lastSampleTime=this._time,this.lastSampleCount=this._count,this.count+=this._count,this.time+=this._time,this.samples+=this._samples,this._time=0,this._count=0,this._samples=0)}}class Jx{constructor(t){this.stats={},this.id=t.id,this.stats={},this._initializeStats(t.stats),Object.seal(this)}get(t,i="count"){return this._getOrCreate({name:t,type:i})}get size(){return Object.keys(this.stats).length}reset(){for(const t of Object.values(this.stats))t.reset();return this}forEach(t){for(const i of Object.values(this.stats))t(i)}getTable(){const t={};return this.forEach(i=>{t[i.name]={time:i.time||0,count:i.count||0,average:i.getAverageTime()||0,hz:i.getHz()||0}}),t}_initializeStats(t=[]){t.forEach(i=>this._getOrCreate(i))}_getOrCreate(t){const{name:i,type:n}=t;let r=this.stats[i];return r||(t instanceof mc?r=t:r=new mc(i,n),this.stats[i]=r),r}}const eS="GPU Time and Memory",tS=["Adapter","GPU","GPU Type","GPU Backend","Frame Rate","CPU Time","GPU Time","GPU Memory","Buffer Memory","Texture Memory","Referenced Buffer Memory","Referenced Texture Memory","Swap Chain Texture"],xc=new WeakMap,Sc=new WeakMap;class iS{constructor(){f(this,"stats",new Map)}getStats(t){return this.get(t)}get(t){this.stats.has(t)||this.stats.set(t,new Jx({id:t}));const i=this.stats.get(t);return t===eS&&nS(i,tS),i}}const yc=new iS;function nS(e,t){const i=e.stats;let n=!1;for(const l of t)i[l]||(e.get(l),n=!0);const r=Object.keys(i).length,s=xc.get(e);if(!n&&(s==null?void 0:s.orderedStatNames)===t&&s.statCount===r)return;const o={};let a=Sc.get(t);a||(a=new Set(t),Sc.set(t,a));for(const l of t)i[l]&&(o[l]=i[l]);for(const[l,c]of Object.entries(i))a.has(l)||(o[l]=c);for(const l of Object.keys(i))delete i[l];Object.assign(i,o),xc.set(e,{orderedStatNames:t,statCount:r})}const Yn=globalThis,Jt=globalThis.process||{},rS=globalThis.navigator||{};function _c(e){var n,r;if(typeof window<"u"&&((n=window.process)==null?void 0:n.type)==="renderer"||typeof process<"u"&&((r=process.versions)!=null&&r.electron))return!0;const i=typeof navigator<"u"&&navigator.userAgent;return!!(i&&i.indexOf("Electron")>=0)}function Mt(){return!(typeof process=="object"&&String(process)==="[object process]"&&!(process!=null&&process.browser))||_c()}function sS(e){return Mt()?_c()?"Electron":(rS.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown":"Node"}const bc="4.1.1";function Ls(e,t){if(!e)throw new Error("Assertion failed")}function Tc(e){if(!e)return 0;let t;switch(typeof e){case"number":t=e;break;case"object":t=e.logLevel||e.priority||0;break;default:return 0}return Ls(Number.isFinite(t)&&t>=0),t}function oS(e){const{logLevel:t,message:i}=e;e.logLevel=Tc(t);const n=e.args?Array.from(e.args):[];for(;n.length&&n.shift()!==i;);switch(typeof t){case"string":case"function":i!==void 0&&n.unshift(i),e.message=t;break;case"object":Object.assign(e,t);break}typeof e.message=="function"&&(e.message=e.message());const r=typeof e.message;return Ls(r==="string"||r==="object"),Object.assign(e,{args:n},e.opts)}const ei=()=>{};class aS{constructor({level:t=0}={}){this.userData={},this._onceCache=new Set,this._level=t}set level(t){this.setLevel(t)}get level(){return this.getLevel()}setLevel(t){return this._level=t,this}getLevel(){return this._level}warn(t,...i){return this._log("warn",0,t,i,{once:!0})}error(t,...i){return this._log("error",0,t,i)}log(t,i,...n){return this._log("log",t,i,n)}info(t,i,...n){return this._log("info",t,i,n)}once(t,i,...n){return this._log("once",t,i,n,{once:!0})}_log(t,i,n,r,s={}){const o=oS({logLevel:i,message:n,args:this._buildArgs(i,n,r),opts:s});return this._createLogFunction(t,o,s)}_buildArgs(t,i,n){return[t,i,...n]}_createLogFunction(t,i,n){if(!this._shouldLog(i.logLevel))return ei;const r=this._getOnceTag(n.tag??i.tag??i.message);if((n.once||i.once)&&r!==void 0){if(this._onceCache.has(r))return ei;this._onceCache.add(r)}return this._emit(t,i)}_shouldLog(t){return this.getLevel()>=Tc(t)}_getOnceTag(t){if(t!==void 0)try{return typeof t=="string"?t:String(t)}catch{return}}}function lS(e){try{const t=window[e],i="__storage_test__";return t.setItem(i,i),t.removeItem(i),t}catch{return null}}class cS{constructor(t,i,n="sessionStorage"){this.storage=lS(n),this.id=t,this.config=i,this._loadConfiguration()}getConfiguration(){return this.config}setConfiguration(t){if(Object.assign(this.config,t),this.storage){const i=JSON.stringify(this.config);this.storage.setItem(this.id,i)}}_loadConfiguration(){let t={};if(this.storage){const i=this.storage.getItem(this.id);t=i?JSON.parse(i):{}}return Object.assign(this.config,t),this}}function uS(e){let t;return e<10?t=`${e.toFixed(2)}ms`:e<100?t=`${e.toFixed(1)}ms`:e<1e3?t=`${e.toFixed(0)}ms`:t=`${(e/1e3).toFixed(2)}s`,t}function dS(e,t=8){const i=Math.max(t-e.length,0);return`${" ".repeat(i)}${e}`}var jn;(function(e){e[e.BLACK=30]="BLACK",e[e.RED=31]="RED",e[e.GREEN=32]="GREEN",e[e.YELLOW=33]="YELLOW",e[e.BLUE=34]="BLUE",e[e.MAGENTA=35]="MAGENTA",e[e.CYAN=36]="CYAN",e[e.WHITE=37]="WHITE",e[e.BRIGHT_BLACK=90]="BRIGHT_BLACK",e[e.BRIGHT_RED=91]="BRIGHT_RED",e[e.BRIGHT_GREEN=92]="BRIGHT_GREEN",e[e.BRIGHT_YELLOW=93]="BRIGHT_YELLOW",e[e.BRIGHT_BLUE=94]="BRIGHT_BLUE",e[e.BRIGHT_MAGENTA=95]="BRIGHT_MAGENTA",e[e.BRIGHT_CYAN=96]="BRIGHT_CYAN",e[e.BRIGHT_WHITE=97]="BRIGHT_WHITE"})(jn||(jn={}));const hS=10;function vc(e){return typeof e!="string"?e:(e=e.toUpperCase(),jn[e]||jn.WHITE)}function fS(e,t,i){return!Mt&&typeof e=="string"&&(t&&(e=`\x1B[${vc(t)}m${e}\x1B[39m`),i&&(e=`\x1B[${vc(i)+hS}m${e}\x1B[49m`)),e}function pS(e,t=["constructor"]){const i=Object.getPrototypeOf(e),n=Object.getOwnPropertyNames(i),r=e;for(const s of n){const o=r[s];typeof o=="function"&&(t.find(a=>s===a)||(r[s]=o.bind(e)))}}function Oi(){var t,i,n;let e;if(Mt()&&Yn.performance)e=(i=(t=Yn==null?void 0:Yn.performance)==null?void 0:t.now)==null?void 0:i.call(t);else if("hrtime"in Jt){const r=(n=Jt==null?void 0:Jt.hrtime)==null?void 0:n.call(Jt);e=r[0]*1e3+r[1]/1e6}else e=Date.now();return e}const ti={debug:Mt()&&console.debug||console.log,log:console.log,info:console.info,warn:console.warn,error:console.error},Ws={enabled:!0,level:0};class Pc extends aS{constructor({id:t}={id:""}){super({level:0}),this.VERSION=bc,this._startTs=Oi(),this._deltaTs=Oi(),this.userData={},this.LOG_THROTTLE_TIMEOUT=0,this.id=t,this.userData={},this._storage=new cS(`__probe-${this.id}__`,{[this.id]:Ws}),this.timeStamp(`${this.id} started`),pS(this),Object.seal(this)}isEnabled(){return this._getConfiguration().enabled}getLevel(){return this._getConfiguration().level}getTotal(){return Number((Oi()-this._startTs).toPrecision(10))}getDelta(){return Number((Oi()-this._deltaTs).toPrecision(10))}set priority(t){this.level=t}get priority(){return this.level}getPriority(){return this.level}enable(t=!0){return this._updateConfiguration({enabled:t}),this}setLevel(t){return this._updateConfiguration({level:t}),this}get(t){return this._getConfiguration()[t]}set(t,i){this._updateConfiguration({[t]:i})}settings(){console.table?console.table(this._storage.config):console.log(this._storage.config)}assert(t,i){if(!t)throw new Error(i||"Assertion failed")}warn(t,...i){return this._log("warn",0,t,i,{method:ti.warn,once:!0})}error(t,...i){return this._log("error",0,t,i,{method:ti.error})}deprecated(t,i){return this.warn(`\`${t}\` is deprecated and will be removed in a later version. Use \`${i}\` instead`)}removed(t,i){return this.error(`\`${t}\` has been removed. Use \`${i}\` instead`)}probe(t,i,...n){return this._log("log",t,i,n,{method:ti.log,time:!0,once:!0})}log(t,i,...n){return this._log("log",t,i,n,{method:ti.debug})}info(t,i,...n){return this._log("info",t,i,n,{method:console.info})}once(t,i,...n){return this._log("once",t,i,n,{method:ti.debug||ti.info,once:!0})}table(t,i,n){return i?this._log("table",t,i,n&&[n]||[],{method:console.table||ei,tag:mS(i)}):ei}time(t,i){return this._log("time",t,i,[],{method:console.time?console.time:console.info})}timeEnd(t,i){return this._log("time",t,i,[],{method:console.timeEnd?console.timeEnd:console.info})}timeStamp(t,i){return this._log("time",t,i,[],{method:console.timeStamp||ei})}group(t,i,n={collapsed:!1}){const r=(n.collapsed?console.groupCollapsed:console.group)||console.info;return this._log("group",t,i,[],{method:r})}groupCollapsed(t,i,n={}){return this.group(t,i,Object.assign({},n,{collapsed:!0}))}groupEnd(t){return this._log("groupEnd",t,"",[],{method:console.groupEnd||ei})}withGroup(t,i,n){this.group(t,i)();try{n()}finally{this.groupEnd(t)()}}trace(){console.trace&&console.trace()}_shouldLog(t){return this.isEnabled()&&super._shouldLog(t)}_emit(t,i){const n=i.method;Ls(n),i.total=this.getTotal(),i.delta=this.getDelta(),this._deltaTs=Oi();const r=gS(this.id,i.message,i);return n.bind(console,r,...i.args)}_getConfiguration(){return this._storage.config[this.id]||this._updateConfiguration(Ws),this._storage.config[this.id]}_updateConfiguration(t){const i=this._storage.config[this.id]||{...Ws};this._storage.setConfiguration({[this.id]:{...i,...t}})}}Pc.VERSION=bc;function gS(e,t,i){if(typeof t=="string"){const n=i.time?dS(uS(i.total)):"";t=i.time?`${e}: ${n} ${t}`:`${e}: ${t}`,t=fS(t,i.color,i.background)}return t}function mS(e){for(const t in e)for(const i in e[t])return i||"untitled";return"empty"}const C=new Pc({id:"luma.gl"}),Vs={};function Ui(e="id"){Vs[e]=Vs[e]||1;const t=Vs[e]++;return`${e}-${t}`}const xS="cpu-hotspot-profiler",Cc="GPU Resource Counts",Ac="Resource Counts",Rc="GPU Time and Memory",SS=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],yS=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","SharedRenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],_S=SS.flatMap(e=>[`${e} Created`,`${e} Active`]),bS=yS.flatMap(e=>[`${e} Created`,`${e} Active`]),wc=new WeakMap,Ec=new WeakMap;class Z{constructor(t,i,n){f(this,"id");f(this,"props");f(this,"userData",{});f(this,"_device");f(this,"destroyed",!1);f(this,"allocatedBytes",0);f(this,"allocatedBytesName",null);f(this,"_attachedResources",new Set);if(!t)throw new Error("no device");this._device=t,this.props=TS(i,n);const r=this.props.id!=="undefined"?this.props.id:Ui(this[Symbol.toStringTag]);this.props.id=r,this.id=r,this.userData=this.props.userData||{},this.addStats()}toString(){return`${this[Symbol.toStringTag]||this.constructor.name}:"${this.id}"`}destroy(){this.destroyed||this.destroyResource()}delete(){return this.destroy(),this}getProps(){return this.props}attachResource(t){this._attachedResources.add(t)}detachResource(t){this._attachedResources.delete(t)}destroyAttachedResource(t){this._attachedResources.delete(t)&&t.destroy()}destroyAttachedResources(){for(const t of this._attachedResources)t.destroy();this._attachedResources=new Set}destroyResource(){this.destroyed||(this.destroyAttachedResources(),this.removeStats(),this.destroyed=!0)}removeStats(){const t=zi(this._device),i=t?yt():0,n=[this._device.statsManager.getStats(Cc),this._device.statsManager.getStats(Ac)],r=kc(this._device);for(const o of n)Ic(o,r);const s=this.getStatsName();for(const o of n)o.get("Resources Active").decrementCount(),o.get(`${s}s Active`).decrementCount();t&&(t.statsBookkeepingCalls=(t.statsBookkeepingCalls||0)+1,t.statsBookkeepingTimeMs=(t.statsBookkeepingTimeMs||0)+(yt()-i))}trackAllocatedMemory(t,i=this.getStatsName()){const n=zi(this._device),r=n?yt():0,s=this._device.statsManager.getStats(Rc);this.allocatedBytes>0&&this.allocatedBytesName&&(s.get("GPU Memory").subtractCount(this.allocatedBytes),s.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes)),s.get("GPU Memory").addCount(t),s.get(`${i} Memory`).addCount(t),n&&(n.statsBookkeepingCalls=(n.statsBookkeepingCalls||0)+1,n.statsBookkeepingTimeMs=(n.statsBookkeepingTimeMs||0)+(yt()-r)),this.allocatedBytes=t,this.allocatedBytesName=i}trackReferencedMemory(t,i=this.getStatsName()){this.trackAllocatedMemory(t,`Referenced ${i}`)}trackDeallocatedMemory(t=this.getStatsName()){if(this.allocatedBytes===0){this.allocatedBytesName=null;return}const i=zi(this._device),n=i?yt():0,r=this._device.statsManager.getStats(Rc);r.get("GPU Memory").subtractCount(this.allocatedBytes),r.get(`${this.allocatedBytesName||t} Memory`).subtractCount(this.allocatedBytes),i&&(i.statsBookkeepingCalls=(i.statsBookkeepingCalls||0)+1,i.statsBookkeepingTimeMs=(i.statsBookkeepingTimeMs||0)+(yt()-n)),this.allocatedBytes=0,this.allocatedBytesName=null}trackDeallocatedReferencedMemory(t=this.getStatsName()){this.trackDeallocatedMemory(`Referenced ${t}`)}addStats(){const t=this.getStatsName(),i=zi(this._device),n=i?yt():0,r=[this._device.statsManager.getStats(Cc),this._device.statsManager.getStats(Ac)],s=kc(this._device);for(const o of r)Ic(o,s);for(const o of r)o.get("Resources Created").incrementCount(),o.get("Resources Active").incrementCount(),o.get(`${t}s Created`).incrementCount(),o.get(`${t}s Active`).incrementCount();i&&(i.statsBookkeepingCalls=(i.statsBookkeepingCalls||0)+1,i.statsBookkeepingTimeMs=(i.statsBookkeepingTimeMs||0)+(yt()-n)),vS(this._device,t)}getStatsName(){return PS(this)}}f(Z,"defaultProps",{id:"undefined",handle:void 0,userData:void 0});function TS(e,t){const i={...t};for(const n in e)e[n]!==void 0&&(i[n]=e[n]);return i}function Ic(e,t){const i=e.stats;let n=!1;for(const l of t)i[l]||(e.get(l),n=!0);const r=Object.keys(i).length,s=wc.get(e);if(!n&&(s==null?void 0:s.orderedStatNames)===t&&s.statCount===r)return;const o={};let a=Ec.get(t);a||(a=new Set(t),Ec.set(t,a));for(const l of t)i[l]&&(o[l]=i[l]);for(const[l,c]of Object.entries(i))a.has(l)||(o[l]=c);for(const l of Object.keys(i))delete i[l];Object.assign(i,o),wc.set(e,{orderedStatNames:t,statCount:r})}function kc(e){return e.type==="webgl"?bS:_S}function zi(e){const t=e.userData[xS];return t!=null&&t.enabled?t:null}function yt(){var e,t;return((t=(e=globalThis.performance)==null?void 0:e.now)==null?void 0:t.call(e))??Date.now()}function vS(e,t){const i=zi(e);if(!(!i||!i.activeDefaultFramebufferAcquireDepth))switch(i.transientCanvasResourceCreates=(i.transientCanvasResourceCreates||0)+1,t){case"Texture":i.transientCanvasTextureCreates=(i.transientCanvasTextureCreates||0)+1;break;case"TextureView":i.transientCanvasTextureViewCreates=(i.transientCanvasTextureViewCreates||0)+1;break;case"Sampler":i.transientCanvasSamplerCreates=(i.transientCanvasSamplerCreates||0)+1;break;case"Framebuffer":i.transientCanvasFramebufferCreates=(i.transientCanvasFramebufferCreates||0)+1;break}}function PS(e){let t=Object.getPrototypeOf(e);for(;t;){const i=Object.getPrototypeOf(t);if(!i||i===Z.prototype)return CS(t)||e[Symbol.toStringTag]||e.constructor.name;t=i}return e[Symbol.toStringTag]||e.constructor.name}function CS(e){const t=Object.getOwnPropertyDescriptor(e,Symbol.toStringTag);return typeof(t==null?void 0:t.get)=="function"?t.get.call(e):typeof(t==null?void 0:t.value)=="string"?t.value:null}const Pe=class Pe extends Z{constructor(i,n){const r={...n};(n.usage||0)&Pe.INDEX&&!n.indexType&&(n.data instanceof Uint32Array?r.indexType="uint32":n.data instanceof Uint16Array?r.indexType="uint16":n.data instanceof Uint8Array&&(r.indexType="uint8")),delete r.data;super(i,r,Pe.defaultProps);f(this,"usage");f(this,"indexType");f(this,"updateTimestamp");f(this,"debugData",new ArrayBuffer(0));this.usage=r.usage||0,this.indexType=r.indexType,this.updateTimestamp=i.incrementTimestamp()}get[Symbol.toStringTag](){return"Buffer"}clone(i){return this.device.createBuffer({...this.props,...i})}_setDebugData(i,n,r){let s=null,o;ArrayBuffer.isView(i)?(s=i,o=i.buffer):o=i;const a=Math.min(i?i.byteLength:r,Pe.DEBUG_DATA_MAX_LENGTH);if(o===null)this.debugData=new ArrayBuffer(a);else{const l=Math.min((s==null?void 0:s.byteOffset)||0,o.byteLength),c=Math.max(0,o.byteLength-l),u=Math.min(a,c);this.debugData=new Uint8Array(o,l,u).slice().buffer}}};f(Pe,"INDEX",16),f(Pe,"VERTEX",32),f(Pe,"UNIFORM",64),f(Pe,"STORAGE",128),f(Pe,"INDIRECT",256),f(Pe,"QUERY_RESOLVE",512),f(Pe,"MAP_READ",1),f(Pe,"MAP_WRITE",2),f(Pe,"COPY_SRC",4),f(Pe,"COPY_DST",8),f(Pe,"DEBUG_DATA_MAX_LENGTH",32),f(Pe,"defaultProps",{...Z.defaultProps,usage:0,byteLength:0,byteOffset:0,data:null,indexType:"uint16",onMapped:void 0});let B=Pe;class AS{getDataTypeInfo(t){const[i,n,r]=Hs[t],s=t.includes("norm"),o=!s&&!t.startsWith("float"),a=t.startsWith("s");return{signedType:i,primitiveType:n,byteLength:r,normalized:s,integer:o,signed:a}}getNormalizedDataType(t){const i=t;switch(i){case"uint8":return"unorm8";case"sint8":return"snorm8";case"uint16":return"unorm16";case"sint16":return"snorm16";default:return i}}alignTo(t,i){switch(i){case 1:return t;case 2:return t+t%2;default:return t+(4-t%4)%4}}getDataType(t){const i=ArrayBuffer.isView(t)?t.constructor:t;if(i===Uint8ClampedArray)return"uint8";const n=Object.values(Hs).find(r=>i===r[4]);if(!n)throw new Error(i.name);return n[0]}getTypedArrayConstructor(t){const[,,,,i]=Hs[t];return i}}const Nt=new AS,Hs={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]};class RS{getVertexFormatInfo(t){let i;t.endsWith("-webgl")&&(t.replace("-webgl",""),i=!0);const[n,r]=t.split("x"),s=n,o=r?parseInt(r):1,a=Nt.getDataTypeInfo(s),l={type:s,components:o,byteLength:a.byteLength*o,integer:a.integer,signed:a.signed,normalized:a.normalized};return i&&(l.webglOnly=!0),l}makeVertexFormat(t,i,n){const r=n?Nt.getNormalizedDataType(t):t;switch(r){case"unorm8":return i===1?"unorm8":i===3?"unorm8x3-webgl":`${r}x${i}`;case"snorm8":return i===1?"snorm8":i===3?"snorm8x3-webgl":`${r}x${i}`;case"uint8":case"sint8":if(i===1||i===3)throw new Error(`size: ${i}`);return`${r}x${i}`;case"uint16":return i===1?"uint16":i===3?"uint16x3-webgl":`${r}x${i}`;case"sint16":return i===1?"sint16":i===3?"sint16x3-webgl":`${r}x${i}`;case"unorm16":return i===1?"unorm16":i===3?"unorm16x3-webgl":`${r}x${i}`;case"snorm16":return i===1?"snorm16":i===3?"snorm16x3-webgl":`${r}x${i}`;case"float16":if(i===1||i===3)throw new Error(`size: ${i}`);return`${r}x${i}`;default:return i===1?r:`${r}x${i}`}}getVertexFormatFromAttribute(t,i,n){if(!i||i>4)throw new Error(`size ${i}`);const r=i,s=Nt.getDataType(t);return this.makeVertexFormat(s,r,n)}getCompatibleVertexFormat(t){let i;switch(t.primitiveType){case"f32":i="float32";break;case"i32":i="sint32";break;case"u32":i="uint32";break;case"f16":return t.components<=2?"float16x2":"float16x4"}return t.components===1?i:`${i}x${t.components}`}}const Li=new RS,Ae="texture-compression-bc",ne="texture-compression-astc",rt="texture-compression-etc2",wS="texture-compression-etc1-webgl",Kn="texture-compression-pvrtc-webgl",$s="texture-compression-atc-webgl",qn="float32-renderable-webgl",Xs="float16-renderable-webgl",ES="rgb9e5ufloat-renderable-webgl",Ys="snorm8-renderable-webgl",_t="norm16-webgl",js="norm16-renderable-webgl",Ks="snorm16-renderable-webgl",Gn="float32-filterable",Dc="float16-filterable-webgl";function Fc(e){const t=Mc[e];if(!t)throw new Error(`Unsupported texture format ${e}`);return t}function IS(){return Mc}const Mc={...{r8unorm:{},rg8unorm:{},"rgb8unorm-webgl":{},rgba8unorm:{},"rgba8unorm-srgb":{},r8snorm:{render:Ys},rg8snorm:{render:Ys},"rgb8snorm-webgl":{},rgba8snorm:{render:Ys},r8uint:{},rg8uint:{},rgba8uint:{},r8sint:{},rg8sint:{},rgba8sint:{},bgra8unorm:{},"bgra8unorm-srgb":{},r16unorm:{f:_t,render:js},rg16unorm:{f:_t,render:js},"rgb16unorm-webgl":{f:_t,render:!1},rgba16unorm:{f:_t,render:js},r16snorm:{f:_t,render:Ks},rg16snorm:{f:_t,render:Ks},"rgb16snorm-webgl":{f:_t,render:!1},rgba16snorm:{f:_t,render:Ks},r16uint:{},rg16uint:{},rgba16uint:{},r16sint:{},rg16sint:{},rgba16sint:{},r16float:{render:Xs,filter:"float16-filterable-webgl"},rg16float:{render:Xs,filter:Dc},rgba16float:{render:Xs,filter:Dc},r32uint:{},rg32uint:{},rgba32uint:{},r32sint:{},rg32sint:{},rgba32sint:{},r32float:{render:qn,filter:Gn},rg32float:{render:!1,filter:Gn},"rgb32float-webgl":{render:qn,filter:Gn},rgba32float:{render:qn,filter:Gn},"rgba4unorm-webgl":{channels:"rgba",bitsPerChannel:[4,4,4,4],packed:!0},"rgb565unorm-webgl":{channels:"rgb",bitsPerChannel:[5,6,5,0],packed:!0},"rgb5a1unorm-webgl":{channels:"rgba",bitsPerChannel:[5,5,5,1],packed:!0},rgb9e5ufloat:{channels:"rgb",packed:!0,render:ES},rg11b10ufloat:{channels:"rgb",bitsPerChannel:[11,11,10,0],packed:!0,p:1,render:qn},rgb10a2unorm:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},rgb10a2uint:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},stencil8:{attachment:"stencil",bitsPerChannel:[8,0,0,0],dataType:"uint8"},depth16unorm:{attachment:"depth",bitsPerChannel:[16,0,0,0],dataType:"uint16"},depth24plus:{attachment:"depth",bitsPerChannel:[24,0,0,0],dataType:"uint32"},depth32float:{attachment:"depth",bitsPerChannel:[32,0,0,0],dataType:"float32"},"depth24plus-stencil8":{attachment:"depth-stencil",bitsPerChannel:[24,8,0,0],packed:!0},"depth32float-stencil8":{attachment:"depth-stencil",bitsPerChannel:[32,8,0,0],packed:!0}},...{"bc1-rgb-unorm-webgl":{f:Ae},"bc1-rgb-unorm-srgb-webgl":{f:Ae},"bc1-rgba-unorm":{f:Ae},"bc1-rgba-unorm-srgb":{f:Ae},"bc2-rgba-unorm":{f:Ae},"bc2-rgba-unorm-srgb":{f:Ae},"bc3-rgba-unorm":{f:Ae},"bc3-rgba-unorm-srgb":{f:Ae},"bc4-r-unorm":{f:Ae},"bc4-r-snorm":{f:Ae},"bc5-rg-unorm":{f:Ae},"bc5-rg-snorm":{f:Ae},"bc6h-rgb-ufloat":{f:Ae},"bc6h-rgb-float":{f:Ae},"bc7-rgba-unorm":{f:Ae},"bc7-rgba-unorm-srgb":{f:Ae},"etc2-rgb8unorm":{f:rt},"etc2-rgb8unorm-srgb":{f:rt},"etc2-rgb8a1unorm":{f:rt},"etc2-rgb8a1unorm-srgb":{f:rt},"etc2-rgba8unorm":{f:rt},"etc2-rgba8unorm-srgb":{f:rt},"eac-r11unorm":{f:rt},"eac-r11snorm":{f:rt},"eac-rg11unorm":{f:rt},"eac-rg11snorm":{f:rt},"astc-4x4-unorm":{f:ne},"astc-4x4-unorm-srgb":{f:ne},"astc-5x4-unorm":{f:ne},"astc-5x4-unorm-srgb":{f:ne},"astc-5x5-unorm":{f:ne},"astc-5x5-unorm-srgb":{f:ne},"astc-6x5-unorm":{f:ne},"astc-6x5-unorm-srgb":{f:ne},"astc-6x6-unorm":{f:ne},"astc-6x6-unorm-srgb":{f:ne},"astc-8x5-unorm":{f:ne},"astc-8x5-unorm-srgb":{f:ne},"astc-8x6-unorm":{f:ne},"astc-8x6-unorm-srgb":{f:ne},"astc-8x8-unorm":{f:ne},"astc-8x8-unorm-srgb":{f:ne},"astc-10x5-unorm":{f:ne},"astc-10x5-unorm-srgb":{f:ne},"astc-10x6-unorm":{f:ne},"astc-10x6-unorm-srgb":{f:ne},"astc-10x8-unorm":{f:ne},"astc-10x8-unorm-srgb":{f:ne},"astc-10x10-unorm":{f:ne},"astc-10x10-unorm-srgb":{f:ne},"astc-12x10-unorm":{f:ne},"astc-12x10-unorm-srgb":{f:ne},"astc-12x12-unorm":{f:ne},"astc-12x12-unorm-srgb":{f:ne},"pvrtc-rgb4unorm-webgl":{f:Kn},"pvrtc-rgba4unorm-webgl":{f:Kn},"pvrtc-rgb2unorm-webgl":{f:Kn},"pvrtc-rgba2unorm-webgl":{f:Kn},"etc1-rbg-unorm-webgl":{f:wS},"atc-rgb-unorm-webgl":{f:$s},"atc-rgba-unorm-webgl":{f:$s},"atc-rgbai-unorm-webgl":{f:$s}}},kS=/^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/,DS=["rgb","rgba","bgra"],FS=["depth","stencil"],MS=["bc1","bc2","bc3","bc4","bc5","bc6","bc7","etc1","etc2","eac","atc","astc","pvrtc"];class NS{isColor(t){return DS.some(i=>t.startsWith(i))}isDepthStencil(t){return FS.some(i=>t.startsWith(i))}isCompressed(t){return MS.some(i=>t.startsWith(i))}getInfo(t){return Nc(t)}getCapabilities(t){return OS(t)}computeMemoryLayout(t){return BS(t)}}const Ve=new NS;function BS({format:e,width:t,height:i,depth:n,byteAlignment:r}){const s=Ve.getInfo(e),{bytesPerPixel:o,bytesPerBlock:a=o,blockWidth:l=1,blockHeight:c=1,compressed:u=!1}=s,d=u?Math.ceil(t/l):t,h=u?Math.ceil(i/c):i,p=d*a,g=Math.ceil(p/r)*r,x=h,T=g*x*n;return{bytesPerPixel:o,bytesPerRow:g,rowsPerImage:x,depthOrArrayLayers:n,bytesPerImage:g*x,byteLength:T}}function OS(e){const t=Fc(e),i={format:e,create:t.f??!0,render:t.render??!0,filter:t.filter??!0,blend:t.blend??!0,store:t.store??!0},n=Nc(e),r=e.startsWith("depth")||e.startsWith("stencil"),s=n==null?void 0:n.signed,o=n==null?void 0:n.integer,a=n==null?void 0:n.webgl,l=!!(n!=null&&n.compressed);return i.render&&(i.render=!r&&!l),i.filter&&(i.filter=!r&&!s&&!o&&!a),i}function Nc(e){let t=US(e);if(Ve.isCompressed(e)){t.channels="rgb",t.components=3,t.bytesPerPixel=1,t.srgb=!1,t.compressed=!0,t.bytesPerBlock=LS(e);const n=zS(e);n&&(t.blockWidth=n.blockWidth,t.blockHeight=n.blockHeight)}const i=t.packed?null:kS.exec(e);if(i){const[,n,r,s,o,a]=i,l=`${s}${r}`,c=Nt.getDataTypeInfo(l),u=c.byteLength*8,d=(n==null?void 0:n.length)??1,h=[u,d>=2?u:0,d>=3?u:0,d>=4?u:0];t={format:e,attachment:t.attachment,dataType:c.signedType,components:d,channels:n,integer:c.integer,signed:c.signed,normalized:c.normalized,bitsPerChannel:h,bytesPerPixel:c.byteLength*d,packed:t.packed,srgb:t.srgb},a==="-webgl"&&(t.webgl=!0),o==="-srgb"&&(t.srgb=!0)}return e.endsWith("-webgl")&&(t.webgl=!0),e.endsWith("-srgb")&&(t.srgb=!0),t}function US(e){var s;const t=Fc(e),i=t.bytesPerPixel||1,n=t.bitsPerChannel||[8,8,8,8];return delete t.bitsPerChannel,delete t.bytesPerPixel,delete t.f,delete t.render,delete t.filter,delete t.blend,delete t.store,{...t,format:e,attachment:t.attachment||"color",channels:t.channels||"r",components:t.components||((s=t.channels)==null?void 0:s.length)||1,bytesPerPixel:i,bitsPerChannel:n,dataType:t.dataType||"uint8",srgb:t.srgb??!1,packed:t.packed??!1,webgl:t.webgl??!1,integer:t.integer??!1,signed:t.signed??!1,normalized:t.normalized??!1,compressed:t.compressed??!1}}function zS(e){const i=/.*-(\d+)x(\d+)-.*/.exec(e);if(i){const[,n,r]=i;return{blockWidth:Number(n),blockHeight:Number(r)}}return e.startsWith("bc")||e.startsWith("etc1")||e.startsWith("etc2")||e.startsWith("eac")||e.startsWith("atc")?{blockWidth:4,blockHeight:4}:e.startsWith("pvrtc-rgb4")||e.startsWith("pvrtc-rgba4")?{blockWidth:4,blockHeight:4}:e.startsWith("pvrtc-rgb2")||e.startsWith("pvrtc-rgba2")?{blockWidth:8,blockHeight:4}:null}function LS(e){return e.startsWith("bc1")||e.startsWith("bc4")||e.startsWith("etc1")||e.startsWith("etc2-rgb8")||e.startsWith("etc2-rgb8a1")||e.startsWith("eac-r11")||e==="atc-rgb-unorm-webgl"?8:e.startsWith("bc2")||e.startsWith("bc3")||e.startsWith("bc5")||e.startsWith("bc6h")||e.startsWith("bc7")||e.startsWith("etc2-rgba8")||e.startsWith("eac-rg11")||e.startsWith("astc")||e==="atc-rgba-unorm-webgl"||e==="atc-rgbai-unorm-webgl"?16:e.startsWith("pvrtc")?8:16}function qs(e){return typeof ImageData<"u"&&e instanceof ImageData||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement||typeof HTMLVideoElement<"u"&&e instanceof HTMLVideoElement||typeof VideoFrame<"u"&&e instanceof VideoFrame||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas}function Bc(e){if(typeof ImageData<"u"&&e instanceof ImageData||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas)return{width:e.width,height:e.height};if(typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement)return{width:e.naturalWidth,height:e.naturalHeight};if(typeof HTMLVideoElement<"u"&&e instanceof HTMLVideoElement)return{width:e.videoWidth,height:e.videoHeight};if(typeof VideoFrame<"u"&&e instanceof VideoFrame)return{width:e.displayWidth,height:e.displayHeight};throw new Error("Unknown image type")}class WS{}function VS(e,t){const i=Gs(e),n=t.map(Gs).filter(r=>r!==void 0);return[i,...n].filter(r=>r!==void 0)}function Gs(e){var t;if(e!==void 0){if(e===null||typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e;if(e instanceof Error)return e.message;if(Array.isArray(e))return e.map(Gs);if(typeof e=="object"){if(HS(e)){const i=String(e);if(i!=="[object Object]")return i}return $S(e)?XS(e):((t=e.constructor)==null?void 0:t.name)||"Object"}return String(e)}}function HS(e){return"toString"in e&&typeof e.toString=="function"&&e.toString!==Object.prototype.toString}function $S(e){return"message"in e&&"type"in e}function XS(e){const t=typeof e.type=="string"?e.type:"message",i=typeof e.message=="string"?e.message:"",n=typeof e.lineNum=="number"?e.lineNum:null,r=typeof e.linePos=="number"?e.linePos:null,s=n!==null&&r!==null?` @ ${n}:${r}`:n!==null?` @ ${n}`:"";return`${t}${s}: ${i}`.trim()}class YS{constructor(t=[],i){f(this,"features");f(this,"disabledFeatures");this.features=new Set(t),this.disabledFeatures=i||{}}*[Symbol.iterator](){yield*this.features}has(t){var i;return!((i=this.disabledFeatures)!=null&&i[t])&&this.features.has(t)}}const Tr=class Tr{constructor(t){f(this,"id");f(this,"props");f(this,"userData",{});f(this,"statsManager",yc);f(this,"_factories",{});f(this,"timestamp",0);f(this,"_reused",!1);f(this,"_moduleData",{});f(this,"_textureCaps",{});f(this,"_debugGPUTimeQuery",null);this.props={...Tr.defaultProps,...t},this.id=this.props.id||Ui(this[Symbol.toStringTag].toLowerCase())}get[Symbol.toStringTag](){return"Device"}toString(){return`Device(${this.id})`}getVertexFormatInfo(t){return Li.getVertexFormatInfo(t)}isVertexFormatSupported(t){return!0}getTextureFormatInfo(t){return Ve.getInfo(t)}getTextureFormatCapabilities(t){let i=this._textureCaps[t];if(!i){const n=this._getDeviceTextureFormatCapabilities(t);i=this._getDeviceSpecificTextureFormatCapabilities(n),this._textureCaps[t]=i}return i}getMipLevelCount(t,i,n=1){const r=Math.max(t,i,n);return 1+Math.floor(Math.log2(r))}isExternalImage(t){return qs(t)}getExternalImageSize(t){return Bc(t)}isTextureFormatSupported(t){return this.getTextureFormatCapabilities(t).create}isTextureFormatFilterable(t){return this.getTextureFormatCapabilities(t).filter}isTextureFormatRenderable(t){return this.getTextureFormatCapabilities(t).render}isTextureFormatCompressed(t){return Ve.isCompressed(t)}getSupportedCompressedTextureFormats(){const t=[];for(const i of Object.keys(IS()))this.isTextureFormatCompressed(i)&&this.isTextureFormatSupported(i)&&t.push(i);return t}pushDebugGroup(t){this.commandEncoder.pushDebugGroup(t)}popDebugGroup(){var t;(t=this.commandEncoder)==null||t.popDebugGroup()}insertDebugMarker(t){var i;(i=this.commandEncoder)==null||i.insertDebugMarker(t)}loseDevice(){return!1}incrementTimestamp(){return this.timestamp++}reportError(t,i,...n){if(!this.props.onError(t,i)){const s=VS(i,n);return C.error(this.type==="webgl"?"%cWebGL":"%cWebGPU","color: white; background: red; padding: 2px 6px; border-radius: 3px;",t.message,...s)}return()=>{}}debug(){if(this.props.debug)debugger;else C.once(0,`'Type luma.log.set({debug: true}) in console to enable debug breakpoints', +or create a device with the 'debug: true' prop.`)()}getDefaultCanvasContext(){if(!this.canvasContext)throw new Error("Device has no default CanvasContext. See props.createCanvasContext");return this.canvasContext}createFence(){throw new Error("createFence() not implemented")}beginRenderPass(t){return this.commandEncoder.beginRenderPass(t)}beginComputePass(t){return this.commandEncoder.beginComputePass(t)}generateMipmapsWebGPU(t){throw new Error("not implemented")}_createSharedRenderPipelineWebGL(t){throw new Error("_createSharedRenderPipelineWebGL() not implemented")}_createBindGroupLayoutWebGPU(t,i){throw new Error("_createBindGroupLayoutWebGPU() not implemented")}_createBindGroupWebGPU(t,i,n,r,s){throw new Error("_createBindGroupWebGPU() not implemented")}_supportsDebugGPUTime(){return this.features.has("timestamp-query")&&!!(this.props.debug||this.props.debugGPUTime)}_enableDebugGPUTime(t=256){if(!this._supportsDebugGPUTime())return null;if(this._debugGPUTimeQuery)return this._debugGPUTimeQuery;try{this._debugGPUTimeQuery=this.createQuerySet({type:"timestamp",count:t}),this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id,timeProfilingQuerySet:this._debugGPUTimeQuery})}catch{this._debugGPUTimeQuery=null}return this._debugGPUTimeQuery}_disableDebugGPUTime(){this._debugGPUTimeQuery&&(this.commandEncoder.getTimeProfilingQuerySet()===this._debugGPUTimeQuery&&(this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id})),this._debugGPUTimeQuery.destroy(),this._debugGPUTimeQuery=null)}_isDebugGPUTimeEnabled(){return this._debugGPUTimeQuery!==null}getCanvasContext(){return this.getDefaultCanvasContext()}readPixelsToArrayWebGL(t,i){throw new Error("not implemented")}readPixelsToBufferWebGL(t,i){throw new Error("not implemented")}setParametersWebGL(t){throw new Error("not implemented")}getParametersWebGL(t){throw new Error("not implemented")}withParametersWebGL(t,i){throw new Error("not implemented")}clearWebGL(t){throw new Error("not implemented")}resetWebGL(){throw new Error("not implemented")}getModuleData(t){var i;return(i=this._moduleData)[t]||(i[t]={}),this._moduleData[t]}static _getCanvasContextProps(t){return t.createCanvasContext===!0?{}:t.createCanvasContext}_getDeviceTextureFormatCapabilities(t){const i=Ve.getCapabilities(t),n=s=>(typeof s=="string"?this.features.has(s):s)??!0,r=n(i.create);return{format:t,create:r,render:r&&n(i.render),filter:r&&n(i.filter),blend:r&&n(i.blend),store:r&&n(i.store)}}_normalizeBufferProps(t){(t instanceof ArrayBuffer||ArrayBuffer.isView(t))&&(t={data:t});const i={...t};if((t.usage||0)&B.INDEX&&(t.indexType||(t.data instanceof Uint32Array?i.indexType="uint32":t.data instanceof Uint16Array?i.indexType="uint16":t.data instanceof Uint8Array&&(i.data=new Uint16Array(t.data),i.indexType="uint16")),!i.indexType))throw new Error("indices buffer content must be of type uint16 or uint32");return i}};f(Tr,"defaultProps",{id:null,powerPreference:"high-performance",failIfMajorPerformanceCaveat:!1,createCanvasContext:void 0,webgl:{},onError:(t,i)=>{},onResize:(t,i)=>{const[n,r]=t.getDevicePixelSize();C.log(1,`${t} resized => ${n}x${r}px`)()},onPositionChange:(t,i)=>{const[n,r]=t.getPosition();C.log(1,`${t} repositioned => ${n},${r}`)()},onVisibilityChange:t=>C.log(1,`${t} Visibility changed ${t.isVisible}`)(),onDevicePixelRatioChange:(t,i)=>C.log(1,`${t} DPR changed ${i.oldRatio} => ${t.devicePixelRatio}`)(),debug:KS(),debugGPUTime:!1,debugShaders:C.get("debug-shaders")||void 0,debugFramebuffers:!!C.get("debug-framebuffers"),debugFactories:!!C.get("debug-factories"),debugWebGL:!!C.get("debug-webgl"),debugSpectorJS:void 0,debugSpectorJSUrl:void 0,_reuseDevices:!1,_requestMaxLimits:!0,_cacheShaders:!0,_destroyShaders:!1,_cachePipelines:!0,_sharePipelines:!0,_destroyPipelines:!1,_initializeFeatures:!0,_disabledFeatures:{"compilation-status-async-webgl":!0},_handle:void 0});let Bt=Tr;function jS(e,t){return e!=null?!!e:t!==void 0?t!=="production":!1}function KS(){return jS(C.get("debug"),qS())}function qS(){const e=globalThis.process;if(e!=null&&e.env)return e.env.NODE_ENV}const GS="set luma.log.level=1 (or higher) to trace rendering",Oc="No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.",nn=class nn{constructor(){f(this,"stats",yc);f(this,"log",C);f(this,"VERSION","9.3.6");f(this,"spector");f(this,"preregisteredAdapters",new Map);if(globalThis.luma){if(globalThis.luma.VERSION!==this.VERSION)throw C.error(`Found luma.gl ${globalThis.luma.VERSION} while initialzing ${this.VERSION}`)(),C.error("'yarn why @luma.gl/core' can help identify the source of the conflict")(),new Error("luma.gl - multiple versions detected: see console log");C.error("This version of luma.gl has already been initialized")()}C.log(1,`${this.VERSION} - ${GS}`)(),globalThis.luma=this}async createDevice(t={}){const i={...nn.defaultProps,...t},n=this.selectAdapter(i.type,i.adapters);if(!n)throw new Error(Oc);return i.waitForPageLoad&&await n.pageLoaded,await n.create(i)}async attachDevice(t,i){var s;const n=this._getTypeFromHandle(t,i.adapters),r=n&&this.selectAdapter(n,i.adapters);if(!r)throw new Error(Oc);return await((s=r==null?void 0:r.attach)==null?void 0:s.call(r,t,i))}registerAdapters(t){for(const i of t)this.preregisteredAdapters.set(i.type,i)}getSupportedAdapters(t=[]){const i=this._getAdapterMap(t);return Array.from(i).map(([,n])=>n).filter(n=>{var r;return(r=n.isSupported)==null?void 0:r.call(n)}).map(n=>n.type)}getBestAvailableAdapterType(t=[]){var r,s;const i=["webgpu","webgl","null"],n=this._getAdapterMap(t);for(const o of i)if((s=(r=n.get(o))==null?void 0:r.isSupported)!=null&&s.call(r))return o;return null}selectAdapter(t,i=[]){let n=t;t==="best-available"&&(n=this.getBestAvailableAdapterType(i));const r=this._getAdapterMap(i);return n&&r.get(n)||null}enforceWebGL2(t=!0,i=[]){var s;const r=this._getAdapterMap(i).get("webgl");r||C.warn("enforceWebGL2: webgl adapter not found")(),(s=r==null?void 0:r.enforceWebGL2)==null||s.call(r,t)}setDefaultDeviceProps(t){Object.assign(nn.defaultProps,t)}_getAdapterMap(t=[]){const i=new Map(this.preregisteredAdapters);for(const n of t)i.set(n.type,n);return i}_getTypeFromHandle(t,i=[]){return t instanceof WebGL2RenderingContext?"webgl":typeof GPUDevice<"u"&&t instanceof GPUDevice||t!=null&&t.queue?"webgpu":t===null?"null":(t instanceof WebGLRenderingContext?C.warn("WebGL1 is not supported",t)():C.warn("Unknown handle type",t)(),null)}};f(nn,"defaultProps",{...Bt.defaultProps,type:"best-available",adapters:void 0,waitForPageLoad:!0});let Zs=nn;const ZS=new Zs;class QS{get pageLoaded(){return t0()}}const JS=Mt()&&typeof document<"u",e0=()=>JS&&document.readyState==="complete";let Zn=null;function t0(){return Zn||(e0()||typeof window>"u"?Zn=Promise.resolve():Zn=new Promise(e=>window.addEventListener("load",()=>e()))),Zn}class i0{constructor(t){f(this,"props");f(this,"_resizeObserver");f(this,"_intersectionObserver");f(this,"_observeDevicePixelRatioTimeout",null);f(this,"_observeDevicePixelRatioMediaQuery",null);f(this,"_handleDevicePixelRatioChange",()=>this._refreshDevicePixelRatio());f(this,"_trackPositionInterval",null);f(this,"_started",!1);this.props=t}get started(){return this._started}start(){if(this._started||!this.props.canvas)return;this._started=!0,this._intersectionObserver||(this._intersectionObserver=new IntersectionObserver(i=>this.props.onIntersection(i))),this._resizeObserver||(this._resizeObserver=new ResizeObserver(i=>this.props.onResize(i))),this._intersectionObserver.observe(this.props.canvas);const t=this.props.resizeObserverBox;try{this._resizeObserver.observe(this.props.canvas,{box:t})}catch{this._resizeObserver.observe(this.props.canvas,{box:"content-box"})}this._observeDevicePixelRatioTimeout=setTimeout(()=>this._refreshDevicePixelRatio(),0),this.props.trackPosition&&this._trackPosition()}stop(){var t,i;this._started&&(this._started=!1,this._observeDevicePixelRatioTimeout&&(clearTimeout(this._observeDevicePixelRatioTimeout),this._observeDevicePixelRatioTimeout=null),this._observeDevicePixelRatioMediaQuery&&(this._observeDevicePixelRatioMediaQuery.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=null),this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null),(t=this._resizeObserver)==null||t.disconnect(),(i=this._intersectionObserver)==null||i.disconnect())}_refreshDevicePixelRatio(){var t;this._started&&(this.props.onDevicePixelRatioChange(),(t=this._observeDevicePixelRatioMediaQuery)==null||t.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),this._observeDevicePixelRatioMediaQuery.addEventListener("change",this._handleDevicePixelRatioChange,{once:!0}))}_trackPosition(t=100){this._trackPositionInterval||(this._trackPositionInterval=setInterval(()=>{this._started?this.props.onPositionChange():this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null)},t))}}function n0(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function Uc(e,t){var i;if(!e){const n=new Error(t??"luma.gl assertion failed.");throw(i=Error.captureStackTrace)==null||i.call(Error,n,Uc),n}}function Qn(e,t){return Uc(e,t),e}const mi=class mi{constructor(t){f(this,"id");f(this,"props");f(this,"canvas");f(this,"htmlCanvas");f(this,"offscreenCanvas");f(this,"type");f(this,"initialized");f(this,"isInitialized",!1);f(this,"isVisible",!0);f(this,"cssWidth");f(this,"cssHeight");f(this,"devicePixelRatio");f(this,"devicePixelWidth");f(this,"devicePixelHeight");f(this,"drawingBufferWidth");f(this,"drawingBufferHeight");f(this,"_initializedResolvers",n0());f(this,"_canvasObserver");f(this,"_position",[0,0]);f(this,"destroyed",!1);f(this,"_needsDrawingBufferResize",!0);var i,n;this.props={...mi.defaultProps,...t},t=this.props,this.initialized=this._initializedResolvers.promise,Mt()?t.canvas?typeof t.canvas=="string"?this.canvas=s0(t.canvas):this.canvas=t.canvas:this.canvas=o0(t):this.canvas={width:t.width||1,height:t.height||1},mi.isHTMLCanvas(this.canvas)?(this.id=t.id||this.canvas.id,this.type="html-canvas",this.htmlCanvas=this.canvas):mi.isOffscreenCanvas(this.canvas)?(this.id=t.id||"offscreen-canvas",this.type="offscreen-canvas",this.offscreenCanvas=this.canvas):(this.id=t.id||"node-canvas-context",this.type="node"),this.cssWidth=((i=this.htmlCanvas)==null?void 0:i.clientWidth)||this.canvas.width,this.cssHeight=((n=this.htmlCanvas)==null?void 0:n.clientHeight)||this.canvas.height,this.devicePixelWidth=this.canvas.width,this.devicePixelHeight=this.canvas.height,this.drawingBufferWidth=this.canvas.width,this.drawingBufferHeight=this.canvas.height,this.devicePixelRatio=globalThis.devicePixelRatio||1,this._position=[0,0],this._canvasObserver=new i0({canvas:this.htmlCanvas,trackPosition:this.props.trackPosition,resizeObserverBox:this.props.pixelSizeSource==="css-dpr"?"content-box":"device-pixel-content-box",onResize:r=>this._handleResize(r),onIntersection:r=>this._handleIntersection(r),onDevicePixelRatioChange:()=>this._observeDevicePixelRatio(),onPositionChange:()=>this.updatePosition()})}static isHTMLCanvas(t){return typeof HTMLCanvasElement<"u"&&t instanceof HTMLCanvasElement}static isOffscreenCanvas(t){return typeof OffscreenCanvas<"u"&&t instanceof OffscreenCanvas}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}destroy(){this.destroyed||(this.destroyed=!0,this._stopObservers(),this.device=null)}setProps(t){return"useDevicePixels"in t&&(this.props.useDevicePixels=t.useDevicePixels||!1,this._updateDrawingBufferSize()),this}getCurrentFramebuffer(t){return this._resizeDrawingBufferIfNeeded(),this._getCurrentFramebuffer(t)}getCSSSize(){return[this.cssWidth,this.cssHeight]}getPosition(){return this._position}getDevicePixelSize(){return[this.devicePixelWidth,this.devicePixelHeight]}getDrawingBufferSize(){return[this.drawingBufferWidth,this.drawingBufferHeight]}getMaxDrawingBufferSize(){const t=this.device.limits.maxTextureDimension2D;return[t,t]}setDrawingBufferSize(t,i){t=Math.floor(t),i=Math.floor(i),!(this.drawingBufferWidth===t&&this.drawingBufferHeight===i)&&(this.drawingBufferWidth=t,this.drawingBufferHeight=i,this._needsDrawingBufferResize=!0)}getDevicePixelRatio(){return typeof window<"u"&&window.devicePixelRatio||1}cssToDevicePixels(t,i=!0){const n=this.cssToDeviceRatio(),[r,s]=this.getDrawingBufferSize();return a0(t,n,r,s,i)}getPixelSize(){return this.getDevicePixelSize()}getAspect(){const[t,i]=this.getDrawingBufferSize();return t>0&&i>0?t/i:1}cssToDeviceRatio(){try{const[t]=this.getDrawingBufferSize(),[i]=this.getCSSSize();return i?t/i:1}catch{return 1}}resize(t){this.setDrawingBufferSize(t.width,t.height)}_setAutoCreatedCanvasId(t){var i;((i=this.htmlCanvas)==null?void 0:i.id)==="lumagl-auto-created-canvas"&&(this.htmlCanvas.id=t)}_startObservers(){this.destroyed||this._canvasObserver.start()}_stopObservers(){this._canvasObserver.stop()}_handleIntersection(t){if(this.destroyed)return;const i=t.find(r=>r.target===this.canvas);if(!i)return;const n=i.isIntersecting;this.isVisible!==n&&(this.isVisible=n,this.device.props.onVisibilityChange(this))}_handleResize(t){var s;if(this.destroyed)return;const i=t.find(o=>o.target===this.canvas);if(!i)return;const n=Qn((s=i.contentBoxSize)==null?void 0:s[0]);this.cssWidth=n.inlineSize,this.cssHeight=n.blockSize;const r=this.getDevicePixelSize();this._setDevicePixelSize(this._getDevicePixelSizeFromResizeEntry(i)),this._updateDrawingBufferSize(),this.device.props.onResize(this,{oldPixelSize:r})}_updateDrawingBufferSize(){if(this.props.autoResize)if(typeof this.props.useDevicePixels=="number"){const t=this.props.useDevicePixels;this.setDrawingBufferSize(this.cssWidth*t,this.cssHeight*t)}else this.props.useDevicePixels?this.setDrawingBufferSize(this.devicePixelWidth,this.devicePixelHeight):this.setDrawingBufferSize(this.cssWidth,this.cssHeight);this._initializedResolvers.resolve(),this.isInitialized=!0,this.updatePosition()}_getDevicePixelSizeFromResizeEntry(t){var n,r,s,o,a;const i=Qn((n=t.contentBoxSize)==null?void 0:n[0]);return this.props.pixelSizeSource==="css-dpr"?this._getDevicePixelSizeFromCSSSize(i.inlineSize,i.blockSize):{devicePixelWidth:((s=(r=t.devicePixelContentBoxSize)==null?void 0:r[0])==null?void 0:s.inlineSize)||i.inlineSize*devicePixelRatio,devicePixelHeight:((a=(o=t.devicePixelContentBoxSize)==null?void 0:o[0])==null?void 0:a.blockSize)||i.blockSize*devicePixelRatio}}_getDevicePixelSizeFromCSSSize(t,i){const n=this.getDevicePixelRatio();return{devicePixelWidth:Math.floor(t*n),devicePixelHeight:Math.floor(i*n)}}_setDevicePixelSize({devicePixelWidth:t,devicePixelHeight:i}){const[n,r]=this.getMaxDrawingBufferSize();this.devicePixelWidth=Math.max(1,Math.min(t,n)),this.devicePixelHeight=Math.max(1,Math.min(i,r))}_resizeDrawingBufferIfNeeded(){this._needsDrawingBufferResize&&(this._needsDrawingBufferResize=!1,(this.drawingBufferWidth!==this.canvas.width||this.drawingBufferHeight!==this.canvas.height)&&(this.canvas.width=this.drawingBufferWidth,this.canvas.height=this.drawingBufferHeight,this._configureDevice()))}_observeDevicePixelRatio(){var i,n;if(this.destroyed||!this._canvasObserver.started)return;const t=this.devicePixelRatio;if(this.devicePixelRatio=window.devicePixelRatio,this.props.pixelSizeSource==="css-dpr"){const r=this.getDevicePixelSize();this._setDevicePixelSize(this._getDevicePixelSizeFromCSSSize(this.cssWidth,this.cssHeight)),this._updateDrawingBufferSize(),this.device.props.onResize(this,{oldPixelSize:r})}this.updatePosition(),(n=(i=this.device.props).onDevicePixelRatioChange)==null||n.call(i,this,{oldRatio:t})}updatePosition(){var i,n,r;if(this.destroyed)return;const t=(i=this.htmlCanvas)==null?void 0:i.getBoundingClientRect();if(t){const s=[t.left,t.top];if(this._position??(this._position=s),s[0]!==this._position[0]||s[1]!==this._position[1]){const a=this._position;this._position=s,(r=(n=this.device.props).onPositionChange)==null||r.call(n,this,{oldPosition:a})}}}};f(mi,"defaultProps",{id:void 0,canvas:null,width:800,height:600,useDevicePixels:!0,pixelSizeSource:"exact",autoResize:!0,container:null,visible:!0,alphaMode:"opaque",colorSpace:"srgb",trackPosition:!1});let ii=mi;function r0(e){if(typeof e=="string"){const t=document.getElementById(e);if(!t)throw new Error(`${e} is not an HTML element`);return t}return e||document.body}function s0(e){const t=document.getElementById(e);if(!ii.isHTMLCanvas(t))throw new Error("Object is not a canvas element");return t}function o0(e){const{width:t,height:i}=e,n=document.createElement("canvas");n.id=Ui("lumagl-auto-created-canvas"),n.width=t||1,n.height=i||1,n.style.width=Number.isFinite(t)?`${t}px`:"100%",n.style.height=Number.isFinite(i)?`${i}px`:"100%",e!=null&&e.visible||(n.style.visibility="hidden");const r=r0((e==null?void 0:e.container)||null);return r.insertBefore(n,r.firstChild),n}function a0(e,t,i,n,r){const s=e,o=zc(s[0],t,i);let a=Lc(s[1],t,n,r),l=zc(s[0]+1,t,i);const c=l===i-1?l:l-1;l=Lc(s[1]+1,t,n,r);let u;return r?(l=l===0?l:l+1,u=a,a=l):u=l===n-1?l:l-1,{x:o,y:a,width:Math.max(c-o+1,1),height:Math.max(u-a+1,1)}}function zc(e,t,i){return Math.min(Math.round(e*t),i-1)}function Lc(e,t,i,n){return n?Math.max(0,i-1-Math.round(e*t)):Math.min(Math.round(e*t),i-1)}class Wc extends ii{}f(Wc,"defaultProps",ii.defaultProps);class l0 extends ii{}const rn=class rn extends Z{get[Symbol.toStringTag](){return"Sampler"}constructor(t,i){i=rn.normalizeProps(t,i),super(t,i,rn.defaultProps)}static normalizeProps(t,i){return i}};f(rn,"defaultProps",{...Z.defaultProps,type:"color-sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge",magFilter:"nearest",minFilter:"nearest",mipmapFilter:"none",lodMinClamp:0,lodMaxClamp:32,compare:"less-equal",maxAnisotropy:1});let ni=rn;const c0={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},ae=class ae extends Z{constructor(i,n,r){n=ae.normalizeProps(i,n);super(i,n,ae.defaultProps);f(this,"dimension");f(this,"baseDimension");f(this,"format");f(this,"width");f(this,"height");f(this,"depth");f(this,"mipLevels");f(this,"samples");f(this,"byteAlignment");f(this,"ready",Promise.resolve(this));f(this,"isReady",!0);f(this,"updateTimestamp");if(this.dimension=this.props.dimension,this.baseDimension=c0[this.dimension],this.format=this.props.format,this.width=this.props.width,this.height=this.props.height,this.depth=this.props.depth,this.mipLevels=this.props.mipLevels,this.samples=this.props.samples||1,this.dimension==="cube"&&(this.depth=6),this.props.width===void 0||this.props.height===void 0)if(i.isExternalImage(n.data)){const s=i.getExternalImageSize(n.data);this.width=(s==null?void 0:s.width)||1,this.height=(s==null?void 0:s.height)||1}else this.width=1,this.height=1,(this.props.width===void 0||this.props.height===void 0)&&C.warn(`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`)();this.byteAlignment=(r==null?void 0:r.byteAlignment)||1,this.updateTimestamp=i.incrementTimestamp()}get[Symbol.toStringTag](){return"Texture"}toString(){return`Texture(${this.id},${this.format},${this.width}x${this.height})`}clone(i){return this.device.createTexture({...this.props,...i})}setSampler(i){this.sampler=i instanceof ni?i:this.device.createSampler(i)}copyImageData(i){const{data:n,depth:r,...s}=i;this.writeData(n,{...s,depthOrArrayLayers:s.depthOrArrayLayers??r})}computeMemoryLayout(i={}){const n=this._normalizeTextureReadOptions(i),{width:r=this.width,height:s=this.height,depthOrArrayLayers:o=this.depth}=n,{format:a,byteAlignment:l}=this;return Ve.computeMemoryLayout({format:a,width:r,height:s,depth:o,byteAlignment:l})}readBuffer(i,n){throw new Error("readBuffer not implemented")}readDataAsync(i){throw new Error("readBuffer not implemented")}writeBuffer(i,n){throw new Error("readBuffer not implemented")}writeData(i,n){throw new Error("readBuffer not implemented")}readDataSyncWebGL(i){throw new Error("readDataSyncWebGL not available")}generateMipmapsWebGL(){throw new Error("generateMipmapsWebGL not available")}static normalizeProps(i,n){const r={...n},{width:s,height:o}=r;return typeof s=="number"&&(r.width=Math.max(1,Math.ceil(s))),typeof o=="number"&&(r.height=Math.max(1,Math.ceil(o))),r}_initializeData(i){this.device.isExternalImage(i)?this.copyExternalImage({image:i,width:this.width,height:this.height,depth:this.depth,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}):i&&this.copyImageData({data:i,mipLevel:0,x:0,y:0,z:0,aspect:"all"})}_normalizeCopyImageDataOptions(i){const{data:n,depth:r,...s}=i,o=this._normalizeTextureWriteOptions({...s,depthOrArrayLayers:s.depthOrArrayLayers??r});return{data:n,depth:o.depthOrArrayLayers,...o}}_normalizeCopyExternalImageOptions(i){const n=ae._omitUndefined(i),r=n.mipLevel??0,s=this._getMipLevelSize(r),o=this.device.getExternalImageSize(i.image),a={...ae.defaultCopyExternalImageOptions,...s,...o,...n};return a.width=Math.min(a.width,s.width-a.x),a.height=Math.min(a.height,s.height-a.y),a.depth=Math.min(a.depth,s.depthOrArrayLayers-a.z),a}_normalizeTextureReadOptions(i){const n=ae._omitUndefined(i),r=n.mipLevel??0,s=this._getMipLevelSize(r),o={...ae.defaultTextureReadOptions,...s,...n};return o.width=Math.min(o.width,s.width-o.x),o.height=Math.min(o.height,s.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,s.depthOrArrayLayers-o.z),o}_getSupportedColorReadOptions(i){const n=this._normalizeTextureReadOptions(i),r=Ve.getInfo(this.format);switch(this._validateColorReadAspect(n),this._validateColorReadFormat(r),this.dimension){case"2d":case"cube":case"cube-array":case"2d-array":case"3d":return n;default:throw new Error(`${this} color readback does not support ${this.dimension} textures`)}}_validateColorReadAspect(i){if(i.aspect!=="all")throw new Error(`${this} color readback only supports aspect 'all'`)}_validateColorReadFormat(i){if(i.compressed)throw new Error(`${this} color readback does not support compressed formats (${this.format})`);switch(i.attachment){case"color":return;case"depth":throw new Error(`${this} color readback does not support depth formats (${this.format})`);case"stencil":throw new Error(`${this} color readback does not support stencil formats (${this.format})`);case"depth-stencil":throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);default:throw new Error(`${this} color readback does not support format ${this.format}`)}}_normalizeTextureWriteOptions(i){const n=ae._omitUndefined(i),r=n.mipLevel??0,s=this._getMipLevelSize(r),o={...ae.defaultTextureWriteOptions,...s,...n};o.width=Math.min(o.width,s.width-o.x),o.height=Math.min(o.height,s.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,s.depthOrArrayLayers-o.z);const a=Ve.computeMemoryLayout({format:this.format,width:o.width,height:o.height,depth:o.depthOrArrayLayers,byteAlignment:this.byteAlignment}),l=a.bytesPerPixel*o.width;if(o.bytesPerRow=n.bytesPerRow??a.bytesPerRow,o.rowsPerImage=n.rowsPerImage??o.height,o.bytesPerRow>i),r=this.baseDimension==="1d"?1:Math.max(1,this.height>>i),s=this.dimension==="3d"?Math.max(1,this.depth>>i):this.depth;return{width:n,height:r,depthOrArrayLayers:s}}getAllocatedByteLength(){let i=0;for(let n=0;nn!==void 0))}};f(ae,"SAMPLE",4),f(ae,"STORAGE",8),f(ae,"RENDER",16),f(ae,"COPY_SRC",1),f(ae,"COPY_DST",2),f(ae,"TEXTURE",4),f(ae,"RENDER_ATTACHMENT",16),f(ae,"defaultProps",{...Z.defaultProps,data:null,dimension:"2d",format:"rgba8unorm",usage:ae.SAMPLE|ae.RENDER|ae.COPY_DST,width:void 0,height:void 0,depth:1,mipLevels:1,samples:void 0,sampler:{},view:void 0}),f(ae,"defaultCopyDataOptions",{data:void 0,byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,width:void 0,height:void 0,depthOrArrayLayers:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all"}),f(ae,"defaultCopyExternalImageOptions",{image:void 0,sourceX:0,sourceY:0,width:void 0,height:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}),f(ae,"defaultTextureReadOptions",{x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"}),f(ae,"defaultTextureWriteOptions",{byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"});let M=ae;const vr=class vr extends Z{get[Symbol.toStringTag](){return"TextureView"}constructor(t,i){super(t,i,vr.defaultProps)}};f(vr,"defaultProps",{...Z.defaultProps,format:void 0,dimension:void 0,aspect:"all",baseMipLevel:0,mipLevelCount:void 0,baseArrayLayer:0,arrayLayerCount:void 0});let Jn=vr;function u0(e,t,i){let n="";const r=t.split(/\r?\n/),s=e.slice().sort((o,a)=>o.lineNum-a.lineNum);switch((i==null?void 0:i.showSourceCode)||"no"){case"all":let o=0;for(let a=1;a<=r.length;a++){const l=r[a-1],c=s[o];for(l&&c&&(n+=Vc(l,a,i));s.length>o&&c.lineNum===a;){const u=s[o++];u&&(n+=Qs(u,r,u.lineNum,{...i,inlineSource:!1}))}}for(;s.length>o;){const a=s[o++];a&&(n+=Qs(a,[],0,{...i,inlineSource:!1}))}return n;case"issues":case"no":for(const a of e)n+=Qs(a,r,a.lineNum,{inlineSource:(i==null?void 0:i.showSourceCode)!=="no"});return n}}function Qs(e,t,i,n){if(n!=null&&n.inlineSource){const s=d0(t,i),o=e.linePos>0?`${" ".repeat(e.linePos+5)}^^^ +`:"";return` +${s}${o}${e.type.toUpperCase()}: ${e.message} + +`}const r=e.type==="error"?"red":"orange";return n!=null&&n.html?`
${e.type.toUpperCase()}: ${e.message}
`:`${e.type.toUpperCase()}: ${e.message}`}function d0(e,t,i){let n="";for(let r=t-2;r<=t;r++){const s=e[r-1];s!==void 0&&(n+=Vc(s,t,i))}return n}function Vc(e,t,i){const n=i!=null&&i.html?f0(e):e;return`${h0(String(t),4)}: ${n}${i!=null&&i.html?"
":` +`}`}function h0(e,t){let i="";for(let n=e.length;n",">").replaceAll('"',""").replaceAll("'","'")}const Pr=class Pr extends Z{constructor(i,n){n={...n,debugShaders:n.debugShaders||i.props.debugShaders||"errors"};super(i,{id:p0(n),...n},Pr.defaultProps);f(this,"stage");f(this,"source");f(this,"compilationStatus","pending");this.stage=this.props.stage,this.source=this.props.source}get[Symbol.toStringTag](){return"Shader"}getCompilationInfoSync(){return null}getTranslatedSource(){return null}async debugShader(){const i=this.props.debugShaders;switch(i){case"never":return;case"errors":if(this.compilationStatus==="success")return;break}const n=await this.getCompilationInfo();i==="warnings"&&(n==null?void 0:n.length)===0||this._displayShaderLog(n,this.id)}_displayShaderLog(i,n){if(typeof document>"u"||!(document!=null&&document.createElement))return;const r=n,s=`${this.stage} shader "${r}"`,o=u0(i,this.source,{showSourceCode:"all",html:!0}),a=this.getTranslatedSource(),l=document.createElement("div");l.innerHTML=`

Compilation error in ${s}

+
+
+ +
+
${o}
`,a&&(l.innerHTML+=`

Translated Source



${a}
`),l.style.top="0",l.style.left="0",l.style.background="white",l.style.position="fixed",l.style.zIndex="9999",l.style.maxWidth="100vw",l.style.maxHeight="100vh",l.style.overflowY="auto",document.body.appendChild(l);const c=l.querySelector(".luma-compiler-log-error");c==null||c.scrollIntoView(),l.querySelector("button#close").onclick=()=>{l.remove()},l.querySelector("button#copy").onclick=()=>{navigator.clipboard.writeText(this.source)}}};f(Pr,"defaultProps",{...Z.defaultProps,language:"auto",stage:void 0,source:"",sourceMap:null,entryPoint:"main",debugShaders:void 0});let er=Pr;function p0(e){return g0(e.source)||e.id||Ui(`unnamed ${e.stage}-shader`)}function g0(e,t="unnamed"){const n=/#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/.exec(e);return(n==null?void 0:n[1])??t}const Cr=class Cr extends Z{constructor(i,n={}){super(i,n,Cr.defaultProps);f(this,"width");f(this,"height");this.width=this.props.width,this.height=this.props.height}get[Symbol.toStringTag](){return"Framebuffer"}clone(i){const n=this.colorAttachments.map(s=>s.texture.clone(i)),r=this.depthStencilAttachment&&this.depthStencilAttachment.texture.clone(i);return this.device.createFramebuffer({...this.props,...i,colorAttachments:n,depthStencilAttachment:r})}resize(i){let n=!i;if(i){const[r,s]=Array.isArray(i)?i:[i.width,i.height];n=n||s!==this.height||r!==this.width,this.width=r,this.height=s}n&&(C.log(2,`Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)(),this.resizeAttachments(this.width,this.height))}autoCreateAttachmentTextures(){if(this.props.colorAttachments.length===0&&!this.props.depthStencilAttachment)throw new Error("Framebuffer has noattachments");this.colorAttachments=this.props.colorAttachments.map((n,r)=>{if(typeof n=="string"){const s=this.createColorTexture(n,r);return this.attachResource(s),s.view}return n instanceof M?n.view:n});const i=this.props.depthStencilAttachment;if(i)if(typeof i=="string"){const n=this.createDepthStencilTexture(i);this.attachResource(n),this.depthStencilAttachment=n.view}else i instanceof M?this.depthStencilAttachment=i.view:this.depthStencilAttachment=i}createColorTexture(i,n){return this.device.createTexture({id:`${this.id}-color-attachment-${n}`,usage:M.RENDER_ATTACHMENT,format:i,width:this.width,height:this.height,sampler:{magFilter:"linear",minFilter:"linear"}})}createDepthStencilTexture(i){return this.device.createTexture({id:`${this.id}-depth-stencil-attachment`,usage:M.RENDER_ATTACHMENT,format:i,width:this.width,height:this.height})}resizeAttachments(i,n){if(this.colorAttachments.forEach((r,s)=>{const o=r.texture.clone({width:i,height:n});this.destroyAttachedResource(r),this.colorAttachments[s]=o.view,this.attachResource(o.view)}),this.depthStencilAttachment){const r=this.depthStencilAttachment.texture.clone({width:i,height:n});this.destroyAttachedResource(this.depthStencilAttachment),this.depthStencilAttachment=r.view,this.attachResource(r)}this.updateAttachments()}};f(Cr,"defaultProps",{...Z.defaultProps,width:1,height:1,colorAttachments:[],depthStencilAttachment:null});let tr=Cr;const Ar=class Ar extends Z{constructor(i,n){super(i,n,Ar.defaultProps);f(this,"shaderLayout");f(this,"bufferLayout");f(this,"linkStatus","pending");f(this,"hash","");f(this,"sharedRenderPipeline",null);this.shaderLayout=this.props.shaderLayout,this.bufferLayout=this.props.bufferLayout||[],this.sharedRenderPipeline=this.props._sharedRenderPipeline||null}get[Symbol.toStringTag](){return"RenderPipeline"}get isPending(){var i;return this.linkStatus==="pending"||this.vs.compilationStatus==="pending"||((i=this.fs)==null?void 0:i.compilationStatus)==="pending"}get isErrored(){var i;return this.linkStatus==="error"||this.vs.compilationStatus==="error"||((i=this.fs)==null?void 0:i.compilationStatus)==="error"}};f(Ar,"defaultProps",{...Z.defaultProps,vs:null,vertexEntryPoint:"vertexMain",vsConstants:{},fs:null,fragmentEntryPoint:"fragmentMain",fsConstants:{},shaderLayout:null,bufferLayout:[],topology:"triangle-list",colorAttachmentFormats:void 0,depthStencilAttachmentFormat:void 0,parameters:{},varyings:void 0,bufferMode:void 0,disableWarnings:!1,_sharedRenderPipeline:void 0,bindings:void 0,bindGroups:void 0});let bt=Ar;class m0 extends Z{get[Symbol.toStringTag](){return"SharedRenderPipeline"}constructor(t,i){super(t,i,{...Z.defaultProps,handle:void 0,vs:void 0,fs:void 0,varyings:void 0,bufferMode:void 0})}}const Rr=class Rr extends Z{constructor(i,n){super(i,n,Rr.defaultProps);f(this,"hash","");f(this,"shaderLayout");this.shaderLayout=n.shaderLayout}get[Symbol.toStringTag](){return"ComputePipeline"}};f(Rr,"defaultProps",{...Z.defaultProps,shader:void 0,entryPoint:void 0,constants:{},shaderLayout:void 0});let ir=Rr;const wr=class wr{constructor(t){f(this,"device");f(this,"_hashCounter",0);f(this,"_hashes",{});f(this,"_renderPipelineCache",{});f(this,"_computePipelineCache",{});f(this,"_sharedRenderPipelineCache",{});this.device=t}static getDefaultPipelineFactory(t){const i=t.getModuleData("@luma.gl/core");return i.defaultPipelineFactory||(i.defaultPipelineFactory=new wr(t)),i.defaultPipelineFactory}get[Symbol.toStringTag](){return"PipelineFactory"}toString(){return`PipelineFactory(${this.device.id})`}createRenderPipeline(t){var o;if(!this.device.props._cachePipelines)return this.device.createRenderPipeline(t);const i={...bt.defaultProps,...t},n=this._renderPipelineCache,r=this._hashRenderPipeline(i);let s=(o=n[r])==null?void 0:o.resource;if(s)n[r].useCount++,this.device.props.debugFactories&&C.log(3,`${this}: ${n[r].resource} reused, count=${n[r].useCount}, (id=${t.id})`)();else{const a=this.device.type==="webgl"&&this.device.props._sharePipelines?this.createSharedRenderPipeline(i):void 0;s=this.device.createRenderPipeline({...i,id:i.id?`${i.id}-cached`:Ui("unnamed-cached"),_sharedRenderPipeline:a}),s.hash=r,n[r]={resource:s,useCount:1},this.device.props.debugFactories&&C.log(3,`${this}: ${s} created, count=${n[r].useCount}`)()}return s}createComputePipeline(t){var o;if(!this.device.props._cachePipelines)return this.device.createComputePipeline(t);const i={...ir.defaultProps,...t},n=this._computePipelineCache,r=this._hashComputePipeline(i);let s=(o=n[r])==null?void 0:o.resource;return s?(n[r].useCount++,this.device.props.debugFactories&&C.log(3,`${this}: ${n[r].resource} reused, count=${n[r].useCount}, (id=${t.id})`)()):(s=this.device.createComputePipeline({...i,id:i.id?`${i.id}-cached`:void 0}),s.hash=r,n[r]={resource:s,useCount:1},this.device.props.debugFactories&&C.log(3,`${this}: ${s} created, count=${n[r].useCount}`)()),s}release(t){if(!this.device.props._cachePipelines){t.destroy();return}const i=this._getCache(t),n=t.hash;i[n].useCount--,i[n].useCount===0?(this._destroyPipeline(t),this.device.props.debugFactories&&C.log(3,`${this}: ${t} released and destroyed`)()):i[n].useCount<0?(C.error(`${this}: ${t} released, useCount < 0, resetting`)(),i[n].useCount=0):this.device.props.debugFactories&&C.log(3,`${this}: ${t} released, count=${i[n].useCount}`)()}createSharedRenderPipeline(t){const i=this._hashSharedRenderPipeline(t);let n=this._sharedRenderPipelineCache[i];return n||(n={resource:this.device._createSharedRenderPipelineWebGL(t),useCount:0},this._sharedRenderPipelineCache[i]=n),n.useCount++,n.resource}releaseSharedRenderPipeline(t){if(!t.sharedRenderPipeline)return;const i=this._hashSharedRenderPipeline(t.sharedRenderPipeline.props),n=this._sharedRenderPipelineCache[i];n&&(n.useCount--,n.useCount===0&&(n.resource.destroy(),delete this._sharedRenderPipelineCache[i]))}_destroyPipeline(t){const i=this._getCache(t);return this.device.props._destroyPipelines?(delete i[t.hash],t.destroy(),t instanceof bt&&this.releaseSharedRenderPipeline(t),!0):!1}_getCache(t){let i;if(t instanceof ir&&(i=this._computePipelineCache),t instanceof bt&&(i=this._renderPipelineCache),!i)throw new Error(`${this}`);if(!i[t.hash])throw new Error(`${this}: ${t} matched incorrect entry`);return i}_hashComputePipeline(t){const{type:i}=this.device,n=this._getHash(t.shader.source),r=this._getHash(JSON.stringify(t.shaderLayout));return`${i}/C/${n}SL${r}`}_hashRenderPipeline(t){const i=t.vs?this._getHash(t.vs.source):0,n=t.fs?this._getHash(t.fs.source):0,r=this._getWebGLVaryingHash(t),s=this._getHash(JSON.stringify(t.shaderLayout)),o=this._getHash(JSON.stringify(t.bufferLayout)),{type:a}=this.device;switch(a){case"webgl":const l=this._getHash(JSON.stringify(t.parameters));return`${a}/R/${i}/${n}V${r}T${t.topology}P${l}SL${s}BL${o}`;case"webgpu":default:const c=this._getHash(JSON.stringify({vertexEntryPoint:t.vertexEntryPoint,fragmentEntryPoint:t.fragmentEntryPoint})),u=this._getHash(JSON.stringify(t.parameters)),d=this._getWebGPUAttachmentHash(t);return`${a}/R/${i}/${n}V${r}T${t.topology}EP${c}P${u}SL${s}BL${o}A${d}`}}_hashSharedRenderPipeline(t){const i=t.vs?this._getHash(t.vs.source):0,n=t.fs?this._getHash(t.fs.source):0,r=this._getWebGLVaryingHash(t);return`webgl/S/${i}/${n}V${r}`}_getHash(t){return this._hashes[t]===void 0&&(this._hashes[t]=this._hashCounter++),this._hashes[t]}_getWebGLVaryingHash(t){const{varyings:i=[],bufferMode:n=null}=t;return this._getHash(JSON.stringify({varyings:i,bufferMode:n}))}_getWebGPUAttachmentHash(t){var r;const i=t.colorAttachmentFormats??[this.device.preferredColorFormat],n=(r=t.parameters)!=null&&r.depthWriteEnabled?t.depthStencilAttachmentFormat||this.device.preferredDepthFormat:null;return this._getHash(JSON.stringify({colorAttachmentFormats:i,depthStencilAttachmentFormat:n}))}};f(wr,"defaultProps",{...bt.defaultProps});let Js=wr;const Er=class Er{constructor(t){f(this,"device");f(this,"_cache",{});this.device=t}static getDefaultShaderFactory(t){const i=t.getModuleData("@luma.gl/core");return i.defaultShaderFactory||(i.defaultShaderFactory=new Er(t)),i.defaultShaderFactory}get[Symbol.toStringTag](){return"ShaderFactory"}toString(){return`${this[Symbol.toStringTag]}(${this.device.id})`}createShader(t){if(!this.device.props._cacheShaders)return this.device.createShader(t);const i=this._hashShader(t);let n=this._cache[i];if(n)n.useCount++,this.device.props.debugFactories&&C.log(3,`${this}: Reusing shader ${n.resource.id} count=${n.useCount}`)();else{const r=this.device.createShader({...t,id:t.id?`${t.id}-cached`:void 0});this._cache[i]=n={resource:r,useCount:1},this.device.props.debugFactories&&C.log(3,`${this}: Created new shader ${r.id}`)()}return n.resource}release(t){if(!this.device.props._cacheShaders){t.destroy();return}const i=this._hashShader(t),n=this._cache[i];if(n)if(n.useCount--,n.useCount===0)this.device.props._destroyShaders&&(delete this._cache[i],n.resource.destroy(),this.device.props.debugFactories&&C.log(3,`${this}: Releasing shader ${t.id}, destroyed`)());else{if(n.useCount<0)throw new Error(`ShaderFactory: Shader ${t.id} released too many times`);this.device.props.debugFactories&&C.log(3,`${this}: Releasing shader ${t.id} count=${n.useCount}`)()}}_hashShader(t){return`${t.stage}:${t.source}`}};f(Er,"defaultProps",{...er.defaultProps});let eo=Er;function x0(e,t,i){const n=e.bindings.find(r=>r.name===t||`${r.name.toLocaleLowerCase()}uniforms`===t.toLocaleLowerCase());return n||C.warn(`Binding ${t} not set: Not found in shader layout.`)(),n||null}function Hc(e,t){if(!t)return{};if(S0(t))return Object.fromEntries(Object.entries(t).map(([r,s])=>[Number(r),{...s}]));const i={};for(const[n,r]of Object.entries(t)){const s=x0(e,n),o=(s==null?void 0:s.group)??0;i[o]||(i[o]={}),i[o][n]=r}return i}function $c(e){const t={};for(const i of Object.values(e))Object.assign(t,i);return t}function S0(e){const t=Object.keys(e);return t.length>0&&t.every(i=>/^\d+$/.test(i))}const Qe=class Qe extends Z{get[Symbol.toStringTag](){return"RenderPass"}constructor(t,i){i=Qe.normalizeProps(t,i),super(t,i,Qe.defaultProps)}static normalizeProps(t,i){return i}};f(Qe,"defaultClearColor",[0,0,0,1]),f(Qe,"defaultClearDepth",1),f(Qe,"defaultClearStencil",0),f(Qe,"defaultProps",{...Z.defaultProps,framebuffer:null,parameters:void 0,clearColor:Qe.defaultClearColor,clearColors:void 0,clearDepth:Qe.defaultClearDepth,clearStencil:Qe.defaultClearStencil,depthReadOnly:!1,stencilReadOnly:!1,discard:!1,occlusionQuerySet:void 0,timestampQuerySet:void 0,beginTimestampIndex:void 0,endTimestampIndex:void 0});let to=Qe;const Ir=class Ir extends Z{constructor(i,n){super(i,n,Ir.defaultProps);f(this,"_timeProfilingQuerySet",null);f(this,"_timeProfilingSlotCount",0);f(this,"_gpuTimeMs");this._timeProfilingQuerySet=n.timeProfilingQuerySet??null,this._timeProfilingSlotCount=0,this._gpuTimeMs=void 0}get[Symbol.toStringTag](){return"CommandEncoder"}async resolveTimeProfilingQuerySet(){if(this._gpuTimeMs=void 0,!this._timeProfilingQuerySet)return;const i=Math.floor(this._timeProfilingSlotCount/2);if(i<=0)return;const n=i*2,r=await this._timeProfilingQuerySet.readResults({firstQuery:0,queryCount:n});let s=0n;for(let o=0;o=this._timeProfilingQuerySet.props.count?n:(this._timeProfilingSlotCount+=2,{...n,timestampQuerySet:this._timeProfilingQuerySet,beginTimestampIndex:r,endTimestampIndex:r+1})}_supportsTimestampQueries(){return this.device.features.has("timestamp-query")}};f(Ir,"defaultProps",{...Z.defaultProps,measureExecutionTime:void 0,timeProfilingQuerySet:void 0});let io=Ir;const kr=class kr extends Z{get[Symbol.toStringTag](){return"CommandBuffer"}constructor(t,i){super(t,i,kr.defaultProps)}};f(kr,"defaultProps",{...Z.defaultProps});let no=kr;function ro(e){const t=so(e),i=C0[t];if(!i)throw new Error(`Unsupported variable shader type: ${e}`);return i}function y0(e){const t=Xc(e),i=P0[t];if(!i)throw new Error(`Unsupported attribute shader type: ${e}`);const[n,r]=i,s=n==="i32"||n==="u32",o=n!=="u32",a=v0[n]*r;return{primitiveType:n,components:r,byteLength:a,integer:s,signed:o}}class _0{getVariableShaderTypeInfo(t){return ro(t)}getAttributeShaderTypeInfo(t){return y0(t)}makeShaderAttributeType(t,i){return b0(t,i)}resolveAttributeShaderTypeAlias(t){return Xc(t)}resolveVariableShaderTypeAlias(t){return so(t)}}function b0(e,t){return t===1?e:`vec${t}<${e}>`}function Xc(e){return A0[e]||e}function so(e){return R0[e]||e}const T0=new _0,v0={f32:4,f16:2,i32:4,u32:4},P0={f32:["f32",1],"vec2":["f32",2],"vec3":["f32",3],"vec4":["f32",4],f16:["f16",1],"vec2":["f16",2],"vec3":["f16",3],"vec4":["f16",4],i32:["i32",1],"vec2":["i32",2],"vec3":["i32",3],"vec4":["i32",4],u32:["u32",1],"vec2":["u32",2],"vec3":["u32",3],"vec4":["u32",4]},C0={f32:{type:"f32",components:1},f16:{type:"f16",components:1},i32:{type:"i32",components:1},u32:{type:"u32",components:1},"vec2":{type:"f32",components:2},"vec3":{type:"f32",components:3},"vec4":{type:"f32",components:4},"vec2":{type:"f16",components:2},"vec3":{type:"f16",components:3},"vec4":{type:"f16",components:4},"vec2":{type:"i32",components:2},"vec3":{type:"i32",components:3},"vec4":{type:"i32",components:4},"vec2":{type:"u32",components:2},"vec3":{type:"u32",components:3},"vec4":{type:"u32",components:4},"mat2x2":{type:"f32",components:4},"mat2x3":{type:"f32",components:6},"mat2x4":{type:"f32",components:8},"mat3x2":{type:"f32",components:6},"mat3x3":{type:"f32",components:9},"mat3x4":{type:"f32",components:12},"mat4x2":{type:"f32",components:8},"mat4x3":{type:"f32",components:12},"mat4x4":{type:"f32",components:16},"mat2x2":{type:"f16",components:4},"mat2x3":{type:"f16",components:6},"mat2x4":{type:"f16",components:8},"mat3x2":{type:"f16",components:6},"mat3x3":{type:"f16",components:9},"mat3x4":{type:"f16",components:12},"mat4x2":{type:"f16",components:8},"mat4x3":{type:"f16",components:12},"mat4x4":{type:"f16",components:16},"mat2x2":{type:"i32",components:4},"mat2x3":{type:"i32",components:6},"mat2x4":{type:"i32",components:8},"mat3x2":{type:"i32",components:6},"mat3x3":{type:"i32",components:9},"mat3x4":{type:"i32",components:12},"mat4x2":{type:"i32",components:8},"mat4x3":{type:"i32",components:12},"mat4x4":{type:"i32",components:16},"mat2x2":{type:"u32",components:4},"mat2x3":{type:"u32",components:6},"mat2x4":{type:"u32",components:8},"mat3x2":{type:"u32",components:6},"mat3x3":{type:"u32",components:9},"mat3x4":{type:"u32",components:12},"mat4x2":{type:"u32",components:8},"mat4x3":{type:"u32",components:12},"mat4x4":{type:"u32",components:16}},A0={vec2i:"vec2",vec3i:"vec3",vec4i:"vec4",vec2u:"vec2",vec3u:"vec3",vec4u:"vec4",vec2f:"vec2",vec3f:"vec3",vec4f:"vec4",vec2h:"vec2",vec3h:"vec3",vec4h:"vec4"},R0={vec2i:"vec2",vec3i:"vec3",vec4i:"vec4",vec2u:"vec2",vec3u:"vec3",vec4u:"vec4",vec2f:"vec2",vec3f:"vec3",vec4f:"vec4",vec2h:"vec2",vec3h:"vec3",vec4h:"vec4",mat2x2f:"mat2x2",mat2x3f:"mat2x3",mat2x4f:"mat2x4",mat3x2f:"mat3x2",mat3x3f:"mat3x3",mat3x4f:"mat3x4",mat4x2f:"mat4x2",mat4x3f:"mat4x3",mat4x4f:"mat4x4",mat2x2i:"mat2x2",mat2x3i:"mat2x3",mat2x4i:"mat2x4",mat3x2i:"mat3x2",mat3x3i:"mat3x3",mat3x4i:"mat3x4",mat4x2i:"mat4x2",mat4x3i:"mat4x3",mat4x4i:"mat4x4",mat2x2u:"mat2x2",mat2x3u:"mat2x3",mat2x4u:"mat2x4",mat3x2u:"mat3x2",mat3x3u:"mat3x3",mat3x4u:"mat3x4",mat4x2u:"mat4x2",mat4x3u:"mat4x3",mat4x4u:"mat4x4",mat2x2h:"mat2x2",mat2x3h:"mat2x3",mat2x4h:"mat2x4",mat3x2h:"mat3x2",mat3x3h:"mat3x3",mat3x4h:"mat3x4",mat4x2h:"mat4x2",mat4x3h:"mat4x3",mat4x4h:"mat4x4"};function Yc(e,t){const i={};for(const n of e.attributes){const r=E0(e,t,n.name);r&&(i[n.name]=r)}return i}function w0(e,t,i=16){const n=Yc(e,t),r=new Array(i).fill(null);for(const s of Object.values(n))r[s.location]=s;return r}function E0(e,t,i){const n=I0(e,i),r=k0(t,i);if(!n)return null;const s=T0.getAttributeShaderTypeInfo(n.type),o=Li.getCompatibleVertexFormat(s),a=(r==null?void 0:r.vertexFormat)||o,l=Li.getVertexFormatInfo(a);return{attributeName:(r==null?void 0:r.attributeName)||n.name,bufferName:(r==null?void 0:r.bufferName)||n.name,location:n.location,shaderType:n.type,primitiveType:s.primitiveType,shaderComponents:s.components,vertexFormat:a,bufferDataType:l.type,bufferComponents:l.components,normalized:l.normalized,integer:s.integer,stepMode:(r==null?void 0:r.stepMode)||n.stepMode||"vertex",byteOffset:(r==null?void 0:r.byteOffset)||0,byteStride:(r==null?void 0:r.byteStride)||0}}function I0(e,t){const i=e.attributes.find(n=>n.name===t);return i||C.warn(`shader layout attribute "${t}" not present in shader`),i||null}function k0(e,t){D0(e);let i=F0(e,t);return i||(i=M0(e,t),i)?i:(C.warn(`layout for attribute "${t}" not present in buffer layout`),null)}function D0(e){for(const t of e)(t.attributes&&t.format||!t.attributes&&!t.format)&&C.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`)}function F0(e,t){for(const i of e)if(i.format&&i.name===t)return{attributeName:i.name,bufferName:t,stepMode:i.stepMode,vertexFormat:i.format,byteOffset:0,byteStride:i.byteStride||0};return null}function M0(e,t){var i;for(const n of e){let r=n.byteStride;if(typeof n.byteStride!="number")for(const o of n.attributes||[]){const a=Li.getVertexFormatInfo(o.format);r+=a.byteLength}const s=(i=n.attributes)==null?void 0:i.find(o=>o.attribute===t);if(s)return{attributeName:s.attribute,bufferName:n.name,stepMode:n.stepMode,vertexFormat:s.format,byteOffset:s.byteOffset,byteStride:r}}return null}const Dr=class Dr extends Z{constructor(i,n){super(i,n,Dr.defaultProps);f(this,"maxVertexAttributes");f(this,"attributeInfos");f(this,"indexBuffer",null);f(this,"attributes");this.maxVertexAttributes=i.limits.maxVertexAttributes,this.attributes=new Array(this.maxVertexAttributes).fill(null),this.attributeInfos=w0(n.shaderLayout,n.bufferLayout,this.maxVertexAttributes)}get[Symbol.toStringTag](){return"VertexArray"}setConstantWebGL(i,n){this.device.reportError(new Error("constant attributes not supported"),this)()}};f(Dr,"defaultProps",{...Z.defaultProps,shaderLayout:void 0,bufferLayout:[]});let oo=Dr;const Fr=class Fr extends Z{get[Symbol.toStringTag](){return"TransformFeedback"}constructor(t,i){super(t,i,Fr.defaultProps)}};f(Fr,"defaultProps",{...Z.defaultProps,layout:void 0,buffers:{}});let ao=Fr;const Mr=class Mr extends Z{get[Symbol.toStringTag](){return"QuerySet"}constructor(t,i){super(t,i,Mr.defaultProps)}};f(Mr,"defaultProps",{...Z.defaultProps,type:void 0,count:void 0});let lo=Mr;const Nr=class Nr extends Z{get[Symbol.toStringTag](){return"Fence"}constructor(t,i={}){super(t,i,Nr.defaultProps)}};f(Nr,"defaultProps",{...Z.defaultProps});let co=Nr;function pt(e,t){switch(t){case 1:return e;case 2:return e+e%2;default:return e+(4-e%4)%4}}function N0(e){const[,,,,t]=B0[e];return t}const B0={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]};function O0(e,t={}){const i={...e},n=t.layout??"std140",r={};let s=0;for(const[o,a]of Object.entries(i))s=uo(r,o,a,s,n);return s=pt(s,Tt(i,n)),{layout:n,byteLength:s*4,uniformTypes:i,fields:r}}function nr(e,t){const i=so(e),n=ro(i),r=/^mat(\d)x(\d)<.+>$/.exec(i);if(r){const o=Number(r[1]),a=Number(r[2]),l=qc(a,i,n.type),c=z0(l.size,l.alignment,t);return{alignment:l.alignment,size:o*c,components:o*a,columns:o,rows:a,columnStride:c,shaderType:i,type:n.type}}const s=/^vec(\d)<.+>$/.exec(i);return s?qc(Number(s[1]),i,n.type):{alignment:1,size:1,components:1,columns:1,rows:1,columnStride:1,shaderType:i,type:n.type}}function jc(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function uo(e,t,i,n,r){if(typeof i=="string"){const s=nr(i,r),o=pt(n,s.alignment);return e[t]={offset:o,...s},o+s.size}if(Array.isArray(i)){if(Array.isArray(i[0]))throw new Error(`Nested arrays are not supported for ${t}`);const s=i[0],o=i[1],a=Gc(s,r),l=pt(n,Tt(i,r));for(let c=0;c=o.length)break;l===1?t[`${i}[${c}]`]=Number(o[u]):t[`${i}[${c}]`]=X0(s,u,u+l)}}_writeLeafValue(t,i,n){const r=this.layout.fields[i];if(!r){C.warn(`Uniform ${i} not found in layout`)();return}const{type:s,components:o,columns:a,rows:l,offset:c,columnStride:u}=r,d=t[s];if(o===1){d[c]=Number(n);return}const h=n;if(a===1){for(let g=0;gs)return!1;for(let o=0;os.type==="uniform"&&s.name===(t==null?void 0:t.name));if(!n)throw new Error(t==null?void 0:t.name);const r=n;for(const s of r.uniforms||[])this.bindingLayout[s.name]=s}}setUniforms(t){for(const[i,n]of Object.entries(t))this._setUniform(i,n),this.needsRedraw||this.setNeedsRedraw(`${this.name}.${i}=${n}`)}setNeedsRedraw(t){this.needsRedraw=this.needsRedraw||t}getAllUniforms(){return this.modifiedUniforms={},this.needsRedraw=!1,this.uniforms||{}}_setUniform(t,i){j0(this.uniforms[t],i)||(this.uniforms[t]=K0(i),this.modifiedUniforms[t]=!0,this.modified=!0)}}const G0=1024;class oe{constructor(t,i){f(this,"device");f(this,"uniformBlocks",new Map);f(this,"shaderBlockLayouts",new Map);f(this,"shaderBlockWriters",new Map);f(this,"uniformBuffers",new Map);this.device=t;for(const[n,r]of Object.entries(i)){const s=n,o=O0(r.uniformTypes??{},{layout:r.layout??Z0(t)}),a=new H0(o);this.shaderBlockLayouts.set(s,o),this.shaderBlockWriters.set(s,a);const l=new q0({name:n});l.setUniforms(a.getFlatUniformValues(r.defaultUniforms||{})),this.uniformBlocks.set(s,l)}}destroy(){for(const t of this.uniformBuffers.values())t.destroy()}setUniforms(t){var i;for(const[n,r]of Object.entries(t)){const s=n,o=this.shaderBlockWriters.get(s),a=o==null?void 0:o.getFlatUniformValues(r||{});(i=this.uniformBlocks.get(s))==null||i.setUniforms(a||{})}this.updateUniformBuffers()}getUniformBufferByteLength(t){var n;const i=((n=this.shaderBlockLayouts.get(t))==null?void 0:n.byteLength)||0;return Math.max(i,G0)}getUniformBufferData(t){var r;const i=((r=this.uniformBlocks.get(t))==null?void 0:r.getAllUniforms())||{},n=this.shaderBlockWriters.get(t);return(n==null?void 0:n.getData(i))||new Uint8Array(0)}createUniformBuffer(t,i){i&&this.setUniforms(i);const n=this.getUniformBufferByteLength(t),r=this.device.createBuffer({usage:B.UNIFORM|B.COPY_DST,byteLength:n}),s=this.getUniformBufferData(t);return r.write(s),r}getManagedUniformBuffer(t){if(!this.uniformBuffers.get(t)){const i=this.getUniformBufferByteLength(t),n=this.device.createBuffer({usage:B.UNIFORM|B.COPY_DST,byteLength:i});this.uniformBuffers.set(t,n)}return this.uniformBuffers.get(t)}updateUniformBuffers(){let t=!1;for(const i of this.uniformBlocks.keys()){const n=this.updateUniformBuffer(i);t||(t=n)}return t&&C.log(3,`UniformStore.updateUniformBuffers(): ${t}`)(),t}updateUniformBuffer(t){var s;const i=this.uniformBlocks.get(t);let n=this.uniformBuffers.get(t),r=!1;if(n&&(i!=null&&i.needsRedraw)){r||(r=i.needsRedraw);const o=this.getUniformBufferData(t);n=this.uniformBuffers.get(t),n==null||n.write(o);const a=(s=this.uniformBlocks.get(t))==null?void 0:s.getAllUniforms();C.log(4,`Writing to uniform buffer ${String(t)}`,o,a)()}return r}}function Z0(e){return e.type==="webgpu"?"wgsl-uniform":"std140"}function Wi(e,t){var i;if(!e){const n=new Error(t||"shadertools: assertion failed.");throw(i=Error.captureStackTrace)==null||i.call(Error,n,Wi),n}}const ho={number:{type:"number",validate(e,t){return Number.isFinite(e)&&typeof t=="object"&&(t.max===void 0||e<=t.max)&&(t.min===void 0||e>=t.min)}},array:{type:"array",validate(e,t){return Array.isArray(e)||ArrayBuffer.isView(e)}}};function Q0(e){const t={};for(const[i,n]of Object.entries(e))t[i]=J0(n);return t}function J0(e){let t=Jc(e);if(t!=="object")return{value:e,...ho[t],type:t};if(typeof e=="object")return e?e.type!==void 0?{...e,...ho[e.type],type:e.type}:e.value===void 0?{type:"object",value:e}:(t=Jc(e.value),{...e,...ho[t],type:t}):{type:"object",value:null};throw new Error("props")}function Jc(e){return Array.isArray(e)||ArrayBuffer.isView(e)?"array":typeof e}const ey={vertex:`#ifdef MODULE_LOGDEPTH + logdepth_adjustPosition(gl_Position); +#endif +`,fragment:`#ifdef MODULE_MATERIAL + fragColor = material_filterColor(fragColor); +#endif + +#ifdef MODULE_LIGHTING + fragColor = lighting_filterColor(fragColor); +#endif + +#ifdef MODULE_FOG + fragColor = fog_filterColor(fragColor); +#endif + +#ifdef MODULE_PICKING + fragColor = picking_filterHighlightColor(fragColor); + fragColor = picking_filterPickingColor(fragColor); +#endif + +#ifdef MODULE_LOGDEPTH + logdepth_setFragDepth(); +#endif +`},eu=/void\s+main\s*\([^)]*\)\s*\{\n?/,tu=/}\n?[^{}]*$/,fo=[],or="__LUMA_INJECT_DECLARATIONS__";function ty(e){const t={vertex:{},fragment:{}};for(const i in e){let n=e[i];const r=iy(i);typeof n=="string"&&(n={order:0,injection:n}),t[r][i]=n}return t}function iy(e){const t=e.slice(0,2);switch(t){case"vs":return"vertex";case"fs":return"fragment";default:throw new Error(t)}}function ar(e,t,i,n=!1){const r=t==="vertex";for(const s in i){const o=i[s];o.sort((l,c)=>l.order-c.order),fo.length=o.length;for(let l=0,c=o.length;ll+a));break;case"vs:#main-end":r&&(e=e.replace(tu,l=>a+l));break;case"fs:#decl":r||(e=e.replace(or,a));break;case"fs:#main-start":r||(e=e.replace(eu,l=>l+a));break;case"fs:#main-end":r||(e=e.replace(tu,l=>a+l));break;default:e=e.replace(s,l=>l+a)}}return e=e.replace(or,""),n&&(e=e.replace(/\}\s*$/,s=>s+ey[t])),e}function lr(e){e.map(t=>ny(t))}function ny(e){if(e.instance)return;lr(e.dependencies||[]);const{propTypes:t={},deprecations:i=[],inject:n={}}=e,r={normalizedInjections:ty(n),parsedDeprecations:ry(i)};t&&(r.propValidators=Q0(t)),e.instance=r;let s={};t&&(s=Object.entries(t).reduce((o,[a,l])=>{const c=l==null?void 0:l.value;return c&&(o[a]=c),o},{})),e.defaultUniforms={...e.defaultUniforms,...s}}function iu(e,t,i){var n;(n=e.deprecations)==null||n.forEach(r=>{var s;(s=r.regex)!=null&&s.test(t)&&(r.deprecated?i.deprecated(r.old,r.new)():i.removed(r.old,r.new)())})}function ry(e){return e.forEach(t=>{switch(t.type){case"function":t.regex=new RegExp(`\\b${t.old}\\(`);break;default:t.regex=new RegExp(`${t.type} ${t.old};`)}}),e}function po(e){lr(e);const t={},i={};nu({modules:e,level:0,moduleMap:t,moduleDepth:i});const n=Object.keys(i).sort((r,s)=>i[s]-i[r]).map(r=>t[r]);return lr(n),n}function nu(e){const{modules:t,level:i,moduleMap:n,moduleDepth:r}=e;if(i>=5)throw new Error("Possible loop in shader dependency graph");for(const s of t)n[s.name]=s,(r[s.name]===void 0||r[s.name]]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/,oy=/((?:layout\s*\([^)]*\)\s*)*)uniform\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{([\s\S]*?)\}\s*([A-Za-z_][A-Za-z0-9_]*)?\s*;/g;function ru(e){return`${e.name}Uniforms`}function ay(e,t){const i=t==="wgsl"?e.source:t==="vertex"?e.vs:e.fs;if(!i)return null;const n=ru(e);return dy(i,t==="wgsl"?"wgsl":"glsl",n)}function ly(e,t){const i=Object.keys(e.uniformTypes||{});if(!i.length)return null;const n=ay(e,t);return n?{moduleName:e.name,uniformBlockName:ru(e),stage:t,expectedUniformNames:i,actualUniformNames:n,matches:py(i,n)}:null}function cy(e,t,i={}){var s,o;const n=ly(e,t);if(!n||n.matches)return n;const r=gy(n);return(o=(s=i.log)==null?void 0:s.error)==null||o.call(s,r,n)(),i.throwOnError!==!1&&Wi(!1,r),n}function su(e){var n;const t=[],i=my(e);for(const r of i.matchAll(oy)){const s=((n=r[1])==null?void 0:n.trim())||null;t.push({blockName:r[2],body:r[3],instanceName:r[4]||null,layoutQualifier:s,hasLayoutQualifier:!!s,isStd140:!!(s&&/\blayout\s*\([^)]*\bstd140\b[^)]*\)/.exec(s))})}return t}function uy(e,t,i,n){var o;const r=su(e).filter(a=>!a.isStd140),s=new Set;for(const a of r){if(s.has(a.blockName))continue;s.add(a.blockName);const l="",c=a.hasLayoutQualifier?`declares ${xy(a.layoutQualifier)} instead of layout(std140)`:"does not declare layout(std140)",u=`${l}${t} shader uniform block ${a.blockName} ${c}. luma.gl host-side shader block packing assumes explicit layout(std140) for GLSL uniform blocks. Add \`layout(std140)\` to the block declaration.`;(o=i==null?void 0:i.warn)==null||o.call(i,u,a)()}return r}function dy(e,t,i){const n=t==="wgsl"?hy(e,i):fy(e,i);if(!n)return null;const r=[];for(const s of n.split(` +`)){const o=s.replace(/\/\/.*$/,"").trim();if(!o||o.startsWith("#"))continue;const a=t==="wgsl"?o.match(/^([A-Za-z0-9_]+)\s*:/):o.match(sy);a&&r.push(a[1])}return r}function hy(e,t){const i=new RegExp(`\\bstruct\\s+${t}\\b`,"m").exec(e);if(!i)return null;const n=e.indexOf("{",i.index);if(n<0)return null;let r=0;for(let s=n;sn.blockName===t);return(i==null?void 0:i.body)||null}function py(e,t){if(e.length!==t.length)return!1;for(let i=0;i!i.includes(a)),r=i.filter(a=>!t.includes(a)),s=[`Expected ${t.length} fields, found ${i.length}.`],o=Sy(t,i);return o&&s.push(o),n.length&&s.push(`Missing from shader block (${n.length}): ${ou(n)}.`),r.length&&s.push(`Unexpected in shader block (${r.length}): ${ou(r)}.`),t.length<=12&&i.length<=12&&(n.length||r.length)&&(s.push(`Expected: ${t.join(", ")}.`),s.push(`Actual: ${i.join(", ")}.`)),`${e.moduleName}: ${e.stage} shader uniform block ${e.uniformBlockName} does not match module.uniformTypes. ${s.join(" ")}`}function my(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function xy(e){return e.replace(/\s+/g," ").trim()}function Sy(e,t){const i=Math.min(e.length,t.length);for(let n=0;nt.length?`Shader block ends after field ${t.length}; expected next field ${e[t.length]}.`:t.length>e.length?`Shader block has extra field ${t.length}: ${t[e.length]}.`:null}function ou(e,t=8){if(e.length<=t)return e.join(", ");const i=e.length-t;return`${e.slice(0,t).join(", ")}, ... (${i} more)`}function yy(e){switch(e==null?void 0:e.gpu.toLowerCase()){case"apple":return`#define APPLE_GPU +// Apple optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`;case"nvidia":return`#define NVIDIA_GPU +// Nvidia optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +`;case"intel":return`#define INTEL_GPU +// Intel optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +// Intel's built-in 'tan' function doesn't have acceptable precision +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`;case"amd":return`#define AMD_GPU +`;default:return`#define DEFAULT_GPU +// Prevent driver from optimizing away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +// Headless Chrome's software shader 'tan' function doesn't have acceptable precision +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// If the GPU doesn't have full 32 bits precision, will causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`}}function _y(e,t){var n;if(Number(((n=e.match(/^#version[ \t]+(\d+)/m))==null?void 0:n[1])||100)!==300)throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");switch(t){case"vertex":return e=lu(e,by),e;case"fragment":return e=lu(e,Ty),e;default:throw new Error(t)}}const au=[[/^(#version[ \t]+(100|300[ \t]+es))?[ \t]*\n/,`#version 300 es +`],[/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g,"textureLod("],[/\btexture(2D|2DProj|Cube)(EXT)?\(/g,"texture("]],by=[...au,[go("attribute"),"in $1"],[go("varying"),"out $1"]],Ty=[...au,[go("varying"),"in $1"]];function lu(e,t){for(const[i,n]of t)e=e.replace(i,n);return e}function go(e){return new RegExp(`\\b${e}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`,"g")}function cu(e,t){let i="";for(const n in e){const r=e[n];if(i+=`void ${r.signature} { +`,r.header&&(i+=` ${r.header}`),t[n]){const s=t[n];s.sort((o,a)=>o.order-a.order);for(const o of s)i+=` ${o.injection} +`}r.footer&&(i+=` ${r.footer}`),i+=`} +`}return i}function uu(e){const t={vertex:{},fragment:{}};for(const i of e){let n,r;typeof i!="string"?(n=i,r=n.hook):(n={},r=i),r=r.trim();const[s,o]=r.split(":"),a=r.replace(/\(.+/,""),l=Object.assign(n,{signature:o});switch(s){case"vs":t.vertex[a]=l;break;case"fs":t.fragment[a]=l;break;default:throw new Error(s)}}return t}function vy(e,t){return{name:Py(e,t),language:"glsl",version:Cy(e)}}function Py(e,t="unnamed"){const n=/#define[^\S\r\n]*SHADER_NAME[^\S\r\n]*([A-Za-z0-9_-]+)\s*/.exec(e);return n?n[1]:t}function Cy(e){let t=100;const i=e.match(/[^\s]+/g);if(i&&i.length>=2&&i[0]==="#version"){const n=parseInt(i[1],10);Number.isFinite(n)&&(t=n)}if(t!==100&&t!==300)throw new Error(`Invalid GLSL version ${t}`);return t}const He="(?:var<\\s*(uniform|storage(?:\\s*,\\s*[A-Za-z_][A-Za-z0-9_]*)?)\\s*>|var)\\s+([A-Za-z_][A-Za-z0-9_]*)",$e="\\s*",Vi=[new RegExp(`@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}@group\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${$e}@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}${He}`,"g")],mo=[new RegExp(`@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}@group\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${$e}@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}${He}`,"g")],Ay=[new RegExp(`@binding\\(\\s*(\\d+)\\s*\\)${$e}@group\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${$e}@binding\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g")],Ry=[new RegExp(`@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)\\s*${He}`,"g"),new RegExp(`@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${He}`,"g")];function xo(e){const t=e.split("");let i=0,n=0,r=!1,s=!1,o=!1;for(;i0){if(a==="/"&&l==="*"){t[i]=" ",t[i+1]=" ",n++,i+=2;continue}if(a==="*"&&l==="/"){t[i]=" ",t[i+1]=" ",n--,i+=2;continue}a!==` +`&&a!=="\r"&&(t[i]=" "),i++;continue}if(a==='"'){s=!0,i++;continue}if(a==="/"&&l==="/"){t[i]=" ",t[i+1]=" ",r=!0,i+=2;continue}if(a==="/"&&l==="*"){t[i]=" ",t[i+1]=" ",n=1,i+=2;continue}i++}return t.join("")}function ri(e,t){var r;const i=xo(e),n=[];for(const s of t){s.lastIndex=0;let o;for(o=s.exec(i);o;){const a=s===t[0],l=o.index,c=o[0].length;n.push({match:e.slice(l,l+c),index:l,length:c,bindingToken:o[a?1:2],groupToken:o[a?2:1],accessDeclaration:(r=o[3])==null?void 0:r.trim(),name:o[4]}),o=s.exec(i)}}return n.sort((s,o)=>s.index-o.index)}function du(e,t,i){const n=ri(e,t);if(!n.length)return e;let r="",s=0;for(const o of n)r+=e.slice(s,o.index),r+=i(o),s=o.index+o.length;return r+=e.slice(s),r}function hu(e){return/@binding\(\s*auto\s*\)/.test(xo(e))}function wy(e,t){return ri(e,t===Vi||t===mo?Ry:t).find(n=>n.bindingToken==="auto")}const fu=[new RegExp(`@binding\\(\\s*(\\d+)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${He}\\s*:\\s*([^;]+);`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(\\d+)\\s*\\)\\s*${He}\\s*:\\s*([^;]+);`,"g")];function pu(e,t=[]){var s;const i=xo(e),n=new Map;for(const o of t)n.set(gu(o.name,o.group,o.location),o.moduleName);const r=[];for(const o of fu){o.lastIndex=0;let a;for(a=o.exec(i);a;){const l=o===fu[0],c=Number(a[l?1:2]),u=Number(a[l?2:1]),d=(s=a[3])==null?void 0:s.trim(),h=a[4],p=a[5].trim(),g=n.get(gu(h,u,c));r.push(Ey({name:h,group:u,binding:c,owner:g?"module":"application",moduleName:g,accessDeclaration:d,resourceType:p})),a=o.exec(i)}}return r.sort((o,a)=>o.group!==a.group?o.group-a.group:o.binding!==a.binding?o.binding-a.binding:o.name.localeCompare(a.name))}function Ey(e){const t={name:e.name,group:e.group,binding:e.binding,owner:e.owner,kind:"unknown",moduleName:e.moduleName,resourceType:e.resourceType};if(e.accessDeclaration){const i=e.accessDeclaration.split(",").map(n=>n.trim());if(i[0]==="uniform")return{...t,kind:"uniform",access:"uniform"};if(i[0]==="storage"){const n=i[1]||"read_write";return{...t,kind:n==="read"?"read-only-storage":"storage",access:n}}}return e.resourceType==="sampler"||e.resourceType==="sampler_comparison"?{...t,kind:"sampler",samplerKind:e.resourceType==="sampler_comparison"?"comparison":"filtering"}:e.resourceType.startsWith("texture_storage_")?{...t,kind:"storage-texture",access:ky(e.resourceType),viewDimension:mu(e.resourceType)}:e.resourceType.startsWith("texture_")?{...t,kind:"texture",viewDimension:mu(e.resourceType),sampleType:Iy(e.resourceType),multisampled:e.resourceType.startsWith("texture_multisampled_")}:t}function gu(e,t,i){return`${t}:${i}:${e}`}function mu(e){if(e.includes("cube_array"))return"cube-array";if(e.includes("2d_array"))return"2d-array";if(e.includes("cube"))return"cube";if(e.includes("3d"))return"3d";if(e.includes("2d"))return"2d";if(e.includes("1d"))return"1d"}function Iy(e){if(e.startsWith("texture_depth_"))return"depth";if(e.includes(""))return"sint";if(e.includes(""))return"uint";if(e.includes(""))return"float"}function ky(e){const t=/,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(e);return t==null?void 0:t[1]}const So=` + +${or} +`,Hi=100,Dy=`precision highp float; +`;function Fy(e){const t=po(e.modules||[]),{source:i,bindingAssignments:n}=Ny(e.platformInfo,{...e,source:e.source,stage:"vertex",modules:t});return{source:i,getUniforms:Su(t),bindingAssignments:n,bindingTable:pu(i,n)}}function My(e){const{vs:t,fs:i}=e,n=po(e.modules||[]);return{vs:xu(e.platformInfo,{...e,source:t,stage:"vertex",modules:n}),fs:xu(e.platformInfo,{...e,source:i,stage:"fragment",modules:n}),getUniforms:Su(n)}}function Ny(e,t){var I;const{source:i,stage:n,modules:r,hookFunctions:s=[],inject:o={},log:a}=t;Wi(typeof i=="string","shader source must be a string");const l=i;let c="";const u=uu(s),d={},h={},p={};for(const y in o){const v=typeof o[y]=="string"?{injection:o[y],order:0}:o[y],E=/^(v|f)s:(#)?([\w-]+)$/.exec(y);if(E){const R=E[2],D=E[3];R?D==="decl"?h[y]=[v]:p[y]=[v]:d[y]=[v]}else p[y]=[v]}const g=r,x=Uy(l),T=Oy(x.source),S=Vy(g,t._bindingRegistry,T),P=[];for(const y of g){a&&iu(y,l,a);const v=zy(yu(y,"wgsl",a),y,{usedBindingsByGroup:T,bindingRegistry:t._bindingRegistry,reservedBindingKeysByGroup:S});P.push(...v.bindingAssignments);const E=v.source;c+=E;const R=((I=y.injections)==null?void 0:I[n])||{};for(const D in R){const z=/^(v|f)s:#([\w-]+)$/.exec(D);if(z){const F=z[2]==="decl"?h:p;F[D]=F[D]||[],F[D].push(R[D])}else d[D]=d[D]||[],d[D].push(R[D])}}return c+=So,c=ar(c,n,h),c+=cu(u[n],d),c+=jy(P),c+=x.source,c=ar(c,n,p),Yy(c),{source:c,bindingAssignments:P}}function xu(e,t){var E;const{source:i,stage:n,language:r="glsl",modules:s,defines:o={},hookFunctions:a=[],inject:l={},prologue:c=!0,log:u}=t;Wi(typeof i=="string","shader source must be a string");const d=r==="glsl"?vy(i).version:-1,h=e.shaderLanguageVersion,p=d===100?"#version 100":"#version 300 es",x=i.split(` +`).slice(1).join(` +`),T={};s.forEach(R=>{Object.assign(T,R.defines)}),Object.assign(T,o);let S="";switch(r){case"wgsl":break;case"glsl":S=c?`${p} + +// ----- PROLOGUE ------------------------- +${`#define SHADER_TYPE_${n.toUpperCase()}`} + +${yy(e)} +${n==="fragment"?Dy:""} + +// ----- APPLICATION DEFINES ------------------------- + +${By(T)} + +`:`${p} +`;break}const P=uu(a),I={},y={},v={};for(const R in l){const D=typeof l[R]=="string"?{injection:l[R],order:0}:l[R],z=/^(v|f)s:(#)?([\w-]+)$/.exec(R);if(z){const $=z[2],F=z[3];$?F==="decl"?y[R]=[D]:v[R]=[D]:I[R]=[D]}else v[R]=[D]}for(const R of s){u&&iu(R,x,u);const D=yu(R,n,u);S+=D;const z=((E=R.instance)==null?void 0:E.normalizedInjections[n])||{};for(const $ in z){const F=/^(v|f)s:#([\w-]+)$/.exec($);if(F){const X=F[2]==="decl"?y:v;X[$]=X[$]||[],X[$].push(z[$])}else I[$]=I[$]||[],I[$].push(z[$])}}return S+="// ----- MAIN SHADER SOURCE -------------------------",S+=So,S=ar(S,n,y),S+=cu(P[n],I),S+=x,S=ar(S,n,v),r==="glsl"&&d!==h&&(S=_y(S,n)),r==="glsl"&&uy(S,n,u),S.trim()}function Su(e){return function(i){var r;const n={};for(const s of e){const o=(r=s.getUniforms)==null?void 0:r.call(s,i,n);Object.assign(n,o)}return n}}function By(e={}){let t="";for(const i in e){const n=e[i];(n||Number.isFinite(n))&&(t+=`#define ${i.toUpperCase()} ${e[i]} +`)}return t}function yu(e,t,i){let n;switch(t){case"vertex":n=e.vs||"";break;case"fragment":n=e.fs||"";break;case"wgsl":n=e.source||"";break;default:Wi(!1)}if(!e.name)throw new Error("Shader module must have a name");cy(e,t,{log:i});const r=e.name.toUpperCase().replace(/[^0-9a-z]/gi,"_");let s=`// ----- MODULE ${e.name} --------------- + +`;return t!=="wgsl"&&(s+=`#define MODULE_${r} +`),s+=`${n} +`,s}function Oy(e){const t=new Map;for(const i of ri(e,Ay)){const n=Number(i.bindingToken),r=Number(i.groupToken);yo(r,n,i.name),si(t,r,n,`application binding "${i.name}"`)}return t}function Uy(e){const t=ri(e,mo),i=new Map;for(const s of t){if(s.bindingToken==="auto")continue;const o=Number(s.bindingToken),a=Number(s.groupToken);yo(a,o,s.name),si(i,a,o,`application binding "${s.name}"`)}const n={sawSupportedBindingDeclaration:t.length>0},r=du(e,mo,s=>Wy(s,i,n));if(hu(e)&&!n.sawSupportedBindingDeclaration)throw new Error('Unsupported @binding(auto) declaration form in application WGSL. Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.');return{source:r}}function zy(e,t,i){const n=[],s={sawSupportedBindingDeclaration:ri(e,Vi).length>0,nextHintedBindingLocation:typeof t.firstBindingSlot=="number"?t.firstBindingSlot:null},o=du(e,Vi,a=>Ly(a,{module:t,context:i,bindingAssignments:n,relocationState:s}));if(hu(e)&&!s.sawSupportedBindingDeclaration)throw new Error(`Unsupported @binding(auto) declaration form in module "${t.name}". Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.`);return{source:o,bindingAssignments:n}}function Ly(e,t){var h,p;const{module:i,context:n,bindingAssignments:r,relocationState:s}=t,{match:o,bindingToken:a,groupToken:l,name:c}=e,u=Number(l);if(a==="auto"){const g=Tu(u,i.name,c),x=(h=n.bindingRegistry)==null?void 0:h.get(g),T=x!==void 0?x:s.nextHintedBindingLocation===null?bu(u,n.usedBindingsByGroup):bu(u,n.usedBindingsByGroup,s.nextHintedBindingLocation);return _u(i.name,u,T,c),x!==void 0&&Hy(n.reservedBindingKeysByGroup,u,T,g)?(r.push({moduleName:i.name,name:c,group:u,location:T}),o.replace(/@binding\(\s*auto\s*\)/,`@binding(${T})`)):(si(n.usedBindingsByGroup,u,T,`module "${i.name}" binding "${c}"`),(p=n.bindingRegistry)==null||p.set(g,T),r.push({moduleName:i.name,name:c,group:u,location:T}),s.nextHintedBindingLocation!==null&&x===void 0&&(s.nextHintedBindingLocation=T+1),o.replace(/@binding\(\s*auto\s*\)/,`@binding(${T})`))}const d=Number(a);return _u(i.name,u,d,c),si(n.usedBindingsByGroup,u,d,`module "${i.name}" binding "${c}"`),r.push({moduleName:i.name,name:c,group:u,location:d}),o}function Wy(e,t,i){const{match:n,bindingToken:r,groupToken:s,name:o}=e,a=Number(s);if(r==="auto"){const l=Xy(a,t);return yo(a,l,o),si(t,a,l,`application binding "${o}"`),n.replace(/@binding\(\s*auto\s*\)/,`@binding(${l})`)}return i.sawSupportedBindingDeclaration=!0,n}function Vy(e,t,i){const n=new Map;if(!t)return n;for(const r of e)for(const s of $y(r)){const o=Tu(s.group,r.name,s.name),a=t.get(o);if(a!==void 0){const l=n.get(s.group)||new Map,c=l.get(a);if(c&&c!==o)throw new Error(`Duplicate WGSL binding reservation for modules "${c}" and "${o}": group ${s.group}, binding ${a}.`);si(i,s.group,a,`registered module binding "${o}"`),l.set(a,o),n.set(s.group,l)}}return n}function Hy(e,t,i,n){const r=e.get(t);if(!r)return!1;const s=r.get(i);if(!s)return!1;if(s!==n)throw new Error(`Registered module binding "${n}" collided with "${s}": group ${t}, binding ${i}.`);return!0}function $y(e){const t=[],i=e.source||"";for(const n of ri(i,Vi))t.push({name:n.name,group:Number(n.groupToken)});return t}function yo(e,t,i){if(e===0&&t>=Hi)throw new Error(`Application binding "${i}" in group 0 uses reserved binding ${t}. Application-owned explicit group-0 bindings must stay below ${Hi}.`)}function _u(e,t,i,n){if(t===0&&i0?Math.max(...n)+1:0);for(;n.has(r);)r++;return r}function Xy(e,t){const i=t.get(e)||new Set;let n=0;for(;i.has(n);)n++;return n}function Yy(e){const t=wy(e,Vi);if(!t)return;const i=Ky(e,t.index);throw i?new Error(`Unresolved @binding(auto) for module "${i}" binding "${t.name}" remained in assembled WGSL source.`):qy(e,t.index)?new Error(`Unresolved @binding(auto) for application binding "${t.name}" remained in assembled WGSL source.`):new Error(`Unresolved @binding(auto) remained in assembled WGSL source near "${Gy(t.match)}".`)}function jy(e){if(e.length===0)return"";let t=`// ----- MODULE WGSL BINDING ASSIGNMENTS --------------- +`;for(const i of e)t+=`// ${i.moduleName}.${i.name} -> @group(${i.group}) @binding(${i.location}) +`;return t+=` +`,t}function Tu(e,t,i){return`${e}:${t}:${i}`}function Ky(e,t){const i=/^\/\/ ----- MODULE ([^\n]+) ---------------$/gm;let n,r;for(r=i.exec(e);r&&r.index<=t;)n=r[1],r=i.exec(e);return n}function qy(e,t){const i=e.indexOf(So);return i>=0?t>i:!0}function Gy(e){return e.replace(/\s+/g," ").trim()}const _o="([a-zA-Z_][a-zA-Z0-9_]*)",Zy=new RegExp(`^\\s*\\#\\s*ifdef\\s*${_o}\\s*$`),Qy=new RegExp(`^\\s*\\#\\s*ifndef\\s*${_o}\\s*(?:\\/\\/.*)?$`),Jy=/^\s*\#\s*else\s*(?:\/\/.*)?$/,e_=/^\s*\#\s*endif\s*$/,t_=new RegExp(`^\\s*\\#\\s*ifdef\\s*${_o}\\s*(?:\\/\\/.*)?$`),i_=/^\s*\#\s*endif\s*(?:\/\/.*)?$/;function n_(e,t){var o,a;const i=e.split(` +`),n=[],r=[];let s=!0;for(const l of i){const c=l.match(t_)||l.match(Zy),u=l.match(Qy),d=l.match(Jy),h=l.match(i_)||l.match(e_);if(c||u){const p=(o=c||u)==null?void 0:o[1],g=!!((a=t==null?void 0:t.defines)!=null&&a[p]),x=c?g:!g,T=s&&x;r.push({parentActive:s,branchTaken:x,active:T}),s=T}else if(d){const p=r[r.length-1];if(!p)throw new Error("Encountered #else without matching #ifdef or #ifndef");p.active=p.parentActive&&!p.branchTaken,p.branchTaken=!0,s=p.active}else h?(r.pop(),s=r.length?r[r.length-1].active:!0):s&&n.push(l)}if(r.length>0)throw new Error("Unterminated conditional block in shader source");return n.join(` +`)}const Lt=class Lt{constructor(){f(this,"_hookFunctions",[]);f(this,"_defaultModules",[]);f(this,"_wgslBindingRegistry",new Map)}static getDefaultShaderAssembler(){return Lt.defaultShaderAssembler=Lt.defaultShaderAssembler||new Lt,Lt.defaultShaderAssembler}addDefaultModule(t){this._defaultModules.find(i=>i.name===(typeof t=="string"?t:t.name))||this._defaultModules.push(t)}removeDefaultModule(t){const i=typeof t=="string"?t:t.name;this._defaultModules=this._defaultModules.filter(n=>n.name!==i)}addShaderHook(t,i){i&&(t=Object.assign(i,{hook:t})),this._hookFunctions.push(t)}assembleWGSLShader(t){const i=this._getModuleList(t.modules),n=this._hookFunctions,{source:r,getUniforms:s,bindingAssignments:o}=Fy({...t,source:t.source,_bindingRegistry:this._wgslBindingRegistry,modules:i,hookFunctions:n}),a={...i.reduce((c,u)=>(Object.assign(c,u.defines),c),{}),...t.defines},l=t.platformInfo.shaderLanguage==="wgsl"?n_(r,{defines:a}):r;return{source:l,getUniforms:s,modules:i,bindingAssignments:o,bindingTable:pu(l,o)}}assembleGLSLShaderPair(t){const i=this._getModuleList(t.modules),n=this._hookFunctions;return{...My({...t,vs:t.vs,fs:t.fs,modules:i,hookFunctions:n}),modules:i}}_getModuleList(t=[]){const i=new Array(this._defaultModules.length+t.length),n={};let r=0;for(let s=0,o=this._defaultModules.length;si.name===t)||null}getAttributeNamesForBuffer(t){var i;return t.attributes?(i=t.attributes)==null?void 0:i.map(n=>n.attribute):[t.name]}mergeBufferLayouts(t,i){const n=[...t];for(const r of i){const s=n.findIndex(o=>o.name===r.name);s<0?n.push(r):n[s]=r}return n}getBufferIndex(t){const i=this.bufferLayouts.findIndex(n=>n.name===t);return i===-1&&C.warn(`BufferLayout: Missing buffer for "${t}".`)(),i}}function Cu(e,t){let i=1/0;for(const n of e){const r=t[n];r!==void 0&&(i=Math.min(i,r))}return i}function p_(e,t){const i=Object.fromEntries(e.attributes.map(r=>[r.name,r.location])),n=t.slice();return n.sort((r,s)=>{const o=r.attributes?r.attributes.map(u=>u.attribute):[r.name],a=s.attributes?s.attributes.map(u=>u.attribute):[s.name],l=Cu(o,i),c=Cu(a,i);return l-c}),n}function Au(e,t){if(!e||!t.some(n=>{var r;return(r=n.bindingLayout)==null?void 0:r.length}))return e;const i={...e,bindings:e.bindings.map(n=>({...n}))};"attributes"in(e||{})&&(i.attributes=(e==null?void 0:e.attributes)||[]);for(const n of t)for(const r of n.bindingLayout||[])for(const s of m_(r.name)){const o=i.bindings.find(a=>a.name===s);(o==null?void 0:o.group)===0&&(o.group=r.group)}return i}function g_(e){return!!(e.uniformTypes&&!x_(e.uniformTypes))}function m_(e){const t=new Set([e,`${e}Uniforms`]);return e.endsWith("Uniforms")||t.add(`${e}Sampler`),[...t]}function x_(e){for(const t in e)return!1;return!0}function S_(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function y_(e){return Array.isArray(e)?e.length===0||typeof e[0]=="number":!1}function __(e){return S_(e)||y_(e)}function b_(e){return __(e)||typeof e=="number"||typeof e=="boolean"}function T_(e,t={}){const i={bindings:{},uniforms:{}};return Object.keys(e).forEach(n=>{const r=e[n];Object.prototype.hasOwnProperty.call(t,n)||b_(r)?i.uniforms[n]=r:i.bindings[n]=r}),i}class v_{constructor(t,i){f(this,"options",{disableWarnings:!1});f(this,"modules");f(this,"moduleUniforms");f(this,"moduleBindings");Object.assign(this.options,i);const n=po(Object.values(t).filter(P_));for(const r of n)t[r.name]=r;C.log(1,"Creating ShaderInputs with modules",Object.keys(t))(),this.modules=t,this.moduleUniforms={},this.moduleBindings={};for(const[r,s]of Object.entries(t))s&&(this._addModule(s),s.name&&r!==s.name&&!this.options.disableWarnings&&C.warn(`Module name: ${r} vs ${s.name}`)())}destroy(){}setProps(t){var i;for(const n of Object.keys(t)){const r=n,s=t[r]||{},o=this.modules[r];if(!o)this.options.disableWarnings||C.warn(`Module ${n} not found`)();else{const a=this.moduleUniforms[r],l=this.moduleBindings[r],c=((i=o.getUniforms)==null?void 0:i.call(o,s,a))||s,{uniforms:u,bindings:d}=T_(c,o.uniformTypes);this.moduleUniforms[r]=Ru(a,u,o.uniformTypes),this.moduleBindings[r]={...l,...d}}}}getModules(){return Object.values(this.modules)}getUniformValues(){return this.moduleUniforms}getBindingValues(){const t={};for(const i of Object.values(this.moduleBindings))Object.assign(t,i);return t}getDebugTable(){var i;const t={};for(const[n,r]of Object.entries(this.moduleUniforms))for(const[s,o]of Object.entries(r))t[`${n}.${s}`]={type:(i=this.modules[n].uniformTypes)==null?void 0:i[s],value:String(o)};return t}_addModule(t){const i=t.name;this.moduleUniforms[i]=Ru({},t.defaultUniforms||{},t.uniformTypes),this.moduleBindings[i]={}}}function Ru(e={},t={},i={}){const n={...e};for(const[r,s]of Object.entries(t))s!==void 0&&(n[r]=Ro(e[r],s,i[r]));return n}function Ro(e,t,i){if(!i||typeof i=="string")return $i(t);if(Array.isArray(i)){if(wo(t)||!Array.isArray(t))return $i(t);const o=Array.isArray(e)&&!wo(e)?[...e]:[],a=o.slice();for(let l=0;li===void 0?void 0:$i(i)):Eo(e)?Object.fromEntries(Object.entries(e).map(([t,i])=>[t,i===void 0?void 0:$i(i)])):e}function wo(e){return ArrayBuffer.isView(e)||Array.isArray(e)&&(e.length===0||typeof e[0]=="number")}function Eo(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&!ArrayBuffer.isView(e)}function P_(e){return!!(e!=null&&e.dependencies)}const wu={"+X":0,"-X":1,"+Y":2,"-Y":3,"+Z":4,"-Z":5};function Xi(e){return e?Array.isArray(e)?e[0]??null:e:null}function C_(e){const{dimension:t,data:i}=e;if(!i)return null;switch(t){case"1d":{const n=Xi(i);if(!n)return null;const{width:r}=Yi(n);return{width:r,height:1}}case"2d":{const n=Xi(i);return n?Yi(n):null}case"3d":case"2d-array":{if(!Array.isArray(i)||i.length===0)return null;const n=Xi(i[0]);return n?Yi(n):null}case"cube":{const n=Object.keys(i)[0]??null;if(!n)return null;const r=i[n],s=Xi(r);return s?Yi(s):null}case"cube-array":{if(!Array.isArray(i)||i.length===0)return null;const n=i[0],r=Object.keys(n)[0]??null;if(!r)return null;const s=Xi(n[r]);return s?Yi(s):null}default:return null}}function Yi(e){if(qs(e))return Bc(e);if(typeof e=="object"&&"width"in e&&"height"in e)return{width:e.width,height:e.height};throw new Error("Unsupported mip-level data")}function A_(e){return typeof e=="object"&&e!==null&&"data"in e&&"width"in e&&"height"in e}function R_(e){return ArrayBuffer.isView(e)}function Eu(e){const{textureFormat:t,format:i}=e;if(t&&i&&t!==i)throw new Error(`Conflicting texture formats "${t}" and "${i}" provided for the same mip level`);return t??i}function Iu(e){const t=wu[e];if(t===void 0)throw new Error(`Invalid cube face: ${e}`);return t}function w_(e,t){return 6*e+Iu(t)}function ku(e){throw new Error("setTexture1DData not supported in WebGL.")}function E_(e){return Array.isArray(e)?e:[e]}function oi(e,t,i,n){const r=E_(t),s=e,o=[];for(let a=0;a>a),height:Math.max(1,i.height>>a),...n?{format:n}:{}},textureFormat:n,z:s,mipLevel:a});else throw new Error("Unsupported 2D mip-level payload")}return o}function Du(e){const t=[];for(let i=0;i{for(const[r,s]of Object.entries(i)){const o=w_(n,r);t.push(...oi(o,s))}}),t}const Br=class Br{constructor(t,i){f(this,"device");f(this,"id");f(this,"props");f(this,"_texture",null);f(this,"_sampler",null);f(this,"_view",null);f(this,"ready");f(this,"isReady",!1);f(this,"destroyed",!1);f(this,"resolveReady",()=>{});f(this,"rejectReady",()=>{});this.device=t;const n=vo("dynamic-texture"),r=i;this.props={...Br.defaultProps,id:n,...i,data:null},this.id=this.props.id,this.ready=new Promise((s,o)=>{this.resolveReady=s,this.rejectReady=o}),this.initAsync(r)}get texture(){if(!this._texture)throw new Error("Texture not initialized yet");return this._texture}get sampler(){if(!this._sampler)throw new Error("Sampler not initialized yet");return this._sampler}get view(){if(!this._view)throw new Error("View not initialized yet");return this._view}get[Symbol.toStringTag](){return"DynamicTexture"}toString(){var n,r;const t=((n=this._texture)==null?void 0:n.width)??this.props.width??"?",i=((r=this._texture)==null?void 0:r.height)??this.props.height??"?";return`DynamicTexture:"${this.id}":${t}x${i}px:(${this.isReady?"ready":"loading..."})`}async initAsync(t){try{const i=await this._loadAllData(t);this._checkNotDestroyed();const n=i.data?I_({...i,width:t.width,height:t.height,format:t.format}):[],r="format"in t&&t.format!==void 0,s="usage"in t&&t.usage!==void 0,a=(()=>{if(this.props.width&&this.props.height)return{width:this.props.width,height:this.props.height};const x=C_(i);return x||{width:this.props.width||1,height:this.props.height||1}})();if(!a||a.width<=0||a.height<=0)throw new Error(`${this} size could not be determined or was zero`);const l=k_(this.device,n,a,{format:r?t.format:void 0}),c=l.format??this.props.format,u={...this.props,...a,format:c,mipLevels:1,data:void 0};this.device.isTextureFormatCompressed(c)&&!s&&(u.usage=M.SAMPLE|M.COPY_DST);const d=this.props.mipmaps&&!l.hasExplicitMipChain&&!this.device.isTextureFormatCompressed(c);if(this.device.type==="webgpu"&&d){const x=this.props.dimension==="3d"?M.SAMPLE|M.STORAGE|M.COPY_DST|M.COPY_SRC:M.SAMPLE|M.RENDER|M.COPY_DST|M.COPY_SRC;u.usage|=x}const h=this.device.getMipLevelCount(u.width,u.height),p=l.hasExplicitMipChain?l.mipLevels:this.props.mipLevels==="auto"?h:Math.max(1,Math.min(h,this.props.mipLevels??1)),g={...u,mipLevels:p};this._texture=this.device.createTexture(g),this._sampler=this.texture.sampler,this._view=this.texture.view,l.subresources.length&&this._setTextureSubresources(l.subresources),this.props.mipmaps&&!l.hasExplicitMipChain&&!d&&C.warn(`${this} skipping auto-generated mipmaps for compressed texture format`)(),d&&this.generateMipmaps(),this.isReady=!0,this.resolveReady(this.texture),C.info(0,`${this} created`)()}catch(i){const n=i instanceof Error?i:new Error(String(i));this.rejectReady(n)}}destroy(){this._texture&&(this._texture.destroy(),this._texture=null,this._sampler=null,this._view=null),this.destroyed=!0}generateMipmaps(){this.device.type==="webgl"?this.texture.generateMipmapsWebGL():this.device.type==="webgpu"?this.device.generateMipmapsWebGPU(this.texture):C.warn(`${this} mipmaps not supported on ${this.device.type}`)}setSampler(t={}){this._checkReady();const i=t instanceof ni?t:this.device.createSampler(t);this.texture.setSampler(i),this._sampler=i}async readBuffer(t={}){this.isReady||await this.ready;const i=t.width??this.texture.width,n=t.height??this.texture.height,r=t.depthOrArrayLayers??this.texture.depth,s=this.texture.computeMemoryLayout({width:i,height:n,depthOrArrayLayers:r}),o=this.device.createBuffer({byteLength:s.byteLength,usage:B.COPY_DST|B.MAP_READ});this.texture.readBuffer({...t,width:i,height:n,depthOrArrayLayers:r},o);const a=this.device.createFence();return await a.signaled,a.destroy(),o}async readAsync(t={}){this.isReady||await this.ready;const i=t.width??this.texture.width,n=t.height??this.texture.height,r=t.depthOrArrayLayers??this.texture.depth,s=this.texture.computeMemoryLayout({width:i,height:n,depthOrArrayLayers:r}),o=await this.readBuffer(t),a=await o.readAsync(0,s.byteLength);return o.destroy(),a.buffer}resize(t){if(this._checkReady(),t.width===this.texture.width&&t.height===this.texture.height)return!1;const i=this.texture;return this._texture=i.clone(t),this._sampler=this.texture.sampler,this._view=this.texture.view,i.destroy(),C.info(`${this} resized`),!0}getCubeFaceIndex(t){const i=wu[t];if(i===void 0)throw new Error(`Invalid cube face: ${t}`);return i}getCubeArrayFaceIndex(t,i){return 6*t+this.getCubeFaceIndex(i)}setTexture1DData(t){if(this._checkReady(),this.texture.props.dimension!=="1d")throw new Error(`${this} is not 1d`);const i=ku();this._setTextureSubresources(i)}setTexture2DData(t,i=0){if(this._checkReady(),this.texture.props.dimension!=="2d")throw new Error(`${this} is not 2d`);const n=oi(i,t);this._setTextureSubresources(n)}setTexture3DData(t){if(this.texture.props.dimension!=="3d")throw new Error(`${this} is not 3d`);const i=Du(t);this._setTextureSubresources(i)}setTextureArrayData(t){if(this.texture.props.dimension!=="2d-array")throw new Error(`${this} is not 2d-array`);const i=Fu(t);this._setTextureSubresources(i)}setTextureCubeData(t){if(this.texture.props.dimension!=="cube")throw new Error(`${this} is not cube`);const i=Mu(t);this._setTextureSubresources(i)}setTextureCubeArrayData(t){if(this.texture.props.dimension!=="cube-array")throw new Error(`${this} is not cube-array`);const i=Nu(t);this._setTextureSubresources(i)}_setTextureSubresources(t){for(const i of t){const{z:n,mipLevel:r}=i;switch(i.type){case"external-image":const{image:s,flipY:o}=i;this.texture.copyExternalImage({image:s,z:n,mipLevel:r,flipY:o});break;case"texture-data":const{data:a,textureFormat:l}=i;if(l&&l!==this.texture.format)throw new Error(`${this} mip level ${r} uses format "${l}" but texture format is "${this.texture.format}"`);this.texture.writeData(a.data,{x:0,y:0,z:n,width:a.width,height:a.height,depthOrArrayLayers:1,mipLevel:r});break;default:throw new Error("Unsupported 2D mip-level payload")}}}async _loadAllData(t){const i=await Io(t.data);return{dimension:t.dimension??"2d",data:i??null}}_checkNotDestroyed(){this.destroyed&&C.warn(`${this} already destroyed`)}_checkReady(){this.isReady||C.warn(`${this} Cannot perform this operation before ready`)}};f(Br,"defaultProps",{...M.defaultProps,dimension:"2d",data:null,mipmaps:!1});let ai=Br;function I_(e){if(!e.data)return[];const t=e.width&&e.height?{width:e.width,height:e.height}:void 0,i="format"in e?e.format:void 0;switch(e.dimension){case"1d":return ku();case"2d":return oi(0,e.data,t,i);case"3d":return Du(e.data);case"2d-array":return Fu(e.data);case"cube":return Mu(e.data);case"cube-array":return Nu(e.data);default:throw new Error(`Unhandled dimension ${e.dimension}`)}}function k_(e,t,i,n){if(t.length===0)return{subresources:t,mipLevels:1,format:n.format,hasExplicitMipChain:!1};const r=new Map;for(const u of t){const d=r.get(u.z)??[];d.push(u),r.set(u.z,d)}const s=t.some(u=>u.mipLevel>0);let o=n.format,a=Number.POSITIVE_INFINITY;const l=[];for(const[u,d]of r){const h=[...d].sort((P,I)=>P.mipLevel-I.mipLevel),p=h[0];if(!p||p.mipLevel!==0)throw new Error(`DynamicTexture: slice ${u} is missing mip level 0`);const g=Ou(e,p);if(g.width!==i.width||g.height!==i.height)throw new Error(`DynamicTexture: slice ${u} base level dimensions ${g.width}x${g.height} do not match expected ${i.width}x${i.height}`);const x=Bu(p);if(x){if(o&&o!==x)throw new Error(`DynamicTexture: slice ${u} base level format "${x}" does not match texture format "${o}"`);o=x}const T=o&&e.isTextureFormatCompressed(o)?D_(e,g.width,g.height,o):e.getMipLevelCount(g.width,g.height);let S=0;for(let P=0;P=T)break;const y=Ou(e,I),v=Math.max(1,g.width>>P),E=Math.max(1,g.height>>P);if(y.width!==v||y.height!==E)break;const R=Bu(I);if(R&&(o||(o=R),R!==o))break;S++,l.push(I)}a=Math.min(a,S)}const c=Number.isFinite(a)?Math.max(1,a):1;return{subresources:l.filter(u=>u.mipLevel>a),c=Math.max(1,i>>a);if(l[h.name,h]))||[]),r=i.shaderInputs||new v_(n,{disableWarnings:this.props.disableWarnings});this.setShaderInputs(r);const s=M_(t),o=(((c=this.props.modules)==null?void 0:c.length)>0?this.props.modules:(u=this.shaderInputs)==null?void 0:u.getModules())||[];if(this.props.shaderLayout=Au(this.props.shaderLayout,o)||null,this.device.type==="webgpu"&&this.props.source){const{source:h,getUniforms:p,bindingTable:g}=this.props.shaderAssembler.assembleWGSLShader({platformInfo:s,...this.props,modules:o});this.source=h,this._getModuleUniforms=p,this._bindingTable=g;const x=(d=t.getShaderLayout)==null?void 0:d.call(t,this.source);this.props.shaderLayout=Au(this.props.shaderLayout||x||null,o)||null}else{const{vs:h,fs:p,getUniforms:g}=this.props.shaderAssembler.assembleGLSLShaderPair({platformInfo:s,...this.props,modules:o});this.vs=h,this.fs=p,this._getModuleUniforms=g,this._bindingTable=[]}this.vertexCount=this.props.vertexCount,this.instanceCount=this.props.instanceCount,this.topology=this.props.topology,this.bufferLayout=this.props.bufferLayout,this.parameters=this.props.parameters,i.geometry&&this.setGeometry(i.geometry),this.pipelineFactory=i.pipelineFactory||Js.getDefaultPipelineFactory(this.device),this.shaderFactory=i.shaderFactory||eo.getDefaultShaderFactory(this.device),this.pipeline=this._updatePipeline(),this.vertexArray=t.createVertexArray({shaderLayout:this.pipeline.shaderLayout,bufferLayout:this.pipeline.bufferLayout}),this._gpuGeometry&&this._setGeometryAttributes(this._gpuGeometry),"isInstanced"in i&&(this.isInstanced=i.isInstanced),i.instanceCount&&this.setInstanceCount(i.instanceCount),i.vertexCount&&this.setVertexCount(i.vertexCount),i.indexBuffer&&this.setIndexBuffer(i.indexBuffer),i.attributes&&this.setAttributes(i.attributes),i.constantAttributes&&this.setConstantAttributes(i.constantAttributes),i.bindings&&this.setBindings(i.bindings),i.transformFeedback&&(this.transformFeedback=i.transformFeedback)}get[Symbol.toStringTag](){return"Model"}toString(){return`Model(${this.id})`}destroy(){var t;this._destroyed||(this.pipelineFactory.release(this.pipeline),this.shaderFactory.release(this.pipeline.vs),this.pipeline.fs&&this.pipeline.fs!==this.pipeline.vs&&this.shaderFactory.release(this.pipeline.fs),this._uniformStore.destroy(),(t=this._gpuGeometry)==null||t.destroy(),this._destroyed=!0)}needsRedraw(){this._getBindingsUpdateTimestamp()>this._lastDrawTimestamp&&this.setNeedsRedraw("contents of bound textures or buffers updated");const t=this._needsRedraw;return this._needsRedraw=!1,t}setNeedsRedraw(t){this._needsRedraw||(this._needsRedraw=t)}getBindingDebugTable(){return this._bindingTable}predraw(){this.updateShaderInputs(),this.pipeline=this._updatePipeline()}draw(t){const i=this._areBindingsLoading();if(i)return C.info(vt,`>>> DRAWING ABORTED ${this.id}: ${i} not loaded`)(),!1;try{t.pushDebugGroup(`${this}.predraw(${t})`),this.predraw()}finally{t.popDebugGroup()}let n,r=this.pipeline.isErrored;try{if(t.pushDebugGroup(`${this}.draw(${t})`),this._logDrawCallStart(),this.pipeline=this._updatePipeline(),r=this.pipeline.isErrored,r)C.info(vt,`>>> DRAWING ABORTED ${this.id}: ${Uu}`)(),n=!1;else{const s=this._getBindings(),o=this._getBindGroups(),{indexBuffer:a}=this.vertexArray,l=a?a.byteLength/(a.indexType==="uint32"?4:2):void 0;n=this.pipeline.draw({renderPass:t,vertexArray:this.vertexArray,isInstanced:this.isInstanced,vertexCount:this.vertexCount,instanceCount:this.instanceCount,indexCount:l,transformFeedback:this.transformFeedback||void 0,bindings:s,bindGroups:o,_bindGroupCacheKeys:this._getBindGroupCacheKeys(),uniforms:this.props.uniforms,parameters:this.parameters,topology:this.topology})}}finally{t.popDebugGroup(),this._logDrawCallEnd()}return this._logFramebuffer(t),n?(this._lastDrawTimestamp=this.device.timestamp,this._needsRedraw=!1):r?this._needsRedraw=Uu:this._needsRedraw="waiting for resource initialization",n}setGeometry(t){var n;(n=this._gpuGeometry)==null||n.destroy();const i=t&&r_(this.device,t);if(i){this.setTopology(i.topology||"triangle-list");const r=new Ao(this.bufferLayout);this.bufferLayout=r.mergeBufferLayouts(i.bufferLayout,this.bufferLayout),this.vertexArray&&this._setGeometryAttributes(i)}this._gpuGeometry=i}setTopology(t){t!==this.topology&&(this.topology=t,this._setPipelineNeedsUpdate("topology"))}setBufferLayout(t){const i=new Ao(this.bufferLayout);this.bufferLayout=this._gpuGeometry?i.mergeBufferLayouts(t,this._gpuGeometry.bufferLayout):t,this._setPipelineNeedsUpdate("bufferLayout"),this.pipeline=this._updatePipeline(),this.vertexArray=this.device.createVertexArray({shaderLayout:this.pipeline.shaderLayout,bufferLayout:this.pipeline.bufferLayout}),this._gpuGeometry&&this._setGeometryAttributes(this._gpuGeometry)}setParameters(t){Co(t,this.parameters,2)||(this.parameters=t,this._setPipelineNeedsUpdate("parameters"))}setInstanceCount(t){this.instanceCount=t,this.isInstanced===void 0&&t>0&&(this.isInstanced=!0),this.setNeedsRedraw("instanceCount")}setVertexCount(t){this.vertexCount=t,this.setNeedsRedraw("vertexCount")}setShaderInputs(t){var i;this.shaderInputs=t,this._uniformStore=new oe(this.device,this.shaderInputs.modules);for(const[n,r]of Object.entries(this.shaderInputs.modules))if(g_(r)&&!((i=this.material)!=null&&i.ownsModule(n))){const s=this._uniformStore.getManagedUniformBuffer(n);this.bindings[`${n}Uniforms`]=s}this.setNeedsRedraw("shaderInputs")}setMaterial(t){this.material=t,this.setNeedsRedraw("material")}updateShaderInputs(){this._uniformStore.setUniforms(this.shaderInputs.getUniformValues()),this.setBindings(this._getNonMaterialBindings(this.shaderInputs.getBindingValues())),this.setNeedsRedraw("shaderInputs")}setBindings(t){Object.assign(this.bindings,t),this.setNeedsRedraw("bindings")}setTransformFeedback(t){this.transformFeedback=t,this.setNeedsRedraw("transformFeedback")}setIndexBuffer(t){this.vertexArray.setIndexBuffer(t),this.setNeedsRedraw("indexBuffer")}setAttributes(t,i){const n=(i==null?void 0:i.disableWarnings)??this.props.disableWarnings;t.indices&&C.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)(),this.bufferLayout=p_(this.pipeline.shaderLayout,this.bufferLayout);const r=new Ao(this.bufferLayout);for(const[s,o]of Object.entries(t)){const a=r.getBufferLayout(s);if(!a){n||C.warn(`Model(${this.id}): Missing layout for buffer "${s}".`)();continue}const l=r.getAttributeNamesForBuffer(a);let c=!1;for(const u of l){const d=this._attributeInfos[u];if(d){const h=this.device.type==="webgpu"?r.getBufferIndex(d.bufferName):d.location;this.vertexArray.setBuffer(h,o),c=!0}}!c&&!n&&C.warn(`Model(${this.id}): Ignoring buffer "${o.id}" for unknown attribute "${s}"`)()}this.setNeedsRedraw("attributes")}setConstantAttributes(t,i){for(const[n,r]of Object.entries(t)){const s=this._attributeInfos[n];s?this.vertexArray.setConstantWebGL(s.location,r):((i==null?void 0:i.disableWarnings)??this.props.disableWarnings)||C.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${n}"`)()}this.setNeedsRedraw("constants")}_areBindingsLoading(){var t;for(const i of Object.values(this.bindings))if(i instanceof ai&&!i.isReady)return i.id;for(const i of Object.values(((t=this.material)==null?void 0:t.bindings)||{}))if(i instanceof ai&&!i.isReady)return i.id;return!1}_getBindings(){const t={};for(const[i,n]of Object.entries(this.bindings))n instanceof ai?n.isReady&&(t[i]=n.texture):t[i]=n;return t}_getBindGroups(){var n;const t=((n=this.pipeline)==null?void 0:n.shaderLayout)||this.props.shaderLayout||{bindings:[]},i=t.bindings.length?Hc(t,this._getBindings()):{0:this._getBindings()};if(!this.material)return i;for(const[r,s]of Object.entries(this.material.getBindingsByGroup())){const o=Number(r);i[o]={...i[o]||{},...s}}return i}_getBindGroupCacheKeys(){var i;const t=(i=this.material)==null?void 0:i.getBindGroupCacheKey(3);return t?{3:t}:{}}_getBindingsUpdateTimestamp(){var i;let t=0;for(const n of Object.values(this.bindings))n instanceof Jn?t=Math.max(t,n.texture.updateTimestamp):n instanceof B||n instanceof M?t=Math.max(t,n.updateTimestamp):n instanceof ai?t=n.texture?Math.max(t,n.texture.updateTimestamp):1/0:n instanceof ni||(t=Math.max(t,n.buffer.updateTimestamp));return Math.max(t,((i=this.material)==null?void 0:i.getBindingsUpdateTimestamp())||0)}_setGeometryAttributes(t){const i={...t.attributes};for(const[n]of Object.entries(i))!this.pipeline.shaderLayout.attributes.find(r=>r.name===n)&&n!=="positions"&&delete i[n];this.vertexCount=t.vertexCount,this.setIndexBuffer(t.indices||null),this.setAttributes(t.attributes,{disableWarnings:!0}),this.setAttributes(i,{disableWarnings:this.props.disableWarnings}),this.setNeedsRedraw("geometry attributes")}_setPipelineNeedsUpdate(t){this._pipelineNeedsUpdate||(this._pipelineNeedsUpdate=t),this.setNeedsRedraw(t)}_updatePipeline(){if(this._pipelineNeedsUpdate){let t=null,i=null;this.pipeline&&(C.log(1,`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)(),t=this.pipeline.vs,i=this.pipeline.fs),this._pipelineNeedsUpdate=!1;const n=this.shaderFactory.createShader({id:`${this.id}-vertex`,stage:"vertex",source:this.source||this.vs,debugShaders:this.props.debugShaders});let r=null;this.source?r=n:this.fs&&(r=this.shaderFactory.createShader({id:`${this.id}-fragment`,stage:"fragment",source:this.source||this.fs,debugShaders:this.props.debugShaders})),this.pipeline=this.pipelineFactory.createRenderPipeline({...this.props,bindings:void 0,bufferLayout:this.bufferLayout,topology:this.topology,parameters:this.parameters,bindGroups:this._getBindGroups(),vs:n,fs:r}),this._attributeInfos=Yc(this.pipeline.shaderLayout,this.bufferLayout),t&&this.shaderFactory.release(t),i&&i!==t&&this.shaderFactory.release(i)}return this.pipeline}_logDrawCallStart(){const t=C.level>3?0:F_;C.level<2||Date.now()-this._lastLogTime>> DRAWING MODEL ${this.id}`,{collapsed:C.level<=2})())}_logDrawCallEnd(){if(this._logOpen){const t=a_(this.pipeline.shaderLayout,this.id);C.table(vt,t)();const i=this.shaderInputs.getDebugTable();C.table(vt,i)();const n=this._getAttributeDebugTable();C.table(vt,this._attributeInfos)(),C.table(vt,n)(),C.groupEnd(vt)(),this._logOpen=!1}}_logFramebuffer(t){const i=this.device.props.debugFramebuffers;if(this._drawCount++,!i)return;const n=t.props.framebuffer;l_(t,n,{id:(n==null?void 0:n.id)||`${this.id}-framebuffer`,minimap:!0})}_getAttributeDebugTable(){const t={};for(const[i,n]of Object.entries(this._attributeInfos)){const r=this.vertexArray.attributes[n.location];t[n.location]={name:i,type:n.shaderType,values:r?this._getBufferOrConstantValues(r,n.bufferDataType):"null"}}if(this.vertexArray.indexBuffer){const{indexBuffer:i}=this.vertexArray,n=i.indexType==="uint32"?new Uint32Array(i.debugData):new Uint16Array(i.debugData);t.indices={name:"indices",type:i.indexType,values:n.toString()}}return t}_getBufferOrConstantValues(t,i){const n=Nt.getTypedArrayConstructor(i);return(t instanceof B?new n(t.debugData):t).toString()}_getNonMaterialBindings(t){if(!this.material)return t;const i={};for(const[n,r]of Object.entries(t))this.material.ownsBinding(n)||(i[n]=r);return i}};f(Or,"defaultProps",{...bt.defaultProps,source:void 0,vs:null,fs:null,id:"unnamed",handle:void 0,userData:{},defines:{},modules:[],geometry:null,indexBuffer:null,attributes:{},constantAttributes:{},bindings:{},uniforms:{},varyings:[],isInstanced:void 0,instanceCount:0,vertexCount:0,shaderInputs:void 0,material:void 0,pipelineFactory:void 0,shaderFactory:void 0,transformFeedback:void 0,shaderAssembler:bo.getDefaultShaderAssembler(),debugShaders:void 0,disableWarnings:void 0});let ee=Or;function M_(e){return{type:e.type,shaderLanguage:e.info.shadingLanguage,shaderLanguageVersion:e.info.shadingLanguageVersion,gpu:e.info.gpu,features:e.features}}const te=Object.freeze({blend:!1,depthWriteEnabled:!1,depthCompare:"always",stencilCompare:"always",cullMode:"none",frontFace:"ccw"});class gt{constructor(t,i,n,r,s){this._debugRandomNumber=Math.floor(Math.random()*1e3),this.device=t,this.config=i,this.store=n,this.data=r,s&&(this.points=s)}}const zu={name:"conicParametricCurve",vs:` +vec2 conicParametricCurve(vec2 A, vec2 B, vec2 ControlPoint, float t, float w) { + vec2 divident = (1.0 - t) * (1.0 - t) * A + 2.0 * (1.0 - t) * t * w * ControlPoint + t * t * B; + float divisor = (1.0 - t) * (1.0 - t) + 2.0 * (1.0 - t) * t * w + t * t; + return divident / divisor; +} +`},ur={name:"pickingColor",fs:` +vec3 encodePickingColor(float index) { + float i = index + 1.0; + return vec3(mod(i, 256.0), mod(floor(i / 256.0), 256.0), floor(i / 65536.0)) / 255.0; +} +`},N_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgbaColor; +in vec2 pos; +in float arrowLength; +in float useArrow; +in float smoothing; +in float arrowWidthFactor; +in float linkIndex; +flat in float vLinkStyle; +flat in float vLinkDashSpan; +flat in float vLinkDashWidth; +flat in vec4 vEndpointColorA; +flat in vec4 vEndpointColorB; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawLineFragmentUniforms { + float renderMode; + float linkDashLength; + float linkDashGap; + float linkColorInterpolateFromEndpoints; + float hoveredLinkIndex; + vec4 hoveredLinkColor; + float linkBlending; + float pickingAlpha; + float pickingIndexOffset; +} drawLineFrag; + +#define renderMode drawLineFrag.renderMode +#define linkDashLength drawLineFrag.linkDashLength +#define linkDashGap drawLineFrag.linkDashGap +#define linkColorInterpolateFromEndpoints drawLineFrag.linkColorInterpolateFromEndpoints +#define hoveredLinkIndex drawLineFrag.hoveredLinkIndex +#define hoveredLinkColor drawLineFrag.hoveredLinkColor +#define linkBlending drawLineFrag.linkBlending +#define pickingAlpha drawLineFrag.pickingAlpha +#define pickingIndexOffset drawLineFrag.pickingIndexOffset +#else +// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking, 3.0 = host picking colors +uniform float renderMode; +uniform float linkDashLength; +uniform float linkDashGap; +uniform float linkColorInterpolateFromEndpoints; +uniform float hoveredLinkIndex; +uniform vec4 hoveredLinkColor; +uniform float linkBlending; +uniform float pickingAlpha; +uniform float pickingIndexOffset; +#endif + +out vec4 fragColor; + +float map(float value, float min1, float max1, float min2, float max2) { + return min2 + (value - min1) * (max2 - min2) / (max1 - min1); +} + +// LinkStyle enum values (must match \`LinkStyle\` in modules/GraphData). Compared with +// exact equality, like the point shapes: the CPU sanitizer guarantees exact integers +// and vLinkStyle is flat, so an unknown future style matches nothing and renders solid. +const float LINK_STYLE_DASHED = 1.0; +const float LINK_STYLE_DOTTED = 2.0; + +// Anti-aliased on/off mask for one dash period. \`phase\` is distance-along-line in px, +// \`on\` is the lit dash length, \`period\` is on + gap, \`aa\` is the smoothing half-width in px. +float strokeMask(float phase, float on, float period, float aa) { + float m = mod(phase, period); + return smoothstep(-aa, aa, m) * (1.0 - smoothstep(on - aa, on + aa, m)); +} + +void main() { + // Geometric coverage only (stroke / arrow / dash). Color alpha is applied after. + float coverage = 1.0; + vec3 color = rgbaColor.rgb; + + // Arrowhead extent along the link (pos.x space) — used by the arrow rendering + // and by the dash mask, which leaves the arrowhead solid. + float end_arrow = 0.5 + arrowLength / 2.0; + float start_arrow = end_arrow - arrowLength; + + // Gradient links: interpolate RGB from the source point color to the target point color + // along the link. Opacity (visibility / greyout) still comes from rgbaColor.a. + if (linkColorInterpolateFromEndpoints > 0.5) { + color = mix(vEndpointColorA.rgb, vEndpointColorB.rgb, clamp(pos.x, 0.0, 1.0)); + } + + if (useArrow > 0.5) { + // pos.y spans the quad, which is the arrow width plus a ramp. arrowWidthFactor is a fraction + // of the arrow width alone, so edges derived from it scale by (1 - smoothing) = arrow / quad. + float preRamp = 1.0 - smoothing; + float bodyEdge = (0.5 - arrowWidthFactor / 2.0) * preRamp; + float headBase = 0.5 * preRamp; + // Body edge, ramp centred on it as for the plain stroke. + float linkCoverage = smoothstep(bodyEdge + smoothing / 2.0, bodyEdge - smoothing / 2.0, abs(pos.y)); + float arrowCoverage = 1.0; + if (pos.x > start_arrow && pos.x < start_arrow + arrowLength) { + // Arrowhead taper, from headBase at its base to the centreline at its tip; ramp centred on it. + float taper = headBase * (1.0 - map(pos.x, start_arrow, end_arrow, 0.0, 1.0)); + arrowCoverage = 1.0 - smoothstep(taper - smoothing / 2.0, taper + smoothing / 2.0, abs(pos.y)); + if (linkCoverage != arrowCoverage) { + linkCoverage = max(linkCoverage, arrowCoverage); + } + } + coverage = linkCoverage; + } else coverage = smoothstep(0.5, 0.5 - smoothing, abs(pos.y)); + + // Dashed / dotted stroke patterns. Applied to the visible pass only (renderMode == 0.0) + // so that gaps stay fully pickable in the index pass. The arrowhead region is left solid. + if (renderMode < 0.5 && (vLinkStyle == LINK_STYLE_DASHED || vLinkStyle == LINK_STYLE_DOTTED)) { + bool inArrowHead = (useArrow > 0.5) && (pos.x > start_arrow) && (pos.x < end_arrow); + if (!inArrowHead) { + // Distance along the link in the dash pattern's space (screen px or world units; see the vertex shader). + // fwidth() gives the screen-space rate of change, so the ramp is EDGE_RAMP_PX device pixels in either space. + float phase = clamp(pos.x, 0.0, 1.0) * vLinkDashSpan; + if (vLinkStyle == LINK_STYLE_DASHED) { + float period = max(linkDashLength + linkDashGap, 0.001); + // Half a ramp in the pattern's units: fwidth(phase) is the change in phase per device pixel. + float aa = max(fwidth(phase), 1e-4) * (EDGE_RAMP_PX * 0.5); + coverage *= strokeMask(phase, linkDashLength, period, aa); + } else { + // Dotted: round dots sized to the stroke, the quad less its ramp; spaced by diameter + gap. + float diameter = vLinkDashWidth * (1.0 - smoothing); + if (linkBlending < 0.5) { + // Unblended keeps only pixels whose centre is inside the dot. A dot under √2 device + // px can miss every pixel centre and vanish; at √2 it always holds one. Pattern units + // per device pixel from the phase's gradient (the pattern space is isotropic). + float pxInPattern = max(length(vec2(dFdx(phase), dFdy(phase))), 1e-4); + diameter = max(diameter, 1.4142136 * pxInPattern); + } + float period = max(diameter + linkDashGap, 0.001); + float localX = mod(phase, period) - period * 0.5; + float localY = pos.y * vLinkDashWidth; + float r = length(vec2(localX, localY)); + // Half a ramp in the pattern's units: fwidth(r) is the change in r per device pixel. + float aa = max(fwidth(r), 1e-4) * (EDGE_RAMP_PX * 0.5); + coverage *= 1.0 - smoothstep(diameter * 0.5 - aa, diameter * 0.5 + aa, r); + } + } + } + + float opacity = rgbaColor.a * coverage; + + // Apply hover color if this is the hovered link and hover color is defined. + // Done last — after the gradient and the dash mask — so hover wins over every + // color source (per-link color from the vertex stage and the endpoint gradient + // alike), while the dash pattern and AA stay intact in the hover color. + if (hoveredLinkIndex == linkIndex && hoveredLinkColor.a > -0.5) { + color = hoveredLinkColor.rgb; + opacity *= hoveredLinkColor.a; + } + + if (renderMode > 2.5) { + // Host picking: the link's index and the host's alpha, where the stroke covers at + // least half the fragment and the link is not fully transparent; dash gaps stay + // pickable, as in the engine's own index pass + if (coverage < 0.5 || rgbaColor.a <= 0.0) discard; + fragColor = vec4(encodePickingColor(linkIndex + pickingIndexOffset), pickingAlpha); + } else if (renderMode > 0.0) { + if (opacity <= 0.0) discard; + fragColor = vec4(linkIndex, 0.0, 0.0, 1.0); + } else if (linkBlending < 0.5) { + // Unblended: opaque, hard edges. Soft fringes would write full RGB with partial + // alpha; canvas compositing treats that as premultiplied and the edge reads + // brighter than the solid core. Every fade is centred on its geometric edge, so + // coverage 0.5 is that edge: keep the pixels whose centre is inside the stroke. + // The vertex stage keeps unblended strokes at least a device pixel wide. + if (coverage < 0.5 || opacity <= 0.0) discard; + fragColor = vec4(color, 1.0); + } else { + fragColor = vec4(color, opacity); + } + +} +`,B_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 position, pointA, pointB; +in vec4 sourceColor; +in vec4 targetColor; +in float sourceWidth; +in float targetWidth; +in float arrow; +in float linkIndices; +in float linkStyle; + +uniform sampler2D positionsTexture; +uniform sampler2D linkStatus; +uniform sampler2D exitTexture; +uniform sampler2D pointColorsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawLineUniforms { + mat4 transformationMatrix; + float widthScale; + float linkArrowsSizeScale; + float spaceSize; + vec2 screenSize; + vec2 linkVisibilityDistanceRange; + float linkVisibilityMinTransparency; + float linkOpacity; + float greyoutOpacity; + float curvedWeight; + float curvedLinkControlPointDistance; + float curvedLinkSegments; + float scaleLinksOnZoom; + float maxPointSize; + float renderMode; + float hoveredLinkIndex; + float hoveredLinkWidthIncrease; + float isLinkHighlightingActive; + float linkStatusTextureSize; + float focusedLinkIndex; + float focusedLinkWidthIncrease; + float transitionProgress; + float animateColors; + float animateWidths; + float animatePositions; + vec4 pointDefaultColor; + float linkColorInterpolateFromEndpoints; + float linkBlending; + float pixelRatio; +} drawLine; + +#define transformationMatrix drawLine.transformationMatrix +#define widthScale drawLine.widthScale +#define linkArrowsSizeScale drawLine.linkArrowsSizeScale +#define spaceSize drawLine.spaceSize +#define screenSize drawLine.screenSize +#define linkVisibilityDistanceRange drawLine.linkVisibilityDistanceRange +#define linkVisibilityMinTransparency drawLine.linkVisibilityMinTransparency +#define linkOpacity drawLine.linkOpacity +#define greyoutOpacity drawLine.greyoutOpacity +#define curvedWeight drawLine.curvedWeight +#define curvedLinkControlPointDistance drawLine.curvedLinkControlPointDistance +#define curvedLinkSegments drawLine.curvedLinkSegments +#define scaleLinksOnZoom drawLine.scaleLinksOnZoom +#define maxPointSize drawLine.maxPointSize +#define renderMode drawLine.renderMode +#define hoveredLinkIndex drawLine.hoveredLinkIndex +#define hoveredLinkWidthIncrease drawLine.hoveredLinkWidthIncrease +#define isLinkHighlightingActive drawLine.isLinkHighlightingActive +#define linkStatusTextureSize drawLine.linkStatusTextureSize +#define focusedLinkIndex drawLine.focusedLinkIndex +#define focusedLinkWidthIncrease drawLine.focusedLinkWidthIncrease +#define transitionProgress drawLine.transitionProgress +#define animateColors drawLine.animateColors +#define animateWidths drawLine.animateWidths +#define animatePositions drawLine.animatePositions +#define pointDefaultColor drawLine.pointDefaultColor +#define linkColorInterpolateFromEndpoints drawLine.linkColorInterpolateFromEndpoints +#define linkBlending drawLine.linkBlending +#define pixelRatio drawLine.pixelRatio +#else +uniform mat3 transformationMatrix; +uniform float widthScale; +uniform float linkArrowsSizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform vec2 linkVisibilityDistanceRange; +uniform float linkVisibilityMinTransparency; +uniform float linkOpacity; +uniform float greyoutOpacity; +uniform float curvedWeight; +uniform float curvedLinkControlPointDistance; +uniform float curvedLinkSegments; +uniform bool scaleLinksOnZoom; +uniform float maxPointSize; +// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking +uniform float renderMode; +uniform float hoveredLinkIndex; +uniform float hoveredLinkWidthIncrease; +uniform float isLinkHighlightingActive; +uniform float linkStatusTextureSize; +uniform float focusedLinkIndex; +uniform float focusedLinkWidthIncrease; +uniform float transitionProgress; +uniform float animateColors; +uniform float animateWidths; +uniform float animatePositions; +uniform vec4 pointDefaultColor; +uniform float linkColorInterpolateFromEndpoints; +uniform float linkBlending; +uniform float pixelRatio; +#endif + +out vec4 rgbaColor; +out vec2 pos; +out float arrowLength; +out float useArrow; +out float smoothing; +out float arrowWidthFactor; +out float linkIndex; +// Per-instance constants (no per-vertex variation), so \`flat\` skips interpolation. +flat out float vLinkStyle; +flat out float vLinkDashSpan; +flat out float vLinkDashWidth; +flat out vec4 vEndpointColorA; +flat out vec4 vEndpointColorB; + +float map(float value, float min1, float max1, float min2, float max2) { + return min2 + (value - min1) * (max2 - min2) / (max1 - min1); +} + +// Resolves NaN color channels the way the point draw shader does: NaN means "use the +// default" — the config default, blended toward the exit default as the endpoint fades +// out. Mirrors resolveColor in draw-points.vert. +vec4 resolveColor(vec4 color, float exitRamp) { + vec4 defaultColor = mix(pointDefaultColor, vec4(EXIT_DEFAULT_COLOR_CHANNEL), exitRamp); + return mix(color, defaultColor, isnan(color)); +} + +float calculateLinkWidth(float width) { + float linkWidth; + if (scaleLinksOnZoom > 0.0) { + // Use original width if links should scale with zoom + linkWidth = width; + } else { + // Adjust width based on zoom level to maintain visual size + linkWidth = width / transformationMatrix[0][0]; + // Apply a non-linear scaling to avoid extreme widths + linkWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01)); + } + // Limit link width based on whether it has an arrow + if (useArrow > 0.5) { + return min(linkWidth, (maxPointSize * 2.0) / transformationMatrix[0][0]); + } else { + return min(linkWidth, maxPointSize / transformationMatrix[0][0]); + } +} + +float calculateArrowWidth(float arrowWidth) { + if (scaleLinksOnZoom > 0.0) { + return arrowWidth; + } else { + // Apply the same scaling logic as calculateLinkWidth to maintain proportionality + arrowWidth = arrowWidth / transformationMatrix[0][0]; + // Apply the same non-linear scaling to avoid extreme widths + arrowWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01)); + return arrowWidth; + } +} + +void main() { + pos = position; + linkIndex = linkIndices; + vLinkStyle = linkStyle; + + ivec2 pointTexelA = ivec2(pointA); + ivec2 pointTexelB = ivec2(pointB); + + vec4 pointPositionA = texelFetch(positionsTexture, pointTexelA, 0); + vec4 pointPositionB = texelFetch(positionsTexture, pointTexelB, 0); + vec2 a = pointPositionA.xy; + vec2 b = pointPositionB.xy; + + // Skip links touching an absent (NaN position) point — interpolating from a NaN + // endpoint would produce garbage geometry. Collapse the link off-screen. This only + // catches snap removals: an animated removal freezes the endpoint at its last real + // position, so absence must be read from the exit texture below. + if (isnan(a.x) || isnan(a.y) || isnan(b.x) || isnan(b.y)) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Exit status of both endpoints (R = previous absence, G = current absence). A link + // is only as present as its endpoints. + vec4 exitStatusA = texelFetch(exitTexture, pointTexelA, 0); + vec4 exitStatusB = texelFetch(exitTexture, pointTexelB, 0); + + // Picking must not report a link to a removed point even mid-fade — same rule as + // point picking, which excludes on current absence. + if (renderMode > 0.0 && (exitStatusA.g > 0.5 || exitStatusB.g > 0.5)) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Visible pass: fade the link with the same animated exit ramp the point fade uses + // (blend R→G during a position transition, settled G otherwise), so a removed + // point's links fade out in sync with it instead of dangling at full opacity. + float exitA = animatePositions > 0.0 ? mix(exitStatusA.r, exitStatusA.g, transitionProgress) : exitStatusA.g; + float exitB = animatePositions > 0.0 ? mix(exitStatusB.r, exitStatusB.g, transitionProgress) : exitStatusB.g; + float exitPresence = (1.0 - exitA) * (1.0 - exitB); + if (exitPresence <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Sample the source/target point colors so the fragment shader can build a gradient + // along the link. Skipped entirely when the gradient is off — the fragment shader + // only reads these varyings inside its own gradient branch, keyed on the same flag. + // The texture mirrors GraphData.pointColors, so channels may be NaN ("use the + // default") — resolve them with the endpoint's exit ramp, like the point draw. + if (linkColorInterpolateFromEndpoints > 0.5) { + vEndpointColorA = resolveColor(texelFetch(pointColorsTexture, pointTexelA, 0), exitA); + vEndpointColorB = resolveColor(texelFetch(pointColorsTexture, pointTexelB, 0), exitB); + } + + // Calculate direction vector and its perpendicular + vec2 xBasis = b - a; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + + // Calculate link distance and control point for curved link + float linkDist = length(xBasis); + float h = curvedLinkControlPointDistance; + vec2 controlPoint = (a + b) / 2.0 + yBasis * linkDist * h; + + // Convert link distance to screen pixels + float linkDistPx = linkDist * transformationMatrix[0][0]; + + // Dash/dot pattern space. When links keep a constant on-screen size (scaleLinksOnZoom = false) + // the pattern is measured in screen pixels (fixed dash size, but it slides as the link's + // on-screen length changes with zoom). When links scale with zoom it is measured in world units, + // which locks the pattern to the link so it scales with zoom instead of crawling. + float dashUnitScale = scaleLinksOnZoom > 0.0 ? 1.0 : transformationMatrix[0][0]; + vLinkDashSpan = linkDist * dashUnitScale; + + float lineWidthBase = animateWidths > 0.0 + ? mix(sourceWidth, targetWidth, transitionProgress) + : targetWidth; + vec4 lineColor = animateColors > 0.0 + ? mix(sourceColor, targetColor, transitionProgress) + : targetColor; + + // Calculate line width using the width scale + float linkWidth = lineWidthBase * widthScale; + // A width of 0 draws nothing, as a point of size 0 does: culled here, before the hover and + // focus increases and the one-pixel floor could widen an absent link. Not pickable either. + if (linkWidth <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + float k = 2.0; + // Arrow width is proportionally larger than the line width + float arrowWidth = linkWidth * k; + arrowWidth *= linkArrowsSizeScale; + + // Ensure arrow width difference is non-negative to prevent unwanted changes to link width + float arrowWidthDifference = max(0.0, arrowWidth - linkWidth); + + // Calculate arrow width in pixels + float arrowWidthPx = calculateArrowWidth(arrowWidth); + + // Calculate arrow length proportional to its width + // 0.866 is approximately sqrt(3)/2 - related to equilateral triangle geometry + // Cap the length to avoid overly long arrows on short links + arrowLength = min(0.3, (0.866 * arrowWidthPx * 2.0) / linkDist); + + useArrow = arrow; + if (useArrow > 0.5) { + linkWidth += arrowWidthDifference; + } + + arrowWidthFactor = arrowWidthDifference / linkWidth; + + // Calculate final link width in pixels with smoothing + float linkWidthPx = calculateLinkWidth(linkWidth); + + if (renderMode > 0.0) { + // Add 5 pixels padding for better hover detection + linkWidthPx += 5.0 / transformationMatrix[0][0]; + // Match the visible-pass width increases so the pickable area covers the full rendered link + if (hoveredLinkIndex == linkIndex) { + linkWidthPx += hoveredLinkWidthIncrease / transformationMatrix[0][0]; + } + if (focusedLinkIndex == linkIndex) { + linkWidthPx += focusedLinkWidthIncrease / transformationMatrix[0][0]; + } + } else { + // Add pixel increase if this is the hovered link + if (hoveredLinkIndex == linkIndex) { + linkWidthPx += hoveredLinkWidthIncrease / transformationMatrix[0][0]; + } + // Add pixel increase if this is the focused link + if (focusedLinkIndex == linkIndex) { + linkWidthPx += focusedLinkWidthIncrease / transformationMatrix[0][0]; + } + } + // Center a one-ramp-wide fade on each stroke edge. + // Strokes thinner than the ramp use the ramp width with reduced alpha. + // Units: EDGE_RAMP_PX is device px; / pixelRatio → CSS px; / k → world, k = transformationMatrix[0][0] + // (the matrix carries no DPR). Widths are extruded in world space, so unlike gl_PointSize they + // never multiply by pixelRatio. The *Px values below are world units. + float smoothingPx = (EDGE_RAMP_PX / pixelRatio) / transformationMatrix[0][0]; + float thinAlpha = min(linkWidthPx / smoothingPx, 1.0); + float minWidthPx = smoothingPx; + if (linkBlending < 0.5) { + // Unblended strokes cannot be dimmed: the fragment cuts them at the edge instead, and a + // stroke under a device pixel is drawn one pixel wide (its body, when it has an arrowhead). + thinAlpha = 1.0; + float bodyShare = useArrow > 0.5 ? 1.0 - arrowWidthFactor : 1.0; + // One device px → world, the same chain as the ramp. + minWidthPx = (1.0 / pixelRatio) / transformationMatrix[0][0] / bodyShare; + } + linkWidthPx = max(linkWidthPx, minWidthPx) + smoothingPx; + smoothing = smoothingPx / linkWidthPx; + + // Quad width (stroke + ramp) in vLinkDashSpan's pattern-space units; the fragment takes the ramp back off. + vLinkDashWidth = linkWidthPx * dashUnitScale; + + + + // Calculate final color with opacity based on link distance + vec3 rgbColor = lineColor.rgb; + // Adjust opacity based on link distance + float opacity = lineColor.a * linkOpacity * max(linkVisibilityMinTransparency, map(linkDistPx, linkVisibilityDistanceRange.g, linkVisibilityDistanceRange.r, 0.0, 1.0)); + // Fade with the exit ramp of the endpoints (1 = both fully present). + opacity *= exitPresence; + // A stroke drawn at ramp width: alpha scales it back to its true width. + opacity *= thinAlpha; + + // Apply greyed-out status from the link status texture. Blended rendering dims + // greyed links by greyoutOpacity. Unblended rendering hides them instead: alpha is + // ignored at write time, links render opaque and can only overwrite each other, so a + // dimmed link drawn later would cut into highlighted links; collapsing the instance + // also skips its fill cost. Runs in the picking pass too — a hidden link is not + // hoverable, matching what is on screen. + if (isLinkHighlightingActive > 0.0 && linkStatusTextureSize > 0.0) { + int statusTexSize = int(linkStatusTextureSize); + int statusIndex = int(linkIndices); + ivec2 statusTexel = ivec2(statusIndex % statusTexSize, statusIndex / statusTexSize); + vec4 linkStatusValue = texelFetch(linkStatus, statusTexel, 0); + if (linkStatusValue.r > 0.0) { + if (linkBlending < 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + opacity *= greyoutOpacity; + } + } + + // Pass final color to fragment shader. Hover color is applied in the fragment + // shader, after the endpoint gradient, so it wins for gradient links too. + rgbaColor = vec4(rgbColor, opacity); + + // Calculate position on the curved path + float t = position.x; + float w = curvedWeight; + + float tPrev = t - 1.0 / curvedLinkSegments; + float tNext = t + 1.0 / curvedLinkSegments; + + vec2 pointCurr = conicParametricCurve(a, b, controlPoint, t, w); + + vec2 pointPrev = conicParametricCurve(a, b, controlPoint, max(0.0, tPrev), w); + vec2 pointNext = conicParametricCurve(a, b, controlPoint, min(tNext, 1.0), w); + + vec2 xBasisCurved = pointNext - pointPrev; + vec2 yBasisCurved = normalize(vec2(-xBasisCurved.y, xBasisCurved.x)); + + pointCurr += yBasisCurved * linkWidthPx * position.y; + + // Transform to clip space coordinates + vec2 p = 2.0 * pointCurr / spaceSize - 1.0; + p *= spaceSize / screenSize; + + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + gl_Position = vec4(final.rg, 0, 1); +}`,O_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + fragColor = rgba; +} +`,U_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 pointA; +in vec2 pointB; +in float linkIndices; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform fillSampledLinksUniforms { + mat4 transformationMatrix; + float spaceSize; + vec2 screenSize; + float curvedWeight; + float curvedLinkControlPointDistance; + float curvedLinkSegments; +} fillSampledLinks; + +#define transformationMatrix fillSampledLinks.transformationMatrix +#define spaceSize fillSampledLinks.spaceSize +#define screenSize fillSampledLinks.screenSize +#define curvedWeight fillSampledLinks.curvedWeight +#define curvedLinkControlPointDistance fillSampledLinks.curvedLinkControlPointDistance +#define curvedLinkSegments fillSampledLinks.curvedLinkSegments +#else +uniform float spaceSize; +uniform vec2 screenSize; +uniform float curvedWeight; +uniform float curvedLinkControlPointDistance; +uniform float curvedLinkSegments; +uniform mat3 transformationMatrix; +#endif + +out vec4 rgba; + +void main() { + ivec2 pointTexelA = ivec2(pointA); + ivec2 pointTexelB = ivec2(pointB); + + // Skip a link touching an absent (faded-out) point. exit.G = current absence. + if (texelFetch(exitTexture, pointTexelA, 0).g > 0.5 || + texelFetch(exitTexture, pointTexelB, 0).g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 posA = texelFetch(positionsTexture, pointTexelA, 0); + vec4 posB = texelFetch(positionsTexture, pointTexelB, 0); + vec2 a = posA.rg; + vec2 b = posB.rg; + + vec2 tangent = b - a; + float angle = -atan(tangent.y, tangent.x); + + vec2 mid; + if (curvedLinkSegments <= 1.0) { + mid = (a + b) * 0.5; + } else if (curvedLinkControlPointDistance != 0.0 && curvedWeight != 0.0) { + vec2 xBasis = b - a; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + float linkDist = length(xBasis); + float h = curvedLinkControlPointDistance; + vec2 controlPoint = (a + b) / 2.0 + yBasis * linkDist * h; + mid = conicParametricCurve(a, b, controlPoint, 0.5, curvedWeight); + } else { + mid = (a + b) * 0.5; + } + + vec2 p = 2.0 * mid / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + vec2 pointScreenPosition = (final.xy + 1.0) * screenSize / 2.0; + rgba = vec4(linkIndices, mid.x, mid.y, angle); + float i = (pointScreenPosition.x + 0.5) / screenSize.x; + float j = (pointScreenPosition.y + 0.5) / screenSize.y; + gl_Position = vec4(2.0 * vec2(i, j) - 1.0, 0.0, 1.0); + + gl_PointSize = 1.0; +} +`;class dr{constructor(t,i){this.buffer=null,this.sync=null,this.isInFlight=!1,this.gl=t,this.data=new Float32Array(i)}get inFlight(){return this.isInFlight}issue(t,i,n,r,s){if(this.isInFlight)return!1;const{gl:o}=this;if(r*s*4>this.data.length||(this.buffer||(this.buffer=o.createBuffer()),!this.buffer))return!1;const a=o.getParameter(o.READ_FRAMEBUFFER_BINDING);return o.bindFramebuffer(o.READ_FRAMEBUFFER,t),o.bindBuffer(o.PIXEL_PACK_BUFFER,this.buffer),o.bufferData(o.PIXEL_PACK_BUFFER,this.data.byteLength,o.STREAM_READ),o.readPixels(i,n,r,s,o.RGBA,o.FLOAT,0),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),o.bindFramebuffer(o.READ_FRAMEBUFFER,a),this.sync=o.fenceSync(o.SYNC_GPU_COMMANDS_COMPLETE,0),o.flush(),this.isInFlight=this.sync!==null,this.isInFlight}poll(){if(!this.isInFlight||!this.sync||!this.buffer)return null;const{gl:t}=this,i=t.clientWaitSync(this.sync,0,0);return i===t.TIMEOUT_EXPIRED||(t.deleteSync(this.sync),this.sync=null,this.isInFlight=!1,i!==t.ALREADY_SIGNALED&&i!==t.CONDITION_SATISFIED)?null:(t.bindBuffer(t.PIXEL_PACK_BUFFER,this.buffer),t.getBufferSubData(t.PIXEL_PACK_BUFFER,0,this.data),t.bindBuffer(t.PIXEL_PACK_BUFFER,null),this.data)}cancel(){this.sync&&(this.gl.deleteSync(this.sync),this.sync=null),this.isInFlight=!1}destroy(){this.cancel(),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null)}}const ko=.5,z_=1536,Fe=9;function L_(e,t){if(e.length!==t.length)return!1;for(const[i,n]of e.entries())if(n!==t[i])return!1;return!0}function W_(e,t){const i=Math.min(ko,z_/Math.max(e,t));return{width:Math.max(Fe,Math.ceil(e*i)),height:Math.max(Fe,Math.ceil(t*i))}}function V_(e,t,i,n,r,s){const o=i*(e/r),a=n*(t/s),l=Math.floor(Fe/2),c=Math.min(Math.max(Math.round(o)-l,0),e-Fe),u=Math.min(Math.max(Math.round(a)-l,0),t-Fe);return{x:c,y:u,centerX:o,centerY:a}}function Lu(e){const t=e[0];return e[3]>0&&t>=0?t:void 0}function Wu(e,t,i){let n=-1,r=[0,0],s=1/0;for(let o=0;o{const t=Vl().exponent(2).range([0,1]).domain([-1,1]),i=km(0,e).map(r=>-.5+r/e);i.push(.5);const n=new Array(i.length*2);return i.forEach((r,s)=>{n[s*2]=[t(r*2),.5],n[s*2+1]=[t(r*2),-.5]}),n};function ji(e){const t=new Float32Array(e*e*2);for(let i=0;iNumber.isInteger(e)?e.toFixed(1):String(e);class $_ extends gt{constructor(){super(...arguments),this.isLinkIndexBufferStale=!0,this.linkStatusTextureSize=0,this.transitionProgress=1,this.shouldAnimateLinkColors=!1,this.shouldAnimateLinkWidths=!1,this.shouldAnimatePositions=!1}get hasPendingPickReadback(){var t;return((t=this.pickingReadback)==null?void 0:t.inFlight)??!1}initPrograms(){const{device:t,config:i,store:n,data:r}=this;this.updateLinkIndexFbo(),this.isLinkIndexBufferStale=!0,this.curveLineGeometry||this.updateCurveLineGeometry();const s=this.data.linksNumber??0;this.pointABuffer||(this.pointABuffer=t.createBuffer({data:new Float32Array(s*2),usage:B.VERTEX|B.COPY_DST})),this.pointBBuffer||(this.pointBBuffer=t.createBuffer({data:new Float32Array(s*2),usage:B.VERTEX|B.COPY_DST})),this.arrowBuffer||(this.arrowBuffer=t.createBuffer({data:new Float32Array(s),usage:B.VERTEX|B.COPY_DST})),this.linkStyleBuffer||(this.linkStyleBuffer=t.createBuffer({data:new Float32Array(s),usage:B.VERTEX|B.COPY_DST})),this.linkIndexBuffer||(this.linkIndexBuffer=t.createBuffer({data:new Float32Array(s),usage:B.VERTEX|B.COPY_DST})),this.drawLineUniformStore||(this.drawLineUniformStore=new oe(t,{drawLineUniforms:{uniformTypes:{transformationMatrix:"mat4x4",widthScale:"f32",linkArrowsSizeScale:"f32",spaceSize:"f32",screenSize:"vec2",linkVisibilityDistanceRange:"vec2",linkVisibilityMinTransparency:"f32",linkOpacity:"f32",greyoutOpacity:"f32",curvedWeight:"f32",curvedLinkControlPointDistance:"f32",curvedLinkSegments:"f32",scaleLinksOnZoom:"f32",maxPointSize:"f32",renderMode:"f32",hoveredLinkIndex:"f32",hoveredLinkWidthIncrease:"f32",isLinkHighlightingActive:"f32",linkStatusTextureSize:"f32",focusedLinkIndex:"f32",focusedLinkWidthIncrease:"f32",transitionProgress:"f32",animateColors:"f32",animateWidths:"f32",animatePositions:"f32",pointDefaultColor:"vec4",linkColorInterpolateFromEndpoints:"f32",linkBlending:"f32",pixelRatio:"f32"},defaultUniforms:{transformationMatrix:n.transformationMatrix4x4,widthScale:i.linkWidthScale,linkArrowsSizeScale:i.linkArrowsSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),linkVisibilityDistanceRange:ie(i.linkVisibilityDistanceRange,[0,0]),linkVisibilityMinTransparency:i.linkVisibilityMinTransparency,linkOpacity:i.linkOpacity,greyoutOpacity:i.linkGreyoutOpacity,curvedWeight:i.curvedLinkWeight,curvedLinkControlPointDistance:i.curvedLinkControlPointDistance,curvedLinkSegments:i.curvedLinks?i.curvedLinkSegments:1,scaleLinksOnZoom:i.scaleLinksOnZoom?1:0,maxPointSize:n.maxPointSize,renderMode:0,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkWidthIncrease:i.hoveredLinkWidthIncrease,isLinkHighlightingActive:0,linkStatusTextureSize:0,focusedLinkIndex:i.focusedLinkIndex??-1,focusedLinkWidthIncrease:i.focusedLinkWidthIncrease,transitionProgress:1,animateColors:0,animateWidths:0,animatePositions:0,pointDefaultColor:ge(We(i.pointDefaultColor),[0,0,0,1]),linkColorInterpolateFromEndpoints:i.linkColorInterpolateFromEndpoints?1:0,linkBlending:i.linkBlending?1:0,pixelRatio:i.pixelRatio}},drawLineFragmentUniforms:{uniformTypes:{renderMode:"f32",linkDashLength:"f32",linkDashGap:"f32",linkColorInterpolateFromEndpoints:"f32",hoveredLinkIndex:"f32",hoveredLinkColor:"vec4",linkBlending:"f32",pickingAlpha:"f32",pickingIndexOffset:"f32"},defaultUniforms:{pickingAlpha:1,pickingIndexOffset:0,renderMode:0,linkDashLength:i.linkDashLength,linkDashGap:i.linkDashGap,linkColorInterpolateFromEndpoints:i.linkColorInterpolateFromEndpoints?1:0,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkColor:ge(n.hoveredLinkColor,[-1,-1,-1,-1]),linkBlending:i.linkBlending?1:0}}})),this.drawCurveCommand||(this.drawCurveCommand=this.createDrawCurveCommand(this.getLinkBlendParameters(this.config.linkBlending))),this.isLinkBlendingActive=this.config.linkBlending,this.fillSampledLinksUniformStore||(this.fillSampledLinksUniformStore=new oe(t,{fillSampledLinksUniforms:{uniformTypes:{transformationMatrix:"mat4x4",spaceSize:"f32",screenSize:"vec2",curvedWeight:"f32",curvedLinkControlPointDistance:"f32",curvedLinkSegments:"f32"},defaultUniforms:{transformationMatrix:n.transformationMatrix4x4,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),curvedWeight:i.curvedLinkWeight,curvedLinkControlPointDistance:i.curvedLinkControlPointDistance,curvedLinkSegments:i.curvedLinks?i.curvedLinkSegments:1}}})),this.fillSampledLinksFboCommand||(this.fillSampledLinksFboCommand=new ee(t,{fs:O_,vs:U_,modules:[zu],topology:"point-list",vertexCount:r.linksNumber??0,attributes:{...this.pointABuffer&&{pointA:this.pointABuffer},...this.pointBBuffer&&{pointB:this.pointBBuffer},...this.linkIndexBuffer&&{linkIndices:this.linkIndexBuffer}},bufferLayout:[{name:"pointA",format:"float32x2"},{name:"pointB",format:"float32x2"},{name:"linkIndices",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{fillSampledLinksUniforms:this.fillSampledLinksUniformStore.getManagedUniformBuffer("fillSampledLinksUniforms")},parameters:te})),this.updateSampledLinksGrid(),this.updateLinkStatus()}drawPicking(t,i,n=0){var o;const{points:r}=this;if(!r||!r.currentPositionTexture||r.currentPositionTexture.destroyed||(r.exitTexture||r.updateExit(),!r.exitTexture||r.exitTexture.destroyed)||((!this.pointABuffer||!this.pointBBuffer)&&this.updatePointsBuffer(),this.targetColorBuffer||this.updateColor(),this.targetWidthBuffer||this.updateWidth(),this.arrowBuffer||this.updateArrow(),this.linkStyleBuffer||this.updateStyle(),this.curveLineGeometry||this.updateCurveLineGeometry(),!this.drawLineUniformStore||!this.linkStatusTexture)||!this.data.linksNumber)return;this.drawPickingCommand||(this.drawPickingCommand=this.createDrawCurveCommand(te)),this.drawPickingCommand.setAttributes(this.getDrawCurveCommandAttributes()),this.drawPickingCommand.setVertexCount(((o=this.curveLineGeometry)==null?void 0:o.length)??0);const s=this.getDrawUniforms();this.drawLineUniformStore.setUniforms({drawLineUniforms:{...s.drawLineUniforms,renderMode:3},drawLineFragmentUniforms:{...s.drawLineFragmentUniforms,renderMode:3,pickingAlpha:i,pickingIndexOffset:n}}),this.drawPickingCommand.setBindings(this.getDrawBindings(r)),this.drawPickingCommand.setInstanceCount(this.data.linksNumber),this.drawPickingCommand.draw(t)}draw(t){const{points:i}=this;i&&(!i.currentPositionTexture||i.currentPositionTexture.destroyed||(i.exitTexture||i.updateExit(),!(!i.exitTexture||i.exitTexture.destroyed)&&((!this.pointABuffer||!this.pointBBuffer)&&this.updatePointsBuffer(),this.targetColorBuffer||this.updateColor(),this.targetWidthBuffer||this.updateWidth(),this.arrowBuffer||this.updateArrow(),this.linkStyleBuffer||this.updateStyle(),this.curveLineGeometry||this.updateCurveLineGeometry(),!(!this.drawCurveCommand||!this.drawLineUniformStore||!this.linkStatusTexture)&&(this.updateLinkBlending(),this.drawLineUniformStore.setUniforms(this.getDrawUniforms()),this.drawCurveCommand.setBindings(this.getDrawBindings(i)),this.drawCurveCommand.setInstanceCount(this.data.linksNumber??0),this.drawCurveCommand.draw(t)))))}updateLinkIndexFbo(){var a,l,c;const{device:t,store:i}=this;if(!this.store.isLinkHoveringEnabled)return;const n=i.screenSize??[0,0],r=n[0],s=n[1];if(!r||!s)return;const o=((a=this.previousScreenSize)==null?void 0:a[0])!==r||((l=this.previousScreenSize)==null?void 0:l[1])!==s;(!this.linkIndexTexture||o)&&((c=this.pickingReadback)==null||c.cancel(),this.linkIndexFbo&&!this.linkIndexFbo.destroyed&&this.linkIndexFbo.destroy(),this.linkIndexTexture&&!this.linkIndexTexture.destroyed&&this.linkIndexTexture.destroy(),this.linkIndexTexture=t.createTexture({width:r,height:s,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.linkIndexTexture.copyImageData({data:new Float32Array(r*s*4).fill(0),bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),this.linkIndexFbo=t.createFramebuffer({width:r,height:s,colorAttachments:[this.linkIndexTexture]}),this.previousScreenSize=[r,s],this.isLinkIndexBufferStale=!0)}updateSampledLinksGrid(){const{store:{screenSize:t},config:{linkSamplingDistance:i},device:n}=this;let r=i??Math.min(...t)/2;r===0&&(r=Ze.linkSamplingDistance);const s=Math.ceil(t[0]/r),o=Math.ceil(t[1]/r);s===0||o===0||(!this.sampledLinksFbo||this.sampledLinksFbo.width!==s||this.sampledLinksFbo.height!==o)&&(this.sampledLinksFbo&&!this.sampledLinksFbo.destroyed&&this.sampledLinksFbo.destroy(),this.sampledLinksFbo=n.createFramebuffer({width:s,height:o,colorAttachments:["rgba32float"]}))}updatePointsBuffer(){var l;const{device:t,data:i,store:n}=this;if(i.linksNumber===void 0||i.links===void 0||!n.pointsTextureSize)return;this.isLinkIndexBufferStale=!0,this.discardPendingPick();const r=new Float32Array(i.linksNumber*2),s=new Float32Array(i.linksNumber*2);for(let c=0;c=0&&c=0&&o!==void 0&&a!==void 0&&l!==void 0&&t.set(Math.round(s),[o,a,l])}return t}getSampledLinks(){const t=[],i=[],n=[];if(!this.sampledLinksFbo||this.sampledLinksFbo.destroyed)return{indices:t,positions:i,angles:n};const r=this.points;if(!(r!=null&&r.currentPositionTexture)||r.currentPositionTexture.destroyed)return{indices:t,positions:i,angles:n};if(!r.exitTexture||r.exitTexture.destroyed)return{indices:t,positions:i,angles:n};if(this.fillSampledLinksFboCommand&&this.fillSampledLinksUniformStore&&this.sampledLinksFbo){this.fillSampledLinksFboCommand.setVertexCount(this.data.linksNumber??0),this.fillSampledLinksUniformStore.setUniforms({fillSampledLinksUniforms:{transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),curvedWeight:this.config.curvedLinkWeight,curvedLinkControlPointDistance:this.config.curvedLinkControlPointDistance,curvedLinkSegments:this.config.curvedLinks?this.config.curvedLinkSegments:1}}),this.fillSampledLinksFboCommand.setBindings({positionsTexture:r.currentPositionTexture,exitTexture:r.exitTexture});const o=this.device.beginRenderPass({framebuffer:this.sampledLinksFbo,clearColor:[-1,-1,-1,-1]});this.fillSampledLinksFboCommand.draw(o),o.end()}const s=we(this.device,this.sampledLinksFbo);for(let o=0;o=0&&l!==void 0&&c!==void 0&&u!==void 0&&(t.push(Math.round(a)),i.push(l,c),n.push(u))}return{indices:t,positions:i,angles:n}}updateLinkIndexBuffer(){if(!this.isLinkIndexBufferStale)return;this.updateLinkIndexFbo();const{config:t,points:i,store:n}=this;if(!i||!i.currentPositionTexture||i.currentPositionTexture.destroyed||(i.exitTexture||i.updateExit(),!i.exitTexture||i.exitTexture.destroyed)||!this.data.linksNumber||!this.store.isLinkHoveringEnabled||!this.linkIndexFbo||!this.drawLineUniformStore||!this.linkStatusTexture||!this.linkIndexTexture||this.linkIndexTexture.destroyed)return;this.drawCurvePickingCommand||(this.drawCurvePickingCommand=this.createDrawCurveCommand(this.getLinkBlendParameters(!1)));const r=t.highlightedLinkIndices!==void 0;this.drawLineUniformStore.setUniforms({drawLineUniforms:{transformationMatrix:n.transformationMatrix4x4,widthScale:t.linkWidthScale,linkArrowsSizeScale:t.linkArrowsSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),linkVisibilityDistanceRange:ie(t.linkVisibilityDistanceRange,[0,0]),linkVisibilityMinTransparency:t.linkVisibilityMinTransparency,linkOpacity:t.linkOpacity,greyoutOpacity:t.linkGreyoutOpacity,curvedWeight:t.curvedLinkWeight,curvedLinkControlPointDistance:t.curvedLinkControlPointDistance,curvedLinkSegments:t.curvedLinks?t.curvedLinkSegments:1,scaleLinksOnZoom:t.scaleLinksOnZoom?1:0,maxPointSize:n.maxPointSize,renderMode:1,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkWidthIncrease:t.hoveredLinkWidthIncrease,isLinkHighlightingActive:r?1:0,linkStatusTextureSize:this.linkStatusTextureSize,focusedLinkIndex:t.focusedLinkIndex??-1,focusedLinkWidthIncrease:t.focusedLinkWidthIncrease,transitionProgress:this.transitionProgress,animateColors:this.shouldAnimateLinkColors?1:0,animateWidths:this.shouldAnimateLinkWidths?1:0,animatePositions:this.shouldAnimatePositions?1:0,pointDefaultColor:ge(this.data.defaultRgba,[0,0,0,1]),linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,linkBlending:t.linkBlending?1:0,pixelRatio:t.pixelRatio},drawLineFragmentUniforms:{renderMode:1,linkDashLength:t.linkDashLength,linkDashGap:t.linkDashGap,linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkColor:ge(n.hoveredLinkColor,[-1,-1,-1,-1]),linkBlending:t.linkBlending?1:0}}),this.drawCurvePickingCommand.setBindings({positionsTexture:i.currentPositionTexture,linkStatus:this.linkStatusTexture,exitTexture:i.exitTexture,pointColorsTexture:i.pointColorsTexture??i.currentPositionTexture}),this.drawCurvePickingCommand.setInstanceCount(this.data.linksNumber??0);const s=this.device.beginRenderPass({framebuffer:this.linkIndexFbo,clearColor:[0,0,0,0]});this.drawCurvePickingCommand.draw(s),s.end(),this.isLinkIndexBufferStale=!1}pickLinkSync(){this.updateLinkIndexBuffer();const t=this.getCursorPickingPixel();if(!t||!this.linkIndexFbo||this.linkIndexFbo.destroyed)return;const i=we(this.device,this.linkIndexFbo,t.x,t.y,1,1);return Lu(i)}requestPickLink(){var r;if((r=this.pickingReadback)!=null&&r.inFlight)return!1;if(this.updateLinkIndexBuffer(),!this.linkIndexFbo||this.linkIndexFbo.destroyed)return!0;const t=this.device.gl,i=this.linkIndexFbo.handle;if(!t||!i)return!0;this.pickingReadback||(this.pickingReadback=new dr(t,4));const n=this.getCursorPickingPixel();return n?this.pickingReadback.issue(i,n.x,n.y,1,1):!0}discardPendingPick(){var t;(t=this.pickingReadback)==null||t.cancel()}takePickLinkResult(){if(!this.pickingReadback)return;const t=this.pickingReadback.poll();if(t)return Lu(t)??null}getAnimatedWidth(t,i){var s,o;const n=((s=this.data.linkWidths)==null?void 0:s[t])??this.config.linkDefaultWidth,r=(o=this.sourceWidthData)==null?void 0:o[t];return r===void 0?n:r+(n-r)*i}setTransitionProgress(t,i=!1,n=!1,r=!1){t!==this.transitionProgress&&(i||n||r)&&(this.isLinkIndexBufferStale=!0),this.transitionProgress=t,this.shouldAnimateLinkColors=i,this.shouldAnimateLinkWidths=n,this.shouldAnimatePositions=r}destroy(){var t,i,n,r,s,o,a;(t=this.drawCurveCommand)==null||t.destroy(),this.drawCurveCommand=void 0,(i=this.drawPickingCommand)==null||i.destroy(),this.drawPickingCommand=void 0,(n=this.drawCurvePickingCommand)==null||n.destroy(),this.drawCurvePickingCommand=void 0,this.isLinkBlendingActive=void 0,(r=this.fillSampledLinksFboCommand)==null||r.destroy(),this.fillSampledLinksFboCommand=void 0,(s=this.pickingReadback)==null||s.destroy(),this.pickingReadback=void 0,this.linkIndexFbo&&!this.linkIndexFbo.destroyed&&this.linkIndexFbo.destroy(),this.linkIndexFbo=void 0,this.sampledLinksFbo&&!this.sampledLinksFbo.destroyed&&this.sampledLinksFbo.destroy(),this.sampledLinksFbo=void 0,this.linkIndexTexture&&!this.linkIndexTexture.destroyed&&this.linkIndexTexture.destroy(),this.linkIndexTexture=void 0,this.linkStatusTexture&&!this.linkStatusTexture.destroyed&&this.linkStatusTexture.destroy(),this.linkStatusTexture=void 0,(o=this.drawLineUniformStore)==null||o.destroy(),this.drawLineUniformStore=void 0,(a=this.fillSampledLinksUniformStore)==null||a.destroy(),this.fillSampledLinksUniformStore=void 0,this.pointABuffer&&!this.pointABuffer.destroyed&&this.pointABuffer.destroy(),this.pointABuffer=void 0,this.pointBBuffer&&!this.pointBBuffer.destroyed&&this.pointBBuffer.destroy(),this.pointBBuffer=void 0,this.sourceColorBuffer&&!this.sourceColorBuffer.destroyed&&this.sourceColorBuffer.destroy(),this.sourceColorBuffer=void 0,this.targetColorBuffer&&!this.targetColorBuffer.destroyed&&this.targetColorBuffer.destroy(),this.targetColorBuffer=void 0,this.previousColorData=void 0,this.sourceWidthBuffer&&!this.sourceWidthBuffer.destroyed&&this.sourceWidthBuffer.destroy(),this.sourceWidthBuffer=void 0,this.targetWidthBuffer&&!this.targetWidthBuffer.destroyed&&this.targetWidthBuffer.destroy(),this.targetWidthBuffer=void 0,this.previousWidthData=void 0,this.sourceWidthData=void 0,this.arrowBuffer&&!this.arrowBuffer.destroyed&&this.arrowBuffer.destroy(),this.arrowBuffer=void 0,this.linkStyleBuffer&&!this.linkStyleBuffer.destroyed&&this.linkStyleBuffer.destroy(),this.linkStyleBuffer=void 0,this.curveLineBuffer&&!this.curveLineBuffer.destroyed&&this.curveLineBuffer.destroy(),this.curveLineBuffer=void 0,this.linkIndexBuffer&&!this.linkIndexBuffer.destroyed&&this.linkIndexBuffer.destroy(),this.linkIndexBuffer=void 0}getCursorPickingPixel(){if(!this.linkIndexFbo||this.linkIndexFbo.destroyed)return;const[t,i]=this.store.screenSize;if(!t||!i)return;const n=Math.floor(this.store.screenMousePosition[0]*(this.linkIndexFbo.width/t)),r=Math.floor(this.store.screenMousePosition[1]*(this.linkIndexFbo.height/i));return{x:Math.min(Math.max(n,0),this.linkIndexFbo.width-1),y:Math.min(Math.max(r,0),this.linkIndexFbo.height-1)}}createDrawCurveCommand(t){var i;if(!this.drawLineUniformStore)throw new Error("Draw line uniforms must be initialized before creating link draw commands");return new ee(this.device,{vs:B_,fs:N_,modules:[zu,ur],topology:"triangle-strip",vertexCount:((i=this.curveLineGeometry)==null?void 0:i.length)??0,attributes:this.getDrawCurveCommandAttributes(),bufferLayout:[{name:"position",format:"float32x2"},{name:"pointA",format:"float32x2",stepMode:"instance"},{name:"pointB",format:"float32x2",stepMode:"instance"},{name:"sourceColor",format:"float32x4",stepMode:"instance"},{name:"targetColor",format:"float32x4",stepMode:"instance"},{name:"sourceWidth",format:"float32",stepMode:"instance"},{name:"targetWidth",format:"float32",stepMode:"instance"},{name:"arrow",format:"float32",stepMode:"instance"},{name:"linkIndices",format:"float32",stepMode:"instance"},{name:"linkStyle",format:"float32",stepMode:"instance"}],defines:{USE_UNIFORM_BUFFERS:!0,EXIT_DEFAULT_COLOR_CHANNEL:li(Xn),EDGE_RAMP_PX:li(Us)},bindings:{drawLineUniforms:this.drawLineUniformStore.getManagedUniformBuffer("drawLineUniforms"),drawLineFragmentUniforms:this.drawLineUniformStore.getManagedUniformBuffer("drawLineFragmentUniforms")},parameters:t})}getDrawCurveCommandAttributes(){const t={};return this.curveLineBuffer&&(t.position=this.curveLineBuffer),this.pointABuffer&&(t.pointA=this.pointABuffer),this.pointBBuffer&&(t.pointB=this.pointBBuffer),this.sourceColorBuffer&&(t.sourceColor=this.sourceColorBuffer),this.targetColorBuffer&&(t.targetColor=this.targetColorBuffer),this.sourceWidthBuffer&&(t.sourceWidth=this.sourceWidthBuffer),this.targetWidthBuffer&&(t.targetWidth=this.targetWidthBuffer),this.arrowBuffer&&(t.arrow=this.arrowBuffer),this.linkIndexBuffer&&(t.linkIndices=this.linkIndexBuffer),this.linkStyleBuffer&&(t.linkStyle=this.linkStyleBuffer),t}setDrawCurveCommandAttributes(t){var i,n;(i=this.drawCurveCommand)==null||i.setAttributes(t),(n=this.drawCurvePickingCommand)==null||n.setAttributes(t)}getLinkBlendParameters(t){const i={...te,cullMode:"back"};return t?{...i,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"src-alpha",blendColorDstFactor:"one-minus-src-alpha",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one-minus-src-alpha"}:{...i,blend:!1}}ensureLinkStatusPlaceholder(){this.linkStatusTexture&&!this.linkStatusTexture.destroyed||(this.linkStatusTexture=this.device.createTexture({width:1,height:1,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST,data:new Float32Array(4).fill(0)}),this.linkStatusTextureSize=0)}getDrawUniforms(){const{config:t,store:i}=this,n=t.highlightedLinkIndices!==void 0,r=i.hostHoveredLinkIndex??i.hoveredLinkIndex??-1;return{drawLineUniforms:{transformationMatrix:i.transformationMatrix4x4,widthScale:t.linkWidthScale,linkArrowsSizeScale:t.linkArrowsSizeScale,spaceSize:i.adjustedSpaceSize,screenSize:ie(i.screenSize,[0,0]),linkVisibilityDistanceRange:ie(t.linkVisibilityDistanceRange,[0,0]),linkVisibilityMinTransparency:t.linkVisibilityMinTransparency,linkOpacity:t.linkOpacity,greyoutOpacity:t.linkGreyoutOpacity,curvedWeight:t.curvedLinkWeight,curvedLinkControlPointDistance:t.curvedLinkControlPointDistance,curvedLinkSegments:t.curvedLinks?t.curvedLinkSegments:1,scaleLinksOnZoom:t.scaleLinksOnZoom?1:0,maxPointSize:i.maxPointSize,renderMode:0,hoveredLinkIndex:r,hoveredLinkWidthIncrease:t.hoveredLinkWidthIncrease,isLinkHighlightingActive:n?1:0,linkStatusTextureSize:this.linkStatusTextureSize,focusedLinkIndex:t.focusedLinkIndex??-1,focusedLinkWidthIncrease:t.focusedLinkWidthIncrease,transitionProgress:this.transitionProgress,animateColors:this.shouldAnimateLinkColors?1:0,animateWidths:this.shouldAnimateLinkWidths?1:0,animatePositions:this.shouldAnimatePositions?1:0,pointDefaultColor:ge(this.data.defaultRgba,[0,0,0,1]),linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,linkBlending:t.linkBlending?1:0,pixelRatio:t.pixelRatio},drawLineFragmentUniforms:{renderMode:0,linkDashLength:t.linkDashLength,linkDashGap:t.linkDashGap,linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,hoveredLinkIndex:r,hoveredLinkColor:ge(i.hoveredLinkColor,[-1,-1,-1,-1]),linkBlending:t.linkBlending?1:0}}}getDrawBindings(t){return{positionsTexture:t.currentPositionTexture,linkStatus:this.linkStatusTexture,exitTexture:t.exitTexture,pointColorsTexture:t.pointColorsTexture??t.currentPositionTexture}}}class X_{constructor(t,i){this.eventTransform=jt,this.behavior=Xg().scaleExtent([.001,1/0]).filter(n=>!this.config.enableZoom&&(n.type==="wheel"||n.type==="dblclick"||n.type==="touchend"||"touches"in n&&n.touches.length>1)?!1:(!n.ctrlKey||n.type==="wheel")&&(n.button??0)===0).on("start",n=>{var s,o;this.isRunning=!0;const r=!!n.sourceEvent;r&&(this.shouldEnableSimulationDuringZoomOverride=void 0),(o=(s=this.config).onZoomStart)==null||o.call(s,n,r)}).on("zoom",n=>{var s,o;this.applyEventTransform(n.transform);const r=!!n.sourceEvent;(o=(s=this.config).onZoom)==null||o.call(s,n,r)}).on("end",n=>{var s,o;this.isRunning=!1;const r=!!n.sourceEvent;(o=(s=this.config).onZoomEnd)==null||o.call(s,n,r)}),this.isRunning=!1,this.shouldEnableSimulationDuringZoomOverride=void 0,this.store=t,this.config=i}applyEventTransform(t){this.eventTransform=t;const{eventTransform:{x:i,y:n,k:r},store:{transform:s,screenSize:o}}=this,a=o[0],l=o[1];!a||!l||(ex(s,a,l),$l(s,s,[i,n]),Rs(s,s,[r,r]),$l(s,s,[a/2,l/2]),Rs(s,s,[a/2,l/2]),Rs(s,s,[1,-1]))}getTransform(t,i,n=.1){if(t.length===0)return this.eventTransform;const{store:{screenSize:r}}=this,s=r[0],o=r[1];let a=1/0,l=-1/0,c=1/0,u=-1/0;for(let v=0;vl&&(l=E),Ru&&(u=R))}if(!Number.isFinite(a)||!Number.isFinite(c))return this.eventTransform;const d=[this.store.scaleX(a),this.store.scaleX(l)],h=[this.store.scaleY(c),this.store.scaleY(u)];d[0]===d[1]&&(d[0]-=.5,d[1]+=.5),h[0]===h[1]&&(h[0]+=.5,h[1]-=.5);const p=s*(1-n*2)/(d[1]-d[0]),g=o*(1-n*2)/(h[0]-h[1]),x=lc(i??Math.min(p,g),...this.behavior.scaleExtent()),T=(d[1]+d[0])/2,S=(h[1]+h[0])/2,P=s/2-T*x,I=o/2-S*x;return jt.translate(P,I).scale(x)}getDistanceToPoint(t){const{x:i,y:n,k:r}=this.eventTransform,s=this.getTransform(t,r),o=i-s.x,a=n-s.y;return Math.sqrt(o*o+a*a)}getMiddlePointTransform(t){if(!Number.isFinite(t[0])||!Number.isFinite(t[1]))return this.eventTransform;const{store:{screenSize:i},eventTransform:{x:n,y:r,k:s}}=this,o=i[0],a=i[1],l=(o/2-n)/s,c=(a/2-r)/s,u=this.store.scaleX(t[0]),d=this.store.scaleY(t[1]),h=(l+u)/2,p=(c+d)/2,g=1,x=o/2-h*g,T=a/2-p*g;return jt.translate(x,T).scale(g)}convertScreenToSpacePosition(t){const{eventTransform:{x:i,y:n,k:r},store:{screenSize:s}}=this,o=s[0],a=s[1],l=(t[0]-i)/r,c=(t[1]-n)/r,u=[l,a-c];return u[0]-=(o-this.store.adjustedSpaceSize)/2,u[1]-=(a-this.store.adjustedSpaceSize)/2,u}convertSpaceToScreenPosition(t){const i=this.eventTransform.applyX(this.store.scaleX(t[0])),n=this.eventTransform.applyY(this.store.scaleY(t[1]));return[i,n]}convertSpaceToScreenRadius(t){const{config:{scalePointsOnZoom:i,pixelRatio:n},store:{maxPointSize:r},eventTransform:{k:s}}=this;let o=t*2;return i?o*=s:o*=Math.min(5,Math.max(1,s*.01)),o<=0?0:Math.min(Math.max(o,1/n),r)/2}}class Y_{constructor(t,i,n){this.isActive=!1,this.behavior=Ug().subject(r=>{if(!(this.transition.isActiveFor(le.Positions)||this.transition.isActiveFor(le.PointSizes)))return this.store.hoveredPoint&&!this.store.isSpaceKeyPressed?{x:r.x,y:r.y}:void 0}).on("start",r=>{var s,o;this.store.hoveredPoint&&(this.store.draggingPointIndex=this.store.hoveredPoint.index,this.isActive=!0,(o=(s=this.config).onDragStart)==null||o.call(s,r))}).on("drag",r=>{var s,o;(o=(s=this.config).onDrag)==null||o.call(s,r)}).on("end",r=>{var s,o;this.isActive=!1,this.store.draggingPointIndex=void 0,(o=(s=this.config).onDragEnd)==null||o.call(s,r)}),this.store=t,this.config=i,this.transition=n}}var ci;(function(e){e[e.DEPTH_BUFFER_BIT=256]="DEPTH_BUFFER_BIT",e[e.STENCIL_BUFFER_BIT=1024]="STENCIL_BUFFER_BIT",e[e.COLOR_BUFFER_BIT=16384]="COLOR_BUFFER_BIT",e[e.POINTS=0]="POINTS",e[e.LINES=1]="LINES",e[e.LINE_LOOP=2]="LINE_LOOP",e[e.LINE_STRIP=3]="LINE_STRIP",e[e.TRIANGLES=4]="TRIANGLES",e[e.TRIANGLE_STRIP=5]="TRIANGLE_STRIP",e[e.TRIANGLE_FAN=6]="TRIANGLE_FAN",e[e.ZERO=0]="ZERO",e[e.ONE=1]="ONE",e[e.SRC_COLOR=768]="SRC_COLOR",e[e.ONE_MINUS_SRC_COLOR=769]="ONE_MINUS_SRC_COLOR",e[e.SRC_ALPHA=770]="SRC_ALPHA",e[e.ONE_MINUS_SRC_ALPHA=771]="ONE_MINUS_SRC_ALPHA",e[e.DST_ALPHA=772]="DST_ALPHA",e[e.ONE_MINUS_DST_ALPHA=773]="ONE_MINUS_DST_ALPHA",e[e.DST_COLOR=774]="DST_COLOR",e[e.ONE_MINUS_DST_COLOR=775]="ONE_MINUS_DST_COLOR",e[e.SRC_ALPHA_SATURATE=776]="SRC_ALPHA_SATURATE",e[e.CONSTANT_COLOR=32769]="CONSTANT_COLOR",e[e.ONE_MINUS_CONSTANT_COLOR=32770]="ONE_MINUS_CONSTANT_COLOR",e[e.CONSTANT_ALPHA=32771]="CONSTANT_ALPHA",e[e.ONE_MINUS_CONSTANT_ALPHA=32772]="ONE_MINUS_CONSTANT_ALPHA",e[e.FUNC_ADD=32774]="FUNC_ADD",e[e.FUNC_SUBTRACT=32778]="FUNC_SUBTRACT",e[e.FUNC_REVERSE_SUBTRACT=32779]="FUNC_REVERSE_SUBTRACT",e[e.BLEND_EQUATION=32777]="BLEND_EQUATION",e[e.BLEND_EQUATION_RGB=32777]="BLEND_EQUATION_RGB",e[e.BLEND_EQUATION_ALPHA=34877]="BLEND_EQUATION_ALPHA",e[e.BLEND_DST_RGB=32968]="BLEND_DST_RGB",e[e.BLEND_SRC_RGB=32969]="BLEND_SRC_RGB",e[e.BLEND_DST_ALPHA=32970]="BLEND_DST_ALPHA",e[e.BLEND_SRC_ALPHA=32971]="BLEND_SRC_ALPHA",e[e.BLEND_COLOR=32773]="BLEND_COLOR",e[e.ARRAY_BUFFER_BINDING=34964]="ARRAY_BUFFER_BINDING",e[e.ELEMENT_ARRAY_BUFFER_BINDING=34965]="ELEMENT_ARRAY_BUFFER_BINDING",e[e.LINE_WIDTH=2849]="LINE_WIDTH",e[e.ALIASED_POINT_SIZE_RANGE=33901]="ALIASED_POINT_SIZE_RANGE",e[e.ALIASED_LINE_WIDTH_RANGE=33902]="ALIASED_LINE_WIDTH_RANGE",e[e.CULL_FACE_MODE=2885]="CULL_FACE_MODE",e[e.FRONT_FACE=2886]="FRONT_FACE",e[e.DEPTH_RANGE=2928]="DEPTH_RANGE",e[e.DEPTH_WRITEMASK=2930]="DEPTH_WRITEMASK",e[e.DEPTH_CLEAR_VALUE=2931]="DEPTH_CLEAR_VALUE",e[e.DEPTH_FUNC=2932]="DEPTH_FUNC",e[e.STENCIL_CLEAR_VALUE=2961]="STENCIL_CLEAR_VALUE",e[e.STENCIL_FUNC=2962]="STENCIL_FUNC",e[e.STENCIL_FAIL=2964]="STENCIL_FAIL",e[e.STENCIL_PASS_DEPTH_FAIL=2965]="STENCIL_PASS_DEPTH_FAIL",e[e.STENCIL_PASS_DEPTH_PASS=2966]="STENCIL_PASS_DEPTH_PASS",e[e.STENCIL_REF=2967]="STENCIL_REF",e[e.STENCIL_VALUE_MASK=2963]="STENCIL_VALUE_MASK",e[e.STENCIL_WRITEMASK=2968]="STENCIL_WRITEMASK",e[e.STENCIL_BACK_FUNC=34816]="STENCIL_BACK_FUNC",e[e.STENCIL_BACK_FAIL=34817]="STENCIL_BACK_FAIL",e[e.STENCIL_BACK_PASS_DEPTH_FAIL=34818]="STENCIL_BACK_PASS_DEPTH_FAIL",e[e.STENCIL_BACK_PASS_DEPTH_PASS=34819]="STENCIL_BACK_PASS_DEPTH_PASS",e[e.STENCIL_BACK_REF=36003]="STENCIL_BACK_REF",e[e.STENCIL_BACK_VALUE_MASK=36004]="STENCIL_BACK_VALUE_MASK",e[e.STENCIL_BACK_WRITEMASK=36005]="STENCIL_BACK_WRITEMASK",e[e.VIEWPORT=2978]="VIEWPORT",e[e.SCISSOR_BOX=3088]="SCISSOR_BOX",e[e.COLOR_CLEAR_VALUE=3106]="COLOR_CLEAR_VALUE",e[e.COLOR_WRITEMASK=3107]="COLOR_WRITEMASK",e[e.UNPACK_ALIGNMENT=3317]="UNPACK_ALIGNMENT",e[e.PACK_ALIGNMENT=3333]="PACK_ALIGNMENT",e[e.MAX_TEXTURE_SIZE=3379]="MAX_TEXTURE_SIZE",e[e.MAX_VIEWPORT_DIMS=3386]="MAX_VIEWPORT_DIMS",e[e.SUBPIXEL_BITS=3408]="SUBPIXEL_BITS",e[e.RED_BITS=3410]="RED_BITS",e[e.GREEN_BITS=3411]="GREEN_BITS",e[e.BLUE_BITS=3412]="BLUE_BITS",e[e.ALPHA_BITS=3413]="ALPHA_BITS",e[e.DEPTH_BITS=3414]="DEPTH_BITS",e[e.STENCIL_BITS=3415]="STENCIL_BITS",e[e.POLYGON_OFFSET_UNITS=10752]="POLYGON_OFFSET_UNITS",e[e.POLYGON_OFFSET_FACTOR=32824]="POLYGON_OFFSET_FACTOR",e[e.TEXTURE_BINDING_2D=32873]="TEXTURE_BINDING_2D",e[e.SAMPLE_BUFFERS=32936]="SAMPLE_BUFFERS",e[e.SAMPLES=32937]="SAMPLES",e[e.SAMPLE_COVERAGE_VALUE=32938]="SAMPLE_COVERAGE_VALUE",e[e.SAMPLE_COVERAGE_INVERT=32939]="SAMPLE_COVERAGE_INVERT",e[e.COMPRESSED_TEXTURE_FORMATS=34467]="COMPRESSED_TEXTURE_FORMATS",e[e.VENDOR=7936]="VENDOR",e[e.RENDERER=7937]="RENDERER",e[e.VERSION=7938]="VERSION",e[e.IMPLEMENTATION_COLOR_READ_TYPE=35738]="IMPLEMENTATION_COLOR_READ_TYPE",e[e.IMPLEMENTATION_COLOR_READ_FORMAT=35739]="IMPLEMENTATION_COLOR_READ_FORMAT",e[e.BROWSER_DEFAULT_WEBGL=37444]="BROWSER_DEFAULT_WEBGL",e[e.STATIC_DRAW=35044]="STATIC_DRAW",e[e.STREAM_DRAW=35040]="STREAM_DRAW",e[e.DYNAMIC_DRAW=35048]="DYNAMIC_DRAW",e[e.ARRAY_BUFFER=34962]="ARRAY_BUFFER",e[e.ELEMENT_ARRAY_BUFFER=34963]="ELEMENT_ARRAY_BUFFER",e[e.BUFFER_SIZE=34660]="BUFFER_SIZE",e[e.BUFFER_USAGE=34661]="BUFFER_USAGE",e[e.CURRENT_VERTEX_ATTRIB=34342]="CURRENT_VERTEX_ATTRIB",e[e.VERTEX_ATTRIB_ARRAY_ENABLED=34338]="VERTEX_ATTRIB_ARRAY_ENABLED",e[e.VERTEX_ATTRIB_ARRAY_SIZE=34339]="VERTEX_ATTRIB_ARRAY_SIZE",e[e.VERTEX_ATTRIB_ARRAY_STRIDE=34340]="VERTEX_ATTRIB_ARRAY_STRIDE",e[e.VERTEX_ATTRIB_ARRAY_TYPE=34341]="VERTEX_ATTRIB_ARRAY_TYPE",e[e.VERTEX_ATTRIB_ARRAY_NORMALIZED=34922]="VERTEX_ATTRIB_ARRAY_NORMALIZED",e[e.VERTEX_ATTRIB_ARRAY_POINTER=34373]="VERTEX_ATTRIB_ARRAY_POINTER",e[e.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING=34975]="VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",e[e.CULL_FACE=2884]="CULL_FACE",e[e.FRONT=1028]="FRONT",e[e.BACK=1029]="BACK",e[e.FRONT_AND_BACK=1032]="FRONT_AND_BACK",e[e.BLEND=3042]="BLEND",e[e.DEPTH_TEST=2929]="DEPTH_TEST",e[e.DITHER=3024]="DITHER",e[e.POLYGON_OFFSET_FILL=32823]="POLYGON_OFFSET_FILL",e[e.SAMPLE_ALPHA_TO_COVERAGE=32926]="SAMPLE_ALPHA_TO_COVERAGE",e[e.SAMPLE_COVERAGE=32928]="SAMPLE_COVERAGE",e[e.SCISSOR_TEST=3089]="SCISSOR_TEST",e[e.STENCIL_TEST=2960]="STENCIL_TEST",e[e.NO_ERROR=0]="NO_ERROR",e[e.INVALID_ENUM=1280]="INVALID_ENUM",e[e.INVALID_VALUE=1281]="INVALID_VALUE",e[e.INVALID_OPERATION=1282]="INVALID_OPERATION",e[e.OUT_OF_MEMORY=1285]="OUT_OF_MEMORY",e[e.CONTEXT_LOST_WEBGL=37442]="CONTEXT_LOST_WEBGL",e[e.CW=2304]="CW",e[e.CCW=2305]="CCW",e[e.DONT_CARE=4352]="DONT_CARE",e[e.FASTEST=4353]="FASTEST",e[e.NICEST=4354]="NICEST",e[e.GENERATE_MIPMAP_HINT=33170]="GENERATE_MIPMAP_HINT",e[e.BYTE=5120]="BYTE",e[e.UNSIGNED_BYTE=5121]="UNSIGNED_BYTE",e[e.SHORT=5122]="SHORT",e[e.UNSIGNED_SHORT=5123]="UNSIGNED_SHORT",e[e.INT=5124]="INT",e[e.UNSIGNED_INT=5125]="UNSIGNED_INT",e[e.FLOAT=5126]="FLOAT",e[e.DOUBLE=5130]="DOUBLE",e[e.DEPTH_COMPONENT=6402]="DEPTH_COMPONENT",e[e.ALPHA=6406]="ALPHA",e[e.RGB=6407]="RGB",e[e.RGBA=6408]="RGBA",e[e.LUMINANCE=6409]="LUMINANCE",e[e.LUMINANCE_ALPHA=6410]="LUMINANCE_ALPHA",e[e.UNSIGNED_SHORT_4_4_4_4=32819]="UNSIGNED_SHORT_4_4_4_4",e[e.UNSIGNED_SHORT_5_5_5_1=32820]="UNSIGNED_SHORT_5_5_5_1",e[e.UNSIGNED_SHORT_5_6_5=33635]="UNSIGNED_SHORT_5_6_5",e[e.FRAGMENT_SHADER=35632]="FRAGMENT_SHADER",e[e.VERTEX_SHADER=35633]="VERTEX_SHADER",e[e.COMPILE_STATUS=35713]="COMPILE_STATUS",e[e.DELETE_STATUS=35712]="DELETE_STATUS",e[e.LINK_STATUS=35714]="LINK_STATUS",e[e.VALIDATE_STATUS=35715]="VALIDATE_STATUS",e[e.ATTACHED_SHADERS=35717]="ATTACHED_SHADERS",e[e.ACTIVE_ATTRIBUTES=35721]="ACTIVE_ATTRIBUTES",e[e.ACTIVE_UNIFORMS=35718]="ACTIVE_UNIFORMS",e[e.MAX_VERTEX_ATTRIBS=34921]="MAX_VERTEX_ATTRIBS",e[e.MAX_VERTEX_UNIFORM_VECTORS=36347]="MAX_VERTEX_UNIFORM_VECTORS",e[e.MAX_VARYING_VECTORS=36348]="MAX_VARYING_VECTORS",e[e.MAX_COMBINED_TEXTURE_IMAGE_UNITS=35661]="MAX_COMBINED_TEXTURE_IMAGE_UNITS",e[e.MAX_VERTEX_TEXTURE_IMAGE_UNITS=35660]="MAX_VERTEX_TEXTURE_IMAGE_UNITS",e[e.MAX_TEXTURE_IMAGE_UNITS=34930]="MAX_TEXTURE_IMAGE_UNITS",e[e.MAX_FRAGMENT_UNIFORM_VECTORS=36349]="MAX_FRAGMENT_UNIFORM_VECTORS",e[e.SHADER_TYPE=35663]="SHADER_TYPE",e[e.SHADING_LANGUAGE_VERSION=35724]="SHADING_LANGUAGE_VERSION",e[e.CURRENT_PROGRAM=35725]="CURRENT_PROGRAM",e[e.NEVER=512]="NEVER",e[e.LESS=513]="LESS",e[e.EQUAL=514]="EQUAL",e[e.LEQUAL=515]="LEQUAL",e[e.GREATER=516]="GREATER",e[e.NOTEQUAL=517]="NOTEQUAL",e[e.GEQUAL=518]="GEQUAL",e[e.ALWAYS=519]="ALWAYS",e[e.KEEP=7680]="KEEP",e[e.REPLACE=7681]="REPLACE",e[e.INCR=7682]="INCR",e[e.DECR=7683]="DECR",e[e.INVERT=5386]="INVERT",e[e.INCR_WRAP=34055]="INCR_WRAP",e[e.DECR_WRAP=34056]="DECR_WRAP",e[e.NEAREST=9728]="NEAREST",e[e.LINEAR=9729]="LINEAR",e[e.NEAREST_MIPMAP_NEAREST=9984]="NEAREST_MIPMAP_NEAREST",e[e.LINEAR_MIPMAP_NEAREST=9985]="LINEAR_MIPMAP_NEAREST",e[e.NEAREST_MIPMAP_LINEAR=9986]="NEAREST_MIPMAP_LINEAR",e[e.LINEAR_MIPMAP_LINEAR=9987]="LINEAR_MIPMAP_LINEAR",e[e.TEXTURE_MAG_FILTER=10240]="TEXTURE_MAG_FILTER",e[e.TEXTURE_MIN_FILTER=10241]="TEXTURE_MIN_FILTER",e[e.TEXTURE_WRAP_S=10242]="TEXTURE_WRAP_S",e[e.TEXTURE_WRAP_T=10243]="TEXTURE_WRAP_T",e[e.TEXTURE_2D=3553]="TEXTURE_2D",e[e.TEXTURE=5890]="TEXTURE",e[e.TEXTURE_CUBE_MAP=34067]="TEXTURE_CUBE_MAP",e[e.TEXTURE_BINDING_CUBE_MAP=34068]="TEXTURE_BINDING_CUBE_MAP",e[e.TEXTURE_CUBE_MAP_POSITIVE_X=34069]="TEXTURE_CUBE_MAP_POSITIVE_X",e[e.TEXTURE_CUBE_MAP_NEGATIVE_X=34070]="TEXTURE_CUBE_MAP_NEGATIVE_X",e[e.TEXTURE_CUBE_MAP_POSITIVE_Y=34071]="TEXTURE_CUBE_MAP_POSITIVE_Y",e[e.TEXTURE_CUBE_MAP_NEGATIVE_Y=34072]="TEXTURE_CUBE_MAP_NEGATIVE_Y",e[e.TEXTURE_CUBE_MAP_POSITIVE_Z=34073]="TEXTURE_CUBE_MAP_POSITIVE_Z",e[e.TEXTURE_CUBE_MAP_NEGATIVE_Z=34074]="TEXTURE_CUBE_MAP_NEGATIVE_Z",e[e.MAX_CUBE_MAP_TEXTURE_SIZE=34076]="MAX_CUBE_MAP_TEXTURE_SIZE",e[e.TEXTURE0=33984]="TEXTURE0",e[e.ACTIVE_TEXTURE=34016]="ACTIVE_TEXTURE",e[e.REPEAT=10497]="REPEAT",e[e.CLAMP_TO_EDGE=33071]="CLAMP_TO_EDGE",e[e.MIRRORED_REPEAT=33648]="MIRRORED_REPEAT",e[e.TEXTURE_WIDTH=4096]="TEXTURE_WIDTH",e[e.TEXTURE_HEIGHT=4097]="TEXTURE_HEIGHT",e[e.FLOAT_VEC2=35664]="FLOAT_VEC2",e[e.FLOAT_VEC3=35665]="FLOAT_VEC3",e[e.FLOAT_VEC4=35666]="FLOAT_VEC4",e[e.INT_VEC2=35667]="INT_VEC2",e[e.INT_VEC3=35668]="INT_VEC3",e[e.INT_VEC4=35669]="INT_VEC4",e[e.BOOL=35670]="BOOL",e[e.BOOL_VEC2=35671]="BOOL_VEC2",e[e.BOOL_VEC3=35672]="BOOL_VEC3",e[e.BOOL_VEC4=35673]="BOOL_VEC4",e[e.FLOAT_MAT2=35674]="FLOAT_MAT2",e[e.FLOAT_MAT3=35675]="FLOAT_MAT3",e[e.FLOAT_MAT4=35676]="FLOAT_MAT4",e[e.SAMPLER_2D=35678]="SAMPLER_2D",e[e.SAMPLER_CUBE=35680]="SAMPLER_CUBE",e[e.LOW_FLOAT=36336]="LOW_FLOAT",e[e.MEDIUM_FLOAT=36337]="MEDIUM_FLOAT",e[e.HIGH_FLOAT=36338]="HIGH_FLOAT",e[e.LOW_INT=36339]="LOW_INT",e[e.MEDIUM_INT=36340]="MEDIUM_INT",e[e.HIGH_INT=36341]="HIGH_INT",e[e.FRAMEBUFFER=36160]="FRAMEBUFFER",e[e.RENDERBUFFER=36161]="RENDERBUFFER",e[e.RGBA4=32854]="RGBA4",e[e.RGB5_A1=32855]="RGB5_A1",e[e.RGB565=36194]="RGB565",e[e.DEPTH_COMPONENT16=33189]="DEPTH_COMPONENT16",e[e.STENCIL_INDEX=6401]="STENCIL_INDEX",e[e.STENCIL_INDEX8=36168]="STENCIL_INDEX8",e[e.DEPTH_STENCIL=34041]="DEPTH_STENCIL",e[e.RENDERBUFFER_WIDTH=36162]="RENDERBUFFER_WIDTH",e[e.RENDERBUFFER_HEIGHT=36163]="RENDERBUFFER_HEIGHT",e[e.RENDERBUFFER_INTERNAL_FORMAT=36164]="RENDERBUFFER_INTERNAL_FORMAT",e[e.RENDERBUFFER_RED_SIZE=36176]="RENDERBUFFER_RED_SIZE",e[e.RENDERBUFFER_GREEN_SIZE=36177]="RENDERBUFFER_GREEN_SIZE",e[e.RENDERBUFFER_BLUE_SIZE=36178]="RENDERBUFFER_BLUE_SIZE",e[e.RENDERBUFFER_ALPHA_SIZE=36179]="RENDERBUFFER_ALPHA_SIZE",e[e.RENDERBUFFER_DEPTH_SIZE=36180]="RENDERBUFFER_DEPTH_SIZE",e[e.RENDERBUFFER_STENCIL_SIZE=36181]="RENDERBUFFER_STENCIL_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE=36048]="FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",e[e.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME=36049]="FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",e[e.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL=36050]="FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",e[e.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE=36051]="FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",e[e.COLOR_ATTACHMENT0=36064]="COLOR_ATTACHMENT0",e[e.DEPTH_ATTACHMENT=36096]="DEPTH_ATTACHMENT",e[e.STENCIL_ATTACHMENT=36128]="STENCIL_ATTACHMENT",e[e.DEPTH_STENCIL_ATTACHMENT=33306]="DEPTH_STENCIL_ATTACHMENT",e[e.NONE=0]="NONE",e[e.FRAMEBUFFER_COMPLETE=36053]="FRAMEBUFFER_COMPLETE",e[e.FRAMEBUFFER_INCOMPLETE_ATTACHMENT=36054]="FRAMEBUFFER_INCOMPLETE_ATTACHMENT",e[e.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT=36055]="FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",e[e.FRAMEBUFFER_INCOMPLETE_DIMENSIONS=36057]="FRAMEBUFFER_INCOMPLETE_DIMENSIONS",e[e.FRAMEBUFFER_UNSUPPORTED=36061]="FRAMEBUFFER_UNSUPPORTED",e[e.FRAMEBUFFER_BINDING=36006]="FRAMEBUFFER_BINDING",e[e.RENDERBUFFER_BINDING=36007]="RENDERBUFFER_BINDING",e[e.READ_FRAMEBUFFER=36008]="READ_FRAMEBUFFER",e[e.DRAW_FRAMEBUFFER=36009]="DRAW_FRAMEBUFFER",e[e.MAX_RENDERBUFFER_SIZE=34024]="MAX_RENDERBUFFER_SIZE",e[e.INVALID_FRAMEBUFFER_OPERATION=1286]="INVALID_FRAMEBUFFER_OPERATION",e[e.UNPACK_FLIP_Y_WEBGL=37440]="UNPACK_FLIP_Y_WEBGL",e[e.UNPACK_PREMULTIPLY_ALPHA_WEBGL=37441]="UNPACK_PREMULTIPLY_ALPHA_WEBGL",e[e.UNPACK_COLORSPACE_CONVERSION_WEBGL=37443]="UNPACK_COLORSPACE_CONVERSION_WEBGL",e[e.READ_BUFFER=3074]="READ_BUFFER",e[e.UNPACK_ROW_LENGTH=3314]="UNPACK_ROW_LENGTH",e[e.UNPACK_SKIP_ROWS=3315]="UNPACK_SKIP_ROWS",e[e.UNPACK_SKIP_PIXELS=3316]="UNPACK_SKIP_PIXELS",e[e.PACK_ROW_LENGTH=3330]="PACK_ROW_LENGTH",e[e.PACK_SKIP_ROWS=3331]="PACK_SKIP_ROWS",e[e.PACK_SKIP_PIXELS=3332]="PACK_SKIP_PIXELS",e[e.TEXTURE_BINDING_3D=32874]="TEXTURE_BINDING_3D",e[e.UNPACK_SKIP_IMAGES=32877]="UNPACK_SKIP_IMAGES",e[e.UNPACK_IMAGE_HEIGHT=32878]="UNPACK_IMAGE_HEIGHT",e[e.MAX_3D_TEXTURE_SIZE=32883]="MAX_3D_TEXTURE_SIZE",e[e.MAX_ELEMENTS_VERTICES=33e3]="MAX_ELEMENTS_VERTICES",e[e.MAX_ELEMENTS_INDICES=33001]="MAX_ELEMENTS_INDICES",e[e.MAX_TEXTURE_LOD_BIAS=34045]="MAX_TEXTURE_LOD_BIAS",e[e.MAX_FRAGMENT_UNIFORM_COMPONENTS=35657]="MAX_FRAGMENT_UNIFORM_COMPONENTS",e[e.MAX_VERTEX_UNIFORM_COMPONENTS=35658]="MAX_VERTEX_UNIFORM_COMPONENTS",e[e.MAX_ARRAY_TEXTURE_LAYERS=35071]="MAX_ARRAY_TEXTURE_LAYERS",e[e.MIN_PROGRAM_TEXEL_OFFSET=35076]="MIN_PROGRAM_TEXEL_OFFSET",e[e.MAX_PROGRAM_TEXEL_OFFSET=35077]="MAX_PROGRAM_TEXEL_OFFSET",e[e.MAX_VARYING_COMPONENTS=35659]="MAX_VARYING_COMPONENTS",e[e.FRAGMENT_SHADER_DERIVATIVE_HINT=35723]="FRAGMENT_SHADER_DERIVATIVE_HINT",e[e.RASTERIZER_DISCARD=35977]="RASTERIZER_DISCARD",e[e.VERTEX_ARRAY_BINDING=34229]="VERTEX_ARRAY_BINDING",e[e.MAX_VERTEX_OUTPUT_COMPONENTS=37154]="MAX_VERTEX_OUTPUT_COMPONENTS",e[e.MAX_FRAGMENT_INPUT_COMPONENTS=37157]="MAX_FRAGMENT_INPUT_COMPONENTS",e[e.MAX_SERVER_WAIT_TIMEOUT=37137]="MAX_SERVER_WAIT_TIMEOUT",e[e.MAX_ELEMENT_INDEX=36203]="MAX_ELEMENT_INDEX",e[e.RED=6403]="RED",e[e.RGB8=32849]="RGB8",e[e.RGBA8=32856]="RGBA8",e[e.RGB10_A2=32857]="RGB10_A2",e[e.TEXTURE_3D=32879]="TEXTURE_3D",e[e.TEXTURE_WRAP_R=32882]="TEXTURE_WRAP_R",e[e.TEXTURE_MIN_LOD=33082]="TEXTURE_MIN_LOD",e[e.TEXTURE_MAX_LOD=33083]="TEXTURE_MAX_LOD",e[e.TEXTURE_BASE_LEVEL=33084]="TEXTURE_BASE_LEVEL",e[e.TEXTURE_MAX_LEVEL=33085]="TEXTURE_MAX_LEVEL",e[e.TEXTURE_COMPARE_MODE=34892]="TEXTURE_COMPARE_MODE",e[e.TEXTURE_COMPARE_FUNC=34893]="TEXTURE_COMPARE_FUNC",e[e.SRGB=35904]="SRGB",e[e.SRGB8=35905]="SRGB8",e[e.SRGB8_ALPHA8=35907]="SRGB8_ALPHA8",e[e.COMPARE_REF_TO_TEXTURE=34894]="COMPARE_REF_TO_TEXTURE",e[e.RGBA32F=34836]="RGBA32F",e[e.RGB32F=34837]="RGB32F",e[e.RGBA16F=34842]="RGBA16F",e[e.RGB16F=34843]="RGB16F",e[e.TEXTURE_2D_ARRAY=35866]="TEXTURE_2D_ARRAY",e[e.TEXTURE_BINDING_2D_ARRAY=35869]="TEXTURE_BINDING_2D_ARRAY",e[e.R11F_G11F_B10F=35898]="R11F_G11F_B10F",e[e.RGB9_E5=35901]="RGB9_E5",e[e.RGBA32UI=36208]="RGBA32UI",e[e.RGB32UI=36209]="RGB32UI",e[e.RGBA16UI=36214]="RGBA16UI",e[e.RGB16UI=36215]="RGB16UI",e[e.RGBA8UI=36220]="RGBA8UI",e[e.RGB8UI=36221]="RGB8UI",e[e.RGBA32I=36226]="RGBA32I",e[e.RGB32I=36227]="RGB32I",e[e.RGBA16I=36232]="RGBA16I",e[e.RGB16I=36233]="RGB16I",e[e.RGBA8I=36238]="RGBA8I",e[e.RGB8I=36239]="RGB8I",e[e.RED_INTEGER=36244]="RED_INTEGER",e[e.RGB_INTEGER=36248]="RGB_INTEGER",e[e.RGBA_INTEGER=36249]="RGBA_INTEGER",e[e.R8=33321]="R8",e[e.RG8=33323]="RG8",e[e.R16F=33325]="R16F",e[e.R32F=33326]="R32F",e[e.RG16F=33327]="RG16F",e[e.RG32F=33328]="RG32F",e[e.R8I=33329]="R8I",e[e.R8UI=33330]="R8UI",e[e.R16I=33331]="R16I",e[e.R16UI=33332]="R16UI",e[e.R32I=33333]="R32I",e[e.R32UI=33334]="R32UI",e[e.RG8I=33335]="RG8I",e[e.RG8UI=33336]="RG8UI",e[e.RG16I=33337]="RG16I",e[e.RG16UI=33338]="RG16UI",e[e.RG32I=33339]="RG32I",e[e.RG32UI=33340]="RG32UI",e[e.R8_SNORM=36756]="R8_SNORM",e[e.RG8_SNORM=36757]="RG8_SNORM",e[e.RGB8_SNORM=36758]="RGB8_SNORM",e[e.RGBA8_SNORM=36759]="RGBA8_SNORM",e[e.RGB10_A2UI=36975]="RGB10_A2UI",e[e.TEXTURE_IMMUTABLE_FORMAT=37167]="TEXTURE_IMMUTABLE_FORMAT",e[e.TEXTURE_IMMUTABLE_LEVELS=33503]="TEXTURE_IMMUTABLE_LEVELS",e[e.UNSIGNED_INT_2_10_10_10_REV=33640]="UNSIGNED_INT_2_10_10_10_REV",e[e.UNSIGNED_INT_10F_11F_11F_REV=35899]="UNSIGNED_INT_10F_11F_11F_REV",e[e.UNSIGNED_INT_5_9_9_9_REV=35902]="UNSIGNED_INT_5_9_9_9_REV",e[e.FLOAT_32_UNSIGNED_INT_24_8_REV=36269]="FLOAT_32_UNSIGNED_INT_24_8_REV",e[e.UNSIGNED_INT_24_8=34042]="UNSIGNED_INT_24_8",e[e.HALF_FLOAT=5131]="HALF_FLOAT",e[e.RG=33319]="RG",e[e.RG_INTEGER=33320]="RG_INTEGER",e[e.INT_2_10_10_10_REV=36255]="INT_2_10_10_10_REV",e[e.CURRENT_QUERY=34917]="CURRENT_QUERY",e[e.QUERY_RESULT=34918]="QUERY_RESULT",e[e.QUERY_RESULT_AVAILABLE=34919]="QUERY_RESULT_AVAILABLE",e[e.ANY_SAMPLES_PASSED=35887]="ANY_SAMPLES_PASSED",e[e.ANY_SAMPLES_PASSED_CONSERVATIVE=36202]="ANY_SAMPLES_PASSED_CONSERVATIVE",e[e.MAX_DRAW_BUFFERS=34852]="MAX_DRAW_BUFFERS",e[e.DRAW_BUFFER0=34853]="DRAW_BUFFER0",e[e.DRAW_BUFFER1=34854]="DRAW_BUFFER1",e[e.DRAW_BUFFER2=34855]="DRAW_BUFFER2",e[e.DRAW_BUFFER3=34856]="DRAW_BUFFER3",e[e.DRAW_BUFFER4=34857]="DRAW_BUFFER4",e[e.DRAW_BUFFER5=34858]="DRAW_BUFFER5",e[e.DRAW_BUFFER6=34859]="DRAW_BUFFER6",e[e.DRAW_BUFFER7=34860]="DRAW_BUFFER7",e[e.DRAW_BUFFER8=34861]="DRAW_BUFFER8",e[e.DRAW_BUFFER9=34862]="DRAW_BUFFER9",e[e.DRAW_BUFFER10=34863]="DRAW_BUFFER10",e[e.DRAW_BUFFER11=34864]="DRAW_BUFFER11",e[e.DRAW_BUFFER12=34865]="DRAW_BUFFER12",e[e.DRAW_BUFFER13=34866]="DRAW_BUFFER13",e[e.DRAW_BUFFER14=34867]="DRAW_BUFFER14",e[e.DRAW_BUFFER15=34868]="DRAW_BUFFER15",e[e.MAX_COLOR_ATTACHMENTS=36063]="MAX_COLOR_ATTACHMENTS",e[e.COLOR_ATTACHMENT1=36065]="COLOR_ATTACHMENT1",e[e.COLOR_ATTACHMENT2=36066]="COLOR_ATTACHMENT2",e[e.COLOR_ATTACHMENT3=36067]="COLOR_ATTACHMENT3",e[e.COLOR_ATTACHMENT4=36068]="COLOR_ATTACHMENT4",e[e.COLOR_ATTACHMENT5=36069]="COLOR_ATTACHMENT5",e[e.COLOR_ATTACHMENT6=36070]="COLOR_ATTACHMENT6",e[e.COLOR_ATTACHMENT7=36071]="COLOR_ATTACHMENT7",e[e.COLOR_ATTACHMENT8=36072]="COLOR_ATTACHMENT8",e[e.COLOR_ATTACHMENT9=36073]="COLOR_ATTACHMENT9",e[e.COLOR_ATTACHMENT10=36074]="COLOR_ATTACHMENT10",e[e.COLOR_ATTACHMENT11=36075]="COLOR_ATTACHMENT11",e[e.COLOR_ATTACHMENT12=36076]="COLOR_ATTACHMENT12",e[e.COLOR_ATTACHMENT13=36077]="COLOR_ATTACHMENT13",e[e.COLOR_ATTACHMENT14=36078]="COLOR_ATTACHMENT14",e[e.COLOR_ATTACHMENT15=36079]="COLOR_ATTACHMENT15",e[e.SAMPLER_3D=35679]="SAMPLER_3D",e[e.SAMPLER_2D_SHADOW=35682]="SAMPLER_2D_SHADOW",e[e.SAMPLER_2D_ARRAY=36289]="SAMPLER_2D_ARRAY",e[e.SAMPLER_2D_ARRAY_SHADOW=36292]="SAMPLER_2D_ARRAY_SHADOW",e[e.SAMPLER_CUBE_SHADOW=36293]="SAMPLER_CUBE_SHADOW",e[e.INT_SAMPLER_2D=36298]="INT_SAMPLER_2D",e[e.INT_SAMPLER_3D=36299]="INT_SAMPLER_3D",e[e.INT_SAMPLER_CUBE=36300]="INT_SAMPLER_CUBE",e[e.INT_SAMPLER_2D_ARRAY=36303]="INT_SAMPLER_2D_ARRAY",e[e.UNSIGNED_INT_SAMPLER_2D=36306]="UNSIGNED_INT_SAMPLER_2D",e[e.UNSIGNED_INT_SAMPLER_3D=36307]="UNSIGNED_INT_SAMPLER_3D",e[e.UNSIGNED_INT_SAMPLER_CUBE=36308]="UNSIGNED_INT_SAMPLER_CUBE",e[e.UNSIGNED_INT_SAMPLER_2D_ARRAY=36311]="UNSIGNED_INT_SAMPLER_2D_ARRAY",e[e.MAX_SAMPLES=36183]="MAX_SAMPLES",e[e.SAMPLER_BINDING=35097]="SAMPLER_BINDING",e[e.PIXEL_PACK_BUFFER=35051]="PIXEL_PACK_BUFFER",e[e.PIXEL_UNPACK_BUFFER=35052]="PIXEL_UNPACK_BUFFER",e[e.PIXEL_PACK_BUFFER_BINDING=35053]="PIXEL_PACK_BUFFER_BINDING",e[e.PIXEL_UNPACK_BUFFER_BINDING=35055]="PIXEL_UNPACK_BUFFER_BINDING",e[e.COPY_READ_BUFFER=36662]="COPY_READ_BUFFER",e[e.COPY_WRITE_BUFFER=36663]="COPY_WRITE_BUFFER",e[e.COPY_READ_BUFFER_BINDING=36662]="COPY_READ_BUFFER_BINDING",e[e.COPY_WRITE_BUFFER_BINDING=36663]="COPY_WRITE_BUFFER_BINDING",e[e.FLOAT_MAT2x3=35685]="FLOAT_MAT2x3",e[e.FLOAT_MAT2x4=35686]="FLOAT_MAT2x4",e[e.FLOAT_MAT3x2=35687]="FLOAT_MAT3x2",e[e.FLOAT_MAT3x4=35688]="FLOAT_MAT3x4",e[e.FLOAT_MAT4x2=35689]="FLOAT_MAT4x2",e[e.FLOAT_MAT4x3=35690]="FLOAT_MAT4x3",e[e.UNSIGNED_INT_VEC2=36294]="UNSIGNED_INT_VEC2",e[e.UNSIGNED_INT_VEC3=36295]="UNSIGNED_INT_VEC3",e[e.UNSIGNED_INT_VEC4=36296]="UNSIGNED_INT_VEC4",e[e.UNSIGNED_NORMALIZED=35863]="UNSIGNED_NORMALIZED",e[e.SIGNED_NORMALIZED=36764]="SIGNED_NORMALIZED",e[e.VERTEX_ATTRIB_ARRAY_INTEGER=35069]="VERTEX_ATTRIB_ARRAY_INTEGER",e[e.VERTEX_ATTRIB_ARRAY_DIVISOR=35070]="VERTEX_ATTRIB_ARRAY_DIVISOR",e[e.TRANSFORM_FEEDBACK_BUFFER_MODE=35967]="TRANSFORM_FEEDBACK_BUFFER_MODE",e[e.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS=35968]="MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",e[e.TRANSFORM_FEEDBACK_VARYINGS=35971]="TRANSFORM_FEEDBACK_VARYINGS",e[e.TRANSFORM_FEEDBACK_BUFFER_START=35972]="TRANSFORM_FEEDBACK_BUFFER_START",e[e.TRANSFORM_FEEDBACK_BUFFER_SIZE=35973]="TRANSFORM_FEEDBACK_BUFFER_SIZE",e[e.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN=35976]="TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",e[e.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS=35978]="MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",e[e.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS=35979]="MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",e[e.INTERLEAVED_ATTRIBS=35980]="INTERLEAVED_ATTRIBS",e[e.SEPARATE_ATTRIBS=35981]="SEPARATE_ATTRIBS",e[e.TRANSFORM_FEEDBACK_BUFFER=35982]="TRANSFORM_FEEDBACK_BUFFER",e[e.TRANSFORM_FEEDBACK_BUFFER_BINDING=35983]="TRANSFORM_FEEDBACK_BUFFER_BINDING",e[e.TRANSFORM_FEEDBACK=36386]="TRANSFORM_FEEDBACK",e[e.TRANSFORM_FEEDBACK_PAUSED=36387]="TRANSFORM_FEEDBACK_PAUSED",e[e.TRANSFORM_FEEDBACK_ACTIVE=36388]="TRANSFORM_FEEDBACK_ACTIVE",e[e.TRANSFORM_FEEDBACK_BINDING=36389]="TRANSFORM_FEEDBACK_BINDING",e[e.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING=33296]="FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",e[e.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE=33297]="FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",e[e.FRAMEBUFFER_ATTACHMENT_RED_SIZE=33298]="FRAMEBUFFER_ATTACHMENT_RED_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE=33299]="FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE=33300]="FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE=33301]="FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE=33302]="FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE=33303]="FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",e[e.FRAMEBUFFER_DEFAULT=33304]="FRAMEBUFFER_DEFAULT",e[e.DEPTH24_STENCIL8=35056]="DEPTH24_STENCIL8",e[e.DRAW_FRAMEBUFFER_BINDING=36006]="DRAW_FRAMEBUFFER_BINDING",e[e.READ_FRAMEBUFFER_BINDING=36010]="READ_FRAMEBUFFER_BINDING",e[e.RENDERBUFFER_SAMPLES=36011]="RENDERBUFFER_SAMPLES",e[e.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER=36052]="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",e[e.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE=36182]="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",e[e.UNIFORM_BUFFER=35345]="UNIFORM_BUFFER",e[e.UNIFORM_BUFFER_BINDING=35368]="UNIFORM_BUFFER_BINDING",e[e.UNIFORM_BUFFER_START=35369]="UNIFORM_BUFFER_START",e[e.UNIFORM_BUFFER_SIZE=35370]="UNIFORM_BUFFER_SIZE",e[e.MAX_VERTEX_UNIFORM_BLOCKS=35371]="MAX_VERTEX_UNIFORM_BLOCKS",e[e.MAX_FRAGMENT_UNIFORM_BLOCKS=35373]="MAX_FRAGMENT_UNIFORM_BLOCKS",e[e.MAX_COMBINED_UNIFORM_BLOCKS=35374]="MAX_COMBINED_UNIFORM_BLOCKS",e[e.MAX_UNIFORM_BUFFER_BINDINGS=35375]="MAX_UNIFORM_BUFFER_BINDINGS",e[e.MAX_UNIFORM_BLOCK_SIZE=35376]="MAX_UNIFORM_BLOCK_SIZE",e[e.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS=35377]="MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",e[e.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS=35379]="MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",e[e.UNIFORM_BUFFER_OFFSET_ALIGNMENT=35380]="UNIFORM_BUFFER_OFFSET_ALIGNMENT",e[e.ACTIVE_UNIFORM_BLOCKS=35382]="ACTIVE_UNIFORM_BLOCKS",e[e.UNIFORM_TYPE=35383]="UNIFORM_TYPE",e[e.UNIFORM_SIZE=35384]="UNIFORM_SIZE",e[e.UNIFORM_BLOCK_INDEX=35386]="UNIFORM_BLOCK_INDEX",e[e.UNIFORM_OFFSET=35387]="UNIFORM_OFFSET",e[e.UNIFORM_ARRAY_STRIDE=35388]="UNIFORM_ARRAY_STRIDE",e[e.UNIFORM_MATRIX_STRIDE=35389]="UNIFORM_MATRIX_STRIDE",e[e.UNIFORM_IS_ROW_MAJOR=35390]="UNIFORM_IS_ROW_MAJOR",e[e.UNIFORM_BLOCK_BINDING=35391]="UNIFORM_BLOCK_BINDING",e[e.UNIFORM_BLOCK_DATA_SIZE=35392]="UNIFORM_BLOCK_DATA_SIZE",e[e.UNIFORM_BLOCK_ACTIVE_UNIFORMS=35394]="UNIFORM_BLOCK_ACTIVE_UNIFORMS",e[e.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES=35395]="UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",e[e.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER=35396]="UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",e[e.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER=35398]="UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",e[e.OBJECT_TYPE=37138]="OBJECT_TYPE",e[e.SYNC_CONDITION=37139]="SYNC_CONDITION",e[e.SYNC_STATUS=37140]="SYNC_STATUS",e[e.SYNC_FLAGS=37141]="SYNC_FLAGS",e[e.SYNC_FENCE=37142]="SYNC_FENCE",e[e.SYNC_GPU_COMMANDS_COMPLETE=37143]="SYNC_GPU_COMMANDS_COMPLETE",e[e.UNSIGNALED=37144]="UNSIGNALED",e[e.SIGNALED=37145]="SIGNALED",e[e.ALREADY_SIGNALED=37146]="ALREADY_SIGNALED",e[e.TIMEOUT_EXPIRED=37147]="TIMEOUT_EXPIRED",e[e.CONDITION_SATISFIED=37148]="CONDITION_SATISFIED",e[e.WAIT_FAILED=37149]="WAIT_FAILED",e[e.SYNC_FLUSH_COMMANDS_BIT=1]="SYNC_FLUSH_COMMANDS_BIT",e[e.COLOR=6144]="COLOR",e[e.DEPTH=6145]="DEPTH",e[e.STENCIL=6146]="STENCIL",e[e.MIN=32775]="MIN",e[e.MAX=32776]="MAX",e[e.DEPTH_COMPONENT24=33190]="DEPTH_COMPONENT24",e[e.STREAM_READ=35041]="STREAM_READ",e[e.STREAM_COPY=35042]="STREAM_COPY",e[e.STATIC_READ=35045]="STATIC_READ",e[e.STATIC_COPY=35046]="STATIC_COPY",e[e.DYNAMIC_READ=35049]="DYNAMIC_READ",e[e.DYNAMIC_COPY=35050]="DYNAMIC_COPY",e[e.DEPTH_COMPONENT32F=36012]="DEPTH_COMPONENT32F",e[e.DEPTH32F_STENCIL8=36013]="DEPTH32F_STENCIL8",e[e.INVALID_INDEX=4294967295]="INVALID_INDEX",e[e.TIMEOUT_IGNORED=-1]="TIMEOUT_IGNORED",e[e.MAX_CLIENT_WAIT_TIMEOUT_WEBGL=37447]="MAX_CLIENT_WAIT_TIMEOUT_WEBGL",e[e.UNMASKED_VENDOR_WEBGL=37445]="UNMASKED_VENDOR_WEBGL",e[e.UNMASKED_RENDERER_WEBGL=37446]="UNMASKED_RENDERER_WEBGL",e[e.MAX_TEXTURE_MAX_ANISOTROPY_EXT=34047]="MAX_TEXTURE_MAX_ANISOTROPY_EXT",e[e.TEXTURE_MAX_ANISOTROPY_EXT=34046]="TEXTURE_MAX_ANISOTROPY_EXT",e[e.R16_EXT=33322]="R16_EXT",e[e.RG16_EXT=33324]="RG16_EXT",e[e.RGB16_EXT=32852]="RGB16_EXT",e[e.RGBA16_EXT=32859]="RGBA16_EXT",e[e.R16_SNORM_EXT=36760]="R16_SNORM_EXT",e[e.RG16_SNORM_EXT=36761]="RG16_SNORM_EXT",e[e.RGB16_SNORM_EXT=36762]="RGB16_SNORM_EXT",e[e.RGBA16_SNORM_EXT=36763]="RGBA16_SNORM_EXT",e[e.COMPRESSED_RGB_S3TC_DXT1_EXT=33776]="COMPRESSED_RGB_S3TC_DXT1_EXT",e[e.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777]="COMPRESSED_RGBA_S3TC_DXT1_EXT",e[e.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778]="COMPRESSED_RGBA_S3TC_DXT3_EXT",e[e.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779]="COMPRESSED_RGBA_S3TC_DXT5_EXT",e[e.COMPRESSED_SRGB_S3TC_DXT1_EXT=35916]="COMPRESSED_SRGB_S3TC_DXT1_EXT",e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT=35917]="COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT",e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT=35918]="COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT",e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT=35919]="COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT",e[e.COMPRESSED_RED_RGTC1_EXT=36283]="COMPRESSED_RED_RGTC1_EXT",e[e.COMPRESSED_SIGNED_RED_RGTC1_EXT=36284]="COMPRESSED_SIGNED_RED_RGTC1_EXT",e[e.COMPRESSED_RED_GREEN_RGTC2_EXT=36285]="COMPRESSED_RED_GREEN_RGTC2_EXT",e[e.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT=36286]="COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT",e[e.COMPRESSED_RGBA_BPTC_UNORM_EXT=36492]="COMPRESSED_RGBA_BPTC_UNORM_EXT",e[e.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT=36493]="COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT",e[e.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT=36494]="COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT",e[e.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT=36495]="COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT",e[e.COMPRESSED_R11_EAC=37488]="COMPRESSED_R11_EAC",e[e.COMPRESSED_SIGNED_R11_EAC=37489]="COMPRESSED_SIGNED_R11_EAC",e[e.COMPRESSED_RG11_EAC=37490]="COMPRESSED_RG11_EAC",e[e.COMPRESSED_SIGNED_RG11_EAC=37491]="COMPRESSED_SIGNED_RG11_EAC",e[e.COMPRESSED_RGB8_ETC2=37492]="COMPRESSED_RGB8_ETC2",e[e.COMPRESSED_RGBA8_ETC2_EAC=37493]="COMPRESSED_RGBA8_ETC2_EAC",e[e.COMPRESSED_SRGB8_ETC2=37494]="COMPRESSED_SRGB8_ETC2",e[e.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC=37495]="COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",e[e.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2=37496]="COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",e[e.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2=37497]="COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",e[e.COMPRESSED_RGB_PVRTC_4BPPV1_IMG=35840]="COMPRESSED_RGB_PVRTC_4BPPV1_IMG",e[e.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG=35842]="COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",e[e.COMPRESSED_RGB_PVRTC_2BPPV1_IMG=35841]="COMPRESSED_RGB_PVRTC_2BPPV1_IMG",e[e.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG=35843]="COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",e[e.COMPRESSED_RGB_ETC1_WEBGL=36196]="COMPRESSED_RGB_ETC1_WEBGL",e[e.COMPRESSED_RGB_ATC_WEBGL=35986]="COMPRESSED_RGB_ATC_WEBGL",e[e.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL=35986]="COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL",e[e.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL=34798]="COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL",e[e.COMPRESSED_RGBA_ASTC_4x4_KHR=37808]="COMPRESSED_RGBA_ASTC_4x4_KHR",e[e.COMPRESSED_RGBA_ASTC_5x4_KHR=37809]="COMPRESSED_RGBA_ASTC_5x4_KHR",e[e.COMPRESSED_RGBA_ASTC_5x5_KHR=37810]="COMPRESSED_RGBA_ASTC_5x5_KHR",e[e.COMPRESSED_RGBA_ASTC_6x5_KHR=37811]="COMPRESSED_RGBA_ASTC_6x5_KHR",e[e.COMPRESSED_RGBA_ASTC_6x6_KHR=37812]="COMPRESSED_RGBA_ASTC_6x6_KHR",e[e.COMPRESSED_RGBA_ASTC_8x5_KHR=37813]="COMPRESSED_RGBA_ASTC_8x5_KHR",e[e.COMPRESSED_RGBA_ASTC_8x6_KHR=37814]="COMPRESSED_RGBA_ASTC_8x6_KHR",e[e.COMPRESSED_RGBA_ASTC_8x8_KHR=37815]="COMPRESSED_RGBA_ASTC_8x8_KHR",e[e.COMPRESSED_RGBA_ASTC_10x5_KHR=37816]="COMPRESSED_RGBA_ASTC_10x5_KHR",e[e.COMPRESSED_RGBA_ASTC_10x6_KHR=37817]="COMPRESSED_RGBA_ASTC_10x6_KHR",e[e.COMPRESSED_RGBA_ASTC_10x8_KHR=37818]="COMPRESSED_RGBA_ASTC_10x8_KHR",e[e.COMPRESSED_RGBA_ASTC_10x10_KHR=37819]="COMPRESSED_RGBA_ASTC_10x10_KHR",e[e.COMPRESSED_RGBA_ASTC_12x10_KHR=37820]="COMPRESSED_RGBA_ASTC_12x10_KHR",e[e.COMPRESSED_RGBA_ASTC_12x12_KHR=37821]="COMPRESSED_RGBA_ASTC_12x12_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR=37840]="COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR=37841]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR=37842]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR=37843]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR=37844]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR=37845]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR=37846]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR=37847]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR=37848]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR=37849]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR=37850]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR=37851]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR=37852]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR=37853]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",e[e.QUERY_COUNTER_BITS_EXT=34916]="QUERY_COUNTER_BITS_EXT",e[e.CURRENT_QUERY_EXT=34917]="CURRENT_QUERY_EXT",e[e.QUERY_RESULT_EXT=34918]="QUERY_RESULT_EXT",e[e.QUERY_RESULT_AVAILABLE_EXT=34919]="QUERY_RESULT_AVAILABLE_EXT",e[e.TIME_ELAPSED_EXT=35007]="TIME_ELAPSED_EXT",e[e.TIMESTAMP_EXT=36392]="TIMESTAMP_EXT",e[e.GPU_DISJOINT_EXT=36795]="GPU_DISJOINT_EXT",e[e.COMPLETION_STATUS_KHR=37297]="COMPLETION_STATUS_KHR",e[e.DEPTH_CLAMP_EXT=34383]="DEPTH_CLAMP_EXT",e[e.FIRST_VERTEX_CONVENTION_WEBGL=36429]="FIRST_VERTEX_CONVENTION_WEBGL",e[e.LAST_VERTEX_CONVENTION_WEBGL=36430]="LAST_VERTEX_CONVENTION_WEBGL",e[e.PROVOKING_VERTEX_WEBL=36431]="PROVOKING_VERTEX_WEBL",e[e.POLYGON_MODE_WEBGL=2880]="POLYGON_MODE_WEBGL",e[e.POLYGON_OFFSET_LINE_WEBGL=10754]="POLYGON_OFFSET_LINE_WEBGL",e[e.LINE_WEBGL=6913]="LINE_WEBGL",e[e.FILL_WEBGL=6914]="FILL_WEBGL",e[e.MAX_CLIP_DISTANCES_WEBGL=3378]="MAX_CLIP_DISTANCES_WEBGL",e[e.MAX_CULL_DISTANCES_WEBGL=33529]="MAX_CULL_DISTANCES_WEBGL",e[e.MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL=33530]="MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL",e[e.CLIP_DISTANCE0_WEBGL=12288]="CLIP_DISTANCE0_WEBGL",e[e.CLIP_DISTANCE1_WEBGL=12289]="CLIP_DISTANCE1_WEBGL",e[e.CLIP_DISTANCE2_WEBGL=12290]="CLIP_DISTANCE2_WEBGL",e[e.CLIP_DISTANCE3_WEBGL=12291]="CLIP_DISTANCE3_WEBGL",e[e.CLIP_DISTANCE4_WEBGL=12292]="CLIP_DISTANCE4_WEBGL",e[e.CLIP_DISTANCE5_WEBGL=12293]="CLIP_DISTANCE5_WEBGL",e[e.CLIP_DISTANCE6_WEBGL=12294]="CLIP_DISTANCE6_WEBGL",e[e.CLIP_DISTANCE7_WEBGL=12295]="CLIP_DISTANCE7_WEBGL",e[e.POLYGON_OFFSET_CLAMP_EXT=36379]="POLYGON_OFFSET_CLAMP_EXT",e[e.LOWER_LEFT_EXT=36001]="LOWER_LEFT_EXT",e[e.UPPER_LEFT_EXT=36002]="UPPER_LEFT_EXT",e[e.NEGATIVE_ONE_TO_ONE_EXT=37726]="NEGATIVE_ONE_TO_ONE_EXT",e[e.ZERO_TO_ONE_EXT=37727]="ZERO_TO_ONE_EXT",e[e.CLIP_ORIGIN_EXT=37724]="CLIP_ORIGIN_EXT",e[e.CLIP_DEPTH_MODE_EXT=37725]="CLIP_DEPTH_MODE_EXT",e[e.SRC1_COLOR_WEBGL=35065]="SRC1_COLOR_WEBGL",e[e.SRC1_ALPHA_WEBGL=34185]="SRC1_ALPHA_WEBGL",e[e.ONE_MINUS_SRC1_COLOR_WEBGL=35066]="ONE_MINUS_SRC1_COLOR_WEBGL",e[e.ONE_MINUS_SRC1_ALPHA_WEBGL=35067]="ONE_MINUS_SRC1_ALPHA_WEBGL",e[e.MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL=35068]="MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL",e[e.MIRROR_CLAMP_TO_EDGE_EXT=34627]="MIRROR_CLAMP_TO_EDGE_EXT"})(ci||(ci={}));const j_={WEBGL_depth_texture:{UNSIGNED_INT_24_8_WEBGL:34042},OES_element_index_uint:{},OES_texture_float:{},OES_texture_half_float:{HALF_FLOAT_OES:5131},EXT_color_buffer_float:{},OES_standard_derivatives:{FRAGMENT_SHADER_DERIVATIVE_HINT_OES:35723},EXT_frag_depth:{},EXT_blend_minmax:{MIN_EXT:32775,MAX_EXT:32776},EXT_shader_texture_lod:{}},K_=e=>({drawBuffersWEBGL(t){return e.drawBuffers(t)},COLOR_ATTACHMENT0_WEBGL:36064,COLOR_ATTACHMENT1_WEBGL:36065,COLOR_ATTACHMENT2_WEBGL:36066,COLOR_ATTACHMENT3_WEBGL:36067}),q_=e=>({VERTEX_ARRAY_BINDING_OES:34229,createVertexArrayOES(){return e.createVertexArray()},deleteVertexArrayOES(t){return e.deleteVertexArray(t)},isVertexArrayOES(t){return e.isVertexArray(t)},bindVertexArrayOES(t){return e.bindVertexArray(t)}}),G_=e=>({VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:35070,drawArraysInstancedANGLE(...t){return e.drawArraysInstanced(...t)},drawElementsInstancedANGLE(...t){return e.drawElementsInstanced(...t)},vertexAttribDivisorANGLE(...t){return e.vertexAttribDivisor(...t)}});function Z_(e=!0){const t=HTMLCanvasElement.prototype;if(!e&&t.originalGetContext){t.getContext=t.originalGetContext,t.originalGetContext=void 0;return}t.originalGetContext=t.getContext,t.getContext=function(i,n){if(i==="webgl"||i==="experimental-webgl"){const r=this.originalGetContext("webgl2",n);return r instanceof HTMLElement&&Q_(r),r}return this.originalGetContext(i,n)}}function Q_(e){e.getExtension("EXT_color_buffer_float");const t={...j_,WEBGL_disjoint_timer_query:e.getExtension("EXT_disjoint_timer_query_webgl2"),WEBGL_draw_buffers:K_(e),OES_vertex_array_object:q_(e),ANGLE_instanced_arrays:G_(e)},i=e.getExtension;e.getExtension=function(r){const s=i.call(e,r);return s||(r in t?t[r]:null)};const n=e.getSupportedExtensions;e.getSupportedExtensions=function(){const r=n.apply(e)||[];return r==null?void 0:r.concat(Object.keys(t))}}async function Hu(e,t){const i=document.getElementsByTagName("head")[0];if(!i)throw new Error("loadScript");const n=document.createElement("script");return n.setAttribute("type","text/javascript"),n.setAttribute("src",e),new Promise((r,s)=>{n.onload=r,n.onerror=o=>s(new Error(`Unable to load script '${e}': ${o}`)),i.appendChild(n)})}function fr(e){const t=e.luma||{_polyfilled:!1,extensions:{},softwareRenderer:!1};return t._polyfilled??(t._polyfilled=!1),t.extensions||(t.extensions={}),e.luma=t,t}const J_=1;let se=null,$u=!1;const Do={debugSpectorJS:C.get("debug-spectorjs"),debugSpectorJSUrl:"https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js",gl:void 0};async function eb(e){if(!globalThis.SPECTOR)try{await Hu(e.debugSpectorJSUrl||Do.debugSpectorJSUrl)}catch(t){C.warn(String(t))}}function tb(e){var t;if(e={...Do,...e},!e.debugSpectorJS)return null;if(!se&&globalThis.SPECTOR&&!((t=globalThis.luma)!=null&&t.spector)){C.probe(J_,"SPECTOR found and initialized. Start with `luma.spector.displayUI()`")();const{Spector:i}=globalThis.SPECTOR;se=new i,globalThis.luma&&(globalThis.luma.spector=se)}if(!se)return null;if($u||($u=!0,se.spyCanvases(),se==null||se.onCaptureStarted.add(i=>C.info("Spector capture started:",i)()),se==null||se.onCapture.add(i=>{C.info("Spector capture complete:",i)(),se==null||se.getResultUI(),se==null||se.resultView.display(),se==null||se.resultView.addCapture(i)})),e.gl){const i=e.gl,n=fr(i),r=n.device;se==null||se.startCapture(e.gl,500),n.device=r,new Promise(s=>setTimeout(s,2e3)).then(s=>{C.info("Spector capture stopped after 2 seconds")(),se==null||se.stopCapture()})}return se}const ib="https://unpkg.com/webgl-debug@2.0.1/index.js";function Xu(e){return e.luma=e.luma||{},e.luma}async function nb(){Mt()&&!globalThis.WebGLDebugUtils&&(globalThis.global=globalThis.global||globalThis,globalThis.global.module={},await Hu(ib))}function rb(e,t={}){return t.debugWebGL||t.traceWebGL?ob(e,t):sb(e)}function sb(e){const t=Xu(e);return t.realContext?t.realContext:e}function ob(e,t){if(!globalThis.WebGLDebugUtils)return C.warn("webgl-debug not loaded")(),e;const i=Xu(e);if(i.debugContext)return i.debugContext;globalThis.WebGLDebugUtils.init({...ci,...e});const n=globalThis.WebGLDebugUtils.makeDebugContext(e,ab.bind(null,t),lb.bind(null,t));for(const o in ci)!(o in n)&&typeof ci[o]=="number"&&(n[o]=ci[o]);class r{}Object.setPrototypeOf(n,Object.getPrototypeOf(e)),Object.setPrototypeOf(r,n);const s=Object.create(r);return i.realContext=e,i.debugContext=s,s.luma=i,s.debug=!0,s}function Yu(e,t){t=Array.from(t).map(n=>n===void 0?"undefined":n);let i=globalThis.WebGLDebugUtils.glFunctionArgsToString(e,t);return i=`${i.slice(0,100)}${i.length>100?"...":""}`,`gl.${e}(${i})`}function ab(e,t,i,n){n=Array.from(n).map(a=>a===void 0?"undefined":a);const r=globalThis.WebGLDebugUtils.glEnumToString(t),s=globalThis.WebGLDebugUtils.glFunctionArgsToString(i,n),o=`${r} in gl.${i}(${s})`;C.error("%cWebGL","color: white; background: red; padding: 2px 6px; border-radius: 3px;",o)();debugger;throw new Error(o)}function lb(e,t,i){let n="";e.traceWebGL&&C.level>=1&&(n=Yu(t,i),C.info(1,"%cWebGL","color: white; background: blue; padding: 2px 6px; border-radius: 3px;",n)());for(const r of i)if(r===void 0){n=n||Yu(t,i);debugger}}const Ki=1;class cb extends QS{constructor(){super();f(this,"type","webgl");Bt.defaultProps={...Bt.defaultProps,...Do}}enforceWebGL2(i){Z_(i)}isSupported(){return typeof WebGL2RenderingContext<"u"}isDeviceHandle(i){return typeof WebGL2RenderingContext<"u"&&i instanceof WebGL2RenderingContext?!0:(typeof WebGLRenderingContext<"u"&&i instanceof WebGLRenderingContext&&C.warn("WebGL1 is not supported",i)(),!1)}async attach(i,n={}){const{WebGLDevice:r}=await Promise.resolve().then(()=>bd);if(i instanceof r)return i;const s=r.getDeviceFromContext(i);if(s)return s;if(!ub(i))throw new Error("Invalid WebGL2RenderingContext");const o=n.createCanvasContext===!0?{}:n.createCanvasContext;return new r({...n,_handle:i,createCanvasContext:{canvas:i.canvas,autoResize:!1,...o}})}async create(i={}){const{WebGLDevice:n}=await Promise.resolve().then(()=>bd),r=[];(i.debugWebGL||i.debug)&&r.push(nb()),i.debugSpectorJS&&r.push(eb(i));const s=await Promise.allSettled(r);for(const o of s)o.status==="rejected"&&C.error(`Failed to initialize debug libraries ${o.reason}`)();try{const o=new n(i);C.groupCollapsed(Ki,`WebGLDevice ${o.id} created`)();const a=`${o._reused?"Reusing":"Created"} device with WebGL2 ${o.props.debug?"debug ":""}context: ${o.info.vendor}, ${o.info.renderer} for canvas: ${o.canvasContext.id}`;return C.probe(Ki,a)(),C.table(Ki,o.info)(),o}finally{C.groupEnd(Ki)(),C.info(Ki,"%cWebGL call tracing: luma.log.set('debug-webgl') ","color: white; background: blue; padding: 2px 6px; border-radius: 3px;")()}}}function ub(e){return typeof WebGL2RenderingContext<"u"&&e instanceof WebGL2RenderingContext?!0:!!(e&&typeof e.createVertexArray=="function")}const db=new cb,Fo={3042:!1,32773:new Float32Array([0,0,0,0]),32777:32774,34877:32774,32969:1,32968:0,32971:1,32970:0,3106:new Float32Array([0,0,0,0]),3107:[!0,!0,!0,!0],2884:!1,2885:1029,2929:!1,2931:1,2932:513,2928:new Float32Array([0,1]),2930:!0,3024:!0,35725:null,36006:null,36007:null,34229:null,34964:null,2886:2305,33170:4352,2849:1,32823:!1,32824:0,10752:0,32926:!1,32928:!1,32938:1,32939:!1,3089:!1,3088:new Int32Array([0,0,1024,1024]),2960:!1,2961:0,2968:4294967295,36005:4294967295,2962:519,2967:0,2963:4294967295,34816:519,36003:0,36004:4294967295,2964:7680,2965:7680,2966:7680,34817:7680,34818:7680,34819:7680,2978:[0,0,1024,1024],36389:null,36662:null,36663:null,35053:null,35055:null,35723:4352,36010:null,35977:!1,3333:4,3317:4,37440:!1,37441:!1,37443:37444,3330:0,3332:0,3331:0,3314:0,32878:0,3316:0,3315:0,32877:0},xe=(e,t,i)=>t?e.enable(i):e.disable(i),ju=(e,t,i)=>e.hint(i,t),Ue=(e,t,i)=>e.pixelStorei(i,t),Ku=(e,t,i)=>{const n=i===36006?36009:36008;return e.bindFramebuffer(n,t)},qi=(e,t,i)=>{const r={34964:34962,36662:36662,36663:36663,35053:35051,35055:35052}[i];e.bindBuffer(r,t)};function Mo(e){return Array.isArray(e)||ArrayBuffer.isView(e)&&!(e instanceof DataView)}const hb={3042:xe,32773:(e,t)=>e.blendColor(...t),32777:"blendEquation",34877:"blendEquation",32969:"blendFunc",32968:"blendFunc",32971:"blendFunc",32970:"blendFunc",3106:(e,t)=>e.clearColor(...t),3107:(e,t)=>e.colorMask(...t),2884:xe,2885:(e,t)=>e.cullFace(t),2929:xe,2931:(e,t)=>e.clearDepth(t),2932:(e,t)=>e.depthFunc(t),2928:(e,t)=>e.depthRange(...t),2930:(e,t)=>e.depthMask(t),3024:xe,35723:ju,35725:(e,t)=>e.useProgram(t),36007:(e,t)=>e.bindRenderbuffer(36161,t),36389:(e,t)=>{var i;return(i=e.bindTransformFeedback)==null?void 0:i.call(e,36386,t)},34229:(e,t)=>e.bindVertexArray(t),36006:Ku,36010:Ku,34964:qi,36662:qi,36663:qi,35053:qi,35055:qi,2886:(e,t)=>e.frontFace(t),33170:ju,2849:(e,t)=>e.lineWidth(t),32823:xe,32824:"polygonOffset",10752:"polygonOffset",35977:xe,32926:xe,32928:xe,32938:"sampleCoverage",32939:"sampleCoverage",3089:xe,3088:(e,t)=>e.scissor(...t),2960:xe,2961:(e,t)=>e.clearStencil(t),2968:(e,t)=>e.stencilMaskSeparate(1028,t),36005:(e,t)=>e.stencilMaskSeparate(1029,t),2962:"stencilFuncFront",2967:"stencilFuncFront",2963:"stencilFuncFront",34816:"stencilFuncBack",36003:"stencilFuncBack",36004:"stencilFuncBack",2964:"stencilOpFront",2965:"stencilOpFront",2966:"stencilOpFront",34817:"stencilOpBack",34818:"stencilOpBack",34819:"stencilOpBack",2978:(e,t)=>e.viewport(...t),34383:xe,10754:xe,12288:xe,12289:xe,12290:xe,12291:xe,12292:xe,12293:xe,12294:xe,12295:xe,3333:Ue,3317:Ue,37440:Ue,37441:Ue,37443:Ue,3330:Ue,3332:Ue,3331:Ue,3314:Ue,32878:Ue,3316:Ue,3315:Ue,32877:Ue,framebuffer:(e,t)=>{const i=t&&"handle"in t?t.handle:t;return e.bindFramebuffer(36160,i)},blend:(e,t)=>t?e.enable(3042):e.disable(3042),blendColor:(e,t)=>e.blendColor(...t),blendEquation:(e,t)=>{const i=typeof t=="number"?[t,t]:t;e.blendEquationSeparate(...i)},blendFunc:(e,t)=>{const i=(t==null?void 0:t.length)===2?[...t,...t]:t;e.blendFuncSeparate(...i)},clearColor:(e,t)=>e.clearColor(...t),clearDepth:(e,t)=>e.clearDepth(t),clearStencil:(e,t)=>e.clearStencil(t),colorMask:(e,t)=>e.colorMask(...t),cull:(e,t)=>t?e.enable(2884):e.disable(2884),cullFace:(e,t)=>e.cullFace(t),depthTest:(e,t)=>t?e.enable(2929):e.disable(2929),depthFunc:(e,t)=>e.depthFunc(t),depthMask:(e,t)=>e.depthMask(t),depthRange:(e,t)=>e.depthRange(...t),dither:(e,t)=>t?e.enable(3024):e.disable(3024),derivativeHint:(e,t)=>{e.hint(35723,t)},frontFace:(e,t)=>e.frontFace(t),mipmapHint:(e,t)=>e.hint(33170,t),lineWidth:(e,t)=>e.lineWidth(t),polygonOffsetFill:(e,t)=>t?e.enable(32823):e.disable(32823),polygonOffset:(e,t)=>e.polygonOffset(...t),sampleCoverage:(e,t)=>e.sampleCoverage(t[0],t[1]||!1),scissorTest:(e,t)=>t?e.enable(3089):e.disable(3089),scissor:(e,t)=>e.scissor(...t),stencilTest:(e,t)=>t?e.enable(2960):e.disable(2960),stencilMask:(e,t)=>{t=Mo(t)?t:[t,t];const[i,n]=t;e.stencilMaskSeparate(1028,i),e.stencilMaskSeparate(1029,n)},stencilFunc:(e,t)=>{t=Mo(t)&&t.length===3?[...t,...t]:t;const[i,n,r,s,o,a]=t;e.stencilFuncSeparate(1028,i,n,r),e.stencilFuncSeparate(1029,s,o,a)},stencilOp:(e,t)=>{t=Mo(t)&&t.length===3?[...t,...t]:t;const[i,n,r,s,o,a]=t;e.stencilOpSeparate(1028,i,n,r),e.stencilOpSeparate(1029,s,o,a)},viewport:(e,t)=>e.viewport(...t)};function fe(e,t,i){return t[e]!==void 0?t[e]:i[e]}const fb={blendEquation:(e,t,i)=>e.blendEquationSeparate(fe(32777,t,i),fe(34877,t,i)),blendFunc:(e,t,i)=>e.blendFuncSeparate(fe(32969,t,i),fe(32968,t,i),fe(32971,t,i),fe(32970,t,i)),polygonOffset:(e,t,i)=>e.polygonOffset(fe(32824,t,i),fe(10752,t,i)),sampleCoverage:(e,t,i)=>e.sampleCoverage(fe(32938,t,i),fe(32939,t,i)),stencilFuncFront:(e,t,i)=>e.stencilFuncSeparate(1028,fe(2962,t,i),fe(2967,t,i),fe(2963,t,i)),stencilFuncBack:(e,t,i)=>e.stencilFuncSeparate(1029,fe(34816,t,i),fe(36003,t,i),fe(36004,t,i)),stencilOpFront:(e,t,i)=>e.stencilOpSeparate(1028,fe(2964,t,i),fe(2965,t,i),fe(2966,t,i)),stencilOpBack:(e,t,i)=>e.stencilOpSeparate(1029,fe(34817,t,i),fe(34818,t,i),fe(34819,t,i))},qu={enable:(e,t)=>e({[t]:!0}),disable:(e,t)=>e({[t]:!1}),pixelStorei:(e,t,i)=>e({[t]:i}),hint:(e,t,i)=>e({[t]:i}),useProgram:(e,t)=>e({35725:t}),bindRenderbuffer:(e,t,i)=>e({36007:i}),bindTransformFeedback:(e,t,i)=>e({36389:i}),bindVertexArray:(e,t)=>e({34229:t}),bindFramebuffer:(e,t,i)=>{switch(t){case 36160:return e({36006:i,36010:i});case 36009:return e({36006:i});case 36008:return e({36010:i});default:return null}},bindBuffer:(e,t,i)=>{const n={34962:[34964],36662:[36662],36663:[36663],35051:[35053],35052:[35055]}[t];return n?e({[n]:i}):{valueChanged:!0}},blendColor:(e,t,i,n,r)=>e({32773:new Float32Array([t,i,n,r])}),blendEquation:(e,t)=>e({32777:t,34877:t}),blendEquationSeparate:(e,t,i)=>e({32777:t,34877:i}),blendFunc:(e,t,i)=>e({32969:t,32968:i,32971:t,32970:i}),blendFuncSeparate:(e,t,i,n,r)=>e({32969:t,32968:i,32971:n,32970:r}),clearColor:(e,t,i,n,r)=>e({3106:new Float32Array([t,i,n,r])}),clearDepth:(e,t)=>e({2931:t}),clearStencil:(e,t)=>e({2961:t}),colorMask:(e,t,i,n,r)=>e({3107:[t,i,n,r]}),cullFace:(e,t)=>e({2885:t}),depthFunc:(e,t)=>e({2932:t}),depthRange:(e,t,i)=>e({2928:new Float32Array([t,i])}),depthMask:(e,t)=>e({2930:t}),frontFace:(e,t)=>e({2886:t}),lineWidth:(e,t)=>e({2849:t}),polygonOffset:(e,t,i)=>e({32824:t,10752:i}),sampleCoverage:(e,t,i)=>e({32938:t,32939:i}),scissor:(e,t,i,n,r)=>e({3088:new Int32Array([t,i,n,r])}),stencilMask:(e,t)=>e({2968:t,36005:t}),stencilMaskSeparate:(e,t,i)=>e({[t===1028?2968:36005]:i}),stencilFunc:(e,t,i,n)=>e({2962:t,2967:i,2963:n,34816:t,36003:i,36004:n}),stencilFuncSeparate:(e,t,i,n,r)=>e({[t===1028?2962:34816]:i,[t===1028?2967:36003]:n,[t===1028?2963:36004]:r}),stencilOp:(e,t,i,n)=>e({2964:t,2965:i,2966:n,34817:t,34818:i,34819:n}),stencilOpSeparate:(e,t,i,n,r)=>e({[t===1028?2964:34817]:i,[t===1028?2965:34818]:n,[t===1028?2966:34819]:r}),viewport:(e,t,i,n,r)=>e({2978:[t,i,n,r]})},st=(e,t)=>e.isEnabled(t),Gu={3042:st,2884:st,2929:st,3024:st,32823:st,32926:st,32928:st,3089:st,2960:st,35977:st},pb=new Set([34016,36388,36387,35983,35368,34965,35739,35738,3074,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,35097,32873,35869,32874,34068]);function ui(e,t){var r;if(mb(t))return;const i={};for(const s in t){const o=Number(s),a=hb[s];a&&(typeof a=="string"?i[a]=!0:a(e,t[s],o))}const n=(r=e.lumaState)==null?void 0:r.cache;if(n)for(const s in i){const o=fb[s];o(e,t,n)}}function Zu(e,t=Fo){if(typeof t=="number"){const r=t,s=Gu[r];return s?s(e,r):e.getParameter(r)}const i=Array.isArray(t)?t:Object.keys(t),n={};for(const r of i){const s=Gu[r];n[r]=s?s(e,Number(r)):e.getParameter(Number(r))}return n}function gb(e){ui(e,Fo)}function mb(e){for(const t in e)return!1;return!0}function xb(e,t){if(e===t)return!0;if(Qu(e)&&Qu(t)&&e.length===t.length){for(let i=0;i{}),this._updateCache=this._updateCache.bind(this),Object.seal(this)}static get(t){return t.lumaState}push(t={}){this.stateStack.push({})}pop(){const t=this.stateStack[this.stateStack.length-1];ui(this.gl,t),this.stateStack.pop()}trackState(t,i){if(this.cache=i!=null&&i.copyState?Zu(t):Object.assign({},Fo),this.initialized)throw new Error("WebGLStateTracker");this.initialized=!0,this.gl.lumaState=this,yb(t);for(const n in qu){const r=qu[n];Sb(t,n,r)}Ju(t,"getParameter"),Ju(t,"isEnabled")}_updateCache(t){let i=!1,n;const r=this.stateStack.length>0?this.stateStack[this.stateStack.length-1]:null;for(const s in t){const o=t[s],a=this.cache[s];xb(o,a)||(i=!0,n=a,r&&!(s in r)&&(r[s]=a),this.cache[s]=o)}return{valueChanged:i,oldValue:n}}}function Ju(e,t){const i=e[t].bind(e);e[t]=function(r){if(r===void 0||pb.has(r))return i(r);const s=Pt.get(e);return r in s.cache||(s.cache[r]=i(r)),s.enable?s.cache[r]:i(r)},Object.defineProperty(e[t],"name",{value:`${t}-from-cache`,configurable:!1})}function Sb(e,t,i){if(!e[t])return;const n=e[t].bind(e);e[t]=function(...s){const o=Pt.get(e),{valueChanged:a,oldValue:l}=i(o._updateCache,...s);return a&&n(...s),l},Object.defineProperty(e[t],"name",{value:`${t}-to-cache`,configurable:!1})}function yb(e){const t=e.useProgram.bind(e);e.useProgram=function(n){const r=Pt.get(e);r.program!==n&&(t(n),r.program=n)}}function _b(e,t,i){let n="";const r=l=>{const c=l.statusMessage;c&&(n||(n=c))};e.addEventListener("webglcontextcreationerror",r,!1);const s=i.failIfMajorPerformanceCaveat!==!0,o={preserveDrawingBuffer:!0,...i,failIfMajorPerformanceCaveat:!0};let a=null;try{a||(a=e.getContext("webgl2",o)),!a&&o.failIfMajorPerformanceCaveat&&(n||(n="Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow."));let l=!1;if(!a&&s&&(o.failIfMajorPerformanceCaveat=!1,a=e.getContext("webgl2",o),l=!0),a||(a=e.getContext("webgl",{}),a&&(a=null,n||(n="Your browser only supports WebGL1"))),!a)throw n||(n="Your browser does not support WebGL"),new Error(`Failed to create WebGL context: ${n}`);const c=fr(a);c.softwareRenderer=l;const{onContextLost:u,onContextRestored:d}=t;return e.addEventListener("webglcontextlost",h=>u(h),!1),e.addEventListener("webglcontextrestored",h=>d(h),!1),a}finally{e.removeEventListener("webglcontextcreationerror",r,!1)}}function Ot(e,t,i){return i[t]===void 0&&(i[t]=e.getExtension(t)||null),i[t]}function bb(e,t){const i=e.getParameter(7936),n=e.getParameter(7937);Ot(e,"WEBGL_debug_renderer_info",t);const r=t.WEBGL_debug_renderer_info,s=e.getParameter(r?r.UNMASKED_VENDOR_WEBGL:7936),o=e.getParameter(r?r.UNMASKED_RENDERER_WEBGL:7937),a=s||i,l=o||n,c=e.getParameter(7938),u=ed(a,l),d=Tb(a,l),h=vb(a,l);return{type:"webgl",gpu:u,gpuType:h,gpuBackend:d,vendor:a,renderer:l,version:c,shadingLanguage:"glsl",shadingLanguageVersion:300}}function ed(e,t){return/NVIDIA/i.exec(e)||/NVIDIA/i.exec(t)?"nvidia":/INTEL/i.exec(e)||/INTEL/i.exec(t)?"intel":/Apple/i.exec(e)||/Apple/i.exec(t)?"apple":/AMD/i.exec(e)||/AMD/i.exec(t)||/ATI/i.exec(e)||/ATI/i.exec(t)?"amd":/SwiftShader/i.exec(e)||/SwiftShader/i.exec(t)?"software":"unknown"}function Tb(e,t){return/Metal/i.exec(e)||/Metal/i.exec(t)?"metal":/ANGLE/i.exec(e)||/ANGLE/i.exec(t)?"opengl":"unknown"}function vb(e,t){if(/SwiftShader/i.exec(e)||/SwiftShader/i.exec(t))return"cpu";switch(ed(e,t)){case"apple":return Pb(e,t)?"integrated":"unknown";case"intel":return"integrated";case"software":return"cpu";case"unknown":return"unknown";default:return"discrete"}}function Pb(e,t){return/Apple (M\d|A\d|GPU)/i.test(`${e} ${t}`)}function td(e){switch(e){case"uint8":return 5121;case"sint8":return 5120;case"unorm8":return 5121;case"snorm8":return 5120;case"uint16":return 5123;case"sint16":return 5122;case"unorm16":return 5123;case"snorm16":return 5122;case"uint32":return 5125;case"sint32":return 5124;case"float16":return 5131;case"float32":return 5126}throw new Error(String(e))}const Gi="WEBGL_compressed_texture_s3tc",Zi="WEBGL_compressed_texture_s3tc_srgb",di="EXT_texture_compression_rgtc",hi="EXT_texture_compression_bptc",Cb="WEBGL_compressed_texture_etc",Ab="WEBGL_compressed_texture_astc",Rb="WEBGL_compressed_texture_etc1",wb="WEBGL_compressed_texture_pvrtc",Eb="WEBGL_compressed_texture_atc",Ib="EXT_texture_norm16",id="EXT_render_snorm",nd="EXT_color_buffer_float",No="snorm8-renderable-webgl",Bo="norm16-renderable-webgl",Oo="snorm16-renderable-webgl",Uo="float16-renderable-webgl",pr="float32-renderable-webgl",kb="rgb9e5ufloat-renderable-webgl",zo={"float32-renderable-webgl":{extensions:[nd]},"float16-renderable-webgl":{extensions:["EXT_color_buffer_half_float"]},"rgb9e5ufloat-renderable-webgl":{extensions:["WEBGL_render_shared_exponent"]},"snorm8-renderable-webgl":{extensions:[id]},"norm16-webgl":{extensions:[Ib]},"norm16-renderable-webgl":{features:["norm16-webgl"]},"snorm16-renderable-webgl":{features:["norm16-webgl"],extensions:[id]},"float32-filterable":{extensions:["OES_texture_float_linear"]},"float16-filterable-webgl":{extensions:["OES_texture_half_float_linear"]},"texture-filterable-anisotropic-webgl":{extensions:["EXT_texture_filter_anisotropic"]},"texture-blend-float-webgl":{extensions:["EXT_float_blend"]},"texture-compression-bc":{extensions:[Gi,Zi,di,hi]},"texture-compression-bc5-webgl":{extensions:[di]},"texture-compression-bc7-webgl":{extensions:[hi]},"texture-compression-etc2":{extensions:[Cb]},"texture-compression-astc":{extensions:[Ab]},"texture-compression-etc1-webgl":{extensions:[Rb]},"texture-compression-pvrtc-webgl":{extensions:[wb]},"texture-compression-atc-webgl":{extensions:[Eb]}};function Db(e){return e in zo}function rd(e,t,i){return sd(e,t,i,new Set)}function sd(e,t,i,n){const r=zo[t];if(!r||n.has(t))return!1;n.add(t);const s=(r.features||[]).every(o=>sd(e,o,i,n));return n.delete(t),s?(r.extensions||[]).every(o=>!!Ot(e,o,i)):!1}const gr={r8unorm:{gl:33321,rb:!0},r8snorm:{gl:36756,r:No},r8uint:{gl:33330,rb:!0},r8sint:{gl:33329,rb:!0},rg8unorm:{gl:33323,rb:!0},rg8snorm:{gl:36757,r:No},rg8uint:{gl:33336,rb:!0},rg8sint:{gl:33335,rb:!0},r16uint:{gl:33332,rb:!0},r16sint:{gl:33331,rb:!0},r16float:{gl:33325,rb:!0,r:Uo},r16unorm:{gl:33322,rb:!0,r:Bo},r16snorm:{gl:36760,r:Oo},"rgba4unorm-webgl":{gl:32854,rb:!0},"rgb565unorm-webgl":{gl:36194,rb:!0},"rgb5a1unorm-webgl":{gl:32855,rb:!0},"rgb8unorm-webgl":{gl:32849},"rgb8snorm-webgl":{gl:36758},rgba8unorm:{gl:32856},"rgba8unorm-srgb":{gl:35907},rgba8snorm:{gl:36759,r:No},rgba8uint:{gl:36220},rgba8sint:{gl:36238},bgra8unorm:{},"bgra8unorm-srgb":{},rg16uint:{gl:33338},rg16sint:{gl:33337},rg16float:{gl:33327,rb:!0,r:Uo},rg16unorm:{gl:33324,r:Bo},rg16snorm:{gl:36761,r:Oo},r32uint:{gl:33334,rb:!0},r32sint:{gl:33333,rb:!0},r32float:{gl:33326,r:pr},rgb9e5ufloat:{gl:35901,r:kb},rg11b10ufloat:{gl:35898,rb:!0},rgb10a2unorm:{gl:32857,rb:!0},rgb10a2uint:{gl:36975,rb:!0},"rgb16unorm-webgl":{gl:32852,r:!1},"rgb16snorm-webgl":{gl:36762,r:!1},rg32uint:{gl:33340,rb:!0},rg32sint:{gl:33339,rb:!0},rg32float:{gl:33328,rb:!0,r:pr},rgba16uint:{gl:36214,rb:!0},rgba16sint:{gl:36232,rb:!0},rgba16float:{gl:34842,r:Uo},rgba16unorm:{gl:32859,rb:!0,r:Bo},rgba16snorm:{gl:36763,r:Oo},"rgb32float-webgl":{gl:34837,x:nd,r:pr,dataFormat:6407,types:[5126]},rgba32uint:{gl:36208,rb:!0},rgba32sint:{gl:36226,rb:!0},rgba32float:{gl:34836,rb:!0,r:pr},stencil8:{gl:36168,rb:!0},depth16unorm:{gl:33189,dataFormat:6402,types:[5123],rb:!0},depth24plus:{gl:33190,dataFormat:6402,types:[5125]},depth32float:{gl:36012,dataFormat:6402,types:[5126],rb:!0},"depth24plus-stencil8":{gl:35056,rb:!0,depthTexture:!0,dataFormat:34041,types:[34042]},"depth32float-stencil8":{gl:36013,dataFormat:34041,types:[36269],rb:!0},"bc1-rgb-unorm-webgl":{gl:33776,x:Gi},"bc1-rgb-unorm-srgb-webgl":{gl:35916,x:Zi},"bc1-rgba-unorm":{gl:33777,x:Gi},"bc1-rgba-unorm-srgb":{gl:35916,x:Zi},"bc2-rgba-unorm":{gl:33778,x:Gi},"bc2-rgba-unorm-srgb":{gl:35918,x:Zi},"bc3-rgba-unorm":{gl:33779,x:Gi},"bc3-rgba-unorm-srgb":{gl:35919,x:Zi},"bc4-r-unorm":{gl:36283,x:di},"bc4-r-snorm":{gl:36284,x:di},"bc5-rg-unorm":{gl:36285,x:di},"bc5-rg-snorm":{gl:36286,x:di},"bc6h-rgb-ufloat":{gl:36495,x:hi},"bc6h-rgb-float":{gl:36494,x:hi},"bc7-rgba-unorm":{gl:36492,x:hi},"bc7-rgba-unorm-srgb":{gl:36493,x:hi},"etc2-rgb8unorm":{gl:37492},"etc2-rgb8unorm-srgb":{gl:37494},"etc2-rgb8a1unorm":{gl:37496},"etc2-rgb8a1unorm-srgb":{gl:37497},"etc2-rgba8unorm":{gl:37493},"etc2-rgba8unorm-srgb":{gl:37495},"eac-r11unorm":{gl:37488},"eac-r11snorm":{gl:37489},"eac-rg11unorm":{gl:37490},"eac-rg11snorm":{gl:37491},"astc-4x4-unorm":{gl:37808},"astc-4x4-unorm-srgb":{gl:37840},"astc-5x4-unorm":{gl:37809},"astc-5x4-unorm-srgb":{gl:37841},"astc-5x5-unorm":{gl:37810},"astc-5x5-unorm-srgb":{gl:37842},"astc-6x5-unorm":{gl:37811},"astc-6x5-unorm-srgb":{gl:37843},"astc-6x6-unorm":{gl:37812},"astc-6x6-unorm-srgb":{gl:37844},"astc-8x5-unorm":{gl:37813},"astc-8x5-unorm-srgb":{gl:37845},"astc-8x6-unorm":{gl:37814},"astc-8x6-unorm-srgb":{gl:37846},"astc-8x8-unorm":{gl:37815},"astc-8x8-unorm-srgb":{gl:37847},"astc-10x5-unorm":{gl:37816},"astc-10x5-unorm-srgb":{gl:37848},"astc-10x6-unorm":{gl:37817},"astc-10x6-unorm-srgb":{gl:37849},"astc-10x8-unorm":{gl:37818},"astc-10x8-unorm-srgb":{gl:37850},"astc-10x10-unorm":{gl:37819},"astc-10x10-unorm-srgb":{gl:37851},"astc-12x10-unorm":{gl:37820},"astc-12x10-unorm-srgb":{gl:37852},"astc-12x12-unorm":{gl:37821},"astc-12x12-unorm-srgb":{gl:37853},"pvrtc-rgb4unorm-webgl":{gl:35840},"pvrtc-rgba4unorm-webgl":{gl:35842},"pvrtc-rgb2unorm-webgl":{gl:35841},"pvrtc-rgba2unorm-webgl":{gl:35843},"etc1-rbg-unorm-webgl":{gl:36196},"atc-rgb-unorm-webgl":{gl:35986},"atc-rgba-unorm-webgl":{gl:35986},"atc-rgbai-unorm-webgl":{gl:34798}};function Fb(e,t,i){let n=t.create;const r=gr[t.format];(r==null?void 0:r.gl)===void 0&&(n=!1),r!=null&&r.x&&(n=n&&!!Ot(e,r.x,i)),t.format==="stencil8"&&(n=!1);const s=(r==null?void 0:r.r)===!1?!1:(r==null?void 0:r.r)===void 0||rd(e,r.r,i),o=n&&t.render&&s&&Mb(e,t.format,i);return{format:t.format,create:n&&t.create,render:o,filter:n&&t.filter,blend:n&&t.blend,store:n&&t.store}}function Mb(e,t,i){const n=gr[t],r=n==null?void 0:n.gl;if(r===void 0||n!=null&&n.x&&!Ot(e,n.x,i))return!1;const s=e.getParameter(32873),o=e.getParameter(36006),a=e.createTexture(),l=e.createFramebuffer();if(!a||!l)return!1;const c=0;let u=Number(e.getError());for(;u!==c;)u=e.getError();let d=!1;try{if(e.bindTexture(3553,a),e.texStorage2D(3553,1,r,1,1),Number(e.getError())!==c)return!1;e.bindFramebuffer(36160,l),e.framebufferTexture2D(36160,36064,3553,a,0),d=Number(e.checkFramebufferStatus(36160))===36053&&Number(e.getError())===c}finally{e.bindFramebuffer(36160,o),e.deleteFramebuffer(l),e.bindTexture(3553,s),e.deleteTexture(a)}return d}function od(e){var r;const t=gr[e],i=Ob(e),n=Ve.getInfo(e);return n.compressed&&(t.dataFormat=i),{internalFormat:i,format:(t==null?void 0:t.dataFormat)||Bb(n.channels,n.integer,n.normalized,i),type:n.dataType?td(n.dataType):((r=t==null?void 0:t.types)==null?void 0:r[0])||5121,compressed:n.compressed||!1}}function Nb(e){switch(Ve.getInfo(e).attachment){case"depth":return 36096;case"stencil":return 36128;case"depth-stencil":return 33306;default:throw new Error(`Not a depth stencil format: ${e}`)}}function Bb(e,t,i,n){if(n===6408||n===6407)return n;switch(e){case"r":return t&&!i?36244:6403;case"rg":return t&&!i?33320:33319;case"rgb":return t&&!i?36248:6407;case"rgba":return t&&!i?36249:6408;case"bgra":throw new Error("bgra pixels not supported by WebGL");default:return 6408}}function Ob(e){const t=gr[e],i=t==null?void 0:t.gl;if(i===void 0)throw new Error(`Unsupported texture format ${e}`);return i}const ad={"depth-clip-control":"EXT_depth_clamp","timestamp-query":"EXT_disjoint_timer_query_webgl2","compilation-status-async-webgl":"KHR_parallel_shader_compile","polygon-mode-webgl":"WEBGL_polygon_mode","provoking-vertex-webgl":"WEBGL_provoking_vertex","shader-clip-cull-distance-webgl":"WEBGL_clip_cull_distance","shader-noperspective-interpolation-webgl":"NV_shader_noperspective_interpolation","shader-conservative-depth-webgl":"EXT_conservative_depth"};class Ub extends YS{constructor(i,n,r){super([],r);f(this,"gl");f(this,"extensions");f(this,"testedFeatures",new Set);this.gl=i,this.extensions=n,Ot(i,"EXT_color_buffer_float",n)}*[Symbol.iterator](){const i=this.getFeatures();for(const n of i)this.has(n)&&(yield n);return[]}has(i){var n;return(n=this.disabledFeatures)!=null&&n[i]?!1:(this.testedFeatures.has(i)||(this.testedFeatures.add(i),Db(i)&&rd(this.gl,i,this.extensions)&&this.features.add(i),this.getWebGLFeature(i)&&this.features.add(i)),this.features.has(i))}initializeFeatures(){const i=this.getFeatures().filter(n=>n!=="polygon-mode-webgl");for(const n of i)this.has(n)}getFeatures(){return[...Object.keys(ad),...Object.keys(zo)]}getWebGLFeature(i){const n=ad[i];return typeof n=="string"?!!Ot(this.gl,n,this.extensions):!!n}}class zb extends WS{constructor(i){super();f(this,"gl");f(this,"limits",{});this.gl=i}get maxTextureDimension1D(){return 0}get maxTextureDimension2D(){return this.getParameter(3379)}get maxTextureDimension3D(){return this.getParameter(32883)}get maxTextureArrayLayers(){return this.getParameter(35071)}get maxBindGroups(){return 0}get maxDynamicUniformBuffersPerPipelineLayout(){return 0}get maxDynamicStorageBuffersPerPipelineLayout(){return 0}get maxSampledTexturesPerShaderStage(){return this.getParameter(35660)}get maxSamplersPerShaderStage(){return this.getParameter(35661)}get maxStorageBuffersPerShaderStage(){return 0}get maxStorageTexturesPerShaderStage(){return 0}get maxUniformBuffersPerShaderStage(){return this.getParameter(35375)}get maxUniformBufferBindingSize(){return this.getParameter(35376)}get maxStorageBufferBindingSize(){return 0}get minUniformBufferOffsetAlignment(){return this.getParameter(35380)}get minStorageBufferOffsetAlignment(){return 0}get maxVertexBuffers(){return 16}get maxVertexAttributes(){return this.getParameter(34921)}get maxVertexBufferArrayStride(){return 2048}get maxInterStageShaderVariables(){return this.getParameter(35659)}get maxComputeWorkgroupStorageSize(){return 0}get maxComputeInvocationsPerWorkgroup(){return 0}get maxComputeWorkgroupSizeX(){return 0}get maxComputeWorkgroupSizeY(){return 0}get maxComputeWorkgroupSizeZ(){return 0}get maxComputeWorkgroupsPerDimension(){return 0}getParameter(i){return this.limits[i]===void 0&&(this.limits[i]=this.gl.getParameter(i)),this.limits[i]||0}}class Qi extends tr{constructor(i,n){super(i,n);f(this,"device");f(this,"gl");f(this,"handle");f(this,"colorAttachments",[]);f(this,"depthStencilAttachment",null);const r=n.handle===null;this.device=i,this.gl=i.gl,this.handle=this.props.handle||r?this.props.handle:this.gl.createFramebuffer(),r||(i._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),n.handle||(this.autoCreateAttachmentTextures(),this.updateAttachments()))}destroy(){super.destroy(),!this.destroyed&&this.handle!==null&&!this.props.handle&&this.gl.deleteFramebuffer(this.handle)}updateAttachments(){const i=this.gl.bindFramebuffer(36160,this.handle);for(let n=0;n{this.compilationStatus="error"})}destroy(){this.handle&&(this.removeStats(),this.device.gl.deleteShader(this.handle),this.destroyed=!0,this.handle.destroyed=!0)}get asyncCompilationStatus(){return this._waitForCompilationComplete().then(()=>(this._getCompilationStatus(),this.compilationStatus))}async getCompilationInfo(){return await this._waitForCompilationComplete(),this.getCompilationInfoSync()}getCompilationInfoSync(){const i=this.device.gl.getShaderInfoLog(this.handle);return i?jb(i):[]}getTranslatedSource(){const n=this.device.getExtension("WEBGL_debug_shaders").WEBGL_debug_shaders;return(n==null?void 0:n.getTranslatedShaderSource(this.handle))||null}_compile(i){i=i.startsWith("#version ")?i:`#version 300 es +${i}`;const{gl:n}=this.device;if(n.shaderSource(this.handle,i),n.compileShader(this.handle),!this.device.props.debug){this.compilationStatus="pending";return}if(!this.device.features.has("compilation-status-async-webgl")){if(this._getCompilationStatus(),this.debugShader(),this.compilationStatus==="error")throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);return}return C.once(1,"Shader compilation is asynchronous")(),this._waitForCompilationComplete().then(()=>{C.info(2,`Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)(),this._getCompilationStatus(),this.debugShader()})}async _waitForCompilationComplete(){const i=async s=>await new Promise(o=>setTimeout(o,s));if(!this.device.features.has("compilation-status-async-webgl")){await i(10);return}const{gl:r}=this.device;for(;;){if(r.getShaderParameter(this.handle,37297))return;await i(10)}}_getCompilationStatus(){this.compilationStatus=this.device.gl.getShaderParameter(this.handle,35713)?"success":"error"}}function qb(e,t,i,n){if(Jb(t))return n(e);const r=e;r.pushState();try{return Gb(e,t),ui(r.gl,i),n(e)}finally{r.popState()}}function Gb(e,t){const i=e,{gl:n}=i;if(t.cullMode)switch(t.cullMode){case"none":n.disable(2884);break;case"front":n.enable(2884),n.cullFace(1028);break;case"back":n.enable(2884),n.cullFace(1029);break}if(t.frontFace&&n.frontFace(Ut("frontFace",t.frontFace,{ccw:2305,cw:2304})),t.unclippedDepth&&e.features.has("depth-clip-control")&&n.enable(34383),t.depthBias!==void 0&&(n.enable(32823),n.polygonOffset(t.depthBias,t.depthBiasSlopeScale||0)),t.provokingVertex&&e.features.has("provoking-vertex-webgl")){const s=i.getExtension("WEBGL_provoking_vertex").WEBGL_provoking_vertex,o=Ut("provokingVertex",t.provokingVertex,{first:36429,last:36430});s==null||s.provokingVertexWEBGL(o)}if((t.polygonMode||t.polygonOffsetLine)&&e.features.has("polygon-mode-webgl")){if(t.polygonMode){const s=i.getExtension("WEBGL_polygon_mode").WEBGL_polygon_mode,o=Ut("polygonMode",t.polygonMode,{fill:6914,line:6913});s==null||s.polygonModeWEBGL(1028,o),s==null||s.polygonModeWEBGL(1029,o)}t.polygonOffsetLine&&n.enable(10754)}if(e.features.has("shader-clip-cull-distance-webgl")&&(t.clipDistance0&&n.enable(12288),t.clipDistance1&&n.enable(12289),t.clipDistance2&&n.enable(12290),t.clipDistance3&&n.enable(12291),t.clipDistance4&&n.enable(12292),t.clipDistance5&&n.enable(12293),t.clipDistance6&&n.enable(12294),t.clipDistance7&&n.enable(12295)),t.depthWriteEnabled!==void 0&&n.depthMask(Qb("depthWriteEnabled",t.depthWriteEnabled)),t.depthCompare&&(t.depthCompare!=="always"?n.enable(2929):n.disable(2929),n.depthFunc(Wo("depthCompare",t.depthCompare))),t.clearDepth!==void 0&&n.clearDepth(t.clearDepth),t.stencilWriteMask){const r=t.stencilWriteMask;n.stencilMaskSeparate(1028,r),n.stencilMaskSeparate(1029,r)}if(t.stencilReadMask&&C.warn("stencilReadMask not supported under WebGL"),t.stencilCompare){const r=t.stencilReadMask||4294967295,s=Wo("depthCompare",t.stencilCompare);t.stencilCompare!=="always"?n.enable(2960):n.disable(2960),n.stencilFuncSeparate(1028,s,0,r),n.stencilFuncSeparate(1029,s,0,r)}if(t.stencilPassOperation&&t.stencilFailOperation&&t.stencilDepthFailOperation){const r=Vo("stencilPassOperation",t.stencilPassOperation),s=Vo("stencilFailOperation",t.stencilFailOperation),o=Vo("stencilDepthFailOperation",t.stencilDepthFailOperation);n.stencilOpSeparate(1028,s,o,r),n.stencilOpSeparate(1029,s,o,r)}switch(t.blend){case!0:n.enable(3042);break;case!1:n.disable(3042);break}if(t.blendColorOperation||t.blendAlphaOperation){const r=ld("blendColorOperation",t.blendColorOperation||"add"),s=ld("blendAlphaOperation",t.blendAlphaOperation||"add");n.blendEquationSeparate(r,s);const o=xr("blendColorSrcFactor",t.blendColorSrcFactor||"one"),a=xr("blendColorDstFactor",t.blendColorDstFactor||"zero"),l=xr("blendAlphaSrcFactor",t.blendAlphaSrcFactor||"one"),c=xr("blendAlphaDstFactor",t.blendAlphaDstFactor||"zero");n.blendFuncSeparate(o,a,l,c)}}function Wo(e,t){return Ut(e,t,{never:512,less:513,equal:514,"less-equal":515,greater:516,"not-equal":517,"greater-equal":518,always:519})}function Vo(e,t){return Ut(e,t,{keep:7680,zero:0,replace:7681,invert:5386,"increment-clamp":7682,"decrement-clamp":7683,"increment-wrap":34055,"decrement-wrap":34056})}function ld(e,t){return Ut(e,t,{add:32774,subtract:32778,"reverse-subtract":32779,min:32775,max:32776})}function xr(e,t,i="color"){return Ut(e,t,{one:1,zero:0,src:768,"one-minus-src":769,dst:774,"one-minus-dst":775,"src-alpha":770,"one-minus-src-alpha":771,"dst-alpha":772,"one-minus-dst-alpha":773,"src-alpha-saturated":776,constant:i==="color"?32769:32771,"one-minus-constant":i==="color"?32770:32772,src1:768,"one-minus-src1":769,"src1-alpha":770,"one-minus-src1-alpha":771})}function Zb(e,t){return`Illegal parameter ${t} for ${e}`}function Ut(e,t,i){if(!(t in i))throw new Error(Zb(e,t));return i[t]}function Qb(e,t){return t}function Jb(e){let t=!0;for(const i in e){t=!1;break}return t}function cd(e){const t={};return e.addressModeU&&(t[10242]=Ho(e.addressModeU)),e.addressModeV&&(t[10243]=Ho(e.addressModeV)),e.addressModeW&&(t[32882]=Ho(e.addressModeW)),e.magFilter&&(t[10240]=$o(e.magFilter)),(e.minFilter||e.mipmapFilter)&&(t[10241]=eT(e.minFilter||"linear",e.mipmapFilter)),e.lodMinClamp!==void 0&&(t[33082]=e.lodMinClamp),e.lodMaxClamp!==void 0&&(t[33083]=e.lodMaxClamp),e.type==="comparison-sampler"&&(t[34892]=34894),e.compare&&(t[34893]=Wo("compare",e.compare)),e.maxAnisotropy&&(t[34046]=e.maxAnisotropy),t}function Ho(e){switch(e){case"clamp-to-edge":return 33071;case"repeat":return 10497;case"mirror-repeat":return 33648}}function $o(e){switch(e){case"nearest":return 9728;case"linear":return 9729}}function eT(e,t="none"){if(!t)return $o(e);switch(t){case"none":return $o(e);case"nearest":switch(e){case"nearest":return 9984;case"linear":return 9985}break;case"linear":switch(e){case"nearest":return 9986;case"linear":return 9987}}}class tT extends ni{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"parameters");this.device=i,this.parameters=cd(n),this.handle=n.handle||this.device.gl.createSampler(),this._setSamplerParameters(this.parameters)}destroy(){this.handle&&(this.device.gl.deleteSampler(this.handle),this.handle=void 0)}toString(){return`Sampler(${this.id},${JSON.stringify(this.props)})`}_setSamplerParameters(i){for(const[n,r]of Object.entries(i)){const s=Number(n);switch(s){case 33082:case 33083:this.device.gl.samplerParameterf(this.handle,s,r);break;default:this.device.gl.samplerParameteri(this.handle,s,r);break}}}}function zt(e,t,i){if(iT(t))return i(e);const{nocatch:n=!0}=t,r=Pt.get(e);r.push(),ui(e,t);let s;if(n)s=i(e),r.pop();else try{s=i(e)}finally{r.pop()}return s}function iT(e){for(const t in e)return!1;return!0}class fi extends Jn{constructor(i,n){super(i,{...M.defaultProps,...n});f(this,"device");f(this,"gl");f(this,"handle");f(this,"texture");this.device=i,this.gl=this.device.gl,this.handle=null,this.texture=n.texture}}function ud(e){return nT[e]}const nT={5124:"sint32",5125:"uint32",5122:"sint16",5123:"uint16",5120:"sint8",5121:"uint8",5126:"float32",5131:"float16",33635:"uint16",32819:"uint16",32820:"uint16",33640:"uint32",35899:"uint32",35902:"uint32",34042:"uint32",36269:"uint32"};class en extends M{constructor(i,n){super(i,n,{byteAlignment:1});f(this,"device");f(this,"gl");f(this,"handle");f(this,"sampler");f(this,"view");f(this,"glTarget");f(this,"glFormat");f(this,"glType");f(this,"glInternalFormat");f(this,"compressed");f(this,"_textureUnit",0);f(this,"_framebuffer",null);f(this,"_framebufferAttachmentKey",null);this.device=i,this.gl=this.device.gl;const r=od(this.props.format);this.glTarget=oT(this.props.dimension),this.glInternalFormat=r.internalFormat,this.glFormat=r.format,this.glType=r.type,this.compressed=r.compressed,this.handle=this.props.handle||this.gl.createTexture(),this.device._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),this.gl.bindTexture(this.glTarget,this.handle);const{dimension:s,width:o,height:a,depth:l,mipLevels:c,glTarget:u,glInternalFormat:d}=this;if(!this.compressed)switch(s){case"2d":case"cube":this.gl.texStorage2D(u,c,d,o,a);break;case"2d-array":case"3d":this.gl.texStorage3D(u,c,d,o,a,l);break;default:throw new Error(s)}this.gl.bindTexture(this.glTarget,null),this._initializeData(n.data),this.props.handle?this.trackReferencedMemory(this.getAllocatedByteLength(),"Texture"):this.trackAllocatedMemory(this.getAllocatedByteLength(),"Texture"),this.setSampler(this.props.sampler),this.view=new fi(this.device,{...this.props,texture:this}),Object.seal(this)}destroy(){var i;this.handle&&((i=this._framebuffer)==null||i.destroy(),this._framebuffer=null,this._framebufferAttachmentKey=null,this.removeStats(),this.props.handle?this.trackDeallocatedReferencedMemory("Texture"):(this.gl.deleteTexture(this.handle),this.trackDeallocatedMemory("Texture")),this.destroyed=!0)}createView(i){return new fi(this.device,{...i,texture:this})}setSampler(i={}){super.setSampler(i);const n=cd(this.sampler.props);this._setSamplerParameters(n)}copyExternalImage(i){const n=this._normalizeCopyExternalImageOptions(i);if(n.sourceX||n.sourceY)throw new Error("WebGL does not support sourceX/sourceY)");const{glFormat:r,glType:s}=this,{image:o,depth:a,mipLevel:l,x:c,y:u,z:d,width:h,height:p}=n,g=Sr(this.glTarget,this.dimension,d),x=n.flipY?{37440:!0}:{};return this.gl.bindTexture(this.glTarget,this.handle),zt(this.gl,x,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(g,l,c,u,h,p,r,s,o);break;case"2d-array":case"3d":this.gl.texSubImage3D(g,l,c,u,d,h,p,a,r,s,o);break;default:}}),this.gl.bindTexture(this.glTarget,null),{width:n.width,height:n.height}}copyImageData(i){super.copyImageData(i)}readBuffer(i={},n){if(!n)throw new Error(`${this} readBuffer requires a destination buffer`);const r=this._getSupportedColorReadOptions(i),s=i.byteOffset??0,o=this.computeMemoryLayout(r);if(n.byteLength{this.gl.readPixels(r.x,r.y,r.width,r.height,this.glFormat,this.glType,s+l)})}finally{this.gl.bindBuffer(35051,null)}return n}async readDataAsync(i={}){throw new Error(`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`)}writeBuffer(i,n={}){const r=this._normalizeTextureWriteOptions(n),{width:s,height:o,depthOrArrayLayers:a,mipLevel:l,byteOffset:c,x:u,y:d,z:h}=r,{glFormat:p,glType:g,compressed:x}=this,T=Sr(this.glTarget,this.dimension,h);if(x)throw new Error("writeBuffer for compressed textures is not implemented in WebGL");const{bytesPerPixel:S}=this.device.getTextureFormatInfo(this.format),P=S?r.bytesPerRow/S:void 0,I={3317:this.byteAlignment,...P!==void 0?{3314:P}:{},32878:r.rowsPerImage};this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,i.handle),zt(this.gl,I,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(T,l,u,d,s,o,p,g,c);break;case"2d-array":case"3d":this.gl.texSubImage3D(T,l,u,d,h,s,o,a,p,g,c);break;default:}}),this.gl.bindBuffer(35052,null),this.gl.bindTexture(this.glTarget,null)}writeData(i,n={}){const r=this._normalizeTextureWriteOptions(n),s=ArrayBuffer.isView(i)?i:new Uint8Array(i),{width:o,height:a,depthOrArrayLayers:l,mipLevel:c,x:u,y:d,z:h,byteOffset:p}=r,{glFormat:g,glType:x,compressed:T}=this,S=Sr(this.glTarget,this.dimension,h);let P;if(!T){const{bytesPerPixel:D}=this.device.getTextureFormatInfo(this.format);D&&(P=r.bytesPerRow/D)}const I=this.compressed?{}:{3317:this.byteAlignment,...P!==void 0?{3314:P}:{},32878:r.rowsPerImage},y=sT(s,p),v=T?rT(s,p):s,E=this._getMipLevelSize(c),R=u===0&&d===0&&h===0&&o===E.width&&a===E.height&&l===E.depthOrArrayLayers;this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,null),zt(this.gl,I,()=>{switch(this.dimension){case"2d":case"cube":T?R?this.gl.compressedTexImage2D(S,c,g,o,a,0,v):this.gl.compressedTexSubImage2D(S,c,u,d,o,a,g,v):this.gl.texSubImage2D(S,c,u,d,o,a,g,x,s,y);break;case"2d-array":case"3d":T?R?this.gl.compressedTexImage3D(S,c,g,o,a,l,0,v):this.gl.compressedTexSubImage3D(S,c,u,d,h,o,a,l,g,v):this.gl.texSubImage3D(S,c,u,d,h,o,a,l,g,x,s,y);break;default:}}),this.gl.bindTexture(this.glTarget,null)}_getRowByteAlignment(i,n){return 1}_getFramebuffer(){return this._framebuffer||(this._framebuffer=this.device.createFramebuffer({id:`framebuffer-for-${this.id}`,width:this.width,height:this.height,colorAttachments:[this]})),this._framebuffer}readDataSyncWebGL(i={}){const n=this._getSupportedColorReadOptions(i),r=this.computeMemoryLayout(n),s=ud(this.glType),o=N0(s),a=new o(r.byteLength/o.BYTES_PER_ELEMENT);return this._readColorTextureLayers(n,r,l=>{const c=new o(a.buffer,a.byteOffset+l,r.bytesPerImage/o.BYTES_PER_ELEMENT);this.gl.readPixels(n.x,n.y,n.width,n.height,this.glFormat,this.glType,c)}),a.buffer}_readColorTextureLayers(i,n,r){const s=this._getFramebuffer(),o=n.bytesPerRow/n.bytesPerPixel,a={3333:this.byteAlignment,...o!==i.width?{3330:o}:{}},l=this.gl.getParameter(3074),c=this.gl.bindFramebuffer(36160,s.handle);try{this.gl.readBuffer(36064),zt(this.gl,a,()=>{for(let u=0;u`"${c.name}"`).join(", ");n!=null&&n.disableWarnings||C.warn(`No binding "${s}" in render pipeline "${this.id}", expected one of ${l}`,o)()}}}draw(i){var P;this._syncLinkStatus();const n=i.bindGroups?$c(i.bindGroups):i.bindings||this.bindings,{renderPass:r,parameters:s=this.props.parameters,topology:o=this.props.topology,vertexArray:a,vertexCount:l,instanceCount:c,isInstanced:u=!1,firstVertex:d=0,transformFeedback:h,uniforms:p=this.uniforms}=i,g=lT(o),x=!!a.indexBuffer,T=(P=a.indexBuffer)==null?void 0:P.glIndexType;if(this.linkStatus!=="success")return C.info(2,`RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)(),!1;if(!this._areTexturesRenderable(n))return C.info(2,`RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)(),!1;this.device.gl.useProgram(this.handle),a.bindBeforeRender(r),h&&h.begin(this.props.topology),this._applyBindings(n,{disableWarnings:this.props.disableWarnings}),this._applyUniforms(p);const S=r;return qb(this.device,s,S.glParameters,()=>{x&&u?this.device.gl.drawElementsInstanced(g,l||0,T,d,c||0):x?this.device.gl.drawElements(g,l||0,T,d):u?this.device.gl.drawArraysInstanced(g,d,l||0,c||0):this.device.gl.drawArrays(g,d,l||0),h&&h.end()}),a.unbindAfterRender(r),!0}_areTexturesRenderable(i){let n=!0;for(const r of this.shaderLayout.bindings)hd(i,r.name)||(C.warn(`Binding ${r.name} not found in ${this.id}`)(),n=!1);return n}_applyBindings(i,n){if(this._syncLinkStatus(),this.linkStatus!=="success")return;const{gl:r}=this.device;r.useProgram(this.handle);let s=0,o=0;for(const a of this.shaderLayout.bindings){const l=hd(i,a.name);if(!l)throw new Error(`No value for binding ${a.name} in ${this.id}`);switch(a.type){case"uniform":const{name:c}=a,u=r.getUniformBlockIndex(this.handle,c);if(u===4294967295)throw new Error(`Invalid uniform block name ${c}`);if(r.uniformBlockBinding(this.handle,u,o),l instanceof Ji)r.bindBufferBase(35345,o,l.handle);else{const h=l;r.bindBufferRange(35345,o,h.buffer.handle,h.offset||0,h.size||h.buffer.byteLength-(h.offset||0))}o+=1;break;case"texture":if(!(l instanceof fi||l instanceof en||l instanceof Qi))throw new Error("texture");let d;if(l instanceof fi)d=l.texture;else if(l instanceof en)d=l;else if(l instanceof Qi&&l.colorAttachments[0]instanceof fi)C.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")(),d=l.colorAttachments[0].texture;else throw new Error("No texture");r.activeTexture(33984+s),r.bindTexture(d.glTarget,d.handle),s+=1;break;case"sampler":break;case"storage":case"read-only-storage":throw new Error(`binding type '${a.type}' not supported in WebGL`)}}}_applyUniforms(i){for(const n of this.shaderLayout.uniforms||[]){const{name:r,location:s,type:o,textureUnit:a}=n,l=i[r]??a;l!==void 0&&aT(this.device.gl,s,o,l)}}_syncLinkStatus(){this.linkStatus=this.sharedRenderPipeline.linkStatus}}function dT(e,t){const i={...e,attributes:e.attributes.map(n=>({...n})),bindings:e.bindings.map(n=>({...n}))};for(const n of(t==null?void 0:t.attributes)||[]){const r=i.attributes.find(s=>s.name===n.name);r?(r.type=n.type||r.type,r.stepMode=n.stepMode||r.stepMode):C.warn(`shader layout attribute ${n.name} not present in shader`)}for(const n of(t==null?void 0:t.bindings)||[]){const r=dd(i,n.name);if(!r){C.warn(`shader layout binding ${n.name} not present in shader`);continue}Object.assign(r,n)}return i}function dd(e,t){return e.bindings.find(i=>i.name===t||i.name===`${t}Uniforms`||`${i.name}Uniforms`===t)}function hd(e,t){return e[t]||e[`${t}Uniforms`]||e[t.replace(/Uniforms$/,"")]}function hT(e){return gT[e]}function Xo(e){return pT[e]}function fd(e){return!!pd[e]}function fT(e){return pd[e]}const pT={5126:"f32",35664:"vec2",35665:"vec3",35666:"vec4",5124:"i32",35667:"vec2",35668:"vec3",35669:"vec4",5125:"u32",36294:"vec2",36295:"vec3",36296:"vec4",35670:"f32",35671:"vec2",35672:"vec3",35673:"vec4",35674:"mat2x2",35685:"mat2x3",35686:"mat2x4",35687:"mat3x2",35675:"mat3x3",35688:"mat3x4",35689:"mat4x2",35690:"mat4x3",35676:"mat4x4"},pd={35678:{viewDimension:"2d",sampleType:"float"},35680:{viewDimension:"cube",sampleType:"float"},35679:{viewDimension:"3d",sampleType:"float"},35682:{viewDimension:"3d",sampleType:"depth"},36289:{viewDimension:"2d-array",sampleType:"float"},36292:{viewDimension:"2d-array",sampleType:"depth"},36293:{viewDimension:"cube",sampleType:"float"},36298:{viewDimension:"2d",sampleType:"sint"},36299:{viewDimension:"3d",sampleType:"sint"},36300:{viewDimension:"cube",sampleType:"sint"},36303:{viewDimension:"2d-array",sampleType:"uint"},36306:{viewDimension:"2d",sampleType:"uint"},36307:{viewDimension:"3d",sampleType:"uint"},36308:{viewDimension:"cube",sampleType:"uint"},36311:{viewDimension:"2d-array",sampleType:"uint"}},gT={uint8:5121,sint8:5120,unorm8:5121,snorm8:5120,uint16:5123,sint16:5122,unorm16:5123,snorm16:5122,uint32:5125,sint32:5124,float16:5131,float32:5126};function mT(e,t){const i={attributes:[],bindings:[]};i.attributes=xT(e,t);const n=_T(e,t);for(const a of n){const l=a.uniforms.map(c=>({name:c.name,format:c.format,byteOffset:c.byteOffset,byteStride:c.byteStride,arrayLength:c.arrayLength}));i.bindings.push({type:"uniform",name:a.name,group:0,location:a.location,visibility:(a.vertex?1:0)&(a.fragment?2:0),minBindingSize:a.byteLength,uniforms:l})}const r=yT(e,t);let s=0;for(const a of r)if(fd(a.type)){const{viewDimension:l,sampleType:c}=fT(a.type);i.bindings.push({type:"texture",name:a.name,group:0,location:s,viewDimension:l,sampleType:c}),a.textureUnit=s,s+=1}r.length&&(i.uniforms=r);const o=ST(e,t);return o!=null&&o.length&&(i.varyings=o),i}function xT(e,t){const i=[],n=e.getProgramParameter(t,35721);for(let r=0;r=0){const c=Xo(a),u=/instance/i.test(o)?"instance":"vertex";i.push({name:o,location:l,stepMode:u,type:c})}}return i.sort((r,s)=>r.location-s.location),i}function ST(e,t){const i=[],n=e.getProgramParameter(t,35971);for(let r=0;rr.location-s.location),i}function yT(e,t){const i=[],n=e.getProgramParameter(t,35718);for(let r=0;r1)for(let p=0;pe.getActiveUniformBlockParameter(t,s,o),n=[],r=e.getProgramParameter(t,35382);for(let s=0;sg.name.split(".")[0]).filter(g=>!!g)),p=o.name.replace(/Uniforms$/,"");if(h.size===1&&!h.has(o.name)&&!h.has(p)){const[g]=h;C.warn(`Uniform block "${o.name}" uses GLSL instance "${g}". luma.gl binds uniform buffers by block name ("${o.name}") and alias ("${p}"). Prefer matching the instance name to one of those to avoid confusing silent mismatches.`)()}n.push(o)}return n.sort((s,o)=>s.location-o.location),n}function bT(e){if(e[e.length-1]!=="]")return{name:e,length:1,isArray:!1};const i=/([^[]*)(\[[0-9]+\])?/.exec(e);return{name:Qn(i==null?void 0:i[1],`Failed to parse GLSL uniform name ${e}`),length:i!=null&&i[2]?1:0,isArray:!!(i!=null&&i[2])}}const gd=4;class TT extends m0{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"vs");f(this,"fs");f(this,"introspectedLayout",{attributes:[],bindings:[],uniforms:[]});f(this,"linkStatus","pending");this.device=i,this.handle=n.handle||this.device.gl.createProgram(),this.vs=n.vs,this.fs=n.fs,n.varyings&&n.varyings.length>0&&this.device.gl.transformFeedbackVaryings(this.handle,n.varyings,n.bufferMode||35981),this._linkShaders(),C.time(3,`RenderPipeline ${this.id} - shaderLayout introspection`)(),this.introspectedLayout=mT(this.device.gl,this.handle),C.timeEnd(3,`RenderPipeline ${this.id} - shaderLayout introspection`)()}destroy(){this.destroyed||(this.device.gl.useProgram(null),this.device.gl.deleteProgram(this.handle),this.handle.destroyed=!0,this.destroyResource())}async _linkShaders(){const{gl:i}=this.device;if(i.attachShader(this.handle,this.vs.handle),i.attachShader(this.handle,this.fs.handle),C.time(gd,`linkProgram for ${this.id}`)(),i.linkProgram(this.handle),C.timeEnd(gd,`linkProgram for ${this.id}`)(),!this.device.features.has("compilation-status-async-webgl")){const r=this._getLinkStatus();this._reportLinkStatus(r);return}C.once(1,"RenderPipeline linking is asynchronous")(),await this._waitForLinkComplete(),C.info(2,`RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();const n=this._getLinkStatus();this._reportLinkStatus(n)}async _reportLinkStatus(i){var n;switch(i){case"success":return;default:const r=i==="link-error"?"Link error":"Validation error";switch(this.vs.compilationStatus){case"error":throw this.vs.debugShader(),new Error(`${this} ${r} during compilation of ${this.vs}`);case"pending":await this.vs.asyncCompilationStatus,this.vs.debugShader();break}switch((n=this.fs)==null?void 0:n.compilationStatus){case"error":throw this.fs.debugShader(),new Error(`${this} ${r} during compilation of ${this.fs}`);case"pending":await this.fs.asyncCompilationStatus,this.fs.debugShader();break}const s=this.device.gl.getProgramInfoLog(this.handle);this.device.reportError(new Error(`${r} during ${i}: ${s}`),this)(),this.device.debug()}}_getLinkStatus(){const{gl:i}=this.device;return i.getProgramParameter(this.handle,35714)?(this._initializeSamplerUniforms(),i.validateProgram(this.handle),i.getProgramParameter(this.handle,35715)?(this.linkStatus="success","success"):(this.linkStatus="error","validation-error")):(this.linkStatus="error","link-error")}_initializeSamplerUniforms(){const{gl:i}=this.device;i.useProgram(this.handle);let n=0;const r=i.getProgramParameter(this.handle,35718);for(let s=0;s1){const a=Int32Array.from({length:n.size},(l,c)=>s+c);return o.uniform1iv(i,a),s+n.size}return o.uniform1i(i,s),s+1}async _waitForLinkComplete(){const i=async s=>await new Promise(o=>setTimeout(o,s));if(!this.device.features.has("compilation-status-async-webgl")){await i(10);return}const{gl:r}=this.device;for(;;){if(r.getProgramParameter(this.handle,37297))return;await i(10)}}}class vT extends no{constructor(i,n={}){super(i,n);f(this,"device");f(this,"handle",null);f(this,"commands",[]);this.device=i}_executeCommands(i=this.commands){for(const n of i)switch(n.name){case"copy-buffer-to-buffer":PT(this.device,n.options);break;case"copy-buffer-to-texture":CT(this.device,n.options);break;case"copy-texture-to-buffer":AT(this.device,n.options);break;case"copy-texture-to-texture":RT(this.device,n.options);break;default:throw new Error(n.name)}}}function PT(e,t){const i=t.sourceBuffer,n=t.destinationBuffer;e.gl.bindBuffer(36662,i.handle),e.gl.bindBuffer(36663,n.handle),e.gl.copyBufferSubData(36662,36663,t.sourceOffset??0,t.destinationOffset??0,t.size),e.gl.bindBuffer(36662,null),e.gl.bindBuffer(36663,null)}function CT(e,t){throw new Error("copyBufferToTexture is not supported in WebGL")}function AT(e,t){const{sourceTexture:i,mipLevel:n=0,aspect:r="all",width:s=t.sourceTexture.width,height:o=t.sourceTexture.height,depthOrArrayLayers:a,origin:l=[0,0,0],destinationBuffer:c,byteOffset:u=0,bytesPerRow:d,rowsPerImage:h}=t;if(i instanceof M){i.readBuffer({x:l[0]??0,y:l[1]??0,z:l[2]??0,width:s,height:o,depthOrArrayLayers:a,mipLevel:n,aspect:r,byteOffset:u},c);return}if(r!=="all")throw new Error("aspect not supported in WebGL");if(n!==0||a!==void 0||d||h)throw new Error("not implemented");const{framebuffer:p,destroyFramebuffer:g}=md(i);let x;try{const T=c,S=s||p.width,P=o||p.height,I=Qn(p.colorAttachments[0]),y=od(I.texture.props.format),v=y.format,E=y.type;e.gl.bindBuffer(35051,T.handle),x=e.gl.bindFramebuffer(36160,p.handle),e.gl.readPixels(l[0],l[1],S,P,v,E,u)}finally{e.gl.bindBuffer(35051,null),x!==void 0&&e.gl.bindFramebuffer(36160,x),g&&p.destroy()}}function RT(e,t){const{sourceTexture:i,destinationMipLevel:n=0,origin:r=[0,0],destinationOrigin:s=[0,0,0],destinationTexture:o}=t;let{width:a=t.destinationTexture.width,height:l=t.destinationTexture.height}=t;const{framebuffer:c,destroyFramebuffer:u}=md(i),[d=0,h=0]=r,[p,g,x]=s,T=e.gl.bindFramebuffer(36160,c.handle);let S,P;if(o instanceof en)S=o,a=Number.isFinite(a)?a:S.width,l=Number.isFinite(l)?l:S.height,S._bind(0),P=S.glTarget;else throw new Error("invalid destination");switch(P){case 3553:case 34067:e.gl.copyTexSubImage2D(P,n,p,g,d,h,a,l);break;case 35866:case 32879:e.gl.copyTexSubImage3D(P,n,p,g,x,d,h,a,l);break}S&&S._unbind(),e.gl.bindFramebuffer(36160,T),u&&c.destroy()}function md(e){if(e instanceof M){const{width:t,height:i,id:n}=e;return{framebuffer:e.device.createFramebuffer({id:`framebuffer-for-${n}`,width:t,height:i,colorAttachments:[e]}),destroyFramebuffer:!0}}return{framebuffer:e,destroyFramebuffer:!1}}const wT=[1,2,4,8];class ET extends to{constructor(i,n){var a;super(i,n);f(this,"device");f(this,"handle",null);f(this,"glParameters",{});this.device=i;const r=this.props.framebuffer,s=!r||r.handle===null;s&&i.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();let o;if(!((a=n==null?void 0:n.parameters)!=null&&a.viewport))if(!s&&r){const{width:l,height:c}=r;o=[0,0,l,c]}else{const[l,c]=i.getDefaultCanvasContext().getDrawingBufferSize();o=[0,0,l,c]}if(this.device.pushState(),this.setParameters({viewport:o,...this.props.parameters}),!s&&(r!=null&&r.colorAttachments.length)){const l=r.colorAttachments.map((c,u)=>36064+u);this.device.gl.drawBuffers(l)}else s&&this.device.gl.drawBuffers([1029]);this.clear(),this.props.timestampQuerySet&&this.props.beginTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.beginTimestampIndex)}end(){this.destroyed||(this.props.timestampQuerySet&&this.props.endTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.endTimestampIndex),this.device.popState(),this.destroy())}pushDebugGroup(i){}popDebugGroup(){}insertDebugMarker(i){}setParameters(i={}){const n={...this.glParameters};n.framebuffer=this.props.framebuffer||null,this.props.depthReadOnly&&(n.depthMask=!this.props.depthReadOnly),n.stencilMask=this.props.stencilReadOnly?0:1,n[35977]=this.props.discard,i.viewport&&(i.viewport.length>=6?(n.viewport=i.viewport.slice(0,4),n.depthRange=[i.viewport[4],i.viewport[5]]):n.viewport=i.viewport),i.scissorRect&&(n.scissorTest=!0,n.scissor=i.scissorRect),i.blendConstant&&(n.blendColor=i.blendConstant),i.stencilReference!==void 0&&(n[2967]=i.stencilReference,n[36003]=i.stencilReference),"colorMask"in i&&(n.colorMask=wT.map(r=>!!(r&i.colorMask))),this.glParameters=n,ui(this.device.gl,n)}beginOcclusionQuery(i){const n=this.props.occlusionQuerySet;n==null||n.beginOcclusionQuery()}endOcclusionQuery(){const i=this.props.occlusionQuerySet;i==null||i.endOcclusionQuery()}clear(){const i={...this.glParameters};let n=0;this.props.clearColors&&this.props.clearColors.forEach((r,s)=>{r&&this.clearColorBuffer(s,r)}),this.props.clearColor!==!1&&this.props.clearColors===void 0&&(n|=16384,i.clearColor=this.props.clearColor),this.props.clearDepth!==!1&&(n|=256,i.clearDepth=this.props.clearDepth),this.props.clearStencil!==!1&&(n|=1024,i.clearStencil=this.props.clearStencil),n!==0&&zt(this.device.gl,i,()=>{this.device.gl.clear(n)})}clearColorBuffer(i=0,n=[0,0,0,0]){zt(this.device.gl,{framebuffer:this.props.framebuffer},()=>{switch(n.constructor){case Int8Array:case Int16Array:case Int32Array:this.device.gl.clearBufferiv(6144,i,n);break;case Uint8Array:case Uint8ClampedArray:case Uint16Array:case Uint32Array:this.device.gl.clearBufferuiv(6144,i,n);break;case Float32Array:this.device.gl.clearBufferfv(6144,i,n);break;default:throw new Error("clearColorBuffer: color must be typed array")}})}}class xd extends io{constructor(i,n){super(i,n);f(this,"device");f(this,"handle",null);f(this,"commandBuffer");this.device=i,this.commandBuffer=new vT(i,{id:`${this.props.id}-command-buffer`})}destroy(){this.destroyResource()}finish(i){return i!=null&&i.id&&this.commandBuffer.id!==i.id&&(this.commandBuffer.id=i.id,this.commandBuffer.props.id=i.id),this.destroy(),this.commandBuffer}beginRenderPass(i={}){return new ET(this.device,this._applyTimeProfilingToPassProps(i))}beginComputePass(i={}){throw new Error("ComputePass not supported in WebGL")}copyBufferToBuffer(i){this.commandBuffer.commands.push({name:"copy-buffer-to-buffer",options:i})}copyBufferToTexture(i){this.commandBuffer.commands.push({name:"copy-buffer-to-texture",options:i})}copyTextureToBuffer(i){this.commandBuffer.commands.push({name:"copy-texture-to-buffer",options:i})}copyTextureToTexture(i){this.commandBuffer.commands.push({name:"copy-texture-to-texture",options:i})}pushDebugGroup(i){}popDebugGroup(){}insertDebugMarker(i){}resolveQuerySet(i,n,r){throw new Error("resolveQuerySet is not supported in WebGL")}writeTimestamp(i,n){i.writeTimestamp(n)}}function IT(e){const{target:t,source:i,start:n=0,count:r=1}=e,s=i.length,o=r*s;let a=0;for(let l=n;a{for(const[n,r]of Object.entries(i))this.setBuffer(n,r)})}setBuffer(i,n){const r=this._getVaryingIndex(i),{buffer:s,byteLength:o,byteOffset:a}=this._getBufferRange(n);if(r<0){this.unusedBuffers[i]=s,C.warn(`${this.id} unusedBuffers varying buffer ${i}`)();return}this.buffers[r]={buffer:s,byteLength:o,byteOffset:a},this.bindOnUse||this._bindBuffer(r,s,a,o)}getBuffer(i){if(Sd(i))return this.buffers[i]||null;const n=this._getVaryingIndex(i);return this.buffers[n]??null}bind(i=this.handle){if(typeof i!="function")return this.gl.bindTransformFeedback(36386,i),this;let n;return this._bound?n=i():(this.gl.bindTransformFeedback(36386,this.handle),this._bound=!0,n=i(),this._bound=!1,this.gl.bindTransformFeedback(36386,null)),n}unbind(){this.bind(null)}_getBufferRange(i){if(i instanceof Ji)return{buffer:i,byteOffset:0,byteLength:i.byteLength};const{buffer:n,byteOffset:r=0,byteLength:s=i.buffer.byteLength}=i;return{buffer:n,byteOffset:r,byteLength:s}}_getVaryingIndex(i){if(Sd(i))return Number(i);for(const n of this.layout.varyings||[])if(i===n.name)return n.location;return-1}_bindBuffers(){for(const[i,n]of Object.entries(this.buffers)){const{buffer:r,byteLength:s,byteOffset:o}=this._getBufferRange(n);this._bindBuffer(Number(i),r,o,s)}}_unbindBuffers(){for(const i in this.buffers)this.gl.bindBufferBase(35982,Number(i),null)}_bindBuffer(i,n,r=0,s){const o=n&&n.handle;!o||s===void 0?this.gl.bindBufferBase(35982,i,o):this.gl.bindBufferRange(35982,i,o,r,s)}}function Sd(e){return typeof e=="number"?Number.isInteger(e):/^\d+$/.test(e)}class MT extends lo{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"_timestampPairs",[]);f(this,"_pendingReads",new Set);f(this,"_occlusionQuery",null);f(this,"_occlusionActive",!1);if(this.device=i,n.type==="timestamp"){if(n.count<2)throw new Error("Timestamp QuerySet requires at least two query slots");this._timestampPairs=new Array(Math.ceil(n.count/2)).fill(null).map(()=>({activeQuery:null,completedQueries:[]})),this.handle=null}else{if(n.count>1)throw new Error("WebGL occlusion QuerySet can only have one value");const r=this.device.gl.createQuery();if(!r)throw new Error("WebGL query not supported");this.handle=r}Object.seal(this)}get[Symbol.toStringTag](){return"QuerySet"}destroy(){if(!this.destroyed){this.handle&&this.device.gl.deleteQuery(this.handle);for(const i of this._timestampPairs){i.activeQuery&&(this._cancelPendingQuery(i.activeQuery),this.device.gl.deleteQuery(i.activeQuery.handle));for(const n of i.completedQueries)this._cancelPendingQuery(n),this.device.gl.deleteQuery(n.handle)}this._occlusionQuery&&(this._cancelPendingQuery(this._occlusionQuery),this.device.gl.deleteQuery(this._occlusionQuery.handle));for(const i of Array.from(this._pendingReads))this._cancelPendingQuery(i);this.destroyResource()}}isResultAvailable(i){return this.props.type==="timestamp"?i===void 0?this._timestampPairs.some((n,r)=>this._isTimestampPairAvailable(r)):this._isTimestampPairAvailable(this._getTimestampPairIndex(i)):this._occlusionQuery?this._pollQueryAvailability(this._occlusionQuery):!1}async readResults(i){const n=(i==null?void 0:i.firstQuery)||0,r=(i==null?void 0:i.queryCount)||this.props.count-n;if(this._validateRange(n,r),this.props.type==="timestamp"){const s=new Array(r).fill(0n),o=Math.floor(n/2),a=Math.floor((n+r-1)/2);for(let l=o;l<=a;l++){const c=await this._consumeTimestampPairResult(l),u=l*2,d=u+1;u>=n&&u=n&&d=this.props.count||n<=i)throw new Error("Timestamp duration range is out of bounds");if(i%2!==0||n!==i+1)throw new Error("WebGL timestamp durations require adjacent even/odd query indices");const r=await this._consumeTimestampPairResult(this._getTimestampPairIndex(i));return Number(r)/1e6}beginOcclusionQuery(){if(this.props.type!=="occlusion")throw new Error("Occlusion queries require an occlusion QuerySet");if(!this.handle)throw new Error("WebGL occlusion query is not available");if(this._occlusionActive)throw new Error("Occlusion query is already active");this.device.gl.beginQuery(35887,this.handle),this._occlusionQuery={handle:this.handle,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null},this._occlusionActive=!0}endOcclusionQuery(){if(!this._occlusionActive)throw new Error("Occlusion query is not active");this.device.gl.endQuery(35887),this._occlusionActive=!1}writeTimestamp(i){if(this.props.type!=="timestamp")throw new Error("Timestamp writes require a timestamp QuerySet");const n=this._getTimestampPairIndex(i),r=this._timestampPairs[n];if(i%2===0){if(r.activeQuery)throw new Error("Timestamp query pair is already active");const s=this.device.gl.createQuery();if(!s)throw new Error("WebGL query not supported");const o={handle:s,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null};this.device.gl.beginQuery(35007,s),r.activeQuery=o;return}if(!r.activeQuery)throw new Error("Timestamp query pair was ended before it was started");this.device.gl.endQuery(35007),r.completedQueries.push(r.activeQuery),r.activeQuery=null}_validateRange(i,n){if(i<0||n<0||i+n>this.props.count)throw new Error("Query read range is out of bounds")}_getTimestampPairIndex(i){if(i<0||i>=this.props.count)throw new Error("Query index is out of bounds");return Math.floor(i/2)}_isTimestampPairAvailable(i){const n=this._timestampPairs[i];return!n||n.completedQueries.length===0?!1:this._pollQueryAvailability(n.completedQueries[0])}_pollQueryAvailability(i){if(i.cancelled||this.destroyed)return i.result=0n,!0;if(i.result!==null||i.disjoint)return!0;if(!this.device.gl.getQueryParameter(i.handle,34919))return!1;const r=!!this.device.gl.getParameter(36795);return i.disjoint=r,i.result=r?0n:BigInt(this.device.gl.getQueryParameter(i.handle,34918)),!0}async _consumeTimestampPairResult(i){const n=this._timestampPairs[i];if(!n||n.completedQueries.length===0)throw new Error("Timestamp query pair has no completed result");const r=n.completedQueries.shift();try{return await this._consumeQueryResult(r)}finally{this.device.gl.deleteQuery(r.handle)}}_consumeQueryResult(i){return i.promise||(this._pendingReads.add(i),i.promise=new Promise((n,r)=>{i.resolve=n,i.reject=r;const s=()=>{if(i.pollRequestId=null,i.cancelled||this.destroyed){this._pendingReads.delete(i),i.promise=null,i.resolve=null,i.reject=null,n(0n);return}if(!this._pollQueryAvailability(i)){i.pollRequestId=this._requestAnimationFrame(s);return}this._pendingReads.delete(i),i.promise=null,i.resolve=null,i.reject=null,i.disjoint?r(new Error("GPU timestamp query was invalidated by a disjoint event")):n(i.result||0n)};s()})),i.promise}_cancelPendingQuery(i){if(this._pendingReads.delete(i),i.cancelled=!0,i.pollRequestId!==null&&(this._cancelAnimationFrame(i.pollRequestId),i.pollRequestId=null),i.resolve){const n=i.resolve;i.promise=null,i.resolve=null,i.reject=null,n(0n)}}_requestAnimationFrame(i){return requestAnimationFrame(i)}_cancelAnimationFrame(i){cancelAnimationFrame(i)}}class NT extends co{constructor(i,n={}){super(i,{});f(this,"device");f(this,"gl");f(this,"handle");f(this,"signaled");f(this,"_signaled",!1);this.device=i,this.gl=i.gl;const r=this.props.handle||this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE,0);if(!r)throw new Error("Failed to create WebGL fence");this.handle=r,this.signaled=new Promise(s=>{const o=()=>{const a=this.gl.clientWaitSync(this.handle,0,0);a===this.gl.ALREADY_SIGNALED||a===this.gl.CONDITION_SATISFIED?(this._signaled=!0,s()):setTimeout(o,1)};o()})}isSignaled(){if(this._signaled)return!0;const i=this.gl.getSyncParameter(this.handle,this.gl.SYNC_STATUS);return this._signaled=i===this.gl.SIGNALED,this._signaled}destroy(){this.destroyed||this.gl.deleteSync(this.handle)}}function yd(e){switch(e){case 6406:case 33326:case 6403:case 36244:return 1;case 33339:case 33340:case 33328:case 33320:case 33319:return 2;case 6407:case 36248:case 34837:return 3;case 6408:case 36249:case 34836:return 4;default:return 0}}function BT(e){switch(e){case 5121:return 1;case 33635:case 32819:case 32820:return 2;case 5126:return 4;default:return 0}}function OT(e,t){var P;const{sourceX:i=0,sourceY:n=0,sourceAttachment:r=0}=t||{};let{target:s=null,sourceWidth:o,sourceHeight:a,sourceDepth:l,sourceFormat:c,sourceType:u}=t||{};const{framebuffer:d,deleteFramebuffer:h}=_d(e),{gl:p,handle:g}=d;o||(o=d.width),a||(a=d.height);const x=(P=d.colorAttachments[r])==null?void 0:P.texture;if(!x)throw new Error(`Invalid framebuffer attachment ${r}`);l=(x==null?void 0:x.depth)||1,c||(c=(x==null?void 0:x.glFormat)||6408),u||(u=(x==null?void 0:x.glType)||5121),s=LT(s,u,c,o,a);const T=Nt.getDataType(s);u=u||hT(T);const S=p.bindFramebuffer(36160,g);return p.readBuffer(36064+r),p.readPixels(i,n,o,a,c,u,s),p.readBuffer(36064),p.bindFramebuffer(36160,S||null),h&&d.destroy(),s}function UT(e,t){const{target:i,sourceX:n=0,sourceY:r=0,sourceFormat:s=6408,targetByteOffset:o=0}=t||{};let{sourceWidth:a,sourceHeight:l,sourceType:c}=t||{};const{framebuffer:u,deleteFramebuffer:d}=_d(e);a=a||u.width,l=l||u.height;const h=u;c=c||5121;let p=i;if(!p){const x=yd(s),T=BT(c),S=o+a*l*x*T;p=h.device.createBuffer({byteLength:S})}const g=e.device.createCommandEncoder();return g.copyTextureToBuffer({sourceTexture:e,width:a,height:l,origin:[n,r],destinationBuffer:p,byteOffset:o}),g.destroy(),d&&u.destroy(),p}function _d(e){return e instanceof tr?{framebuffer:e,deleteFramebuffer:!1}:{framebuffer:zT(e),deleteFramebuffer:!0}}function zT(e,t){const{device:i,width:n,height:r,id:s}=e;return i.createFramebuffer({...t,id:`framebuffer-for-${s}`,width:n,height:r,colorAttachments:[e]})}function LT(e,t,i,n,r,s){if(e)return e;t||(t=5121);const o=ud(t),a=Nt.getTypedArrayConstructor(o),l=yd(i);return new a(n*r*l)}class yr extends Bt{constructor(i){var d;super({...i,id:i.id||$b("webgl-device")});f(this,"type","webgl");f(this,"handle");f(this,"features");f(this,"limits");f(this,"info");f(this,"canvasContext");f(this,"preferredColorFormat","rgba8unorm");f(this,"preferredDepthFormat","depth24plus");f(this,"commandEncoder");f(this,"lost");f(this,"_resolveContextLost");f(this,"gl");f(this,"_constants");f(this,"extensions");f(this,"_polyfilled",!1);f(this,"spectorJS");const n=Bt._getCanvasContextProps(i);if(!n)throw new Error("WebGLDevice requires props.createCanvasContext to be set");const r=((d=n.canvas)==null?void 0:d.gl)??null;let s=yr.getDeviceFromContext(r);if(s)throw new Error(`WebGL context already attached to device ${s.id}`);this.canvasContext=new Vb(this,n),this.lost=new Promise(h=>{this._resolveContextLost=h});const o={...i.webgl};n.alphaMode==="premultiplied"&&(o.premultipliedAlpha=!0),i.powerPreference!==void 0&&(o.powerPreference=i.powerPreference),i.failIfMajorPerformanceCaveat!==void 0&&(o.failIfMajorPerformanceCaveat=i.failIfMajorPerformanceCaveat);const l=this.props._handle||_b(this.canvasContext.canvas,{onContextLost:h=>{var p;return(p=this._resolveContextLost)==null?void 0:p.call(this,{reason:"destroyed",message:"Entered sleep mode, or too many apps or browser tabs are using the GPU."})},onContextRestored:h=>console.log("WebGL context restored")},o);if(!l)throw new Error("WebGL context creation failed");if(s=yr.getDeviceFromContext(l),s){if(i._reuseDevices)return C.log(1,`Not creating a new Device, instead returning a reference to Device ${s.id} already attached to WebGL context`,s)(),this.canvasContext.destroy(),s._reused=!0,s;throw new Error(`WebGL context already attached to device ${s.id}`)}this.handle=l,this.gl=l,this.spectorJS=tb({...this.props,gl:this.handle});const c=fr(this.handle);c.device=this,c.extensions||(c.extensions={}),this.extensions=c.extensions,this.info=bb(this.gl,this.extensions),this.limits=new zb(this.gl),this.features=new Ub(this.gl,this.extensions,this.props._disabledFeatures),this.props._initializeFeatures&&this.features.initializeFeatures(),new Pt(this.gl,{log:(...h)=>C.log(1,...h)()}).trackState(this.gl,{copyState:!1}),(i.debug||i.debugWebGL)&&(this.gl=rb(this.gl,{debugWebGL:!0,traceWebGL:i.debugWebGL}),C.warn("WebGL debug mode activated. Performance reduced.")()),i.debugWebGL&&(C.level=Math.max(C.level,1)),this.commandEncoder=new xd(this,{id:`${this}-command-encoder`}),this.canvasContext._startObservers()}static getDeviceFromContext(i){var n;return i?((n=i.luma)==null?void 0:n.device)??null:null}get[Symbol.toStringTag](){return"WebGLDevice"}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}isVertexFormatSupported(i){switch(i){case"unorm8x4-bgra":return!1;default:return!0}}destroy(){var i;if((i=this.commandEncoder)==null||i.destroy(),!this.props._reuseDevices&&!this._reused){const n=fr(this.handle);n.device=null}}get isLost(){return this.gl.isContextLost()}createCanvasContext(i){throw new Error("WebGL only supports a single canvas")}createPresentationContext(i){return new Hb(this,i||{})}createBuffer(i){const n=this._normalizeBufferProps(i);return new Ji(this,n)}createTexture(i){return new en(this,i)}createExternalTexture(i){throw new Error("createExternalTexture() not implemented")}createSampler(i){return new tT(this,i)}createShader(i){return new Kb(this,i)}createFramebuffer(i){return new Qi(this,i)}createVertexArray(i){return new Yo(this,i)}createTransformFeedback(i){return new FT(this,i)}createQuerySet(i){return new MT(this,i)}createFence(){return new NT(this)}createRenderPipeline(i){return new uT(this,i)}_createSharedRenderPipelineWebGL(i){return new TT(this,i)}createComputePipeline(i){throw new Error("ComputePipeline not supported in WebGL")}createCommandEncoder(i={}){return new xd(this,i)}submit(i){let n=null;i||({submittedCommandEncoder:n,commandBuffer:i}=this._finalizeDefaultCommandEncoderForSubmit());try{i._executeCommands(),n&&n.resolveTimeProfilingQuerySet().then(()=>{this.commandEncoder._gpuTimeMs=n._gpuTimeMs}).catch(()=>{})}finally{i.destroy()}}_finalizeDefaultCommandEncoderForSubmit(){const i=this.commandEncoder,n=i.finish();return this.commandEncoder.destroy(),this.commandEncoder=this.createCommandEncoder({id:i.props.id,timeProfilingQuerySet:i.getTimeProfilingQuerySet()}),{submittedCommandEncoder:i,commandBuffer:n}}readPixelsToArrayWebGL(i,n){return OT(i,n)}readPixelsToBufferWebGL(i,n){return UT(i,n)}setParametersWebGL(i){ui(this.gl,i)}getParametersWebGL(i){return Zu(this.gl,i)}withParametersWebGL(i,n){return zt(this.gl,i,n)}resetWebGL(){C.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")(),gb(this.gl)}_getDeviceSpecificTextureFormatCapabilities(i){return Fb(this.gl,i,this.extensions)}loseDevice(){var s;let i=!1;const r=this.getExtension("WEBGL_lose_context").WEBGL_lose_context;return r&&(i=!0,r.loseContext()),(s=this._resolveContextLost)==null||s.call(this,{reason:"destroyed",message:"Application triggered context loss"}),i}pushState(){Pt.get(this.gl).push()}popState(){Pt.get(this.gl).pop()}getGLKey(i,n){const r=Number(i);for(const s in this.gl)if(this.gl[s]===r)return`GL.${s}`;return n!=null&&n.emptyIfUnknown?"":String(i)}getGLKeys(i){const n={emptyIfUnknown:!0};return Object.entries(i).reduce((r,[s,o])=>(r[`${s}:${this.getGLKey(s,n)}`]=`${o}:${this.getGLKey(o,n)}`,r),{})}setConstantAttributeWebGL(i,n){const r=this.limits.maxVertexAttributes;this._constants=this._constants||new Array(r).fill(null);const s=this._constants[i];switch(s&&$T(s,n)&&C.info(1,`setConstantAttributeWebGL(${i}) could have been skipped, value unchanged`)(),this._constants[i]=n,n.constructor){case Float32Array:WT(this,i,n);break;case Int32Array:VT(this,i,n);break;case Uint32Array:HT(this,i,n);break;default:throw new Error("constant")}}getExtension(i){return Ot(this.gl,i,this.extensions),this.extensions}_setWebGLDebugMetadata(i,n,r){i.luma=n;const s={props:r.spector,id:r.spector.id};i.__SPECTOR_Metadata=s}}function WT(e,t,i){switch(i.length){case 1:e.gl.vertexAttrib1fv(t,i);break;case 2:e.gl.vertexAttrib2fv(t,i);break;case 3:e.gl.vertexAttrib3fv(t,i);break;case 4:e.gl.vertexAttrib4fv(t,i);break}}function VT(e,t,i){e.gl.vertexAttribI4iv(t,i)}function HT(e,t,i){e.gl.vertexAttribI4uiv(t,i)}function $T(e,t){if(!e||!t||e.length!==t.length||e.constructor!==t.constructor)return!1;for(let i=0;i 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + rgba = vec4(pointPosition.xy, 1.0, 0.0); + + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,jT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D centermassTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceCenterUniforms { + float centerForce; + float alpha; +} forceCenter; + +#define centerForce forceCenter.centerForce +#define alpha forceCenter.alpha +#else +uniform float centerForce; +uniform float alpha; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + vec4 centermassValues = texelFetch(centermassTexture, ivec2(0), 0); + vec2 centermassPosition = centermassValues.xy / centermassValues.b; + vec2 distVector = centermassPosition - pointPosition.xy; + float dist = sqrt(dot(distVector, distVector)); + if (dist > 0.0) { + float angle = atan(distVector.y, distVector.x); + float addV = alpha * centerForce * dist * 0.01; + velocity.rg += addV * vec2(cos(angle), sin(angle)); + } + + fragColor = velocity; +}`,Ee=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 vertexCoord; // Vertex coordinates in normalized device coordinates + +void main() { + gl_Position = vec4(vertexCoord, 0, 1); +} +`;class KT extends gt{create(){var r;const{device:t,store:i}=this,{pointsTextureSize:n}=i;if(n){if(this.centermassTexture||(this.centermassTexture=t.createTexture({width:1,height:1,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST})),this.centermassTexture.copyImageData({data:new Float32Array(4).fill(0),bytesPerRow:q("rgba32float",1),mipLevel:0,x:0,y:0}),this.centermassFbo||(this.centermassFbo=t.createFramebuffer({width:1,height:1,colorAttachments:[this.centermassTexture]})),!this.pointIndices||this.previousPointsTextureSize!==i.pointsTextureSize){this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy();const s=ji(i.pointsTextureSize);this.pointIndices=t.createBuffer({data:s,usage:B.VERTEX|B.COPY_DST}),(r=this.calculateCentermassCommand)==null||r.setAttributes({pointIndices:this.pointIndices})}this.previousPointsTextureSize=n}}initPrograms(){const{device:t,store:i,points:n}=this;!n||!i.pointsTextureSize||!this.centermassFbo||this.centermassFbo.destroyed||!this.centermassTexture||this.centermassTexture.destroyed||(this.forceVertexCoordBuffer||(this.forceVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.forceUniformStore||(this.forceUniformStore=new oe(t,{forceCenterUniforms:{uniformTypes:{centerForce:"f32",alpha:"f32"}}})),this.calculateCentermassCommand||(this.calculateCentermassCommand=new ee(t,{fs:XT,vs:YT,topology:"point-list",attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber??0),this.runCommand||(this.runCommand=new ee(t,{fs:jT,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceCenterUniforms:this.forceUniformStore.getManagedUniformBuffer("forceCenterUniforms")},parameters:te})))}run(){const{device:t,store:i,points:n}=this;if(!n||!this.calculateCentermassCommand||!this.runCommand||!this.forceUniformStore||!this.centermassFbo||!this.centermassTexture||!n.previousPositionTexture||n.previousPositionTexture.destroyed||!n.velocityFbo||n.velocityFbo.destroyed||!n.exitTexture||n.exitTexture.destroyed||i.pointsTextureSize!==this.previousPointsTextureSize||!this.pointIndices)return;const r=t.beginRenderPass({framebuffer:this.centermassFbo,clearColor:[0,0,0,0]});this.calculateCentermassCommand.setBindings({positionsTexture:n.previousPositionTexture,exitTexture:n.exitTexture}),this.calculateCentermassCommand.draw(r),r.end(),this.forceUniformStore.setUniforms({forceCenterUniforms:{centerForce:this.config.simulationCenter,alpha:i.alpha}}),this.runCommand.setBindings({positionsTexture:n.previousPositionTexture,centermassTexture:this.centermassTexture});const s=t.beginRenderPass({framebuffer:n.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(s),s.end()}destroy(){var t,i,n;(t=this.calculateCentermassCommand)==null||t.destroy(),this.calculateCentermassCommand=void 0,(i=this.runCommand)==null||i.destroy(),this.runCommand=void 0,this.centermassFbo&&!this.centermassFbo.destroyed&&this.centermassFbo.destroy(),this.centermassFbo=void 0,this.centermassTexture&&!this.centermassTexture.destroyed&&this.centermassTexture.destroy(),this.centermassTexture=void 0,(n=this.forceUniformStore)==null||n.destroy(),this.forceUniformStore=void 0,this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=void 0,this.forceVertexCoordBuffer&&!this.forceVertexCoordBuffer.destroyed&&this.forceVertexCoordBuffer.destroy(),this.forceVertexCoordBuffer=void 0,this.previousPointsTextureSize=void 0}}const qT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D sizeTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform buildGridUniforms { + float gridTextureSize; + float cellSize; + vec2 gridOffset; // Offset for multi-pass (0-1 range, multiplied by cellSize) +} buildGrid; + +#define gridTextureSize buildGrid.gridTextureSize +#define cellSize buildGrid.cellSize +#define gridOffset buildGrid.gridOffset +#else +uniform float gridTextureSize; +uniform float cellSize; +uniform vec2 gridOffset; +#endif + +in vec2 pointIndices; + +out vec4 cellData; // xy = position, z = size, w = count (1.0) + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not enter the grid — a NaN position bins to a NaN cell and + // poisons the accumulated position/size sum for every point in that cell. (exit.g = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 pointSize = texelFetch(sizeTexture, pointTexel, 0); + + // Output: position sum, size sum, count + cellData = vec4(pointPosition.xy, pointSize.r, 1.0); + + // Apply grid offset for multi-pass collision detection + vec2 offsetPosition = pointPosition.xy + gridOffset * cellSize; + + // Calculate which grid cell this point belongs to + float cellX = floor(offsetPosition.x / cellSize); + float cellY = floor(offsetPosition.y / cellSize); + + // Clamp to grid bounds + cellX = clamp(cellX, 0.0, gridTextureSize - 1.0); + cellY = clamp(cellY, 0.0, gridTextureSize - 1.0); + + // Convert to clip space coordinates + vec2 gridPosition = 2.0 * (vec2(cellX, cellY) + 0.5) / gridTextureSize - 1.0; + + gl_Position = vec4(gridPosition, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,GT=`#version 300 es +precision highp float; + +in vec4 cellData; +out vec4 fragColor; + +void main() { + // Output accumulated cell data (blended additively) + // xy = sum of positions, z = sum of sizes, w = count + fragColor = cellData; +} +`,ZT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D sizeTexture; +uniform sampler2D gridTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceCollisionUniforms { + float gridTextureSize; + float cellSize; + float alpha; + float collisionStrength; + float collisionRadius; + float collisionPadding; + float pointsNumber; + vec2 gridOffset; // Must match the offset used when building the grid +} forceCollision; + +#define gridTextureSize forceCollision.gridTextureSize +#define cellSize forceCollision.cellSize +#define alpha forceCollision.alpha +#define collisionStrength forceCollision.collisionStrength +#define collisionRadius forceCollision.collisionRadius +#define collisionPadding forceCollision.collisionPadding +#define pointsNumber forceCollision.pointsNumber +#define gridOffset forceCollision.gridOffset +#else +uniform float gridTextureSize; +uniform float cellSize; +uniform float alpha; +uniform float collisionStrength; +uniform float collisionRadius; +uniform float collisionPadding; +uniform float pointsNumber; +uniform vec2 gridOffset; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + + // Get current point's index + float currentIndex = pointPosition.b; + + // Skip if this is an empty texel + if (currentIndex < 0.0 || currentIndex >= pointsNumber) { + fragColor = velocity; + return; + } + + // Get current point's size for collision radius + vec4 currentSizeData = texelFetch(sizeTexture, pointTexel, 0); + float currentSize = currentSizeData.r; + float currentCollisionRadius = (collisionRadius > 0.0 ? collisionRadius : currentSize * 0.5) + collisionPadding; + + vec2 currentPos = pointPosition.rg; + + // Apply the same offset used when building the grid + vec2 offsetPos = currentPos + gridOffset * cellSize; + + // Calculate which grid cell this point is in (with offset). + // Clamp to the grid bounds to match build-grid.vert, so a point that drifts + // outside the space still reads the edge cell it was binned into. + float myCellX = clamp(floor(offsetPos.x / cellSize), 0.0, gridTextureSize - 1.0); + float myCellY = clamp(floor(offsetPos.y / cellSize), 0.0, gridTextureSize - 1.0); + + // Track total neighbor count for damping + float totalNeighbors = 0.0; + + // Check 3x3 neighborhood of cells + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + float neighborCellX = myCellX + float(dx); + float neighborCellY = myCellY + float(dy); + + // Skip cells outside grid bounds + if (neighborCellX < 0.0 || neighborCellX >= gridTextureSize || + neighborCellY < 0.0 || neighborCellY >= gridTextureSize) { + continue; + } + + // Sample the grid cell (the bounds check above keeps the fetch in range) + ivec2 cell = ivec2(neighborCellX, neighborCellY); + vec4 cellData = texelFetch(gridTexture, cell, 0); + + float cellCount = cellData.w; + if (cellCount < 0.5) continue; // Empty cell + + // The own cell's sums include this point, which drags the average toward + // it and halves the measured distance for a two-point cell. Remove the + // self-contribution before averaging, and skip a cell holding only self. + float effectiveCount = cellCount; + vec2 sumPos = cellData.xy; + float sumSize = cellData.z; + if (dx == 0 && dy == 0) { + effectiveCount = cellCount - 1.0; + sumPos -= currentPos; + sumSize -= currentSize; + } + if (effectiveCount < 0.5) continue; + + totalNeighbors += effectiveCount; + + // Average position and size of the *other* points in this cell + vec2 avgPos = sumPos / effectiveCount; + float avgSize = sumSize / effectiveCount; + float otherCollisionRadius = (collisionRadius > 0.0 ? collisionRadius : avgSize * 0.5) + collisionPadding; + + // Calculate combined collision radius + float combinedRadius = currentCollisionRadius + otherCollisionRadius; + + // Calculate distance vector to average position (using original positions) + vec2 distVector = currentPos - avgPos; + float dist = length(distVector); + + // Check for collision + if (dist < combinedRadius && dist > 0.001) { + // Calculate overlap ratio (0 = just touching, 1 = fully overlapping) + float overlapRatio = (combinedRadius - dist) / combinedRadius; + + // Soft collision curve: use square root for gentler force near edges + // This prevents the "ping-pong" effect at boundaries + float softOverlap = sqrt(overlapRatio) * combinedRadius * 0.5; + + // Direction to push apart (normalized) + vec2 direction = distVector / dist; + + // Apply repulsion force with soft curve + // Divide by 4 since we run 4 passes with different offsets + float force = alpha * collisionStrength * softOverlap * 0.25 * effectiveCount; + + // Clamp maximum force to prevent instability + force = min(force, combinedRadius * 0.5); + + velocity.rg += force * direction; + } else if (dist <= 0.001 && effectiveCount > 0.0) { + // Points at same position - push based on index + float angle = currentIndex * 0.618033988749895; + float force = min(alpha * collisionStrength * combinedRadius * 0.1, combinedRadius * 0.3); + velocity.rg += force * effectiveCount * vec2(cos(angle), sin(angle)); + } + } + } + + // Apply density-based damping: reduce force when surrounded by many neighbors + // This prevents chaotic oscillations in dense clusters + if (totalNeighbors > 2.0) { + float damping = 2.0 / totalNeighbors; + velocity.rg *= damping; + } + + // Cap the per-pass correction so overlaps resolve by relaxation over a few + // frames instead of overshooting in one. Across the 4 offset passes the + // total displacement stays within ~40% of this point's collision radius, + // which converges without the ping-pong of full-overlap corrections. + float maxCorrection = currentCollisionRadius * 0.1; + float correction = length(velocity.rg); + if (correction > maxCorrection) { + velocity.rg *= maxCorrection / correction; + } + + fragColor = velocity; +} +`,tn=[[0,0],[.5,0],[0,.5],[.5,.5]];class QT extends gt{constructor(){super(...arguments),this.gridTargets=[],this.gridTextureSize=0,this.cellSize=0}create(){var p;const{device:t,store:i,data:n,config:r}=this;if(!i.pointsTextureSize||n.pointsNumber===void 0)return;let o=r.pointDefaultSize??Ze.pointDefaultSize;if(n.pointSizes&&n.pointsNumber!==void 0)for(let g=0;g0?a:o*.5)+l;this.cellSize=Math.max(c*2,8),this.gridTextureSize=Math.min(512,Math.max(1,Math.floor(i.adjustedSpaceSize/this.cellSize))),this.cellSize=i.adjustedSpaceSize/this.gridTextureSize,this.gridTargets.length===tn.length&&this.gridTargets.every(g=>!g.texture.destroyed&&!g.fbo.destroyed&&g.texture.width===this.gridTextureSize)||(this.destroyGridTargets(),this.gridTargets=tn.map(()=>{const g=t.createTexture({width:this.gridTextureSize,height:this.gridTextureSize,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),x=t.createFramebuffer({width:this.gridTextureSize,height:this.gridTextureSize,colorAttachments:[g]});return{texture:g,fbo:x}}));const d=new Float32Array(i.pointsTextureSize*i.pointsTextureSize*4);for(let g=0;g"}}})),this.buildGridCommand||(this.buildGridCommand=new ee(t,{fs:GT,vs:qT,topology:"point-list",vertexCount:n.pointsNumber,attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{buildGridUniforms:this.buildGridUniformStore.getManagedUniformBuffer("buildGridUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.forceUniformStore||(this.forceUniformStore=new oe(t,{forceCollisionUniforms:{uniformTypes:{gridTextureSize:"f32",cellSize:"f32",alpha:"f32",collisionStrength:"f32",collisionRadius:"f32",collisionPadding:"f32",pointsNumber:"f32",gridOffset:"vec2"}}})),this.forceVertexCoordBuffer||(this.forceVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.forceCommand||(this.forceCommand=new ee(t,{fs:ZT,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceCollisionUniforms:this.forceUniformStore.getManagedUniformBuffer("forceCollisionUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})))}run(){const{device:t,store:i,data:n,points:r,config:s}=this;if(!r||!this.buildGridCommand||!this.buildGridUniformStore||!this.forceCommand||!this.forceUniformStore||!this.pointIndices||n.pointsNumber===void 0||!r.previousPositionTexture||r.previousPositionTexture.destroyed||!r.exitTexture||r.exitTexture.destroyed||!r.velocityFbo||r.velocityFbo.destroyed||!this.sizeTexture||this.sizeTexture.destroyed||this.gridTargets.length!==tn.length||i.pointsTextureSize!==this.previousPointsTextureSize||i.adjustedSpaceSize!==this.previousSpaceSize)return;const o=s.simulationCollisionRadius??0,a=s.simulationCollisionPadding??0;this.buildGridCommand.setVertexCount(n.pointsNumber),this.buildGridCommand.setBindings({positionsTexture:r.previousPositionTexture,sizeTexture:this.sizeTexture,exitTexture:r.exitTexture});for(const[c,u]of tn.entries()){const d=this.gridTargets[c];if(!d||d.fbo.destroyed||d.texture.destroyed)continue;this.buildGridUniformStore.setUniforms({buildGridUniforms:{gridTextureSize:this.gridTextureSize,cellSize:this.cellSize,gridOffset:u}});const h=t.beginRenderPass({framebuffer:d.fbo,clearColor:[0,0,0,0]});this.buildGridCommand.draw(h),h.end()}this.forceCommand.setBindings({positionsTexture:r.previousPositionTexture,sizeTexture:this.sizeTexture});const l=t.beginRenderPass({framebuffer:r.velocityFbo,clearColor:[0,0,0,0]});for(const[c,u]of tn.entries()){const d=this.gridTargets[c];!d||d.texture.destroyed||(this.forceUniformStore.setUniforms({forceCollisionUniforms:{gridTextureSize:this.gridTextureSize,cellSize:this.cellSize,alpha:i.alpha,collisionStrength:s.simulationCollision??0,collisionRadius:o,collisionPadding:a,pointsNumber:n.pointsNumber,gridOffset:u}}),this.forceCommand.setBindings({gridTexture:d.texture}),this.forceCommand.draw(l))}l.end()}destroy(){var t,i,n,r;(t=this.buildGridCommand)==null||t.destroy(),this.buildGridCommand=void 0,(i=this.forceCommand)==null||i.destroy(),this.forceCommand=void 0,this.destroyGridTargets(),this.sizeTexture&&!this.sizeTexture.destroyed&&this.sizeTexture.destroy(),this.sizeTexture=void 0,(n=this.buildGridUniformStore)==null||n.destroy(),this.buildGridUniformStore=void 0,(r=this.forceUniformStore)==null||r.destroy(),this.forceUniformStore=void 0,this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=void 0,this.forceVertexCoordBuffer&&!this.forceVertexCoordBuffer.destroyed&&this.forceVertexCoordBuffer.destroy(),this.forceVertexCoordBuffer=void 0}destroyGridTargets(){for(const t of this.gridTargets)t.fbo&&!t.fbo.destroyed&&t.fbo.destroy();for(const t of this.gridTargets)t.texture&&!t.texture.destroyed&&t.texture.destroy();this.gridTargets=[]}}const JT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceGravityUniforms { + float gravity; + float spaceSize; + float alpha; +} forceGravity; + +#define gravity forceGravity.gravity +#define spaceSize forceGravity.spaceSize +#define alpha forceGravity.alpha +#else +uniform float gravity; +uniform float spaceSize; +uniform float alpha; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + + vec4 velocity = vec4(0.0); + + vec2 centerPosition = vec2(spaceSize * 0.5); + vec2 distVector = centerPosition - pointPosition.rg; + float dist = sqrt(dot(distVector, distVector)); + if (dist > 0.0) { + float angle = atan(distVector.y, distVector.x); + float additionalVelocity = alpha * gravity * dist * 0.1; + velocity.rg += additionalVelocity * vec2(cos(angle), sin(angle)); + } + + fragColor = velocity; +}`;class ev extends gt{initPrograms(){const{device:t,points:i,store:n}=this;!i||!n.pointsTextureSize||(this.vertexCoordBuffer||(this.vertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.uniformStore||(this.uniformStore=new oe(t,{forceGravityUniforms:{uniformTypes:{gravity:"f32",spaceSize:"f32",alpha:"f32"}}})),this.runCommand||(this.runCommand=new ee(t,{fs:JT,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.vertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceGravityUniforms:this.uniformStore.getManagedUniformBuffer("forceGravityUniforms")},parameters:te})))}run(){const{device:t,points:i,store:n}=this;if(!i||!this.runCommand||!this.uniformStore||!i.previousPositionTexture||i.previousPositionTexture.destroyed||!i.velocityFbo||i.velocityFbo.destroyed)return;this.uniformStore.setUniforms({forceGravityUniforms:{gravity:this.config.simulationGravity,spaceSize:n.adjustedSpaceSize,alpha:n.alpha}}),this.runCommand.setBindings({positionsTexture:i.previousPositionTexture});const r=t.beginRenderPass({framebuffer:i.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(r),r.end()}destroy(){var t,i;(t=this.runCommand)==null||t.destroy(),this.runCommand=void 0,(i=this.uniformStore)==null||i.destroy(),this.uniformStore=void 0,this.vertexCoordBuffer&&!this.vertexCoordBuffer.destroyed&&this.vertexCoordBuffer.destroy(),this.vertexCoordBuffer=void 0}}function tv(e){return`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; +uniform sampler2D linkInfoTexture; // Texture storing first link indices and amount +uniform sampler2D linkIndicesTexture; +uniform sampler2D linkPropertiesTexture; // Texture storing link bias and strength +uniform sampler2D linkRandomDistanceTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceLinkUniforms { + float linkSpring; + float linkDistance; + vec2 linkDistRandomVariationRange; + float linksTextureSize; + float alpha; +} forceLink; + +#define linkSpring forceLink.linkSpring +#define linkDistance forceLink.linkDistance +#define linkDistRandomVariationRange forceLink.linkDistRandomVariationRange +#define linksTextureSize forceLink.linksTextureSize +#define alpha forceLink.alpha +#else +uniform float linkSpring; +uniform float linkDistance; +uniform vec2 linkDistRandomVariationRange; +uniform float linksTextureSize; +uniform float alpha; +#endif + +out vec4 fragColor; + +const float MAX_LINKS = ${e}.0; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + + vec4 linkInfo = texelFetch(linkInfoTexture, pointTexel, 0); + float iCount = linkInfo.r; + float jCount = linkInfo.g; + float linkAmount = linkInfo.b; + if (linkAmount > 0.0) { + for (float i = 0.0; i < MAX_LINKS; i += 1.0) { + if (i < linkAmount) { + if (iCount >= linksTextureSize) { + iCount = 0.0; + jCount += 1.0; + } + ivec2 linkTexel = ivec2(iCount, jCount); + vec4 connectedPointIndex = texelFetch(linkIndicesTexture, linkTexel, 0); + vec4 biasAndStrength = texelFetch(linkPropertiesTexture, linkTexel, 0); + vec4 randomMinDistance = texelFetch(linkRandomDistanceTexture, linkTexel, 0); + float bias = biasAndStrength.r; + float strength = biasAndStrength.g; + float randomMinLinkDist = randomMinDistance.r * (linkDistRandomVariationRange.g - linkDistRandomVariationRange.r) + linkDistRandomVariationRange.r; + randomMinLinkDist *= linkDistance; + + iCount += 1.0; + + // linkIndicesTexture stores whole texel coordinates, so truncating is exact. + ivec2 connectedTexel = ivec2(connectedPointIndex.rg); + + // Skip a link to an absent point — its position would poison the spring + // force. (exit.G = current absence) + vec4 connectedExit = texelFetch(exitTexture, connectedTexel, 0); + if (connectedExit.g > 0.5) { + continue; + } + + vec4 connectedPointPosition = texelFetch(positionsTexture, connectedTexel, 0); + float x = connectedPointPosition.x - (pointPosition.x + velocity.x); + float y = connectedPointPosition.y - (pointPosition.y + velocity.y); + float l = sqrt(x * x + y * y); + + // Apply the link force + l = max(l, randomMinLinkDist * 0.99); + l = (l - randomMinLinkDist) / l; + l *= linkSpring * alpha; + l *= strength; + l *= bias; + x *= l; + y *= l; + velocity.x += x; + velocity.y += y; + } + } + } + + fragColor = vec4(velocity.rg, 0.0, 0.0); +} + `}var jo=(e=>(e.OUTGOING="outgoing",e.INCOMING="incoming",e))(jo||{});class Td extends gt{constructor(){super(...arguments),this.linkFirstIndicesAndAmount=new Float32Array,this.indices=new Float32Array,this.maxPointDegree=0}create(t){var d,h,p,g;const{device:i,store:{pointsTextureSize:n,linksTextureSize:r},data:s}=this;if(!n||!r)return;this.linkFirstIndicesAndAmount=new Float32Array(n*n*4),this.indices=new Float32Array(r*r*4);const o=new Float32Array(r*r*4),a=new Float32Array(r*r*4),l=t==="incoming"?s.linksBySource:s.linksByTarget;if(this.maxPointDegree=0,l){const{offsets:x,neighbors:T,linkIndices:S}=l;for(let P=0;P",linksTextureSize:"f32",alpha:"f32"}}})),this.runCommand||(this.runCommand=new ee(t,{fs:tv(this.maxPointDegree),vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.vertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceLinkUniforms:this.uniformStore.getManagedUniformBuffer("forceLinkUniforms")},parameters:te})))}run(){const{device:t,store:i,points:n}=this;if(!n||!this.runCommand||!this.uniformStore||!n.previousPositionTexture||n.previousPositionTexture.destroyed||!n.exitTexture||n.exitTexture.destroyed||!this.linkFirstIndicesAndAmountTexture||!this.indicesTexture||!this.biasAndStrengthTexture||!this.randomDistanceTexture||!n.velocityFbo||n.velocityFbo.destroyed||i.pointsTextureSize!==this.previousPointsTextureSize||i.linksTextureSize!==this.previousLinksTextureSize)return;this.uniformStore.setUniforms({forceLinkUniforms:{linkSpring:this.config.simulationLinkSpring,linkDistance:this.config.simulationLinkDistance,linkDistRandomVariationRange:ie(this.config.simulationLinkDistRandomVariationRange,[0,0]),linksTextureSize:i.linksTextureSize,alpha:i.alpha}}),this.runCommand.setBindings({positionsTexture:n.previousPositionTexture,exitTexture:n.exitTexture,linkInfoTexture:this.linkFirstIndicesAndAmountTexture,linkIndicesTexture:this.indicesTexture,linkPropertiesTexture:this.biasAndStrengthTexture,linkRandomDistanceTexture:this.randomDistanceTexture});const r=t.beginRenderPass({framebuffer:n.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(r),r.end()}destroy(){var t,i;(t=this.runCommand)==null||t.destroy(),this.runCommand=void 0,this.linkFirstIndicesAndAmountTexture&&!this.linkFirstIndicesAndAmountTexture.destroyed&&this.linkFirstIndicesAndAmountTexture.destroy(),this.linkFirstIndicesAndAmountTexture=void 0,this.indicesTexture&&!this.indicesTexture.destroyed&&this.indicesTexture.destroy(),this.indicesTexture=void 0,this.biasAndStrengthTexture&&!this.biasAndStrengthTexture.destroyed&&this.biasAndStrengthTexture.destroy(),this.biasAndStrengthTexture=void 0,this.randomDistanceTexture&&!this.randomDistanceTexture.destroyed&&this.randomDistanceTexture.destroy(),this.randomDistanceTexture=void 0,(i=this.uniformStore)==null||i.destroy(),this.uniformStore=void 0,this.vertexCoordBuffer&&!this.vertexCoordBuffer.destroyed&&this.vertexCoordBuffer.destroy(),this.vertexCoordBuffer=void 0}}const iv=`#version 300 es +precision highp float; + +in vec4 vColor; +out vec4 fragColor; + +void main() { + fragColor = vColor; +}`,nv=`#version 300 es +precision highp float; + +// Aggregates each point into its grid cell. A level is a plain 2D grid of +// \`levelGridSize\` cells per axis rendered one texel per cell; additive blending +// accumulates [sum(x), sum(y), count, 0] per cell via calculate-level.frag. + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform calculateLevelsPreciseUniforms { + float levelGridSize; + float cellSize; +} calculateLevelsPrecise; + +#define levelGridSize calculateLevelsPrecise.levelGridSize +#define cellSize calculateLevelsPrecise.cellSize +#else +uniform float levelGridSize; +uniform float cellSize; +#endif + +in vec2 pointIndices; + +out vec4 vColor; + +void main() { + vColor = vec4(0.0); + + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not enter the grid — a NaN position bins to a NaN cell and + // poisons the centermass that drives repulsion for every point. (exit.G = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vColor = vec4(pointPosition.rg, 1.0, 0.0); + + // The clamp must match the force shaders exactly, or boundary points fall out + // of the level decomposition's exactly-once coverage. + int gridSize = int(levelGridSize); + ivec2 cell = clamp(ivec2(floor(pointPosition.rg / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + vec2 levelPosition = 2.0 * (vec2(cell) + 0.5) / levelGridSize - 1.0; + gl_Position = vec4(levelPosition, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,rv=`#version 300 es +precision highp float; + +// One grid level of precise many-body repulsion (Barnes-Hut-style approximation). +// +// Levels are 2D grids of increasing resolution (4², 8², …) holding +// [sum(x), sum(y), count, 0] per cell. The decomposition tiles space exactly +// once across the level passes: after level L the only un-accumulated region is +// the 3×3 Chebyshev-1 neighborhood of the point's cell, which the next level +// refines (its aligned 6×6 child block), and which force-nearfield.frag finally +// covers at the finest level. The exclusion shell is fixed at Chebyshev +// distance 1. + +uniform sampler2D positionsTexture; +uniform sampler2D levelTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceLevelPreciseUniforms { + float levelGridSize; + float cellSize; + float isFirstLevel; + float alpha; + float repulsion; +} forceLevelPrecise; + +#define levelGridSize forceLevelPrecise.levelGridSize +#define cellSize forceLevelPrecise.cellSize +#define isFirstLevel forceLevelPrecise.isFirstLevel +#define alpha forceLevelPrecise.alpha +#define repulsion forceLevelPrecise.repulsion +#else +uniform float levelGridSize; +uniform float cellSize; +uniform float isFirstLevel; +uniform float alpha; +uniform float repulsion; +#endif + +out vec4 fragColor; + +// Repulsion from one cell's center of mass — a d3-style clamped +// inverse-distance falloff. +vec2 cellVelocity(ivec2 cell, vec2 position) { + vec4 centermass = texelFetch(levelTexture, cell, 0); + // Count-only guard: zero coordinate sums are legitimate, but dividing by a zero + // count would produce NaN that additive blending propagates into the velocity FBO. + if (centermass.b <= 0.0) return vec2(0.0); + vec2 centermassPosition = centermass.rg / centermass.b; + vec2 distVector = position - centermassPosition; + float l = dot(distVector, distVector); + if (l <= 0.0) return vec2(0.0); + float distanceMin2 = 1.0; + if (l < distanceMin2) l = sqrt(distanceMin2 * l); + float addV = alpha * repulsion * centermass.b / sqrt(l); + return addV * normalize(distVector); +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 position = pointPosition.rg; + + int gridSize = int(levelGridSize); + // Must match the aggregation shader's cell formula exactly. + ivec2 pointCell = clamp(ivec2(floor(position / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + vec2 velocity = vec2(0.0); + + if (isFirstLevel > 0.5) { + // Coarsest level: every cell except the 3×3 neighborhood, which finer levels refine. + for (int j = 0; j < gridSize; j += 1) { + for (int i = 0; i < gridSize; i += 1) { + ivec2 cell = ivec2(i, j); + ivec2 cellDist = abs(cell - pointCell); + if (max(cellDist.x, cellDist.y) <= 1) continue; + velocity += cellVelocity(cell, position); + } + } + } else { + // The coarser level left its 3×3 neighborhood unhandled; those cells refine to + // the aligned 6×6 child block at this level. Sample it minus this level's own + // 3×3 neighborhood (always strictly inside the block). + ivec2 base = (pointCell / 2) * 2 - 2; + for (int j = 0; j < 6; j += 1) { + for (int i = 0; i < 6; i += 1) { + ivec2 cell = base + ivec2(i, j); + // Bounds check must precede texelFetch (out-of-range fetches are undefined). + if (any(lessThan(cell, ivec2(0))) || any(greaterThanEqual(cell, ivec2(gridSize)))) continue; + ivec2 cellDist = abs(cell - pointCell); + if (max(cellDist.x, cellDist.y) <= 1) continue; + velocity += cellVelocity(cell, position); + } + } + } + + fragColor = vec4(velocity, 0.0, 0.0); +} +`,sv=`#version 300 es +precision highp float; +// Fragment shaders default int to mediump, guaranteed only to 32767 — +// point indices go far higher. +precision highp int; + +// Near-field pass of the precise grid repulsion (P3M-style). After the finest +// level pass, the only un-accumulated region is the 3×3 neighborhood of the +// point's cell. +// +// Cell centroids exert a purely radial force there, which flattens dense hubs +// into disks and petals — even as a residual for unsampled mass, the centroid +// bias dominates (tangential repulsion scaled by ~K/n never spreads a dense +// clump before alpha decays). So the near field is a pure Monte-Carlo estimator +// instead: the K depth-peeled points of a cell are a uniform random subset +// (re-drawn every tick by build-nearfield-slots.vert), and weighting each +// sampled pairwise force by count/sampled makes the expected force equal the +// exact all-pairs sum — unbiased, no centroid term. Cells holding ≤ K points +// are sampled exhaustively, so their forces are exact. The per-tick sampling +// noise acts as annealed jitter: it shrinks with alpha and is precisely what +// breaks clumps apart. The point itself is excluded from both the sample and +// the count. + +uniform sampler2D positionsTexture; +uniform sampler2D levelTexture; +uniform sampler2D randomValues; +// All near-field slots live in one array texture (one layer per depth-peeling +// pass), so the slot count is a runtime uniform instead of a hard-wired list +// of sampler2Ds. Float data — highp, the default sampler precision is lowp. +uniform highp sampler2DArray slotsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceNearFieldUniforms { + float pointsTextureSize; + float levelGridSize; + float cellSize; + float alpha; + float repulsion; + float slotCount; +} forceNearField; + +#define pointsTextureSize forceNearField.pointsTextureSize +#define levelGridSize forceNearField.levelGridSize +#define cellSize forceNearField.cellSize +#define alpha forceNearField.alpha +#define repulsion forceNearField.repulsion +#define slotCount forceNearField.slotCount +#else +uniform float pointsTextureSize; +uniform float levelGridSize; +uniform float cellSize; +uniform float alpha; +uniform float repulsion; +uniform float slotCount; +#endif + +out vec4 fragColor; + +// Same clamped inverse-distance falloff as the level passes (must stay identical). +vec2 pairwiseVelocity(vec2 position, vec2 otherPosition, vec2 randomDir) { + vec2 distVector = position - otherPosition; + float l = dot(distVector, distVector); + if (l <= 0.0) { + // Exactly coincident points have no separation direction, so an inverse-distance + // force is undefined and they would stay stacked forever — a stack's cell count + // then repels everything around it, carving a void ring. Kick along this point's + // random vector instead (each point has a different one, so a pile disperses). + distVector = randomDir; + l = dot(distVector, distVector); + if (l <= 0.0) return vec2(0.0); + } + float distanceMin2 = 1.0; + if (l < distanceMin2) l = sqrt(distanceMin2 * l); + float addV = alpha * repulsion / sqrt(l); + return addV * normalize(distVector); +} + +// One peeled slot of a cell: the unweighted pairwise force from the sampled +// point, counting it toward the sample size. Empty slots and the point itself +// contribute nothing. +vec2 slotVelocity(vec2 slot, vec2 position, float selfIndex, vec2 randomDir, inout float sampled) { + float index = slot.x; + // Skip empty slots (index -1) and the point itself. This exact \`==\` — and the + // texel math just below — count on a point index fitting exactly in a float, + // which only holds for whole numbers up to ~16.7M (2^24). That's every + // realistic graph; you'd need a points texture bigger than 4096² to get there. + // Past that, indices start rounding, so a point could sample the wrong texel or + // fail to skip itself — but you'd hit memory limits long before it matters. + if (index < 0.0 || index == selfIndex) return vec2(0.0); + int size = int(pointsTextureSize); + int i = int(index); + vec4 other = texelFetch(positionsTexture, ivec2(i % size, i / size), 0); + sampled += 1.0; + return pairwiseVelocity(position, other.rg, randomDir); +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 position = pointPosition.rg; + // One fragment per point: the fragment's pixel is the point's texel. + float selfIndex = floor(gl_FragCoord.y) * pointsTextureSize + floor(gl_FragCoord.x); + vec4 random = texelFetch(randomValues, pointTexel, 0); + + int gridSize = int(levelGridSize); + ivec2 pointCell = clamp(ivec2(floor(position / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + vec2 velocity = vec2(0.0); + + for (int j = -1; j <= 1; j += 1) { + for (int i = -1; i <= 1; i += 1) { + ivec2 cell = pointCell + ivec2(i, j); + if (any(lessThan(cell, ivec2(0))) || any(greaterThanEqual(cell, ivec2(gridSize)))) continue; + + // [sum(x), sum(y), count, 0] — only the count is used here. + vec4 aggregate = texelFetch(levelTexture, cell, 0); + // The count never includes the point itself in the estimate. + bool ownCell = (i == 0 && j == 0); + float others = aggregate.b - (ownCell ? 1.0 : 0.0); + if (others <= 0.0) continue; + + vec2 pairSum = vec2(0.0); + float sampled = 0.0; + // One layer per depth-peeling pass. An exhausted cell peels empty slots + // (index -1) for the remaining layers; the early break skips them — + // empty layers can't be followed by occupied ones within a cell. + int slots = int(slotCount); + for (int s = 0; s < slots; s += 1) { + vec2 slot = texelFetch(slotsTexture, ivec3(cell, s), 0).rg; + if (slot.x < 0.0) break; + pairSum += slotVelocity(slot, position, selfIndex, random.rg, sampled); + } + + // Horvitz–Thompson weighting: the sample is uniform among the cell's + // other points (conditioned on whether the point itself was peeled), + // so scaling by others/sampled gives E[force] = exact all-pairs sum. + // Exhaustively peeled cells (others == sampled) are exact. + if (sampled > 0.0) velocity += (others / sampled) * pairSum; + } + } + + // Random jitter proportional to the velocity, to keep points from sticking. + velocity += velocity * random.rg; + + // Bound the per-tick kick to the neighborhood scale. The estimator is unbiased + // but high-variance: in a cell holding far more points than sampled slots, the + // count/sampled weight can turn a few close samples into a huge one-tick kick. + // Unbounded, that flings points across the screen at startup and — because the + // weight is largest where density is highest — ejects points from dense cluster + // centers, leaving voids. Clamping the magnitude keeps the spreading direction + // while capping the fling; genuine spreading kicks are far below this bound and + // pass through untouched. The far-field grid levels still drive bulk expansion. + float maxStep = 2.0 * cellSize; + float speed = length(velocity); + if (speed > maxStep) velocity *= maxStep / speed; + + fragColor = vec4(velocity, 0.0, 0.0); +} +`,ov=`#version 300 es +precision highp float; +// Fragment shaders default int to mediump, guaranteed only to 32767 — +// point indices go far higher. +precision highp int; + +// Exact all-pairs repulsion for small graphs. One fragment per point, looping +// over every other point — O(n²) total, but below the brute-force threshold a +// single pass is both cheaper than the grid pyramid's sequential depth-peeling +// passes and exact at any cell occupancy: no Monte-Carlo sampling, hence none +// of the per-tick re-sampling noise that shows up as shimmer in dense layouts +// (see force-nearfield.frag for the sampled path used above the threshold). + +uniform sampler2D positionsTexture; +uniform sampler2D randomValues; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceAllPairsUniforms { + float pointsTextureSize; + float pointsNumber; + float alpha; + float repulsion; + float maxStep; +} forceAllPairs; + +#define pointsTextureSize forceAllPairs.pointsTextureSize +#define pointsNumber forceAllPairs.pointsNumber +#define alpha forceAllPairs.alpha +#define repulsion forceAllPairs.repulsion +#define maxStep forceAllPairs.maxStep +#else +uniform float pointsTextureSize; +uniform float pointsNumber; +uniform float alpha; +uniform float repulsion; +uniform float maxStep; +#endif + +out vec4 fragColor; + +// Same clamped inverse-distance falloff as the grid-path shaders (must stay identical). +vec2 pairwiseVelocity(vec2 position, vec2 otherPosition, vec2 randomDir) { + vec2 distVector = position - otherPosition; + float l = dot(distVector, distVector); + if (l <= 0.0) { + // Exactly coincident points have no separation direction, so an + // inverse-distance force is undefined and they would stay stacked forever. + // Kick along this point's random vector instead (each point has a + // different one, so a pile disperses). + distVector = randomDir; + l = dot(distVector, distVector); + if (l <= 0.0) return vec2(0.0); + } + float distanceMin2 = 1.0; + if (l < distanceMin2) l = sqrt(distanceMin2 * l); + float addV = alpha * repulsion / sqrt(l); + return addV * normalize(distVector); +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + int size = int(pointsTextureSize); + int selfIndex = pointTexel.y * size + pointTexel.x; + int count = int(pointsNumber); + + // Fragments beyond the point count are unused texture pixels. + if (selfIndex >= count) { + fragColor = vec4(0.0); + return; + } + + // An absent point must neither move nor repel (its position is NaN). + vec4 selfExit = texelFetch(exitTexture, pointTexel, 0); + if (selfExit.g > 0.5) { + fragColor = vec4(0.0); + return; + } + + vec2 position = texelFetch(positionsTexture, pointTexel, 0).rg; + vec4 random = texelFetch(randomValues, pointTexel, 0); + + // Pairs are split at the grid path's near-field scale (maxStep = 2 × the + // finest cell size it would use at this point count): closer pairs + // correspond to its 3×3 near-field pass — jittered and bounded below, the + // way that pass bounds its own sum — farther pairs to its level passes, + // which it leaves unbounded. The same split keeps the dynamics continuous + // across the point-count threshold between the two paths. + vec2 nearVelocity = vec2(0.0); + vec2 farVelocity = vec2(0.0); + float nearRadius2 = maxStep * maxStep; + for (int i = 0; i < count; i += 1) { + if (i == selfIndex) continue; + ivec2 texel = ivec2(i % size, i / size); + if (texelFetch(exitTexture, texel, 0).g > 0.5) continue; + vec2 otherPosition = texelFetch(positionsTexture, texel, 0).rg; + vec2 distVector = position - otherPosition; + vec2 pairVelocity = pairwiseVelocity(position, otherPosition, random.rg); + if (dot(distVector, distVector) < nearRadius2) nearVelocity += pairVelocity; + else farVelocity += pairVelocity; + } + + // Random jitter proportional to the near velocity, to keep points from + // sticking (same as the near-field pass). + nearVelocity += nearVelocity * random.rg; + + // Bound the per-tick near kick. Exactness alone does not bound it: the + // falloff still diverges at near-zero separations, and a coincident stack + // sums n−1 same-direction random kicks into one fling. The clamp caps the + // magnitude and keeps the direction. + float speed = length(nearVelocity); + if (speed > maxStep) nearVelocity *= maxStep / speed; + + fragColor = vec4(farVelocity + nearVelocity, 0.0, 0.0); +} +`,av=`#version 300 es +precision highp float; + +// One depth-peeling pass of the near-field point-slot build. +// +// The precise grid's near field needs actual point-to-point forces (cell +// centroids alone exert a purely radial force that flattens dense hubs into +// disks and spikes). Each peeling pass selects, per finest-level cell, the +// not-yet-peeled point with the smallest per-tick random hash: the depth test +// keeps the smallest \`hashValue\` among eligible points, and eligibility excludes +// points already captured by the previous slot (hash <= previous slot's hash). +// Running K passes yields a uniform random K-subset per cell, re-randomized +// every tick via \`randomSeed\`; force-nearfield.frag turns it into an unbiased +// estimate of the cell's exact all-pairs repulsion (Monte-Carlo P3M). + +uniform sampler2D positionsTexture; +uniform sampler2D previousSlot; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform buildNearFieldSlotsUniforms { + float pointsTextureSize; + float levelGridSize; + float cellSize; + float hasPreviousSlot; + float randomSeed; +} buildNearFieldSlots; + +#define pointsTextureSize buildNearFieldSlots.pointsTextureSize +#define levelGridSize buildNearFieldSlots.levelGridSize +#define cellSize buildNearFieldSlots.cellSize +#define hasPreviousSlot buildNearFieldSlots.hasPreviousSlot +#define randomSeed buildNearFieldSlots.randomSeed +#else +uniform float pointsTextureSize; +uniform float levelGridSize; +uniform float cellSize; +uniform float hasPreviousSlot; +uniform float randomSeed; +#endif + +in vec2 pointIndices; + +out vec2 slotData; // [point index, hash] + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not be captured as neighbors — a NaN position bins to an + // undefined cell and its distance poisons the force of every point sampling + // that slot. Same guard as calculate-level.vert. (exit.G = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + slotData = vec2(-1.0, 1.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 1.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + float index = pointIndices.y * pointsTextureSize + pointIndices.x; + + // Per-tick random ordering via an integer hash (lowbias32). A fract(sin(...)) + // hash breaks down here: at large point indices GPU sin() loses precision + // (differently per vendor), producing correlated or colliding hashes — and a + // hash collision makes the peeling test below silently drop a point from the + // sample. Integer ops are exact everywhere, and both inputs are exact (the + // index is an integer-valued float; floatBitsToUint reinterprets seed bits). + uint h = uint(index) ^ floatBitsToUint(randomSeed); + h ^= h >> 16u; + h *= 0x7feb352du; + h ^= h >> 15u; + h *= 0x846ca68bu; + h ^= h >> 16u; + // Top 24 bits only, so the value is exactly representable in a float32 and + // round-trips bit-exactly through the slot texture into the next pass's + // comparison. Kept strictly inside (0, 1) so the depth range is safe. + float hashValue = (float(h >> 8u) + 0.5) / 16777216.0; + hashValue = 0.001 + hashValue * 0.998; + + // Must match the cell formula of the aggregation and force shaders exactly. + int gridSize = int(levelGridSize); + ivec2 cell = clamp(ivec2(floor(pointPosition.rg / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + if (hasPreviousSlot > 0.5) { + vec2 previous = texelFetch(previousSlot, cell, 0).rg; + // Eligible only if the previous slot captured a point with a smaller hash. + // An empty previous slot (index -1) means the cell is exhausted — otherwise + // this pass would re-capture already-peeled points and double-count them. + if (previous.x < 0.0 || hashValue <= previous.y) { + slotData = vec2(-1.0, 1.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 1.0; + return; + } + } + + slotData = vec2(index, hashValue); + vec2 ndc = 2.0 * (vec2(cell) + 0.5) / levelGridSize - 1.0; + // The depth test (less) keeps the eligible point with the smallest hash. + gl_Position = vec4(ndc, hashValue * 2.0 - 1.0, 1.0); + gl_PointSize = 1.0; +} +`,lv=`#version 300 es +precision highp float; + +in vec2 slotData; +out vec4 fragColor; + +void main() { + fragColor = vec4(slotData, 0.0, 0.0); +} +`,cv=512,vd=e=>Math.min(cv,Math.max(8,Math.pow(2,Math.ceil(Math.log2(2*Math.sqrt(e)))))),uv=e=>e<=16384?32:e<=65536?16:8,dv=4096,pi=2;class hv extends gt{constructor(){super(...arguments),this.levels=0,this.levelTargets=new Map,this.nearFieldSlots=0,this.peelTargets=[]}get usesAllPairs(){return(this.data.pointsNumber??0)<=dv}create(){var o,a;const{device:t,store:i}=this;if(!i.pointsTextureSize)return;this.usesAllPairs?(this.destroyLevelTargets(),this.levels=0):this.createLevels();const n=i.pointsTextureSize*i.pointsTextureSize,r=new Float32Array(n*4);for(let l=0;l=this.levels&&(o.fbo.destroyed||o.fbo.destroy(),o.texture.destroyed||o.texture.destroy(),this.levelTargets.delete(s));const r=this.levelTargets.get(this.levels-1);r&&this.createNearFieldSlotTargets(r)}createNearFieldSlotTargets(t){const{device:i}=this,n=uv(this.data.pointsNumber??0),r=this.peelTargets[0];if(!(r&&!r.texture.destroyed&&r.texture.width===t.gridSize&&r.texture.height===t.gridSize&&this.peelTargets.length===pi&&this.slotsArrayTexture&&!this.slotsArrayTexture.destroyed&&this.nearFieldSlots===n)){this.destroyNearFieldSlotTargets(),this.nearFieldSlots=n;for(let s=0;s"}}})),this.runCommand||(this.runCommand=new ee(t,{fs:fv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.vertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceMouseUniforms:this.uniformStore.getManagedUniformBuffer("forceMouseUniforms")},parameters:te})))}run(){const{device:t,points:i,store:n}=this;if(!i||!this.runCommand||!this.uniformStore||!i.previousPositionTexture||i.previousPositionTexture.destroyed||!i.velocityFbo||i.velocityFbo.destroyed)return;this.uniformStore.setUniforms({forceMouseUniforms:{repulsion:this.config.simulationRepulsionFromMouse,mousePos:ie(n.mousePosition,[0,0])}}),this.runCommand.setBindings({positionsTexture:i.previousPositionTexture});const r=t.beginRenderPass({framebuffer:i.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(r),r.end()}destroy(){var t,i;(t=this.runCommand)==null||t.destroy(),this.runCommand=void 0,(i=this.uniformStore)==null||i.destroy(),this.uniformStore=void 0,this.vertexCoordBuffer&&!this.vertexCoordBuffer.destroyed&&this.vertexCoordBuffer.destroy(),this.vertexCoordBuffer=void 0}}const gv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + fragColor = rgba; +}`,mv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D clusterTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform calculateCentermassUniforms { + float clustersTextureSize; +} calculateCentermass; + +#define clustersTextureSize calculateCentermass.clustersTextureSize +#else +uniform float clustersTextureSize; +#endif + +in vec2 pointIndices; + +out vec4 rgba; + +void main() { + rgba = vec4(0.0); + + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not contribute to their cluster's centroid. (exit.G = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Unclustered points ([-1, -1]) must not contribute mass to any cluster — + // a default position of (0, 0) is the framebuffer's center texel, a real + // cluster's slot, so cull them off-screen instead. + vec4 pointClusterIndices = texelFetch(clusterTexture, pointTexel, 0); + if (pointClusterIndices.x < 0.0 || pointClusterIndices.y < 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + rgba = vec4(pointPosition.xy, 1.0, 0.0); + + vec2 xy = 2.0 * (pointClusterIndices.xy + 0.5) / clustersTextureSize - 1.0; + gl_Position = vec4(xy, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,xv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D centermassTexture; +uniform sampler2D clusterTexture; +uniform sampler2D clusterPositionsTexture; +uniform sampler2D clusterForceCoefficient; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform applyForcesUniforms { + float alpha; + float clusterCoefficient; +} applyForces; + +#define alpha applyForces.alpha +#define clusterCoefficient applyForces.clusterCoefficient +#else +uniform float alpha; +uniform float clusterCoefficient; +#endif + +out vec4 fragColor; + + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + vec4 pointClusterIndices = texelFetch(clusterTexture, pointTexel, 0); + // no cluster, so no forces + if (pointClusterIndices.x >= 0.0 && pointClusterIndices.y >= 0.0) { + // clusterTexture stores whole texel coordinates, so truncating to int is exact. + ivec2 clusterTexel = ivec2(pointClusterIndices.xy); + // positioning points to custom cluster position or either to the center of mass + vec2 clusterPositions = texelFetch(clusterPositionsTexture, clusterTexel, 0).xy; + if (clusterPositions.x < 0.0 || clusterPositions.y < 0.0) { + vec4 centermassValues = texelFetch(centermassTexture, clusterTexel, 0); + clusterPositions = centermassValues.xy / centermassValues.b; + } + vec4 clusterCustomCoeff = texelFetch(clusterForceCoefficient, pointTexel, 0); + vec2 distVector = clusterPositions.xy - pointPosition.xy; + float dist = length(distVector); + if (dist > 0.0) { + float addV = alpha * dist * clusterCoefficient * clusterCustomCoeff.r; + velocity.rg += addV * normalize(distVector); + } + } + + fragColor = velocity; +}`;class Sv extends gt{constructor(){super(...arguments),this.cachedCentroidPositions=null,this.isCentroidReadbackWanted=!1}get hasPendingCentroidReadback(){var t;return((t=this.centroidReadback)==null?void 0:t.inFlight)??!1}get needsCentroidReadback(){var t;return this.isCentroidReadbackWanted&&((t=this.points)==null?void 0:t.areClusterCentroidsUpToDate)===!1}create(){var d,h,p;this.cachedCentroidPositions=null,(d=this.centroidReadback)==null||d.destroy(),this.centroidReadback=void 0;const{device:t,store:i,data:n}=this,{pointsTextureSize:r}=i;if(n.pointsNumber===void 0||!n.pointClusters&&!n.clusterPositions)return;this.clusterCount=(n.pointClusters??[]).reduce((g,x)=>x===void 0||x<0?g:Math.max(g,x),0)+1,this.clustersTextureSize=Math.ceil(Math.sqrt(this.clusterCount));const s=this.previousPointsTextureSize!==r||this.previousClustersTextureSize!==this.clustersTextureSize||this.previousClusterCount!==this.clusterCount,o=r*r*4,a=this.clustersTextureSize*this.clustersTextureSize*4,l=new Float32Array(o),c=new Float32Array(a).fill(-1),u=new Float32Array(o).fill(1);if(n.clusterPositions)for(let g=0;g 0.0) { + float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color) + + if (isDarkenGreyout > 0.0) { + finalColor = mix(finalColor, vec3(0.2), blendFactor); + } else { + finalColor = mix(finalColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + + return vec4(finalColor, finalAlpha); +} + +float squareDistance(vec2 p) { + vec2 d = abs(p) - vec2(0.8); + return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); +} + +float triangleDistance(vec2 p) { + const float k = sqrt(3.0); // ≈1.732; slope of 60° lines for an equilateral triangle + const float r = 0.9; // half the edge length; each edge is 2r + p.x = abs(p.x) - r; // fold the X axis and shift: the base corner is at the origin + p.y += 0.55; // move the base (y = -0.55 in the core) to y = 0. The centred offset is + // r/k = 0.52; 0.55 keeps the apex at 1.01 rather than 1.04 + + // Reflect across the corner's bisector: the slanted edge maps onto the x axis, + // corner at x = 0, apex at x = -2r + if (p.x + k * p.y > 0.0) + p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0; + + // Distance to the edge as the segment [-2r, 0] on the x axis + p.x -= clamp(p.x, -2.0 * r, 0.0); + + // Return signed distance: negative = inside; positive = outside + return -length(p) * sign(p.y); +} + +float diamondDistance(vec2 p) { + // aspect > 1 → taller diamond + const float aspect = 1.2; + return abs(p.x) + abs(p.y) / aspect - 0.8; +} + +float pentagonDistance(vec2 p) { + // Regular pentagon signed-distance (Inigo Quilez) + const vec3 k = vec3(0.809016994, 0.587785252, 0.726542528); // cos 36°, sin 36°, tan 36° + const float r = 0.726542528; // apothem: the flat edge is at y = r; equal to k.z by + // coincidence of the chosen size, not by construction + p.x = abs(p.x); + + // Reflect across the two tilted edges ─ only if point is outside + p -= 2.0 * min(dot(vec2(-k.x, k.y), p), 0.0) * vec2(-k.x, k.y); + p -= 2.0 * min(dot(vec2( k.x, k.y), p), 0.0) * vec2( k.x, k.y); + + // distance to the flat edge as a segment: every corner folds onto x = ±r·tan 36° + p -= vec2(clamp(p.x, -r * k.z, r * k.z), r); + + // Return signed distance (negative → inside, positive → outside) + return length(p) * sign(p.y); +} + +float hexagonDistance(vec2 p) { + const vec3 k = vec3(-0.866025404, 0.5, 0.577350269); + p = abs(p); + p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy; + p -= vec2(clamp(p.x, -k.z * 0.8, k.z * 0.8), 0.8); + return length(p) * sign(p.y); +} + +float starDistance(vec2 p) { + // 5-point star signed-distance function (adapted from Inigo Quilez) + // r – outer radius, rf – inner/outer radius ratio + const float r = 0.9; + const float rf = 0.45; + + // Pre-computed rotation vectors for the star arms (36° increments) + const vec2 k1 = vec2(0.809016994, -0.587785252); + const vec2 k2 = vec2(-k1.x, k1.y); + + // Fold the plane into a single arm sector + p.x = abs(p.x); + p -= 2.0 * max(dot(k1, p), 0.0) * k1; + p -= 2.0 * max(dot(k2, p), 0.0) * k2; + p.x = abs(p.x); + + // Translate so the top tip of the star lies on the X-axis + p.y -= r; + + // Vector describing the edge between an outer tip and its adjacent inner point + vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0); + // Project the point onto that edge and clamp the projection to the segment + float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r); + + // Return signed distance (negative => inside, positive => outside) + return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y); +} + +float crossDistance(vec2 p) { + // Signed distance function for a cross (union of two rectangles) + // Adapted from Inigo Quilez (https://iquilezles.org/) + // Each arm has half-sizes 0.3 (thickness) and 0.8 (length) + p = abs(p); + if (p.y > p.x) p = p.yx; // exploit symmetry + + vec2 q = p - vec2(0.8, 0.3); // subtract half-sizes (length, thickness) + + // Standard rectangle SDF, then take union of the two arms + return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0); +} + +float getShapeDistance(vec2 p, float shape) { + if (shape == SQUARE) return squareDistance(p); + else if (shape == TRIANGLE) return triangleDistance(p); + else if (shape == DIAMOND) return diamondDistance(p); + else if (shape == PENTAGON) return pentagonDistance(p); + else if (shape == HEXAGON) return hexagonDistance(p); + else if (shape == STAR) return starDistance(p); + else if (shape == CROSS) return crossDistance(p); + else return circleDistance(p); // Default to circle +} + +void main() { + // Discard the fragment if the point is fully transparent and has no image + if (shapeColor.a == 0.0 && imageAtlasUV.x == -1.0) { + discard; + } + + // Discard the fragment if the point has no shape and no image + if (pointShape == NONE && imageAtlasUV.x == -1.0) { + discard; + } + + // Calculate coordinates within the point + vec2 pointCoord = 2.0 * gl_PointCoord - 1.0; + + // pointCoord covers the full sprite, which is larger than the shape when the point is + // outlined, carries a bigger image, or is under a pixel. Rescale it so the shape keeps + // its intended size. + vec2 shapeCoord = pointCoord; + float shapeDiameterPx = overallSize; + if (overallSize > shapeSize && shapeSize > 0.0) { + shapeCoord = pointCoord * (overallSize / shapeSize); + shapeDiameterPx = shapeSize; + } + + vec4 finalShapeColor = vec4(0.0); + vec4 finalImageColor = vec4(0.0); + // Geometric coverage, before color alpha: what the host picking pass decides on + float shapeCoverage = 0.0; + bool imageCovered = false; + + // Ramp of EDGE_RAMP_PX device pixels centred on the shape edge. The sprite is the shape's own + // size: the outer half of the ramp is clipped only where the shape touches the sprite's sides. + // A shape under one device pixel is drawn as a one-pixel core with alpha shape² / core², the + // ink of its true area; a size of 0 has no shape. + if (pointShape != NONE && shapeSize > 0.0) { + float coreDiameterPx = max(shapeDiameterPx, 1.0); + float smallAlpha = min(1.0, (shapeDiameterPx * shapeDiameterPx) / (coreDiameterPx * coreDiameterPx)); + vec2 coreCoord = shapeCoord * (shapeDiameterPx / coreDiameterPx); // -1..1 across the core + float halfRampPx = EDGE_RAMP_PX * 0.5; + + float opacity; + if (pointShape == CIRCLE) { + // Along the radius: a ramp in r² skews coverage outward on small discs. + float rPx = length(coreCoord) * coreDiameterPx * 0.5; + opacity = 1.0 - smoothstep(coreDiameterPx * 0.5 - halfRampPx, coreDiameterPx * 0.5 + halfRampPx, rPx); + } else { + float shapeDistance = getShapeDistance(coreCoord, pointShape); + // Half a ramp in field units, via the field's gradient per pixel: exact for a field that + // is linear across the ramp, as every polygon field is at its edge. All fragments of a + // sprite share pointShape, so the derivative is taken in coherent control flow. + float shapeHalfRamp = max(halfRampPx * length(vec2(dFdx(shapeDistance), dFdy(shapeDistance))), 1e-6); + opacity = 1.0 - smoothstep(-shapeHalfRamp, shapeHalfRamp, shapeDistance); + } + shapeCoverage = opacity; + opacity *= smallAlpha * shapeColor.a; + + finalShapeColor = vec4(shapeColor.rgb, opacity); + } + + // Handle image rendering with centering logic + if (imageAtlasUV.x != -1.0) { + // Calculate image coordinates with centering + vec2 imageCoord = pointCoord; + if (overallSize > imageSizeVarying && imageSizeVarying > 0.0) { + // Image is smaller than overall size, center it + float scale = imageSizeVarying / overallSize; + imageCoord = pointCoord / scale; + + // Check if we're outside the valid image area + if (abs(imageCoord.x) > 1.0 || abs(imageCoord.y) > 1.0) { + // We're outside the image bounds, don't render the image + finalImageColor = vec4(0.0); + } else { + // Sample from texture atlas + vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5); + vec4 imageColor = texture(imageAtlasTexture, atlasUV); + finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut); + imageCovered = true; + } + } else { + // Image is same size or larger than overall size, no scaling needed + // Sample from texture atlas + vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5); + vec4 imageColor = texture(imageAtlasTexture, atlasUV); + finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut); + imageCovered = true; + } + } + + // Host picking: a fragment counts where the shape covers at least half of it (and the + // point is not fully transparent) or an image does; it carries the index and the host's + // alpha, with no blending and no ramp — the hard edge is the picked outline + if (renderMode > 2.5) { + bool covered = (shapeCoverage >= 0.5 && shapeColor.a > 0.0) || imageCovered; + if (!covered) discard; + fragColor = vec4(encodePickingColor(vPointIndex + pickingIndexOffset), pickingAlpha); + return; + } + + float finalPointAlpha = max(finalShapeColor.a, finalImageColor.a); + if (isGreyedOut > 0.0 && greyoutOpacity != -1.0) { + finalPointAlpha *= greyoutOpacity; + } else { + finalPointAlpha *= pointOpacity; + } + + // Blend image color above point color + fragColor = vec4( + mix(finalShapeColor.rgb, finalImageColor.rgb, finalImageColor.a), + finalPointAlpha + ); + + // Outline ring: band [outlineWidth × R, R], R = POINT_RING_SCALE × point radius, device px. + // Core at least a ramp wide, centred on the band, ramp centred on both edges. A ring is an + // interface mark: thinner than the ramp it is widened at full alpha, not dimmed. + // + // inner R outer R + // ────────░░┤░░████████░░├░░──────── + // fade core fade + if (isOutlined > 0.0) { + // Sized from the drawn core (a shape under a pixel is drawn as one), inside the sprite, + // which the hardware cap can clamp: the ring then tightens onto the body. + float ringOuterPx = min(POINT_RING_SCALE * max(max(shapeSize, 1.0), imageSizeVarying), overallSize - EDGE_RAMP_PX) * 0.5; + float ringInnerPx = outlineWidth * ringOuterPx; + float ringCentrePx = (ringOuterPx + ringInnerPx) * 0.5; + float ringHalfCorePx = max(ringOuterPx - ringInnerPx, EDGE_RAMP_PX) * 0.5; + float rPx = length(pointCoord) * overallSize * 0.5; + float ringAlpha = 1.0 - smoothstep(-EDGE_RAMP_PX * 0.5, EDGE_RAMP_PX * 0.5, abs(rPx - ringCentrePx) - ringHalfCorePx); + + // Grey out the ring color when the point is greyed + vec3 ringColor = outlineColor.rgb; + if (isGreyedOut > 0.0) { + float blendFactor = 0.65; + if (isDarkenGreyout > 0.0) { + ringColor = mix(ringColor, vec3(0.2), blendFactor); + } else { + ringColor = mix(ringColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + + float ringOpacity = ringAlpha * outlineColor.a; + // Source-over of the ring onto the fragment. A plain mix would tint the ring with a + // transparent body's colour, and the blend would then apply the ring's alpha twice. + float outAlpha = ringOpacity + fragColor.a * (1.0 - ringOpacity); + vec3 outRgb = outAlpha > 0.0 + ? (ringColor * ringOpacity + fragColor.rgb * fragColor.a * (1.0 - ringOpacity)) / outAlpha + : fragColor.rgb; + fragColor = vec4(outRgb, outAlpha); + } + + // Occlusion culling: split every fragment between the opaque core pass + // (depth-writing, unblended) and the blended fringe pass. The same + // final-alpha rule runs in both passes so each fragment renders exactly once. + if (renderMode > 1.5) { + if (fragColor.a >= OPAQUE_ALPHA_THRESHOLD) discard; // already drawn by core pass + } else if (renderMode > 0.5) { + if (fragColor.a < OPAQUE_ALPHA_THRESHOLD) discard; // left for fringe pass + } +} +`,qo=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 pointIndices; +in float sourceSize; +in float targetSize; +in vec4 sourceColor; +in vec4 targetColor; +in float shape; +in float imageIndex; +in float imageSize; + +uniform sampler2D positionsTexture; +uniform sampler2D pointStatus; +uniform sampler2D exitTexture; +uniform sampler2D imageAtlasCoords; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawVertexUniforms { + float ratio; + mat4 transformationMatrix; + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + vec4 greyoutColor; + vec4 backgroundColor; + float scalePointsOnZoom; + float maxPointSize; + float isDarkenGreyout; + float skipHighlighted; + float skipGreyed; + float hasImages; + float imageCount; + float imageAtlasCoordsTextureSize; + float transitionProgress; + float animateColors; + float animateSizes; + float animatePositions; + vec4 pointDefaultColor; + float pointDefaultSize; + float pointsNumber; +} drawVertex; + +#define ratio drawVertex.ratio +#define transformationMatrix drawVertex.transformationMatrix +#define pointsTextureSize drawVertex.pointsTextureSize +#define sizeScale drawVertex.sizeScale +#define spaceSize drawVertex.spaceSize +#define screenSize drawVertex.screenSize +#define greyoutColor drawVertex.greyoutColor +#define backgroundColor drawVertex.backgroundColor +#define scalePointsOnZoom drawVertex.scalePointsOnZoom +#define maxPointSize drawVertex.maxPointSize +#define isDarkenGreyout drawVertex.isDarkenGreyout +#define skipHighlighted drawVertex.skipHighlighted +#define skipGreyed drawVertex.skipGreyed +#define hasImages drawVertex.hasImages +#define imageCount drawVertex.imageCount +#define imageAtlasCoordsTextureSize drawVertex.imageAtlasCoordsTextureSize +#define transitionProgress drawVertex.transitionProgress +#define animateColors drawVertex.animateColors +#define animateSizes drawVertex.animateSizes +#define animatePositions drawVertex.animatePositions +#define pointDefaultColor drawVertex.pointDefaultColor +#define pointDefaultSize drawVertex.pointDefaultSize +#define pointsNumber drawVertex.pointsNumber +#else +uniform float ratio; +uniform mat3 transformationMatrix; +uniform float pointsTextureSize; +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform vec4 greyoutColor; +uniform vec4 backgroundColor; +uniform float scalePointsOnZoom; +uniform float maxPointSize; +uniform float isDarkenGreyout; +uniform float skipHighlighted; +uniform float skipGreyed; +uniform float hasImages; +uniform float imageCount; +uniform float imageAtlasCoordsTextureSize; +uniform float transitionProgress; +uniform float animateColors; +uniform float animateSizes; +uniform float animatePositions; +uniform vec4 pointDefaultColor; +uniform float pointDefaultSize; +uniform float pointsNumber; +#endif + +out float pointShape; +out float isGreyedOut; +out float isOutlined; +out vec4 shapeColor; +out vec4 imageAtlasUV; +out float shapeSize; +out float imageSizeVarying; +out float overallSize; +// The point's index, for the host picking pass +flat out float vPointIndex; + +// The size rule is the shared pointSize module, so drawing, picking and selection agree on it. +float calculatePointSize(float size) { + return pointSizePx(size, ratio, transformationMatrix[0][0], scalePointsOnZoom, maxPointSize); +} + +// Read-time resolution of NaN channels — input arrays are used verbatim and never +// edited, so "use the default" stays encoded as NaN all the way to the GPU. A NaN +// resolves to the config default blended toward the exit default along the animated +// exit ramp (0 = present, 1 = gone), so the enter/exit fade of default-valued +// channels drives itself — no size/color transition needed for a removal. Explicit +// (real) values pass through. EXIT_DEFAULT_* are #defines injected from variables.ts, +// shared with the CPU resolvers (GraphData.getResolvedPoint*). The ramp and the size +// rule are the shared exitRamp module (exit-ramp.glsl), which the hover/focus ring +// draws by too; only the sprite resolves colors. +vec4 resolveColor(vec4 color, float exit) { + vec4 defaultColor = mix(pointDefaultColor, vec4(EXIT_DEFAULT_COLOR_CHANNEL), exit); + return mix(color, defaultColor, isnan(color)); +} + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Read point status texture: R = greyout, G = outlined + vec4 status = texelFetch(pointStatus, pointTexel, 0); + isGreyedOut = status.r; + isOutlined = status.g; + float isHighlighted = (status.r == 0.0) ? 1.0 : 0.0; + + // Discard point based on rendering mode + if (skipHighlighted > 0.0 && isHighlighted > 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + if (skipGreyed > 0.0 && isHighlighted <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Exit ramp (exit-ramp.glsl): 0 = present, 1 = gone. The caller drives the visual + // fade via setPointSizes/setPointColors; here we only remove the point once it is + // fully gone. + float exit = exitRamp(texelFetch(exitTexture, pointTexel, 0), animatePositions, transitionProgress); + if (exit >= 1.0) { + // Fully gone — skip. Also avoids using a NaN position on the snapped path. + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Position + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 point = pointPosition.rg; + + // Transform point position to normalized device coordinates + // Convert from space coordinates [0, spaceSize] to normalized [-1, 1] + vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0; + + // Apply aspect ratio correction - this is needed to map the square space to the rectangular screen + // The transformation matrix handles zoom/pan, but we need this to handle aspect ratio + normalizedPosition *= spaceSize / screenSize; + + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1); + #else + vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1); + #endif + // Depth encodes stacking order: higher point index = drawn on top = nearer + // (smaller z). Harmless when depth testing is off (depthCompare 'always'). + float linearIndex = pointIndices.y * pointsTextureSize + pointIndices.x; + vPointIndex = linearIndex; + float depthZ = 1.0 - 2.0 * (linearIndex + 0.5) / max(pointsNumber, 1.0); + gl_Position = vec4(finalPosition.rg, depthZ, 1.0); + + // Resolve NaN channels against the animated exit ramp before mixing — default + // sizes/colors of an entering or leaving point fade with the ramp regardless of + // whether a size/color transition is active. + float pointSize = transitionedSize(sourceSize, targetSize, animateSizes, transitionProgress, exit, pointDefaultSize); + vec4 pointColor = animateColors > 0.0 + ? mix(resolveColor(sourceColor, exit), resolveColor(targetColor, exit), transitionProgress) + : resolveColor(targetColor, exit); + + + // Calculate sizes for shape and image. A point without an image has no image + // size: the attribute still holds a value (a copy of the target point size when + // none was given), and letting it into the sprite footprint would hold the + // outline ring at the target while the shape is still transitioning. + bool hasImage = hasImages > 0.0 && imageIndex >= 0.0 && imageIndex < imageCount; + float shapeSizeValue = calculatePointSize(pointSize * sizeScale); + float imageSizeValue = hasImage ? calculatePointSize(imageSize * sizeScale) : 0.0; + + // A size of 0 draws nothing; the sprite below is never smaller than a pixel. + if (max(shapeSizeValue, imageSizeValue) <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Use the larger of the shape, image, and 1-pixel minimum. The sprite is the shape's own size: + // the ramp stays centred on the edge, and its outer half is clipped where the shape meets the + // sprite's sides. + float overallSizeValue = max(max(shapeSizeValue, 1.0), imageSizeValue); + + // Outlined: scale the drawn core (a shape is never under a pixel) to the ring size, then add + // ramp room on both sides. + if (isOutlined > 0.0) { + overallSizeValue = POINT_RING_SCALE * max(max(shapeSizeValue, 1.0), imageSizeValue) + 2.0 * EDGE_RAMP_PX; + } + // Clamp to the hardware limit; the fragment shader preserves the shape size. + overallSizeValue = min(overallSizeValue, maxPointSize * ratio); + + gl_PointSize = overallSizeValue; + + // Pass size information to fragment shader + shapeSize = shapeSizeValue; + imageSizeVarying = imageSizeValue; + overallSize = overallSizeValue; + + shapeColor = pointColor; + pointShape = shape; + + // Adjust color of greyed-out points + if (isGreyedOut > 0.0) { + if (greyoutColor[0] != -1.0) { + shapeColor = greyoutColor; + } else { + // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout + float blendFactor = 0.65; + + if (isDarkenGreyout > 0.0) { + shapeColor.rgb = mix(shapeColor.rgb, vec3(0.2), blendFactor); + } else { + shapeColor.rgb = mix(shapeColor.rgb, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + } + + if (!hasImage) { + imageAtlasUV = vec4(-1.0); + } else { + int atlasTexSize = int(imageAtlasCoordsTextureSize); + int atlasCoordIndex = int(imageIndex); + ivec2 atlasTexel = ivec2(atlasCoordIndex % atlasTexSize, atlasCoordIndex / atlasTexSize); + vec4 atlasCoords = texelFetch(imageAtlasCoords, atlasTexel, 0); + imageAtlasUV = atlasCoords; + } +} +`,yv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D pointSize; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform findPointsInRectUniforms { + float sizeScale; + float spaceSize; + vec2 screenSize; + float ratio; + mat4 transformationMatrix; + vec2 rect0; + vec2 rect1; + float scalePointsOnZoom; + float maxPointSize; +} findPointsInRect; + +#define sizeScale findPointsInRect.sizeScale +#define spaceSize findPointsInRect.spaceSize +#define screenSize findPointsInRect.screenSize +#define ratio findPointsInRect.ratio +#define transformationMatrix findPointsInRect.transformationMatrix +#define rect0 findPointsInRect.rect0 +#define rect1 findPointsInRect.rect1 +#define scalePointsOnZoom findPointsInRect.scalePointsOnZoom +#define maxPointSize findPointsInRect.maxPointSize +#else +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform float ratio; +uniform mat3 transformationMatrix; +uniform vec2 rect0; +uniform vec2 rect1; +uniform float scalePointsOnZoom; +uniform float maxPointSize; +#endif + +out vec4 fragColor; + +// The drawn size (draw-points.vert), so the selection footprint is the rendered point: a shape +// under a device pixel is drawn as one. In CSS px, the units of the rectangle and screenSize. +float pointSizeF(float size) { + return max(pointSizePx(size, ratio, transformationMatrix[0][0], scalePointsOnZoom, maxPointSize), 1.0) / ratio; +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + // Skip absent (faded-out) points — never select a removed point. exit.G = absent. + if (texelFetch(exitTexture, pointTexel, 0).g > 0.5) { + fragColor = vec4(0.0); + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + // Convert mat4 to mat3 for vec3 multiplication + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + vec4 pSize = texelFetch(pointSize, pointTexel, 0); + float size = pSize.r * sizeScale; + // A size of 0 draws nothing (draw-points.vert), so it is not selectable either. + if (size <= 0.0) { + fragColor = vec4(0.0); + return; + } + + float left = 2.0 * (rect0.x - 0.5 * pointSizeF(size)) / screenSize.x - 1.0; + float right = 2.0 * (rect1.x + 0.5 * pointSizeF(size)) / screenSize.x - 1.0; + float top = 2.0 * (rect0.y - 0.5 * pointSizeF(size)) / screenSize.y - 1.0; + float bottom = 2.0 * (rect1.y + 0.5 * pointSizeF(size)) / screenSize.y - 1.0; + + fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g); + if (final.x >= left && final.x <= right && final.y >= top && final.y <= bottom) { + fragColor.r = 1.0; + } +} + +`,_v=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D polygonPathTexture; // Texture containing polygon path points +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform findPointsInPolygonUniforms { + float spaceSize; + vec2 screenSize; + mat4 transformationMatrix; + float polygonPathLength; +} findPointsInPolygon; + +#define spaceSize findPointsInPolygon.spaceSize +#define screenSize findPointsInPolygon.screenSize +#define transformationMatrix findPointsInPolygon.transformationMatrix +#define polygonPathLength int(findPointsInPolygon.polygonPathLength) +#else +uniform int polygonPathLength; +uniform float spaceSize; +uniform vec2 screenSize; +uniform mat3 transformationMatrix; +#endif + +out vec4 fragColor; + +// Get a point from the polygon path texture at a specific index +vec2 getPolygonPoint(sampler2D pathTexture, int index, int pathLength) { + if (index >= pathLength) return vec2(0.0); + + // The path is written row-major into a square texture. Ask the texture how wide it + // is rather than re-deriving ceil(sqrt(pathLength)) — that duplicates the formula + // the allocation used, and a local named textureSize would shadow this builtin. + int width = textureSize(pathTexture, 0).x; + + vec4 pathData = texelFetch(pathTexture, ivec2(index % width, index / width), 0); + + return pathData.xy; +} + +// Point-in-polygon algorithm using ray casting +bool pointInPolygon(vec2 point, sampler2D pathTexture, int pathLength) { + bool inside = false; + + for (int i = 0; i < 2048; i++) { + if (i >= pathLength) break; + + int j = (i + 1) % pathLength; + + vec2 pi = getPolygonPoint(pathTexture, i, pathLength); + vec2 pj = getPolygonPoint(pathTexture, j, pathLength); + + if (((pi.y > point.y) != (pj.y > point.y)) && + (point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x)) { + inside = !inside; + } + } + + return inside; +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + // Skip absent (faded-out) points — never select a removed point. exit.G = absent. + if (texelFetch(exitTexture, pointTexel, 0).g > 0.5) { + fragColor = vec4(0.0); + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + // Convert mat4 to mat3 for vec3 multiplication + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + // Convert to screen coordinates for polygon check + vec2 screenPos = (final.xy + 1.0) * screenSize / 2.0; + + fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g); + + // Check if point center is inside the polygon + if (pointInPolygon(screenPos, polygonPathTexture, polygonPathLength)) { + fragColor.r = 1.0; + } +} `,bv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawHighlightedUniforms { + float sourceSize; + float targetSize; + float imageSize; + mat4 transformationMatrix; + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + float scalePointsOnZoom; + float pointIndex; + float maxPointSize; + vec4 color; + float universalPointOpacity; + float greyoutOpacity; + float isDarkenGreyout; + vec4 backgroundColor; + vec4 greyoutColor; + float animatePositions; + float transitionProgress; + float animateSizes; + float pointDefaultSize; + float width; + float pixelRatio; +} drawHighlighted; + +#define width drawHighlighted.width +#else +uniform float width; +uniform float pixelRatio; +#endif + +in vec2 vertexPosition; +in float pointOpacity; +in vec3 rgbColor; +flat in float ringRadiusPx; +flat in float quadHalfPx; + +out vec4 fragColor; + +// Ring band [sqrt(width) × R, R], R the outer radius in device px (\`width\` is the inner +// edge as a squared radius). Core at least EDGE_RAMP_PX wide, centred on the band, ramp +// centred on both edges. A ring is an interface mark: thinner than the ramp it is widened +// at full alpha, not dimmed. +void main () { + float rPx = length(vertexPosition) * quadHalfPx; + float innerPx = sqrt(width) * ringRadiusPx; + float centrePx = (ringRadiusPx + innerPx) * 0.5; + float halfCorePx = max(ringRadiusPx - innerPx, EDGE_RAMP_PX) * 0.5; + float ring = 1.0 - smoothstep(-EDGE_RAMP_PX * 0.5, EDGE_RAMP_PX * 0.5, abs(rPx - centrePx) - halfCorePx); + fragColor = vec4(rgbColor, ring * pointOpacity); +}`,Tv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 vertexCoord; + +uniform sampler2D positionsTexture; +uniform sampler2D pointStatus; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawHighlightedUniforms { + float sourceSize; + float targetSize; + float imageSize; + mat4 transformationMatrix; + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + float scalePointsOnZoom; + float pointIndex; + float maxPointSize; + vec4 color; + float universalPointOpacity; + float greyoutOpacity; + float isDarkenGreyout; + vec4 backgroundColor; + vec4 greyoutColor; + float animatePositions; + float transitionProgress; + float animateSizes; + float pointDefaultSize; + float width; + float pixelRatio; +} drawHighlighted; + +#define sourceSize drawHighlighted.sourceSize +#define targetSize drawHighlighted.targetSize +#define imageSize drawHighlighted.imageSize +#define pixelRatio drawHighlighted.pixelRatio +#define transformationMatrix drawHighlighted.transformationMatrix +#define pointsTextureSize drawHighlighted.pointsTextureSize +#define sizeScale drawHighlighted.sizeScale +#define spaceSize drawHighlighted.spaceSize +#define screenSize drawHighlighted.screenSize +#define scalePointsOnZoom drawHighlighted.scalePointsOnZoom +#define pointIndex drawHighlighted.pointIndex +#define maxPointSize drawHighlighted.maxPointSize +#define color drawHighlighted.color +#define universalPointOpacity drawHighlighted.universalPointOpacity +#define greyoutOpacity drawHighlighted.greyoutOpacity +#define isDarkenGreyout drawHighlighted.isDarkenGreyout +#define backgroundColor drawHighlighted.backgroundColor +#define greyoutColor drawHighlighted.greyoutColor +#define animatePositions drawHighlighted.animatePositions +#define transitionProgress drawHighlighted.transitionProgress +#define animateSizes drawHighlighted.animateSizes +#define pointDefaultSize drawHighlighted.pointDefaultSize +#else +uniform float sourceSize; +uniform float targetSize; +uniform float imageSize; +uniform mat3 transformationMatrix; +uniform float pointsTextureSize; +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform float scalePointsOnZoom; +uniform float pointIndex; +uniform float maxPointSize; +uniform vec4 color; +uniform float universalPointOpacity; +uniform float greyoutOpacity; +uniform float isDarkenGreyout; +uniform vec4 backgroundColor; +uniform vec4 greyoutColor; +uniform float animatePositions; +uniform float transitionProgress; +uniform float animateSizes; +uniform float pointDefaultSize; +uniform float width; +uniform float pixelRatio; +#endif +out vec2 vertexPosition; +out float pointOpacity; +out vec3 rgbColor; +// Ring outer radius and quad half-size, device px: the ring plus a full ramp per side. +flat out float ringRadiusPx; +flat out float quadHalfPx; + +// The drawn size (draw-points.vert), so the ring follows it. The sizes are uniforms here. +float calculatePointSize(float pointSize) { + return pointSizePx(pointSize, pixelRatio, transformationMatrix[0][0], scalePointsOnZoom, maxPointSize); +} + +void main () { + vertexPosition = vertexCoord; + + int pointTexSize = int(pointsTextureSize); + int pointLinearIndex = int(pointIndex); + // Integer % and / are undefined on a negative or zero operand, and pointIndex + // defaults to -1 (no point highlighted). Nothing to draw in that case anyway. + if (pointLinearIndex < 0 || pointTexSize <= 0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + ivec2 pointTexel = ivec2(pointLinearIndex % pointTexSize, pointLinearIndex / pointTexSize); + + // Exit ramp (exit-ramp.glsl), the sprite's: drop the ring only once the point is fully + // gone, so it stays on the body while that fades out or in. + float exit = exitRamp(texelFetch(exitTexture, pointTexel, 0), animatePositions, transitionProgress); + if (exit >= 1.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + + rgbColor = color.rgb; + pointOpacity = color.a * universalPointOpacity; + vec4 greyoutStatus = texelFetch(pointStatus, pointTexel, 0); + if (greyoutStatus.r > 0.0) { + if (greyoutColor[0] != -1.0) { + rgbColor = greyoutColor.rgb; + pointOpacity = greyoutColor.a; + } else { + // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout + float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color) + + if (isDarkenGreyout > 0.0) { + // Darken the color + rgbColor = mix(rgbColor, vec3(0.2), blendFactor); + } else { + // Lighten the color + rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + + if (greyoutOpacity != -1.0) { + pointOpacity *= greyoutOpacity; + } + } + + // The sprite's footprint this frame: its size by the shared rule (exit-ramp.glsl), and + // the image size (0 for a point without an image) when larger. + float pointSize = transitionedSize(sourceSize, targetSize, animateSizes, transitionProgress, exit, pointDefaultSize); + float footprint = max(calculatePointSize(pointSize * sizeScale), calculatePointSize(imageSize * sizeScale)); + + // A size of 0 draws nothing (draw-points.vert culls the sprite), so it has no ring; the + // quad below is never narrower than the ramp. + if (footprint <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Ring radius from the drawn core, device px: a shape under a device pixel is drawn as one. + ringRadiusPx = max(footprint, 1.0) * POINT_RING_SCALE * 0.5; + quadHalfPx = ringRadiusPx + EDGE_RAMP_PX; + float radius = quadHalfPx / pixelRatio / transformationMatrix[0][0]; + + // Calculate point position in screen space + vec2 a = pointPosition.xy; + vec2 b = pointPosition.xy + vec2(0.0, radius); + vec2 xBasis = b - a; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + vec2 pointPositionInScreenSpace = a + xBasis * vertexCoord.x + yBasis * radius * vertexCoord.y; + + // Transform point position to normalized device coordinates + vec2 p = 2.0 * pointPositionInScreenSpace / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + gl_Position = vec4(final.rg, 0, 1); +}`,vv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + // Circular sprite: hover is radius-based, like the rendered point shape. + vec2 fromCenter = 2.0 * gl_PointCoord - 1.0; + if (dot(fromCenter, fromCenter) > 1.0) discard; + fragColor = rgba; +} +`,Pv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +// Fills the screen-space picking buffer: every point rasterizes its sprite at +// its projected screen position, carrying [index, x, y] to the fragment shader. +// Hover detection then only reads a small window of this buffer under the +// cursor — it never has to touch the point set again until the scene changes +// (see Points.updatePickingBuffer / Graph.findHoveredItem). +// +// The two-pass highlight priority mirrors the draw order: greyed first, then +// highlighted (top-most wins), since later points overwrite earlier ones with +// the depth test off. + +in vec2 pointIndices; +in float size; +in float imageSize; +in float imageIndex; + +uniform sampler2D positionsTexture; +uniform sampler2D pointStatus; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform fillPickingBufferUniforms { + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + float ratio; + float pickingPixelRatio; + mat4 transformationMatrix; + float scalePointsOnZoom; + float maxPointSize; + float skipHighlighted; + float skipGreyed; + float pointDefaultSize; + float hasImages; + float imageCount; +} fillPickingBuffer; + +#define pointsTextureSize fillPickingBuffer.pointsTextureSize +#define sizeScale fillPickingBuffer.sizeScale +#define spaceSize fillPickingBuffer.spaceSize +#define screenSize fillPickingBuffer.screenSize +#define ratio fillPickingBuffer.ratio +#define pickingPixelRatio fillPickingBuffer.pickingPixelRatio +#define transformationMatrix fillPickingBuffer.transformationMatrix +#define scalePointsOnZoom fillPickingBuffer.scalePointsOnZoom +#define maxPointSize fillPickingBuffer.maxPointSize +#define skipHighlighted fillPickingBuffer.skipHighlighted +#define skipGreyed fillPickingBuffer.skipGreyed +#define pointDefaultSize fillPickingBuffer.pointDefaultSize +#define hasImages fillPickingBuffer.hasImages +#define imageCount fillPickingBuffer.imageCount +#else +uniform float pointsTextureSize; +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform float ratio; +uniform float pickingPixelRatio; +uniform mat3 transformationMatrix; +uniform float scalePointsOnZoom; +uniform float maxPointSize; +uniform float skipHighlighted; +uniform float skipGreyed; +uniform float pointDefaultSize; +uniform float hasImages; +uniform float imageCount; +#endif + +out vec4 rgba; + +// Keep tiny points pickable: below this sprite footprint (in picking-buffer +// pixels) a point could fall between the buffer's texels. +const float minPickingSize = 2.0; + +// The drawn size (draw-points.vert), so the pickable footprint is the rendered point. +float calculatePointSize(float size, float pxPerUnit) { + return pointSizePx(size, ratio, pxPerUnit, scalePointsOnZoom, maxPointSize); +} + +void main() { + // Fully clipped: a skipped point must not rasterize anywhere in the buffer. + rgba = vec4(-1.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 1.0; + + ivec2 pointTexel = ivec2(pointIndices); + + // Skip absent (faded-out) points so hover never lands on a removed one. Their + // size/position may still look hittable mid-fade (only alpha faded), so the exit + // status is the reliable signal. exit.G = current absence. + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) return; + + vec4 greyoutStatus = texelFetch(pointStatus, pointTexel, 0); + float isHighlighted = (greyoutStatus.r == 0.0) ? 1.0 : 0.0; + + if (skipHighlighted > 0.0 && isHighlighted > 0.0) return; + if (skipGreyed > 0.0 && isHighlighted <= 0.0) return; + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 point = pointPosition.rg; + + vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0; + normalizedPosition *= spaceSize / screenSize; + + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1); + #else + vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1); + #endif + float pxPerUnit = transformationMatrix[0][0]; + vec2 ndc = finalPosition.xy; + + // Resolve a NaN size at read time. The absent-point guard above already returned, + // so a NaN here means "use the config default". + float resolvedSize = isnan(size) ? pointDefaultSize : size; + + // Same footprint as draw-points.vert: the image size counts only for a point + // that draws an image. + bool hasImage = hasImages > 0.0 && imageIndex >= 0.0 && imageIndex < imageCount; + float shapeSizeValue = calculatePointSize(resolvedSize * sizeScale, pxPerUnit); + float imageSizeValue = hasImage ? calculatePointSize(imageSize * sizeScale, pxPerUnit) : 0.0; + // A size of 0 draws nothing (draw-points.vert), so it is not hoverable either. + if (max(shapeSizeValue, imageSizeValue) <= 0.0) return; + + // Device px → CSS px → picking-buffer px (the buffer is smaller than the screen) + float spriteSize = max(shapeSizeValue, imageSizeValue) / ratio * pickingPixelRatio; + + float index = pointIndices.g * pointsTextureSize + pointIndices.r; + rgba = vec4(index, pointPosition.rg, 0.0); + gl_PointSize = max(spriteSize, minPickingSize); + // 2D: later points overwrite earlier ones (depth test off), matching draw order. + gl_Position = vec4(ndc, 0.0, 1.0); +} +`,Pd=`// A point's size in device pixels: the size (CSS px) by the pixel ratio and the zoom — 1:1 with +// scalePointsOnZoom, otherwise held near constant — capped at the hardware sprite limit. +// pxPerUnit is the zoom scale. Module code precedes each shader's own uniforms, so they come in +// as parameters. +float pointSizePx(float size, float ratio, float pxPerUnit, float scalePointsOnZoom, float maxPointSize) { + float zoom = scalePointsOnZoom > 0.0 ? pxPerUnit : min(5.0, max(1.0, pxPerUnit * 0.01)); + return min(size * ratio * zoom, maxPointSize * ratio); +} +`,gi={name:"pointSize",vs:Pd,fs:Pd},_r={name:"exitRamp",vs:`// Shared by draw-points.vert and draw-highlighted.vert, so the sprite and its hover/focus ring +// fade and mix sizes by one rule. Module code precedes each shader's own uniforms, so they come +// in as parameters; EXIT_DEFAULT_SIZE is a #define injected from variables.ts. + +// How gone a point is, 0 = present, 1 = gone, from its exit-texture texel (R = previous absence, +// G = current absence). During a position transition the enter/exit fade blends R→G; otherwise +// the settled G, so an unrelated color or size transition cannot replay the fade. +float exitRamp(vec4 exitStatus, float animatePositions, float transitionProgress) { + return animatePositions > 0.0 ? mix(exitStatus.r, exitStatus.g, transitionProgress) : exitStatus.g; +} + +// A NaN size means "use the default": the config default blended toward the exit default along +// the ramp, so a default-sized point grows in and shrinks out with its fade. Explicit values +// pass through. +float resolveSize(float size, float exit, float pointDefaultSize) { + return isnan(size) ? mix(pointDefaultSize, EXIT_DEFAULT_SIZE, exit) : size; +} + +// The point's size this frame: the source→target mix by progress during a size transition, +// else the target, each resolved along the exit ramp. +float transitionedSize(float sourceSize, float targetSize, float animateSizes, float transitionProgress, float exit, float pointDefaultSize) { + return animateSizes > 0.0 + ? mix(resolveSize(sourceSize, exit, pointDefaultSize), resolveSize(targetSize, exit, pointDefaultSize), transitionProgress) + : resolveSize(targetSize, exit, pointDefaultSize); +} +`},Cv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + fragColor = rgba; +}`,Av=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 pointIndices; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform fillSampledPointsUniforms { + float pointsTextureSize; + mat4 transformationMatrix; + float spaceSize; + vec2 screenSize; +} fillSampledPoints; + +#define pointsTextureSize fillSampledPoints.pointsTextureSize +#define transformationMatrix fillSampledPoints.transformationMatrix +#define spaceSize fillSampledPoints.spaceSize +#define screenSize fillSampledPoints.screenSize +#else +uniform float pointsTextureSize; +uniform float spaceSize; +uniform vec2 screenSize; +uniform mat3 transformationMatrix; +#endif + +out vec4 rgba; + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Keep absent (faded-out) points out of the sample. exit.G = current absence. + if (texelFetch(exitTexture, pointTexel, 0).g > 0.5) { + rgba = vec4(0.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + // Convert mat4 to mat3 for vec3 multiplication + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + vec2 pointScreenPosition = (final.xy + 1.0) * screenSize / 2.0; + float index = pointIndices.g * pointsTextureSize + pointIndices.r; + rgba = vec4(index, 1.0, pointPosition.xy); + float i = (pointScreenPosition.x + 0.5) / screenSize.x; + float j = (pointScreenPosition.y + 0.5) / screenSize.y; + gl_Position = vec4(2.0 * vec2(i, j) - 1.0, 0.0, 1.0); + + gl_PointSize = 1.0; +}`,Rv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D velocity; +uniform sampler2D pinnedStatusTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform updatePositionUniforms { + float friction; + float spaceSize; +} updatePosition; + +#define friction updatePosition.friction +#define spaceSize updatePosition.spaceSize +#else +uniform float friction; +uniform float spaceSize; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 pointVelocity = texelFetch(velocity, pointTexel, 0); + + // Check if point is pinned + // pinnedStatusTexture has the same size and layout as positionsTexture + // Each pixel corresponds to a point: red channel > 0.5 means the point is pinned + vec4 pinnedStatus = texelFetch(pinnedStatusTexture, pointTexel, 0); + + // If pinned, don't update position + if (pinnedStatus.r > 0.5) { + fragColor = pointPosition; + return; + } + + // If absent (current absence = exit.G), leave it untouched — don't integrate or + // clamp it (clamping NaN is undefined and could resurrect the point at (0,0)). + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + fragColor = pointPosition; + return; + } + + // Friction + pointVelocity.rg *= friction; + + pointPosition.rg += pointVelocity.rg; + + pointPosition.r = clamp(pointPosition.r, 0.0, spaceSize); + pointPosition.g = clamp(pointPosition.g, 0.0, spaceSize); + + fragColor = pointPosition; +}`,wv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D sourceTexture; +uniform sampler2D targetTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform interpolatePositionUniforms { + float progress; +} interpolatePosition; + +#define progress interpolatePosition.progress +#else +uniform float progress; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 source = texelFetch(sourceTexture, pointTexel, 0); + vec4 target = texelFetch(targetTexture, pointTexel, 0); + // NaN means absent (ingest normalizes half-NaN to full-NaN, so checking one + // channel suffices). Hold the real side so the point stays put while it fades, + // never interpolating to/from NaN: + // · exiting (target NaN): freeze at source. + // · entering (source NaN): appear at target (no slide in from NaN). + vec2 src = isnan(source.r) ? target.rg : source.rg; + vec2 tgt = isnan(target.r) ? src : target.rg; + vec2 position = mix(src, tgt, progress); + fragColor = vec4(position, source.b, 1.0); +} +`,Ev=`#version 300 es +#ifdef GL_ES +precision highp float; +// Fragment shaders default int to mediump, guaranteed only to 32767 — +// point indices go far higher. +precision highp int; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D trackedIndices; + +out vec4 fragColor; + +void main() { + ivec2 trackedTexel = ivec2(gl_FragCoord.xy); + + // The table holds raw point indices (-1 = unused slot). The texel is derived + // here, from the width the positions texture has right now — the grid relayouts + // when the point count changes, so a texel computed at bake time would keep + // addressing the old layout. textureSize() is valid here because this shader + // samples positionsTexture itself. + float index = texelFetch(trackedIndices, trackedTexel, 0).r; + if (index < 0.0) discard; + + int i = int(index); + int w = textureSize(positionsTexture, 0).x; + // An index past the point count fetches out of range and yields zeros; the + // CPU readback owns range validation and drops such entries. + vec4 pointPosition = texelFetch(positionsTexture, ivec2(i % w, i / w), 0); + + fragColor = vec4(pointPosition.rg, 1.0, 1.0); +} +`,Iv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform dragPointUniforms { + vec2 mousePos; + float index; +} dragPoint; + +#define mousePos dragPoint.mousePos +#define index dragPoint.index +#else +uniform vec2 mousePos; +uniform float index; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + + // Check if a point is being dragged + if (index >= 0.0 && index == pointPosition.b) { + pointPosition.rg = mousePos.rg; + } + + fragColor = pointPosition; +}`;function kv(e,t=16384){if(!(e!=null&&e.length))return null;let i=0;for(const c of e){const u=Math.max(c.width,c.height);u>i&&(i=u)}if(i===0)return console.warn("Invalid image dimensions: all images have zero width or height"),null;const n=i,r=Math.ceil(Math.sqrt(e.length));let s=r*i,o=1;s>t&&(o=t/s,i=Math.max(1,Math.floor(i*o)),s=Math.max(1,Math.floor(s*o)),console.warn(`🖼️ Atlas scaling required: Original size ${(n*r).toLocaleString()}px exceeds WebGL limit ${t.toLocaleString()}px. Scaling down to ${s.toLocaleString()}px (${Math.round(o*100)}% of original quality)`));const a=new Uint8Array(s*s*4).fill(0),l=new Float32Array(r*r*4).fill(-1);for(const[c,u]of e.entries()){const d=u.width,h=u.height;if(d===0||h===0)continue;const p=Math.min(1,i/Math.max(d,h)),g=Math.floor(d*p),x=Math.floor(h*p),T=Math.floor(c/r),P=c%r*i,I=T*i;l[c*4]=P/s,l[c*4+1]=I/s,l[c*4+2]=(P+g)/s,l[c*4+3]=(I+x)/s;for(let y=0;y0&&!!this.currentPositionTexture,h=Dv(n.pointPositions,o,c);let p;if(d&&(this.createTransitionResources(),this.sourcePositionTexture&&this.targetPositionTexture)){if(u){const P=this.currentPositionTexture;if(P&&!P.destroyed){const I=this.device.createCommandEncoder();I.copyTextureToTexture({sourceTexture:P,destinationTexture:this.sourcePositionTexture,width:o,height:o}),this.device.submit(I.finish())}}else if(this.currentPositionFbo){const P=we(t,this.currentPositionFbo);p=Fv(P,h,Math.min(l,c),c,o),this.writePositionTexture(this.sourcePositionTexture,p,o)}else this.writePositionTexture(this.sourcePositionTexture,h,o);this.writePositionTexture(this.targetPositionTexture,h,o)}this.ensurePositionTextures(o),d?p&&(this.writePositionTexture(this.currentPositionTexture,p,o),this.writePositionTexture(this.previousPositionTexture,p,o)):(this.writePositionTexture(this.currentPositionTexture,h,o),this.writePositionTexture(this.previousPositionTexture,h,o)),this.areClusterCentroidsUpToDate=!1,this.markPositionsChanged(),this.config.enableSimulation&&this.ensureSimulationResources(),!this.searchTexture||this.searchTexture.width!==o||this.searchTexture.height!==o?(this.searchTexture&&!this.searchTexture.destroyed&&this.searchTexture.destroy(),this.searchFbo&&!this.searchFbo.destroyed&&this.searchFbo.destroy(),this.searchTexture=t.createTexture({width:o,height:o,format:"rgba32float"}),this.searchTexture.copyImageData({data:h,bytesPerRow:q("rgba32float",o),mipLevel:0,x:0,y:0}),this.searchFbo=t.createFramebuffer({width:o,height:o,colorAttachments:[this.searchTexture]})):this.searchTexture.copyImageData({data:h,bytesPerRow:q("rgba32float",o),mipLevel:0,x:0,y:0}),this.isPickingBufferStale=!0,this.discardPendingPick();const g=ji(i.pointsTextureSize),x=g.byteLength;return!this.drawPointIndices||this.drawPointIndices.byteLength!==x?(this.drawPointIndices&&!this.drawPointIndices.destroyed&&this.drawPointIndices.destroy(),this.drawPointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST})):this.drawPointIndices.write(g),this.drawCommand&&this.drawCommand.setAttributes({pointIndices:this.drawPointIndices}),this.drawCoreCommand&&this.drawCoreCommand.setAttributes({pointIndices:this.drawPointIndices}),this.updateReversedPointIndexBuffer(),!this.hoveredPointIndices||this.hoveredPointIndices.byteLength!==x?(this.hoveredPointIndices&&!this.hoveredPointIndices.destroyed&&this.hoveredPointIndices.destroy(),this.hoveredPointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST})):this.hoveredPointIndices.write(g),!this.sampledPointIndices||this.sampledPointIndices.byteLength!==x?(this.sampledPointIndices&&!this.sampledPointIndices.destroyed&&this.sampledPointIndices.destroy(),this.sampledPointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST})):this.sampledPointIndices.write(g),this.fillSampledPointsFboCommand&&this.fillSampledPointsFboCommand.setAttributes({pointIndices:this.sampledPointIndices}),this.updatePointStatus(),this.updatePinnedStatus(),this.updateExit(),this.updateSampledPointsGrid(),d||this.gatherTrackers(),d}initPrograms(){var s,o,a;const{device:t,config:i,store:n,data:r}=this;(!this.imageAtlasCoordsTexture||!this.imageAtlasTexture)&&this.createAtlas(),this.targetColorBuffer||this.updateColor(),this.targetSizeBuffer||this.updateSize(),this.shapeBuffer||this.updateShape(),this.imageIndicesBuffer||this.updateImageIndices(),this.imageSizesBuffer||this.updateImageSizes(),this.pointStatusTexture||this.updatePointStatus(),i.enableSimulation&&this.ensureUpdatePositionProgram(),this.dragPointVertexCoordBuffer||(this.dragPointVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.dragPointUniformStore||(this.dragPointUniformStore=new oe(t,{dragPointUniforms:{uniformTypes:{mousePos:"vec2",index:"f32"},defaultUniforms:{mousePos:ie(n.mousePosition,[0,0]),index:((s=n.hoveredPoint)==null?void 0:s.index)??-1}}})),this.dragPointCommand||(this.dragPointCommand=new ee(t,{fs:Iv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.dragPointVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{dragPointUniforms:this.dragPointUniformStore.getManagedUniformBuffer("dragPointUniforms")},parameters:te})),this.drawUniformStore||(this.drawUniformStore=new oe(t,{drawVertexUniforms:{uniformTypes:{ratio:"f32",transformationMatrix:"mat4x4",pointsTextureSize:"f32",sizeScale:"f32",spaceSize:"f32",screenSize:"vec2",greyoutColor:"vec4",backgroundColor:"vec4",scalePointsOnZoom:"f32",maxPointSize:"f32",isDarkenGreyout:"f32",skipHighlighted:"f32",skipGreyed:"f32",hasImages:"f32",imageCount:"f32",imageAtlasCoordsTextureSize:"f32",transitionProgress:"f32",animateColors:"f32",animateSizes:"f32",animatePositions:"f32",pointDefaultColor:"vec4",pointDefaultSize:"f32",pointsNumber:"f32"},defaultUniforms:{ratio:i.pixelRatio,transformationMatrix:(()=>{const l=n.transform??[1,0,0,0,1,0,0,0,1];return[l[0],l[1],l[2],0,l[3],l[4],l[5],0,l[6],l[7],l[8],0,0,0,0,1]})(),pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),greyoutColor:ge(n.greyoutPointColor,[0,0,0,1]),backgroundColor:ge(n.backgroundColor,[0,0,0,1]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,skipHighlighted:0,skipGreyed:0,hasImages:this.imageCount>0?1:0,imageCount:this.imageCount,imageAtlasCoordsTextureSize:this.imageAtlasCoordsTextureSize??0,transitionProgress:1,animateColors:0,animateSizes:0,animatePositions:0,pointDefaultColor:ge(We(i.pointDefaultColor),[0,0,0,1]),pointDefaultSize:i.pointDefaultSize,pointsNumber:r.pointsNumber??0}},drawFragmentUniforms:{uniformTypes:{greyoutOpacity:"f32",pointOpacity:"f32",isDarkenGreyout:"f32",backgroundColor:"vec4",outlineColor:"vec4",outlineWidth:"f32",renderMode:"f32",pickingAlpha:"f32",pickingIndexOffset:"f32"},defaultUniforms:{pickingAlpha:1,pickingIndexOffset:0,greyoutOpacity:i.pointGreyoutOpacity??-1,pointOpacity:i.pointOpacity,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,backgroundColor:ge(n.backgroundColor,[0,0,0,1]),outlineColor:ge(n.outlinedPointRingColor,[1,1,1,1]),outlineWidth:.9,renderMode:0}}})),this.drawCommand||(this.drawCommand=new ee(t,{fs:Ko,vs:qo,modules:[gi,_r,ur],topology:"point-list",vertexCount:r.pointsNumber??0,attributes:{...this.drawPointIndices&&{pointIndices:this.drawPointIndices},...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer},...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer},...this.shapeBuffer&&{shape:this.shapeBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer}},bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"sourceSize",format:"float32"},{name:"targetSize",format:"float32"},{name:"sourceColor",format:"float32x4"},{name:"targetColor",format:"float32x4"},{name:"shape",format:"float32"},{name:"imageIndex",format:"float32"},{name:"imageSize",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawVertexUniforms:this.drawUniformStore.getManagedUniformBuffer("drawVertexUniforms"),drawFragmentUniforms:this.drawUniformStore.getManagedUniformBuffer("drawFragmentUniforms")},parameters:Ad})),this.updateReversedPointIndexBuffer(),this.drawCoreCommand||(this.drawCoreCommand=new ee(t,{fs:Ko,vs:qo,modules:[gi,_r,ur],topology:"point-list",vertexCount:r.pointsNumber??0,indexBuffer:this.reversedPointIndexBuffer??null,attributes:{...this.drawPointIndices&&{pointIndices:this.drawPointIndices},...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer},...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer},...this.shapeBuffer&&{shape:this.shapeBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer}},bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"sourceSize",format:"float32"},{name:"targetSize",format:"float32"},{name:"sourceColor",format:"float32x4"},{name:"targetColor",format:"float32x4"},{name:"shape",format:"float32"},{name:"imageIndex",format:"float32"},{name:"imageSize",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawVertexUniforms:this.drawUniformStore.getManagedUniformBuffer("drawVertexUniforms"),drawFragmentUniforms:this.drawUniformStore.getManagedUniformBuffer("drawFragmentUniforms")},parameters:Mv})),this.findPointsInRectVertexCoordBuffer||(this.findPointsInRectVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.findPointsInRectUniformStore||(this.findPointsInRectUniformStore=new oe(t,{findPointsInRectUniforms:{uniformTypes:{sizeScale:"f32",spaceSize:"f32",screenSize:"vec2",ratio:"f32",transformationMatrix:"mat4x4",rect0:"vec2",rect1:"vec2",scalePointsOnZoom:"f32",maxPointSize:"f32"},defaultUniforms:{sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),ratio:i.pixelRatio,transformationMatrix:n.transformationMatrix4x4,rect0:ie((o=n.searchArea)==null?void 0:o[0],[0,0]),rect1:ie((a=n.searchArea)==null?void 0:a[1],[0,0]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize}}})),this.findPointsInRectCommand||(this.findPointsInRectCommand=new ee(t,{fs:yv,vs:Ee,modules:[gi],topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.findPointsInRectVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{findPointsInRectUniforms:this.findPointsInRectUniformStore.getManagedUniformBuffer("findPointsInRectUniforms")},parameters:te})),this.findPointsInPolygonVertexCoordBuffer||(this.findPointsInPolygonVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.findPointsInPolygonUniformStore||(this.findPointsInPolygonUniformStore=new oe(t,{findPointsInPolygonUniforms:{uniformTypes:{spaceSize:"f32",screenSize:"vec2",transformationMatrix:"mat4x4",polygonPathLength:"f32"},defaultUniforms:{spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),transformationMatrix:n.transformationMatrix4x4,polygonPathLength:this.polygonPathLength}}})),this.findPointsInPolygonCommand||(this.findPointsInPolygonCommand=new ee(t,{fs:_v,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.findPointsInPolygonVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{findPointsInPolygonUniforms:this.findPointsInPolygonUniformStore.getManagedUniformBuffer("findPointsInPolygonUniforms")},parameters:te})),this.fillPickingBufferUniformStore||(this.fillPickingBufferUniformStore=new oe(t,{fillPickingBufferUniforms:{uniformTypes:{pointsTextureSize:"f32",sizeScale:"f32",spaceSize:"f32",screenSize:"vec2",ratio:"f32",pickingPixelRatio:"f32",transformationMatrix:"mat4x4",scalePointsOnZoom:"f32",maxPointSize:"f32",skipHighlighted:"f32",skipGreyed:"f32",pointDefaultSize:"f32",hasImages:"f32",imageCount:"f32"},defaultUniforms:{pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),ratio:i.pixelRatio,pickingPixelRatio:ko,transformationMatrix:n.transformationMatrix4x4,scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize,skipHighlighted:0,skipGreyed:0,pointDefaultSize:i.pointDefaultSize,hasImages:0,imageCount:0}}})),this.fillPickingBufferCommand||(this.fillPickingBufferCommand=new ee(t,{fs:vv,vs:Pv,modules:[gi],topology:"point-list",vertexCount:r.pointsNumber??0,attributes:{...this.hoveredPointIndices&&{pointIndices:this.hoveredPointIndices},...this.targetSizeBuffer&&{size:this.targetSizeBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer}},bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"size",format:"float32"},{name:"imageSize",format:"float32"},{name:"imageIndex",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{fillPickingBufferUniforms:this.fillPickingBufferUniformStore.getManagedUniformBuffer("fillPickingBufferUniforms")},parameters:te})),this.fillSampledPointsUniformStore||(this.fillSampledPointsUniformStore=new oe(t,{fillSampledPointsUniforms:{uniformTypes:{pointsTextureSize:"f32",transformationMatrix:"mat4x4",spaceSize:"f32",screenSize:"vec2"},defaultUniforms:{pointsTextureSize:n.pointsTextureSize??0,transformationMatrix:n.transformationMatrix4x4,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0])}}})),this.fillSampledPointsFboCommand||(this.fillSampledPointsFboCommand=new ee(t,{fs:Cv,vs:Av,topology:"point-list",vertexCount:r.pointsNumber??0,attributes:{...this.sampledPointIndices&&{pointIndices:this.sampledPointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{fillSampledPointsUniforms:this.fillSampledPointsUniformStore.getManagedUniformBuffer("fillSampledPointsUniforms")},parameters:te})),this.drawHighlightedVertexCoordBuffer||(this.drawHighlightedVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.drawHighlightedUniformStore||(this.drawHighlightedUniformStore=new oe(t,{drawHighlightedUniforms:{uniformTypes:{sourceSize:"f32",targetSize:"f32",imageSize:"f32",transformationMatrix:"mat4x4",pointsTextureSize:"f32",sizeScale:"f32",spaceSize:"f32",screenSize:"vec2",scalePointsOnZoom:"f32",pointIndex:"f32",maxPointSize:"f32",color:"vec4",universalPointOpacity:"f32",greyoutOpacity:"f32",isDarkenGreyout:"f32",backgroundColor:"vec4",greyoutColor:"vec4",animatePositions:"f32",transitionProgress:"f32",animateSizes:"f32",pointDefaultSize:"f32",width:"f32",pixelRatio:"f32"},defaultUniforms:{sourceSize:1,targetSize:1,imageSize:0,transformationMatrix:n.transformationMatrix4x4,pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,pointIndex:-1,maxPointSize:n.maxPointSize,color:[0,0,0,1],universalPointOpacity:i.pointOpacity,greyoutOpacity:i.pointGreyoutOpacity??-1,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,backgroundColor:ge(n.backgroundColor,[0,0,0,1]),greyoutColor:ge(n.greyoutPointColor,[0,0,0,1]),animatePositions:0,transitionProgress:1,animateSizes:0,pointDefaultSize:i.pointDefaultSize,width:.85,pixelRatio:i.pixelRatio}}})),this.drawHighlightedCommand||(this.drawHighlightedCommand=new ee(t,{fs:bv,vs:Tv,modules:[gi,_r],topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.drawHighlightedVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawHighlightedUniforms:this.drawHighlightedUniformStore.getManagedUniformBuffer("drawHighlightedUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"src-alpha",blendColorDstFactor:"one-minus-src-alpha",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one-minus-src-alpha",depthWriteEnabled:!1,depthCompare:"always"}})),this.trackPointsVertexCoordBuffer||(this.trackPointsVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.trackPointsCommand||(this.trackPointsCommand=new ee(t,{fs:Ev,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.trackPointsVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{},parameters:te}))}updateColor(){const{device:t,store:{pointsTextureSize:i},data:n}=this;if(!i)return;const r=n.pointColors,{source:s,target:o,previous:a}=hr(this.device,r,this.sourceColorBuffer,this.targetColorBuffer,this.previousColorData,4);this.sourceColorBuffer=s,this.targetColorBuffer=o,this.previousColorData=a;const l={...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer}};if(this.drawCommand&&this.drawCommand.setAttributes(l),this.drawCoreCommand&&this.drawCoreCommand.setAttributes(l),this.config.linkColorInterpolateFromEndpoints){const c=new Float32Array(i*i*4);c.set(r.subarray(0,Math.min(r.length,c.length))),(!this.pointColorsTexture||this.pointColorsTexture.width!==i||this.pointColorsTexture.height!==i)&&(this.pointColorsTexture&&!this.pointColorsTexture.destroyed&&this.pointColorsTexture.destroy(),this.pointColorsTexture=t.createTexture({width:i,height:i,format:"rgba32float"})),this.pointColorsTexture.copyImageData({data:c,bytesPerRow:q("rgba32float",i),mipLevel:0,x:0,y:0})}else this.pointColorsTexture&&(this.pointColorsTexture.destroyed||this.pointColorsTexture.destroy(),this.pointColorsTexture=void 0)}updatePointStatus(){const{device:t,config:i,data:n,store:{pointsTextureSize:r}}=this;if(!r||n.pointsNumber===void 0)return;this.isPickingBufferStale=!0;const{highlightedPointIndices:s,outlinedPointIndices:o}=i,a=s!==void 0,l=o!==void 0,c=new Float32Array(r*r*4);if(a){for(let d=0;d=0&&d=0&&d=0&&s{n.setBindings({positionsTexture:r,trackedIndices:t});const o=this.device.beginRenderPass({framebuffer:i});n.draw(o),o.end()};return this.withHostState?this.withHostState(s):s(),!0}addTracker(t){t.attach(this)&&this.trackers.add(t)}removeTracker(t){this.trackers.delete(t)}getAnimatedSize(t,i){var o;const n=this.data.getResolvedPointSize(t),r=(o=this.sourceSizeData)==null?void 0:o[t];if(r===void 0)return n;const s=this.data.resolvePointSize(t,r);return s+(n-s)*i}setTransitionProgress(t,i=!1,n=!1,r=!1){this.transitionProgress=t,this.shouldAnimatePointColors=i,this.shouldAnimatePointSizes=n,this.shouldAnimatePointPositions=r}drawPicking(t,i,n=0){const{data:r,store:s}=this;if(this.targetColorBuffer||this.updateColor(),this.targetSizeBuffer||this.updateSize(),this.exitTexture||this.updateExit(),this.shapeBuffer||this.updateShape(),this.imageIndicesBuffer||this.updateImageIndices(),this.imageSizesBuffer||this.updateImageSizes(),!this.drawCommand||!this.drawUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.pointStatusTexture||this.pointStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed||((!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)&&this.createAtlas(),!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)||this.imageAtlasTexture.destroyed||this.imageAtlasCoordsTexture.destroyed||!r.pointsNumber||!s.screenSize||s.screenSize[0]===0||s.screenSize[1]===0)return;this.drawPickingCommand||(this.drawPickingCommand=new ee(this.device,{fs:Ko,vs:qo,modules:[gi,_r,ur],topology:"point-list",vertexCount:r.pointsNumber,attributes:this.getDrawCommandAttributes(),bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"sourceSize",format:"float32"},{name:"targetSize",format:"float32"},{name:"sourceColor",format:"float32x4"},{name:"targetColor",format:"float32x4"},{name:"shape",format:"float32"},{name:"imageIndex",format:"float32"},{name:"imageSize",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawVertexUniforms:this.drawUniformStore.getManagedUniformBuffer("drawVertexUniforms"),drawFragmentUniforms:this.drawUniformStore.getManagedUniformBuffer("drawFragmentUniforms")},parameters:te})),this.drawPickingCommand.setAttributes(this.getDrawCommandAttributes()),this.drawPickingCommand.setVertexCount(r.pointsNumber);const{vertex:o,fragment:a}=this.getDrawUniforms();this.drawUniformStore.setUniforms({drawVertexUniforms:{...o,skipHighlighted:0,skipGreyed:0},drawFragmentUniforms:{...a,renderMode:3,pickingAlpha:i,pickingIndexOffset:n}}),this.drawPickingCommand.setBindings(this.getDrawTextureBindings()),this.drawPickingCommand.draw(t)}draw(t){var p,g;const{data:i,config:n,store:r}=this;if(this.targetColorBuffer||this.updateColor(),this.targetSizeBuffer||this.updateSize(),this.exitTexture||this.updateExit(),this.shapeBuffer||this.updateShape(),this.imageIndicesBuffer||this.updateImageIndices(),this.imageSizesBuffer||this.updateImageSizes(),!this.drawCommand||!this.drawUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.pointStatusTexture||this.pointStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed||(!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)&&(this.createAtlas(),!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)||this.imageAtlasTexture.destroyed||this.imageAtlasCoordsTexture.destroyed||!i.pointsNumber||i.pointsNumber===0||!r.screenSize||r.screenSize[0]===0||r.screenSize[1]===0)return;this.drawCommand.setVertexCount(i.pointsNumber);const{vertex:s,fragment:o}=this.getDrawUniforms(),a=this.getDrawTextureBindings(),l=n.highlightedPointIndices!==void 0,c=n.pointOcclusionCulling&&n.pointOpacity>=1&&!l&&!!this.drawCoreCommand&&((p=this.reversedPointIndexBuffer)==null?void 0:p.byteLength)===i.pointsNumber*4;c!==this.isOcclusionCullingActive&&(this.drawCommand.setParameters(c?Nv:Ad),this.isOcclusionCullingActive=c),c&&this.drawCoreCommand?(this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:0,skipGreyed:0},drawFragmentUniforms:{...o,renderMode:1}}),this.drawCoreCommand.setVertexCount(i.pointsNumber),this.drawCoreCommand.setBindings(a),this.drawCoreCommand.draw(t),this.drawUniformStore.setUniforms({drawFragmentUniforms:{...o,renderMode:2}}),this.drawCommand.setBindings(a),this.drawCommand.draw(t)):l?(this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:1,skipGreyed:0},drawFragmentUniforms:o}),this.drawCommand.setBindings(a),this.drawCommand.draw(t),this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:0,skipGreyed:1},drawFragmentUniforms:o}),this.drawCommand.setBindings(a),this.drawCommand.draw(t)):(this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:0,skipGreyed:0},drawFragmentUniforms:o}),this.drawCommand.setBindings(a),this.drawCommand.draw(t));const u=n.renderHoveredPointRing?(g=r.hoveredPoint)==null?void 0:g.index:void 0,d=r.hostHoveredPointIndex,h=d!==void 0&&Number.isInteger(d)&&d>=0&&d<(this.data.pointsNumber??0)?d:void 0;u!==void 0&&this.drawPointRing(t,u,r.hoveredPointRingColor),h!==void 0&&h!==u&&this.drawPointRing(t,h,r.hoveredPointRingColor),r.focusedPoint&&this.drawPointRing(t,r.focusedPoint.index,r.focusedPointRingColor)}updatePosition(){if(!this.updatePositionCommand||!this.updatePositionUniformStore||!this.currentPositionFbo||this.currentPositionFbo.destroyed||!this.previousPositionTexture||this.previousPositionTexture.destroyed||!this.velocityTexture||this.velocityTexture.destroyed||!this.pinnedStatusTexture||this.pinnedStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed)return;this.updatePositionUniformStore.setUniforms({updatePositionUniforms:{friction:this.config.simulationFriction,spaceSize:this.store.adjustedSpaceSize}}),this.updatePositionCommand.setBindings({positionsTexture:this.previousPositionTexture,velocity:this.velocityTexture,pinnedStatusTexture:this.pinnedStatusTexture,exitTexture:this.exitTexture});const t=this.device.beginRenderPass({framebuffer:this.currentPositionFbo});this.updatePositionCommand.draw(t),t.end(),this.markPositionsChanged()}drag(){var i;if(!this.dragPointCommand||!this.dragPointUniformStore||!this.currentPositionFbo||this.currentPositionFbo.destroyed||!this.previousPositionTexture||this.previousPositionTexture.destroyed)return;this.dragPointUniformStore.setUniforms({dragPointUniforms:{mousePos:ie(this.store.mousePosition,[0,0]),index:((i=this.store.hoveredPoint)==null?void 0:i.index)??-1}}),this.dragPointCommand.setBindings({positionsTexture:this.previousPositionTexture});const t=this.device.beginRenderPass({framebuffer:this.currentPositionFbo});this.dragPointCommand.draw(t),t.end(),this.markPositionsChanged()}setPointPositionsByIndices(t,i){var l,c;const{store:{pointsTextureSize:n},data:r}=this;if(!n||r.pointsNumber===void 0||!this.currentPositionTexture||this.currentPositionTexture.destroyed)return;const s=[this.currentPositionTexture];if(((l=this.transition)==null?void 0:l.isActiveFor(le.Positions))||((c=this.transition)==null?void 0:c.isPendingFor(le.Positions)))for(const u of[this.sourcePositionTexture,this.targetPositionTexture])u&&!u.destroyed&&s.push(u);const a=new Float32Array(4);for(let u=0,d=t.length;u=r.pointsNumber)&&!(r.pointPositions&&De(r.pointPositions,h))){a[0]=i[u*2],a[1]=i[u*2+1],a[2]=h;for(const p of s)p.copyImageData({data:a,x:h%n,y:Math.floor(h/n),width:1,height:1,bytesPerRow:q("rgba32float",1),mipLevel:0})}}this.markPositionsChanged(),this.areClusterCentroidsUpToDate=!1}setPointPinnedStatus(t,i){const{store:{pointsTextureSize:n},data:r}=this;if(!(!n||r.pointsNumber===void 0)&&!(t<0||t>=r.pointsNumber)){if(!this.pinnedStatusTexture||this.pinnedStatusTexture.destroyed||this.pinnedStatusTexture.width!==n||this.pinnedStatusTexture.height!==n){this.updatePinnedStatus();return}this.pinnedStatusTexture.copyImageData({data:new Float32Array([i?1:0,0,0,0]),x:t%n,y:Math.floor(t/n),width:1,height:1,bytesPerRow:q("rgba32float",1),mipLevel:0})}}async readPositionPixelsAsync(){const{device:t,store:{pointsTextureSize:i},data:{pointsNumber:n}}=this;if(!i||!this.currentPositionFbo||this.currentPositionFbo.destroyed)return;const r=i*i*4*4,s=t.createBuffer({byteLength:r,usage:B.COPY_DST|B.MAP_READ});try{const o=t.createCommandEncoder();if(o.copyTextureToBuffer({sourceTexture:this.currentPositionFbo,width:i,height:i,destinationBuffer:s}),t.submit(o.finish()),await this.waitForGpu(),this.store.pointsTextureSize!==i||this.data.pointsNumber!==n||!this.currentPositionFbo||this.currentPositionFbo.destroyed)return;const a=await s.readAsync();return new Float32Array(a.buffer,a.byteOffset,r/4)}finally{s.destroy()}}findPointsInRect(){var i,n;if(!this.findPointsInRectCommand||!this.findPointsInRectUniformStore||!this.searchFbo||this.searchFbo.destroyed||!this.currentPositionTexture||this.currentPositionTexture.destroyed||(this.isSizeTextureStale&&this.updateSizeTexture(),!this.sizeTexture||this.sizeTexture.destroyed)||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return!1;this.findPointsInRectUniformStore.setUniforms({findPointsInRectUniforms:{spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),sizeScale:this.config.pointSizeScale,transformationMatrix:this.store.transformationMatrix4x4,ratio:this.config.pixelRatio,rect0:ie((i=this.store.searchArea)==null?void 0:i[0],[0,0]),rect1:ie((n=this.store.searchArea)==null?void 0:n[1],[0,0]),scalePointsOnZoom:this.config.scalePointsOnZoom?1:0,maxPointSize:this.store.maxPointSize}}),this.findPointsInRectCommand.setBindings({positionsTexture:this.currentPositionTexture,pointSize:this.sizeTexture,exitTexture:this.exitTexture});const t=this.device.beginRenderPass({framebuffer:this.searchFbo});return this.findPointsInRectCommand.draw(t),t.end(),!0}findPointsInPolygon(){if(!this.findPointsInPolygonCommand||!this.findPointsInPolygonUniformStore||!this.searchFbo||this.searchFbo.destroyed||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.polygonPathTexture||this.polygonPathTexture.destroyed||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return!1;this.findPointsInPolygonUniformStore.setUniforms({findPointsInPolygonUniforms:{spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),transformationMatrix:this.store.transformationMatrix4x4,polygonPathLength:this.polygonPathLength}}),this.findPointsInPolygonCommand.setBindings({positionsTexture:this.currentPositionTexture,polygonPathTexture:this.polygonPathTexture,exitTexture:this.exitTexture});const t=this.device.beginRenderPass({framebuffer:this.searchFbo});return this.findPointsInPolygonCommand.draw(t),t.end(),!0}updatePolygonPath(t){const{device:i}=this;if(this.polygonPathLength=t.length,t.length===0){this.polygonPathTexture&&!this.polygonPathTexture.destroyed&&this.polygonPathTexture.destroy(),this.polygonPathTexture=void 0;return}const n=Math.ceil(Math.sqrt(t.length)),r=new Float32Array(n*n*4);for(const[s,o]of t.entries()){const[a,l]=o;r[s*4]=a,r[s*4+1]=l,r[s*4+2]=0,r[s*4+3]=0}!this.polygonPathTexture||this.polygonPathTexture.width!==n||this.polygonPathTexture.height!==n?(this.polygonPathTexture&&!this.polygonPathTexture.destroyed&&this.polygonPathTexture.destroy(),this.polygonPathTexture=i.createTexture({width:n,height:n,format:"rgba32float"}),this.polygonPathTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0})):this.polygonPathTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0})}updatePickingBuffer(){if(!this.isPickingBufferStale||!this.ensurePickingBuffer()||!this.pickingFbo||this.pickingFbo.destroyed||!this.fillPickingBufferCommand||!this.fillPickingBufferUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||(this.pointStatusTexture||this.updatePointStatus(),!this.pointStatusTexture||this.pointStatusTexture.destroyed)||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return;this.fillPickingBufferCommand.setVertexCount(this.data.pointsNumber??0),this.fillPickingBufferCommand.setAttributes({...this.hoveredPointIndices&&{pointIndices:this.hoveredPointIndices},...this.targetSizeBuffer&&{size:this.targetSizeBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer}});const t=ie(this.store.screenSize,[0,0]),i={ratio:this.config.pixelRatio,sizeScale:this.config.pointSizeScale,pointsTextureSize:this.store.pointsTextureSize??0,transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:t,scalePointsOnZoom:this.config.scalePointsOnZoom?1:0,pickingPixelRatio:t[0]>0?this.pickingFbo.width/t[0]:ko,maxPointSize:this.store.maxPointSize,pointDefaultSize:this.config.pointDefaultSize,hasImages:this.imageCount>0?1:0,imageCount:this.imageCount},n={positionsTexture:this.currentPositionTexture,pointStatus:this.pointStatusTexture,exitTexture:this.exitTexture},r=this.device.beginRenderPass({framebuffer:this.pickingFbo,clearColor:[-1,0,0,0],clearDepth:1});this.config.highlightedPointIndices!==void 0?(this.fillPickingBufferUniformStore.setUniforms({fillPickingBufferUniforms:{...i,skipHighlighted:1,skipGreyed:0}}),this.fillPickingBufferCommand.setBindings(n),this.fillPickingBufferCommand.draw(r),this.fillPickingBufferUniformStore.setUniforms({fillPickingBufferUniforms:{...i,skipHighlighted:0,skipGreyed:1}}),this.fillPickingBufferCommand.setBindings(n),this.fillPickingBufferCommand.draw(r)):(this.fillPickingBufferUniformStore.setUniforms({fillPickingBufferUniforms:{...i,skipHighlighted:0,skipGreyed:0}}),this.fillPickingBufferCommand.setBindings(n),this.fillPickingBufferCommand.draw(r)),r.end(),this.isPickingBufferStale=!1}pickPointSync(){this.updatePickingBuffer();const t=this.getCursorPickingWindow();if(!t||!this.pickingFbo||this.pickingFbo.destroyed)return;const i=we(this.device,this.pickingFbo,t.x,t.y,Fe,Fe);return Wu(i,t.centerX-t.x,t.centerY-t.y)}requestPickPoint(){var r;if((r=this.pickingReadback)!=null&&r.inFlight)return!1;if(this.updatePickingBuffer(),!this.pickingFbo||this.pickingFbo.destroyed)return!0;const t=this.device.gl,i=this.pickingFbo.handle;if(!t||!i)return!0;this.pickingReadback||(this.pickingReadback=new dr(t,Fe*Fe*4));const n=this.getCursorPickingWindow();return n?this.pickingReadback.issue(i,n.x,n.y,Fe,Fe)?(this.issuedPickingWindow=n,!0):!1:!0}discardPendingPick(){var t;(t=this.pickingReadback)==null||t.cancel(),this.issuedPickingWindow=void 0}takePickResult(){if(!this.pickingReadback||!this.issuedPickingWindow)return;const t=this.pickingReadback.poll();if(!t)return;const i=this.issuedPickingWindow;return this.issuedPickingWindow=void 0,Wu(t,i.centerX-i.x,i.centerY-i.y)??null}requestTrackedPositionsReadback(){for(const t of this.trackers)t.requestReadback()}resolveTrackedPositionsReadback(){for(const t of this.trackers)t.resolveReadback()}getSampledPointPositionsMap(){const t=new Map;if(!this.sampledPointsFbo||this.sampledPointsFbo.destroyed)return t;if(this.fillSampledPointsFboCommand&&this.fillSampledPointsUniformStore&&this.sampledPointsFbo){if(!this.currentPositionTexture||this.currentPositionTexture.destroyed||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return t;this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber??0),this.fillSampledPointsUniformStore.setUniforms({fillSampledPointsUniforms:{pointsTextureSize:this.store.pointsTextureSize??0,transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0])}}),this.fillSampledPointsFboCommand.setBindings({positionsTexture:this.currentPositionTexture,exitTexture:this.exitTexture});const n=this.device.beginRenderPass({framebuffer:this.sampledPointsFbo,clearColor:[0,0,0,0]});this.fillSampledPointsFboCommand.draw(n),n.end()}const i=we(this.device,this.sampledPointsFbo);for(let n=0;n{n=setTimeout(r,t)})])}finally{clearTimeout(n),i.destroy()}}writePositionTexture(t,i,n){t.copyImageData({data:i,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0})}ensurePickingBuffer(){var a;const{device:t,store:i}=this,[n,r]=i.screenSize;if(!n||!r)return!1;const{width:s,height:o}=W_(n,r);return this.pickingTexture&&!this.pickingTexture.destroyed&&this.pickingTexture.width===s&&this.pickingTexture.height===o||((a=this.pickingReadback)==null||a.cancel(),this.issuedPickingWindow=void 0,this.pickingFbo&&!this.pickingFbo.destroyed&&this.pickingFbo.destroy(),this.pickingTexture&&!this.pickingTexture.destroyed&&this.pickingTexture.destroy(),this.pickingTexture=t.createTexture({width:s,height:o,format:"rgba32float",usage:M.SAMPLE|M.RENDER}),this.pickingFbo=t.createFramebuffer({width:s,height:o,colorAttachments:[this.pickingTexture],depthStencilAttachment:"depth16unorm"}),this.isPickingBufferStale=!0),!0}getCursorPickingWindow(){if(!this.pickingFbo||this.pickingFbo.destroyed)return;const[t,i]=this.store.screenSize;if(!(!t||!i))return V_(this.pickingFbo.width,this.pickingFbo.height,this.store.screenMousePosition[0],this.store.screenMousePosition[1],t,i)}ensureUpdatePositionProgram(){const{device:t,config:i,store:n}=this;this.updatePositionVertexCoordBuffer||(this.updatePositionVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.updatePositionUniformStore||(this.updatePositionUniformStore=new oe(t,{updatePositionUniforms:{uniformTypes:{friction:"f32",spaceSize:"f32"},defaultUniforms:{friction:i.simulationFriction,spaceSize:n.adjustedSpaceSize}}})),this.updatePositionCommand||(this.updatePositionCommand=new ee(t,{fs:Rv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.updatePositionVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{updatePositionUniforms:this.updatePositionUniformStore.getManagedUniformBuffer("updatePositionUniforms")},parameters:te}))}rescaleInitialNodePositions(){const{config:{spaceSize:t}}=this;if(!this.data.pointPositions||!t)return;const i=this.data.pointPositions,n=i.length/2;let r=1/0,s=-1/0,o=1/0,a=-1/0;for(let S=0;SP-r+S,this.scaleY=P=>P-o+S;for(let P=0;Pt){this.scaleX=void 0,this.scaleY=void 0;return}const d=t*t*.001,h=n>d?t*Math.max(1.2,Math.sqrt(n)/t):t*.1,p=h/u,g=(t-h)/2,x=(u-l)/2*p+g,T=(u-c)/2*p+g;this.scaleX=S=>(S-r)*p+x,this.scaleY=S=>(S-o)*p+T;for(let S=0;S0?1:0,imageCount:this.imageCount,imageAtlasCoordsTextureSize:this.imageAtlasCoordsTextureSize??0,transitionProgress:this.transitionProgress,animateColors:this.shouldAnimatePointColors?1:0,animateSizes:this.shouldAnimatePointSizes?1:0,animatePositions:this.shouldAnimatePointPositions?1:0,pointDefaultColor:ge(t.defaultRgba,[0,0,0,1]),pointDefaultSize:i.pointDefaultSize,pointsNumber:t.pointsNumber},s={greyoutOpacity:i.pointGreyoutOpacity??-1,pointOpacity:i.pointOpacity,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,backgroundColor:ge(n.backgroundColor,[0,0,0,1]),outlineColor:ge(n.outlinedPointRingColor,[1,1,1,1]),outlineWidth:.9,renderMode:0};return{vertex:r,fragment:s}}getDrawTextureBindings(){return{positionsTexture:this.currentPositionTexture,pointStatus:this.pointStatusTexture,exitTexture:this.exitTexture,imageAtlasTexture:this.imageAtlasTexture,imageAtlasCoords:this.imageAtlasCoordsTexture}}getDrawCommandAttributes(){return{...this.drawPointIndices&&{pointIndices:this.drawPointIndices},...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer},...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer},...this.shapeBuffer&&{shape:this.shapeBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer}}}}class Ov{constructor(t){this.isDestroyed=!1,this.gatheredVersion=-1,this.cachedVersion=-1,this.cachedPointList=-1,this.issuedVersion=-1,this.issuedPointList=-1,this.isReadbackWanted=!1,this.indices=[...t]}get hasPendingReadback(){var t;return((t=this.readback)==null?void 0:t.inFlight)??!1}positions(t){var s,o;const{host:i}=this;if(!i||!this.indices.length)return new Map;this.resolveReadback();const n=i.positionVersion,r=i.pointListVersion;return this.cached&&this.cachedVersion===n&&this.cachedPointList===r?this.cached:t!=null&&t.nonBlocking&&this.cached?(this.cachedPointList!==r&&this.dropGonePoints(),this.isReadbackWanted=!0,this.issuedVersion!==n&&!(((s=i.requestTick)==null?void 0:s.call(i))??!1)&&this.requestReadback(),this.cached):!this.positionsFbo||this.positionsFbo.destroyed?new Map:(this.isReadbackWanted=!1,(o=this.readback)==null||o.cancel(),this.gather(),this.cached=this.buildMap(we(i.device,this.positionsFbo)),this.cachedVersion=n,this.cachedPointList=r,this.issuedVersion=n,this.cached)}positionsArray(){const{host:t,indices:i}=this;if(!t||!i.length||!this.positionsFbo||this.positionsFbo.destroyed)return[];const n=new Array(i.length*2);this.gather();const r=we(t.device,this.positionsFbo);for(let s=0,o=i.length;s{var o;return this._isDestroyed?(this.shouldDestroyDevice&&((o=s.canvasContext)==null||o.destroy(),s.destroy()),s):(this._device=s,this.store.adjustSpaceSize(this.config.spaceSize,s.limits.maxTextureDimension2D),this.store.setWebGLMaxTextureSize(s.limits.maxTextureDimension2D),this.store.maxPointSize=Fs(s,this.config.pixelRatio),this.store.isSimulationRunning=this.config.enableSimulation,this.points=new Bv(s,this.config,this.store,this.data),this.points.withHostState=a=>this.withExternalDeviceState(a),this.config.enableSimulation&&this.ensureSimulationModules(),this.clusters=new Sv(s,this.config,this.store,this.data,this.points),this.config.randomSeed!==void 0&&this.store.addRandomSeed(this.config.randomSeed),this.isReady=!0,s)}).catch(s=>{throw this._device=void 0,this.isReady=!1,console.error("Device initialization failed:",s),s});this.ready=r.then(()=>{})}get device(){return this._device}get ownsDevice(){return this.shouldDestroyDevice}get progress(){return this._isDestroyed?0:this.store.simulationProgress}get isSimulationRunning(){return this._isDestroyed?!1:this.store.isSimulationRunning}get hasPendingCentroidReadback(){var t;return((t=this.clusters)==null?void 0:t.hasPendingCentroidReadback)??!1}setConfig(t){var n,r;if(this._isDestroyed||this.ensureDevice(()=>this.setConfig(t)))return;const i={...this.config};Bi(this.config,t,!0),this.applyEnableSimulationConfigChange(i),i.pointDefaultSize!==this.config.pointDefaultSize&&(this.data.updatePointSize(),(n=this.points)==null||n.updateSize()),(i.simulationCollisionRadius!==this.config.simulationCollisionRadius||i.simulationCollisionPadding!==this.config.simulationCollisionPadding||(this.config.simulationCollisionRadius===void 0||this.config.simulationCollisionRadius===0)&&i.pointDefaultSize!==this.config.pointDefaultSize)&&(this.isForceCollisionReady=!1),i.spaceSize!==this.config.spaceSize&&(this.store.adjustSpaceSize(this.config.spaceSize,((r=this._device)==null?void 0:r.limits.maxTextureDimension2D)??4096),this.isForceCollisionReady=!1,this.update(this.store.isSimulationRunning?this.store.alpha:0))}setPointPositions(t,i){this._isDestroyed||this.ensureDevice(()=>this.setPointPositions(t,i))||(this.data.inputPointPositions=t,this.points&&(this.points.shouldSkipRescale=i),this.isPointPositionsUpdateNeeded=!0,this.isPointSizeUpdateNeeded=!0,this.isPointClusterUpdateNeeded=!0,this.isForceManyBodyUpdateNeeded=!0,this.isForceLinkUpdateNeeded=!0,this.isForceCenterUpdateNeeded=!0)}setPointSizes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointSizes(t))||(this.data.inputPointSizes=t,this.isPointSizeUpdateNeeded=!0)}setLinks(t){this._isDestroyed||this.ensureDevice(()=>this.setLinks(t))||(this.data.inputLinks=t,this.isForceLinkUpdateNeeded=!0)}setLinkStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkStrength(t))||(this.data.inputLinkStrength=t,this.isForceLinkUpdateNeeded=!0)}setPointClusters(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusters(t))||(this.data.inputPointClusters=t,this.isPointClusterUpdateNeeded=!0)}setClusterPositions(t){this._isDestroyed||this.ensureDevice(()=>this.setClusterPositions(t))||(this.data.inputClusterPositions=t,this.isPointClusterUpdateNeeded=!0)}setPointClusterStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusterStrength(t))||(this.data.inputClusterStrength=t,this.isPointClusterUpdateNeeded=!0)}setPinnedPoints(t){var r;if(this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoints(t)))return;const i=t==null?void 0:t.filter(s=>Number.isInteger(s)&&s>=0),n=i&&i.length>0?[...new Set(i)]:void 0;this.data.inputPinnedPoints=n,(r=this.points)==null||r.updatePinnedStatus()}setPinnedPoint(t,i){var r;if(this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoint(t,i))||!Number.isInteger(t)||t<0)return;const n=new Set(this.data.inputPinnedPoints);i?n.add(t):n.delete(t),this.data.inputPinnedPoints=n.size>0?[...n]:void 0,(r=this.points)==null||r.setPointPinnedStatus(t,i)}isPointPinned(t){var i;return this._isDestroyed?!1:((i=this.data.inputPinnedPoints)==null?void 0:i.includes(t))??!1}setPointPosition(t,i,n){this.setPointPositionsByIndices([t],[i,n])}setPointPositionsByIndices(t,i){if(this._isDestroyed||this.ensureDevice(()=>this.setPointPositionsByIndices(t,i)))return;if(t.length*2!==i.length){console.warn(`setPointPositionsByIndices: expected ${t.length*2} coordinates for ${t.length} indices, got ${i.length}. Call ignored.`);return}const n=this.points;n&&this.withExternalDeviceState(()=>{n.setPointPositionsByIndices(t,i),n.gatherTrackers()})}applyData(t){this._isDestroyed||this.ensureDevice(()=>this.applyData(t))||(this.data.update(),this.update(t))}start(t=1){var n,r;if(this._isDestroyed||this.ensureDevice(()=>this.start(t))||!this.config.enableSimulation||!this.data.pointsNumber)return;const i=this.store.isSimulationRunning;this.store.isSimulationRunning=!0,this.store.simulationProgress=0,this.store.alpha=t,i||(r=(n=this.config).onSimulationStart)==null||r.call(n)}stop(){var i,n;if(this._isDestroyed||this.ensureDevice(()=>this.stop()))return;const t=this.store.isSimulationRunning||this.store.alpha>0||this.store.simulationProgress>0;this.store.isSimulationRunning=!1,this.store.simulationProgress=0,this.store.alpha=0,t&&((n=(i=this.config).onSimulationEnd)==null||n.call(i))}pause(){var t,i;this._isDestroyed||this.ensureDevice(()=>this.pause())||this.store.isSimulationRunning&&(this.store.isSimulationRunning=!1,(i=(t=this.config).onSimulationPause)==null||i.call(t))}unpause(){var t,i;this._isDestroyed||this.ensureDevice(()=>this.unpause())||this.config.enableSimulation&&(this.store.isSimulationRunning||(this.store.isSimulationRunning=!0,(i=(t=this.config).onSimulationUnpause)==null||i.call(t)))}step(){this._isDestroyed||this.ensureDevice(()=>this.step())||this.config.enableSimulation&&this.store.pointsTextureSize&&(this.runSimulationStep(!0),this.store.alpha{var r;return(r=this.points)==null?void 0:r.addTracker(i)};return this.isReady?n():this.ensureDevice(n),i}getClusterPositions(t){if(this._isDestroyed||!this._device||!this.clusters)return[];if(this.data.pointClusters===void 0||this.clusters.clusterCount===void 0)return[];const i=this.clusters;return this.withExternalDeviceState(()=>{var r,s;t!=null&&t.nonBlocking&&i.resolveCentroidReadback();const n=i.getCentroidPositions(t==null?void 0:t.nonBlocking);return t!=null&&t.nonBlocking&&i.needsCentroidReadback&&!(((s=(r=this.points)==null?void 0:r.requestTick)==null?void 0:s.call(r))??!1)&&i.requestCentroidReadback(),n})}collectReadbacks(){var t,i;(t=this.points)==null||t.resolveTrackedPositionsReadback(),(i=this.clusters)==null||i.resolveCentroidReadback()}issueReadbacks(){var t,i;(t=this.points)==null||t.requestTrackedPositionsReadback(),(i=this.clusters)==null||i.requestCentroidReadback()}destroy(){var t,i,n,r;this._isDestroyed||(this._isDestroyed=!0,this.isReady=!1,(t=this.points)==null||t.destroy(),(i=this.clusters)==null||i.destroy(),this.destroySimulationModules(),(n=this.forceMouse)==null||n.destroy(),this.forceMouse=void 0,this._device&&this.shouldDestroyDevice&&(this._device.beginRenderPass({clearColor:this.store.backgroundColor,clearDepth:1,clearStencil:0}).end(),this._device.submit(),(r=this._device.canvasContext)==null||r.destroy(),this._device.destroy()))}updateTextureSizes(){this.store.pointsTextureSize=Math.ceil(Math.sqrt(this.data.pointsNumber??0)),this.store.linksTextureSize=Math.ceil(Math.sqrt((this.data.linksNumber??0)*2))}applyDataUpdates(){var i,n,r,s,o;const t=this.isPointPositionsUpdateNeeded;return this.points?(this.isPointPositionsUpdateNeeded&&this.points.updatePositions(),this.isPointSizeUpdateNeeded&&this.points.updateSize(),this.isForceManyBodyUpdateNeeded&&((i=this.forceManyBody)==null||i.create()),(this.isForceManyBodyUpdateNeeded||this.isPointSizeUpdateNeeded)&&(this.isForceCollisionReady=!1),this.isForceLinkUpdateNeeded&&((n=this.forceLinkIncoming)==null||n.create(jo.INCOMING),(r=this.forceLinkOutgoing)==null||r.create(jo.OUTGOING)),this.isForceCenterUpdateNeeded&&((s=this.forceCenter)==null||s.create()),this.isPointClusterUpdateNeeded&&((o=this.clusters)==null||o.create()),this.isPointPositionsUpdateNeeded=!1,this.isPointSizeUpdateNeeded=!1,this.isForceManyBodyUpdateNeeded=!1,this.isForceLinkUpdateNeeded=!1,this.isForceCenterUpdateNeeded=!1,this.isPointClusterUpdateNeeded=!1,{positionsUpdated:t}):{positionsUpdated:!1}}initPrograms(){var t,i,n,r,s,o;this._isDestroyed||!this.points||!this.clusters||(this.points.initPrograms(),(t=this.forceGravity)==null||t.initPrograms(),(i=this.forceManyBody)==null||i.initPrograms(),(n=this.forceCenter)==null||n.initPrograms(),(r=this.forceLinkIncoming)==null||r.initPrograms(),(s=this.forceLinkOutgoing)==null||s.initPrograms(),(o=this.forceMouse)==null||o.initPrograms(),this.clusters.initPrograms())}runSimulationStep(t=!1,i){return this.config.enableSimulation?this.withExternalDeviceState(()=>this.runStepPasses(t,i)):!1}end(){var t,i;this.store.isSimulationRunning=!1,this.store.simulationProgress=1,(i=(t=this.config).onSimulationEnd)==null||i.call(t)}withExternalDeviceState(t){const i=this._device;if(this.shouldDestroyDevice||!i)return t();const n=i.gl,r=n?Pt.get(n):void 0,s=(r==null?void 0:r.stateStack.length)??0;try{return i.withParametersWebGL({blend:!1,depthTest:!1,depthMask:!0,scissorTest:!1,stencilTest:!1,cull:!1,colorMask:[!0,!0,!0,!0],nocatch:!0},t)}finally{if(r)for(;r.stateStack.length>s;)r.pop()}}ensureSimulationModules(){!this._device||!this.points||(this.forceGravity||(this.forceGravity=new ev(this._device,this.config,this.store,this.data,this.points)),this.forceCenter||(this.forceCenter=new KT(this._device,this.config,this.store,this.data,this.points)),this.forceManyBody||(this.forceManyBody=new hv(this._device,this.config,this.store,this.data,this.points)),this.forceLinkIncoming||(this.forceLinkIncoming=new Td(this._device,this.config,this.store,this.data,this.points)),this.forceLinkOutgoing||(this.forceLinkOutgoing=new Td(this._device,this.config,this.store,this.data,this.points)),this.forceMouse||(this.forceMouse=new pv(this._device,this.config,this.store,this.data,this.points)),this.forceCollision||(this.forceCollision=new QT(this._device,this.config,this.store,this.data,this.points)))}destroySimulationModules(){var t,i,n,r,s,o,a,l;(t=this.forceGravity)==null||t.destroy(),this.forceGravity=void 0,(i=this.forceCenter)==null||i.destroy(),this.forceCenter=void 0,(n=this.forceManyBody)==null||n.destroy(),this.forceManyBody=void 0,(r=this.forceLinkIncoming)==null||r.destroy(),this.forceLinkIncoming=void 0,(s=this.forceLinkOutgoing)==null||s.destroy(),this.forceLinkOutgoing=void 0,(o=this.forceMouse)==null||o.destroy(),this.forceMouse=void 0,(a=this.forceCollision)==null||a.destroy(),this.forceCollision=void 0,this.isForceCollisionReady=!1,(l=this.points)==null||l.destroySimulationResources()}markForcesDirty(){this.isForceManyBodyUpdateNeeded=!0,this.isForceLinkUpdateNeeded=!0,this.isForceCenterUpdateNeeded=!0}invalidateCollisionResources(){this.isForceCollisionReady=!1}runStepPasses(t,i){var l,c,u,d,h,p,g,x,T,S,P,I,y,v,E,R,D,z,$,F,Q,X,b,N,A,O,V,L,Y,J,H;const{config:{simulationGravity:n,simulationCenter:r,simulationCollision:s},store:{isSimulationRunning:o}}=this;i!=null&&i.applyMouseRepulsion&&((l=this.points)==null||l.swapFbo(),(c=this.forceMouse)==null||c.run(),(u=this.points)==null||u.updatePosition());const a=t||o&&!(i!=null&&i.blockedByInteraction);return a&&(n&&((d=this.points)==null||d.swapFbo(),(h=this.forceGravity)==null||h.run(),(p=this.points)==null||p.updatePosition()),r&&((g=this.points)==null||g.swapFbo(),(x=this.forceCenter)==null||x.run(),(T=this.points)==null||T.updatePosition()),(S=this.points)==null||S.swapFbo(),(P=this.forceManyBody)==null||P.run(),(I=this.points)==null||I.updatePosition(),this.store.linksTextureSize&&((y=this.points)==null||y.swapFbo(),(v=this.forceLinkIncoming)==null||v.run(),(E=this.points)==null||E.updatePosition(),(R=this.points)==null||R.swapFbo(),(D=this.forceLinkOutgoing)==null||D.run(),(z=this.points)==null||z.updatePosition()),(this.data.pointClusters||this.data.clusterPositions)&&(($=this.points)==null||$.swapFbo(),(F=this.clusters)==null||F.run(),(Q=this.points)==null||Q.updatePosition()),s&&(this.isForceCollisionReady||((X=this.forceCollision)==null||X.create(),(b=this.forceCollision)==null||b.initPrograms(),this.isForceCollisionReady=!0),(N=this.points)==null||N.swapFbo(),(A=this.forceCollision)==null||A.run(),(O=this.points)==null||O.updatePosition()),this.store.alpha+=this.store.addAlpha(this.config.simulationDecay),i!=null&&i.applyMouseRepulsion&&(this.store.alpha=Math.max(this.store.alpha,.1)),this.store.simulationProgress=Math.sqrt(Math.min(1,Qt/this.store.alpha)),(J=(Y=this.config).onSimulationTick)==null||J.call(Y,this.store.alpha,(V=this.store.hoveredPoint)==null?void 0:V.index,(L=this.store.hoveredPoint)==null?void 0:L.position)),(H=this.points)==null||H.gatherTrackers(),a}applyEnableSimulationConfigChange(t){var n,r,s,o,a;if(t.enableSimulation===this.config.enableSimulation)return;if(this.config.enableSimulation){this.ensureSimulationModules(),(n=this.points)==null||n.ensureSimulationResources(),this.markForcesDirty(),this.applyDataUpdates(),this.initPrograms(),this.store.simulationProgress=0,this.store.alpha=1,this.store.isSimulationRunning=!0,(s=(r=this.config).onSimulationStart)==null||s.call(r);return}const i=this.store.isSimulationRunning||this.store.alpha>0||this.store.simulationProgress>0;this.store.isSimulationRunning=!1,this.store.alpha=0,this.store.simulationProgress=0,i&&((a=(o=this.config).onSimulationEnd)==null||a.call(o)),this.destroySimulationModules()}update(t=this.store.alpha){this.updateTextureSizes(),this.applyDataUpdates(),this.initPrograms(),this.store.alpha=t}ensureDevice(t){return this.isReady?!1:(this.ready.then(()=>{this._isDestroyed||t()}).catch(i=>{console.error("Device initialization failed",i)}),!0)}async createDevice(t){return await ZS.createDevice({type:"webgl",adapters:[db],webgl:{antialias:!1},createCanvasContext:{canvas:t,useDevicePixels:this.config.pixelRatio,autoResize:!0,width:void 0,height:void 0}})}composePointPositions(t,i){const n=this.data.pointsNumber??0,r=i&&i.length>=n*2?i:new Float32Array(n*2);for(let s=0;s{const s=this.simulation.device;if(!(this._isDestroyed||!s)){if(this.device=s,!this._isHeadless){const o=this.validateDevice(s);n&&o.setProps({useDevicePixels:this.config.pixelRatio}),this.store.div=t;const a=o.canvas;if(a.parentNode!==this.store.div&&(a.parentNode&&a.parentNode.removeChild(a),this.store.div.appendChild(a)),this.addAttribution(),a.style.width="100%",a.style.height="100%",this.canvas=a,this.updateCanvasTouchAction(),await Promise.race([o.initialized,new Promise(l=>{setTimeout(l,500)})]),this._isDestroyed)return;typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{this._shouldSyncScreenSize=!0,this.requestRender()}),this.resizeObserver.observe(this.canvas))}this._isHeadless||this.initInteractions(),this.points=this.simulation.points,this.points&&(this.points.transition=this.transition),this.points&&(this.points.requestTick=()=>this._isHeadless||!this.config.enableRenderLoop?!1:(this.requestRender(),!0)),this.lines=new $_(s,this.config,this.store,this.graph,this.points),this.store.backgroundColor=We(this.config.backgroundColor),this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor),this.store.setFocusedPointRingColor(this.config.focusedPointRingColor),this.config.focusedPointIndex!==void 0&&this.store.setFocusedPoint(this.config.focusedPointIndex),this.store.setGreyoutPointColor(this.config.pointGreyoutColor),this.store.setOutlinedPointRingColor(this.config.outlinedPointRingColor),this.store.setHighlightedPointSet(this.config.highlightedPointIndices),this.store.setOutlinedPointSet(this.config.outlinedPointIndices),this.store.setHoveredLinkColor(this.config.hoveredLinkColor),this.store.updateLinkHoveringEnabled(this.config),!this._isHeadless&&this.config.showFPSMonitor&&(this.fpsMonitor=new pc(this.canvas,this.store.div)),this.isReady=!0,this.setZoomLevel(this.config.initialZoomLevel??1)}}).catch(s=>{throw this.device=void 0,this.isReady=!1,console.error("Device initialization failed:",s),s});this.ready=r.then(()=>{})}get progress(){return this._isDestroyed?0:this.store.simulationProgress}get isSimulationRunning(){return this._isDestroyed?!1:this.store.isSimulationRunning}get maxPointSize(){return this._isDestroyed?0:this.store.maxPointSize}setConfig(t){if(this._isDestroyed||this.ensureDevice(()=>this.setConfig(t)))return;const i={...this.config};Kx(this.config),Bi(this.config,t),this.preserveInitOnlyFields(i),this.updateStateFromConfig(i)}setConfigPartial(t){if(this._isDestroyed||this.ensureDevice(()=>this.setConfigPartial(t)))return;const i={...this.config};Bi(this.config,t,!0),this.preserveInitOnlyFields(i),this.updateStateFromConfig(i)}setPointPositions(t,i){var r;if(this._isDestroyed||this.ensureDevice(()=>this.setPointPositions(t,i)))return;this.simulation.setPointPositions(t,i);const n=(r=this.points)==null?void 0:r.currentPositionTexture;n&&!n.destroyed&&this.transition.queue(le.Positions),this.isLinksUpdateNeeded=!0,this.isPointColorUpdateNeeded=!0,this.isPointShapeUpdateNeeded=!0,this.isPointImageIndicesUpdateNeeded=!0,this.isPointImageSizesUpdateNeeded=!0}setPointColors(t){this._isDestroyed||this.ensureDevice(()=>this.setPointColors(t))||(this.graph.inputPointColors=t,this.isPointColorUpdateNeeded=!0,this.transition.queue(le.PointColors))}getPointColors(){if(this._isDestroyed)return new Float32Array;if(this.graph.pointColors===void 0||this.graph.pointsNumber===void 0)return new Float32Array;const t=new Float32Array(this.graph.pointsNumber*4);for(let i=0;ithis.setPointSizes(t))||(this.simulation.setPointSizes(t),this.isPointImageSizesUpdateNeeded=!0,this.transition.queue(le.PointSizes))}setPointShapes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointShapes(t))||(this.graph.inputPointShapes=t,this.isPointShapeUpdateNeeded=!0)}setImageData(t){var n;if(this._isDestroyed||this.ensureDevice(()=>this.setImageData(t)))return;const i=this.graph.inputImageData;this.graph.inputImageData=t,((n=this.points)==null?void 0:n.createAtlas())===!1&&(this.graph.inputImageData=i),this.requestRender()}setPointImageIndices(t){this._isDestroyed||this.ensureDevice(()=>this.setPointImageIndices(t))||(this.graph.inputPointImageIndices=t,this.isPointImageIndicesUpdateNeeded=!0)}setPointImageSizes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointImageSizes(t))||(this.graph.inputPointImageSizes=t,this.isPointImageSizesUpdateNeeded=!0)}getPointSizes(){if(this._isDestroyed)return new Float32Array;if(this.graph.pointSizes===void 0||this.graph.pointsNumber===void 0)return new Float32Array;const t=new Float32Array(this.graph.pointsNumber);for(let i=0;ithis.setLinks(t))||(this.simulation.setLinks(t),this.isLinksUpdateNeeded=!0,this.isLinkColorUpdateNeeded=!0,this.isLinkWidthUpdateNeeded=!0,this.isLinkArrowUpdateNeeded=!0,this.isLinkStyleUpdateNeeded=!0)}setLinkColors(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkColors(t))||(this.graph.inputLinkColors=t,this.isLinkColorUpdateNeeded=!0,this.transition.queue(le.LinkColors))}getLinkColors(){return this._isDestroyed?new Float32Array:this.graph.linkColors??new Float32Array}setLinkWidths(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkWidths(t))||(this.graph.inputLinkWidths=t,this.isLinkWidthUpdateNeeded=!0,this.transition.queue(le.LinkWidths))}getLinkWidths(){return this._isDestroyed?new Float32Array:this.graph.linkWidths??new Float32Array}getLinkWidthByIndex(t){var n;if(this._isDestroyed)return;const i=(n=this.graph.linkWidths)==null?void 0:n[t];if(i!==void 0)return this.lines&&this.transition.isActiveFor(le.LinkWidths)?this.lines.getAnimatedWidth(t,this.transition.progress):i}setLinkArrows(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkArrows(t))||(this.graph.linkArrowsBoolean=t,this.isLinkArrowUpdateNeeded=!0)}setLinkStyles(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkStyles(t))||(this.graph.inputLinkStyles=t,this.isLinkStyleUpdateNeeded=!0)}getLinkStyles(){return this._isDestroyed?new Float32Array:this.graph.linkStyles??new Float32Array}setLinkStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkStrength(t))||this.simulation.setLinkStrength(t)}setPointClusters(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusters(t))||this.simulation.setPointClusters(t)}setClusterPositions(t){this._isDestroyed||this.ensureDevice(()=>this.setClusterPositions(t))||this.simulation.setClusterPositions(t)}setPointClusterStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusterStrength(t))||this.simulation.setPointClusterStrength(t)}setPinnedPoints(t){this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoints(t))||(this.simulation.setPinnedPoints(t),this.requestRender())}setPinnedPoint(t,i){this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoint(t,i))||(this.simulation.setPinnedPoint(t,i),this.requestRender())}isPointPinned(t){return this._isDestroyed?!1:this.simulation.isPointPinned(t)}setPointPosition(t,i,n){this.setPointPositionsByIndices([t],[i,n])}setPointPositionsByIndices(t,i){this._isDestroyed||this.ensureDevice(()=>this.setPointPositionsByIndices(t,i))||(this.simulation.setPointPositionsByIndices(t,i),this.markPickingBuffersStale(),this.requestRender())}render(t,i){var d,h,p;if(this._isDestroyed||this.ensureDevice(()=>this.render(t,i)))return;this.graph.update();const{fitViewOnInit:n,fitViewDelay:r,fitViewPadding:s,fitViewDuration:o,fitViewByPointsInRect:a,fitViewByPointIndices:l,initialZoomLevel:c}=this.config;if(!this.graph.pointsNumber&&!this.graph.linksNumber){this.stopFrames(),this._isHeadless||(ye(this.canvas).style("cursor",null),this.device&&(this.device.beginRenderPass({clearColor:this.store.backgroundColor,clearDepth:1,clearStencil:0}).end(),this.device.submit()));return}!this._isHeadless&&this._isFirstRenderAfterInit&&n&&c===void 0&&(this._fitViewOnInitTimeoutID=window.setTimeout(()=>{l?this.fitViewByPointIndices(l,o,s):a?this.setZoomTransformByPointPositions(new Float32Array(this.flatten(a)),o,void 0,s):this.fitView(o,s)},r)),this.transition.setDurationOverride(this._isHeadless?0:i),this.update(t),this.transition.isPendingFor(le.Positions)&&this.store.isSimulationRunning&&this.transition.duration>0&&!this._isFirstRenderAfterInit&&(this.store.isSimulationRunning=!1,(h=(d=this.config).onSimulationPause)==null||h.call(d));const u=(p=this.points)==null?void 0:p.currentPositionTexture;this.transition.isPending&&(!u||u.destroyed)&&this.transition.abort(),this.transition.start(),this._shouldForceHoverDetection=!0,this.requestRender(),this._isFirstRenderAfterInit=!1}zoomToPointByIndex(t,i=700,n=3,r=!0,s=!0){if(this._isDestroyed||this.ensureDevice(()=>this.zoomToPointByIndex(t,i,n,r,s))||!this.device||!this.points||!this.canvasD3Selection)return;const o=this.graph.pointPositions;if(!o||De(o,t))return;const{store:{screenSize:a}}=this,l=we(this.device,this.points.currentPositionFbo);if(t===void 0)return;const c=l[t*4+0],u=l[t*4+1];if(c===void 0||u===void 0)return;const d=this.zoomInstance.getDistanceToPoint([c,u]),h=r?n:Math.max(this.getZoomLevel(),n);if(dthis.setZoomLevel(t,i,n))||this.canvasD3Selection&&(this.zoomInstance.shouldEnableSimulationDuringZoomOverride=n,i===0?this.canvasD3Selection.call(this.zoomInstance.behavior.scaleTo,t):this.canvasD3Selection.transition().duration(i).call(this.zoomInstance.behavior.scaleTo,t))}getZoomLevel(){return this._isDestroyed?0:this.zoomInstance.eventTransform.k}getPointPositions(){return this._isDestroyed?[]:this.simulation.getPointPositions()}getPointPositionsArray(t){return this._isDestroyed?new Float32Array(0):this.simulation.getPointPositionsArray(t)}async getPointPositionsAsync(t){return this._isDestroyed?new Float32Array(0):await this.simulation.getPointPositionsAsync(t)}getPointPositionTexture(){if(!this._isDestroyed)return this.simulation.getPointPositionTexture()}getClusterPositions(t){return this._isDestroyed?[]:this.simulation.getClusterPositions(t)}fitView(t=250,i=.1,n=!0){this._isDestroyed||this.ensureDevice(()=>this.fitView(t,i,n))||this.setZoomTransformByPointPositions(this.getFitViewPositions(),t,void 0,i,n)}fitViewByPointIndices(t,i=250,n=.1,r=!0){if(this._isDestroyed||this.ensureDevice(()=>this.fitViewByPointIndices(t,i,n,r)))return;const s=this.getFitViewPositions(),o=new Float32Array(t.length*2);for(const[a,l]of t.entries())o[a*2]=s[l*2],o[a*2+1]=s[l*2+1];this.setZoomTransformByPointPositions(o,i,void 0,n,r)}fitViewByPointPositions(t,i=250,n=.1,r=!0){this._isDestroyed||this.ensureDevice(()=>this.fitViewByPointPositions(t,i,n,r))||this.setZoomTransformByPointPositions(new Float32Array(t),i,void 0,n,r)}setZoomTransformByPointPositions(t,i=250,n,r=.1,s=!0){var a;if(this._isDestroyed||this.ensureDevice(()=>this.setZoomTransformByPointPositions(t,i,n,r,s)))return;this.zoomInstance.shouldEnableSimulationDuringZoomOverride=s,this.syncScreenSize();const o=this.zoomInstance.getTransform(t,n,r);(a=this.canvasD3Selection)==null||a.transition().ease(tl).duration(i).call(this.zoomInstance.behavior.transform,o)}findPointsInRect(t){if(this._isDestroyed)return[];if(!this.isReady||!this.device||!this.points)return[];const i=this.store.screenSize[1];return this.store.searchArea=[[t[0][0],i-t[1][1]],[t[1][0],i-t[0][1]]],this.points.findPointsInRect()?Ds(we(this.device,this.points.searchFbo),this.graph.pointsNumber):[]}findPointsInPolygon(t){if(this._isDestroyed)return[];if(!this.isReady||!this.device||!this.points)return[];if(t.length<3)return console.warn("Polygon path requires at least 3 points to form a polygon."),[];const i=this.store.screenSize[1],n=t.map(([r,s])=>[r,i-s]);return this.points.updatePolygonPath(n),this.points.findPointsInPolygon()?Ds(we(this.device,this.points.searchFbo),this.graph.pointsNumber):[]}getNeighboringPointIndices(t){return this._isDestroyed?[]:this.graph.getNeighboringPointIndices(t)}getConnectedLinkIndices(t){return this._isDestroyed?[]:this.graph.getConnectedLinkIndices(t)}getConnectedPointIndices(t){return this._isDestroyed?[]:this.graph.getConnectedPointIndices(t)}spaceToScreenPosition(t){return this._isDestroyed?[0,0]:this.zoomInstance.convertSpaceToScreenPosition(t)}screenToSpacePosition(t){return this._isDestroyed?[0,0]:this.zoomInstance.convertScreenToSpacePosition(t)}spaceToScreenRadius(t){return this._isDestroyed?0:this.zoomInstance.convertSpaceToScreenRadius(t)}getPointRadiusByIndex(t){if(this._isDestroyed||this.graph.pointSizes===void 0&&this.graph.pointImageSizes===void 0||!this.graph.isPointIndex(t))return;const i=this.points&&this.transition.isActiveFor(le.PointSizes)?this.points.getAnimatedSize(t,this.transition.progress):void 0;return this.graph.getResolvedPointFootprint(t,i)}trackPointPositionsByIndices(t){if(this._isDestroyed)return;const i=t??[];this.tracker?this.tracker.setIndices(i):this.tracker=this.simulation.trackPoints(i)}getTrackedPointPositionsMap(t){return this._isDestroyed||!this.tracker?new Map:this.tracker.positions(t)}getTrackedPointPositionsArray(){return this._isDestroyed||!this.tracker?[]:this.tracker.positionsArray()}getSampledPointPositionsMap(){return this._isDestroyed||!this.points?new Map:this.points.getSampledPointPositionsMap()}getSampledPoints(){return this._isDestroyed||!this.points?{indices:[],positions:[]}:this.points.getSampledPoints()}getSampledLinkPositionsMap(){return this._isDestroyed||!this.lines?new Map:this.lines.getSampledLinkPositionsMap()}getSampledLinks(){return this._isDestroyed||!this.lines?{indices:[],positions:[],angles:[]}:this.lines.getSampledLinks()}getScaleX(){if(!(this._isDestroyed||!this.points))return this.points.scaleX}getScaleY(){if(!(this._isDestroyed||!this.points))return this.points.scaleY}start(t=1){this._isDestroyed||this.ensureDevice(()=>this.start(t))||this.config.enableSimulation&&this.graph.pointsNumber&&(this.transition.isActiveFor(le.Positions)&&this.transition.end(!0),this.simulation.start(t),this.requestRender())}stop(){this._isDestroyed||this.simulation.stop()}pause(){this._isDestroyed||this.ensureDevice(()=>this.pause())||this.simulation.pause()}unpause(){this._isDestroyed||this.ensureDevice(()=>this.unpause())||this.config.enableSimulation&&(this.store.isSimulationRunning||(this.transition.isActiveFor(le.Positions)&&this.transition.end(!0),this.simulation.unpause(),this.requestRender()))}step(){this._isDestroyed||this.ensureDevice(()=>this.step())||this.config.enableSimulation&&this.store.pointsTextureSize&&(this.runSimulationStep(!0),(this._isHeadless||!this.config.enableRenderLoop)&&this.store.alphathis.setViewTransform(t,i))||(i&&this.store.updateScreenSize(i[0],i[1]),this.zoomInstance.applyEventTransform(jt.translate(t.x,t.y).scale(t.k)),this.markPickingBuffersStale(),this.requestRender())}drawToRenderPass(t,i){var r,s,o,a;if(this._isDestroyed||!this.device||!this.store.pointsTextureSize)return;const n=((i==null?void 0:i.links)??!0)&&this.config.renderLinks!==!1&&!!this.store.linksTextureSize&&!!this.graph.linksNumber&&this.graph.linksNumber>0;if(i!=null&&i.picking){const{alpha:l,linkIndexOffset:c=0}=i.picking;n&&((r=this.lines)==null||r.drawPicking(t,l,c)),(i.points??!0)&&((s=this.points)==null||s.drawPicking(t,l));return}n&&((o=this.lines)==null||o.draw(t)),((i==null?void 0:i.points)??!0)&&((a=this.points)==null||a.draw(t))}setHostHoveredPoint(t){this._isDestroyed||(this.store.hostHoveredPointIndex=t,this.requestRender())}setHostHoveredLink(t){this._isDestroyed||(this.store.hostHoveredLinkIndex=t,this.requestRender())}renderOneFrame(){this._isDestroyed||this.ensureDevice(()=>this.renderOneFrame())||this._isHeadless||!this.store.pointsTextureSize||!this.graph.pointsNumber&&!this.graph.linksNumber||(this.store.alphathis.create())||!this.points||!this.lines)return;const{positionsUpdated:t}=this.simulation.applyDataUpdates();t&&(this.lines.isLinkIndexBufferStale=!0),this.isPointColorUpdateNeeded&&this.points.updateColor(),this.isPointShapeUpdateNeeded&&this.points.updateShape(),this.isPointImageIndicesUpdateNeeded&&this.points.updateImageIndices(),this.isPointImageSizesUpdateNeeded&&this.points.updateImageSizes(),this.isLinksUpdateNeeded&&this.lines.updatePointsBuffer(),this.isLinkColorUpdateNeeded&&this.lines.updateColor(),this.isLinkWidthUpdateNeeded&&this.lines.updateWidth(),this.isLinkArrowUpdateNeeded&&this.lines.updateArrow(),this.isLinkStyleUpdateNeeded&&this.lines.updateStyle(),this.isPointColorUpdateNeeded=!1,this.isPointShapeUpdateNeeded=!1,this.isPointImageIndicesUpdateNeeded=!1,this.isPointImageSizesUpdateNeeded=!1,this.isLinksUpdateNeeded=!1,this.isLinkColorUpdateNeeded=!1,this.isLinkWidthUpdateNeeded=!1,this.isLinkArrowUpdateNeeded=!1,this.isLinkStyleUpdateNeeded=!1,this.requestRender()}flatten(t){return t.flat()}pair(t){const i=Math.floor(t.length/2),n=new Array(i);for(let r=0;r0||this.store.simulationProgress>0;this.store.isSimulationRunning=!1,this.store.alpha=0,this.store.simulationProgress=0,this._shouldForceHoverDetection=!0,i&&((a=(o=this.config).onSimulationEnd)==null||a.call(o)),this.simulation.destroySimulationModules()}ensureDevice(t){return this.isReady?!1:(this.ready.then(()=>{this._isDestroyed||t()}).catch(i=>{console.error("Device initialization failed",i)}),!0)}initInteractions(){const t=this.canvas.clientWidth,i=this.canvas.clientHeight;this.store.updateScreenSize(t,i),this.canvasD3Selection=ye(this.canvas).call(this.dragInstance.behavior).call(this.zoomInstance.behavior).on("pointerenter.cosmos",n=>{n.isPrimary&&(this._isPointerOnCanvas=!0,this._lastMouseX=n.clientX,this._lastMouseY=n.clientY,this.requestRender())}).on("pointermove.cosmos",n=>{var r,s,o,a;if(n.isPrimary){if(this._isPointerOnCanvas=!0,this._lastMouseX=n.clientX,this._lastMouseY=n.clientY,this.currentEvent=n,this.updateMousePosition(n),this.isRightClickMouse=(n.buttons&2)!==0,this._longPressTimerId!==void 0){const l=Math.abs(n.clientX-this._longPressStartX),c=Math.abs(n.clientY-this._longPressStartY);(l>wd||c>wd)&&this.cancelLongPress()}(a=(o=this.config).onMouseMove)==null||a.call(o,(r=this.store.hoveredPoint)==null?void 0:r.index,(s=this.store.hoveredPoint)==null?void 0:s.position,this.currentEvent),this.requestRender()}}).on("pointerleave.cosmos pointercancel.cosmos",n=>{n.isPrimary&&(this.cancelLongPress(),this._isPointerOnCanvas=!1,n.pointerType==="mouse"&&(this.currentEvent=n,this.store.hoveredPoint!==void 0&&this.config.onPointMouseOut&&this.config.onPointMouseOut(n),this.store.hoveredLinkIndex!==void 0&&this.config.onLinkMouseOut&&this.config.onLinkMouseOut(n),this.isRightClickMouse=!1,this.store.hoveredPoint=void 0,this.store.hoveredLinkIndex=void 0,this.lines&&(this.lines.isLinkIndexBufferStale=!0),this.updateCanvasCursor(),this.requestRender()))}).on("pointerdown.cosmos",n=>{n.isPrimary&&(this.currentEvent=n,this._shouldSuppressNextClick=!1,this._lastMouseX=n.clientX,this._lastMouseY=n.clientY,this.updateMousePosition(n),this.findHoveredItem(!0),this.requestRender(),n.pointerType!=="mouse"&&(this._longPressStartX=n.clientX,this._longPressStartY=n.clientY,this.cancelLongPress(),this._longPressTimerId=window.setTimeout(()=>{this._longPressTimerId=void 0,!this._isDestroyed&&(this.findHoveredItem(!0),this.requestRender(),this._shouldSuppressNextClick=!0,this.fireContextMenu(n))},Uv)))}).on("pointerup.cosmos",n=>{n.isPrimary&&(this.cancelLongPress(),this.isRightClickMouse=(n.buttons&2)!==0)}).on("click.cosmos",this.onClick.bind(this)).on("contextmenu.cosmos",this.onContextMenu.bind(this)),ye(document).on(`keydown.cosmos-${this._instanceId}`,n=>{n.code==="Space"&&(this.store.isSpaceKeyPressed=!0)}).on(`keyup.cosmos-${this._instanceId}`,n=>{n.code==="Space"&&(this.store.isSpaceKeyPressed=!1)}),this.zoomInstance.behavior.on("start.detect",n=>{this.currentEvent=n,this.requestRender()}).on("zoom.detect",n=>{!!n.sourceEvent&&this.updateMousePosition(n.sourceEvent),this.currentEvent=n,this.requestRender()}).on("end.detect",n=>{this.currentEvent=n,this._shouldForceHoverDetection=!0,this.requestRender()}),this.dragInstance.behavior.on("start.detect",n=>{this.currentEvent=n,this.updateCanvasCursor(),this.requestRender()}).on("drag.detect",n=>{this.dragInstance.isActive&&this.updateMousePosition(n),this.currentEvent=n,this.requestRender()}).on("end.detect",n=>{this.currentEvent=n,this.updateCanvasCursor(),this.requestRender()}),(!this.config.enableZoom||!this.config.enableDrag)&&this.updateZoomDragBehaviors()}validateDevice(t){const i=t.canvasContext;if(i===null||i.type==="offscreen-canvas")throw new Error("Device must have an HTMLCanvasElement canvas context. OffscreenCanvas and compute-only devices are not supported.");return i}update(t=this.store.alpha){this.simulation.updateTextureSizes(),this.create(),this.initPrograms(),this.store.alpha=t}runSimulationStep(t=!1){if(!this.config.enableSimulation)return;const i=this.isRightClickMouse&&this.config.enableRightClickRepulsion,n=this.zoomInstance.shouldEnableSimulationDuringZoomOverride??this.config.enableSimulationDuringZoom,r=this.zoomInstance.isRunning&&!n;(this.simulation.runSimulationStep(t,{applyMouseRepulsion:i,blockedByInteraction:r})||i)&&this.markPickingBuffersStale()}initPrograms(){this._isDestroyed||!this.points||!this.lines||(this.simulation.initPrograms(),this.lines.initPrograms())}frame(){this._isDestroyed||this._isHeadless||!this.config.enableRenderLoop||this.requestAnimationFrameId||!this.store.pointsTextureSize||!this.graph.pointsNumber&&!this.graph.linksNumber||(this.requestAnimationFrameId=window.requestAnimationFrame(t=>{this.requestAnimationFrameId=0;const{store:{alpha:i,isSimulationRunning:n}}=this;i$n||i>$n}renderFrame(t){this._isDestroyed||this.store.pointsTextureSize&&this.simulation.withExternalDeviceState(()=>this.drawFrame(t))}drawFrame(t){var l,c,u,d,h,p,g,x,T;const i=t??performance.now();(l=this.fpsMonitor)==null||l.begin(),(this._shouldSyncScreenSize||!this.resizeObserver)&&(this._shouldSyncScreenSize=!1,this.syncScreenSize()),this.simulation.collectReadbacks();const n=this.transition.isActiveFor(le.Positions),r=this.transition.isActiveFor(le.PointColors),s=this.transition.isActiveFor(le.PointSizes),o=this.transition.isActiveFor(le.LinkColors),a=this.transition.isActiveFor(le.LinkWidths);if(this.transition.isActive&&(this.transition.step(),n&&((c=this.points)==null||c.interpolatePosition(this.transition.progress),(u=this.points)==null||u.gatherTrackers(),this.markPickingBuffersStale())),(d=this.points)==null||d.setTransitionProgress(this.transition.progress,r,s,n),(h=this.lines)==null||h.setTransitionProgress(this.transition.progress,o,a,n),this.dragInstance.isActive||(this.resolvePendingPick(),this.findHoveredItem()),this.runSimulationStep(!1),this.device){const S=this.store.backgroundColor??[0,0,0,1],P=this.device.beginRenderPass({clearColor:S,clearDepth:1,clearStencil:0});this.drawToRenderPass(P),this.dragInstance.isActive&&((p=this.points)==null||p.swapFbo(),(g=this.points)==null||g.drag(),(x=this.points)==null||x.gatherTrackers(),this.markPickingBuffersStale()),P.end(),this.device.submit()}this.simulation.issueReadbacks(),(T=this.fpsMonitor)==null||T.end(i),this.currentEvent=void 0}stopFrames(){this.requestAnimationFrameId&&(window.cancelAnimationFrame(this.requestAnimationFrameId),this.requestAnimationFrameId=0)}end(){this.simulation.end(),this._shouldForceHoverDetection=!0}onClick(t){var i,n,r,s,o,a,l,c,u,d;if(this._shouldSuppressNextClick){this._shouldSuppressNextClick=!1;return}(s=(r=this.config).onClick)==null||s.call(r,(i=this.store.hoveredPoint)==null?void 0:i.index,(n=this.store.hoveredPoint)==null?void 0:n.position,t),this.store.hoveredPoint?(a=(o=this.config).onPointClick)==null||a.call(o,this.store.hoveredPoint.index,this.store.hoveredPoint.position,t):this.store.hoveredLinkIndex!==void 0?(c=(l=this.config).onLinkClick)==null||c.call(l,this.store.hoveredLinkIndex,t):(d=(u=this.config).onBackgroundClick)==null||d.call(u,t)}updateMousePosition(t){if(!t)return;const i=t.offsetX??t.x,n=t.offsetY??t.y;i===void 0||n===void 0||(this.store.mousePosition=this.zoomInstance.convertScreenToSpacePosition([i,n]),this.store.screenMousePosition=[i,this.store.screenSize[1]-n])}onContextMenu(t){t.preventDefault(),this.cancelLongPress(),this._shouldSuppressNextClick=!0,this.fireContextMenu(t)}cancelLongPress(){this._longPressTimerId!==void 0&&(window.clearTimeout(this._longPressTimerId),this._longPressTimerId=void 0)}fireContextMenu(t){var i,n,r,s,o,a,l,c,u,d;(s=(r=this.config).onContextMenu)==null||s.call(r,(i=this.store.hoveredPoint)==null?void 0:i.index,(n=this.store.hoveredPoint)==null?void 0:n.position,t),this.store.hoveredPoint?(a=(o=this.config).onPointContextMenu)==null||a.call(o,this.store.hoveredPoint.index,this.store.hoveredPoint.position,t):this.store.hoveredLinkIndex!==void 0?(c=(l=this.config).onLinkContextMenu)==null||c.call(l,this.store.hoveredLinkIndex,t):(d=(u=this.config).onBackgroundContextMenu)==null||d.call(u,t)}syncScreenSize(t=!1){var o,a,l,c;if(this._isHeadless||!this.canvas||this._isDestroyed)return;const i=this.canvas.clientWidth,n=this.canvas.clientHeight,[r,s]=this.store.screenSize;if(t||r!==i||s!==n){const{k:u}=this.zoomInstance.eventTransform,d=this.zoomInstance.convertScreenToSpacePosition([r/2,s/2]);this.store.updateScreenSize(i,n),(o=this.canvasD3Selection)==null||o.call(this.zoomInstance.behavior.transform,this.zoomInstance.getTransform(d,u)),(a=this.points)==null||a.updateSampledPointsGrid(),(l=this.lines)==null||l.updateSampledLinksGrid(),this.store.isLinkHoveringEnabled&&((c=this.lines)==null||c.updateLinkIndexFbo()),this.markPickingBuffersStale()}}updateZoomDragBehaviors(){var t,i,n,r;this._isHeadless||(this.config.enableDrag?(t=this.canvasD3Selection)==null||t.call(this.dragInstance.behavior):(i=this.canvasD3Selection)==null||i.call(this.dragInstance.behavior).on(".drag",null),this.config.enableZoom?(n=this.canvasD3Selection)==null||n.call(this.zoomInstance.behavior):(r=this.canvasD3Selection)==null||r.call(this.zoomInstance.behavior).on("wheel.zoom",null),this.updateCanvasTouchAction())}updateCanvasTouchAction(){this.canvas.style.touchAction=this.config.enableDrag||this.config.enableZoom?"none":""}findHoveredItem(t=!1){var o,a,l,c;if(this._isDestroyed||!t&&!this._isPointerOnCanvas||this.transition.isActiveFor(le.PointSizes))return;if(!t&&this._findHoveredItemExecutionCount$n||n>$n;if(!t&&!r&&!this._shouldForceHoverDetection)return;this.updatePickingBufferStaleness();const s=!!this.graph.linksNumber&&this.store.isLinkHoveringEnabled;if(t){(o=this.points)==null||o.discardPendingPick(),(a=this.lines)==null||a.discardPendingPick();const u=((l=this.points)==null?void 0:l.pickPointSync())??null;let d;!u&&s&&(d=((c=this.lines)==null?void 0:c.pickLinkSync())??null),this.processHoverResult(u,d)}else{const u=this.points?this.points.requestPickPoint():!0,d=s&&this.lines?this.lines.requestPickLink():!0;if(!u||!d)return}this._findHoveredItemExecutionCount=0,this._lastCheckedMouseX=this._lastMouseX,this._lastCheckedMouseY=this._lastMouseY,this._shouldForceHoverDetection=!1}updatePickingBufferStaleness(){const t=this.store.transformationMatrix4x4;L_(this._lastPickingMatrix,t)||(this._lastPickingMatrix=Array.from(t),this.markPickingBuffersStale())}markPickingBuffersStale(){this.points&&(this.points.isPickingBufferStale=!0),this.lines&&(this.lines.isLinkIndexBufferStale=!0)}resolvePendingPick(){var n,r;const t=(n=this.points)==null?void 0:n.takePickResult(),i=(r=this.lines)==null?void 0:r.takePickLinkResult();t===void 0&&i===void 0||this._isPointerOnCanvas&&this.processHoverResult(t,i)}processHoverResult(t,i){var s,o,a,l,c,u,d,h,p,g;if(this._isDestroyed)return;const n=t===void 0?{mouseover:!1,mouseout:!1}:this.applyPickedPoint(t);let r={mouseover:!1,mouseout:!1};if(this.graph.linksNumber&&this.store.isLinkHoveringEnabled?this.store.hoveredPoint?r=this.applyPickedLink(null):i!==void 0&&(r=this.applyPickedLink(i)):this.store.hoveredLinkIndex!==void 0&&(r=this.applyPickedLink(null)),n.mouseout&&((o=(s=this.config).onPointMouseOut)==null||o.call(s,this.currentEvent)),r.mouseout&&((l=(a=this.config).onLinkMouseOut)==null||l.call(a,this.currentEvent)),n.mouseover&&this.store.hoveredPoint){const x=this.store.hoveredPoint.index;(h=(d=this.config).onPointMouseOver)==null||h.call(d,this.store.hoveredPoint.index,this.store.hoveredPoint.position,this.currentEvent,((c=this.store.highlightedPointSet)==null?void 0:c.has(x))??!1,((u=this.store.outlinedPointSet)==null?void 0:u.has(x))??!1)}r.mouseover&&this.store.hoveredLinkIndex!==void 0&&((g=(p=this.config).onLinkMouseOver)==null||g.call(p,this.store.hoveredLinkIndex)),this.updateCanvasCursor()}applyPickedPoint(t){let i=!1,n=!1;return t&&t.index>=(this.graph.pointsNumber??0)&&(t=null),t?((this.store.hoveredPoint===void 0||this.store.hoveredPoint.index!==t.index)&&(i=!0),this.store.hoveredPoint=t):(this.store.hoveredPoint&&(n=!0),this.store.hoveredPoint=void 0),{mouseover:i,mouseout:n}}applyPickedLink(t){let i=!1,n=!1;return t!==null&&t>=(this.graph.linksNumber??0)&&(t=null),t!==null?(this.store.hoveredLinkIndex!==t&&(i=!0),this.store.hoveredLinkIndex=t):(this.store.hoveredLinkIndex!==void 0&&(n=!0),this.store.hoveredLinkIndex=void 0),(i||n)&&this.lines&&(this.lines.isLinkIndexBufferStale=!0),{mouseover:i,mouseout:n}}updateCanvasCursor(){const{hoveredPointCursor:t,hoveredLinkCursor:i}=this.config;this.dragInstance.isActive?ye(this.canvas).style("cursor","grabbing"):this.store.hoveredPoint?!this.config.enableDrag||this.store.isSpaceKeyPressed?ye(this.canvas).style("cursor",t):ye(this.canvas).style("cursor","grab"):this.store.isLinkHoveringEnabled&&this.store.hoveredLinkIndex!==void 0?ye(this.canvas).style("cursor",i):ye(this.canvas).style("cursor",null)}addAttribution(){var t;this.config.attribution&&(this.attributionDivElement=document.createElement("div"),this.attributionDivElement.style.cssText=` + user-select: none; + position: absolute; + bottom: 0; + right: 0; + color: var(--cosmosgl-attribution-color); + margin: 0 0.6rem 0.6rem 0; + font-size: 0.7rem; + font-family: inherit; + `,this.attributionDivElement.innerHTML=cc(this.config.attribution,{ALLOWED_TAGS:["a","b","i","em","strong","span","div","p","br","img"],ALLOWED_ATTR:["href","target","class","id","style","src","alt","title"]}),(t=this.store.div)==null||t.appendChild(this.attributionDivElement))}}K.EDGE_RAMP_PX=Us,K.EXIT_DEFAULT_COLOR_CHANNEL=Xn,K.EXIT_DEFAULT_SIZE=Os,K.Graph=zv,K.GraphSimulation=Rd,K.LinkStyle=Ns,K.POINT_RING_SCALE=fc,K.PointShape=Ms,K.TransitionEasing=Bs,K.clamp=lc,K.defaultConfigValues=Ze,K.extractIndicesFromPixels=Ds,K.focusedPointRingOpacity=hc,K.generateRandomId=ac,K.getMaxPointSize=Fs,K.getRgbaColor=We,K.hoveredPointRingOpacity=dc,K.isAClassInstance=sc,K.isArray=ks,K.isFunction=nc,K.isNumber=ft,K.isObject=rc,K.isPlainObject=$x,K.isPointAbsent=De,K.readPixels=we,K.rgbToBrightness=oc,K.sanitizeHtml=cc,Object.defineProperty(K,Symbol.toStringTag,{value:"Module"})}); +//# sourceMappingURL=index.min.js.map diff --git a/tools/memorygraph/build_graph.py b/tools/memorygraph/build_graph.py new file mode 100644 index 0000000..8f94add --- /dev/null +++ b/tools/memorygraph/build_graph.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +"""Build graph.json (or a self-contained snapshot report) from the phosphor +memory SQLite store. Standalone; no phosphor imports. + +Usage: + python build_graph.py [db_path] # writes graph.json next to view.html + python build_graph.py [db_path] --report FILE # writes a portable one-file report + python build_graph.py [db_path] --serve # graph.json + live viewer over HTTP +""" +import argparse +import json +import os +import sqlite3 +import sys +from collections import Counter +from datetime import datetime, timezone + +HERE = os.path.dirname(os.path.abspath(__file__)) +VIEW_HTML = os.path.join(HERE, "view.html") + + +def find_db(): + home = os.path.expanduser("~") + rel = os.path.join(".phosphor", "memory", ".phosphor-index", "memory.db") + candidates = [] + # walk up from the current directory for a project vault + d = os.getcwd() + while True: + candidates.append(os.path.join(d, rel)) + parent = os.path.dirname(d) + if parent == d: + break + d = parent + candidates += [ + os.path.join(home, ".local", "share", "phosphor", rel), + os.path.join(home, ".phosphor", rel), + os.path.join(home, ".config", "phosphor", rel), + ] + for c in candidates: + if os.path.exists(c): + return c + raise SystemExit("no memory.db found; pass the path as an argument") + + +def build(db): + con = sqlite3.connect(f"file:{db}?mode=ro", uri=True) + con.row_factory = sqlite3.Row + + nodes = [] + ids = set() + edges = [] + + # canonical tags per entry, for clustering + tags_of = {} + for r in con.execute( + "SELECT et.entry_id AS e, t.term AS term FROM entry_tags et " + "JOIN tags t ON t.id = et.tag_id" + ): + tags_of.setdefault(r["e"], []).append(r["term"]) + + for r in con.execute( + "SELECT id, type, status, thread, trust, recall_count, hot_score, " + "created_ts, updated_ts, supersedes, from_decision, summary, body FROM entries" + ): + if r["id"] in ids: + continue + ids.add(r["id"]) + nodes.append( + { + "id": r["id"], + "type": r["type"] or "unknown", + "status": r["status"] or "active", + "thread": r["thread"] or "", + "tags": tags_of.get(r["id"], []), + "summary": (r["summary"] or "")[:120], + "body": (r["body"] or "")[:4000], + "trust": r["trust"] or 0, + "recall": r["recall_count"] or 0, + "hot": r["hot_score"] or 0, + "created": r["created_ts"] or "", + "updated": r["updated_ts"] or "", + } + ) + if r["supersedes"]: + edges.append({"source": r["id"], "target": r["supersedes"], "kind": "supersedes"}) + if r["from_decision"]: + edges.append({"source": r["id"], "target": r["from_decision"], "kind": "decision"}) + + threads = Counter(n["thread"] for n in nodes if n["thread"]) + # tag nodes: entries cluster around their first tag, threads around their own node + tag_counts = Counter(t for n in nodes for t in n["tags"]) + for t, c in tag_counts.most_common(12): + tid = f"tag:{t}" + if tid not in ids: + ids.add(tid) + nodes.append( + { + "id": tid, + "type": "tag", + "status": "group", + "thread": "", + "tags": [], + "summary": t, + "trust": 0, + "recall": c, + "hot": c, + "created": "", + "updated": "", + } + ) + + for t, c in threads.items(): + tid = f"thread:{t}" + if tid not in ids: + ids.add(tid) + nodes.append( + { + "id": tid, + "type": "thread", + "status": "group", + "thread": t, + "tags": [], + "summary": t, + "trust": 0, + "recall": c, + "hot": c, + "created": "", + "updated": "", + } + ) + for n in nodes: + if n["type"] == "entry" or (n["type"] not in ("thread", "tag")): + if n["thread"] == t: + edges.append({"source": n["id"], "target": tid, "kind": "thread"}) + + for n in nodes: + if n["type"] in ("thread", "tag"): + continue + for t in n["tags"][:3]: + tid = f"tag:{t}" + if tid in ids: + edges.append({"source": n["id"], "target": tid, "kind": "tag"}) + + # verdict tallies for the VERDICTS panel + verdicts = Counter(n["type"] for n in nodes if n["type"] != "thread") + + # arrivals: created_ts bucketed by day for the ARRIVALS dot grid + arrivals = Counter( + (n["created"] or "")[:10] for n in nodes if n["type"] != "thread" and n["created"] + ) + + return { + "generated": datetime.now(timezone.utc).isoformat(), + "db": db, + "nodes": nodes, + "edges": edges, + "verdicts": dict(verdicts), + "arrivals": dict(arrivals), + } + + +def write_report(graph, path): + """Freeze the current graph into a single self-contained HTML report.""" + with open(VIEW_HTML, encoding="utf-8") as f: + html = f.read() + payload = json.dumps(graph).replace("window.__PHOSPHOR_SNAPSHOT__ = true;\n" + "window.__PHOSPHOR_GRAPH__ = " + payload + ";\n" + ) + if "" not in html: + raise SystemExit("view.html has no ; cannot embed snapshot payload") + html = html.replace("", head, 1) + with open(path, "w", encoding="utf-8") as f: + f.write(html) + print(f"wrote snapshot report: {path} " + f"({len(graph['nodes'])} nodes, {len(graph['edges'])} edges)") + + +def serve(): + """Serve the live viewer; the page polls graph.json and self-refreshes.""" + import http.server + import socketserver + + class Handler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=HERE, **kwargs) + + def end_headers(self): + # never cache graph.json so the poller sees fresh data + self.send_header("Cache-Control", "no-store") + super().end_headers() + + with socketserver.TCPServer(("127.0.0.1", 8642), Handler) as httpd: + print("serving live viewer at http://127.0.0.1:8642/view.html (ctrl-c to stop)") + httpd.serve_forever() + + +def main(): + ap = argparse.ArgumentParser(description="phosphor memory graph builder") + ap.add_argument("db", nargs="?", help="path to memory.db (auto-discovered if omitted)") + ap.add_argument("--report", metavar="FILE", + help="write a portable single-file snapshot report instead of graph.json") + ap.add_argument("--serve", action="store_true", + help="rebuild graph.json and serve the live viewer on 127.0.0.1:8642") + args = ap.parse_args() + + db = args.db or find_db() + graph = build(db) + + if args.report: + write_report(graph, args.report) + return + + out = os.path.join(HERE, "graph.json") + with open(out, "w") as f: + json.dump(graph, f, indent=1) + print(f"wrote graph.json: {len(graph['nodes'])} nodes, {len(graph['edges'])} edges") + + if args.serve: + serve() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tools/memorygraph/view.html b/tools/memorygraph/view.html new file mode 100644 index 0000000..8c6dcbd --- /dev/null +++ b/tools/memorygraph/view.html @@ -0,0 +1,950 @@ + + + + + + + +MEMORY AURORA + + + + +
+
+
+
+
+
+
+
+
+
┌ MEMORY · CONSTELLATION ┐
+
SYS.TIME --:--:--
+
+
+ + +
+
+
+

THREADS

+

ARRIVALS

+

VERDICTS

+

STREAM

+
+
+
+ + + ✕ + ← back +
+

+
+
+
Trust
+
Recall
+
Created
+
Updated
+
+
+
+
+
    +
    +
    + + + \ No newline at end of file From df9ea88660e7fc13194b5a544ca2790c0dae3a53 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Tue, 20 Oct 2026 00:08:58 -0700 Subject: [PATCH 2/9] feat: serve the memory graph viewer from the phosphor binary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embed the memorygraph viewer page and port the graph builder to Go, served live from the local API service so the page polls fresh vault data as memory grows. ஃ Generated with Phosphor --- internal/platform/httpapi/service.go | 11 + internal/server/memorygraph.go | 311 +++++++++ internal/server/memorygraph/view.html | 950 ++++++++++++++++++++++++++ internal/server/memorygraph_embed.go | 6 + internal/server/memorygraph_test.go | 129 ++++ tools/memorygraph/README.md | 10 +- 6 files changed, 1414 insertions(+), 3 deletions(-) create mode 100644 internal/server/memorygraph.go create mode 100644 internal/server/memorygraph/view.html create mode 100644 internal/server/memorygraph_embed.go create mode 100644 internal/server/memorygraph_test.go diff --git a/internal/platform/httpapi/service.go b/internal/platform/httpapi/service.go index b233b05..98b4218 100644 --- a/internal/platform/httpapi/service.go +++ b/internal/platform/httpapi/service.go @@ -271,6 +271,17 @@ func (s *Service) Start(ctx context.Context) error { // Register Mermaid rendering endpoint s.echoSrv.GET("/service/mermaid/render", server.HandleMermaidRender) server.SetMermaidServiceEnabled(true, openaiCfg.port) + + // Register memory graph viewer endpoints. The viewer page and the + // graph data live side by side so the page's relative graph.json + // polling resolves to the live endpoint. + s.echoSrv.GET("/service/memorygraph/view.html", server.HandleMemoryGraphView) + s.echoSrv.GET("/service/memorygraph/graph.json", server.HandleMemoryGraphData) + if len(wsList) > 0 { + server.SetMemoryGraphWorkspace(wsList[0].Path) + } else if s.workspace != "" { + server.SetMemoryGraphWorkspace(s.workspace) + } // Create a DB connection and set it on the server for mermaid diagram lookups. dataDir := "" if s.cfgStore != nil { diff --git a/internal/server/memorygraph.go b/internal/server/memorygraph.go new file mode 100644 index 0000000..67df572 --- /dev/null +++ b/internal/server/memorygraph.go @@ -0,0 +1,311 @@ +package server + +import ( + "context" + "database/sql" + "net/http" + "os" + "path/filepath" + "sort" + "time" + "unicode/utf8" + + "github.com/hackafterdark/phosphor/internal/home" + "github.com/hackafterdark/phosphor/internal/memory" + "github.com/labstack/echo/v5" +) + +// memoryGraphWorkspace is the workspace directory used to discover the +// project memory vault. Empty falls back to the process working directory. +var memoryGraphWorkspace string + +// SetMemoryGraphWorkspace sets the workspace used to discover the memory +// vault for the graph viewer endpoints. +func SetMemoryGraphWorkspace(dir string) { + memoryGraphWorkspace = dir +} + +// memoryGraphDBPath locates the memory index database: project vaults found +// by walking up from the workspace directory, then the global vault. +func memoryGraphDBPath() string { + start := memoryGraphWorkspace + if start == "" { + if cwd, err := os.Getwd(); err == nil { + start = cwd + } + } + rel := filepath.Join( + memory.PhosphorDirName, memory.VaultDirName, + memory.IndexDirName, memory.IndexFileName, + ) + if start != "" { + for d := start; ; { + candidate := filepath.Join(d, rel) + if _, err := os.Stat(candidate); err == nil { + return candidate + } + parent := filepath.Dir(d) + if parent == d { + break + } + d = parent + } + } + candidate := filepath.Join( + home.Dir(), memory.PhosphorDirName, memory.VaultDirName, + memory.IndexDirName, memory.IndexFileName, + ) + if _, err := os.Stat(candidate); err == nil { + return candidate + } + return "" +} + +// HandleMemoryGraphView serves the embedded memory graph viewer page. +func HandleMemoryGraphView(ctx *echo.Context) error { + return ctx.HTML(http.StatusOK, memoryGraphHTML) +} + +// HandleMemoryGraphData builds the graph for the current memory vault on +// every request, so the viewer's polling sees fresh entries. +func HandleMemoryGraphData(ctx *echo.Context) error { + dbPath := memoryGraphDBPath() + if dbPath == "" { + return ctx.String(http.StatusNotFound, "No memory vault found") + } + graph, err := buildMemoryGraph(ctx.Request().Context(), dbPath) + if err != nil { + return ctx.String(http.StatusInternalServerError, "Failed to build memory graph: "+err.Error()) + } + return ctx.JSON(http.StatusOK, graph) +} + +type graphNode struct { + ID string `json:"id"` + Type string `json:"type"` + Status string `json:"status"` + Thread string `json:"thread"` + Tags []string `json:"tags"` + Summary string `json:"summary"` + Body string `json:"body,omitempty"` + Trust float64 `json:"trust"` + Recall int64 `json:"recall"` + Hot float64 `json:"hot"` + Created string `json:"created"` + Updated string `json:"updated"` +} + +type graphEdge struct { + Source string `json:"source"` + Target string `json:"target"` + Kind string `json:"kind"` +} + +type memoryGraph struct { + Generated string `json:"generated"` + DB string `json:"db"` + Nodes []*graphNode `json:"nodes"` + Edges []graphEdge `json:"edges"` + Verdicts map[string]int64 `json:"verdicts"` + Arrivals map[string]int64 `json:"arrivals"` +} + +// maxTagHubs bounds the number of tag hub nodes drawn, matching the +// reference builder. +const maxTagHubs = 12 + +// buildMemoryGraph reads the vault index read-only and clusters entries by +// thread and tag, mirroring the tools/memorygraph builder. +func buildMemoryGraph(ctx context.Context, dbPath string) (*memoryGraph, error) { + db, err := sql.Open("sqlite", "file:"+filepath.ToSlash(dbPath)+"?mode=ro") + if err != nil { + return nil, err + } + defer db.Close() + + tagsOf := map[string][]string{} + rows, err := db.QueryContext(ctx, + "SELECT et.entry_id, t.term FROM entry_tags et JOIN tags t ON t.id = et.tag_id") + if err != nil { + return nil, err + } + for rows.Next() { + var e, term string + if err := rows.Scan(&e, &term); err != nil { + rows.Close() + return nil, err + } + tagsOf[e] = append(tagsOf[e], term) + } + rows.Close() + if err := rows.Err(); err != nil { + return nil, err + } + + graph := &memoryGraph{ + Generated: time.Now().UTC().Format(time.RFC3339), + DB: dbPath, + Nodes: []*graphNode{}, + Edges: []graphEdge{}, + Verdicts: map[string]int64{}, + Arrivals: map[string]int64{}, + } + seen := map[string]bool{} + + entryRows, err := db.QueryContext(ctx, + "SELECT id, type, status, thread, trust, recall_count, hot_score, "+ + "created_ts, updated_ts, supersedes, from_decision, summary, body FROM entries") + if err != nil { + return nil, err + } + for entryRows.Next() { + var ( + id, typ, status, thread, summary, body string + trust, hot float64 + recall int64 + created, updated sql.NullString + supersedes, fromDecision sql.NullString + ) + if err := entryRows.Scan( + &id, &typ, &status, &thread, &trust, &recall, &hot, + &created, &updated, &supersedes, &fromDecision, &summary, &body, + ); err != nil { + entryRows.Close() + return nil, err + } + if seen[id] { + continue + } + seen[id] = true + if typ == "" { + typ = "unknown" + } + if status == "" { + status = "active" + } + tags := tagsOf[id] + if tags == nil { + tags = []string{} + } + graph.Nodes = append(graph.Nodes, &graphNode{ + ID: id, + Type: typ, + Status: status, + Thread: thread, + Tags: tags, + Summary: truncateRunes(summary, 120), + Body: truncateRunes(body, 4000), + Trust: trust, + Recall: recall, + Hot: hot, + Created: created.String, + Updated: updated.String, + }) + if supersedes.String != "" { + graph.Edges = append(graph.Edges, graphEdge{Source: id, Target: supersedes.String, Kind: "supersedes"}) + } + if fromDecision.String != "" { + graph.Edges = append(graph.Edges, graphEdge{Source: id, Target: fromDecision.String, Kind: "decision"}) + } + } + entryRows.Close() + if err := entryRows.Err(); err != nil { + return nil, err + } + + threads := map[string]int64{} + tagCounts := map[string]int64{} + tagOrder := []string{} + for _, n := range graph.Nodes { + if n.Thread != "" { + threads[n.Thread]++ + } + for _, t := range n.Tags { + if _, ok := tagCounts[t]; !ok { + tagOrder = append(tagOrder, t) + } + tagCounts[t]++ + } + } + + // Tag hub nodes: the twelve most common tags, highest count first. + sort.SliceStable(tagOrder, func(i, j int) bool { + return tagCounts[tagOrder[i]] > tagCounts[tagOrder[j]] + }) + for i, t := range tagOrder { + if i >= maxTagHubs { + break + } + tid := "tag:" + t + if seen[tid] { + continue + } + seen[tid] = true + graph.Nodes = append(graph.Nodes, &graphNode{ + ID: tid, Type: "tag", Status: "group", Tags: []string{}, + Summary: t, Recall: tagCounts[t], Hot: float64(tagCounts[t]), + }) + } + + // Thread hub nodes, attached once per distinct thread. + for _, t := range threadOrder(graph.Nodes) { + tid := "thread:" + t + if seen[tid] { + continue + } + seen[tid] = true + graph.Nodes = append(graph.Nodes, &graphNode{ + ID: tid, Type: "thread", Status: "group", Thread: t, + Tags: []string{}, Summary: t, Recall: threads[t], Hot: float64(threads[t]), + }) + } + + for _, n := range graph.Nodes { + if n.Type == "tag" || n.Type == "thread" { + continue + } + if n.Thread != "" { + graph.Edges = append(graph.Edges, graphEdge{Source: n.ID, Target: "thread:" + n.Thread, Kind: "thread"}) + } + for i, t := range n.Tags { + if i >= 3 { + break + } + tid := "tag:" + t + if seen[tid] { + graph.Edges = append(graph.Edges, graphEdge{Source: n.ID, Target: tid, Kind: "tag"}) + } + } + } + + for _, n := range graph.Nodes { + if n.Type == "thread" { + continue + } + graph.Verdicts[n.Type]++ + if n.Created != "" { + graph.Arrivals[truncateRunes(n.Created, 10)]++ + } + } + return graph, nil +} + +// threadOrder returns the distinct threads in first-appearance order. +func threadOrder(nodes []*graphNode) []string { + seen := map[string]bool{} + var out []string + for _, n := range nodes { + if n.Thread != "" && !seen[n.Thread] { + seen[n.Thread] = true + out = append(out, n.Thread) + } + } + return out +} + +func truncateRunes(s string, n int) string { + if utf8.RuneCountInString(s) <= n { + return s + } + return string([]rune(s)[:n]) +} diff --git a/internal/server/memorygraph/view.html b/internal/server/memorygraph/view.html new file mode 100644 index 0000000..8c6dcbd --- /dev/null +++ b/internal/server/memorygraph/view.html @@ -0,0 +1,950 @@ + + + + + + + +MEMORY AURORA + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    ┌ MEMORY · CONSTELLATION ┐
    +
    SYS.TIME --:--:--
    +
    +
    + + +
    +
    +
    +

    THREADS

    +

    ARRIVALS

    +

    VERDICTS

    +

    STREAM

    +
    +
    +
    + + + ✕ + ← back +
    +

    +
    +
    +
    Trust
    +
    Recall
    +
    Created
    +
    Updated
    +
    +
    +
    +
    +
      +
      +
      + + + \ No newline at end of file diff --git a/internal/server/memorygraph_embed.go b/internal/server/memorygraph_embed.go new file mode 100644 index 0000000..e0963d5 --- /dev/null +++ b/internal/server/memorygraph_embed.go @@ -0,0 +1,6 @@ +package server + +import _ "embed" + +//go:embed memorygraph/view.html +var memoryGraphHTML string \ No newline at end of file diff --git a/internal/server/memorygraph_test.go b/internal/server/memorygraph_test.go new file mode 100644 index 0000000..e1f2e37 --- /dev/null +++ b/internal/server/memorygraph_test.go @@ -0,0 +1,129 @@ +package server + +import ( + "context" + "database/sql" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/labstack/echo/v5" + "github.com/stretchr/testify/require" +) + +func seedMemoryDB(t *testing.T) string { + t.Helper() + dbPath := filepath.Join(t.TempDir(), "memory.db") + db, err := sql.Open("sqlite", dbPath) + require.NoError(t, err) + t.Cleanup(func() { db.Close() }) + + schema := []string{ + `CREATE TABLE entries ( + id TEXT PRIMARY KEY, type TEXT, status TEXT, thread TEXT, + trust REAL, recall_count INTEGER, hot_score REAL, + created_ts TEXT, updated_ts TEXT, supersedes TEXT, from_decision TEXT, + summary TEXT, body TEXT + )`, + `CREATE TABLE tags (id INTEGER PRIMARY KEY AUTOINCREMENT, term TEXT UNIQUE)`, + `CREATE TABLE entry_tags (entry_id TEXT, tag_id INTEGER, PRIMARY KEY (entry_id, tag_id))`, + } + for _, stmt := range schema { + _, err := db.Exec(stmt) + require.NoError(t, err) + } + + _, err = db.Exec( + `INSERT INTO entries (id, type, status, thread, trust, recall_count, hot_score, ` + + `created_ts, updated_ts, supersedes, from_decision, summary, body) VALUES ` + + `('e1', 'decision', 'active', 'alpha', 0.8, 3, 12.5, '2026-10-01T00:00:00Z', '2026-10-01T00:00:00Z', '', '', 'first', 'body one'),` + + `('e2', 'decision', 'active', 'alpha', 0.5, 0, 0.0, '2026-10-02T00:00:00Z', '2026-10-02T00:00:00Z', 'e1', '', 'second', 'body two'),` + + `('e3', 'reference', 'active', '', 0.5, 1, 2.0, '2026-10-02T00:00:00Z', '2026-10-02T00:00:00Z', '', 'e1', 'third', 'body three')`) + require.NoError(t, err) + _, err = db.Exec(`INSERT INTO tags (id, term) VALUES (1, 'x'), (2, 'y'), (3, 'z')`) + require.NoError(t, err) + _, err = db.Exec(`INSERT INTO entry_tags (entry_id, tag_id) VALUES ('e1', 1), ('e1', 2), ('e3', 3)`) + require.NoError(t, err) + return dbPath +} + +func TestBuildMemoryGraph(t *testing.T) { + t.Parallel() + dbPath := seedMemoryDB(t) + g, err := buildMemoryGraph(context.Background(), dbPath) + require.NoError(t, err) + + byID := map[string]*graphNode{} + for _, n := range g.Nodes { + byID[n.ID] = n + } + // 3 entries + 3 tag hubs + 1 thread hub. + require.Len(t, g.Nodes, 7) + require.Contains(t, byID, "tag:x") + require.Contains(t, byID, "thread:alpha") + require.Equal(t, int64(2), byID["thread:alpha"].Recall) + + kinds := map[string]int{} + for _, e := range g.Edges { + kinds[e.Kind]++ + } + require.Equal(t, 1, kinds["supersedes"]) + require.Equal(t, 1, kinds["decision"]) + require.Equal(t, 2, kinds["thread"]) + require.Equal(t, 3, kinds["tag"]) + + require.Equal(t, int64(2), g.Verdicts["decision"]) + require.Equal(t, int64(1), g.Verdicts["reference"]) + require.Equal(t, int64(3), g.Verdicts["tag"]) + require.Equal(t, int64(2), g.Arrivals["2026-10-02"]) +} + +func TestMemoryGraphDBPathDiscovery(t *testing.T) { + ws := t.TempDir() + vault := filepath.Join(ws, ".phosphor", "memory", ".phosphor-index") + require.NoError(t, os.MkdirAll(vault, 0o755)) + dbPath := filepath.Join(vault, "memory.db") + fd, err := os.Create(dbPath) + require.NoError(t, err) + require.NoError(t, fd.Close()) + + orig := memoryGraphWorkspace + t.Cleanup(func() { memoryGraphWorkspace = orig }) + memoryGraphWorkspace = ws + require.Equal(t, dbPath, memoryGraphDBPath()) +} + +func TestMemoryGraphHandlers(t *testing.T) { + ws := t.TempDir() + vault := filepath.Join(ws, ".phosphor", "memory", ".phosphor-index") + require.NoError(t, os.MkdirAll(vault, 0o755)) + orig := memoryGraphWorkspace + t.Cleanup(func() { memoryGraphWorkspace = orig }) + memoryGraphWorkspace = ws + + e := echo.New() + + seed := seedMemoryDB(t) + data, err := os.ReadFile(seed) + require.NoError(t, err) + require.NoError(t, os.WriteFile(filepath.Join(vault, "memory.db"), data, 0o644)) + + req := httptest.NewRequest(http.MethodGet, "/service/memorygraph/graph.json", nil) + rec := httptest.NewRecorder() + ctx := e.NewContext(req, rec) + require.NoError(t, HandleMemoryGraphData(ctx)) + require.Equal(t, http.StatusOK, rec.Code) + var g memoryGraph + require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &g)) + require.Len(t, g.Nodes, 7) + + req = httptest.NewRequest(http.MethodGet, "/service/memorygraph/view.html", nil) + rec = httptest.NewRecorder() + ctx = e.NewContext(req, rec) + require.NoError(t, HandleMemoryGraphView(ctx)) + require.Equal(t, http.StatusOK, rec.Code) + require.Contains(t, rec.Body.String(), "cosmos") +} diff --git a/tools/memorygraph/README.md b/tools/memorygraph/README.md index afc3f7d..594d134 100644 --- a/tools/memorygraph/README.md +++ b/tools/memorygraph/README.md @@ -36,6 +36,10 @@ checking the usual per-user phosphor data locations. - The viewer renders with cosmos.gl 3.5.1 (GPU force graph) via CDN; only thread/tag hub nodes carry text labels. - `graph.json` and `report*.html` hold raw memory entries and are git-ignored. -- Plan of record: replace this Python builder with serving from the phosphor - Go binary itself, plus a JS chat app so the web GUI is an alternative - front-end to the TUI. \ No newline at end of file +- The embedded viewer now ships with the phosphor binary: with the + `openai-api` service enabled, open + `http://127.0.0.1:8643/service/memorygraph/view.html` (served by + `internal/server/memorygraph.go` on the same port as the Mermaid + renderer). This Python builder remains for offline/standalone use. +- Future: add a JS chat app on top of the same web surface so the web GUI + is an alternative front-end to the TUI. \ No newline at end of file From 1f7ca178aa36051be6546a543ccbeabc2e9aaa53 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Tue, 20 Oct 2026 00:52:10 -0700 Subject: [PATCH 3/9] fix: probe memory graph data with GET so the viewer boots on Go servers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HEAD probe only worked on the Python dev server; the Go router routes strictly by method, so the page loaded but never fetched data. ஃ Generated with Phosphor --- internal/server/memorygraph/view.html | 2 +- tools/memorygraph/view.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/server/memorygraph/view.html b/internal/server/memorygraph/view.html index 8c6dcbd..379b9c1 100644 --- a/internal/server/memorygraph/view.html +++ b/internal/server/memorygraph/view.html @@ -915,7 +915,7 @@

      } async function probe() { try { - const r = await fetch("graph.json?_=" + Date.now(), { method: "HEAD" }); + const r = await fetch("graph.json?_=" + Date.now()); return r.ok && r.headers.get("content-length") !== liveSize; } catch { return false; } } diff --git a/tools/memorygraph/view.html b/tools/memorygraph/view.html index 8c6dcbd..379b9c1 100644 --- a/tools/memorygraph/view.html +++ b/tools/memorygraph/view.html @@ -915,7 +915,7 @@

      } async function probe() { try { - const r = await fetch("graph.json?_=" + Date.now(), { method: "HEAD" }); + const r = await fetch("graph.json?_=" + Date.now()); return r.ok && r.headers.get("content-length") !== liveSize; } catch { return false; } } From 9e867bd7f6ef534d7f1eb71d44b3a94273f642d5 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Tue, 20 Oct 2026 01:08:45 -0700 Subject: [PATCH 4/9] feat: gate the memory graph viewer behind the memory-graph service config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The viewer endpoints are on by default and can be turned off with "services": { "memory-graph": { "enabled": false } } in phosphor.json. ஃ Generated with Phosphor --- docs/CONFIGURATION.md | 6 +++++ internal/platform/httpapi/service.go | 30 +++++++++++++++++------ internal/platform/httpapi/service_test.go | 27 ++++++++++++++++++++ pkg/phosphordocs/content/CONFIGURATION.md | 6 +++++ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 0b13ce0..367c3fa 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -513,11 +513,17 @@ the agent, and the cron scheduler for unattended runs: "port": 8643, "auth": { "type": "bearer", "key": "$PHOSPHOR_API_TOKEN" } }, + "memory-graph": { "enabled": true }, "cron": { "enabled": true, "jobs_directory": ".phosphor/jobs" } } } ``` +The `memory-graph` service serves the memory vault viewer at +`http://127.0.0.1:/service/memorygraph/view.html` and is on +by default. Set `"enabled": false` to remove the endpoints; it rides on the +OpenAI-compatible API server, so it is unavailable when that service is off. + Docs: [platform/openai-api.md](platform/openai-api.md), [platform/SCHEDULED_JOBS.md](platform/SCHEDULED_JOBS.md). diff --git a/internal/platform/httpapi/service.go b/internal/platform/httpapi/service.go index 98b4218..a35d05f 100644 --- a/internal/platform/httpapi/service.go +++ b/internal/platform/httpapi/service.go @@ -72,6 +72,19 @@ func (s *Service) resolveOpenaiConfig() openaiConfig { return cfg } +// memoryGraphViewerEnabled reports whether the memory graph viewer +// endpoints should be registered. The viewer is on unless the +// memory-graph service entry in phosphor.json turns it off. +func (s *Service) memoryGraphViewerEnabled() bool { + if s.cfgStore == nil { + return true + } + if entry, ok := s.cfgStore.Config().Services["memory-graph"]; ok { + return entry.Enabled + } + return true +} + // Name returns the service name "http-api". func (s *Service) Name() string { return "http-api" @@ -274,13 +287,16 @@ func (s *Service) Start(ctx context.Context) error { // Register memory graph viewer endpoints. The viewer page and the // graph data live side by side so the page's relative graph.json - // polling resolves to the live endpoint. - s.echoSrv.GET("/service/memorygraph/view.html", server.HandleMemoryGraphView) - s.echoSrv.GET("/service/memorygraph/graph.json", server.HandleMemoryGraphData) - if len(wsList) > 0 { - server.SetMemoryGraphWorkspace(wsList[0].Path) - } else if s.workspace != "" { - server.SetMemoryGraphWorkspace(s.workspace) + // polling resolves to the live endpoint. Disable with + // "services": { "memory-graph": { "enabled": false } }. + if s.memoryGraphViewerEnabled() { + s.echoSrv.GET("/service/memorygraph/view.html", server.HandleMemoryGraphView) + s.echoSrv.GET("/service/memorygraph/graph.json", server.HandleMemoryGraphData) + if len(wsList) > 0 { + server.SetMemoryGraphWorkspace(wsList[0].Path) + } else if s.workspace != "" { + server.SetMemoryGraphWorkspace(s.workspace) + } } // Create a DB connection and set it on the server for mermaid diagram lookups. dataDir := "" diff --git a/internal/platform/httpapi/service_test.go b/internal/platform/httpapi/service_test.go index be6fafd..b4d4bc4 100644 --- a/internal/platform/httpapi/service_test.go +++ b/internal/platform/httpapi/service_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/hackafterdark/phosphor/pkg/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -24,3 +25,29 @@ func TestService_StartStop(t *testing.T) { err = svc.Stop(ctx) require.NoError(t, err) } +func TestMemoryGraphViewerEnabled(t *testing.T) { + t.Parallel() + + // No config store: on by default. + require.True(t, NewService(nil, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) + + // Config present but no memory-graph entry: on by default. + plain := config.NewTestStore(&config.Config{}) + require.True(t, NewService(plain, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) + + // memory-graph entry present with enabled false: off. + off := config.NewTestStore(&config.Config{ + Services: map[string]config.ServiceEntry{ + "memory-graph": {Enabled: false}, + }, + }) + require.False(t, NewService(off, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) + + // memory-graph entry present with enabled true: on. + on := config.NewTestStore(&config.Config{ + Services: map[string]config.ServiceEntry{ + "memory-graph": {Enabled: true}, + }, + }) + require.True(t, NewService(on, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) +} diff --git a/pkg/phosphordocs/content/CONFIGURATION.md b/pkg/phosphordocs/content/CONFIGURATION.md index 0b13ce0..367c3fa 100644 --- a/pkg/phosphordocs/content/CONFIGURATION.md +++ b/pkg/phosphordocs/content/CONFIGURATION.md @@ -513,11 +513,17 @@ the agent, and the cron scheduler for unattended runs: "port": 8643, "auth": { "type": "bearer", "key": "$PHOSPHOR_API_TOKEN" } }, + "memory-graph": { "enabled": true }, "cron": { "enabled": true, "jobs_directory": ".phosphor/jobs" } } } ``` +The `memory-graph` service serves the memory vault viewer at +`http://127.0.0.1:/service/memorygraph/view.html` and is on +by default. Set `"enabled": false` to remove the endpoints; it rides on the +OpenAI-compatible API server, so it is unavailable when that service is off. + Docs: [platform/openai-api.md](platform/openai-api.md), [platform/SCHEDULED_JOBS.md](platform/SCHEDULED_JOBS.md). From ec83e853e62cc5b54cc20192ff86ba88b823ad79 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Tue, 20 Oct 2026 01:21:40 -0700 Subject: [PATCH 5/9] feat: run the memory graph viewer as a standalone phosphor memorygraph command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The viewer no longer depends on the openai-api service: it serves its own HTTP server on port 8644 (configurable via the memory-graph service entry in phosphor.json), the same foreground pattern as phosphor cron. ஃ Generated with Phosphor --- docs/CONFIGURATION.md | 10 +- internal/cmd/memorygraph.go | 106 ++++++++++++++++++++++ internal/cmd/root.go | 1 + internal/platform/httpapi/service.go | 27 ------ internal/platform/httpapi/service_test.go | 27 ------ internal/server/memorygraph.go | 42 +++++++-- internal/server/memorygraph_test.go | 13 +-- pkg/phosphordocs/content/CONFIGURATION.md | 10 +- tools/memorygraph/README.md | 10 +- 9 files changed, 160 insertions(+), 86 deletions(-) create mode 100644 internal/cmd/memorygraph.go diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 367c3fa..f216a37 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -513,16 +513,16 @@ the agent, and the cron scheduler for unattended runs: "port": 8643, "auth": { "type": "bearer", "key": "$PHOSPHOR_API_TOKEN" } }, - "memory-graph": { "enabled": true }, + "memory-graph": { "host": "127.0.0.1", "port": 8644 }, "cron": { "enabled": true, "jobs_directory": ".phosphor/jobs" } } } ``` -The `memory-graph` service serves the memory vault viewer at -`http://127.0.0.1:/service/memorygraph/view.html` and is on -by default. Set `"enabled": false` to remove the endpoints; it rides on the -OpenAI-compatible API server, so it is unavailable when that service is off. +The `memory-graph` entry configures the memory vault viewer started with +`phosphor memorygraph`. It is a standalone foreground server (like +`phosphor cron`) on its own port — it does not depend on the OpenAI API +service. The host and port fields above are the defaults. Docs: [platform/openai-api.md](platform/openai-api.md), [platform/SCHEDULED_JOBS.md](platform/SCHEDULED_JOBS.md). diff --git a/internal/cmd/memorygraph.go b/internal/cmd/memorygraph.go new file mode 100644 index 0000000..81a4c2a --- /dev/null +++ b/internal/cmd/memorygraph.go @@ -0,0 +1,106 @@ +package cmd + +import ( + "context" + "fmt" + "log/slog" + "net" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/spf13/cobra" + + "github.com/hackafterdark/phosphor/internal/server" + "github.com/hackafterdark/phosphor/pkg/config" +) + +// memoryGraphDefaultPort is the standalone viewer port. 8643 is the +// openai-api/mermaid service; the viewer rides its own port so it works +// regardless of whether that service is enabled. +const memoryGraphDefaultPort = 8644 + +// NewMemoryGraphCommand returns a new command for running the memory graph +// viewer as a standalone service. +func NewMemoryGraphCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "memorygraph", + Short: "Run the memory graph viewer server", + Long: `Start the memory graph viewer to browse the phosphor memory vault. + +The viewer runs in the foreground and serves the constellation view and its +live data endpoint until interrupted by a signal (Ctrl+C). Host and port can +be overridden with the memory-graph service entry in phosphor.json: + + "services": { "memory-graph": { "host": "127.0.0.1", "port": 8644 } }`, + RunE: func(cmd *cobra.Command, args []string) error { + cwd, err := ResolveCwd(cmd) + if err != nil { + return fmt.Errorf("failed to resolve working directory: %w", err) + } + server.SetMemoryGraphWorkspace(cwd) + + host, port := memoryGraphHostPort(cwd) + addr := fmt.Sprintf("%s:%d", host, port) + + // Bind before printing the URL so a port conflict fails fast + // instead of leaving the user on a dead page. + ln, err := net.Listen("tcp", addr) + if err != nil { + return fmt.Errorf("failed to listen on %s: %w", addr, err) + } + + srv := &http.Server{Handler: server.NewMemoryGraphHandler()} + + errCh := make(chan error, 1) + go func() { errCh <- srv.Serve(ln) }() + + fmt.Println("Phosphor Memory Graph Viewer") + fmt.Println("============================") + fmt.Printf("Open http://%s/view.html\n", ln.Addr()) + fmt.Println("\nPress Ctrl+C to stop.") + + sigCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) + defer stop() + + select { + case <-sigCtx.Done(): + slog.Info("Received shutdown signal") + case err := <-errCh: + return fmt.Errorf("memory graph server failed: %w", err) + } + + shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := srv.Shutdown(shutdownCtx); err != nil { + return fmt.Errorf("failed to stop memory graph server: %w", err) + } + slog.Info("Memory graph viewer stopped") + return nil + }, + } + + return cmd +} + +// memoryGraphHostPort resolves the viewer bind address from the memory-graph +// service entry in phosphor.json, falling back to the defaults when the +// config is missing or unreadable. +func memoryGraphHostPort(cwd string) (string, int) { + host, port := "127.0.0.1", memoryGraphDefaultPort + store, err := config.Init(cwd, "", false) + if err != nil { + return host, port + } + if entry, ok := store.Config().Services["memory-graph"]; ok { + if entry.Host != "" { + host = entry.Host + } + if entry.Port != 0 { + port = entry.Port + } + } + return host, port +} diff --git a/internal/cmd/root.go b/internal/cmd/root.go index f93e6e0..ff14124 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -73,6 +73,7 @@ func init() { sessionCmd, indexCmd, NewCronCommand(), + NewMemoryGraphCommand(), ) } diff --git a/internal/platform/httpapi/service.go b/internal/platform/httpapi/service.go index a35d05f..b233b05 100644 --- a/internal/platform/httpapi/service.go +++ b/internal/platform/httpapi/service.go @@ -72,19 +72,6 @@ func (s *Service) resolveOpenaiConfig() openaiConfig { return cfg } -// memoryGraphViewerEnabled reports whether the memory graph viewer -// endpoints should be registered. The viewer is on unless the -// memory-graph service entry in phosphor.json turns it off. -func (s *Service) memoryGraphViewerEnabled() bool { - if s.cfgStore == nil { - return true - } - if entry, ok := s.cfgStore.Config().Services["memory-graph"]; ok { - return entry.Enabled - } - return true -} - // Name returns the service name "http-api". func (s *Service) Name() string { return "http-api" @@ -284,20 +271,6 @@ func (s *Service) Start(ctx context.Context) error { // Register Mermaid rendering endpoint s.echoSrv.GET("/service/mermaid/render", server.HandleMermaidRender) server.SetMermaidServiceEnabled(true, openaiCfg.port) - - // Register memory graph viewer endpoints. The viewer page and the - // graph data live side by side so the page's relative graph.json - // polling resolves to the live endpoint. Disable with - // "services": { "memory-graph": { "enabled": false } }. - if s.memoryGraphViewerEnabled() { - s.echoSrv.GET("/service/memorygraph/view.html", server.HandleMemoryGraphView) - s.echoSrv.GET("/service/memorygraph/graph.json", server.HandleMemoryGraphData) - if len(wsList) > 0 { - server.SetMemoryGraphWorkspace(wsList[0].Path) - } else if s.workspace != "" { - server.SetMemoryGraphWorkspace(s.workspace) - } - } // Create a DB connection and set it on the server for mermaid diagram lookups. dataDir := "" if s.cfgStore != nil { diff --git a/internal/platform/httpapi/service_test.go b/internal/platform/httpapi/service_test.go index b4d4bc4..be6fafd 100644 --- a/internal/platform/httpapi/service_test.go +++ b/internal/platform/httpapi/service_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/hackafterdark/phosphor/pkg/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -25,29 +24,3 @@ func TestService_StartStop(t *testing.T) { err = svc.Stop(ctx) require.NoError(t, err) } -func TestMemoryGraphViewerEnabled(t *testing.T) { - t.Parallel() - - // No config store: on by default. - require.True(t, NewService(nil, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) - - // Config present but no memory-graph entry: on by default. - plain := config.NewTestStore(&config.Config{}) - require.True(t, NewService(plain, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) - - // memory-graph entry present with enabled false: off. - off := config.NewTestStore(&config.Config{ - Services: map[string]config.ServiceEntry{ - "memory-graph": {Enabled: false}, - }, - }) - require.False(t, NewService(off, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) - - // memory-graph entry present with enabled true: on. - on := config.NewTestStore(&config.Config{ - Services: map[string]config.ServiceEntry{ - "memory-graph": {Enabled: true}, - }, - }) - require.True(t, NewService(on, "tcp", "127.0.0.1:0", t.TempDir(), nil).memoryGraphViewerEnabled()) -} diff --git a/internal/server/memorygraph.go b/internal/server/memorygraph.go index 67df572..3cc3f43 100644 --- a/internal/server/memorygraph.go +++ b/internal/server/memorygraph.go @@ -3,6 +3,9 @@ package server import ( "context" "database/sql" + "encoding/json" + "io" + "log/slog" "net/http" "os" "path/filepath" @@ -12,7 +15,6 @@ import ( "github.com/hackafterdark/phosphor/internal/home" "github.com/hackafterdark/phosphor/internal/memory" - "github.com/labstack/echo/v5" ) // memoryGraphWorkspace is the workspace directory used to discover the @@ -62,22 +64,46 @@ func memoryGraphDBPath() string { } // HandleMemoryGraphView serves the embedded memory graph viewer page. -func HandleMemoryGraphView(ctx *echo.Context) error { - return ctx.HTML(http.StatusOK, memoryGraphHTML) +func HandleMemoryGraphView(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusOK) + io.WriteString(w, memoryGraphHTML) } // HandleMemoryGraphData builds the graph for the current memory vault on // every request, so the viewer's polling sees fresh entries. -func HandleMemoryGraphData(ctx *echo.Context) error { +func HandleMemoryGraphData(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Cache-Control", "no-store") dbPath := memoryGraphDBPath() if dbPath == "" { - return ctx.String(http.StatusNotFound, "No memory vault found") + http.Error(w, "No memory vault found", http.StatusNotFound) + return } - graph, err := buildMemoryGraph(ctx.Request().Context(), dbPath) + graph, err := buildMemoryGraph(r.Context(), dbPath) if err != nil { - return ctx.String(http.StatusInternalServerError, "Failed to build memory graph: "+err.Error()) + http.Error(w, "Failed to build memory graph: "+err.Error(), http.StatusInternalServerError) + return } - return ctx.JSON(http.StatusOK, graph) + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(graph); err != nil { + slog.Error("Failed to encode memory graph", "error", err) + } +} + +// NewMemoryGraphHandler returns an http.Handler serving the viewer page at +// / (and /view.html) and the graph data at /graph.json. +func NewMemoryGraphHandler() http.Handler { + mux := http.NewServeMux() + mux.HandleFunc("/view.html", HandleMemoryGraphView) + mux.HandleFunc("/graph.json", HandleMemoryGraphData) + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/" { + HandleMemoryGraphView(w, r) + return + } + http.NotFound(w, r) + }) + return mux } type graphNode struct { diff --git a/internal/server/memorygraph_test.go b/internal/server/memorygraph_test.go index e1f2e37..3a4b09e 100644 --- a/internal/server/memorygraph_test.go +++ b/internal/server/memorygraph_test.go @@ -10,7 +10,6 @@ import ( "path/filepath" "testing" - "github.com/labstack/echo/v5" "github.com/stretchr/testify/require" ) @@ -104,26 +103,22 @@ func TestMemoryGraphHandlers(t *testing.T) { t.Cleanup(func() { memoryGraphWorkspace = orig }) memoryGraphWorkspace = ws - e := echo.New() - seed := seedMemoryDB(t) data, err := os.ReadFile(seed) require.NoError(t, err) require.NoError(t, os.WriteFile(filepath.Join(vault, "memory.db"), data, 0o644)) - req := httptest.NewRequest(http.MethodGet, "/service/memorygraph/graph.json", nil) + req := httptest.NewRequest(http.MethodGet, "/graph.json", nil) rec := httptest.NewRecorder() - ctx := e.NewContext(req, rec) - require.NoError(t, HandleMemoryGraphData(ctx)) + HandleMemoryGraphData(rec, req) require.Equal(t, http.StatusOK, rec.Code) var g memoryGraph require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &g)) require.Len(t, g.Nodes, 7) - req = httptest.NewRequest(http.MethodGet, "/service/memorygraph/view.html", nil) + req = httptest.NewRequest(http.MethodGet, "/view.html", nil) rec = httptest.NewRecorder() - ctx = e.NewContext(req, rec) - require.NoError(t, HandleMemoryGraphView(ctx)) + HandleMemoryGraphView(rec, req) require.Equal(t, http.StatusOK, rec.Code) require.Contains(t, rec.Body.String(), "cosmos") } diff --git a/pkg/phosphordocs/content/CONFIGURATION.md b/pkg/phosphordocs/content/CONFIGURATION.md index 367c3fa..f216a37 100644 --- a/pkg/phosphordocs/content/CONFIGURATION.md +++ b/pkg/phosphordocs/content/CONFIGURATION.md @@ -513,16 +513,16 @@ the agent, and the cron scheduler for unattended runs: "port": 8643, "auth": { "type": "bearer", "key": "$PHOSPHOR_API_TOKEN" } }, - "memory-graph": { "enabled": true }, + "memory-graph": { "host": "127.0.0.1", "port": 8644 }, "cron": { "enabled": true, "jobs_directory": ".phosphor/jobs" } } } ``` -The `memory-graph` service serves the memory vault viewer at -`http://127.0.0.1:/service/memorygraph/view.html` and is on -by default. Set `"enabled": false` to remove the endpoints; it rides on the -OpenAI-compatible API server, so it is unavailable when that service is off. +The `memory-graph` entry configures the memory vault viewer started with +`phosphor memorygraph`. It is a standalone foreground server (like +`phosphor cron`) on its own port — it does not depend on the OpenAI API +service. The host and port fields above are the defaults. Docs: [platform/openai-api.md](platform/openai-api.md), [platform/SCHEDULED_JOBS.md](platform/SCHEDULED_JOBS.md). diff --git a/tools/memorygraph/README.md b/tools/memorygraph/README.md index 594d134..5231c2d 100644 --- a/tools/memorygraph/README.md +++ b/tools/memorygraph/README.md @@ -36,10 +36,10 @@ checking the usual per-user phosphor data locations. - The viewer renders with cosmos.gl 3.5.1 (GPU force graph) via CDN; only thread/tag hub nodes carry text labels. - `graph.json` and `report*.html` hold raw memory entries and are git-ignored. -- The embedded viewer now ships with the phosphor binary: with the - `openai-api` service enabled, open - `http://127.0.0.1:8643/service/memorygraph/view.html` (served by - `internal/server/memorygraph.go` on the same port as the Mermaid - renderer). This Python builder remains for offline/standalone use. +- The viewer ships with the phosphor binary: run `phosphor memorygraph` to + start its own server (default `http://127.0.0.1:8644/view.html`), + independent of the OpenAI API service. Host and port are configurable via + the `memory-graph` service entry in phosphor.json. This Python builder + remains for offline/standalone use. - Future: add a JS chat app on top of the same web surface so the web GUI is an alternative front-end to the TUI. \ No newline at end of file From 6fb1e4685b09b914e5d8f174923710c7300546e4 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Tue, 20 Oct 2026 07:11:27 -0700 Subject: [PATCH 6/9] fix: poll memory graph body length instead of Content-Length header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Go's net/http chunks streamed responses and omits Content-Length, so the header-based probe never detected data and the viewer never booted. The poll now compares the fetched body length and runs every 10s instead of 3s, since memory grows slowly. ஃ Generated with Phosphor --- internal/server/memorygraph/view.html | 26 +++++++++++--------------- tools/memorygraph/view.html | 26 +++++++++++--------------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/internal/server/memorygraph/view.html b/internal/server/memorygraph/view.html index 379b9c1..7edc308 100644 --- a/internal/server/memorygraph/view.html +++ b/internal/server/memorygraph/view.html @@ -908,30 +908,26 @@

      // ---- data loading: snapshot (embedded) or live polling -------------------- const live = !window.__PHOSPHOR_SNAPSHOT__; +const POLL_MS = 10000; let liveSize = null; function status(msg) { const el = document.getElementById("status"); if (el) el.textContent = msg; } -async function probe() { - try { - const r = await fetch("graph.json?_=" + Date.now()); - return r.ok && r.headers.get("content-length") !== liveSize; - } catch { return false; } -} async function poll() { if (!live) return; - if (await probe()) { - try { - const r = await fetch("graph.json?_=" + Date.now()); - if (r.ok) { - liveSize = r.headers.get("content-length"); - boot(await r.json()); + try { + const r = await fetch("graph.json?_=" + Date.now()); + if (r.ok) { + const text = await r.text(); + if (text.length !== liveSize) { + liveSize = text.length; + boot(JSON.parse(text)); status("LIVE · SYNCED"); } - } catch { /* transient; retry on next tick */ } - } - liveTimer = setTimeout(poll, 3000); + } + } catch { /* transient; retry on next tick */ } + liveTimer = setTimeout(poll, POLL_MS); } if (live) { if (location.protocol === "file:") { diff --git a/tools/memorygraph/view.html b/tools/memorygraph/view.html index 379b9c1..7edc308 100644 --- a/tools/memorygraph/view.html +++ b/tools/memorygraph/view.html @@ -908,30 +908,26 @@

      // ---- data loading: snapshot (embedded) or live polling -------------------- const live = !window.__PHOSPHOR_SNAPSHOT__; +const POLL_MS = 10000; let liveSize = null; function status(msg) { const el = document.getElementById("status"); if (el) el.textContent = msg; } -async function probe() { - try { - const r = await fetch("graph.json?_=" + Date.now()); - return r.ok && r.headers.get("content-length") !== liveSize; - } catch { return false; } -} async function poll() { if (!live) return; - if (await probe()) { - try { - const r = await fetch("graph.json?_=" + Date.now()); - if (r.ok) { - liveSize = r.headers.get("content-length"); - boot(await r.json()); + try { + const r = await fetch("graph.json?_=" + Date.now()); + if (r.ok) { + const text = await r.text(); + if (text.length !== liveSize) { + liveSize = text.length; + boot(JSON.parse(text)); status("LIVE · SYNCED"); } - } catch { /* transient; retry on next tick */ } - } - liveTimer = setTimeout(poll, 3000); + } + } catch { /* transient; retry on next tick */ } + liveTimer = setTimeout(poll, POLL_MS); } if (live) { if (location.protocol === "file:") { From 31d0da85b7f8453c5b40cfd023b7f9b3db64e623 Mon Sep 17 00:00:00 2001 From: Tom Maiaroto Date: Tue, 20 Oct 2026 07:58:16 -0700 Subject: [PATCH 7/9] feat: add memory graph viewer with live polling and portable snapshot reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The phosphor memorygraph command serves the live constellation view and, with --report, freezes the current graph into a single self-contained HTML file that opens offline with no server or polling. ஃ Generated with Phosphor --- internal/cmd/memorygraph.go | 29 ++++++++++++++++++++++++- internal/server/memorygraph.go | 33 +++++++++++++++++++++++++++++ internal/server/memorygraph_test.go | 20 +++++++++++++++++ tools/memorygraph/README.md | 5 +++-- 4 files changed, 84 insertions(+), 3 deletions(-) diff --git a/internal/cmd/memorygraph.go b/internal/cmd/memorygraph.go index 81a4c2a..18012c8 100644 --- a/internal/cmd/memorygraph.go +++ b/internal/cmd/memorygraph.go @@ -34,7 +34,10 @@ The viewer runs in the foreground and serves the constellation view and its live data endpoint until interrupted by a signal (Ctrl+C). Host and port can be overridden with the memory-graph service entry in phosphor.json: - "services": { "memory-graph": { "host": "127.0.0.1", "port": 8644 } }`, + "services": { "memory-graph": { "host": "127.0.0.1", "port": 8644 } } + +With --report FILE the current graph is frozen into a single self-contained +HTML file that opens offline with no server, and the command exits.`, RunE: func(cmd *cobra.Command, args []string) error { cwd, err := ResolveCwd(cmd) if err != nil { @@ -42,6 +45,10 @@ be overridden with the memory-graph service entry in phosphor.json: } server.SetMemoryGraphWorkspace(cwd) + if report, _ := cmd.Flags().GetString("report"); report != "" { + return writeMemoryGraphReport(cmd.Context(), report) + } + host, port := memoryGraphHostPort(cwd) addr := fmt.Sprintf("%s:%d", host, port) @@ -82,9 +89,29 @@ be overridden with the memory-graph service entry in phosphor.json: }, } + cmd.Flags().String("report", "", "Write a self-contained snapshot report HTML file and exit") + return cmd } +// writeMemoryGraphReport freezes the current memory graph into a single +// self-contained HTML file that opens offline with no server or polling. +func writeMemoryGraphReport(ctx context.Context, path string) error { + dbPath := server.MemoryGraphDBPath() + if dbPath == "" { + return fmt.Errorf("no memory vault found") + } + page, err := server.RenderMemoryGraphReport(ctx, dbPath) + if err != nil { + return fmt.Errorf("failed to render memory graph report: %w", err) + } + if err := os.WriteFile(path, page, 0o644); err != nil { + return fmt.Errorf("failed to write report: %w", err) + } + fmt.Printf("wrote snapshot report: %s\n", path) + return nil +} + // memoryGraphHostPort resolves the viewer bind address from the memory-graph // service entry in phosphor.json, falling back to the defaults when the // config is missing or unreadable. diff --git a/internal/server/memorygraph.go b/internal/server/memorygraph.go index 3cc3f43..cd3478d 100644 --- a/internal/server/memorygraph.go +++ b/internal/server/memorygraph.go @@ -1,15 +1,18 @@ package server import ( + "bytes" "context" "database/sql" "encoding/json" + "fmt" "io" "log/slog" "net/http" "os" "path/filepath" "sort" + "strings" "time" "unicode/utf8" @@ -106,6 +109,36 @@ func NewMemoryGraphHandler() http.Handler { return mux } +// MemoryGraphDBPath returns the path of the discovered memory vault index, +// or "" when no vault exists. +func MemoryGraphDBPath() string { + return memoryGraphDBPath() +} + +// RenderMemoryGraphReport freezes the current graph into a single +// self-contained HTML report. The page opens offline with no server and no +// polling; its snapshot mode reads the embedded payload instead. +func RenderMemoryGraphReport(ctx context.Context, dbPath string) ([]byte, error) { + graph, err := buildMemoryGraph(ctx, dbPath) + if err != nil { + return nil, err + } + payload, err := json.Marshal(graph) + if err != nil { + return nil, err + } + // Escape " inside any entry body cannot + // terminate the payload tag early. + payload = bytes.ReplaceAll(payload, []byte("") { + return nil, fmt.Errorf("viewer page has no ; cannot embed snapshot payload") + } + head := "\n" + page := strings.Replace(memoryGraphHTML, "", head, 1) + return []byte(page), nil +} + type graphNode struct { ID string `json:"id"` Type string `json:"type"` diff --git a/internal/server/memorygraph_test.go b/internal/server/memorygraph_test.go index 3a4b09e..ade1142 100644 --- a/internal/server/memorygraph_test.go +++ b/internal/server/memorygraph_test.go @@ -8,6 +8,7 @@ import ( "net/http/httptest" "os" "path/filepath" + "strings" "testing" "github.com/stretchr/testify/require" @@ -122,3 +123,22 @@ func TestMemoryGraphHandlers(t *testing.T) { require.Equal(t, http.StatusOK, rec.Code) require.Contains(t, rec.Body.String(), "cosmos") } +func TestRenderMemoryGraphReport(t *testing.T) { + t.Parallel() + dbPath := seedMemoryDB(t) + page, err := RenderMemoryGraphReport(context.Background(), dbPath) + require.NoError(t, err) + html := string(page) + require.Contains(t, html, "window.__PHOSPHOR_SNAPSHOT__ = true;") + require.Contains(t, html, "window.__PHOSPHOR_GRAPH__ = ") + + // The embedded payload must parse back into the same graph. + _, payload, ok := strings.Cut(html, "window.__PHOSPHOR_GRAPH__ = ") + require.True(t, ok) + payload, _, ok = strings.Cut(payload, ";") + require.True(t, ok) + payload = strings.ReplaceAll(payload, `<\/`, ` Date: Tue, 20 Oct 2026 12:32:13 -0700 Subject: [PATCH 8/9] feat: vendor cosmos.gl, add viewer search, and document CLI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - inline cosmos.gl runtime into memory graph viewer and reports (no CDN dependency) - add client-side search to the viewer (works in live and report modes) - fix report export payload insertion colliding with inlined bundle - add docs/memory/MEMORYGRAPH.md and docs/CLI.md; regenerate embedded docs corpus ஃ Generated with Phosphor Assisted-by: Phosphor:CYBER-FROST-3.8-EXL3-SAGE-3.87bpw --- docs/CLI.md | 169 + docs/INDEX.md | 12 +- docs/memory/MEMORYGRAPH.md | 69 + internal/server/memorygraph.go | 37 +- internal/server/memorygraph/cosmos.min.js | 3530 +++++++++++++++++ internal/server/memorygraph/view.html | 68 +- internal/server/memorygraph_embed.go | 5 +- internal/server/memorygraph_test.go | 12 +- pkg/phosphordocs/content/CLI.md | 169 + pkg/phosphordocs/content/README.md | 2 + .../content/memory/MEMORYGRAPH.md | 69 + 11 files changed, 4131 insertions(+), 11 deletions(-) create mode 100644 docs/CLI.md create mode 100644 docs/memory/MEMORYGRAPH.md create mode 100644 internal/server/memorygraph/cosmos.min.js create mode 100644 pkg/phosphordocs/content/CLI.md create mode 100644 pkg/phosphordocs/content/memory/MEMORYGRAPH.md diff --git a/docs/CLI.md b/docs/CLI.md new file mode 100644 index 0000000..aef8aa8 --- /dev/null +++ b/docs/CLI.md @@ -0,0 +1,169 @@ +# CLI Reference + +This page describes the `phosphor` command-line interface. For command-specific +details, see the linked docs or run `phosphor --help`. + +## Global flags + +These flags apply to the root command and are inherited by subcommands. + +| Flag | Short | Description | +| --- | --- | --- | +| `--cwd ` | `-c` | Set the current working directory. | +| `--data-dir ` | `-D` | Use a custom Phosphor data directory. | +| `--debug` | `-d` | Enable debug logging. | +| `--host ` | `-H` | Connect to a specific Phosphor server host. | +| `--profile ` | | Select an active prompt/governance profile. | +| `--trust` | `-T` | Trust the workspace and load repo-local tools/MCP configuration. | +| `--yolo` | `-y` | Automatically accept all permissions. | +| `--session ` | `-s` | Continue a previous session by ID. | +| `--continue` | `-C` | Continue the most recent session. | +| `--help` | `-h` | Show help. | + +`--session` and `--continue` are mutually exclusive. + +## Commands + +| Command | Description | +| --- | --- | +| `phosphor` | Start the TUI and HTTP API (default). | +| `phosphor run [prompt...]` | Run a single non-interactive prompt. | +| `phosphor server` | Start the HTTP API server. | +| `phosphor acp` | Start the Agent Client Protocol service. | +| `phosphor login [platform]` | Authenticate with a provider. | +| `phosphor logout [platform]` | Log out from a provider. | +| `phosphor update-providers [path-or-url]` | Update provider metadata. | +| `phosphor index [directory]` | Build the workspace FTS5 index. | +| `phosphor session` | List and manage sessions. | +| `phosphor projects` | List known project directories. | +| `phosphor logs` | View Phosphor logs. | +| `phosphor stats` | Show token and cost usage statistics. | +| `phosphor memorygraph` | Run the memory graph viewer. | +| `phosphor cron` | Run the cron service for scheduled jobs. | +| `phosphor job` | Manage scheduled jobs. | +| `phosphor bindings` | List all keybindings. | +| `phosphor dirs` | Show config and data directories. | +| `phosphor schema` | Generate JSON schema for configuration. | + +## `phosphor run` + +`phosphor run` sends a single prompt to the agent and exits. It supports +piping input from stdin. + +| Flag | Short | Description | +| --- | --- | --- | +| `--quiet` | `-q` | Hide the spinner. | +| `--verbose` | `-v` | Show logs. | +| `--model ` | `-m` | Model to use (`model` or `provider/model`). | +| `--small-model ` | | Small model to use. | +| `--session ` | `-s` | Continue a previous session by ID. | +| `--continue` | `-C` | Continue the most recent session. | + +## `phosphor server` + +| Flag | Short | Description | +| --- | --- | --- | +| `--host ` | `-H` | Server host (TCP or Unix socket). | +| `--openai-host ` | | OpenAI-compatible API host. | +| `--openai-port ` | | OpenAI-compatible API port. | +| `--openai-enabled ` | | Enable the OpenAI API service (default: true). | +| `--workspace ` | | Workspace directory path. | + +## `phosphor login` + +| Flag | Short | Description | +| --- | --- | --- | +| `--force` | `-f` | Force re-authentication even if already logged in. | + +## `phosphor logout` + +| Flag | Short | Description | +| --- | --- | --- | +| `--force` | `-f` | Skip the logout confirmation prompt. | + +## `phosphor update-providers` + +| Flag | Description | +| --- | --- | +| `--source ` | Provider source to update (`catwalk` or `hyper`, default: `catwalk`). | + +## `phosphor index` + +No subcommand-specific flags. Builds the workspace FTS5 index for the given +directory (defaults to the current directory). + +## `phosphor session` + +| Subcommand | Description | +| --- | --- | +| `phosphor session list` | List all sessions. | +| `phosphor session show ` | Show session details. | +| `phosphor session last` | Show the most recent session. | +| `phosphor session delete ` | Delete a session. | +| `phosphor session rename ` | Rename a session. | +| `phosphor session pin <id>` | Pin a session against bulk deletion. | +| `phosphor session unpin <id>` | Unpin a session. | +| `phosphor session prune-sessions` | Bulk delete old sessions. | +| `phosphor session prune <session-id>` | Prune old messages from a stateless session. | +| `phosphor session list-stateless` | List stateless sessions. | + +Common output flags: + +| Flag | Description | +| --- | --- | +| `--json` | Output in JSON format. | +| `--before <duration>` | Only affect sessions older than the duration. | +| `--dry-run` | Show what would be deleted without deleting. | + +## `phosphor projects` + +| Flag | Description | +| --- | --- | +| `--json` | Output as JSON. | + +## `phosphor logs` + +| Flag | Short | Description | +| --- | --- | --- | +| `--follow` | `-f` | Follow log output. | +| `--tail <n>` | `-t` | Show only the last N lines (default: 1000). | + +## `phosphor memorygraph` + +| Flag | Description | +| --- | --- | +| `--report <file>` | Write a self-contained snapshot report HTML file and exit. | + +See [Memory Graph Viewer](memory/MEMORYGRAPH.md) for details. + +## `phosphor cron` + +Runs the cron service for scheduled jobs. See +[Scheduled Jobs](platform/SCHEDULED_JOBS.md) for job file format and management. + +## `phosphor job` + +| Subcommand | Description | +| --- | --- | +| `phosphor job add <name>` | Create a new job. | +| `phosphor job list` | List all jobs. | +| `phosphor job remove <name>` | Remove a job. | +| `phosphor job edit <name>` | Edit a job. | + +## `phosphor acp` + +| Flag | Description | +| --- | --- | +| `--workspace <dir>` | Workspace directory (defaults to current directory). | + +## `phosphor bindings` + +Lists all available keybindings. + +## `phosphor dirs` + +Shows the config and data directories used by Phosphor. + +## `phosphor schema` + +Generates the JSON schema for `phosphor.json`. \ No newline at end of file diff --git a/docs/INDEX.md b/docs/INDEX.md index 6520b4e..36ed3e4 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -8,8 +8,9 @@ searchable through the `phosphor_docs` tool or by viewing any | Doc | Covers | | --- | --- | -| [CONFIGURATION.md](CONFIGURATION.md) | Where config files live per OS, merge order, and a snippet for every config section. Start here. | -| [CORE_PHILOSOPHY.md](CORE_PHILOSOPHY.md) | Identity and core pillars of the project. | +|| [CONFIGURATION.md](CONFIGURATION.md) | Where config files live per OS, merge order, and a snippet for every config section. Start here. | +|| [CLI.md](CLI.md) | Global flags, subcommands, and per-command options for the `phosphor` CLI. | +|| [CORE_PHILOSOPHY.md](CORE_PHILOSOPHY.md) | Identity and core pillars of the project. | | [KEYBINDINGS.md](KEYBINDINGS.md) | Default TUI key bindings and how to configure custom ones. | ## Configuration @@ -50,9 +51,10 @@ searchable through the `phosphor_docs` tool or by viewing any | Doc | Covers | | --- | --- | -| [memory/OVERVIEW.md](memory/OVERVIEW.md) | How the memory system works: vaults, the entry model, write/read paths, Tier A/B injection, config, `/memory`. | -| [memory/INTEGRITY.md](memory/INTEGRITY.md) | The tamper seal: the HMAC key, what is signed vs. deliberately exempt, the threat model, key operations. | -| [memory/POISONING.md](memory/POISONING.md) | The layered defenses against a poisoned memory entry reaching the system prompt. | +|| [memory/OVERVIEW.md](memory/OVERVIEW.md) | How the memory system works: vaults, the entry model, write/read paths, Tier A/B injection, config, `/memory`. | +|| [memory/INTEGRITY.md](memory/INTEGRITY.md) | The tamper seal: the HMAC key, what is signed vs. deliberately exempt, the threat model, key operations. | +|| [memory/POISONING.md](memory/POISONING.md) | The layered defenses against a poisoned memory entry reaching the system prompt. | +|| [memory/MEMORYGRAPH.md](memory/MEMORYGRAPH.md) | The memory graph viewer: live server, report export, host/port config, and node/edge semantics. | ## Extending the Agent diff --git a/docs/memory/MEMORYGRAPH.md b/docs/memory/MEMORYGRAPH.md new file mode 100644 index 0000000..078c594 --- /dev/null +++ b/docs/memory/MEMORYGRAPH.md @@ -0,0 +1,69 @@ +# Memory Graph Viewer + +`phosphor memorygraph` visualizes the memory vault as an interactive 2D +constellation. Memory entries are nodes colored by type; threads and tags +become hub nodes that cluster related entries together. + +## Run the live viewer + +```bash +phosphor memorygraph +``` + +The command starts a local HTTP server and prints the viewer URL: + +``` +Phosphor Memory Graph Viewer +============================ +Open http://127.0.0.1:8644/view.html + +Press Ctrl+C to stop. +``` + +The viewer polls the graph data endpoint every 10 seconds, so new memory +entries appear without restarting. Press `Ctrl+C` to stop the server. + +## Export a snapshot report + +```bash +phosphor memorygraph --report report.html +``` + +This writes a single self-contained HTML file that embeds the current graph +payload and opens offline with no server or polling. The exported report is +static: it shows the graph as it existed at export time. + +## Host and port + +The viewer defaults to `127.0.0.1:8644`. You can override it in +`phosphor.json`: + +```json +{ + "services": { + "memory-graph": { + "host": "127.0.0.1", + "port": 8644 + } + } +} +``` + +The viewer uses its own port so it works regardless of whether the +OpenAI-compatible API service is enabled. + +## What the viewer shows + +- **Nodes**: memory entries (decisions, constraints, references, etc.) plus + thread and tag hubs. +- **Edges**: relationships such as `supersedes`, `decision`, `thread`, and + `tag`. +- **Side panel**: click a node to view its id, type, trust, recall, dates, + tags, body, and linked nodes. +- **Search**: press `/` to focus the search box, type to filter nodes, and + press `Enter` to jump to the top-scoring match. + +## Related docs + +- [Memory Overview](OVERVIEW.md) — how the memory vault and index work. +- [CLI Reference](CLI.md) — global flags and all commands. \ No newline at end of file diff --git a/internal/server/memorygraph.go b/internal/server/memorygraph.go index cd3478d..21d2bdf 100644 --- a/internal/server/memorygraph.go +++ b/internal/server/memorygraph.go @@ -5,6 +5,7 @@ import ( "context" "database/sql" "encoding/json" + "errors" "fmt" "io" "log/slog" @@ -13,6 +14,7 @@ import ( "path/filepath" "sort" "strings" + "sync" "time" "unicode/utf8" @@ -66,11 +68,39 @@ func memoryGraphDBPath() string { return "" } +// cosmosPlaceholder marks where the bundled cosmos.gl runtime is injected +// into the viewer page. +const cosmosPlaceholder = "<!--PHOSPHOR_COSMOS_JS-->" + +// hydrateCosmos replaces the cosmos placeholder with the bundled runtime +// wrapped in a script tag. +func hydrateCosmos(page string) string { + // Escape the close-tag sequence so a literal inside the bundle cannot + // terminate the injected script tag early. + js := strings.ReplaceAll(cosmosGraphJS, "</script>", `<\/script>`) + return strings.Replace(page, cosmosPlaceholder, "<script>"+js+"</script>", 1) +} + +// viewerPage returns the viewer HTML with the bundled cosmos.gl runtime +// inlined, so both the live viewer and exported reports render with no +// network access and no CDN dependency. +var viewerPage = sync.OnceValues(func() (string, error) { + if !strings.Contains(memoryGraphHTML, cosmosPlaceholder) { + return "", errors.New("viewer page has no " + cosmosPlaceholder + " placeholder") + } + return hydrateCosmos(memoryGraphHTML), nil +}) + // HandleMemoryGraphView serves the embedded memory graph viewer page. func HandleMemoryGraphView(w http.ResponseWriter, _ *http.Request) { + page, err := viewerPage() + if err != nil { + http.Error(w, "Failed to hydrate viewer page: "+err.Error(), http.StatusInternalServerError) + return + } w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusOK) - io.WriteString(w, memoryGraphHTML) + io.WriteString(w, page) } // HandleMemoryGraphData builds the graph for the current memory vault on @@ -130,13 +160,16 @@ func RenderMemoryGraphReport(ctx context.Context, dbPath string) ([]byte, error) // Escape </ sequences so a "</script>" inside any entry body cannot // terminate the payload tag early. payload = bytes.ReplaceAll(payload, []byte("</"), []byte(`<\/`)) + // Insert the payload into the bare template before hydrating cosmos.gl: + // the bundle itself contains a literal "</head>" inside a string, so + // replacing after injection would splice the payload into the bundle. if !strings.Contains(memoryGraphHTML, "</head>") { return nil, fmt.Errorf("viewer page has no </head>; cannot embed snapshot payload") } head := "<script>window.__PHOSPHOR_SNAPSHOT__ = true;\n" + "window.__PHOSPHOR_GRAPH__ = " + string(payload) + ";</script>\n</head>" page := strings.Replace(memoryGraphHTML, "</head>", head, 1) - return []byte(page), nil + return []byte(hydrateCosmos(page)), nil } type graphNode struct { diff --git a/internal/server/memorygraph/cosmos.min.js b/internal/server/memorygraph/cosmos.min.js new file mode 100644 index 0000000..552a528 --- /dev/null +++ b/internal/server/memorygraph/cosmos.min.js @@ -0,0 +1,3530 @@ +(function(K,Re){typeof exports=="object"&&typeof module<"u"?Re(exports):typeof define=="function"&&define.amd?define(["exports"],Re):(K=typeof globalThis<"u"?globalThis:K||self,Re(K.Cosmos={}))})(this,function(K){"use strict";var nP=Object.defineProperty;var rP=(K,Re,Et)=>Re in K?nP(K,Re,{enumerable:!0,configurable:!0,writable:!0,value:Et}):K[Re]=Et;var f=(K,Re,Et)=>rP(K,typeof Re!="symbol"?Re+"":Re,Et);var Re="http://www.w3.org/1999/xhtml";const Et={svg:"http://www.w3.org/2000/svg",xhtml:Re,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function cn(e){var t=e+="",i=t.indexOf(":");return i>=0&&(t=e.slice(0,i))!=="xmlns"&&(e=e.slice(i+1)),Et.hasOwnProperty(t)?{space:Et[t],local:e}:e}function Qd(e){return function(){var t=this.ownerDocument,i=this.namespaceURI;return i===Re&&t.documentElement.namespaceURI===Re?t.createElement(e):t.createElementNS(i,e)}}function Jd(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function ha(e){var t=cn(e);return(t.local?Jd:Qd)(t)}function eh(){}function qr(e){return e==null?eh:function(){return this.querySelector(e)}}function th(e){typeof e!="function"&&(e=qr(e));for(var t=this._groups,i=t.length,n=new Array(i),r=0;r<i;++r)for(var s=t[r],o=s.length,a=n[r]=new Array(o),l,c,u=0;u<o;++u)(l=s[u])&&(c=e.call(l,l.__data__,u,s))&&("__data__"in l&&(c.__data__=l.__data__),a[u]=c);return new Be(n,this._parents)}function ih(e){return e==null?[]:Array.isArray(e)?e:Array.from(e)}function nh(){return[]}function fa(e){return e==null?nh:function(){return this.querySelectorAll(e)}}function rh(e){return function(){return ih(e.apply(this,arguments))}}function sh(e){typeof e=="function"?e=rh(e):e=fa(e);for(var t=this._groups,i=t.length,n=[],r=[],s=0;s<i;++s)for(var o=t[s],a=o.length,l,c=0;c<a;++c)(l=o[c])&&(n.push(e.call(l,l.__data__,c,o)),r.push(l));return new Be(n,r)}function pa(e){return function(){return this.matches(e)}}function ga(e){return function(t){return t.matches(e)}}var oh=Array.prototype.find;function ah(e){return function(){return oh.call(this.children,e)}}function lh(){return this.firstElementChild}function ch(e){return this.select(e==null?lh:ah(typeof e=="function"?e:ga(e)))}var uh=Array.prototype.filter;function dh(){return Array.from(this.children)}function hh(e){return function(){return uh.call(this.children,e)}}function fh(e){return this.selectAll(e==null?dh:hh(typeof e=="function"?e:ga(e)))}function ph(e){typeof e!="function"&&(e=pa(e));for(var t=this._groups,i=t.length,n=new Array(i),r=0;r<i;++r)for(var s=t[r],o=s.length,a=n[r]=[],l,c=0;c<o;++c)(l=s[c])&&e.call(l,l.__data__,c,s)&&a.push(l);return new Be(n,this._parents)}function ma(e){return new Array(e.length)}function gh(){return new Be(this._enter||this._groups.map(ma),this._parents)}function un(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}un.prototype={constructor:un,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};function mh(e){return function(){return e}}function xh(e,t,i,n,r,s){for(var o=0,a,l=t.length,c=s.length;o<c;++o)(a=t[o])?(a.__data__=s[o],n[o]=a):i[o]=new un(e,s[o]);for(;o<l;++o)(a=t[o])&&(r[o]=a)}function Sh(e,t,i,n,r,s,o){var a,l,c=new Map,u=t.length,d=s.length,h=new Array(u),p;for(a=0;a<u;++a)(l=t[a])&&(h[a]=p=o.call(l,l.__data__,a,t)+"",c.has(p)?r[a]=l:c.set(p,l));for(a=0;a<d;++a)p=o.call(e,s[a],a,s)+"",(l=c.get(p))?(n[a]=l,l.__data__=s[a],c.delete(p)):i[a]=new un(e,s[a]);for(a=0;a<u;++a)(l=t[a])&&c.get(h[a])===l&&(r[a]=l)}function yh(e){return e.__data__}function _h(e,t){if(!arguments.length)return Array.from(this,yh);var i=t?Sh:xh,n=this._parents,r=this._groups;typeof e!="function"&&(e=mh(e));for(var s=r.length,o=new Array(s),a=new Array(s),l=new Array(s),c=0;c<s;++c){var u=n[c],d=r[c],h=d.length,p=bh(e.call(u,u&&u.__data__,c,n)),g=p.length,x=a[c]=new Array(g),T=o[c]=new Array(g),S=l[c]=new Array(h);i(u,d,x,T,S,p,t);for(var P=0,I=0,y,v;P<g;++P)if(y=x[P]){for(P>=I&&(I=P+1);!(v=T[I])&&++I<g;);y._next=v||null}}return o=new Be(o,n),o._enter=a,o._exit=l,o}function bh(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function Th(){return new Be(this._exit||this._groups.map(ma),this._parents)}function vh(e,t,i){var n=this.enter(),r=this,s=this.exit();return typeof e=="function"?(n=e(n),n&&(n=n.selection())):n=n.append(e+""),t!=null&&(r=t(r),r&&(r=r.selection())),i==null?s.remove():i(s),n&&r?n.merge(r).order():r}function Ph(e){for(var t=e.selection?e.selection():e,i=this._groups,n=t._groups,r=i.length,s=n.length,o=Math.min(r,s),a=new Array(r),l=0;l<o;++l)for(var c=i[l],u=n[l],d=c.length,h=a[l]=new Array(d),p,g=0;g<d;++g)(p=c[g]||u[g])&&(h[g]=p);for(;l<r;++l)a[l]=i[l];return new Be(a,this._parents)}function Ch(){for(var e=this._groups,t=-1,i=e.length;++t<i;)for(var n=e[t],r=n.length-1,s=n[r],o;--r>=0;)(o=n[r])&&(s&&o.compareDocumentPosition(s)^4&&s.parentNode.insertBefore(o,s),s=o);return this}function Ah(e){e||(e=Rh);function t(d,h){return d&&h?e(d.__data__,h.__data__):!d-!h}for(var i=this._groups,n=i.length,r=new Array(n),s=0;s<n;++s){for(var o=i[s],a=o.length,l=r[s]=new Array(a),c,u=0;u<a;++u)(c=o[u])&&(l[u]=c);l.sort(t)}return new Be(r,this._parents).order()}function Rh(e,t){return e<t?-1:e>t?1:e>=t?0:NaN}function wh(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function Eh(){return Array.from(this)}function Ih(){for(var e=this._groups,t=0,i=e.length;t<i;++t)for(var n=e[t],r=0,s=n.length;r<s;++r){var o=n[r];if(o)return o}return null}function kh(){let e=0;for(const t of this)++e;return e}function Dh(){return!this.node()}function Fh(e){for(var t=this._groups,i=0,n=t.length;i<n;++i)for(var r=t[i],s=0,o=r.length,a;s<o;++s)(a=r[s])&&e.call(a,a.__data__,s,r);return this}function Mh(e){return function(){this.removeAttribute(e)}}function Nh(e){return function(){this.removeAttributeNS(e.space,e.local)}}function Bh(e,t){return function(){this.setAttribute(e,t)}}function Oh(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function Uh(e,t){return function(){var i=t.apply(this,arguments);i==null?this.removeAttribute(e):this.setAttribute(e,i)}}function zh(e,t){return function(){var i=t.apply(this,arguments);i==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,i)}}function Lh(e,t){var i=cn(e);if(arguments.length<2){var n=this.node();return i.local?n.getAttributeNS(i.space,i.local):n.getAttribute(i)}return this.each((t==null?i.local?Nh:Mh:typeof t=="function"?i.local?zh:Uh:i.local?Oh:Bh)(i,t))}function xa(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function Wh(e){return function(){this.style.removeProperty(e)}}function Vh(e,t,i){return function(){this.style.setProperty(e,t,i)}}function Hh(e,t,i){return function(){var n=t.apply(this,arguments);n==null?this.style.removeProperty(e):this.style.setProperty(e,n,i)}}function $h(e,t,i){return arguments.length>1?this.each((t==null?Wh:typeof t=="function"?Hh:Vh)(e,t,i??"")):Ht(this.node(),e)}function Ht(e,t){return e.style.getPropertyValue(t)||xa(e).getComputedStyle(e,null).getPropertyValue(t)}function Xh(e){return function(){delete this[e]}}function Yh(e,t){return function(){this[e]=t}}function jh(e,t){return function(){var i=t.apply(this,arguments);i==null?delete this[e]:this[e]=i}}function Kh(e,t){return arguments.length>1?this.each((t==null?Xh:typeof t=="function"?jh:Yh)(e,t)):this.node()[e]}function Sa(e){return e.trim().split(/^|\s+/)}function Gr(e){return e.classList||new ya(e)}function ya(e){this._node=e,this._names=Sa(e.getAttribute("class")||"")}ya.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function _a(e,t){for(var i=Gr(e),n=-1,r=t.length;++n<r;)i.add(t[n])}function ba(e,t){for(var i=Gr(e),n=-1,r=t.length;++n<r;)i.remove(t[n])}function qh(e){return function(){_a(this,e)}}function Gh(e){return function(){ba(this,e)}}function Zh(e,t){return function(){(t.apply(this,arguments)?_a:ba)(this,e)}}function Qh(e,t){var i=Sa(e+"");if(arguments.length<2){for(var n=Gr(this.node()),r=-1,s=i.length;++r<s;)if(!n.contains(i[r]))return!1;return!0}return this.each((typeof t=="function"?Zh:t?qh:Gh)(i,t))}function Jh(){this.textContent=""}function ef(e){return function(){this.textContent=e}}function tf(e){return function(){var t=e.apply(this,arguments);this.textContent=t??""}}function nf(e){return arguments.length?this.each(e==null?Jh:(typeof e=="function"?tf:ef)(e)):this.node().textContent}function rf(){this.innerHTML=""}function sf(e){return function(){this.innerHTML=e}}function of(e){return function(){var t=e.apply(this,arguments);this.innerHTML=t??""}}function af(e){return arguments.length?this.each(e==null?rf:(typeof e=="function"?of:sf)(e)):this.node().innerHTML}function lf(){this.nextSibling&&this.parentNode.appendChild(this)}function cf(){return this.each(lf)}function uf(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function df(){return this.each(uf)}function hf(e){var t=typeof e=="function"?e:ha(e);return this.select(function(){return this.appendChild(t.apply(this,arguments))})}function ff(){return null}function pf(e,t){var i=typeof e=="function"?e:ha(e),n=t==null?ff:typeof t=="function"?t:qr(t);return this.select(function(){return this.insertBefore(i.apply(this,arguments),n.apply(this,arguments)||null)})}function gf(){var e=this.parentNode;e&&e.removeChild(this)}function mf(){return this.each(gf)}function xf(){var e=this.cloneNode(!1),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function Sf(){var e=this.cloneNode(!0),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function yf(e){return this.select(e?Sf:xf)}function _f(e){return arguments.length?this.property("__data__",e):this.node().__data__}function bf(e){return function(t){e.call(this,t,this.__data__)}}function Tf(e){return e.trim().split(/^|\s+/).map(function(t){var i="",n=t.indexOf(".");return n>=0&&(i=t.slice(n+1),t=t.slice(0,n)),{type:t,name:i}})}function vf(e){return function(){var t=this.__on;if(t){for(var i=0,n=-1,r=t.length,s;i<r;++i)s=t[i],(!e.type||s.type===e.type)&&s.name===e.name?this.removeEventListener(s.type,s.listener,s.options):t[++n]=s;++n?t.length=n:delete this.__on}}}function Pf(e,t,i){return function(){var n=this.__on,r,s=bf(t);if(n){for(var o=0,a=n.length;o<a;++o)if((r=n[o]).type===e.type&&r.name===e.name){this.removeEventListener(r.type,r.listener,r.options),this.addEventListener(r.type,r.listener=s,r.options=i),r.value=t;return}}this.addEventListener(e.type,s,i),r={type:e.type,name:e.name,value:t,listener:s,options:i},n?n.push(r):this.__on=[r]}}function Cf(e,t,i){var n=Tf(e+""),r,s=n.length,o;if(arguments.length<2){var a=this.node().__on;if(a){for(var l=0,c=a.length,u;l<c;++l)for(r=0,u=a[l];r<s;++r)if((o=n[r]).type===u.type&&o.name===u.name)return u.value}return}for(a=t?Pf:vf,r=0;r<s;++r)this.each(a(n[r],t,i));return this}function Ta(e,t,i){var n=xa(e),r=n.CustomEvent;typeof r=="function"?r=new r(t,i):(r=n.document.createEvent("Event"),i?(r.initEvent(t,i.bubbles,i.cancelable),r.detail=i.detail):r.initEvent(t,!1,!1)),e.dispatchEvent(r)}function Af(e,t){return function(){return Ta(this,e,t)}}function Rf(e,t){return function(){return Ta(this,e,t.apply(this,arguments))}}function wf(e,t){return this.each((typeof t=="function"?Rf:Af)(e,t))}function*Ef(){for(var e=this._groups,t=0,i=e.length;t<i;++t)for(var n=e[t],r=0,s=n.length,o;r<s;++r)(o=n[r])&&(yield o)}var va=[null];function Be(e,t){this._groups=e,this._parents=t}function vi(){return new Be([[document.documentElement]],va)}function If(){return this}Be.prototype=vi.prototype={constructor:Be,select:th,selectAll:sh,selectChild:ch,selectChildren:fh,filter:ph,data:_h,enter:gh,exit:Th,join:vh,merge:Ph,selection:If,order:Ch,sort:Ah,call:wh,nodes:Eh,node:Ih,size:kh,empty:Dh,each:Fh,attr:Lh,style:$h,property:Kh,classed:Qh,text:nf,html:af,raise:cf,lower:df,append:hf,insert:pf,remove:mf,clone:yf,datum:_f,on:Cf,dispatch:wf,[Symbol.iterator]:Ef};function ye(e){return typeof e=="string"?new Be([[document.querySelector(e)]],[document.documentElement]):new Be([[e]],va)}function kf(e){let t;for(;t=e.sourceEvent;)e=t;return e}function ct(e,t){if(e=kf(e),t===void 0&&(t=e.currentTarget),t){var i=t.ownerSVGElement||t;if(i.createSVGPoint){var n=i.createSVGPoint();return n.x=e.clientX,n.y=e.clientY,n=n.matrixTransform(t.getScreenCTM().inverse()),[n.x,n.y]}if(t.getBoundingClientRect){var r=t.getBoundingClientRect();return[e.clientX-r.left-t.clientLeft,e.clientY-r.top-t.clientTop]}}return[e.pageX,e.pageY]}var Df={value:()=>{}};function dn(){for(var e=0,t=arguments.length,i={},n;e<t;++e){if(!(n=arguments[e]+"")||n in i||/[\s.]/.test(n))throw new Error("illegal type: "+n);i[n]=[]}return new hn(i)}function hn(e){this._=e}function Ff(e,t){return e.trim().split(/^|\s+/).map(function(i){var n="",r=i.indexOf(".");if(r>=0&&(n=i.slice(r+1),i=i.slice(0,r)),i&&!t.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:n}})}hn.prototype=dn.prototype={constructor:hn,on:function(e,t){var i=this._,n=Ff(e+"",i),r,s=-1,o=n.length;if(arguments.length<2){for(;++s<o;)if((r=(e=n[s]).type)&&(r=Mf(i[r],e.name)))return r;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++s<o;)if(r=(e=n[s]).type)i[r]=Pa(i[r],e.name,t);else if(t==null)for(r in i)i[r]=Pa(i[r],e.name,null);return this},copy:function(){var e={},t=this._;for(var i in t)e[i]=t[i].slice();return new hn(e)},call:function(e,t){if((r=arguments.length-2)>0)for(var i=new Array(r),n=0,r,s;n<r;++n)i[n]=arguments[n+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(s=this._[e],n=0,r=s.length;n<r;++n)s[n].value.apply(t,i)},apply:function(e,t,i){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var n=this._[e],r=0,s=n.length;r<s;++r)n[r].value.apply(t,i)}};function Mf(e,t){for(var i=0,n=e.length,r;i<n;++i)if((r=e[i]).name===t)return r.value}function Pa(e,t,i){for(var n=0,r=e.length;n<r;++n)if(e[n].name===t){e[n]=Df,e=e.slice(0,n).concat(e.slice(n+1));break}return i!=null&&e.push({name:t,value:i}),e}var $t=0,Pi=0,Ci=0,Ca=1e3,fn,Ai,pn=0,It=0,gn=0,Ri=typeof performance=="object"&&performance.now?performance:Date,Aa=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function Zr(){return It||(Aa(Nf),It=Ri.now()+gn)}function Nf(){It=0}function mn(){this._call=this._time=this._next=null}mn.prototype=Ra.prototype={constructor:mn,restart:function(e,t,i){if(typeof e!="function")throw new TypeError("callback is not a function");i=(i==null?Zr():+i)+(t==null?0:+t),!this._next&&Ai!==this&&(Ai?Ai._next=this:fn=this,Ai=this),this._call=e,this._time=i,Qr()},stop:function(){this._call&&(this._call=null,this._time=1/0,Qr())}};function Ra(e,t,i){var n=new mn;return n.restart(e,t,i),n}function Bf(){Zr(),++$t;for(var e=fn,t;e;)(t=It-e._time)>=0&&e._call.call(null,t),e=e._next;--$t}function wa(){It=(pn=Ri.now())+gn,$t=Pi=0;try{Bf()}finally{$t=0,Uf(),It=0}}function Of(){var e=Ri.now(),t=e-pn;t>Ca&&(gn-=t,pn=e)}function Uf(){for(var e,t=fn,i,n=1/0;t;)t._call?(n>t._time&&(n=t._time),e=t,t=t._next):(i=t._next,t._next=null,t=e?e._next=i:fn=i);Ai=e,Qr(n)}function Qr(e){if(!$t){Pi&&(Pi=clearTimeout(Pi));var t=e-It;t>24?(e<1/0&&(Pi=setTimeout(wa,e-Ri.now()-gn)),Ci&&(Ci=clearInterval(Ci))):(Ci||(pn=Ri.now(),Ci=setInterval(Of,Ca)),$t=1,Aa(wa))}}function Ea(e,t,i){var n=new mn;return t=t==null?0:+t,n.restart(r=>{n.stop(),e(r+t)},t,i),n}var zf=dn("start","end","cancel","interrupt"),Lf=[],Ia=0,ka=1,Jr=2,xn=3,Da=4,es=5,Sn=6;function yn(e,t,i,n,r,s){var o=e.__transition;if(!o)e.__transition={};else if(i in o)return;Wf(e,i,{name:t,index:n,group:r,on:zf,tween:Lf,time:s.time,delay:s.delay,duration:s.duration,ease:s.ease,timer:null,state:Ia})}function ts(e,t){var i=Ye(e,t);if(i.state>Ia)throw new Error("too late; already scheduled");return i}function tt(e,t){var i=Ye(e,t);if(i.state>xn)throw new Error("too late; already running");return i}function Ye(e,t){var i=e.__transition;if(!i||!(i=i[t]))throw new Error("transition not found");return i}function Wf(e,t,i){var n=e.__transition,r;n[t]=i,i.timer=Ra(s,0,i.time);function s(c){i.state=ka,i.timer.restart(o,i.delay,i.time),i.delay<=c&&o(c-i.delay)}function o(c){var u,d,h,p;if(i.state!==ka)return l();for(u in n)if(p=n[u],p.name===i.name){if(p.state===xn)return Ea(o);p.state===Da?(p.state=Sn,p.timer.stop(),p.on.call("interrupt",e,e.__data__,p.index,p.group),delete n[u]):+u<t&&(p.state=Sn,p.timer.stop(),p.on.call("cancel",e,e.__data__,p.index,p.group),delete n[u])}if(Ea(function(){i.state===xn&&(i.state=Da,i.timer.restart(a,i.delay,i.time),a(c))}),i.state=Jr,i.on.call("start",e,e.__data__,i.index,i.group),i.state===Jr){for(i.state=xn,r=new Array(h=i.tween.length),u=0,d=-1;u<h;++u)(p=i.tween[u].value.call(e,e.__data__,i.index,i.group))&&(r[++d]=p);r.length=d+1}}function a(c){for(var u=c<i.duration?i.ease.call(null,c/i.duration):(i.timer.restart(l),i.state=es,1),d=-1,h=r.length;++d<h;)r[d].call(e,u);i.state===es&&(i.on.call("end",e,e.__data__,i.index,i.group),l())}function l(){i.state=Sn,i.timer.stop(),delete n[t];for(var c in n)return;delete e.__transition}}function _n(e,t){var i=e.__transition,n,r,s=!0,o;if(i){t=t==null?null:t+"";for(o in i){if((n=i[o]).name!==t){s=!1;continue}r=n.state>Jr&&n.state<es,n.state=Sn,n.timer.stop(),n.on.call(r?"interrupt":"cancel",e,e.__data__,n.index,n.group),delete i[o]}s&&delete e.__transition}}function Vf(e){return this.each(function(){_n(this,e)})}function is(e,t,i){e.prototype=t.prototype=i,i.constructor=e}function Fa(e,t){var i=Object.create(e.prototype);for(var n in t)i[n]=t[n];return i}function wi(){}var Ei=.7,bn=1/Ei,Xt="\\s*([+-]?\\d+)\\s*",Ii="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",it="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",Hf=/^#([0-9a-f]{3,8})$/,$f=new RegExp(`^rgb\\(${Xt},${Xt},${Xt}\\)$`),Xf=new RegExp(`^rgb\\(${it},${it},${it}\\)$`),Yf=new RegExp(`^rgba\\(${Xt},${Xt},${Xt},${Ii}\\)$`),jf=new RegExp(`^rgba\\(${it},${it},${it},${Ii}\\)$`),Kf=new RegExp(`^hsl\\(${Ii},${it},${it}\\)$`),qf=new RegExp(`^hsla\\(${Ii},${it},${it},${Ii}\\)$`),Ma={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};is(wi,mt,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:Na,formatHex:Na,formatHex8:Gf,formatHsl:Zf,formatRgb:Ba,toString:Ba});function Na(){return this.rgb().formatHex()}function Gf(){return this.rgb().formatHex8()}function Zf(){return Wa(this).formatHsl()}function Ba(){return this.rgb().formatRgb()}function mt(e){var t,i;return e=(e+"").trim().toLowerCase(),(t=Hf.exec(e))?(i=t[1].length,t=parseInt(t[1],16),i===6?Oa(t):i===3?new ke(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):i===8?Tn(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):i===4?Tn(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=$f.exec(e))?new ke(t[1],t[2],t[3],1):(t=Xf.exec(e))?new ke(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=Yf.exec(e))?Tn(t[1],t[2],t[3],t[4]):(t=jf.exec(e))?Tn(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=Kf.exec(e))?La(t[1],t[2]/100,t[3]/100,1):(t=qf.exec(e))?La(t[1],t[2]/100,t[3]/100,t[4]):Ma.hasOwnProperty(e)?Oa(Ma[e]):e==="transparent"?new ke(NaN,NaN,NaN,0):null}function Oa(e){return new ke(e>>16&255,e>>8&255,e&255,1)}function Tn(e,t,i,n){return n<=0&&(e=t=i=NaN),new ke(e,t,i,n)}function Qf(e){return e instanceof wi||(e=mt(e)),e?(e=e.rgb(),new ke(e.r,e.g,e.b,e.opacity)):new ke}function ns(e,t,i,n){return arguments.length===1?Qf(e):new ke(e,t,i,n??1)}function ke(e,t,i,n){this.r=+e,this.g=+t,this.b=+i,this.opacity=+n}is(ke,ns,Fa(wi,{brighter(e){return e=e==null?bn:Math.pow(bn,e),new ke(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Ei:Math.pow(Ei,e),new ke(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new ke(kt(this.r),kt(this.g),kt(this.b),vn(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Ua,formatHex:Ua,formatHex8:Jf,formatRgb:za,toString:za}));function Ua(){return`#${Dt(this.r)}${Dt(this.g)}${Dt(this.b)}`}function Jf(){return`#${Dt(this.r)}${Dt(this.g)}${Dt(this.b)}${Dt((isNaN(this.opacity)?1:this.opacity)*255)}`}function za(){const e=vn(this.opacity);return`${e===1?"rgb(":"rgba("}${kt(this.r)}, ${kt(this.g)}, ${kt(this.b)}${e===1?")":`, ${e})`}`}function vn(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function kt(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Dt(e){return e=kt(e),(e<16?"0":"")+e.toString(16)}function La(e,t,i,n){return n<=0?e=t=i=NaN:i<=0||i>=1?e=t=NaN:t<=0&&(e=NaN),new je(e,t,i,n)}function Wa(e){if(e instanceof je)return new je(e.h,e.s,e.l,e.opacity);if(e instanceof wi||(e=mt(e)),!e)return new je;if(e instanceof je)return e;e=e.rgb();var t=e.r/255,i=e.g/255,n=e.b/255,r=Math.min(t,i,n),s=Math.max(t,i,n),o=NaN,a=s-r,l=(s+r)/2;return a?(t===s?o=(i-n)/a+(i<n)*6:i===s?o=(n-t)/a+2:o=(t-i)/a+4,a/=l<.5?s+r:2-s-r,o*=60):a=l>0&&l<1?0:o,new je(o,a,l,e.opacity)}function ep(e,t,i,n){return arguments.length===1?Wa(e):new je(e,t,i,n??1)}function je(e,t,i,n){this.h=+e,this.s=+t,this.l=+i,this.opacity=+n}is(je,ep,Fa(wi,{brighter(e){return e=e==null?bn:Math.pow(bn,e),new je(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Ei:Math.pow(Ei,e),new je(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,i=this.l,n=i+(i<.5?i:1-i)*t,r=2*i-n;return new ke(rs(e>=240?e-240:e+120,r,n),rs(e,r,n),rs(e<120?e+240:e-120,r,n),this.opacity)},clamp(){return new je(Va(this.h),Pn(this.s),Pn(this.l),vn(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=vn(this.opacity);return`${e===1?"hsl(":"hsla("}${Va(this.h)}, ${Pn(this.s)*100}%, ${Pn(this.l)*100}%${e===1?")":`, ${e})`}`}}));function Va(e){return e=(e||0)%360,e<0?e+360:e}function Pn(e){return Math.max(0,Math.min(1,e||0))}function rs(e,t,i){return(e<60?t+(i-t)*e/60:e<180?i:e<240?t+(i-t)*(240-e)/60:t)*255}const ss=e=>()=>e;function tp(e,t){return function(i){return e+i*t}}function ip(e,t,i){return e=Math.pow(e,i),t=Math.pow(t,i)-e,i=1/i,function(n){return Math.pow(e+n*t,i)}}function np(e){return(e=+e)==1?Ha:function(t,i){return i-t?ip(t,i,e):ss(isNaN(t)?i:t)}}function Ha(e,t){var i=t-e;return i?tp(e,i):ss(isNaN(e)?t:e)}const Cn=function e(t){var i=np(t);function n(r,s){var o=i((r=ns(r)).r,(s=ns(s)).r),a=i(r.g,s.g),l=i(r.b,s.b),c=Ha(r.opacity,s.opacity);return function(u){return r.r=o(u),r.g=a(u),r.b=l(u),r.opacity=c(u),r+""}}return n.gamma=e,n}(1);function rp(e,t){t||(t=[]);var i=e?Math.min(t.length,e.length):0,n=t.slice(),r;return function(s){for(r=0;r<i;++r)n[r]=e[r]*(1-s)+t[r]*s;return n}}function sp(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function op(e,t){var i=t?t.length:0,n=e?Math.min(i,e.length):0,r=new Array(n),s=new Array(i),o;for(o=0;o<n;++o)r[o]=ls(e[o],t[o]);for(;o<i;++o)s[o]=t[o];return function(a){for(o=0;o<n;++o)s[o]=r[o](a);return s}}function ap(e,t){var i=new Date;return e=+e,t=+t,function(n){return i.setTime(e*(1-n)+t*n),i}}function Ke(e,t){return e=+e,t=+t,function(i){return e*(1-i)+t*i}}function lp(e,t){var i={},n={},r;(e===null||typeof e!="object")&&(e={}),(t===null||typeof t!="object")&&(t={});for(r in t)r in e?i[r]=ls(e[r],t[r]):n[r]=t[r];return function(s){for(r in i)n[r]=i[r](s);return n}}var os=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,as=new RegExp(os.source,"g");function cp(e){return function(){return e}}function up(e){return function(t){return e(t)+""}}function $a(e,t){var i=os.lastIndex=as.lastIndex=0,n,r,s,o=-1,a=[],l=[];for(e=e+"",t=t+"";(n=os.exec(e))&&(r=as.exec(t));)(s=r.index)>i&&(s=t.slice(i,s),a[o]?a[o]+=s:a[++o]=s),(n=n[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:Ke(n,r)})),i=as.lastIndex;return i<t.length&&(s=t.slice(i),a[o]?a[o]+=s:a[++o]=s),a.length<2?l[0]?up(l[0].x):cp(t):(t=l.length,function(c){for(var u=0,d;u<t;++u)a[(d=l[u]).i]=d.x(c);return a.join("")})}function ls(e,t){var i=typeof t,n;return t==null||i==="boolean"?ss(t):(i==="number"?Ke:i==="string"?(n=mt(t))?(t=n,Cn):$a:t instanceof mt?Cn:t instanceof Date?ap:sp(t)?rp:Array.isArray(t)?op:typeof t.valueOf!="function"&&typeof t.toString!="function"||isNaN(t)?lp:Ke)(e,t)}function dp(e,t){return e=+e,t=+t,function(i){return Math.round(e*(1-i)+t*i)}}var Xa=180/Math.PI,cs={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Ya(e,t,i,n,r,s){var o,a,l;return(o=Math.sqrt(e*e+t*t))&&(e/=o,t/=o),(l=e*i+t*n)&&(i-=e*l,n-=t*l),(a=Math.sqrt(i*i+n*n))&&(i/=a,n/=a,l/=a),e*n<t*i&&(e=-e,t=-t,l=-l,o=-o),{translateX:r,translateY:s,rotate:Math.atan2(t,e)*Xa,skewX:Math.atan(l)*Xa,scaleX:o,scaleY:a}}var An;function hp(e){const t=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(e+"");return t.isIdentity?cs:Ya(t.a,t.b,t.c,t.d,t.e,t.f)}function fp(e){return e==null||(An||(An=document.createElementNS("http://www.w3.org/2000/svg","g")),An.setAttribute("transform",e),!(e=An.transform.baseVal.consolidate()))?cs:(e=e.matrix,Ya(e.a,e.b,e.c,e.d,e.e,e.f))}function ja(e,t,i,n){function r(c){return c.length?c.pop()+" ":""}function s(c,u,d,h,p,g){if(c!==d||u!==h){var x=p.push("translate(",null,t,null,i);g.push({i:x-4,x:Ke(c,d)},{i:x-2,x:Ke(u,h)})}else(d||h)&&p.push("translate("+d+t+h+i)}function o(c,u,d,h){c!==u?(c-u>180?u+=360:u-c>180&&(c+=360),h.push({i:d.push(r(d)+"rotate(",null,n)-2,x:Ke(c,u)})):u&&d.push(r(d)+"rotate("+u+n)}function a(c,u,d,h){c!==u?h.push({i:d.push(r(d)+"skewX(",null,n)-2,x:Ke(c,u)}):u&&d.push(r(d)+"skewX("+u+n)}function l(c,u,d,h,p,g){if(c!==d||u!==h){var x=p.push(r(p)+"scale(",null,",",null,")");g.push({i:x-4,x:Ke(c,d)},{i:x-2,x:Ke(u,h)})}else(d!==1||h!==1)&&p.push(r(p)+"scale("+d+","+h+")")}return function(c,u){var d=[],h=[];return c=e(c),u=e(u),s(c.translateX,c.translateY,u.translateX,u.translateY,d,h),o(c.rotate,u.rotate,d,h),a(c.skewX,u.skewX,d,h),l(c.scaleX,c.scaleY,u.scaleX,u.scaleY,d,h),c=u=null,function(p){for(var g=-1,x=h.length,T;++g<x;)d[(T=h[g]).i]=T.x(p);return d.join("")}}}var pp=ja(hp,"px, ","px)","deg)"),gp=ja(fp,", ",")",")"),mp=1e-12;function Ka(e){return((e=Math.exp(e))+1/e)/2}function xp(e){return((e=Math.exp(e))-1/e)/2}function Sp(e){return((e=Math.exp(2*e))-1)/(e+1)}const yp=function e(t,i,n){function r(s,o){var a=s[0],l=s[1],c=s[2],u=o[0],d=o[1],h=o[2],p=u-a,g=d-l,x=p*p+g*g,T,S;if(x<mp)S=Math.log(h/c)/t,T=function(R){return[a+R*p,l+R*g,c*Math.exp(t*R*S)]};else{var P=Math.sqrt(x),I=(h*h-c*c+n*x)/(2*c*i*P),y=(h*h-c*c-n*x)/(2*h*i*P),v=Math.log(Math.sqrt(I*I+1)-I),E=Math.log(Math.sqrt(y*y+1)-y);S=(E-v)/t,T=function(R){var D=R*S,z=Ka(v),$=c/(i*P)*(z*Sp(t*D+v)-xp(v));return[a+$*p,l+$*g,c*z/Ka(t*D+v)]}}return T.duration=S*1e3*t/Math.SQRT2,T}return r.rho=function(s){var o=Math.max(.001,+s),a=o*o,l=a*a;return e(o,a,l)},r}(Math.SQRT2,2,4);function _p(e,t){var i,n;return function(){var r=tt(this,e),s=r.tween;if(s!==i){n=i=s;for(var o=0,a=n.length;o<a;++o)if(n[o].name===t){n=n.slice(),n.splice(o,1);break}}r.tween=n}}function bp(e,t,i){var n,r;if(typeof i!="function")throw new Error;return function(){var s=tt(this,e),o=s.tween;if(o!==n){r=(n=o).slice();for(var a={name:t,value:i},l=0,c=r.length;l<c;++l)if(r[l].name===t){r[l]=a;break}l===c&&r.push(a)}s.tween=r}}function Tp(e,t){var i=this._id;if(e+="",arguments.length<2){for(var n=Ye(this.node(),i).tween,r=0,s=n.length,o;r<s;++r)if((o=n[r]).name===e)return o.value;return null}return this.each((t==null?_p:bp)(i,e,t))}function us(e,t,i){var n=e._id;return e.each(function(){var r=tt(this,n);(r.value||(r.value={}))[t]=i.apply(this,arguments)}),function(r){return Ye(r,n).value[t]}}function qa(e,t){var i;return(typeof t=="number"?Ke:t instanceof mt?Cn:(i=mt(t))?(t=i,Cn):$a)(e,t)}function vp(e){return function(){this.removeAttribute(e)}}function Pp(e){return function(){this.removeAttributeNS(e.space,e.local)}}function Cp(e,t,i){var n,r=i+"",s;return function(){var o=this.getAttribute(e);return o===r?null:o===n?s:s=t(n=o,i)}}function Ap(e,t,i){var n,r=i+"",s;return function(){var o=this.getAttributeNS(e.space,e.local);return o===r?null:o===n?s:s=t(n=o,i)}}function Rp(e,t,i){var n,r,s;return function(){var o,a=i(this),l;return a==null?void this.removeAttribute(e):(o=this.getAttribute(e),l=a+"",o===l?null:o===n&&l===r?s:(r=l,s=t(n=o,a)))}}function wp(e,t,i){var n,r,s;return function(){var o,a=i(this),l;return a==null?void this.removeAttributeNS(e.space,e.local):(o=this.getAttributeNS(e.space,e.local),l=a+"",o===l?null:o===n&&l===r?s:(r=l,s=t(n=o,a)))}}function Ep(e,t){var i=cn(e),n=i==="transform"?gp:qa;return this.attrTween(e,typeof t=="function"?(i.local?wp:Rp)(i,n,us(this,"attr."+e,t)):t==null?(i.local?Pp:vp)(i):(i.local?Ap:Cp)(i,n,t))}function Ip(e,t){return function(i){this.setAttribute(e,t.call(this,i))}}function kp(e,t){return function(i){this.setAttributeNS(e.space,e.local,t.call(this,i))}}function Dp(e,t){var i,n;function r(){var s=t.apply(this,arguments);return s!==n&&(i=(n=s)&&kp(e,s)),i}return r._value=t,r}function Fp(e,t){var i,n;function r(){var s=t.apply(this,arguments);return s!==n&&(i=(n=s)&&Ip(e,s)),i}return r._value=t,r}function Mp(e,t){var i="attr."+e;if(arguments.length<2)return(i=this.tween(i))&&i._value;if(t==null)return this.tween(i,null);if(typeof t!="function")throw new Error;var n=cn(e);return this.tween(i,(n.local?Dp:Fp)(n,t))}function Np(e,t){return function(){ts(this,e).delay=+t.apply(this,arguments)}}function Bp(e,t){return t=+t,function(){ts(this,e).delay=t}}function Op(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?Np:Bp)(t,e)):Ye(this.node(),t).delay}function Up(e,t){return function(){tt(this,e).duration=+t.apply(this,arguments)}}function zp(e,t){return t=+t,function(){tt(this,e).duration=t}}function Lp(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?Up:zp)(t,e)):Ye(this.node(),t).duration}function Wp(e,t){if(typeof t!="function")throw new Error;return function(){tt(this,e).ease=t}}function Vp(e){var t=this._id;return arguments.length?this.each(Wp(t,e)):Ye(this.node(),t).ease}function Hp(e,t){return function(){var i=t.apply(this,arguments);if(typeof i!="function")throw new Error;tt(this,e).ease=i}}function $p(e){if(typeof e!="function")throw new Error;return this.each(Hp(this._id,e))}function Xp(e){typeof e!="function"&&(e=pa(e));for(var t=this._groups,i=t.length,n=new Array(i),r=0;r<i;++r)for(var s=t[r],o=s.length,a=n[r]=[],l,c=0;c<o;++c)(l=s[c])&&e.call(l,l.__data__,c,s)&&a.push(l);return new ut(n,this._parents,this._name,this._id)}function Yp(e){if(e._id!==this._id)throw new Error;for(var t=this._groups,i=e._groups,n=t.length,r=i.length,s=Math.min(n,r),o=new Array(n),a=0;a<s;++a)for(var l=t[a],c=i[a],u=l.length,d=o[a]=new Array(u),h,p=0;p<u;++p)(h=l[p]||c[p])&&(d[p]=h);for(;a<n;++a)o[a]=t[a];return new ut(o,this._parents,this._name,this._id)}function jp(e){return(e+"").trim().split(/^|\s+/).every(function(t){var i=t.indexOf(".");return i>=0&&(t=t.slice(0,i)),!t||t==="start"})}function Kp(e,t,i){var n,r,s=jp(t)?ts:tt;return function(){var o=s(this,e),a=o.on;a!==n&&(r=(n=a).copy()).on(t,i),o.on=r}}function qp(e,t){var i=this._id;return arguments.length<2?Ye(this.node(),i).on.on(e):this.each(Kp(i,e,t))}function Gp(e){return function(){var t=this.parentNode;for(var i in this.__transition)if(+i!==e)return;t&&t.removeChild(this)}}function Zp(){return this.on("end.remove",Gp(this._id))}function Qp(e){var t=this._name,i=this._id;typeof e!="function"&&(e=qr(e));for(var n=this._groups,r=n.length,s=new Array(r),o=0;o<r;++o)for(var a=n[o],l=a.length,c=s[o]=new Array(l),u,d,h=0;h<l;++h)(u=a[h])&&(d=e.call(u,u.__data__,h,a))&&("__data__"in u&&(d.__data__=u.__data__),c[h]=d,yn(c[h],t,i,h,c,Ye(u,i)));return new ut(s,this._parents,t,i)}function Jp(e){var t=this._name,i=this._id;typeof e!="function"&&(e=fa(e));for(var n=this._groups,r=n.length,s=[],o=[],a=0;a<r;++a)for(var l=n[a],c=l.length,u,d=0;d<c;++d)if(u=l[d]){for(var h=e.call(u,u.__data__,d,l),p,g=Ye(u,i),x=0,T=h.length;x<T;++x)(p=h[x])&&yn(p,t,i,x,h,g);s.push(h),o.push(u)}return new ut(s,o,t,i)}var eg=vi.prototype.constructor;function tg(){return new eg(this._groups,this._parents)}function ig(e,t){var i,n,r;return function(){var s=Ht(this,e),o=(this.style.removeProperty(e),Ht(this,e));return s===o?null:s===i&&o===n?r:r=t(i=s,n=o)}}function Ga(e){return function(){this.style.removeProperty(e)}}function ng(e,t,i){var n,r=i+"",s;return function(){var o=Ht(this,e);return o===r?null:o===n?s:s=t(n=o,i)}}function rg(e,t,i){var n,r,s;return function(){var o=Ht(this,e),a=i(this),l=a+"";return a==null&&(l=a=(this.style.removeProperty(e),Ht(this,e))),o===l?null:o===n&&l===r?s:(r=l,s=t(n=o,a))}}function sg(e,t){var i,n,r,s="style."+t,o="end."+s,a;return function(){var l=tt(this,e),c=l.on,u=l.value[s]==null?a||(a=Ga(t)):void 0;(c!==i||r!==u)&&(n=(i=c).copy()).on(o,r=u),l.on=n}}function og(e,t,i){var n=(e+="")=="transform"?pp:qa;return t==null?this.styleTween(e,ig(e,n)).on("end.style."+e,Ga(e)):typeof t=="function"?this.styleTween(e,rg(e,n,us(this,"style."+e,t))).each(sg(this._id,e)):this.styleTween(e,ng(e,n,t),i).on("end.style."+e,null)}function ag(e,t,i){return function(n){this.style.setProperty(e,t.call(this,n),i)}}function lg(e,t,i){var n,r;function s(){var o=t.apply(this,arguments);return o!==r&&(n=(r=o)&&ag(e,o,i)),n}return s._value=t,s}function cg(e,t,i){var n="style."+(e+="");if(arguments.length<2)return(n=this.tween(n))&&n._value;if(t==null)return this.tween(n,null);if(typeof t!="function")throw new Error;return this.tween(n,lg(e,t,i??""))}function ug(e){return function(){this.textContent=e}}function dg(e){return function(){var t=e(this);this.textContent=t??""}}function hg(e){return this.tween("text",typeof e=="function"?dg(us(this,"text",e)):ug(e==null?"":e+""))}function fg(e){return function(t){this.textContent=e.call(this,t)}}function pg(e){var t,i;function n(){var r=e.apply(this,arguments);return r!==i&&(t=(i=r)&&fg(r)),t}return n._value=e,n}function gg(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(e==null)return this.tween(t,null);if(typeof e!="function")throw new Error;return this.tween(t,pg(e))}function mg(){for(var e=this._name,t=this._id,i=Za(),n=this._groups,r=n.length,s=0;s<r;++s)for(var o=n[s],a=o.length,l,c=0;c<a;++c)if(l=o[c]){var u=Ye(l,t);yn(l,e,i,c,o,{time:u.time+u.delay+u.duration,delay:0,duration:u.duration,ease:u.ease})}return new ut(n,this._parents,e,i)}function xg(){var e,t,i=this,n=i._id,r=i.size();return new Promise(function(s,o){var a={value:o},l={value:function(){--r===0&&s()}};i.each(function(){var c=tt(this,n),u=c.on;u!==e&&(t=(e=u).copy(),t._.cancel.push(a),t._.interrupt.push(a),t._.end.push(l)),c.on=t}),r===0&&s()})}var Sg=0;function ut(e,t,i,n){this._groups=e,this._parents=t,this._name=i,this._id=n}function Za(){return++Sg}var dt=vi.prototype;ut.prototype={constructor:ut,select:Qp,selectAll:Jp,selectChild:dt.selectChild,selectChildren:dt.selectChildren,filter:Xp,merge:Yp,selection:tg,transition:mg,call:dt.call,nodes:dt.nodes,node:dt.node,size:dt.size,empty:dt.empty,each:dt.each,on:qp,attr:Ep,attrTween:Mp,style:og,styleTween:cg,text:hg,textTween:gg,remove:Zp,tween:Tp,delay:Op,duration:Lp,ease:Vp,easeVarying:$p,end:xg,[Symbol.iterator]:dt[Symbol.iterator]};const Qa=e=>+e;function Ja(e){return e*e}function el(e){return e*(2-e)}function tl(e){return((e*=2)<=1?e*e:--e*(2-e)+1)/2}function yg(e){return e*e*e}function _g(e){return--e*e*e+1}function il(e){return((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2}var nl=Math.PI,rl=nl/2;function bg(e){return+e==1?1:1-Math.cos(e*rl)}function Tg(e){return Math.sin(e*rl)}function vg(e){return(1-Math.cos(nl*e))/2}function Rn(e){return(Math.pow(2,-10*e)-.0009765625)*1.0009775171065494}function Pg(e){return Rn(1-+e)}function Cg(e){return 1-Rn(e)}function Ag(e){return((e*=2)<=1?Rn(1-e):2-Rn(e-1))/2}function Rg(e){return 1-Math.sqrt(1-e*e)}function wg(e){return Math.sqrt(1- --e*e)}function Eg(e){return((e*=2)<=1?1-Math.sqrt(1-e*e):Math.sqrt(1-(e-=2)*e)+1)/2}var Ig={time:null,delay:0,duration:250,ease:il};function kg(e,t){for(var i;!(i=e.__transition)||!(i=i[t]);)if(!(e=e.parentNode))throw new Error(`transition ${t} not found`);return i}function Dg(e){var t,i;e instanceof ut?(t=e._id,e=e._name):(t=Za(),(i=Ig).time=Zr(),e=e==null?null:e+"");for(var n=this._groups,r=n.length,s=0;s<r;++s)for(var o=n[s],a=o.length,l,c=0;c<a;++c)(l=o[c])&&yn(l,e,t,c,o,i||kg(l,t));return new ut(n,this._parents,e,t)}vi.prototype.interrupt=Vf,vi.prototype.transition=Dg;const Fg={passive:!1},ki={capture:!0,passive:!1};function ds(e){e.stopImmediatePropagation()}function Yt(e){e.preventDefault(),e.stopImmediatePropagation()}function sl(e){var t=e.document.documentElement,i=ye(e).on("dragstart.drag",Yt,ki);"onselectstart"in t?i.on("selectstart.drag",Yt,ki):(t.__noselect=t.style.MozUserSelect,t.style.MozUserSelect="none")}function ol(e,t){var i=e.document.documentElement,n=ye(e).on("dragstart.drag",null);t&&(n.on("click.drag",Yt,ki),setTimeout(function(){n.on("click.drag",null)},0)),"onselectstart"in i?n.on("selectstart.drag",null):(i.style.MozUserSelect=i.__noselect,delete i.__noselect)}const wn=e=>()=>e;function hs(e,{sourceEvent:t,subject:i,target:n,identifier:r,active:s,x:o,y:a,dx:l,dy:c,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:i,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},identifier:{value:r,enumerable:!0,configurable:!0},active:{value:s,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:a,enumerable:!0,configurable:!0},dx:{value:l,enumerable:!0,configurable:!0},dy:{value:c,enumerable:!0,configurable:!0},_:{value:u}})}hs.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function Mg(e){return!e.ctrlKey&&!e.button}function Ng(){return this.parentNode}function Bg(e,t){return t??{x:e.x,y:e.y}}function Og(){return navigator.maxTouchPoints||"ontouchstart"in this}function Ug(){var e=Mg,t=Ng,i=Bg,n=Og,r={},s=dn("start","drag","end"),o=0,a,l,c,u,d=0;function h(y){y.on("mousedown.drag",p).filter(n).on("touchstart.drag",T).on("touchmove.drag",S,Fg).on("touchend.drag touchcancel.drag",P).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function p(y,v){if(!(u||!e.call(this,y,v))){var E=I(this,t.call(this,y,v),y,v,"mouse");E&&(ye(y.view).on("mousemove.drag",g,ki).on("mouseup.drag",x,ki),sl(y.view),ds(y),c=!1,a=y.clientX,l=y.clientY,E("start",y))}}function g(y){if(Yt(y),!c){var v=y.clientX-a,E=y.clientY-l;c=v*v+E*E>d}r.mouse("drag",y)}function x(y){ye(y.view).on("mousemove.drag mouseup.drag",null),ol(y.view,c),Yt(y),r.mouse("end",y)}function T(y,v){if(e.call(this,y,v)){var E=y.changedTouches,R=t.call(this,y,v),D=E.length,z,$;for(z=0;z<D;++z)($=I(this,R,y,v,E[z].identifier,E[z]))&&(ds(y),$("start",y,E[z]))}}function S(y){var v=y.changedTouches,E=v.length,R,D;for(R=0;R<E;++R)(D=r[v[R].identifier])&&(Yt(y),D("drag",y,v[R]))}function P(y){var v=y.changedTouches,E=v.length,R,D;for(u&&clearTimeout(u),u=setTimeout(function(){u=null},500),R=0;R<E;++R)(D=r[v[R].identifier])&&(ds(y),D("end",y,v[R]))}function I(y,v,E,R,D,z){var $=s.copy(),F=ct(z||E,v),Q,X,b;if((b=i.call(y,new hs("beforestart",{sourceEvent:E,target:h,identifier:D,active:o,x:F[0],y:F[1],dx:0,dy:0,dispatch:$}),R))!=null)return Q=b.x-F[0]||0,X=b.y-F[1]||0,function N(A,O,V){var L=F,Y;switch(A){case"start":r[D]=N,Y=o++;break;case"end":delete r[D],--o;case"drag":F=ct(V||O,v),Y=o;break}$.call(A,y,new hs(A,{sourceEvent:O,subject:b,target:h,identifier:D,active:Y,x:F[0]+Q,y:F[1]+X,dx:F[0]-L[0],dy:F[1]-L[1],dispatch:$}),R)}}return h.filter=function(y){return arguments.length?(e=typeof y=="function"?y:wn(!!y),h):e},h.container=function(y){return arguments.length?(t=typeof y=="function"?y:wn(y),h):t},h.subject=function(y){return arguments.length?(i=typeof y=="function"?y:wn(y),h):i},h.touchable=function(y){return arguments.length?(n=typeof y=="function"?y:wn(!!y),h):n},h.on=function(){var y=s.on.apply(s,arguments);return y===s?h:y},h.clickDistance=function(y){return arguments.length?(d=(y=+y)*y,h):Math.sqrt(d)},h}const En=e=>()=>e;function zg(e,{sourceEvent:t,target:i,transform:n,dispatch:r}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:i,enumerable:!0,configurable:!0},transform:{value:n,enumerable:!0,configurable:!0},_:{value:r}})}function ht(e,t,i){this.k=e,this.x=t,this.y=i}ht.prototype={constructor:ht,scale:function(e){return e===1?this:new ht(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new ht(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var jt=new ht(1,0,0);ht.prototype;function fs(e){e.stopImmediatePropagation()}function Di(e){e.preventDefault(),e.stopImmediatePropagation()}function Lg(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function Wg(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function al(){return this.__zoom||jt}function Vg(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function Hg(){return navigator.maxTouchPoints||"ontouchstart"in this}function $g(e,t,i){var n=e.invertX(t[0][0])-i[0][0],r=e.invertX(t[1][0])-i[1][0],s=e.invertY(t[0][1])-i[0][1],o=e.invertY(t[1][1])-i[1][1];return e.translate(r>n?(n+r)/2:Math.min(0,n)||Math.max(0,r),o>s?(s+o)/2:Math.min(0,s)||Math.max(0,o))}function Xg(){var e=Lg,t=Wg,i=$g,n=Vg,r=Hg,s=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],a=250,l=yp,c=dn("start","zoom","end"),u,d,h,p=500,g=150,x=0,T=10;function S(b){b.property("__zoom",al).on("wheel.zoom",D,{passive:!1}).on("mousedown.zoom",z).on("dblclick.zoom",$).filter(r).on("touchstart.zoom",F).on("touchmove.zoom",Q).on("touchend.zoom touchcancel.zoom",X).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}S.transform=function(b,N,A,O){var V=b.selection?b.selection():b;V.property("__zoom",al),b!==V?v(b,N,A,O):V.interrupt().each(function(){E(this,arguments).event(O).start().zoom(null,typeof N=="function"?N.apply(this,arguments):N).end()})},S.scaleBy=function(b,N,A,O){S.scaleTo(b,function(){var V=this.__zoom.k,L=typeof N=="function"?N.apply(this,arguments):N;return V*L},A,O)},S.scaleTo=function(b,N,A,O){S.transform(b,function(){var V=t.apply(this,arguments),L=this.__zoom,Y=A==null?y(V):typeof A=="function"?A.apply(this,arguments):A,J=L.invert(Y),H=typeof N=="function"?N.apply(this,arguments):N;return i(I(P(L,H),Y,J),V,o)},A,O)},S.translateBy=function(b,N,A,O){S.transform(b,function(){return i(this.__zoom.translate(typeof N=="function"?N.apply(this,arguments):N,typeof A=="function"?A.apply(this,arguments):A),t.apply(this,arguments),o)},null,O)},S.translateTo=function(b,N,A,O,V){S.transform(b,function(){var L=t.apply(this,arguments),Y=this.__zoom,J=O==null?y(L):typeof O=="function"?O.apply(this,arguments):O;return i(jt.translate(J[0],J[1]).scale(Y.k).translate(typeof N=="function"?-N.apply(this,arguments):-N,typeof A=="function"?-A.apply(this,arguments):-A),L,o)},O,V)};function P(b,N){return N=Math.max(s[0],Math.min(s[1],N)),N===b.k?b:new ht(N,b.x,b.y)}function I(b,N,A){var O=N[0]-A[0]*b.k,V=N[1]-A[1]*b.k;return O===b.x&&V===b.y?b:new ht(b.k,O,V)}function y(b){return[(+b[0][0]+ +b[1][0])/2,(+b[0][1]+ +b[1][1])/2]}function v(b,N,A,O){b.on("start.zoom",function(){E(this,arguments).event(O).start()}).on("interrupt.zoom end.zoom",function(){E(this,arguments).event(O).end()}).tween("zoom",function(){var V=this,L=arguments,Y=E(V,L).event(O),J=t.apply(V,L),H=A==null?y(J):typeof A=="function"?A.apply(V,L):A,Xe=Math.max(J[1][0]-J[0][0],J[1][1]-J[0][1]),Se=V.__zoom,ze=typeof N=="function"?N.apply(V,L):N,Je=l(Se.invert(H).concat(Xe/Se.k),ze.invert(H).concat(Xe/ze.k));return function(Le){if(Le===1)Le=ze;else{var et=Je(Le),xi=Xe/et[2];Le=new ht(xi,H[0]-et[0]*xi,H[1]-et[1]*xi)}Y.zoom(null,Le)}})}function E(b,N,A){return!A&&b.__zooming||new R(b,N)}function R(b,N){this.that=b,this.args=N,this.active=0,this.sourceEvent=null,this.extent=t.apply(b,N),this.taps=0}R.prototype={event:function(b){return b&&(this.sourceEvent=b),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(b,N){return this.mouse&&b!=="mouse"&&(this.mouse[1]=N.invert(this.mouse[0])),this.touch0&&b!=="touch"&&(this.touch0[1]=N.invert(this.touch0[0])),this.touch1&&b!=="touch"&&(this.touch1[1]=N.invert(this.touch1[0])),this.that.__zoom=N,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(b){var N=ye(this.that).datum();c.call(b,this.that,new zg(b,{sourceEvent:this.sourceEvent,target:S,transform:this.that.__zoom,dispatch:c}),N)}};function D(b,...N){if(!e.apply(this,arguments))return;var A=E(this,N).event(b),O=this.__zoom,V=Math.max(s[0],Math.min(s[1],O.k*Math.pow(2,n.apply(this,arguments)))),L=ct(b);if(A.wheel)(A.mouse[0][0]!==L[0]||A.mouse[0][1]!==L[1])&&(A.mouse[1]=O.invert(A.mouse[0]=L)),clearTimeout(A.wheel);else{if(O.k===V)return;A.mouse=[L,O.invert(L)],_n(this),A.start()}Di(b),A.wheel=setTimeout(Y,g),A.zoom("mouse",i(I(P(O,V),A.mouse[0],A.mouse[1]),A.extent,o));function Y(){A.wheel=null,A.end()}}function z(b,...N){if(h||!e.apply(this,arguments))return;var A=b.currentTarget,O=E(this,N,!0).event(b),V=ye(b.view).on("mousemove.zoom",H,!0).on("mouseup.zoom",Xe,!0),L=ct(b,A),Y=b.clientX,J=b.clientY;sl(b.view),fs(b),O.mouse=[L,this.__zoom.invert(L)],_n(this),O.start();function H(Se){if(Di(Se),!O.moved){var ze=Se.clientX-Y,Je=Se.clientY-J;O.moved=ze*ze+Je*Je>x}O.event(Se).zoom("mouse",i(I(O.that.__zoom,O.mouse[0]=ct(Se,A),O.mouse[1]),O.extent,o))}function Xe(Se){V.on("mousemove.zoom mouseup.zoom",null),ol(Se.view,O.moved),Di(Se),O.event(Se).end()}}function $(b,...N){if(e.apply(this,arguments)){var A=this.__zoom,O=ct(b.changedTouches?b.changedTouches[0]:b,this),V=A.invert(O),L=A.k*(b.shiftKey?.5:2),Y=i(I(P(A,L),O,V),t.apply(this,N),o);Di(b),a>0?ye(this).transition().duration(a).call(v,Y,O,b):ye(this).call(S.transform,Y,O,b)}}function F(b,...N){if(e.apply(this,arguments)){var A=b.touches,O=A.length,V=E(this,N,b.changedTouches.length===O).event(b),L,Y,J,H;for(fs(b),Y=0;Y<O;++Y)J=A[Y],H=ct(J,this),H=[H,this.__zoom.invert(H),J.identifier],V.touch0?!V.touch1&&V.touch0[2]!==H[2]&&(V.touch1=H,V.taps=0):(V.touch0=H,L=!0,V.taps=1+!!u);u&&(u=clearTimeout(u)),L&&(V.taps<2&&(d=H[0],u=setTimeout(function(){u=null},p)),_n(this),V.start())}}function Q(b,...N){if(this.__zooming){var A=E(this,N).event(b),O=b.changedTouches,V=O.length,L,Y,J,H;for(Di(b),L=0;L<V;++L)Y=O[L],J=ct(Y,this),A.touch0&&A.touch0[2]===Y.identifier?A.touch0[0]=J:A.touch1&&A.touch1[2]===Y.identifier&&(A.touch1[0]=J);if(Y=A.that.__zoom,A.touch1){var Xe=A.touch0[0],Se=A.touch0[1],ze=A.touch1[0],Je=A.touch1[1],Le=(Le=ze[0]-Xe[0])*Le+(Le=ze[1]-Xe[1])*Le,et=(et=Je[0]-Se[0])*et+(et=Je[1]-Se[1])*et;Y=P(Y,Math.sqrt(Le/et)),J=[(Xe[0]+ze[0])/2,(Xe[1]+ze[1])/2],H=[(Se[0]+Je[0])/2,(Se[1]+Je[1])/2]}else if(A.touch0)J=A.touch0[0],H=A.touch0[1];else return;A.zoom("touch",i(I(Y,J,H),A.extent,o))}}function X(b,...N){if(this.__zooming){var A=E(this,N).event(b),O=b.changedTouches,V=O.length,L,Y;for(fs(b),h&&clearTimeout(h),h=setTimeout(function(){h=null},p),L=0;L<V;++L)Y=O[L],A.touch0&&A.touch0[2]===Y.identifier?delete A.touch0:A.touch1&&A.touch1[2]===Y.identifier&&delete A.touch1;if(A.touch1&&!A.touch0&&(A.touch0=A.touch1,delete A.touch1),A.touch0)A.touch0[1]=this.__zoom.invert(A.touch0[0]);else if(A.end(),A.taps===2&&(Y=ct(Y,this),Math.hypot(d[0]-Y[0],d[1]-Y[1])<T)){var J=ye(this).on("dblclick.zoom");J&&J.apply(this,arguments)}}}return S.wheelDelta=function(b){return arguments.length?(n=typeof b=="function"?b:En(+b),S):n},S.filter=function(b){return arguments.length?(e=typeof b=="function"?b:En(!!b),S):e},S.touchable=function(b){return arguments.length?(r=typeof b=="function"?b:En(!!b),S):r},S.extent=function(b){return arguments.length?(t=typeof b=="function"?b:En([[+b[0][0],+b[0][1]],[+b[1][0],+b[1][1]]]),S):t},S.scaleExtent=function(b){return arguments.length?(s[0]=+b[0],s[1]=+b[1],S):[s[0],s[1]]},S.translateExtent=function(b){return arguments.length?(o[0][0]=+b[0][0],o[1][0]=+b[1][0],o[0][1]=+b[0][1],o[1][1]=+b[1][1],S):[[o[0][0],o[0][1]],[o[1][0],o[1][1]]]},S.constrain=function(b){return arguments.length?(i=b,S):i},S.duration=function(b){return arguments.length?(a=+b,S):a},S.interpolate=function(b){return arguments.length?(l=b,S):l},S.on=function(){var b=c.on.apply(c,arguments);return b===c?S:b},S.clickDistance=function(b){return arguments.length?(x=(b=+b)*b,S):Math.sqrt(x)},S.tapDistance=function(b){return arguments.length?(T=+b,S):T},S}/*! @license DOMPurify 3.4.13 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.13/LICENSE */function ll(e,t){(t==null||t>e.length)&&(t=e.length);for(var i=0,n=Array(t);i<t;i++)n[i]=e[i];return n}function Yg(e){if(Array.isArray(e))return e}function jg(e,t){var i=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(i!=null){var n,r,s,o,a=[],l=!0,c=!1;try{if(s=(i=i.call(e)).next,t!==0)for(;!(l=(n=s.call(i)).done)&&(a.push(n.value),a.length!==t);l=!0);}catch(u){c=!0,r=u}finally{try{if(!l&&i.return!=null&&(o=i.return(),Object(o)!==o))return}finally{if(c)throw r}}return a}}function Kg(){throw new TypeError(`Invalid attempt to destructure non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function qg(e,t){return Yg(e)||jg(e,t)||Gg(e,t)||Kg()}function Gg(e,t){if(e){if(typeof e=="string")return ll(e,t);var i={}.toString.call(e).slice(8,-1);return i==="Object"&&e.constructor&&(i=e.constructor.name),i==="Map"||i==="Set"?Array.from(e):i==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?ll(e,t):void 0}}const cl=Object.entries,ul=Object.setPrototypeOf,Zg=Object.isFrozen,Qg=Object.getPrototypeOf,Jg=Object.getOwnPropertyDescriptor;let Te=Object.freeze,ve=Object.seal,Kt=Object.create,dl=typeof Reflect<"u"&&Reflect,ps=dl.apply,gs=dl.construct;Te||(Te=function(t){return t}),ve||(ve=function(t){return t}),ps||(ps=function(t,i){for(var n=arguments.length,r=new Array(n>2?n-2:0),s=2;s<n;s++)r[s-2]=arguments[s];return t.apply(i,r)}),gs||(gs=function(t){for(var i=arguments.length,n=new Array(i>1?i-1:0),r=1;r<i;r++)n[r-1]=arguments[r];return new t(...n)});const qt=me(Array.prototype.forEach),em=me(Array.prototype.lastIndexOf),hl=me(Array.prototype.pop),Gt=me(Array.prototype.push),tm=me(Array.prototype.splice),xt=Array.isArray,Fi=me(String.prototype.toLowerCase),ms=me(String.prototype.toString),fl=me(String.prototype.match),Mi=me(String.prototype.replace),pl=me(String.prototype.indexOf),im=me(String.prototype.trim),nm=me(Number.prototype.toString),rm=me(Boolean.prototype.toString),gl=typeof BigInt>"u"?null:me(BigInt.prototype.toString),ml=typeof Symbol>"u"?null:me(Symbol.prototype.toString),_e=me(Object.prototype.hasOwnProperty),Ni=me(Object.prototype.toString),be=me(RegExp.prototype.test),Ft=sm(TypeError);function me(e){return function(t){t instanceof RegExp&&(t.lastIndex=0);for(var i=arguments.length,n=new Array(i>1?i-1:0),r=1;r<i;r++)n[r-1]=arguments[r];return ps(e,t,n)}}function sm(e){return function(){for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];return gs(e,i)}}function G(e,t){let i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Fi;if(ul&&ul(e,null),!xt(t))return e;let n=t.length;for(;n--;){let r=t[n];if(typeof r=="string"){const s=i(r);s!==r&&(Zg(t)||(t[n]=s),r=s)}e[r]=!0}return e}function om(e){for(let t=0;t<e.length;t++)_e(e,t)||(e[t]=null);return e}function Ce(e){const t=Kt(null);for(const n of cl(e)){var i=qg(n,2);const r=i[0],s=i[1];_e(e,r)&&(xt(s)?t[r]=om(s):s&&typeof s=="object"&&s.constructor===Object?t[r]=Ce(s):t[r]=s)}return t}function am(e){switch(typeof e){case"string":return e;case"number":return nm(e);case"boolean":return rm(e);case"bigint":return gl?gl(e):"0";case"symbol":return ml?ml(e):"Symbol()";case"undefined":return Ni(e);case"function":case"object":{if(e===null)return Ni(e);const t=e,i=qe(t,"toString");if(typeof i=="function"){const n=i(t);return typeof n=="string"?n:Ni(n)}return Ni(e)}default:return Ni(e)}}function qe(e,t){for(;e!==null;){const n=Jg(e,t);if(n){if(n.get)return me(n.get);if(typeof n.value=="function")return me(n.value)}e=Qg(e)}function i(){return null}return i}function lm(e){try{return be(e,""),!0}catch{return!1}}const xl=Te(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","search","section","select","shadow","slot","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),xs=Te(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","enterkeyhint","exportparts","filter","font","g","glyph","glyphref","hkern","image","inputmode","line","lineargradient","marker","mask","metadata","mpath","part","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),Ss=Te(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),cm=Te(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),ys=Te(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),um=Te(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),Sl=Te(["#text"]),yl=Te(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","command","commandfor","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","exportparts","face","for","headers","height","hidden","high","href","hreflang","id","inert","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","part","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","slot","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns"]),_s=Te(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dominant-baseline","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","mask-type","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-orientation","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),_l=Te(["accent","accentunder","align","bevelled","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lquote","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),In=Te(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),dm=ve(/{{[\w\W]*|^[\w\W]*}}/g),hm=ve(/<%[\w\W]*|^[\w\W]*%>/g),fm=ve(/\${[\w\W]*/g),pm=ve(/^data-[\-\w.\u00B7-\uFFFF]+$/),gm=ve(/^aria-[\-\w]+$/),bl=ve(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),mm=ve(/^(?:\w+script|data):/i),xm=ve(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Sm=ve(/^html$/i),ym=ve(/^[a-z][.\w]*(-[.\w]+)+$/i),Tl=ve(/<[/\w!]/g),vl=ve(/<[/\w]/g),_m=ve(/<\/no(script|embed|frames)/i),bm=ve(/\/>/i),Oe={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,processingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},Tm=function(){return typeof window>"u"?null:window},vm=function(t,i){if(typeof t!="object"||typeof t.createPolicy!="function")return null;let n=null;const r="data-tt-policy-suffix";i&&i.hasAttribute(r)&&(n=i.getAttribute(r));const s="dompurify"+(n?"#"+n:"");try{return t.createPolicy(s,{createHTML(o){return o},createScriptURL(o){return o}})}catch{return console.warn("TrustedTypes policy "+s+" could not be created."),null}},Pl=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},St=function(t,i,n,r){return _e(t,i)&&xt(t[i])?G(r.base?Ce(r.base):{},t[i],r.transform):n};function Cl(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Tm();const t=k=>Cl(k);if(t.version="3.4.13",t.removed=[],!e||!e.document||e.document.nodeType!==Oe.document||!e.Element)return t.isSupported=!1,t;let i=e.document;const n=i,r=n.currentScript;e.DocumentFragment;const s=e.HTMLTemplateElement,o=e.Node,a=e.Element,l=e.NodeFilter,c=e.NamedNodeMap;c===void 0&&(e.NamedNodeMap||e.MozNamedAttrMap),e.HTMLFormElement;const u=e.DOMParser,d=e.trustedTypes,h=a.prototype,p=qe(h,"cloneNode"),g=qe(h,"remove"),x=qe(h,"nextSibling"),T=qe(h,"childNodes"),S=qe(h,"parentNode"),P=qe(h,"shadowRoot"),I=qe(h,"attributes"),y=o&&o.prototype?qe(o.prototype,"nodeType"):null,v=o&&o.prototype?qe(o.prototype,"nodeName"):null,E=o&&o.prototype?qe(o.prototype,"ownerDocument"):null;if(typeof s=="function"){const k=i.createElement("template");k.content&&k.content.ownerDocument&&(i=k.content.ownerDocument)}let R,D="",z,$=!1,F=0;const Q=function(){if(F>0)throw Ft('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},X=function(m){Q(),F++;try{return R.createHTML(m)}finally{F--}},b=function(m){Q(),F++;try{return R.createScriptURL(m)}finally{F--}},N=function(){return $||(z=vm(d,r),$=!0),z},A=i,O=A.implementation,V=A.createNodeIterator,L=A.createDocumentFragment,Y=A.getElementsByTagName,J=n.importNode;let H=Pl();t.isSupported=typeof cl=="function"&&typeof S=="function"&&O&&O.createHTMLDocument!==void 0;const Xe=dm,Se=hm,ze=fm,Je=pm,Le=gm,et=mm,xi=xm,Lv=ym;let Ed=bl,ce=null;const Go=G({},[...xl,...xs,...Ss,...ys,...Sl]);let ue=null;const Zo=G({},[...yl,..._s,..._l,...In]);let pe=Object.seal(Kt(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),sn=null,Id=null;const Ct=Object.seal(Kt(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let kd=!0,Qo=!0,Dd=!1,Fd=!0,At=!1,Rt=!0,Wt=!1,Jo=!1,Ur=null,zr=null,ea=!1,Si=!1,Lr=!1,Wr=!1,Md=!0,Nd=!1;const Bd="user-content-";let ta=!0,Vr=!1,yi={},ot=null;const ia=G({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let Od=null;const Ud=G({},["audio","video","img","source","image","track"]);let na=null;const zd=G({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Hr="http://www.w3.org/1998/Math/MathML",$r="http://www.w3.org/2000/svg",at="http://www.w3.org/1999/xhtml";let _i=at,ra=!1,sa=null;const Wv=G({},[Hr,$r,at],ms),Ld=Te(["mi","mo","mn","ms","mtext"]);let oa=G({},Ld);const Wd=Te(["annotation-xml"]);let aa=G({},Wd);const Vv=G({},["title","style","font","a","script"]);let on=null;const Hv=["application/xhtml+xml","text/html"],$v="text/html";let de=null,bi=null;const Xv=i.createElement("form"),Vd=function(m){return m instanceof RegExp||m instanceof Function},la=function(){let m=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(bi&&bi===m)return;(!m||typeof m!="object")&&(m={}),m=Ce(m),on=Hv.indexOf(m.PARSER_MEDIA_TYPE)===-1?$v:m.PARSER_MEDIA_TYPE,de=on==="application/xhtml+xml"?ms:Fi,ce=St(m,"ALLOWED_TAGS",Go,{transform:de}),ue=St(m,"ALLOWED_ATTR",Zo,{transform:de}),sa=St(m,"ALLOWED_NAMESPACES",Wv,{transform:ms}),na=St(m,"ADD_URI_SAFE_ATTR",zd,{transform:de,base:zd}),Od=St(m,"ADD_DATA_URI_TAGS",Ud,{transform:de,base:Ud}),ot=St(m,"FORBID_CONTENTS",ia,{transform:de}),sn=St(m,"FORBID_TAGS",Ce({}),{transform:de}),Id=St(m,"FORBID_ATTR",Ce({}),{transform:de}),yi=_e(m,"USE_PROFILES")?m.USE_PROFILES&&typeof m.USE_PROFILES=="object"?Ce(m.USE_PROFILES):m.USE_PROFILES:!1,kd=m.ALLOW_ARIA_ATTR!==!1,Qo=m.ALLOW_DATA_ATTR!==!1,Dd=m.ALLOW_UNKNOWN_PROTOCOLS||!1,Fd=m.ALLOW_SELF_CLOSE_IN_ATTR!==!1,At=m.SAFE_FOR_TEMPLATES||!1,Rt=m.SAFE_FOR_XML!==!1,Wt=m.WHOLE_DOCUMENT||!1,Si=m.RETURN_DOM||!1,Lr=m.RETURN_DOM_FRAGMENT||!1,Wr=m.RETURN_TRUSTED_TYPE||!1,ea=m.FORCE_BODY||!1,Md=m.SANITIZE_DOM!==!1,Nd=m.SANITIZE_NAMED_PROPS||!1,ta=m.KEEP_CONTENT!==!1,Vr=m.IN_PLACE||!1,Ed=lm(m.ALLOWED_URI_REGEXP)?m.ALLOWED_URI_REGEXP:bl,_i=typeof m.NAMESPACE=="string"?m.NAMESPACE:at,oa=_e(m,"MATHML_TEXT_INTEGRATION_POINTS")&&m.MATHML_TEXT_INTEGRATION_POINTS&&typeof m.MATHML_TEXT_INTEGRATION_POINTS=="object"?Ce(m.MATHML_TEXT_INTEGRATION_POINTS):G({},Ld),aa=_e(m,"HTML_INTEGRATION_POINTS")&&m.HTML_INTEGRATION_POINTS&&typeof m.HTML_INTEGRATION_POINTS=="object"?Ce(m.HTML_INTEGRATION_POINTS):G({},Wd);const _=_e(m,"CUSTOM_ELEMENT_HANDLING")&&m.CUSTOM_ELEMENT_HANDLING&&typeof m.CUSTOM_ELEMENT_HANDLING=="object"?Ce(m.CUSTOM_ELEMENT_HANDLING):Kt(null);if(pe=Kt(null),_e(_,"tagNameCheck")&&Vd(_.tagNameCheck)&&(pe.tagNameCheck=_.tagNameCheck),_e(_,"attributeNameCheck")&&Vd(_.attributeNameCheck)&&(pe.attributeNameCheck=_.attributeNameCheck),_e(_,"allowCustomizedBuiltInElements")&&typeof _.allowCustomizedBuiltInElements=="boolean"&&(pe.allowCustomizedBuiltInElements=_.allowCustomizedBuiltInElements),ve(pe),At&&(Qo=!1),Lr&&(Si=!0),yi&&(ce=G({},Sl),ue=Kt(null),yi.html===!0&&(G(ce,xl),G(ue,yl)),yi.svg===!0&&(G(ce,xs),G(ue,_s),G(ue,In)),yi.svgFilters===!0&&(G(ce,Ss),G(ue,_s),G(ue,In)),yi.mathMl===!0&&(G(ce,ys),G(ue,_l),G(ue,In))),Ct.tagCheck=null,Ct.attributeCheck=null,_e(m,"ADD_TAGS")&&(typeof m.ADD_TAGS=="function"?Ct.tagCheck=m.ADD_TAGS:xt(m.ADD_TAGS)&&(ce===Go&&(ce=Ce(ce)),G(ce,m.ADD_TAGS,de))),_e(m,"ADD_ATTR")&&(typeof m.ADD_ATTR=="function"?Ct.attributeCheck=m.ADD_ATTR:xt(m.ADD_ATTR)&&(ue===Zo&&(ue=Ce(ue)),G(ue,m.ADD_ATTR,de))),_e(m,"ADD_URI_SAFE_ATTR")&&xt(m.ADD_URI_SAFE_ATTR)&&G(na,m.ADD_URI_SAFE_ATTR,de),_e(m,"FORBID_CONTENTS")&&xt(m.FORBID_CONTENTS)&&(ot===ia&&(ot=Ce(ot)),G(ot,m.FORBID_CONTENTS,de)),_e(m,"ADD_FORBID_CONTENTS")&&xt(m.ADD_FORBID_CONTENTS)&&(ot===ia&&(ot=Ce(ot)),G(ot,m.ADD_FORBID_CONTENTS,de)),ta&&(ce["#text"]=!0),Wt&&G(ce,["html","head","body"]),ce.table&&(G(ce,["tbody"]),delete sn.tbody),m.TRUSTED_TYPES_POLICY){if(typeof m.TRUSTED_TYPES_POLICY.createHTML!="function")throw Ft('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof m.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw Ft('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const w=R;R=m.TRUSTED_TYPES_POLICY;try{D=X("")}catch(U){throw R=w,U}}else m.TRUSTED_TYPES_POLICY===null?(R=void 0,D=""):(R===void 0&&(R=N()),R&&typeof D=="string"&&(D=X("")));Te&&Te(m),bi=m},Hd=G({},[...xs,...Ss,...cm]),$d=G({},[...ys,...um]),Yv=function(m,_,w){return _.namespaceURI===at?m==="svg":_.namespaceURI===Hr?m==="svg"&&(w==="annotation-xml"||oa[w]):!!Hd[m]},jv=function(m,_,w){return _.namespaceURI===at?m==="math":_.namespaceURI===$r?m==="math"&&aa[w]:!!$d[m]},Kv=function(m,_,w){return _.namespaceURI===$r&&!aa[w]||_.namespaceURI===Hr&&!oa[w]?!1:!$d[m]&&(Vv[m]||!Hd[m])},qv=function(m){let _=S(m);(!_||!_.tagName)&&(_={namespaceURI:_i,tagName:"template"});const w=Fi(m.tagName),U=Fi(_.tagName);return sa[m.namespaceURI]?m.namespaceURI===$r?Yv(w,_,U):m.namespaceURI===Hr?jv(w,_,U):m.namespaceURI===at?Kv(w,_,U):!!(on==="application/xhtml+xml"&&sa[m.namespaceURI]):!1},wt=function(m){Gt(t.removed,{element:m});try{S(m).removeChild(m)}catch{if(g(m),!S(m))throw Ft("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Xr=function(m){an(m);const _=T(m);if(_){const U=[];qt(_,W=>{Gt(U,W)}),qt(U,W=>{try{g(W)}catch{}})}const w=I(m);if(w)for(let U=w.length-1;U>=0;--U){const W=w[U],j=W&&W.name;if(typeof j=="string")try{m.removeAttribute(j)}catch{}}},Vt=function(m,_){try{Gt(t.removed,{attribute:_.getAttributeNode(m),from:_})}catch{Gt(t.removed,{attribute:null,from:_})}if(_.removeAttribute(m),m==="is")if(Si||Lr)try{wt(_)}catch{}else try{_.setAttribute(m,"")}catch{}},Gv=function(m){const _=I(m);if(_)for(let w=_.length-1;w>=0;--w){const U=_[w],W=U&&U.name;if(!(typeof W!="string"||ue[de(W)]))try{m.removeAttribute(W)}catch{}}},an=function(m){const _=[m];for(;_.length>0;){const w=_.pop();(y?y(w):w.nodeType)===Oe.element&&Gv(w);const W=T(w);if(W)for(let j=W.length-1;j>=0;--j)_.push(W[j])}},Zv=function(m){if(!Rt)return;const _=[m];for(;_.length>0;){const w=_.pop(),U=y?y(w):w.nodeType;if(U===Oe.processingInstruction||U===Oe.comment&&be(vl,w.data)){try{g(w)}catch{}continue}if(U===Oe.element){const j=w,re=de(v?v(w):w.nodeName);try{j.hasAttribute&&j.hasAttribute("patchsrc")&&j.removeAttribute("patchsrc"),j.hasAttribute&&j.hasAttribute("for")&&re!=="label"&&re!=="output"&&j.removeAttribute("for")}catch{}}const W=T(w);if(W)for(let j=W.length-1;j>=0;--j)_.push(W[j])}},Xd=function(m){let _=null,w=null;if(ea)m="<remove></remove>"+m;else{const j=fl(m,/^[\r\n\t ]+/);w=j&&j[0]}on==="application/xhtml+xml"&&_i===at&&(m='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+m+"</body></html>");const U=R?X(m):m;if(_i===at)try{_=new u().parseFromString(U,on)}catch{}if(!_||!_.documentElement){_=O.createDocument(_i,"template",null);try{_.documentElement.innerHTML=ra?D:U}catch{}}const W=_.body||_.documentElement;return m&&w&&W.insertBefore(i.createTextNode(w),W.childNodes[0]||null),_i===at?Y.call(_,Wt?"html":"body")[0]:Wt?_.documentElement:W},Yd=function(m){const _=E?E(m):m.ownerDocument;return V.call(_||m,m,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},Yr=function(m){return m=Mi(m,Xe," "),m=Mi(m,Se," "),m=Mi(m,ze," "),m},ca=function(m){var _;m.normalize();const w=E?E(m):m.ownerDocument,U=V.call(w||m,m,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let W=U.nextNode();for(;W;)W.data=Yr(W.data),W=U.nextNode();const j=(_=m.querySelectorAll)===null||_===void 0?void 0:_.call(m,"template");j&&qt(j,re=>{Ti(re.content)&&ca(re.content)})},jr=function(m){const _=v?v(m):null;return typeof _!="string"||de(_)!=="form"?!1:typeof m.nodeName!="string"||typeof m.textContent!="string"||typeof m.removeChild!="function"||m.attributes!==I(m)||typeof m.removeAttribute!="function"||typeof m.setAttribute!="function"||typeof m.namespaceURI!="string"||typeof m.insertBefore!="function"||typeof m.hasChildNodes!="function"||m.nodeType!==y(m)||m.childNodes!==T(m)},Ti=function(m){if(!y||typeof m!="object"||m===null)return!1;try{return y(m)===Oe.documentFragment}catch{return!1}},ln=function(m){if(!y||typeof m!="object"||m===null)return!1;try{return typeof y(m)=="number"}catch{return!1}};function lt(k,m,_){k.length!==0&&qt(k,w=>{w.call(t,m,_,bi)})}const Qv=function(m,_){return!!(Rt&&m.hasChildNodes()&&!ln(m.firstElementChild)&&be(Tl,m.textContent)&&be(Tl,m.innerHTML)||Rt&&m.namespaceURI===at&&_==="style"&&ln(m.firstElementChild)||m.nodeType===Oe.processingInstruction||Rt&&m.nodeType===Oe.comment&&be(vl,m.data))},Jv=function(m,_,w){if(!sn[_]&&Gd(_)&&(pe.tagNameCheck instanceof RegExp&&be(pe.tagNameCheck,_)||pe.tagNameCheck instanceof Function&&pe.tagNameCheck(_)))return!1;if(ta&&!ot[_]){const U=S(m),W=T(m);if(W&&U){const j=W.length;for(let re=j-1;re>=0;--re){const he=m===w?p(W[re],!0):W[re];U.insertBefore(he,x(m))}}}return wt(m),!0},jd=function(m,_,w,U){return m.length===0?_:_===w||_===U?Ce(_):_},Kd=function(m,_){if(lt(H.beforeSanitizeElements,m,null),m!==_&&S(m)===null)return Vr&&an(m),!0;if(jr(m))return wt(m),!0;const w=de(v?v(m):m.nodeName);if(ce=jd(H.uponSanitizeElement,ce,Go,Ur),lt(H.uponSanitizeElement,m,{tagName:w,allowedTags:ce}),m!==_&&S(m)===null)return Vr&&an(m),!0;if(Qv(m,w))return wt(m),!0;if(sn[w]||!(Ct.tagCheck instanceof Function&&Ct.tagCheck(w))&&!ce[w]){const W=Jv(m,w,_);return W===!1&<(H.afterSanitizeElements,m,null),W}if((y?y(m):m.nodeType)===Oe.element&&!qv(m)||(w==="noscript"||w==="noembed"||w==="noframes")&&be(_m,m.innerHTML))return wt(m),!0;if(At&&m.nodeType===Oe.text){const W=Yr(m.textContent);m.textContent!==W&&(Gt(t.removed,{element:m.cloneNode()}),m.textContent=W)}return lt(H.afterSanitizeElements,m,null),!1},qd=function(m,_,w){if(Id[_]||Rt&&_==="patchsrc"||Rt&&_==="for"&&m!=="label"&&m!=="output"||Md&&(_==="id"||_==="name")&&(w in i||w in Xv))return!1;const U=ue[_]||Ct.attributeCheck instanceof Function&&Ct.attributeCheck(_,m);if(!(Qo&&be(Je,_))){if(!(kd&&be(Le,_))){if(U){if(!na[_]){if(!be(Ed,Mi(w,xi,""))){if(!((_==="src"||_==="xlink:href"||_==="href")&&m!=="script"&&pl(w,"data:")===0&&Od[m])){if(!(Dd&&!be(et,Mi(w,xi,"")))){if(w)return!1}}}}}else if(!(Gd(m)&&(pe.tagNameCheck instanceof RegExp&&be(pe.tagNameCheck,m)||pe.tagNameCheck instanceof Function&&pe.tagNameCheck(m))&&(pe.attributeNameCheck instanceof RegExp&&be(pe.attributeNameCheck,_)||pe.attributeNameCheck instanceof Function&&pe.attributeNameCheck(_,m))||_==="is"&&pe.allowCustomizedBuiltInElements&&(pe.tagNameCheck instanceof RegExp&&be(pe.tagNameCheck,w)||pe.tagNameCheck instanceof Function&&pe.tagNameCheck(w))))return!1}}return!0},eP=G({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),Gd=function(m){return!eP[Fi(m)]&&be(Lv,m)},tP=function(m,_,w,U){if(R&&typeof d=="object"&&typeof d.getAttributeType=="function"&&!w)switch(d.getAttributeType(m,_)){case"TrustedHTML":return X(U);case"TrustedScriptURL":return b(U)}return U},iP=function(m,_,w,U){try{w?m.setAttributeNS(w,_,U):m.setAttribute(_,U),jr(m)?wt(m):hl(t.removed)}catch{Vt(_,m)}},Zd=function(m){lt(H.beforeSanitizeAttributes,m,null);const _=m.attributes;if(!_||jr(m))return;ue=jd(H.uponSanitizeAttribute,ue,Zo,zr);const w={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:ue,forceKeepAttr:void 0};let U=_.length;const W=de(m.nodeName);for(;U--;){const j=_[U],re=j.name,he=j.namespaceURI,Me=j.value,Ne=de(re),da=Me;let Ie=re==="value"?da:im(da);if(w.attrName=Ne,w.attrValue=Ie,w.keepAttr=!0,w.forceKeepAttr=void 0,lt(H.uponSanitizeAttribute,m,w),Ie=w.attrValue,Nd&&(Ne==="id"||Ne==="name")&&pl(Ie,Bd)!==0&&(Vt(re,m),Ie=Bd+Ie),Rt&&be(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,Ie)){Vt(re,m);continue}if(Ne==="attributename"&&fl(Ie,"href")){Vt(re,m);continue}if(!w.forceKeepAttr){if(!w.keepAttr){Vt(re,m);continue}if(!Fd&&be(bm,Ie)){Vt(re,m);continue}if(At&&(Ie=Yr(Ie)),!qd(W,Ne,Ie)){Vt(re,m);continue}Ie=tP(W,Ne,he,Ie),Ie!==da&&iP(m,re,he,Ie)}}lt(H.afterSanitizeAttributes,m,null)},Kr=function(m){let _=null;const w=Yd(m);for(lt(H.beforeSanitizeShadowDOM,m,null);_=w.nextNode();)if(lt(H.uponSanitizeShadowNode,_,null),Kd(_,m),Zd(_),Ti(_.content)&&Kr(_.content),(y?y(_):_.nodeType)===Oe.element){const W=P(_);Ti(W)&&(ua(W),Kr(W))}lt(H.afterSanitizeShadowDOM,m,null)},ua=function(m){const _=[{node:m,shadow:null}];for(;_.length>0;){const w=_.pop();if(w.shadow){Kr(w.shadow);continue}const U=w.node,j=(y?y(U):U.nodeType)===Oe.element,re=T(U);if(re)for(let he=re.length-1;he>=0;--he)_.push({node:re[he],shadow:null});if(j){const he=v?v(U):null;if(typeof he=="string"&&de(he)==="template"){const Me=U.content;Ti(Me)&&_.push({node:Me,shadow:null})}}if(j){const he=P(U);Ti(he)&&_.push({node:null,shadow:he},{node:he,shadow:null})}}};return t.sanitize=function(k){let m=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},_=null,w=null,U=null,W=null;if(ra=!k,ra&&(k="<!-->"),typeof k!="string"&&!ln(k)&&(k=am(k),typeof k!="string"))throw Ft("dirty is not a string, aborting");if(!t.isSupported)return k;Jo?(ce=Ur,ue=zr):la(m),(H.uponSanitizeElement.length>0||H.uponSanitizeAttribute.length>0)&&(ce=Ce(ce)),H.uponSanitizeAttribute.length>0&&(ue=Ce(ue)),t.removed=[];const j=Vr&&typeof k!="string"&&ln(k);if(j){Zv(k);const Me=v?v(k):k.nodeName;if(typeof Me=="string"){const Ne=de(Me);if(!ce[Ne]||sn[Ne])throw Xr(k),Ft("root node is forbidden and cannot be sanitized in-place")}if(jr(k))throw Xr(k),Ft("root node is clobbered and cannot be sanitized in-place");try{ua(k)}catch(Ne){throw Xr(k),Ne}}else if(ln(k))_=Xd("<!---->"),w=_.ownerDocument.importNode(k,!0),w.nodeType===Oe.element&&w.nodeName==="BODY"||w.nodeName==="HTML"?_=w:_.appendChild(w),ua(w);else{if(!Si&&!At&&!Wt&&k.indexOf("<")===-1)return R&&Wr?X(k):k;if(_=Xd(k),!_)return Si?null:Wr?D:""}_&&ea&&wt(_.firstChild);const re=j?k:_;try{const Me=Yd(re);for(;U=Me.nextNode();)Kd(U,re),Zd(U),Ti(U.content)&&Kr(U.content)}catch(Me){throw j&&(Xr(k),qt(t.removed,Ne=>{Ne.element&&an(Ne.element)})),Me}if(j)return qt(t.removed,Me=>{Me.element&&an(Me.element)}),At&&ca(k),k;if(Si){if(At&&ca(_),Lr)for(W=L.call(_.ownerDocument);_.firstChild;)W.appendChild(_.firstChild);else W=_;return(ue.shadowroot||ue.shadowrootmode)&&(W=J.call(n,W,!0)),W}let he=Wt?_.outerHTML:_.innerHTML;return Wt&&ce["!doctype"]&&_.ownerDocument&&_.ownerDocument.doctype&&_.ownerDocument.doctype.name&&be(Sm,_.ownerDocument.doctype.name)&&(he="<!DOCTYPE "+_.ownerDocument.doctype.name+`> +`+he),At&&(he=Yr(he)),R&&Wr?X(he):he},t.setConfig=function(){let k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};la(k),Jo=!0,Ur=ce,zr=ue},t.clearConfig=function(){bi=null,Jo=!1,Ur=null,zr=null,R=z,D=""},t.isValidAttribute=function(k,m,_){bi||la({});const w=de(k),U=de(m);return qd(w,U,_)},t.addHook=function(k,m){typeof m=="function"&&_e(H,k)&&Gt(H[k],m)},t.removeHook=function(k,m){if(_e(H,k)){if(m!==void 0){const _=em(H[k],m);return _===-1?void 0:tm(H[k],_,1)[0]}return hl(H[k])}},t.removeHooks=function(k){_e(H,k)&&(H[k]=[])},t.removeAllHooks=function(){H=Pl()},t}var Pm=Cl();function kn(e,t){return e==null||t==null?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function Cm(e,t){return e==null||t==null?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Al(e){let t,i,n;e.length!==2?(t=kn,i=(a,l)=>kn(e(a),l),n=(a,l)=>e(a)-l):(t=e===kn||e===Cm?e:Am,i=e,n=e);function r(a,l,c=0,u=a.length){if(c<u){if(t(l,l)!==0)return u;do{const d=c+u>>>1;i(a[d],l)<0?c=d+1:u=d}while(c<u)}return c}function s(a,l,c=0,u=a.length){if(c<u){if(t(l,l)!==0)return u;do{const d=c+u>>>1;i(a[d],l)<=0?c=d+1:u=d}while(c<u)}return c}function o(a,l,c=0,u=a.length){const d=r(a,l,c,u-1);return d>c&&n(a[d-1],l)>-n(a[d],l)?d-1:d}return{left:r,center:o,right:s}}function Am(){return 0}function Rm(e){return e===null?NaN:+e}const wm=Al(kn).right;Al(Rm).center;var bs=Math.sqrt(50),Ts=Math.sqrt(10),vs=Math.sqrt(2);function Em(e,t,i){var n,r=-1,s,o,a;if(t=+t,e=+e,i=+i,e===t&&i>0)return[e];if((n=t<e)&&(s=e,e=t,t=s),(a=Rl(e,t,i))===0||!isFinite(a))return[];if(a>0){let l=Math.round(e/a),c=Math.round(t/a);for(l*a<e&&++l,c*a>t&&--c,o=new Array(s=c-l+1);++r<s;)o[r]=(l+r)*a}else{a=-a;let l=Math.round(e*a),c=Math.round(t*a);for(l/a<e&&++l,c/a>t&&--c,o=new Array(s=c-l+1);++r<s;)o[r]=(l+r)/a}return n&&o.reverse(),o}function Rl(e,t,i){var n=(t-e)/Math.max(0,i),r=Math.floor(Math.log(n)/Math.LN10),s=n/Math.pow(10,r);return r>=0?(s>=bs?10:s>=Ts?5:s>=vs?2:1)*Math.pow(10,r):-Math.pow(10,-r)/(s>=bs?10:s>=Ts?5:s>=vs?2:1)}function Im(e,t,i){var n=Math.abs(t-e)/Math.max(0,i),r=Math.pow(10,Math.floor(Math.log(n)/Math.LN10)),s=n/r;return s>=bs?r*=10:s>=Ts?r*=5:s>=vs&&(r*=2),t<e?-r:r}function km(e,t,i){e=+e,t=+t,i=(r=arguments.length)<2?(t=e,e=0,1):r<3?1:+i;for(var n=-1,r=Math.max(0,Math.ceil((t-e)/i))|0,s=new Array(r);++n<r;)s[n]=e+n*i;return s}function wl(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e);break}return this}function Dm(e){return function(){return e}}function Fm(e){return+e}var El=[0,1];function nt(e){return e}function Ps(e,t){return(t-=e=+e)?function(i){return(i-e)/t}:Dm(isNaN(t)?NaN:.5)}function Mm(e,t){var i;return e>t&&(i=e,e=t,t=i),function(n){return Math.max(e,Math.min(t,n))}}function Nm(e,t,i){var n=e[0],r=e[1],s=t[0],o=t[1];return r<n?(n=Ps(r,n),s=i(o,s)):(n=Ps(n,r),s=i(s,o)),function(a){return s(n(a))}}function Bm(e,t,i){var n=Math.min(e.length,t.length)-1,r=new Array(n),s=new Array(n),o=-1;for(e[n]<e[0]&&(e=e.slice().reverse(),t=t.slice().reverse());++o<n;)r[o]=Ps(e[o],e[o+1]),s[o]=i(t[o],t[o+1]);return function(a){var l=wm(e,a,1,n)-1;return s[l](r[l](a))}}function Il(e,t){return t.domain(e.domain()).range(e.range()).interpolate(e.interpolate()).clamp(e.clamp()).unknown(e.unknown())}function kl(){var e=El,t=El,i=ls,n,r,s,o=nt,a,l,c;function u(){var h=Math.min(e.length,t.length);return o!==nt&&(o=Mm(e[0],e[h-1])),a=h>2?Bm:Nm,l=c=null,d}function d(h){return h==null||isNaN(h=+h)?s:(l||(l=a(e.map(n),t,i)))(n(o(h)))}return d.invert=function(h){return o(r((c||(c=a(t,e.map(n),Ke)))(h)))},d.domain=function(h){return arguments.length?(e=Array.from(h,Fm),u()):e.slice()},d.range=function(h){return arguments.length?(t=Array.from(h),u()):t.slice()},d.rangeRound=function(h){return t=Array.from(h),i=dp,u()},d.clamp=function(h){return arguments.length?(o=h?!0:nt,u()):o!==nt},d.interpolate=function(h){return arguments.length?(i=h,u()):i},d.unknown=function(h){return arguments.length?(s=h,d):s},function(h,p){return n=h,r=p,u()}}function Om(){return kl()(nt,nt)}function Um(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function Dn(e,t){if((i=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var i,n=e.slice(0,i);return[n.length>1?n[0]+n.slice(2):n,+e.slice(i+1)]}function Zt(e){return e=Dn(Math.abs(e)),e?e[1]:NaN}function zm(e,t){return function(i,n){for(var r=i.length,s=[],o=0,a=e[0],l=0;r>0&&a>0&&(l+a+1>n&&(a=Math.max(1,n-l)),s.push(i.substring(r-=a,r+a)),!((l+=a+1)>n));)a=e[o=(o+1)%e.length];return s.reverse().join(t)}}function Lm(e){return function(t){return t.replace(/[0-9]/g,function(i){return e[+i]})}}var Wm=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Fn(e){if(!(t=Wm.exec(e)))throw new Error("invalid format: "+e);var t;return new Cs({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}Fn.prototype=Cs.prototype;function Cs(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}Cs.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function Vm(e){e:for(var t=e.length,i=1,n=-1,r;i<t;++i)switch(e[i]){case".":n=r=i;break;case"0":n===0&&(n=i),r=i;break;default:if(!+e[i])break e;n>0&&(n=0);break}return n>0?e.slice(0,n)+e.slice(r+1):e}var Dl;function Hm(e,t){var i=Dn(e,t);if(!i)return e+"";var n=i[0],r=i[1],s=r-(Dl=Math.max(-8,Math.min(8,Math.floor(r/3)))*3)+1,o=n.length;return s===o?n:s>o?n+new Array(s-o+1).join("0"):s>0?n.slice(0,s)+"."+n.slice(s):"0."+new Array(1-s).join("0")+Dn(e,Math.max(0,t+s-1))[0]}function Fl(e,t){var i=Dn(e,t);if(!i)return e+"";var n=i[0],r=i[1];return r<0?"0."+new Array(-r).join("0")+n:n.length>r+1?n.slice(0,r+1)+"."+n.slice(r+1):n+new Array(r-n.length+2).join("0")}const Ml={"%":(e,t)=>(e*100).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:Um,e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>Fl(e*100,t),r:Fl,s:Hm,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function Nl(e){return e}var Bl=Array.prototype.map,Ol=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function $m(e){var t=e.grouping===void 0||e.thousands===void 0?Nl:zm(Bl.call(e.grouping,Number),e.thousands+""),i=e.currency===void 0?"":e.currency[0]+"",n=e.currency===void 0?"":e.currency[1]+"",r=e.decimal===void 0?".":e.decimal+"",s=e.numerals===void 0?Nl:Lm(Bl.call(e.numerals,String)),o=e.percent===void 0?"%":e.percent+"",a=e.minus===void 0?"−":e.minus+"",l=e.nan===void 0?"NaN":e.nan+"";function c(d){d=Fn(d);var h=d.fill,p=d.align,g=d.sign,x=d.symbol,T=d.zero,S=d.width,P=d.comma,I=d.precision,y=d.trim,v=d.type;v==="n"?(P=!0,v="g"):Ml[v]||(I===void 0&&(I=12),y=!0,v="g"),(T||h==="0"&&p==="=")&&(T=!0,h="0",p="=");var E=x==="$"?i:x==="#"&&/[boxX]/.test(v)?"0"+v.toLowerCase():"",R=x==="$"?n:/[%p]/.test(v)?o:"",D=Ml[v],z=/[defgprs%]/.test(v);I=I===void 0?6:/[gprs]/.test(v)?Math.max(1,Math.min(21,I)):Math.max(0,Math.min(20,I));function $(F){var Q=E,X=R,b,N,A;if(v==="c")X=D(F)+X,F="";else{F=+F;var O=F<0||1/F<0;if(F=isNaN(F)?l:D(Math.abs(F),I),y&&(F=Vm(F)),O&&+F==0&&g!=="+"&&(O=!1),Q=(O?g==="("?g:a:g==="-"||g==="("?"":g)+Q,X=(v==="s"?Ol[8+Dl/3]:"")+X+(O&&g==="("?")":""),z){for(b=-1,N=F.length;++b<N;)if(A=F.charCodeAt(b),48>A||A>57){X=(A===46?r+F.slice(b+1):F.slice(b))+X,F=F.slice(0,b);break}}}P&&!T&&(F=t(F,1/0));var V=Q.length+F.length+X.length,L=V<S?new Array(S-V+1).join(h):"";switch(P&&T&&(F=t(L+F,L.length?S-X.length:1/0),L=""),p){case"<":F=Q+F+X+L;break;case"=":F=Q+L+F+X;break;case"^":F=L.slice(0,V=L.length>>1)+Q+F+X+L.slice(V);break;default:F=L+Q+F+X;break}return s(F)}return $.toString=function(){return d+""},$}function u(d,h){var p=c((d=Fn(d),d.type="f",d)),g=Math.max(-8,Math.min(8,Math.floor(Zt(h)/3)))*3,x=Math.pow(10,-g),T=Ol[8+g/3];return function(S){return p(x*S)+T}}return{format:c,formatPrefix:u}}var Mn,Ul,zl;Xm({thousands:",",grouping:[3],currency:["$",""]});function Xm(e){return Mn=$m(e),Ul=Mn.format,zl=Mn.formatPrefix,Mn}function Ym(e){return Math.max(0,-Zt(Math.abs(e)))}function jm(e,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Zt(t)/3)))*3-Zt(Math.abs(e)))}function Km(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,Zt(t)-Zt(e))+1}function qm(e,t,i,n){var r=Im(e,t,i),s;switch(n=Fn(n??",f"),n.type){case"s":{var o=Math.max(Math.abs(e),Math.abs(t));return n.precision==null&&!isNaN(s=jm(r,o))&&(n.precision=s),zl(n,o)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(s=Km(r,Math.max(Math.abs(e),Math.abs(t))))&&(n.precision=s-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(s=Ym(r))&&(n.precision=s-(n.type==="%")*2);break}}return Ul(n)}function Ll(e){var t=e.domain;return e.ticks=function(i){var n=t();return Em(n[0],n[n.length-1],i??10)},e.tickFormat=function(i,n){var r=t();return qm(r[0],r[r.length-1],i??10,n)},e.nice=function(i){i==null&&(i=10);var n=t(),r=0,s=n.length-1,o=n[r],a=n[s],l,c,u=10;for(a<o&&(c=o,o=a,a=c,c=r,r=s,s=c);u-- >0;){if(c=Rl(o,a,i),c===l)return n[r]=o,n[s]=a,t(n);if(c>0)o=Math.floor(o/c)*c,a=Math.ceil(a/c)*c;else if(c<0)o=Math.ceil(o*c)/c,a=Math.floor(a*c)/c;else break;l=c}return e},e}function As(){var e=Om();return e.copy=function(){return Il(e,As())},wl.apply(e,arguments),Ll(e)}function Wl(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function Gm(e){return e<0?-Math.sqrt(-e):Math.sqrt(e)}function Zm(e){return e<0?-e*e:e*e}function Qm(e){var t=e(nt,nt),i=1;function n(){return i===1?e(nt,nt):i===.5?e(Gm,Zm):e(Wl(i),Wl(1/i))}return t.exponent=function(r){return arguments.length?(i=+r,n()):i},Ll(t)}function Vl(){var e=Qm(kl());return e.copy=function(){return Il(e,Vl()).exponent(e.exponent())},wl.apply(e,arguments),e}var Hl=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)});function Jm(){var e=new Hl(9);return Hl!=Float32Array&&(e[1]=0,e[2]=0,e[3]=0,e[5]=0,e[6]=0,e[7]=0),e[0]=1,e[4]=1,e[8]=1,e}function $l(e,t,i){var n=t[0],r=t[1],s=t[2],o=t[3],a=t[4],l=t[5],c=t[6],u=t[7],d=t[8],h=i[0],p=i[1];return e[0]=n,e[1]=r,e[2]=s,e[3]=o,e[4]=a,e[5]=l,e[6]=h*n+p*o+c,e[7]=h*r+p*a+u,e[8]=h*s+p*l+d,e}function Rs(e,t,i){var n=i[0],r=i[1];return e[0]=n*t[0],e[1]=n*t[1],e[2]=n*t[2],e[3]=r*t[3],e[4]=r*t[4],e[5]=r*t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e}function ex(e,t,i){return e[0]=2/t,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/i,e[5]=0,e[6]=-1,e[7]=1,e[8]=1,e}function tx(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function ix(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if(typeof t=="function"){var i=function n(){return this instanceof n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};i.prototype=t.prototype}else i={};return Object.defineProperty(i,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(i,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}),i}var Nn={exports:{}},nx=Nn.exports,Xl;function rx(){return Xl||(Xl=1,function(e){(function(t,i,n){function r(l){var c=this,u=a();c.next=function(){var d=2091639*c.s0+c.c*23283064365386963e-26;return c.s0=c.s1,c.s1=c.s2,c.s2=d-(c.c=d|0)},c.c=1,c.s0=u(" "),c.s1=u(" "),c.s2=u(" "),c.s0-=u(l),c.s0<0&&(c.s0+=1),c.s1-=u(l),c.s1<0&&(c.s1+=1),c.s2-=u(l),c.s2<0&&(c.s2+=1),u=null}function s(l,c){return c.c=l.c,c.s0=l.s0,c.s1=l.s1,c.s2=l.s2,c}function o(l,c){var u=new r(l),d=c&&c.state,h=u.next;return h.int32=function(){return u.next()*4294967296|0},h.double=function(){return h()+(h()*2097152|0)*11102230246251565e-32},h.quick=h,d&&(typeof d=="object"&&s(d,u),h.state=function(){return s(u,{})}),h}function a(){var l=4022871197,c=function(u){u=String(u);for(var d=0;d<u.length;d++){l+=u.charCodeAt(d);var h=.02519603282416938*l;l=h>>>0,h-=l,h*=l,l=h>>>0,h-=l,l+=h*4294967296}return(l>>>0)*23283064365386963e-26};return c}i&&i.exports?i.exports=o:this.alea=o})(nx,e)}(Nn)),Nn.exports}var Bn={exports:{}},sx=Bn.exports,Yl;function ox(){return Yl||(Yl=1,function(e){(function(t,i,n){function r(a){var l=this,c="";l.x=0,l.y=0,l.z=0,l.w=0,l.next=function(){var d=l.x^l.x<<11;return l.x=l.y,l.y=l.z,l.z=l.w,l.w^=l.w>>>19^d^d>>>8},a===(a|0)?l.x=a:c+=a;for(var u=0;u<c.length+64;u++)l.x^=c.charCodeAt(u)|0,l.next()}function s(a,l){return l.x=a.x,l.y=a.y,l.z=a.z,l.w=a.w,l}function o(a,l){var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(typeof u=="object"&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xor128=o})(sx,e)}(Bn)),Bn.exports}var On={exports:{}},ax=On.exports,jl;function lx(){return jl||(jl=1,function(e){(function(t,i,n){function r(a){var l=this,c="";l.next=function(){var d=l.x^l.x>>>2;return l.x=l.y,l.y=l.z,l.z=l.w,l.w=l.v,(l.d=l.d+362437|0)+(l.v=l.v^l.v<<4^(d^d<<1))|0},l.x=0,l.y=0,l.z=0,l.w=0,l.v=0,a===(a|0)?l.x=a:c+=a;for(var u=0;u<c.length+64;u++)l.x^=c.charCodeAt(u)|0,u==c.length&&(l.d=l.x<<10^l.x>>>4),l.next()}function s(a,l){return l.x=a.x,l.y=a.y,l.z=a.z,l.w=a.w,l.v=a.v,l.d=a.d,l}function o(a,l){var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(typeof u=="object"&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xorwow=o})(ax,e)}(On)),On.exports}var Un={exports:{}},cx=Un.exports,Kl;function ux(){return Kl||(Kl=1,function(e){(function(t,i,n){function r(a){var l=this;l.next=function(){var u=l.x,d=l.i,h,p;return h=u[d],h^=h>>>7,p=h^h<<24,h=u[d+1&7],p^=h^h>>>10,h=u[d+3&7],p^=h^h>>>3,h=u[d+4&7],p^=h^h<<7,h=u[d+7&7],h=h^h<<13,p^=h^h<<9,u[d]=p,l.i=d+1&7,p};function c(u,d){var h,p=[];if(d===(d|0))p[0]=d;else for(d=""+d,h=0;h<d.length;++h)p[h&7]=p[h&7]<<15^d.charCodeAt(h)+p[h+1&7]<<13;for(;p.length<8;)p.push(0);for(h=0;h<8&&p[h]===0;++h);for(h==8?p[7]=-1:p[h],u.x=p,u.i=0,h=256;h>0;--h)u.next()}c(l,a)}function s(a,l){return l.x=a.x.slice(),l.i=a.i,l}function o(a,l){a==null&&(a=+new Date);var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(u.x&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xorshift7=o})(cx,e)}(Un)),Un.exports}var zn={exports:{}},dx=zn.exports,ql;function hx(){return ql||(ql=1,function(e){(function(t,i,n){function r(a){var l=this;l.next=function(){var u=l.w,d=l.X,h=l.i,p,g;return l.w=u=u+1640531527|0,g=d[h+34&127],p=d[h=h+1&127],g^=g<<13,p^=p<<17,g^=g>>>15,p^=p>>>12,g=d[h]=g^p,l.i=h,g+(u^u>>>16)|0};function c(u,d){var h,p,g,x,T,S=[],P=128;for(d===(d|0)?(p=d,d=null):(d=d+"\0",p=0,P=Math.max(P,d.length)),g=0,x=-32;x<P;++x)d&&(p^=d.charCodeAt((x+32)%d.length)),x===0&&(T=p),p^=p<<10,p^=p>>>15,p^=p<<4,p^=p>>>13,x>=0&&(T=T+1640531527|0,h=S[x&127]^=p+T,g=h==0?g+1:0);for(g>=128&&(S[(d&&d.length||0)&127]=-1),g=127,x=4*128;x>0;--x)p=S[g+34&127],h=S[g=g+1&127],p^=p<<13,h^=h<<17,p^=p>>>15,h^=h>>>12,S[g]=p^h;u.w=T,u.X=S,u.i=g}c(l,a)}function s(a,l){return l.i=a.i,l.w=a.w,l.X=a.X.slice(),l}function o(a,l){a==null&&(a=+new Date);var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(u.X&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.xor4096=o})(dx,e)}(zn)),zn.exports}var Ln={exports:{}},fx=Ln.exports,Gl;function px(){return Gl||(Gl=1,function(e){(function(t,i,n){function r(a){var l=this,c="";l.next=function(){var d=l.b,h=l.c,p=l.d,g=l.a;return d=d<<25^d>>>7^h,h=h-p|0,p=p<<24^p>>>8^g,g=g-d|0,l.b=d=d<<20^d>>>12^h,l.c=h=h-p|0,l.d=p<<16^h>>>16^g,l.a=g-d|0},l.a=0,l.b=0,l.c=-1640531527,l.d=1367130551,a===Math.floor(a)?(l.a=a/4294967296|0,l.b=a|0):c+=a;for(var u=0;u<c.length+20;u++)l.b^=c.charCodeAt(u)|0,l.next()}function s(a,l){return l.a=a.a,l.b=a.b,l.c=a.c,l.d=a.d,l}function o(a,l){var c=new r(a),u=l&&l.state,d=function(){return(c.next()>>>0)/4294967296};return d.double=function(){do var h=c.next()>>>11,p=(c.next()>>>0)/4294967296,g=(h+p)/(1<<21);while(g===0);return g},d.int32=c.next,d.quick=d,u&&(typeof u=="object"&&s(u,c),d.state=function(){return s(c,{})}),d}i&&i.exports?i.exports=o:this.tychei=o})(fx,e)}(Ln)),Ln.exports}var Wn={exports:{}};const gx=ix(Object.freeze(Object.defineProperty({__proto__:null,default:{}},Symbol.toStringTag,{value:"Module"})));var mx=Wn.exports,Zl;function xx(){return Zl||(Zl=1,function(e){(function(t,i,n){var r=256,s=6,o=52,a="random",l=n.pow(r,s),c=n.pow(2,o),u=c*2,d=r-1,h;function p(y,v,E){var R=[];v=v==!0?{entropy:!0}:v||{};var D=S(T(v.entropy?[y,I(i)]:y??P(),3),R),z=new g(R),$=function(){for(var F=z.g(s),Q=l,X=0;F<c;)F=(F+X)*r,Q*=r,X=z.g(1);for(;F>=u;)F/=2,Q/=2,X>>>=1;return(F+X)/Q};return $.int32=function(){return z.g(4)|0},$.quick=function(){return z.g(4)/4294967296},$.double=$,S(I(z.S),i),(v.pass||E||function(F,Q,X,b){return b&&(b.S&&x(b,z),F.state=function(){return x(z,{})}),X?(n[a]=F,Q):F})($,D,"global"in v?v.global:this==n,v.state)}function g(y){var v,E=y.length,R=this,D=0,z=R.i=R.j=0,$=R.S=[];for(E||(y=[E++]);D<r;)$[D]=D++;for(D=0;D<r;D++)$[D]=$[z=d&z+y[D%E]+(v=$[D])],$[z]=v;(R.g=function(F){for(var Q,X=0,b=R.i,N=R.j,A=R.S;F--;)Q=A[b=d&b+1],X=X*r+A[d&(A[b]=A[N=d&N+Q])+(A[N]=Q)];return R.i=b,R.j=N,X})(r)}function x(y,v){return v.i=y.i,v.j=y.j,v.S=y.S.slice(),v}function T(y,v){var E=[],R=typeof y,D;if(v&&R=="object")for(D in y)try{E.push(T(y[D],v-1))}catch{}return E.length?E:R=="string"?y:y+"\0"}function S(y,v){for(var E=y+"",R,D=0;D<E.length;)v[d&D]=d&(R^=v[d&D]*19)+E.charCodeAt(D++);return I(v)}function P(){try{var y;return h&&(y=h.randomBytes)?y=y(r):(y=new Uint8Array(r),(t.crypto||t.msCrypto).getRandomValues(y)),I(y)}catch{var v=t.navigator,E=v&&v.plugins;return[+new Date,t,E,t.screen,I(i)]}}function I(y){return String.fromCharCode.apply(0,y)}if(S(n.random(),i),e.exports){e.exports=p;try{h=gx}catch{}}else n["seed"+a]=p})(typeof self<"u"?self:mx,[],Math)}(Wn)),Wn.exports}var ws,Ql;function Sx(){if(Ql)return ws;Ql=1;var e=rx(),t=ox(),i=lx(),n=ux(),r=hx(),s=px(),o=xx();return o.alea=e,o.xor128=t,o.xorwow=i,o.xorshift7=n,o.xor4096=r,o.tychei=s,ws=o,ws}var yx=Sx();const _x=tx(yx);function bx(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,vx(n.key),n)}}function Es(e,t,i){return t&&bx(e.prototype,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function Jl(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,Is(e,t)}function Is(e,t){return Is=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,r){return n.__proto__=r,n},Is(e,t)}function Tx(e,t){if(typeof e!="object"||e===null)return e;var i=e[Symbol.toPrimitive];if(i!==void 0){var n=i.call(e,t);if(typeof n!="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}function vx(e){var t=Tx(e,"string");return typeof t=="symbol"?t:String(t)}var Vn=function(){function e(){}var t=e.prototype;return t._seed=function(n,r){if(n===(n||0))return n;for(var s=""+n,o=0,a=0;a<s.length;++a)o^=s.charCodeAt(a)|0;return o},e}(),ec=function(e){Jl(t,e);function t(n,r){var s;return s=e.call(this)||this,s._rng=void 0,s.seed(n,r),s}var i=t.prototype;return i.next=function(){return this._rng()},i.seed=function(r,s){this._rng=r},i.clone=function(r,s){return new t(this._rng,s)},Es(t,[{key:"name",get:function(){return"function"}}]),t}(Vn),tc=function(){var e=[].slice.call(arguments),t=e,i=t[0],n=i===void 0?"default":i;switch(typeof n){case"object":if(n instanceof Vn)return n;break;case"function":return new ec(n);case"number":case"string":default:return new ec(_x.apply(void 0,e))}throw new Error('invalid RNG "'+n+'"')},Px=function(e,t,i){return t===void 0&&(t=0),i===void 0&&(i=1),function(){return e.next()*(i-t)+t}};function Ge(e){return new Cx(e)}var Cx=function(t){var i=this;this.n=void 0,this.isInt=function(){if(Number.isInteger(i.n))return i;throw new Error("Expected number to be an integer, got "+i.n)},this.isPositive=function(){if(i.n>0)return i;throw new Error("Expected number to be positive, got "+i.n)},this.lessThan=function(n){if(i.n<n)return i;throw new Error("Expected number to be less than "+n+", got "+i.n)},this.greaterThanOrEqual=function(n){if(i.n>=n)return i;throw new Error("Expected number to be greater than or equal to "+n+", got "+i.n)},this.greaterThan=function(n){if(i.n>n)return i;throw new Error("Expected number to be greater than "+n+", got "+i.n)},this.n=t},Ax=function(e,t,i){return t===void 0&&(t=0),i===void 0&&(i=1),i===void 0&&(i=t===void 0?1:t,t=0),Ge(t).isInt(),Ge(i).isInt(),function(){return Math.floor(e.next()*(i-t+1)+t)}},Rx=function(e){return function(){return e.next()>=.5}},wx=function(e,t,i){return t===void 0&&(t=0),i===void 0&&(i=1),function(){var n,r,s;do n=e.next()*2-1,r=e.next()*2-1,s=n*n+r*r;while(!s||s>1);return t+i*r*Math.sqrt(-2*Math.log(s)/s)}},Ex=function(e,t,i){t===void 0&&(t=0),i===void 0&&(i=1);var n=e.normal(t,i);return function(){return Math.exp(n())}},Ix=function(e,t){return t===void 0&&(t=.5),Ge(t).greaterThanOrEqual(0).lessThan(1),function(){return Math.floor(e.next()+t)}},kx=function(e,t,i){return t===void 0&&(t=1),i===void 0&&(i=.5),Ge(t).isInt().isPositive(),Ge(i).greaterThanOrEqual(0).lessThan(1),function(){for(var n=0,r=0;n++<t;)e.next()<i&&r++;return r}},Dx=function(e,t){t===void 0&&(t=.5),Ge(t).greaterThan(0).lessThan(1);var i=1/Math.log(1-t);return function(){return Math.floor(1+Math.log(e.next())*i)}},Fx=[0,0,.6931471805599453,1.791759469228055,3.1780538303479458,4.787491742782046,6.579251212010101,8.525161361065415,10.60460290274525,12.801827480081469],Mx=function(t){return Fx[t]},Nx=.9189385332046727,Bx=function(e,t){if(t===void 0&&(t=1),Ge(t).isPositive(),t<10){var i=Math.exp(-t);return function(){for(var l=i,c=0,u=e.next();u>l;)u=u-l,l=t*l/++c;return c}}else{var n=Math.sqrt(t),r=.931+2.53*n,s=-.059+.02483*r,o=1.1239+1.1328/(r-3.4),a=.9277-3.6224/(r-2);return function(){for(;;){var l=void 0,c=e.next();if(c<=.86*a)return l=c/a-.43,Math.floor((2*s/(.5-Math.abs(l))+r)*l+t+.445);c>=a?l=e.next()-.5:(l=c/a-.93,l=(l<0?-.5:.5)-l,c=e.next()*a);var u=.5-Math.abs(l);if(!(u<.013&&c>u)){var d=Math.floor((2*s/u+r)*l+t+.445);if(c=c*o/(s/(u*u)+r),d>=10){var h=(d+.5)*Math.log(t/d)-t-Nx+d-(.08333333333333333-(.002777777777777778-1/(1260*d*d))/(d*d))/d;if(Math.log(c*n)<=h)return d}else if(d>=0){var p,g=(p=Mx(d))!=null?p:0;if(Math.log(c)<=d*Math.log(t)-t-g)return d}}}}}},Ox=function(e,t){return t===void 0&&(t=1),Ge(t).isPositive(),function(){return-Math.log(1-e.next())/t}},Ux=function(e,t){return t===void 0&&(t=1),Ge(t).isInt().greaterThanOrEqual(0),function(){for(var i=0,n=0;n<t;++n)i+=e.next();return i}},zx=function(e,t){t===void 0&&(t=1),Ge(t).isInt().isPositive();var i=e.irwinHall(t);return function(){return i()/t}},Lx=function(e,t){t===void 0&&(t=1),Ge(t).greaterThanOrEqual(0);var i=1/t;return function(){return 1/Math.pow(1-e.next(),i)}},Wx=function(e){Jl(t,e);function t(){return e.apply(this,arguments)||this}var i=t.prototype;return i.next=function(){return Math.random()},i.seed=function(r,s){},i.clone=function(){return new t},Es(t,[{key:"name",get:function(){return"default"}}]),t}(Vn),ic=function(){function e(i){var n=this;this._rng=void 0,this._patch=void 0,this._cache={},this.next=function(){return n._rng.next()},this.float=function(r,s){return n.uniform(r,s)()},this.int=function(r,s){return n.uniformInt(r,s)()},this.integer=function(r,s){return n.uniformInt(r,s)()},this.bool=function(){return n.uniformBoolean()()},this.boolean=function(){return n.uniformBoolean()()},this.uniform=function(r,s){return n._memoize("uniform",Px,r,s)},this.uniformInt=function(r,s){return n._memoize("uniformInt",Ax,r,s)},this.uniformBoolean=function(){return n._memoize("uniformBoolean",Rx)},this.normal=function(r,s){return wx(n,r,s)},this.logNormal=function(r,s){return Ex(n,r,s)},this.bernoulli=function(r){return Ix(n,r)},this.binomial=function(r,s){return kx(n,r,s)},this.geometric=function(r){return Dx(n,r)},this.poisson=function(r){return Bx(n,r)},this.exponential=function(r){return Ox(n,r)},this.irwinHall=function(r){return Ux(n,r)},this.bates=function(r){return zx(n,r)},this.pareto=function(r){return Lx(n,r)},i&&i instanceof Vn?this.use(i):this.use(new Wx),this._cache={}}var t=e.prototype;return t.clone=function(){var n=[].slice.call(arguments);return n.length?new e(tc.apply(void 0,n)):new e(this.rng.clone())},t.use=function(){this._rng=tc.apply(void 0,[].slice.call(arguments))},t.patch=function(){if(this._patch)throw new Error("Math.random already patched");this._patch=Math.random,Math.random=this.uniform()},t.unpatch=function(){this._patch&&(Math.random=this._patch,delete this._patch)},t.choice=function(n){if(!Array.isArray(n))throw new Error("Random.choice expected input to be an array, got "+typeof n);var r=n==null?void 0:n.length;if(r>0){var s=this.uniformInt(0,r-1)();return n[s]}else return},t._memoize=function(n,r){var s=[].slice.call(arguments,2),o=""+s.join(";"),a=this._cache[n];return(a===void 0||a.key!==o)&&(a={key:o,distribution:r.apply(void 0,[this].concat(s))},this._cache[n]=a),a.distribution},Es(e,[{key:"rng",get:function(){return this._rng}}]),e}();new ic;const Qt=.001,Hn=64,Vx=4,$n=2;class Hx{constructor(){this.pointsTextureSize=0,this.linksTextureSize=0,this.alpha=1,this.transform=Jm(),this.screenSize=[0,0],this.mousePosition=[0,0],this.screenMousePosition=[0,0],this.searchArea=[[0,0],[0,0]],this.isSimulationRunning=!1,this.simulationProgress=0,this.maxPointSize=Hn,this.hoveredPoint=void 0,this.focusedPoint=void 0,this.draggingPointIndex=void 0,this.hoveredLinkIndex=void 0,this.hostHoveredPointIndex=void 0,this.hostHoveredLinkIndex=void 0,this.adjustedSpaceSize=Ze.spaceSize,this.isSpaceKeyPressed=!1,this.webglMaxTextureSize=16384,this.hoveredPointRingColor=[1,1,1,dc],this.focusedPointRingColor=[1,1,1,hc],this.outlinedPointRingColor=[1,1,1,1],this.highlightedPointSet=void 0,this.outlinedPointSet=void 0,this.hoveredLinkColor=[-1,-1,-1,-1],this.greyoutPointColor=[-1,-1,-1,-1],this.isDarkenGreyout=!1,this.isLinkHoveringEnabled=!1,this.alphaTarget=0,this.scalePointX=As(),this.scalePointY=As(),this.random=new ic,this._backgroundColor=[0,0,0,0],this.alphaDecay=t=>1-Math.pow(Qt,1/t)}get backgroundColor(){return this._backgroundColor}get transformationMatrix4x4(){const t=this.transform;if(t.length!==9)throw new Error(`Transform must be a 9-element array (3x3 matrix), got ${t.length} elements`);return[t[0],t[1],t[2],0,t[3],t[4],t[5],0,t[6],t[7],t[8],0,0,0,0,1]}set backgroundColor(t){this._backgroundColor=t;const i=oc(t[0],t[1],t[2]);if(this.div){const n=i>.65?"black":"white";this.div.style.setProperty("--cosmosgl-attribution-color",n),this.div.style.setProperty("--cosmosgl-error-message-color",n),this.div.style.backgroundColor=`rgba(${t[0]*255}, ${t[1]*255}, ${t[2]*255}, ${t[3]})`}this.isDarkenGreyout=i<.65}addRandomSeed(t){this.random=this.random.clone(t)}getRandomFloat(t,i){return this.random.float(t,i)}adjustSpaceSize(t,i){(t<=0||!isFinite(t))&&(console.error(`Invalid spaceSize value: ${t}. Using default value of ${Ze.spaceSize}`),t=Ze.spaceSize);const n=2;if(t<n&&(console.warn(`spaceSize (${t}) is too small. Using minimum value of ${n}`),t=n),!Number.isFinite(i)||i<=0||i<n){console.warn(`Invalid webglMaxTextureSize: ${i}. Using configSpaceSize without WebGL limit adjustment.`),this.adjustedSpaceSize=t;return}t>=i?(this.adjustedSpaceSize=Math.max(i/2,n),console.warn(`The \`spaceSize\` has been reduced to ${this.adjustedSpaceSize} due to WebGL limits`)):this.adjustedSpaceSize=t}setWebGLMaxTextureSize(t){this.webglMaxTextureSize=t}updateScreenSize(t,i){const{adjustedSpaceSize:n}=this;this.screenSize=[t,i],this.scalePointX.domain([0,n]).range([(t-n)/2,(t+n)/2]),this.scalePointY.domain([n,0]).range([(i-n)/2,(i+n)/2])}scaleX(t){return this.scalePointX(t)}scaleY(t){return this.scalePointY(t)}setHoveredPointRingColor(t){const i=We(t);this.hoveredPointRingColor[0]=i[0],this.hoveredPointRingColor[1]=i[1],this.hoveredPointRingColor[2]=i[2]}setFocusedPointRingColor(t){const i=We(t);this.focusedPointRingColor[0]=i[0],this.focusedPointRingColor[1]=i[1],this.focusedPointRingColor[2]=i[2]}setOutlinedPointRingColor(t){const i=We(t);this.outlinedPointRingColor[0]=i[0],this.outlinedPointRingColor[1]=i[1],this.outlinedPointRingColor[2]=i[2],this.outlinedPointRingColor[3]=i[3]}setHighlightedPointSet(t){this.highlightedPointSet=t?new Set(t):void 0}setOutlinedPointSet(t){this.outlinedPointSet=t?new Set(t):void 0}setGreyoutPointColor(t){if(t===void 0){this.greyoutPointColor=[-1,-1,-1,-1];return}const i=We(t);this.greyoutPointColor[0]=i[0],this.greyoutPointColor[1]=i[1],this.greyoutPointColor[2]=i[2],this.greyoutPointColor[3]=i[3]}updateLinkHoveringEnabled(t){this.isLinkHoveringEnabled=!!(t.onLinkClick||t.onLinkContextMenu||t.onLinkMouseOver||t.onLinkMouseOut),this.isLinkHoveringEnabled||(this.hoveredLinkIndex=void 0)}setHoveredLinkColor(t){if(t===void 0){this.hoveredLinkColor=[-1,-1,-1,-1];return}const i=We(t);this.hoveredLinkColor[0]=i[0],this.hoveredLinkColor[1]=i[1],this.hoveredLinkColor[2]=i[2],this.hoveredLinkColor[3]=i[3]}setFocusedPoint(t){t!==void 0?this.focusedPoint={index:t}:this.focusedPoint=void 0}addAlpha(t){return(this.alphaTarget-this.alpha)*this.alphaDecay(t)}}const nc=e=>typeof e=="function",ks=e=>Array.isArray(e),rc=e=>e instanceof Object,sc=e=>e instanceof Object?e.constructor.name!=="Function"&&e.constructor.name!=="Object":!1,$x=e=>rc(e)&&!ks(e)&&!nc(e)&&!sc(e);function We(e){let t;if(ks(e))t=e;else{const i=mt(e),n=i==null?void 0:i.rgb();t=[((n==null?void 0:n.r)??0)/255,((n==null?void 0:n.g)??0)/255,((n==null?void 0:n.b)??0)/255,(i==null?void 0:i.opacity)??1]}return t}function oc(e,t,i){return .2126*e+.7152*t+.0722*i}function we(e,t,i=0,n=0,r,s){return e.readPixelsToArrayWebGL(t,{sourceX:i,sourceY:n,sourceWidth:r,sourceHeight:s})}function ac(){const e=new Uint32Array(2);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(7,"0")).join("")}function Ds(e,t){const i=[],n=Math.min(e.length/4,t??1/0);for(let r=0;r<n;r+=1)e[r*4]!==0&&i.push(r);return i}function Fs(e,t){switch(e.info.type){case"webgl":{const i=e.gl,n=i.getParameter(i.ALIASED_POINT_SIZE_RANGE);return((n==null?void 0:n[1])??Hn)/t}case"webgpu":return Hn/t;default:return Hn/t}}function lc(e,t,i){return Math.min(Math.max(e,t),i)}function ft(e){return e!=null&&!Number.isNaN(e)}function De(e,t){return Number.isNaN(e[t*2])||Number.isNaN(e[t*2+1])}function cc(e,t){return Pm.sanitize(e,{ALLOWED_TAGS:["a","b","i","em","strong","span","div","p","br"],ALLOWED_ATTR:["href","target","class","id","style"],ALLOW_DATA_ATTR:!1,...t})}var Ms=(e=>(e[e.Circle=0]="Circle",e[e.Square=1]="Square",e[e.Triangle=2]="Triangle",e[e.Diamond=3]="Diamond",e[e.Pentagon=4]="Pentagon",e[e.Hexagon=5]="Hexagon",e[e.Star=6]="Star",e[e.Cross=7]="Cross",e[e.None=8]="None",e))(Ms||{}),Ns=(e=>(e[e.Solid=0]="Solid",e[e.Dashed=1]="Dashed",e[e.Dotted=2]="Dotted",e))(Ns||{});const uc=e=>{if(!e)return;const{offsets:t,neighbors:i,linkIndices:n}=e,r=new Array(t.length-1).fill(void 0);for(let s=0;s<r.length;s++){const o=t[s],a=t[s+1];if(o===a)continue;const l=new Array(a-o);for(let c=o;c<a;c++)l[c-o]=[i[c],n[c]];r[s]=l}return r};class Xx{constructor(t){this.sourcePointsNumber=0,this.targetPointsNumber=0,this._isLinkGroupingStale=!0,this._config=t}get pointsNumber(){return this.pointPositions&&this.pointPositions.length/2}get linksNumber(){return this.links&&this.links.length/2}get sourceIndexToTargetIndices(){return this._sourceIndexToTargetIndices??(this._sourceIndexToTargetIndices=uc(this.linksBySource)),this._sourceIndexToTargetIndices}get targetIndexToSourceIndices(){return this._targetIndexToSourceIndices??(this._targetIndexToSourceIndices=uc(this.linksByTarget)),this._targetIndexToSourceIndices}get defaultRgba(){return this._defaultRgba??(this._defaultRgba=We(this._config.pointDefaultColor)),this._defaultRgba}get inputLinks(){return this._inputLinks}set inputLinks(t){this._inputLinks=t,this._isLinkGroupingStale=!0}updatePoints(){this.inputPointPositions!==void 0&&this.inputPointPositions.length%2!==0&&(console.warn(`Invalid point positions length: ${this.inputPointPositions.length}. The array must hold [x, y] pairs — the trailing value was ignored.`),this.inputPointPositions=this.inputPointPositions.subarray(0,this.inputPointPositions.length-1)),this.pointPositions!==this.inputPointPositions&&(this.sourcePointsNumber=this.pointPositions?this.pointPositions.length/2:0,this.pointPositions=this.inputPointPositions,this.targetPointsNumber=this.pointPositions?this.pointPositions.length/2:0)}updatePointColor(){if(this.pointsNumber===void 0){this.pointColors=void 0;return}this._defaultRgba=void 0,this.inputPointColors===void 0||this.inputPointColors.length/4!==this.pointsNumber?this.pointColors=new Float32Array(this.pointsNumber*4).fill(NaN):this.pointColors=this.inputPointColors}getResolvedPointColorChannel(t,i){var r;const n=(r=this.pointColors)==null?void 0:r[t*4+i];return ft(n)?n:this.pointPositions&&De(this.pointPositions,t)?Xn:this.defaultRgba[i]}updatePointSize(){if(this.pointsNumber===void 0){this.pointSizes=void 0;return}this.inputPointSizes===void 0||this.inputPointSizes.length!==this.pointsNumber?this.pointSizes=new Float32Array(this.pointsNumber).fill(NaN):this.pointSizes=this.inputPointSizes}getResolvedPointSize(t){var i;return this.resolvePointSize(t,(i=this.pointSizes)==null?void 0:i[t])}resolvePointSize(t,i){return ft(i)?i:this.pointPositions&&De(this.pointPositions,t)?Os:this._config.pointDefaultSize}updatePointShape(){if(this.pointsNumber===void 0){this.pointShapes=void 0;return}const{pointDefaultShape:t}=this._config,i=typeof t=="string"?Number(t):t,n=Number.isInteger(i)&&i>=0&&i<=8?i:Ze.pointDefaultShape;if(this.inputPointShapes===void 0||this.inputPointShapes.length!==this.pointsNumber)this.pointShapes=new Float32Array(this.pointsNumber).fill(n);else{this.pointShapes=new Float32Array(this.inputPointShapes);const r=this.pointShapes;for(let s=0;s<r.length;s++){const o=r[s]??-1;(!Number.isInteger(o)||o<0||o>8)&&(r[s]=n)}}}updatePointImageIndices(){if(this.pointsNumber===void 0){this.pointImageIndices=void 0;return}if(this.inputPointImageIndices===void 0||this.inputPointImageIndices.length!==this.pointsNumber)this.pointImageIndices=new Float32Array(this.pointsNumber).fill(-1);else{const t=new Float32Array(this.inputPointImageIndices);for(let i=0;i<t.length;i++){const n=t[i],r=n===void 0?NaN:n;!Number.isFinite(r)||r<0?t[i]=-1:t[i]=Math.trunc(r)}this.pointImageIndices=t}}updatePointImageSizes(){if(this.pointsNumber===void 0){this.pointImageSizes=void 0;return}if(this.inputPointImageSizes===void 0||this.inputPointImageSizes.length!==this.pointsNumber){this.pointImageSizes=new Float32Array(this.pointsNumber);for(let t=0;t<this.pointsNumber;t++)this.pointImageSizes[t]=this.getResolvedPointSize(t)}else{this.pointImageSizes=new Float32Array(this.inputPointImageSizes);for(let t=0;t<this.pointImageSizes.length;t++)ft(this.pointImageSizes[t])||(this.pointImageSizes[t]=this.getResolvedPointSize(t))}}pointDrawsImage(t){var n,r;const i=((n=this.pointImageIndices)==null?void 0:n[t])??-1;return i>=0&&i<(((r=this.inputImageData)==null?void 0:r.length)??0)}getResolvedPointFootprint(t,i){var r;const n=this.pointDrawsImage(t)?(r=this.pointImageSizes)==null?void 0:r[t]:void 0;return Math.max(i??this.getResolvedPointSize(t),n??0)}isPointIndex(t){return t!==void 0&&Number.isInteger(t)&&t>=0&&t<(this.pointsNumber??0)}updateLinks(){this.inputLinks!==void 0&&this.inputLinks.length%2!==0&&(console.warn(`Invalid links length: ${this.inputLinks.length}. The array must hold [source, target] pairs — the trailing value was ignored.`),this.inputLinks=this.inputLinks.subarray(0,this.inputLinks.length-1)),this.links=this.inputLinks}updateLinkColor(){if(this.linksNumber===void 0){this.linkColors=void 0;return}const t=We(this._config.linkDefaultColor);if(this.inputLinkColors===void 0||this.inputLinkColors.length/4!==this.linksNumber){this.linkColors=new Float32Array(this.linksNumber*4);for(let i=0;i<this.linkColors.length/4;i++)this.linkColors[i*4]=t[0],this.linkColors[i*4+1]=t[1],this.linkColors[i*4+2]=t[2],this.linkColors[i*4+3]=t[3]}else{this.linkColors=this.inputLinkColors;for(let i=0;i<this.linkColors.length/4;i++)ft(this.linkColors[i*4])||(this.linkColors[i*4]=t[0]),ft(this.linkColors[i*4+1])||(this.linkColors[i*4+1]=t[1]),ft(this.linkColors[i*4+2])||(this.linkColors[i*4+2]=t[2]),ft(this.linkColors[i*4+3])||(this.linkColors[i*4+3]=t[3])}}updateLinkWidth(){if(this.linksNumber===void 0){this.linkWidths=void 0;return}const t=this._config.linkDefaultWidth;if(this.inputLinkWidths===void 0||this.inputLinkWidths.length!==this.linksNumber)this.linkWidths=new Float32Array(this.linksNumber).fill(t);else{this.linkWidths=this.inputLinkWidths;for(let i=0;i<this.linkWidths.length;i++)ft(this.linkWidths[i])||(this.linkWidths[i]=t)}}updateLinkStyles(){if(this.linksNumber===void 0){this.linkStyles=void 0;return}const{linkDefaultStyle:t}=this._config,i=typeof t=="string"?Number(t):t,n=Number.isInteger(i)&&i>=0&&i<=2?i:Ze.linkDefaultStyle;if(this.inputLinkStyles===void 0||this.inputLinkStyles.length!==this.linksNumber)this.linkStyles=new Float32Array(this.linksNumber).fill(n);else{this.linkStyles=new Float32Array(this.inputLinkStyles);const r=this.linkStyles;for(let s=0;s<r.length;s++){const o=r[s]??-1;(!Number.isInteger(o)||o<0||o>2)&&(r[s]=n)}}}updateArrows(){if(this.linksNumber===void 0){this.linkArrows=void 0;return}const t=this._config.linkDefaultArrows;this.linkArrowsBoolean===void 0||this.linkArrowsBoolean.length!==this.linksNumber?this.linkArrows=new Array(this.linksNumber).fill(+t):this.linkArrows=this.linkArrowsBoolean.map(i=>+i)}updateLinkStrength(){this.linksNumber===void 0&&(this.linkStrength=void 0),this.inputLinkStrength===void 0||this.inputLinkStrength.length!==this.linksNumber?this.linkStrength=void 0:this.linkStrength=this.inputLinkStrength}updateClusters(){if(this.pointsNumber===void 0){this.pointClusters=void 0,this.clusterPositions=void 0;return}this.inputPointClusters===void 0||this.inputPointClusters.length!==this.pointsNumber?this.pointClusters=void 0:this.pointClusters=this.inputPointClusters,this.inputClusterPositions===void 0?this.clusterPositions=void 0:this.clusterPositions=this.inputClusterPositions,this.inputClusterStrength===void 0||this.inputClusterStrength.length!==this.pointsNumber?this.clusterStrength=void 0:this.clusterStrength=this.inputClusterStrength}update(){this.updatePoints(),this.updatePointColor(),this.updatePointSize(),this.updatePointShape(),this.updatePointImageIndices(),this.updatePointImageSizes(),this.updateLinks(),this.updateLinkColor(),this.updateLinkWidth(),this.updateArrows(),this.updateLinkStyles(),this.updateLinkStrength(),this.updateClusters(),(this._isLinkGroupingStale||this._linkGroupingPointsNumber!==this.pointsNumber)&&(this._groupLinksByPoint(),this._calculateDegrees())}getNeighboringPointIndices(t){const i=Array.isArray(t)?t:[t],n=new Set,r=[this.linksBySource,this.linksByTarget];for(const s of i)if(this.isPointIndex(s))for(const o of r){if(!o)continue;const{offsets:a,neighbors:l}=o,c=a[s+1];for(let u=a[s];u<c;u++)n.add(l[u])}return[...n]}getConnectedLinkIndices(t){const i=Array.isArray(t)?t:[t],n=new Set(i),r=[];if(!this.linksBySource)return r;const{offsets:s,neighbors:o,linkIndices:a}=this.linksBySource;for(const l of n){if(!this.isPointIndex(l))continue;const c=s[l+1];for(let u=s[l];u<c;u++)n.has(o[u])&&r.push(a[u])}return r}getConnectedPointIndices(t){const i=Array.isArray(t)?t:[t],n=new Set;if(this.links===void 0)return[];const r=this.linksNumber??0;for(const s of i){if(!Number.isInteger(s)||s<0||s>=r)continue;const o=this.links[s*2],a=this.links[s*2+1];!this.isPointIndex(o)||!this.isPointIndex(a)||(n.add(o),n.add(a))}return[...n]}_groupLinksByPoint(){const{links:t,linksNumber:i,pointsNumber:n}=this;if(this._isLinkGroupingStale=!1,this._linkGroupingPointsNumber=n,this._sourceIndexToTargetIndices=void 0,this._targetIndexToSourceIndices=void 0,t===void 0||i===void 0||n===void 0){this.linksBySource=void 0,this.linksByTarget=void 0;return}const r=new Uint32Array(n+1),s=new Uint32Array(n+1);for(let d=0;d<i;d++){const h=t[d*2],p=t[d*2+1];!this.isPointIndex(h)||!this.isPointIndex(p)||(r[h+1]=r[h+1]+1,s[p+1]=s[p+1]+1)}for(let d=0;d<n;d++)r[d+1]=r[d+1]+r[d],s[d+1]=s[d+1]+s[d];const o=r[n],a={offsets:r,neighbors:new Uint32Array(o),linkIndices:new Uint32Array(o)},l={offsets:s,neighbors:new Uint32Array(o),linkIndices:new Uint32Array(o)},c=r.slice(0,n),u=s.slice(0,n);for(let d=0;d<i;d++){const h=t[d*2],p=t[d*2+1];if(!this.isPointIndex(h)||!this.isPointIndex(p))continue;const g=c[h];c[h]=g+1,a.neighbors[g]=p,a.linkIndices[g]=d;const x=u[p];u[p]=x+1,l.neighbors[x]=h,l.linkIndices[x]=d}this.linksBySource=a,this.linksByTarget=l}_calculateDegrees(){var r,s;const t=this.pointsNumber;if(t===void 0){this.degree=void 0,this.inDegree=void 0,this.outDegree=void 0;return}this.degree=new Array(t).fill(0),this.inDegree=new Array(t).fill(0),this.outDegree=new Array(t).fill(0);const i=(r=this.linksBySource)==null?void 0:r.offsets,n=(s=this.linksByTarget)==null?void 0:s.offsets;if(!(!i||!n))for(let o=0;o<t;o++){const a=n[o+1]-n[o],l=i[o+1]-i[o];this.inDegree[o]=a,this.outDegree[o]=l,this.degree[o]=a+l}}}var le=(e=>(e.Positions="positions",e.PointColors="pointColors",e.PointSizes="pointSizes",e.LinkColors="linkColors",e.LinkWidths="linkWidths",e))(le||{}),Bs=(e=>(e.Linear="linear",e.QuadIn="quad-in",e.QuadOut="quad-out",e.QuadInOut="quad-in-out",e.CubicIn="cubic-in",e.CubicOut="cubic-out",e.CubicInOut="cubic-in-out",e.SinIn="sin-in",e.SinOut="sin-out",e.SinInOut="sin-in-out",e.ExpIn="exp-in",e.ExpOut="exp-out",e.ExpInOut="exp-in-out",e.CircleIn="circle-in",e.CircleOut="circle-out",e.CircleInOut="circle-in-out",e))(Bs||{});const Yx={linear:Qa,"quad-in":Ja,"quad-out":el,"quad-in-out":tl,"cubic-in":yg,"cubic-out":_g,"cubic-in-out":il,"sin-in":bg,"sin-out":Tg,"sin-in-out":vg,"exp-in":Pg,"exp-out":Cg,"exp-in-out":Ag,"circle-in":Rg,"circle-out":wg,"circle-in-out":Eg};class jx{constructor(t){this.progress=1,this.startTime=0,this.pendingProperties=new Set,this.activeProperties=new Set,this.activeDuration=0,this.config=t}get duration(){return this.overrideDuration??this.config.transitionDuration}get isPending(){return this.pendingProperties.size>0}get isActive(){return this.activeProperties.size>0}setDurationOverride(t){this.overrideDuration=t!==void 0&&Number.isFinite(t)?t:void 0}isPendingFor(t){return this.pendingProperties.has(t)}isActiveFor(t){return this.activeProperties.has(t)}queue(t){this.pendingProperties.add(t)}dequeue(t){this.pendingProperties.delete(t)}start(){var i,n,r,s;const t=this.duration;if(this.overrideDuration=void 0,!!this.isPending){if(t<=0){const o=this.isActive;this.pendingProperties.clear(),this.clearActiveCycle(),o&&((n=(i=this.config).onTransitionEnd)==null||n.call(i,!0));return}this.isActive&&this.end(!0),this.activeDuration=t,this.startTime=performance.now(),this.progress=0,this.activeProperties=new Set(this.pendingProperties),this.pendingProperties.clear(),(s=(r=this.config).onTransitionStart)==null||s.call(r)}}step(){var r,s;if(!this.isActive)return;const t=this.activeDuration;if(t<=0){this.end(!0);return}const i=Math.min((performance.now()-this.startTime)/t,1),n=this.applyEasing(i);this.progress=n,(s=(r=this.config).onTransition)==null||s.call(r,n),i>=1&&this.end(!1)}end(t){var i,n;this.isActive&&(this.clearActiveCycle(),(n=(i=this.config).onTransitionEnd)==null||n.call(i,t))}abort(){this.pendingProperties.clear(),this.overrideDuration=void 0,this.clearActiveCycle()}applyEasing(t){return(Yx[this.config.transitionEasing]??Qa)(t)}clearActiveCycle(){this.startTime=0,this.progress=1,this.activeProperties.clear()}}const Ze={enableSimulation:!0,enableRenderLoop:!0,transitionDuration:800,transitionEasing:Bs.CubicInOut,backgroundColor:"#222222",spaceSize:4096,pointDefaultColor:"#b3b3b3",pointDefaultSize:4,pointDefaultShape:Ms.Circle,pointOpacity:1,pointGreyoutOpacity:void 0,pointGreyoutColor:void 0,pointSizeScale:1,pointOcclusionCulling:!0,scalePointsOnZoom:!1,hoveredPointCursor:"auto",renderHoveredPointRing:!1,hoveredPointRingColor:"white",focusedPointRingColor:"white",focusedPointIndex:void 0,highlightedPointIndices:void 0,outlinedPointIndices:void 0,outlinedPointRingColor:"white",renderLinks:!0,linkDefaultColor:"#666666",linkDefaultWidth:1,linkDefaultStyle:Ns.Solid,linkDashLength:8,linkDashGap:4,linkColorInterpolateFromEndpoints:!1,linkOpacity:1,linkGreyoutOpacity:.1,linkWidthScale:1,scaleLinksOnZoom:!1,linkBlending:!0,curvedLinks:!1,curvedLinkSegments:19,curvedLinkWeight:.8,curvedLinkControlPointDistance:.5,linkDefaultArrows:!1,linkArrowsSizeScale:1,linkVisibilityDistanceRange:[50,150],linkVisibilityMinTransparency:.25,hoveredLinkCursor:"auto",hoveredLinkColor:void 0,hoveredLinkWidthIncrease:5,highlightedLinkIndices:void 0,focusedLinkIndex:void 0,focusedLinkWidthIncrease:5,simulationDecay:5e3,simulationGravity:.25,simulationCenter:0,simulationRepulsion:1,simulationRepulsionTheta:1.15,simulationLinkSpring:1,simulationLinkDistance:10,simulationLinkDistRandomVariationRange:[1,1.2],simulationRepulsionFromMouse:2,simulationFriction:.85,simulationCluster:.1,simulationCollision:0,simulationCollisionRadius:void 0,simulationCollisionPadding:0,enableRightClickRepulsion:!1,onSimulationStart:void 0,onSimulationTick:void 0,onSimulationEnd:void 0,onSimulationPause:void 0,onSimulationUnpause:void 0,onTransitionStart:void 0,onTransition:void 0,onTransitionEnd:void 0,onClick:void 0,onPointClick:void 0,onLinkClick:void 0,onBackgroundClick:void 0,onContextMenu:void 0,onPointContextMenu:void 0,onLinkContextMenu:void 0,onBackgroundContextMenu:void 0,onMouseMove:void 0,onPointMouseOver:void 0,onPointMouseOut:void 0,onLinkMouseOver:void 0,onLinkMouseOut:void 0,onZoomStart:void 0,onZoom:void 0,onZoomEnd:void 0,onDragStart:void 0,onDrag:void 0,onDragEnd:void 0,showFPSMonitor:!1,pixelRatio:typeof window<"u"&&window.devicePixelRatio||2,enableZoom:!0,enableSimulationDuringZoom:!1,initialZoomLevel:void 0,enableDrag:!1,fitViewOnInit:!0,fitViewDelay:250,fitViewPadding:.1,fitViewDuration:250,fitViewByPointsInRect:void 0,fitViewByPointIndices:void 0,pointSamplingDistance:100,linkSamplingDistance:100,randomSeed:void 0,rescalePositions:void 0,attribution:""},dc=.7,hc=.95,Os=0,Xn=0,Us=1,fc=1.3;function zs(){const e={};for(const[t,i]of Object.entries(Ze))e[t]=Array.isArray(i)?[...i]:i;return e}function Kx(e){Object.assign(e,zs())}function Bi(e,t,i=!1){const n={};for(const[r,s]of Object.entries(t))if(s!==void 0)n[r]=s;else if(i){const o=Ze[r];n[r]=Array.isArray(o)?[...o]:o}Object.assign(e,n)}var qx=`<div class="gl-box"> + <svg viewBox="0 0 55 60"> + <text x="27" y="56" class="gl-fps">00 FPS</text> + <text x="28" y="8" class="gl-mem"></text> + <rect x="0" y="14" rx="4" ry="4" width="55" height="32"></rect> + <polyline class="gl-chart"></polyline> + </svg> + <svg viewBox="0 0 14 60" class="gl-cpu-svg"> + <line x1="7" y1="38" x2="7" y2="11" class="opacity"/> + <line x1="7" y1="38" x2="7" y2="11" class="gl-cpu" stroke-dasharray="0 27"/> + <path d="M5.35 43c-.464 0-.812.377-.812.812v1.16c-.783.1972-1.421.812-1.595 1.624h-1.16c-.435 0-.812.348-.812.812s.348.812.812.812h1.102v1.653H1.812c-.464 0-.812.377-.812.812 0 .464.377.812.812.812h1.131c.1943.783.812 1.392 1.595 1.595v1.131c0 .464.377.812.812.812.464 0 .812-.377.812-.812V53.15h1.653v1.073c0 .464.377.812.812.812.464 0 .812-.377.812-.812v-1.131c.783-.1943 1.392-.812 1.595-1.595h1.131c.464 0 .812-.377.812-.812 0-.464-.377-.812-.812-.812h-1.073V48.22h1.102c.435 0 .812-.348.812-.812s-.348-.812-.812-.812h-1.16c-.1885-.783-.812-1.421-1.595-1.624v-1.131c0-.464-.377-.812-.812-.812-.464 0-.812.377-.812.812v1.073H6.162v-1.073c0-.464-.377-.812-.812-.812zm.58 3.48h2.088c.754 0 1.363.609 1.363 1.363v2.088c0 .754-.609 1.363-1.363 1.363H5.93c-.754 0-1.363-.609-1.363-1.363v-2.088c0-.754.609-1.363 1.363-1.363z"/> + </svg> + <svg viewBox="0 0 14 60" class="gl-gpu-svg"> + <line x1="7" y1="38" x2="7" y2="11" class="opacity"/> + <line x1="7" y1="38" x2="7" y2="11" class="gl-gpu" stroke-dasharray="0 27"/> + <path d="M1.94775 43.3772a.736.736 0 10-.00416 1.472c.58535.00231.56465.1288.6348.3197.07015.18975.04933.43585.04933.43585l-.00653.05405v8.671a.736.736 0 101.472 0v-1.4145c.253.09522.52785.1495.81765.1495h5.267c1.2535 0 2.254-.9752 2.254-2.185v-3.105c0-1.2075-1.00625-2.185-2.254-2.185h-5.267c-.28865 0-.5635.05405-.8165.1495.01806-.16445.04209-.598-.1357-1.0787-.22425-.6072-.9499-1.2765-2.0125-1.2765zm2.9095 3.6455c.42435 0 .7659.36225.7659.8119v2.9785c0 .44965-.34155.8119-.7659.8119s-.7659-.36225-.7659-.8119v-2.9785c0-.44965.34155-.8119.7659-.8119zm4.117 0a2.3 2.3 0 012.3 2.3 2.3 2.3 0 01-2.3 2.3 2.3 2.3 0 01-2.3-2.3 2.3 2.3 0 012.3-2.3z"/> + </svg> +</div>`,Gx=`#gl-bench { + position:absolute; + left:0; + top:0; + z-index:1000; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +#gl-bench div { + position: relative; + display: block; + margin: 4px; + padding: 0 7px 0 10px; + background: #6c6; + border-radius: 15px; + cursor: pointer; + opacity: 0.9; +} + +#gl-bench svg { + height: 60px; + margin: 0 -1px; +} + +#gl-bench text { + font-size: 12px; + font-family: Helvetica,Arial,sans-serif; + font-weight: 700; + dominant-baseline: middle; + text-anchor: middle; +} + +#gl-bench .gl-mem { + font-size: 9px; +} + +#gl-bench line { + stroke-width: 5; + stroke: #112211; + stroke-linecap: round; +} + +#gl-bench polyline { + fill: none; + stroke: #112211; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 3.5; +} + +#gl-bench rect { + fill: #448844; +} + +#gl-bench .opacity { + stroke: #448844; +} +`;class Zx{constructor(t,i={}){this.css=Gx,this.svg=qx,this.paramLogger=()=>{},this.chartLogger=()=>{},this.chartLen=20,this.chartHz=20,this.names=[],this.cpuAccums=[],this.gpuAccums=[],this.activeAccums=[],this.chart=new Array(this.chartLen),this.now=()=>performance&&performance.now?performance.now():Date.now(),this.updateUI=()=>{[].forEach.call(this.nodes["gl-gpu-svg"],a=>{a.style.display=this.trackGPU?"inline":"none"})},Object.assign(this,i),this.detected=0,this.finished=[],this.isFramebuffer=0,this.frameId=0;let n,r=0,s,o=a=>{++r<20?n=requestAnimationFrame(o):(this.detected=Math.ceil(1e3*r/(a-s)/70),cancelAnimationFrame(n)),s||(s=a)};if(requestAnimationFrame(o),t){const a=async(c,u)=>Promise.resolve(setTimeout(()=>{t.getError();const d=this.now()-c;u.forEach((h,p)=>{h&&(this.gpuAccums[p]+=d)})},0)),l=(c,u,d)=>function(){const h=u.now();c.apply(d,arguments),u.trackGPU&&u.finished.push(a(h,u.activeAccums.slice(0)))};["drawArrays","drawElements","drawArraysInstanced","drawBuffers","drawElementsInstanced","drawRangeElements"].forEach(c=>{t[c]&&(t[c]=l(t[c],this,t))}),t.getExtension=((c,u)=>function(){let d=c.apply(t,arguments);return d&&["drawElementsInstancedANGLE","drawBuffersWEBGL"].forEach(h=>{d[h]&&(d[h]=l(d[h],u,d))}),d})(t.getExtension,this)}if(!this.withoutUI){this.dom||(this.dom=document.body);let a=document.createElement("div");a.id="gl-bench",this.dom.appendChild(a),this.dom.insertAdjacentHTML("afterbegin",'<style id="gl-bench-style">'+this.css+"</style>"),this.dom=a,this.dom.addEventListener("click",()=>{this.trackGPU=!this.trackGPU,this.updateUI()}),this.paramLogger=((l,c,u)=>{const d=["gl-cpu","gl-gpu","gl-mem","gl-fps","gl-gpu-svg","gl-chart"],h=Object.assign({},d);return d.forEach(p=>h[p]=c.getElementsByClassName(p)),this.nodes=h,(p,g,x,T,S,P,I)=>{h["gl-cpu"][p].style.strokeDasharray=(g*.27).toFixed(0)+" 100",h["gl-gpu"][p].style.strokeDasharray=(x*.27).toFixed(0)+" 100",h["gl-mem"][p].innerHTML=u[p]?u[p]:T?"mem: "+T.toFixed(0)+"mb":"",h["gl-fps"][p].innerHTML=S.toFixed(0)+" FPS",l(u[p],g,x,T,S,P,I)}})(this.paramLogger,this.dom,this.names),this.chartLogger=((l,c)=>{let u={"gl-chart":c.getElementsByClassName("gl-chart")};return(d,h,p)=>{let g="",x=h.length;for(let T=0;T<x;T++){let S=(p+T+1)%x;h[S]!=null&&(g=g+" "+(55*T/(x-1)).toFixed(1)+","+(45-h[S]*22/60/this.detected).toFixed(1))}u["gl-chart"][d].setAttribute("points",g),l(this.names[d],h,p)}})(this.chartLogger,this.dom)}}addUI(t){this.names.indexOf(t)==-1&&(this.names.push(t),this.dom&&(this.dom.insertAdjacentHTML("beforeend",this.svg),this.updateUI()),this.cpuAccums.push(0),this.gpuAccums.push(0),this.activeAccums.push(!1))}nextFrame(t){this.frameId++;const i=t||this.now();if(this.frameId<=1)this.paramFrame=this.frameId,this.paramTime=i;else{let n=i-this.paramTime;if(n>=1e3){const r=this.frameId-this.paramFrame,s=r/n*1e3;for(let o=0;o<this.names.length;o++){const a=this.cpuAccums[o]/n*100,l=this.gpuAccums[o]/n*100,c=performance&&performance.memory?performance.memory.usedJSHeapSize/(1<<20):0;this.paramLogger(o,a,l,c,s,n,r),this.cpuAccums[o]=0,Promise.all(this.finished).then(()=>{this.gpuAccums[o]=0,this.finished=[]})}this.paramFrame=this.frameId,this.paramTime=i}}if(!this.detected||!this.chartFrame)this.chartFrame=this.frameId,this.chartTime=i,this.circularId=0;else{let n=i-this.chartTime,r=this.chartHz*n/1e3;for(;--r>0&&this.detected;){const o=(this.frameId-this.chartFrame)/n*1e3;this.chart[this.circularId%this.chartLen]=o;for(let a=0;a<this.names.length;a++)this.chartLogger(a,this.chart,this.circularId);this.circularId++,this.chartFrame=this.frameId,this.chartTime=i}}}begin(t){this.updateAccums(t)}end(t){this.updateAccums(t)}updateAccums(t){let i=this.names.indexOf(t);i==-1&&(i=this.names.length,this.addUI(t));const n=this.now(),r=n-this.t0;for(let s=0;s<i+1;s++)this.activeAccums[s]&&(this.cpuAccums[s]+=r);this.activeAccums[i]=!this.activeAccums[i],this.t0=n}}const Qx=` + #gl-bench { + position:absolute; + right:0; + top:0; + z-index:1000; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + } + #gl-bench div { + position: relative; + display: block; + margin: 4px; + padding: 0 7px 0 10px; + background: #5f69de; + border-radius: 15px; + cursor: pointer; + opacity: 0.9; + } + #gl-bench svg { + height: 60px; + margin: 0 -1px; + } + #gl-bench text { + font-size: 12px; + font-family: Helvetica,Arial,sans-serif; + font-weight: 700; + dominant-baseline: middle; + text-anchor: middle; + } + #gl-bench .gl-mem { + font-size: 9px; + } + #gl-bench line { + stroke-width: 5; + stroke: #112211; + stroke-linecap: round; + } + #gl-bench polyline { + fill: none; + stroke: #112211; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 3.5; + } + #gl-bench rect { + fill: #8288e4; + } + #gl-bench .opacity { + stroke: #8288e4; + } +`;class pc{constructor(t,i){this.container=i??document.body,this.destroy();const n=t.getContext("webgl")||t.getContext("experimental-webgl");this.bench=new Zx(n,{css:Qx,dom:this.container})}begin(){var t;(t=this.bench)==null||t.begin("frame")}end(t){var i,n;(i=this.bench)==null||i.end("frame"),(n=this.bench)==null||n.nextFrame(t)}destroy(){var t,i;this.bench=void 0,(t=this.container.querySelector(":scope > #gl-bench"))==null||t.remove(),(i=this.container.querySelector(":scope > #gl-bench-style"))==null||i.remove()}}function gc(){let e;if(typeof window<"u"&&window.performance)e=window.performance.now();else if(typeof process<"u"&&process.hrtime){const t=process.hrtime();e=t[0]*1e3+t[1]/1e6}else e=Date.now();return e}class mc{constructor(t,i){this.sampleSize=1,this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this.name=t,this.type=i,this.reset()}reset(){return this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this}setSampleSize(t){return this.sampleSize=t,this}incrementCount(){return this.addCount(1),this}decrementCount(){return this.subtractCount(1),this}addCount(t){return this._count+=t,this._samples++,this._checkSampling(),this}subtractCount(t){return this._count-=t,this._samples++,this._checkSampling(),this}addTime(t){return this._time+=t,this.lastTiming=t,this._samples++,this._checkSampling(),this}timeStart(){return this._startTime=gc(),this._timerPending=!0,this}timeEnd(){return this._timerPending?(this.addTime(gc()-this._startTime),this._timerPending=!1,this._checkSampling(),this):this}getSampleAverageCount(){return this.sampleSize>0?this.lastSampleCount/this.sampleSize:0}getSampleAverageTime(){return this.sampleSize>0?this.lastSampleTime/this.sampleSize:0}getSampleHz(){return this.lastSampleTime>0?this.sampleSize/(this.lastSampleTime/1e3):0}getAverageCount(){return this.samples>0?this.count/this.samples:0}getAverageTime(){return this.samples>0?this.time/this.samples:0}getHz(){return this.time>0?this.samples/(this.time/1e3):0}_checkSampling(){this._samples===this.sampleSize&&(this.lastSampleTime=this._time,this.lastSampleCount=this._count,this.count+=this._count,this.time+=this._time,this.samples+=this._samples,this._time=0,this._count=0,this._samples=0)}}class Jx{constructor(t){this.stats={},this.id=t.id,this.stats={},this._initializeStats(t.stats),Object.seal(this)}get(t,i="count"){return this._getOrCreate({name:t,type:i})}get size(){return Object.keys(this.stats).length}reset(){for(const t of Object.values(this.stats))t.reset();return this}forEach(t){for(const i of Object.values(this.stats))t(i)}getTable(){const t={};return this.forEach(i=>{t[i.name]={time:i.time||0,count:i.count||0,average:i.getAverageTime()||0,hz:i.getHz()||0}}),t}_initializeStats(t=[]){t.forEach(i=>this._getOrCreate(i))}_getOrCreate(t){const{name:i,type:n}=t;let r=this.stats[i];return r||(t instanceof mc?r=t:r=new mc(i,n),this.stats[i]=r),r}}const eS="GPU Time and Memory",tS=["Adapter","GPU","GPU Type","GPU Backend","Frame Rate","CPU Time","GPU Time","GPU Memory","Buffer Memory","Texture Memory","Referenced Buffer Memory","Referenced Texture Memory","Swap Chain Texture"],xc=new WeakMap,Sc=new WeakMap;class iS{constructor(){f(this,"stats",new Map)}getStats(t){return this.get(t)}get(t){this.stats.has(t)||this.stats.set(t,new Jx({id:t}));const i=this.stats.get(t);return t===eS&&nS(i,tS),i}}const yc=new iS;function nS(e,t){const i=e.stats;let n=!1;for(const l of t)i[l]||(e.get(l),n=!0);const r=Object.keys(i).length,s=xc.get(e);if(!n&&(s==null?void 0:s.orderedStatNames)===t&&s.statCount===r)return;const o={};let a=Sc.get(t);a||(a=new Set(t),Sc.set(t,a));for(const l of t)i[l]&&(o[l]=i[l]);for(const[l,c]of Object.entries(i))a.has(l)||(o[l]=c);for(const l of Object.keys(i))delete i[l];Object.assign(i,o),xc.set(e,{orderedStatNames:t,statCount:r})}const Yn=globalThis,Jt=globalThis.process||{},rS=globalThis.navigator||{};function _c(e){var n,r;if(typeof window<"u"&&((n=window.process)==null?void 0:n.type)==="renderer"||typeof process<"u"&&((r=process.versions)!=null&&r.electron))return!0;const i=typeof navigator<"u"&&navigator.userAgent;return!!(i&&i.indexOf("Electron")>=0)}function Mt(){return!(typeof process=="object"&&String(process)==="[object process]"&&!(process!=null&&process.browser))||_c()}function sS(e){return Mt()?_c()?"Electron":(rS.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown":"Node"}const bc="4.1.1";function Ls(e,t){if(!e)throw new Error("Assertion failed")}function Tc(e){if(!e)return 0;let t;switch(typeof e){case"number":t=e;break;case"object":t=e.logLevel||e.priority||0;break;default:return 0}return Ls(Number.isFinite(t)&&t>=0),t}function oS(e){const{logLevel:t,message:i}=e;e.logLevel=Tc(t);const n=e.args?Array.from(e.args):[];for(;n.length&&n.shift()!==i;);switch(typeof t){case"string":case"function":i!==void 0&&n.unshift(i),e.message=t;break;case"object":Object.assign(e,t);break}typeof e.message=="function"&&(e.message=e.message());const r=typeof e.message;return Ls(r==="string"||r==="object"),Object.assign(e,{args:n},e.opts)}const ei=()=>{};class aS{constructor({level:t=0}={}){this.userData={},this._onceCache=new Set,this._level=t}set level(t){this.setLevel(t)}get level(){return this.getLevel()}setLevel(t){return this._level=t,this}getLevel(){return this._level}warn(t,...i){return this._log("warn",0,t,i,{once:!0})}error(t,...i){return this._log("error",0,t,i)}log(t,i,...n){return this._log("log",t,i,n)}info(t,i,...n){return this._log("info",t,i,n)}once(t,i,...n){return this._log("once",t,i,n,{once:!0})}_log(t,i,n,r,s={}){const o=oS({logLevel:i,message:n,args:this._buildArgs(i,n,r),opts:s});return this._createLogFunction(t,o,s)}_buildArgs(t,i,n){return[t,i,...n]}_createLogFunction(t,i,n){if(!this._shouldLog(i.logLevel))return ei;const r=this._getOnceTag(n.tag??i.tag??i.message);if((n.once||i.once)&&r!==void 0){if(this._onceCache.has(r))return ei;this._onceCache.add(r)}return this._emit(t,i)}_shouldLog(t){return this.getLevel()>=Tc(t)}_getOnceTag(t){if(t!==void 0)try{return typeof t=="string"?t:String(t)}catch{return}}}function lS(e){try{const t=window[e],i="__storage_test__";return t.setItem(i,i),t.removeItem(i),t}catch{return null}}class cS{constructor(t,i,n="sessionStorage"){this.storage=lS(n),this.id=t,this.config=i,this._loadConfiguration()}getConfiguration(){return this.config}setConfiguration(t){if(Object.assign(this.config,t),this.storage){const i=JSON.stringify(this.config);this.storage.setItem(this.id,i)}}_loadConfiguration(){let t={};if(this.storage){const i=this.storage.getItem(this.id);t=i?JSON.parse(i):{}}return Object.assign(this.config,t),this}}function uS(e){let t;return e<10?t=`${e.toFixed(2)}ms`:e<100?t=`${e.toFixed(1)}ms`:e<1e3?t=`${e.toFixed(0)}ms`:t=`${(e/1e3).toFixed(2)}s`,t}function dS(e,t=8){const i=Math.max(t-e.length,0);return`${" ".repeat(i)}${e}`}var jn;(function(e){e[e.BLACK=30]="BLACK",e[e.RED=31]="RED",e[e.GREEN=32]="GREEN",e[e.YELLOW=33]="YELLOW",e[e.BLUE=34]="BLUE",e[e.MAGENTA=35]="MAGENTA",e[e.CYAN=36]="CYAN",e[e.WHITE=37]="WHITE",e[e.BRIGHT_BLACK=90]="BRIGHT_BLACK",e[e.BRIGHT_RED=91]="BRIGHT_RED",e[e.BRIGHT_GREEN=92]="BRIGHT_GREEN",e[e.BRIGHT_YELLOW=93]="BRIGHT_YELLOW",e[e.BRIGHT_BLUE=94]="BRIGHT_BLUE",e[e.BRIGHT_MAGENTA=95]="BRIGHT_MAGENTA",e[e.BRIGHT_CYAN=96]="BRIGHT_CYAN",e[e.BRIGHT_WHITE=97]="BRIGHT_WHITE"})(jn||(jn={}));const hS=10;function vc(e){return typeof e!="string"?e:(e=e.toUpperCase(),jn[e]||jn.WHITE)}function fS(e,t,i){return!Mt&&typeof e=="string"&&(t&&(e=`\x1B[${vc(t)}m${e}\x1B[39m`),i&&(e=`\x1B[${vc(i)+hS}m${e}\x1B[49m`)),e}function pS(e,t=["constructor"]){const i=Object.getPrototypeOf(e),n=Object.getOwnPropertyNames(i),r=e;for(const s of n){const o=r[s];typeof o=="function"&&(t.find(a=>s===a)||(r[s]=o.bind(e)))}}function Oi(){var t,i,n;let e;if(Mt()&&Yn.performance)e=(i=(t=Yn==null?void 0:Yn.performance)==null?void 0:t.now)==null?void 0:i.call(t);else if("hrtime"in Jt){const r=(n=Jt==null?void 0:Jt.hrtime)==null?void 0:n.call(Jt);e=r[0]*1e3+r[1]/1e6}else e=Date.now();return e}const ti={debug:Mt()&&console.debug||console.log,log:console.log,info:console.info,warn:console.warn,error:console.error},Ws={enabled:!0,level:0};class Pc extends aS{constructor({id:t}={id:""}){super({level:0}),this.VERSION=bc,this._startTs=Oi(),this._deltaTs=Oi(),this.userData={},this.LOG_THROTTLE_TIMEOUT=0,this.id=t,this.userData={},this._storage=new cS(`__probe-${this.id}__`,{[this.id]:Ws}),this.timeStamp(`${this.id} started`),pS(this),Object.seal(this)}isEnabled(){return this._getConfiguration().enabled}getLevel(){return this._getConfiguration().level}getTotal(){return Number((Oi()-this._startTs).toPrecision(10))}getDelta(){return Number((Oi()-this._deltaTs).toPrecision(10))}set priority(t){this.level=t}get priority(){return this.level}getPriority(){return this.level}enable(t=!0){return this._updateConfiguration({enabled:t}),this}setLevel(t){return this._updateConfiguration({level:t}),this}get(t){return this._getConfiguration()[t]}set(t,i){this._updateConfiguration({[t]:i})}settings(){console.table?console.table(this._storage.config):console.log(this._storage.config)}assert(t,i){if(!t)throw new Error(i||"Assertion failed")}warn(t,...i){return this._log("warn",0,t,i,{method:ti.warn,once:!0})}error(t,...i){return this._log("error",0,t,i,{method:ti.error})}deprecated(t,i){return this.warn(`\`${t}\` is deprecated and will be removed in a later version. Use \`${i}\` instead`)}removed(t,i){return this.error(`\`${t}\` has been removed. Use \`${i}\` instead`)}probe(t,i,...n){return this._log("log",t,i,n,{method:ti.log,time:!0,once:!0})}log(t,i,...n){return this._log("log",t,i,n,{method:ti.debug})}info(t,i,...n){return this._log("info",t,i,n,{method:console.info})}once(t,i,...n){return this._log("once",t,i,n,{method:ti.debug||ti.info,once:!0})}table(t,i,n){return i?this._log("table",t,i,n&&[n]||[],{method:console.table||ei,tag:mS(i)}):ei}time(t,i){return this._log("time",t,i,[],{method:console.time?console.time:console.info})}timeEnd(t,i){return this._log("time",t,i,[],{method:console.timeEnd?console.timeEnd:console.info})}timeStamp(t,i){return this._log("time",t,i,[],{method:console.timeStamp||ei})}group(t,i,n={collapsed:!1}){const r=(n.collapsed?console.groupCollapsed:console.group)||console.info;return this._log("group",t,i,[],{method:r})}groupCollapsed(t,i,n={}){return this.group(t,i,Object.assign({},n,{collapsed:!0}))}groupEnd(t){return this._log("groupEnd",t,"",[],{method:console.groupEnd||ei})}withGroup(t,i,n){this.group(t,i)();try{n()}finally{this.groupEnd(t)()}}trace(){console.trace&&console.trace()}_shouldLog(t){return this.isEnabled()&&super._shouldLog(t)}_emit(t,i){const n=i.method;Ls(n),i.total=this.getTotal(),i.delta=this.getDelta(),this._deltaTs=Oi();const r=gS(this.id,i.message,i);return n.bind(console,r,...i.args)}_getConfiguration(){return this._storage.config[this.id]||this._updateConfiguration(Ws),this._storage.config[this.id]}_updateConfiguration(t){const i=this._storage.config[this.id]||{...Ws};this._storage.setConfiguration({[this.id]:{...i,...t}})}}Pc.VERSION=bc;function gS(e,t,i){if(typeof t=="string"){const n=i.time?dS(uS(i.total)):"";t=i.time?`${e}: ${n} ${t}`:`${e}: ${t}`,t=fS(t,i.color,i.background)}return t}function mS(e){for(const t in e)for(const i in e[t])return i||"untitled";return"empty"}const C=new Pc({id:"luma.gl"}),Vs={};function Ui(e="id"){Vs[e]=Vs[e]||1;const t=Vs[e]++;return`${e}-${t}`}const xS="cpu-hotspot-profiler",Cc="GPU Resource Counts",Ac="Resource Counts",Rc="GPU Time and Memory",SS=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],yS=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","SharedRenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],_S=SS.flatMap(e=>[`${e} Created`,`${e} Active`]),bS=yS.flatMap(e=>[`${e} Created`,`${e} Active`]),wc=new WeakMap,Ec=new WeakMap;class Z{constructor(t,i,n){f(this,"id");f(this,"props");f(this,"userData",{});f(this,"_device");f(this,"destroyed",!1);f(this,"allocatedBytes",0);f(this,"allocatedBytesName",null);f(this,"_attachedResources",new Set);if(!t)throw new Error("no device");this._device=t,this.props=TS(i,n);const r=this.props.id!=="undefined"?this.props.id:Ui(this[Symbol.toStringTag]);this.props.id=r,this.id=r,this.userData=this.props.userData||{},this.addStats()}toString(){return`${this[Symbol.toStringTag]||this.constructor.name}:"${this.id}"`}destroy(){this.destroyed||this.destroyResource()}delete(){return this.destroy(),this}getProps(){return this.props}attachResource(t){this._attachedResources.add(t)}detachResource(t){this._attachedResources.delete(t)}destroyAttachedResource(t){this._attachedResources.delete(t)&&t.destroy()}destroyAttachedResources(){for(const t of this._attachedResources)t.destroy();this._attachedResources=new Set}destroyResource(){this.destroyed||(this.destroyAttachedResources(),this.removeStats(),this.destroyed=!0)}removeStats(){const t=zi(this._device),i=t?yt():0,n=[this._device.statsManager.getStats(Cc),this._device.statsManager.getStats(Ac)],r=kc(this._device);for(const o of n)Ic(o,r);const s=this.getStatsName();for(const o of n)o.get("Resources Active").decrementCount(),o.get(`${s}s Active`).decrementCount();t&&(t.statsBookkeepingCalls=(t.statsBookkeepingCalls||0)+1,t.statsBookkeepingTimeMs=(t.statsBookkeepingTimeMs||0)+(yt()-i))}trackAllocatedMemory(t,i=this.getStatsName()){const n=zi(this._device),r=n?yt():0,s=this._device.statsManager.getStats(Rc);this.allocatedBytes>0&&this.allocatedBytesName&&(s.get("GPU Memory").subtractCount(this.allocatedBytes),s.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes)),s.get("GPU Memory").addCount(t),s.get(`${i} Memory`).addCount(t),n&&(n.statsBookkeepingCalls=(n.statsBookkeepingCalls||0)+1,n.statsBookkeepingTimeMs=(n.statsBookkeepingTimeMs||0)+(yt()-r)),this.allocatedBytes=t,this.allocatedBytesName=i}trackReferencedMemory(t,i=this.getStatsName()){this.trackAllocatedMemory(t,`Referenced ${i}`)}trackDeallocatedMemory(t=this.getStatsName()){if(this.allocatedBytes===0){this.allocatedBytesName=null;return}const i=zi(this._device),n=i?yt():0,r=this._device.statsManager.getStats(Rc);r.get("GPU Memory").subtractCount(this.allocatedBytes),r.get(`${this.allocatedBytesName||t} Memory`).subtractCount(this.allocatedBytes),i&&(i.statsBookkeepingCalls=(i.statsBookkeepingCalls||0)+1,i.statsBookkeepingTimeMs=(i.statsBookkeepingTimeMs||0)+(yt()-n)),this.allocatedBytes=0,this.allocatedBytesName=null}trackDeallocatedReferencedMemory(t=this.getStatsName()){this.trackDeallocatedMemory(`Referenced ${t}`)}addStats(){const t=this.getStatsName(),i=zi(this._device),n=i?yt():0,r=[this._device.statsManager.getStats(Cc),this._device.statsManager.getStats(Ac)],s=kc(this._device);for(const o of r)Ic(o,s);for(const o of r)o.get("Resources Created").incrementCount(),o.get("Resources Active").incrementCount(),o.get(`${t}s Created`).incrementCount(),o.get(`${t}s Active`).incrementCount();i&&(i.statsBookkeepingCalls=(i.statsBookkeepingCalls||0)+1,i.statsBookkeepingTimeMs=(i.statsBookkeepingTimeMs||0)+(yt()-n)),vS(this._device,t)}getStatsName(){return PS(this)}}f(Z,"defaultProps",{id:"undefined",handle:void 0,userData:void 0});function TS(e,t){const i={...t};for(const n in e)e[n]!==void 0&&(i[n]=e[n]);return i}function Ic(e,t){const i=e.stats;let n=!1;for(const l of t)i[l]||(e.get(l),n=!0);const r=Object.keys(i).length,s=wc.get(e);if(!n&&(s==null?void 0:s.orderedStatNames)===t&&s.statCount===r)return;const o={};let a=Ec.get(t);a||(a=new Set(t),Ec.set(t,a));for(const l of t)i[l]&&(o[l]=i[l]);for(const[l,c]of Object.entries(i))a.has(l)||(o[l]=c);for(const l of Object.keys(i))delete i[l];Object.assign(i,o),wc.set(e,{orderedStatNames:t,statCount:r})}function kc(e){return e.type==="webgl"?bS:_S}function zi(e){const t=e.userData[xS];return t!=null&&t.enabled?t:null}function yt(){var e,t;return((t=(e=globalThis.performance)==null?void 0:e.now)==null?void 0:t.call(e))??Date.now()}function vS(e,t){const i=zi(e);if(!(!i||!i.activeDefaultFramebufferAcquireDepth))switch(i.transientCanvasResourceCreates=(i.transientCanvasResourceCreates||0)+1,t){case"Texture":i.transientCanvasTextureCreates=(i.transientCanvasTextureCreates||0)+1;break;case"TextureView":i.transientCanvasTextureViewCreates=(i.transientCanvasTextureViewCreates||0)+1;break;case"Sampler":i.transientCanvasSamplerCreates=(i.transientCanvasSamplerCreates||0)+1;break;case"Framebuffer":i.transientCanvasFramebufferCreates=(i.transientCanvasFramebufferCreates||0)+1;break}}function PS(e){let t=Object.getPrototypeOf(e);for(;t;){const i=Object.getPrototypeOf(t);if(!i||i===Z.prototype)return CS(t)||e[Symbol.toStringTag]||e.constructor.name;t=i}return e[Symbol.toStringTag]||e.constructor.name}function CS(e){const t=Object.getOwnPropertyDescriptor(e,Symbol.toStringTag);return typeof(t==null?void 0:t.get)=="function"?t.get.call(e):typeof(t==null?void 0:t.value)=="string"?t.value:null}const Pe=class Pe extends Z{constructor(i,n){const r={...n};(n.usage||0)&Pe.INDEX&&!n.indexType&&(n.data instanceof Uint32Array?r.indexType="uint32":n.data instanceof Uint16Array?r.indexType="uint16":n.data instanceof Uint8Array&&(r.indexType="uint8")),delete r.data;super(i,r,Pe.defaultProps);f(this,"usage");f(this,"indexType");f(this,"updateTimestamp");f(this,"debugData",new ArrayBuffer(0));this.usage=r.usage||0,this.indexType=r.indexType,this.updateTimestamp=i.incrementTimestamp()}get[Symbol.toStringTag](){return"Buffer"}clone(i){return this.device.createBuffer({...this.props,...i})}_setDebugData(i,n,r){let s=null,o;ArrayBuffer.isView(i)?(s=i,o=i.buffer):o=i;const a=Math.min(i?i.byteLength:r,Pe.DEBUG_DATA_MAX_LENGTH);if(o===null)this.debugData=new ArrayBuffer(a);else{const l=Math.min((s==null?void 0:s.byteOffset)||0,o.byteLength),c=Math.max(0,o.byteLength-l),u=Math.min(a,c);this.debugData=new Uint8Array(o,l,u).slice().buffer}}};f(Pe,"INDEX",16),f(Pe,"VERTEX",32),f(Pe,"UNIFORM",64),f(Pe,"STORAGE",128),f(Pe,"INDIRECT",256),f(Pe,"QUERY_RESOLVE",512),f(Pe,"MAP_READ",1),f(Pe,"MAP_WRITE",2),f(Pe,"COPY_SRC",4),f(Pe,"COPY_DST",8),f(Pe,"DEBUG_DATA_MAX_LENGTH",32),f(Pe,"defaultProps",{...Z.defaultProps,usage:0,byteLength:0,byteOffset:0,data:null,indexType:"uint16",onMapped:void 0});let B=Pe;class AS{getDataTypeInfo(t){const[i,n,r]=Hs[t],s=t.includes("norm"),o=!s&&!t.startsWith("float"),a=t.startsWith("s");return{signedType:i,primitiveType:n,byteLength:r,normalized:s,integer:o,signed:a}}getNormalizedDataType(t){const i=t;switch(i){case"uint8":return"unorm8";case"sint8":return"snorm8";case"uint16":return"unorm16";case"sint16":return"snorm16";default:return i}}alignTo(t,i){switch(i){case 1:return t;case 2:return t+t%2;default:return t+(4-t%4)%4}}getDataType(t){const i=ArrayBuffer.isView(t)?t.constructor:t;if(i===Uint8ClampedArray)return"uint8";const n=Object.values(Hs).find(r=>i===r[4]);if(!n)throw new Error(i.name);return n[0]}getTypedArrayConstructor(t){const[,,,,i]=Hs[t];return i}}const Nt=new AS,Hs={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]};class RS{getVertexFormatInfo(t){let i;t.endsWith("-webgl")&&(t.replace("-webgl",""),i=!0);const[n,r]=t.split("x"),s=n,o=r?parseInt(r):1,a=Nt.getDataTypeInfo(s),l={type:s,components:o,byteLength:a.byteLength*o,integer:a.integer,signed:a.signed,normalized:a.normalized};return i&&(l.webglOnly=!0),l}makeVertexFormat(t,i,n){const r=n?Nt.getNormalizedDataType(t):t;switch(r){case"unorm8":return i===1?"unorm8":i===3?"unorm8x3-webgl":`${r}x${i}`;case"snorm8":return i===1?"snorm8":i===3?"snorm8x3-webgl":`${r}x${i}`;case"uint8":case"sint8":if(i===1||i===3)throw new Error(`size: ${i}`);return`${r}x${i}`;case"uint16":return i===1?"uint16":i===3?"uint16x3-webgl":`${r}x${i}`;case"sint16":return i===1?"sint16":i===3?"sint16x3-webgl":`${r}x${i}`;case"unorm16":return i===1?"unorm16":i===3?"unorm16x3-webgl":`${r}x${i}`;case"snorm16":return i===1?"snorm16":i===3?"snorm16x3-webgl":`${r}x${i}`;case"float16":if(i===1||i===3)throw new Error(`size: ${i}`);return`${r}x${i}`;default:return i===1?r:`${r}x${i}`}}getVertexFormatFromAttribute(t,i,n){if(!i||i>4)throw new Error(`size ${i}`);const r=i,s=Nt.getDataType(t);return this.makeVertexFormat(s,r,n)}getCompatibleVertexFormat(t){let i;switch(t.primitiveType){case"f32":i="float32";break;case"i32":i="sint32";break;case"u32":i="uint32";break;case"f16":return t.components<=2?"float16x2":"float16x4"}return t.components===1?i:`${i}x${t.components}`}}const Li=new RS,Ae="texture-compression-bc",ne="texture-compression-astc",rt="texture-compression-etc2",wS="texture-compression-etc1-webgl",Kn="texture-compression-pvrtc-webgl",$s="texture-compression-atc-webgl",qn="float32-renderable-webgl",Xs="float16-renderable-webgl",ES="rgb9e5ufloat-renderable-webgl",Ys="snorm8-renderable-webgl",_t="norm16-webgl",js="norm16-renderable-webgl",Ks="snorm16-renderable-webgl",Gn="float32-filterable",Dc="float16-filterable-webgl";function Fc(e){const t=Mc[e];if(!t)throw new Error(`Unsupported texture format ${e}`);return t}function IS(){return Mc}const Mc={...{r8unorm:{},rg8unorm:{},"rgb8unorm-webgl":{},rgba8unorm:{},"rgba8unorm-srgb":{},r8snorm:{render:Ys},rg8snorm:{render:Ys},"rgb8snorm-webgl":{},rgba8snorm:{render:Ys},r8uint:{},rg8uint:{},rgba8uint:{},r8sint:{},rg8sint:{},rgba8sint:{},bgra8unorm:{},"bgra8unorm-srgb":{},r16unorm:{f:_t,render:js},rg16unorm:{f:_t,render:js},"rgb16unorm-webgl":{f:_t,render:!1},rgba16unorm:{f:_t,render:js},r16snorm:{f:_t,render:Ks},rg16snorm:{f:_t,render:Ks},"rgb16snorm-webgl":{f:_t,render:!1},rgba16snorm:{f:_t,render:Ks},r16uint:{},rg16uint:{},rgba16uint:{},r16sint:{},rg16sint:{},rgba16sint:{},r16float:{render:Xs,filter:"float16-filterable-webgl"},rg16float:{render:Xs,filter:Dc},rgba16float:{render:Xs,filter:Dc},r32uint:{},rg32uint:{},rgba32uint:{},r32sint:{},rg32sint:{},rgba32sint:{},r32float:{render:qn,filter:Gn},rg32float:{render:!1,filter:Gn},"rgb32float-webgl":{render:qn,filter:Gn},rgba32float:{render:qn,filter:Gn},"rgba4unorm-webgl":{channels:"rgba",bitsPerChannel:[4,4,4,4],packed:!0},"rgb565unorm-webgl":{channels:"rgb",bitsPerChannel:[5,6,5,0],packed:!0},"rgb5a1unorm-webgl":{channels:"rgba",bitsPerChannel:[5,5,5,1],packed:!0},rgb9e5ufloat:{channels:"rgb",packed:!0,render:ES},rg11b10ufloat:{channels:"rgb",bitsPerChannel:[11,11,10,0],packed:!0,p:1,render:qn},rgb10a2unorm:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},rgb10a2uint:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},stencil8:{attachment:"stencil",bitsPerChannel:[8,0,0,0],dataType:"uint8"},depth16unorm:{attachment:"depth",bitsPerChannel:[16,0,0,0],dataType:"uint16"},depth24plus:{attachment:"depth",bitsPerChannel:[24,0,0,0],dataType:"uint32"},depth32float:{attachment:"depth",bitsPerChannel:[32,0,0,0],dataType:"float32"},"depth24plus-stencil8":{attachment:"depth-stencil",bitsPerChannel:[24,8,0,0],packed:!0},"depth32float-stencil8":{attachment:"depth-stencil",bitsPerChannel:[32,8,0,0],packed:!0}},...{"bc1-rgb-unorm-webgl":{f:Ae},"bc1-rgb-unorm-srgb-webgl":{f:Ae},"bc1-rgba-unorm":{f:Ae},"bc1-rgba-unorm-srgb":{f:Ae},"bc2-rgba-unorm":{f:Ae},"bc2-rgba-unorm-srgb":{f:Ae},"bc3-rgba-unorm":{f:Ae},"bc3-rgba-unorm-srgb":{f:Ae},"bc4-r-unorm":{f:Ae},"bc4-r-snorm":{f:Ae},"bc5-rg-unorm":{f:Ae},"bc5-rg-snorm":{f:Ae},"bc6h-rgb-ufloat":{f:Ae},"bc6h-rgb-float":{f:Ae},"bc7-rgba-unorm":{f:Ae},"bc7-rgba-unorm-srgb":{f:Ae},"etc2-rgb8unorm":{f:rt},"etc2-rgb8unorm-srgb":{f:rt},"etc2-rgb8a1unorm":{f:rt},"etc2-rgb8a1unorm-srgb":{f:rt},"etc2-rgba8unorm":{f:rt},"etc2-rgba8unorm-srgb":{f:rt},"eac-r11unorm":{f:rt},"eac-r11snorm":{f:rt},"eac-rg11unorm":{f:rt},"eac-rg11snorm":{f:rt},"astc-4x4-unorm":{f:ne},"astc-4x4-unorm-srgb":{f:ne},"astc-5x4-unorm":{f:ne},"astc-5x4-unorm-srgb":{f:ne},"astc-5x5-unorm":{f:ne},"astc-5x5-unorm-srgb":{f:ne},"astc-6x5-unorm":{f:ne},"astc-6x5-unorm-srgb":{f:ne},"astc-6x6-unorm":{f:ne},"astc-6x6-unorm-srgb":{f:ne},"astc-8x5-unorm":{f:ne},"astc-8x5-unorm-srgb":{f:ne},"astc-8x6-unorm":{f:ne},"astc-8x6-unorm-srgb":{f:ne},"astc-8x8-unorm":{f:ne},"astc-8x8-unorm-srgb":{f:ne},"astc-10x5-unorm":{f:ne},"astc-10x5-unorm-srgb":{f:ne},"astc-10x6-unorm":{f:ne},"astc-10x6-unorm-srgb":{f:ne},"astc-10x8-unorm":{f:ne},"astc-10x8-unorm-srgb":{f:ne},"astc-10x10-unorm":{f:ne},"astc-10x10-unorm-srgb":{f:ne},"astc-12x10-unorm":{f:ne},"astc-12x10-unorm-srgb":{f:ne},"astc-12x12-unorm":{f:ne},"astc-12x12-unorm-srgb":{f:ne},"pvrtc-rgb4unorm-webgl":{f:Kn},"pvrtc-rgba4unorm-webgl":{f:Kn},"pvrtc-rgb2unorm-webgl":{f:Kn},"pvrtc-rgba2unorm-webgl":{f:Kn},"etc1-rbg-unorm-webgl":{f:wS},"atc-rgb-unorm-webgl":{f:$s},"atc-rgba-unorm-webgl":{f:$s},"atc-rgbai-unorm-webgl":{f:$s}}},kS=/^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/,DS=["rgb","rgba","bgra"],FS=["depth","stencil"],MS=["bc1","bc2","bc3","bc4","bc5","bc6","bc7","etc1","etc2","eac","atc","astc","pvrtc"];class NS{isColor(t){return DS.some(i=>t.startsWith(i))}isDepthStencil(t){return FS.some(i=>t.startsWith(i))}isCompressed(t){return MS.some(i=>t.startsWith(i))}getInfo(t){return Nc(t)}getCapabilities(t){return OS(t)}computeMemoryLayout(t){return BS(t)}}const Ve=new NS;function BS({format:e,width:t,height:i,depth:n,byteAlignment:r}){const s=Ve.getInfo(e),{bytesPerPixel:o,bytesPerBlock:a=o,blockWidth:l=1,blockHeight:c=1,compressed:u=!1}=s,d=u?Math.ceil(t/l):t,h=u?Math.ceil(i/c):i,p=d*a,g=Math.ceil(p/r)*r,x=h,T=g*x*n;return{bytesPerPixel:o,bytesPerRow:g,rowsPerImage:x,depthOrArrayLayers:n,bytesPerImage:g*x,byteLength:T}}function OS(e){const t=Fc(e),i={format:e,create:t.f??!0,render:t.render??!0,filter:t.filter??!0,blend:t.blend??!0,store:t.store??!0},n=Nc(e),r=e.startsWith("depth")||e.startsWith("stencil"),s=n==null?void 0:n.signed,o=n==null?void 0:n.integer,a=n==null?void 0:n.webgl,l=!!(n!=null&&n.compressed);return i.render&&(i.render=!r&&!l),i.filter&&(i.filter=!r&&!s&&!o&&!a),i}function Nc(e){let t=US(e);if(Ve.isCompressed(e)){t.channels="rgb",t.components=3,t.bytesPerPixel=1,t.srgb=!1,t.compressed=!0,t.bytesPerBlock=LS(e);const n=zS(e);n&&(t.blockWidth=n.blockWidth,t.blockHeight=n.blockHeight)}const i=t.packed?null:kS.exec(e);if(i){const[,n,r,s,o,a]=i,l=`${s}${r}`,c=Nt.getDataTypeInfo(l),u=c.byteLength*8,d=(n==null?void 0:n.length)??1,h=[u,d>=2?u:0,d>=3?u:0,d>=4?u:0];t={format:e,attachment:t.attachment,dataType:c.signedType,components:d,channels:n,integer:c.integer,signed:c.signed,normalized:c.normalized,bitsPerChannel:h,bytesPerPixel:c.byteLength*d,packed:t.packed,srgb:t.srgb},a==="-webgl"&&(t.webgl=!0),o==="-srgb"&&(t.srgb=!0)}return e.endsWith("-webgl")&&(t.webgl=!0),e.endsWith("-srgb")&&(t.srgb=!0),t}function US(e){var s;const t=Fc(e),i=t.bytesPerPixel||1,n=t.bitsPerChannel||[8,8,8,8];return delete t.bitsPerChannel,delete t.bytesPerPixel,delete t.f,delete t.render,delete t.filter,delete t.blend,delete t.store,{...t,format:e,attachment:t.attachment||"color",channels:t.channels||"r",components:t.components||((s=t.channels)==null?void 0:s.length)||1,bytesPerPixel:i,bitsPerChannel:n,dataType:t.dataType||"uint8",srgb:t.srgb??!1,packed:t.packed??!1,webgl:t.webgl??!1,integer:t.integer??!1,signed:t.signed??!1,normalized:t.normalized??!1,compressed:t.compressed??!1}}function zS(e){const i=/.*-(\d+)x(\d+)-.*/.exec(e);if(i){const[,n,r]=i;return{blockWidth:Number(n),blockHeight:Number(r)}}return e.startsWith("bc")||e.startsWith("etc1")||e.startsWith("etc2")||e.startsWith("eac")||e.startsWith("atc")?{blockWidth:4,blockHeight:4}:e.startsWith("pvrtc-rgb4")||e.startsWith("pvrtc-rgba4")?{blockWidth:4,blockHeight:4}:e.startsWith("pvrtc-rgb2")||e.startsWith("pvrtc-rgba2")?{blockWidth:8,blockHeight:4}:null}function LS(e){return e.startsWith("bc1")||e.startsWith("bc4")||e.startsWith("etc1")||e.startsWith("etc2-rgb8")||e.startsWith("etc2-rgb8a1")||e.startsWith("eac-r11")||e==="atc-rgb-unorm-webgl"?8:e.startsWith("bc2")||e.startsWith("bc3")||e.startsWith("bc5")||e.startsWith("bc6h")||e.startsWith("bc7")||e.startsWith("etc2-rgba8")||e.startsWith("eac-rg11")||e.startsWith("astc")||e==="atc-rgba-unorm-webgl"||e==="atc-rgbai-unorm-webgl"?16:e.startsWith("pvrtc")?8:16}function qs(e){return typeof ImageData<"u"&&e instanceof ImageData||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement||typeof HTMLVideoElement<"u"&&e instanceof HTMLVideoElement||typeof VideoFrame<"u"&&e instanceof VideoFrame||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas}function Bc(e){if(typeof ImageData<"u"&&e instanceof ImageData||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas)return{width:e.width,height:e.height};if(typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement)return{width:e.naturalWidth,height:e.naturalHeight};if(typeof HTMLVideoElement<"u"&&e instanceof HTMLVideoElement)return{width:e.videoWidth,height:e.videoHeight};if(typeof VideoFrame<"u"&&e instanceof VideoFrame)return{width:e.displayWidth,height:e.displayHeight};throw new Error("Unknown image type")}class WS{}function VS(e,t){const i=Gs(e),n=t.map(Gs).filter(r=>r!==void 0);return[i,...n].filter(r=>r!==void 0)}function Gs(e){var t;if(e!==void 0){if(e===null||typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e;if(e instanceof Error)return e.message;if(Array.isArray(e))return e.map(Gs);if(typeof e=="object"){if(HS(e)){const i=String(e);if(i!=="[object Object]")return i}return $S(e)?XS(e):((t=e.constructor)==null?void 0:t.name)||"Object"}return String(e)}}function HS(e){return"toString"in e&&typeof e.toString=="function"&&e.toString!==Object.prototype.toString}function $S(e){return"message"in e&&"type"in e}function XS(e){const t=typeof e.type=="string"?e.type:"message",i=typeof e.message=="string"?e.message:"",n=typeof e.lineNum=="number"?e.lineNum:null,r=typeof e.linePos=="number"?e.linePos:null,s=n!==null&&r!==null?` @ ${n}:${r}`:n!==null?` @ ${n}`:"";return`${t}${s}: ${i}`.trim()}class YS{constructor(t=[],i){f(this,"features");f(this,"disabledFeatures");this.features=new Set(t),this.disabledFeatures=i||{}}*[Symbol.iterator](){yield*this.features}has(t){var i;return!((i=this.disabledFeatures)!=null&&i[t])&&this.features.has(t)}}const Tr=class Tr{constructor(t){f(this,"id");f(this,"props");f(this,"userData",{});f(this,"statsManager",yc);f(this,"_factories",{});f(this,"timestamp",0);f(this,"_reused",!1);f(this,"_moduleData",{});f(this,"_textureCaps",{});f(this,"_debugGPUTimeQuery",null);this.props={...Tr.defaultProps,...t},this.id=this.props.id||Ui(this[Symbol.toStringTag].toLowerCase())}get[Symbol.toStringTag](){return"Device"}toString(){return`Device(${this.id})`}getVertexFormatInfo(t){return Li.getVertexFormatInfo(t)}isVertexFormatSupported(t){return!0}getTextureFormatInfo(t){return Ve.getInfo(t)}getTextureFormatCapabilities(t){let i=this._textureCaps[t];if(!i){const n=this._getDeviceTextureFormatCapabilities(t);i=this._getDeviceSpecificTextureFormatCapabilities(n),this._textureCaps[t]=i}return i}getMipLevelCount(t,i,n=1){const r=Math.max(t,i,n);return 1+Math.floor(Math.log2(r))}isExternalImage(t){return qs(t)}getExternalImageSize(t){return Bc(t)}isTextureFormatSupported(t){return this.getTextureFormatCapabilities(t).create}isTextureFormatFilterable(t){return this.getTextureFormatCapabilities(t).filter}isTextureFormatRenderable(t){return this.getTextureFormatCapabilities(t).render}isTextureFormatCompressed(t){return Ve.isCompressed(t)}getSupportedCompressedTextureFormats(){const t=[];for(const i of Object.keys(IS()))this.isTextureFormatCompressed(i)&&this.isTextureFormatSupported(i)&&t.push(i);return t}pushDebugGroup(t){this.commandEncoder.pushDebugGroup(t)}popDebugGroup(){var t;(t=this.commandEncoder)==null||t.popDebugGroup()}insertDebugMarker(t){var i;(i=this.commandEncoder)==null||i.insertDebugMarker(t)}loseDevice(){return!1}incrementTimestamp(){return this.timestamp++}reportError(t,i,...n){if(!this.props.onError(t,i)){const s=VS(i,n);return C.error(this.type==="webgl"?"%cWebGL":"%cWebGPU","color: white; background: red; padding: 2px 6px; border-radius: 3px;",t.message,...s)}return()=>{}}debug(){if(this.props.debug)debugger;else C.once(0,`'Type luma.log.set({debug: true}) in console to enable debug breakpoints', +or create a device with the 'debug: true' prop.`)()}getDefaultCanvasContext(){if(!this.canvasContext)throw new Error("Device has no default CanvasContext. See props.createCanvasContext");return this.canvasContext}createFence(){throw new Error("createFence() not implemented")}beginRenderPass(t){return this.commandEncoder.beginRenderPass(t)}beginComputePass(t){return this.commandEncoder.beginComputePass(t)}generateMipmapsWebGPU(t){throw new Error("not implemented")}_createSharedRenderPipelineWebGL(t){throw new Error("_createSharedRenderPipelineWebGL() not implemented")}_createBindGroupLayoutWebGPU(t,i){throw new Error("_createBindGroupLayoutWebGPU() not implemented")}_createBindGroupWebGPU(t,i,n,r,s){throw new Error("_createBindGroupWebGPU() not implemented")}_supportsDebugGPUTime(){return this.features.has("timestamp-query")&&!!(this.props.debug||this.props.debugGPUTime)}_enableDebugGPUTime(t=256){if(!this._supportsDebugGPUTime())return null;if(this._debugGPUTimeQuery)return this._debugGPUTimeQuery;try{this._debugGPUTimeQuery=this.createQuerySet({type:"timestamp",count:t}),this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id,timeProfilingQuerySet:this._debugGPUTimeQuery})}catch{this._debugGPUTimeQuery=null}return this._debugGPUTimeQuery}_disableDebugGPUTime(){this._debugGPUTimeQuery&&(this.commandEncoder.getTimeProfilingQuerySet()===this._debugGPUTimeQuery&&(this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id})),this._debugGPUTimeQuery.destroy(),this._debugGPUTimeQuery=null)}_isDebugGPUTimeEnabled(){return this._debugGPUTimeQuery!==null}getCanvasContext(){return this.getDefaultCanvasContext()}readPixelsToArrayWebGL(t,i){throw new Error("not implemented")}readPixelsToBufferWebGL(t,i){throw new Error("not implemented")}setParametersWebGL(t){throw new Error("not implemented")}getParametersWebGL(t){throw new Error("not implemented")}withParametersWebGL(t,i){throw new Error("not implemented")}clearWebGL(t){throw new Error("not implemented")}resetWebGL(){throw new Error("not implemented")}getModuleData(t){var i;return(i=this._moduleData)[t]||(i[t]={}),this._moduleData[t]}static _getCanvasContextProps(t){return t.createCanvasContext===!0?{}:t.createCanvasContext}_getDeviceTextureFormatCapabilities(t){const i=Ve.getCapabilities(t),n=s=>(typeof s=="string"?this.features.has(s):s)??!0,r=n(i.create);return{format:t,create:r,render:r&&n(i.render),filter:r&&n(i.filter),blend:r&&n(i.blend),store:r&&n(i.store)}}_normalizeBufferProps(t){(t instanceof ArrayBuffer||ArrayBuffer.isView(t))&&(t={data:t});const i={...t};if((t.usage||0)&B.INDEX&&(t.indexType||(t.data instanceof Uint32Array?i.indexType="uint32":t.data instanceof Uint16Array?i.indexType="uint16":t.data instanceof Uint8Array&&(i.data=new Uint16Array(t.data),i.indexType="uint16")),!i.indexType))throw new Error("indices buffer content must be of type uint16 or uint32");return i}};f(Tr,"defaultProps",{id:null,powerPreference:"high-performance",failIfMajorPerformanceCaveat:!1,createCanvasContext:void 0,webgl:{},onError:(t,i)=>{},onResize:(t,i)=>{const[n,r]=t.getDevicePixelSize();C.log(1,`${t} resized => ${n}x${r}px`)()},onPositionChange:(t,i)=>{const[n,r]=t.getPosition();C.log(1,`${t} repositioned => ${n},${r}`)()},onVisibilityChange:t=>C.log(1,`${t} Visibility changed ${t.isVisible}`)(),onDevicePixelRatioChange:(t,i)=>C.log(1,`${t} DPR changed ${i.oldRatio} => ${t.devicePixelRatio}`)(),debug:KS(),debugGPUTime:!1,debugShaders:C.get("debug-shaders")||void 0,debugFramebuffers:!!C.get("debug-framebuffers"),debugFactories:!!C.get("debug-factories"),debugWebGL:!!C.get("debug-webgl"),debugSpectorJS:void 0,debugSpectorJSUrl:void 0,_reuseDevices:!1,_requestMaxLimits:!0,_cacheShaders:!0,_destroyShaders:!1,_cachePipelines:!0,_sharePipelines:!0,_destroyPipelines:!1,_initializeFeatures:!0,_disabledFeatures:{"compilation-status-async-webgl":!0},_handle:void 0});let Bt=Tr;function jS(e,t){return e!=null?!!e:t!==void 0?t!=="production":!1}function KS(){return jS(C.get("debug"),qS())}function qS(){const e=globalThis.process;if(e!=null&&e.env)return e.env.NODE_ENV}const GS="set luma.log.level=1 (or higher) to trace rendering",Oc="No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.",nn=class nn{constructor(){f(this,"stats",yc);f(this,"log",C);f(this,"VERSION","9.3.6");f(this,"spector");f(this,"preregisteredAdapters",new Map);if(globalThis.luma){if(globalThis.luma.VERSION!==this.VERSION)throw C.error(`Found luma.gl ${globalThis.luma.VERSION} while initialzing ${this.VERSION}`)(),C.error("'yarn why @luma.gl/core' can help identify the source of the conflict")(),new Error("luma.gl - multiple versions detected: see console log");C.error("This version of luma.gl has already been initialized")()}C.log(1,`${this.VERSION} - ${GS}`)(),globalThis.luma=this}async createDevice(t={}){const i={...nn.defaultProps,...t},n=this.selectAdapter(i.type,i.adapters);if(!n)throw new Error(Oc);return i.waitForPageLoad&&await n.pageLoaded,await n.create(i)}async attachDevice(t,i){var s;const n=this._getTypeFromHandle(t,i.adapters),r=n&&this.selectAdapter(n,i.adapters);if(!r)throw new Error(Oc);return await((s=r==null?void 0:r.attach)==null?void 0:s.call(r,t,i))}registerAdapters(t){for(const i of t)this.preregisteredAdapters.set(i.type,i)}getSupportedAdapters(t=[]){const i=this._getAdapterMap(t);return Array.from(i).map(([,n])=>n).filter(n=>{var r;return(r=n.isSupported)==null?void 0:r.call(n)}).map(n=>n.type)}getBestAvailableAdapterType(t=[]){var r,s;const i=["webgpu","webgl","null"],n=this._getAdapterMap(t);for(const o of i)if((s=(r=n.get(o))==null?void 0:r.isSupported)!=null&&s.call(r))return o;return null}selectAdapter(t,i=[]){let n=t;t==="best-available"&&(n=this.getBestAvailableAdapterType(i));const r=this._getAdapterMap(i);return n&&r.get(n)||null}enforceWebGL2(t=!0,i=[]){var s;const r=this._getAdapterMap(i).get("webgl");r||C.warn("enforceWebGL2: webgl adapter not found")(),(s=r==null?void 0:r.enforceWebGL2)==null||s.call(r,t)}setDefaultDeviceProps(t){Object.assign(nn.defaultProps,t)}_getAdapterMap(t=[]){const i=new Map(this.preregisteredAdapters);for(const n of t)i.set(n.type,n);return i}_getTypeFromHandle(t,i=[]){return t instanceof WebGL2RenderingContext?"webgl":typeof GPUDevice<"u"&&t instanceof GPUDevice||t!=null&&t.queue?"webgpu":t===null?"null":(t instanceof WebGLRenderingContext?C.warn("WebGL1 is not supported",t)():C.warn("Unknown handle type",t)(),null)}};f(nn,"defaultProps",{...Bt.defaultProps,type:"best-available",adapters:void 0,waitForPageLoad:!0});let Zs=nn;const ZS=new Zs;class QS{get pageLoaded(){return t0()}}const JS=Mt()&&typeof document<"u",e0=()=>JS&&document.readyState==="complete";let Zn=null;function t0(){return Zn||(e0()||typeof window>"u"?Zn=Promise.resolve():Zn=new Promise(e=>window.addEventListener("load",()=>e()))),Zn}class i0{constructor(t){f(this,"props");f(this,"_resizeObserver");f(this,"_intersectionObserver");f(this,"_observeDevicePixelRatioTimeout",null);f(this,"_observeDevicePixelRatioMediaQuery",null);f(this,"_handleDevicePixelRatioChange",()=>this._refreshDevicePixelRatio());f(this,"_trackPositionInterval",null);f(this,"_started",!1);this.props=t}get started(){return this._started}start(){if(this._started||!this.props.canvas)return;this._started=!0,this._intersectionObserver||(this._intersectionObserver=new IntersectionObserver(i=>this.props.onIntersection(i))),this._resizeObserver||(this._resizeObserver=new ResizeObserver(i=>this.props.onResize(i))),this._intersectionObserver.observe(this.props.canvas);const t=this.props.resizeObserverBox;try{this._resizeObserver.observe(this.props.canvas,{box:t})}catch{this._resizeObserver.observe(this.props.canvas,{box:"content-box"})}this._observeDevicePixelRatioTimeout=setTimeout(()=>this._refreshDevicePixelRatio(),0),this.props.trackPosition&&this._trackPosition()}stop(){var t,i;this._started&&(this._started=!1,this._observeDevicePixelRatioTimeout&&(clearTimeout(this._observeDevicePixelRatioTimeout),this._observeDevicePixelRatioTimeout=null),this._observeDevicePixelRatioMediaQuery&&(this._observeDevicePixelRatioMediaQuery.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=null),this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null),(t=this._resizeObserver)==null||t.disconnect(),(i=this._intersectionObserver)==null||i.disconnect())}_refreshDevicePixelRatio(){var t;this._started&&(this.props.onDevicePixelRatioChange(),(t=this._observeDevicePixelRatioMediaQuery)==null||t.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),this._observeDevicePixelRatioMediaQuery.addEventListener("change",this._handleDevicePixelRatioChange,{once:!0}))}_trackPosition(t=100){this._trackPositionInterval||(this._trackPositionInterval=setInterval(()=>{this._started?this.props.onPositionChange():this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null)},t))}}function n0(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function Uc(e,t){var i;if(!e){const n=new Error(t??"luma.gl assertion failed.");throw(i=Error.captureStackTrace)==null||i.call(Error,n,Uc),n}}function Qn(e,t){return Uc(e,t),e}const mi=class mi{constructor(t){f(this,"id");f(this,"props");f(this,"canvas");f(this,"htmlCanvas");f(this,"offscreenCanvas");f(this,"type");f(this,"initialized");f(this,"isInitialized",!1);f(this,"isVisible",!0);f(this,"cssWidth");f(this,"cssHeight");f(this,"devicePixelRatio");f(this,"devicePixelWidth");f(this,"devicePixelHeight");f(this,"drawingBufferWidth");f(this,"drawingBufferHeight");f(this,"_initializedResolvers",n0());f(this,"_canvasObserver");f(this,"_position",[0,0]);f(this,"destroyed",!1);f(this,"_needsDrawingBufferResize",!0);var i,n;this.props={...mi.defaultProps,...t},t=this.props,this.initialized=this._initializedResolvers.promise,Mt()?t.canvas?typeof t.canvas=="string"?this.canvas=s0(t.canvas):this.canvas=t.canvas:this.canvas=o0(t):this.canvas={width:t.width||1,height:t.height||1},mi.isHTMLCanvas(this.canvas)?(this.id=t.id||this.canvas.id,this.type="html-canvas",this.htmlCanvas=this.canvas):mi.isOffscreenCanvas(this.canvas)?(this.id=t.id||"offscreen-canvas",this.type="offscreen-canvas",this.offscreenCanvas=this.canvas):(this.id=t.id||"node-canvas-context",this.type="node"),this.cssWidth=((i=this.htmlCanvas)==null?void 0:i.clientWidth)||this.canvas.width,this.cssHeight=((n=this.htmlCanvas)==null?void 0:n.clientHeight)||this.canvas.height,this.devicePixelWidth=this.canvas.width,this.devicePixelHeight=this.canvas.height,this.drawingBufferWidth=this.canvas.width,this.drawingBufferHeight=this.canvas.height,this.devicePixelRatio=globalThis.devicePixelRatio||1,this._position=[0,0],this._canvasObserver=new i0({canvas:this.htmlCanvas,trackPosition:this.props.trackPosition,resizeObserverBox:this.props.pixelSizeSource==="css-dpr"?"content-box":"device-pixel-content-box",onResize:r=>this._handleResize(r),onIntersection:r=>this._handleIntersection(r),onDevicePixelRatioChange:()=>this._observeDevicePixelRatio(),onPositionChange:()=>this.updatePosition()})}static isHTMLCanvas(t){return typeof HTMLCanvasElement<"u"&&t instanceof HTMLCanvasElement}static isOffscreenCanvas(t){return typeof OffscreenCanvas<"u"&&t instanceof OffscreenCanvas}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}destroy(){this.destroyed||(this.destroyed=!0,this._stopObservers(),this.device=null)}setProps(t){return"useDevicePixels"in t&&(this.props.useDevicePixels=t.useDevicePixels||!1,this._updateDrawingBufferSize()),this}getCurrentFramebuffer(t){return this._resizeDrawingBufferIfNeeded(),this._getCurrentFramebuffer(t)}getCSSSize(){return[this.cssWidth,this.cssHeight]}getPosition(){return this._position}getDevicePixelSize(){return[this.devicePixelWidth,this.devicePixelHeight]}getDrawingBufferSize(){return[this.drawingBufferWidth,this.drawingBufferHeight]}getMaxDrawingBufferSize(){const t=this.device.limits.maxTextureDimension2D;return[t,t]}setDrawingBufferSize(t,i){t=Math.floor(t),i=Math.floor(i),!(this.drawingBufferWidth===t&&this.drawingBufferHeight===i)&&(this.drawingBufferWidth=t,this.drawingBufferHeight=i,this._needsDrawingBufferResize=!0)}getDevicePixelRatio(){return typeof window<"u"&&window.devicePixelRatio||1}cssToDevicePixels(t,i=!0){const n=this.cssToDeviceRatio(),[r,s]=this.getDrawingBufferSize();return a0(t,n,r,s,i)}getPixelSize(){return this.getDevicePixelSize()}getAspect(){const[t,i]=this.getDrawingBufferSize();return t>0&&i>0?t/i:1}cssToDeviceRatio(){try{const[t]=this.getDrawingBufferSize(),[i]=this.getCSSSize();return i?t/i:1}catch{return 1}}resize(t){this.setDrawingBufferSize(t.width,t.height)}_setAutoCreatedCanvasId(t){var i;((i=this.htmlCanvas)==null?void 0:i.id)==="lumagl-auto-created-canvas"&&(this.htmlCanvas.id=t)}_startObservers(){this.destroyed||this._canvasObserver.start()}_stopObservers(){this._canvasObserver.stop()}_handleIntersection(t){if(this.destroyed)return;const i=t.find(r=>r.target===this.canvas);if(!i)return;const n=i.isIntersecting;this.isVisible!==n&&(this.isVisible=n,this.device.props.onVisibilityChange(this))}_handleResize(t){var s;if(this.destroyed)return;const i=t.find(o=>o.target===this.canvas);if(!i)return;const n=Qn((s=i.contentBoxSize)==null?void 0:s[0]);this.cssWidth=n.inlineSize,this.cssHeight=n.blockSize;const r=this.getDevicePixelSize();this._setDevicePixelSize(this._getDevicePixelSizeFromResizeEntry(i)),this._updateDrawingBufferSize(),this.device.props.onResize(this,{oldPixelSize:r})}_updateDrawingBufferSize(){if(this.props.autoResize)if(typeof this.props.useDevicePixels=="number"){const t=this.props.useDevicePixels;this.setDrawingBufferSize(this.cssWidth*t,this.cssHeight*t)}else this.props.useDevicePixels?this.setDrawingBufferSize(this.devicePixelWidth,this.devicePixelHeight):this.setDrawingBufferSize(this.cssWidth,this.cssHeight);this._initializedResolvers.resolve(),this.isInitialized=!0,this.updatePosition()}_getDevicePixelSizeFromResizeEntry(t){var n,r,s,o,a;const i=Qn((n=t.contentBoxSize)==null?void 0:n[0]);return this.props.pixelSizeSource==="css-dpr"?this._getDevicePixelSizeFromCSSSize(i.inlineSize,i.blockSize):{devicePixelWidth:((s=(r=t.devicePixelContentBoxSize)==null?void 0:r[0])==null?void 0:s.inlineSize)||i.inlineSize*devicePixelRatio,devicePixelHeight:((a=(o=t.devicePixelContentBoxSize)==null?void 0:o[0])==null?void 0:a.blockSize)||i.blockSize*devicePixelRatio}}_getDevicePixelSizeFromCSSSize(t,i){const n=this.getDevicePixelRatio();return{devicePixelWidth:Math.floor(t*n),devicePixelHeight:Math.floor(i*n)}}_setDevicePixelSize({devicePixelWidth:t,devicePixelHeight:i}){const[n,r]=this.getMaxDrawingBufferSize();this.devicePixelWidth=Math.max(1,Math.min(t,n)),this.devicePixelHeight=Math.max(1,Math.min(i,r))}_resizeDrawingBufferIfNeeded(){this._needsDrawingBufferResize&&(this._needsDrawingBufferResize=!1,(this.drawingBufferWidth!==this.canvas.width||this.drawingBufferHeight!==this.canvas.height)&&(this.canvas.width=this.drawingBufferWidth,this.canvas.height=this.drawingBufferHeight,this._configureDevice()))}_observeDevicePixelRatio(){var i,n;if(this.destroyed||!this._canvasObserver.started)return;const t=this.devicePixelRatio;if(this.devicePixelRatio=window.devicePixelRatio,this.props.pixelSizeSource==="css-dpr"){const r=this.getDevicePixelSize();this._setDevicePixelSize(this._getDevicePixelSizeFromCSSSize(this.cssWidth,this.cssHeight)),this._updateDrawingBufferSize(),this.device.props.onResize(this,{oldPixelSize:r})}this.updatePosition(),(n=(i=this.device.props).onDevicePixelRatioChange)==null||n.call(i,this,{oldRatio:t})}updatePosition(){var i,n,r;if(this.destroyed)return;const t=(i=this.htmlCanvas)==null?void 0:i.getBoundingClientRect();if(t){const s=[t.left,t.top];if(this._position??(this._position=s),s[0]!==this._position[0]||s[1]!==this._position[1]){const a=this._position;this._position=s,(r=(n=this.device.props).onPositionChange)==null||r.call(n,this,{oldPosition:a})}}}};f(mi,"defaultProps",{id:void 0,canvas:null,width:800,height:600,useDevicePixels:!0,pixelSizeSource:"exact",autoResize:!0,container:null,visible:!0,alphaMode:"opaque",colorSpace:"srgb",trackPosition:!1});let ii=mi;function r0(e){if(typeof e=="string"){const t=document.getElementById(e);if(!t)throw new Error(`${e} is not an HTML element`);return t}return e||document.body}function s0(e){const t=document.getElementById(e);if(!ii.isHTMLCanvas(t))throw new Error("Object is not a canvas element");return t}function o0(e){const{width:t,height:i}=e,n=document.createElement("canvas");n.id=Ui("lumagl-auto-created-canvas"),n.width=t||1,n.height=i||1,n.style.width=Number.isFinite(t)?`${t}px`:"100%",n.style.height=Number.isFinite(i)?`${i}px`:"100%",e!=null&&e.visible||(n.style.visibility="hidden");const r=r0((e==null?void 0:e.container)||null);return r.insertBefore(n,r.firstChild),n}function a0(e,t,i,n,r){const s=e,o=zc(s[0],t,i);let a=Lc(s[1],t,n,r),l=zc(s[0]+1,t,i);const c=l===i-1?l:l-1;l=Lc(s[1]+1,t,n,r);let u;return r?(l=l===0?l:l+1,u=a,a=l):u=l===n-1?l:l-1,{x:o,y:a,width:Math.max(c-o+1,1),height:Math.max(u-a+1,1)}}function zc(e,t,i){return Math.min(Math.round(e*t),i-1)}function Lc(e,t,i,n){return n?Math.max(0,i-1-Math.round(e*t)):Math.min(Math.round(e*t),i-1)}class Wc extends ii{}f(Wc,"defaultProps",ii.defaultProps);class l0 extends ii{}const rn=class rn extends Z{get[Symbol.toStringTag](){return"Sampler"}constructor(t,i){i=rn.normalizeProps(t,i),super(t,i,rn.defaultProps)}static normalizeProps(t,i){return i}};f(rn,"defaultProps",{...Z.defaultProps,type:"color-sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge",magFilter:"nearest",minFilter:"nearest",mipmapFilter:"none",lodMinClamp:0,lodMaxClamp:32,compare:"less-equal",maxAnisotropy:1});let ni=rn;const c0={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},ae=class ae extends Z{constructor(i,n,r){n=ae.normalizeProps(i,n);super(i,n,ae.defaultProps);f(this,"dimension");f(this,"baseDimension");f(this,"format");f(this,"width");f(this,"height");f(this,"depth");f(this,"mipLevels");f(this,"samples");f(this,"byteAlignment");f(this,"ready",Promise.resolve(this));f(this,"isReady",!0);f(this,"updateTimestamp");if(this.dimension=this.props.dimension,this.baseDimension=c0[this.dimension],this.format=this.props.format,this.width=this.props.width,this.height=this.props.height,this.depth=this.props.depth,this.mipLevels=this.props.mipLevels,this.samples=this.props.samples||1,this.dimension==="cube"&&(this.depth=6),this.props.width===void 0||this.props.height===void 0)if(i.isExternalImage(n.data)){const s=i.getExternalImageSize(n.data);this.width=(s==null?void 0:s.width)||1,this.height=(s==null?void 0:s.height)||1}else this.width=1,this.height=1,(this.props.width===void 0||this.props.height===void 0)&&C.warn(`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`)();this.byteAlignment=(r==null?void 0:r.byteAlignment)||1,this.updateTimestamp=i.incrementTimestamp()}get[Symbol.toStringTag](){return"Texture"}toString(){return`Texture(${this.id},${this.format},${this.width}x${this.height})`}clone(i){return this.device.createTexture({...this.props,...i})}setSampler(i){this.sampler=i instanceof ni?i:this.device.createSampler(i)}copyImageData(i){const{data:n,depth:r,...s}=i;this.writeData(n,{...s,depthOrArrayLayers:s.depthOrArrayLayers??r})}computeMemoryLayout(i={}){const n=this._normalizeTextureReadOptions(i),{width:r=this.width,height:s=this.height,depthOrArrayLayers:o=this.depth}=n,{format:a,byteAlignment:l}=this;return Ve.computeMemoryLayout({format:a,width:r,height:s,depth:o,byteAlignment:l})}readBuffer(i,n){throw new Error("readBuffer not implemented")}readDataAsync(i){throw new Error("readBuffer not implemented")}writeBuffer(i,n){throw new Error("readBuffer not implemented")}writeData(i,n){throw new Error("readBuffer not implemented")}readDataSyncWebGL(i){throw new Error("readDataSyncWebGL not available")}generateMipmapsWebGL(){throw new Error("generateMipmapsWebGL not available")}static normalizeProps(i,n){const r={...n},{width:s,height:o}=r;return typeof s=="number"&&(r.width=Math.max(1,Math.ceil(s))),typeof o=="number"&&(r.height=Math.max(1,Math.ceil(o))),r}_initializeData(i){this.device.isExternalImage(i)?this.copyExternalImage({image:i,width:this.width,height:this.height,depth:this.depth,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}):i&&this.copyImageData({data:i,mipLevel:0,x:0,y:0,z:0,aspect:"all"})}_normalizeCopyImageDataOptions(i){const{data:n,depth:r,...s}=i,o=this._normalizeTextureWriteOptions({...s,depthOrArrayLayers:s.depthOrArrayLayers??r});return{data:n,depth:o.depthOrArrayLayers,...o}}_normalizeCopyExternalImageOptions(i){const n=ae._omitUndefined(i),r=n.mipLevel??0,s=this._getMipLevelSize(r),o=this.device.getExternalImageSize(i.image),a={...ae.defaultCopyExternalImageOptions,...s,...o,...n};return a.width=Math.min(a.width,s.width-a.x),a.height=Math.min(a.height,s.height-a.y),a.depth=Math.min(a.depth,s.depthOrArrayLayers-a.z),a}_normalizeTextureReadOptions(i){const n=ae._omitUndefined(i),r=n.mipLevel??0,s=this._getMipLevelSize(r),o={...ae.defaultTextureReadOptions,...s,...n};return o.width=Math.min(o.width,s.width-o.x),o.height=Math.min(o.height,s.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,s.depthOrArrayLayers-o.z),o}_getSupportedColorReadOptions(i){const n=this._normalizeTextureReadOptions(i),r=Ve.getInfo(this.format);switch(this._validateColorReadAspect(n),this._validateColorReadFormat(r),this.dimension){case"2d":case"cube":case"cube-array":case"2d-array":case"3d":return n;default:throw new Error(`${this} color readback does not support ${this.dimension} textures`)}}_validateColorReadAspect(i){if(i.aspect!=="all")throw new Error(`${this} color readback only supports aspect 'all'`)}_validateColorReadFormat(i){if(i.compressed)throw new Error(`${this} color readback does not support compressed formats (${this.format})`);switch(i.attachment){case"color":return;case"depth":throw new Error(`${this} color readback does not support depth formats (${this.format})`);case"stencil":throw new Error(`${this} color readback does not support stencil formats (${this.format})`);case"depth-stencil":throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);default:throw new Error(`${this} color readback does not support format ${this.format}`)}}_normalizeTextureWriteOptions(i){const n=ae._omitUndefined(i),r=n.mipLevel??0,s=this._getMipLevelSize(r),o={...ae.defaultTextureWriteOptions,...s,...n};o.width=Math.min(o.width,s.width-o.x),o.height=Math.min(o.height,s.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,s.depthOrArrayLayers-o.z);const a=Ve.computeMemoryLayout({format:this.format,width:o.width,height:o.height,depth:o.depthOrArrayLayers,byteAlignment:this.byteAlignment}),l=a.bytesPerPixel*o.width;if(o.bytesPerRow=n.bytesPerRow??a.bytesPerRow,o.rowsPerImage=n.rowsPerImage??o.height,o.bytesPerRow<l)throw new Error(`bytesPerRow (${o.bytesPerRow}) must be at least ${l} for ${this.format}`);if(o.rowsPerImage<o.height)throw new Error(`rowsPerImage (${o.rowsPerImage}) must be at least ${o.height} for ${this.format}`);const c=this.device.getTextureFormatInfo(this.format).bytesPerPixel;if(c&&o.bytesPerRow%c!==0)throw new Error(`bytesPerRow (${o.bytesPerRow}) must be a multiple of bytesPerPixel (${c}) for ${this.format}`);return o}_getMipLevelSize(i){const n=Math.max(1,this.width>>i),r=this.baseDimension==="1d"?1:Math.max(1,this.height>>i),s=this.dimension==="3d"?Math.max(1,this.depth>>i):this.depth;return{width:n,height:r,depthOrArrayLayers:s}}getAllocatedByteLength(){let i=0;for(let n=0;n<this.mipLevels;n++){const{width:r,height:s,depthOrArrayLayers:o}=this._getMipLevelSize(n);i+=Ve.computeMemoryLayout({format:this.format,width:r,height:s,depth:o,byteAlignment:1}).byteLength}return i*this.samples}static _omitUndefined(i){return Object.fromEntries(Object.entries(i).filter(([,n])=>n!==void 0))}};f(ae,"SAMPLE",4),f(ae,"STORAGE",8),f(ae,"RENDER",16),f(ae,"COPY_SRC",1),f(ae,"COPY_DST",2),f(ae,"TEXTURE",4),f(ae,"RENDER_ATTACHMENT",16),f(ae,"defaultProps",{...Z.defaultProps,data:null,dimension:"2d",format:"rgba8unorm",usage:ae.SAMPLE|ae.RENDER|ae.COPY_DST,width:void 0,height:void 0,depth:1,mipLevels:1,samples:void 0,sampler:{},view:void 0}),f(ae,"defaultCopyDataOptions",{data:void 0,byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,width:void 0,height:void 0,depthOrArrayLayers:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all"}),f(ae,"defaultCopyExternalImageOptions",{image:void 0,sourceX:0,sourceY:0,width:void 0,height:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}),f(ae,"defaultTextureReadOptions",{x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"}),f(ae,"defaultTextureWriteOptions",{byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"});let M=ae;const vr=class vr extends Z{get[Symbol.toStringTag](){return"TextureView"}constructor(t,i){super(t,i,vr.defaultProps)}};f(vr,"defaultProps",{...Z.defaultProps,format:void 0,dimension:void 0,aspect:"all",baseMipLevel:0,mipLevelCount:void 0,baseArrayLayer:0,arrayLayerCount:void 0});let Jn=vr;function u0(e,t,i){let n="";const r=t.split(/\r?\n/),s=e.slice().sort((o,a)=>o.lineNum-a.lineNum);switch((i==null?void 0:i.showSourceCode)||"no"){case"all":let o=0;for(let a=1;a<=r.length;a++){const l=r[a-1],c=s[o];for(l&&c&&(n+=Vc(l,a,i));s.length>o&&c.lineNum===a;){const u=s[o++];u&&(n+=Qs(u,r,u.lineNum,{...i,inlineSource:!1}))}}for(;s.length>o;){const a=s[o++];a&&(n+=Qs(a,[],0,{...i,inlineSource:!1}))}return n;case"issues":case"no":for(const a of e)n+=Qs(a,r,a.lineNum,{inlineSource:(i==null?void 0:i.showSourceCode)!=="no"});return n}}function Qs(e,t,i,n){if(n!=null&&n.inlineSource){const s=d0(t,i),o=e.linePos>0?`${" ".repeat(e.linePos+5)}^^^ +`:"";return` +${s}${o}${e.type.toUpperCase()}: ${e.message} + +`}const r=e.type==="error"?"red":"orange";return n!=null&&n.html?`<div class='luma-compiler-log-${e.type}' style="color:${r};"><b> ${e.type.toUpperCase()}: ${e.message}</b></div>`:`${e.type.toUpperCase()}: ${e.message}`}function d0(e,t,i){let n="";for(let r=t-2;r<=t;r++){const s=e[r-1];s!==void 0&&(n+=Vc(s,t,i))}return n}function Vc(e,t,i){const n=i!=null&&i.html?f0(e):e;return`${h0(String(t),4)}: ${n}${i!=null&&i.html?"<br/>":` +`}`}function h0(e,t){let i="";for(let n=e.length;n<t;++n)i+=" ";return i+e}function f0(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}const Pr=class Pr extends Z{constructor(i,n){n={...n,debugShaders:n.debugShaders||i.props.debugShaders||"errors"};super(i,{id:p0(n),...n},Pr.defaultProps);f(this,"stage");f(this,"source");f(this,"compilationStatus","pending");this.stage=this.props.stage,this.source=this.props.source}get[Symbol.toStringTag](){return"Shader"}getCompilationInfoSync(){return null}getTranslatedSource(){return null}async debugShader(){const i=this.props.debugShaders;switch(i){case"never":return;case"errors":if(this.compilationStatus==="success")return;break}const n=await this.getCompilationInfo();i==="warnings"&&(n==null?void 0:n.length)===0||this._displayShaderLog(n,this.id)}_displayShaderLog(i,n){if(typeof document>"u"||!(document!=null&&document.createElement))return;const r=n,s=`${this.stage} shader "${r}"`,o=u0(i,this.source,{showSourceCode:"all",html:!0}),a=this.getTranslatedSource(),l=document.createElement("div");l.innerHTML=`<h1>Compilation error in ${s}</h1> +<div style="display:flex;position:fixed;top:10px;right:20px;gap:2px;"> +<button id="copy">Copy source</button><br/> +<button id="close">Close</button> +</div> +<code><pre>${o}</pre></code>`,a&&(l.innerHTML+=`<br /><h1>Translated Source</h1><br /><br /><code><pre>${a}</pre></code>`),l.style.top="0",l.style.left="0",l.style.background="white",l.style.position="fixed",l.style.zIndex="9999",l.style.maxWidth="100vw",l.style.maxHeight="100vh",l.style.overflowY="auto",document.body.appendChild(l);const c=l.querySelector(".luma-compiler-log-error");c==null||c.scrollIntoView(),l.querySelector("button#close").onclick=()=>{l.remove()},l.querySelector("button#copy").onclick=()=>{navigator.clipboard.writeText(this.source)}}};f(Pr,"defaultProps",{...Z.defaultProps,language:"auto",stage:void 0,source:"",sourceMap:null,entryPoint:"main",debugShaders:void 0});let er=Pr;function p0(e){return g0(e.source)||e.id||Ui(`unnamed ${e.stage}-shader`)}function g0(e,t="unnamed"){const n=/#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/.exec(e);return(n==null?void 0:n[1])??t}const Cr=class Cr extends Z{constructor(i,n={}){super(i,n,Cr.defaultProps);f(this,"width");f(this,"height");this.width=this.props.width,this.height=this.props.height}get[Symbol.toStringTag](){return"Framebuffer"}clone(i){const n=this.colorAttachments.map(s=>s.texture.clone(i)),r=this.depthStencilAttachment&&this.depthStencilAttachment.texture.clone(i);return this.device.createFramebuffer({...this.props,...i,colorAttachments:n,depthStencilAttachment:r})}resize(i){let n=!i;if(i){const[r,s]=Array.isArray(i)?i:[i.width,i.height];n=n||s!==this.height||r!==this.width,this.width=r,this.height=s}n&&(C.log(2,`Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)(),this.resizeAttachments(this.width,this.height))}autoCreateAttachmentTextures(){if(this.props.colorAttachments.length===0&&!this.props.depthStencilAttachment)throw new Error("Framebuffer has noattachments");this.colorAttachments=this.props.colorAttachments.map((n,r)=>{if(typeof n=="string"){const s=this.createColorTexture(n,r);return this.attachResource(s),s.view}return n instanceof M?n.view:n});const i=this.props.depthStencilAttachment;if(i)if(typeof i=="string"){const n=this.createDepthStencilTexture(i);this.attachResource(n),this.depthStencilAttachment=n.view}else i instanceof M?this.depthStencilAttachment=i.view:this.depthStencilAttachment=i}createColorTexture(i,n){return this.device.createTexture({id:`${this.id}-color-attachment-${n}`,usage:M.RENDER_ATTACHMENT,format:i,width:this.width,height:this.height,sampler:{magFilter:"linear",minFilter:"linear"}})}createDepthStencilTexture(i){return this.device.createTexture({id:`${this.id}-depth-stencil-attachment`,usage:M.RENDER_ATTACHMENT,format:i,width:this.width,height:this.height})}resizeAttachments(i,n){if(this.colorAttachments.forEach((r,s)=>{const o=r.texture.clone({width:i,height:n});this.destroyAttachedResource(r),this.colorAttachments[s]=o.view,this.attachResource(o.view)}),this.depthStencilAttachment){const r=this.depthStencilAttachment.texture.clone({width:i,height:n});this.destroyAttachedResource(this.depthStencilAttachment),this.depthStencilAttachment=r.view,this.attachResource(r)}this.updateAttachments()}};f(Cr,"defaultProps",{...Z.defaultProps,width:1,height:1,colorAttachments:[],depthStencilAttachment:null});let tr=Cr;const Ar=class Ar extends Z{constructor(i,n){super(i,n,Ar.defaultProps);f(this,"shaderLayout");f(this,"bufferLayout");f(this,"linkStatus","pending");f(this,"hash","");f(this,"sharedRenderPipeline",null);this.shaderLayout=this.props.shaderLayout,this.bufferLayout=this.props.bufferLayout||[],this.sharedRenderPipeline=this.props._sharedRenderPipeline||null}get[Symbol.toStringTag](){return"RenderPipeline"}get isPending(){var i;return this.linkStatus==="pending"||this.vs.compilationStatus==="pending"||((i=this.fs)==null?void 0:i.compilationStatus)==="pending"}get isErrored(){var i;return this.linkStatus==="error"||this.vs.compilationStatus==="error"||((i=this.fs)==null?void 0:i.compilationStatus)==="error"}};f(Ar,"defaultProps",{...Z.defaultProps,vs:null,vertexEntryPoint:"vertexMain",vsConstants:{},fs:null,fragmentEntryPoint:"fragmentMain",fsConstants:{},shaderLayout:null,bufferLayout:[],topology:"triangle-list",colorAttachmentFormats:void 0,depthStencilAttachmentFormat:void 0,parameters:{},varyings:void 0,bufferMode:void 0,disableWarnings:!1,_sharedRenderPipeline:void 0,bindings:void 0,bindGroups:void 0});let bt=Ar;class m0 extends Z{get[Symbol.toStringTag](){return"SharedRenderPipeline"}constructor(t,i){super(t,i,{...Z.defaultProps,handle:void 0,vs:void 0,fs:void 0,varyings:void 0,bufferMode:void 0})}}const Rr=class Rr extends Z{constructor(i,n){super(i,n,Rr.defaultProps);f(this,"hash","");f(this,"shaderLayout");this.shaderLayout=n.shaderLayout}get[Symbol.toStringTag](){return"ComputePipeline"}};f(Rr,"defaultProps",{...Z.defaultProps,shader:void 0,entryPoint:void 0,constants:{},shaderLayout:void 0});let ir=Rr;const wr=class wr{constructor(t){f(this,"device");f(this,"_hashCounter",0);f(this,"_hashes",{});f(this,"_renderPipelineCache",{});f(this,"_computePipelineCache",{});f(this,"_sharedRenderPipelineCache",{});this.device=t}static getDefaultPipelineFactory(t){const i=t.getModuleData("@luma.gl/core");return i.defaultPipelineFactory||(i.defaultPipelineFactory=new wr(t)),i.defaultPipelineFactory}get[Symbol.toStringTag](){return"PipelineFactory"}toString(){return`PipelineFactory(${this.device.id})`}createRenderPipeline(t){var o;if(!this.device.props._cachePipelines)return this.device.createRenderPipeline(t);const i={...bt.defaultProps,...t},n=this._renderPipelineCache,r=this._hashRenderPipeline(i);let s=(o=n[r])==null?void 0:o.resource;if(s)n[r].useCount++,this.device.props.debugFactories&&C.log(3,`${this}: ${n[r].resource} reused, count=${n[r].useCount}, (id=${t.id})`)();else{const a=this.device.type==="webgl"&&this.device.props._sharePipelines?this.createSharedRenderPipeline(i):void 0;s=this.device.createRenderPipeline({...i,id:i.id?`${i.id}-cached`:Ui("unnamed-cached"),_sharedRenderPipeline:a}),s.hash=r,n[r]={resource:s,useCount:1},this.device.props.debugFactories&&C.log(3,`${this}: ${s} created, count=${n[r].useCount}`)()}return s}createComputePipeline(t){var o;if(!this.device.props._cachePipelines)return this.device.createComputePipeline(t);const i={...ir.defaultProps,...t},n=this._computePipelineCache,r=this._hashComputePipeline(i);let s=(o=n[r])==null?void 0:o.resource;return s?(n[r].useCount++,this.device.props.debugFactories&&C.log(3,`${this}: ${n[r].resource} reused, count=${n[r].useCount}, (id=${t.id})`)()):(s=this.device.createComputePipeline({...i,id:i.id?`${i.id}-cached`:void 0}),s.hash=r,n[r]={resource:s,useCount:1},this.device.props.debugFactories&&C.log(3,`${this}: ${s} created, count=${n[r].useCount}`)()),s}release(t){if(!this.device.props._cachePipelines){t.destroy();return}const i=this._getCache(t),n=t.hash;i[n].useCount--,i[n].useCount===0?(this._destroyPipeline(t),this.device.props.debugFactories&&C.log(3,`${this}: ${t} released and destroyed`)()):i[n].useCount<0?(C.error(`${this}: ${t} released, useCount < 0, resetting`)(),i[n].useCount=0):this.device.props.debugFactories&&C.log(3,`${this}: ${t} released, count=${i[n].useCount}`)()}createSharedRenderPipeline(t){const i=this._hashSharedRenderPipeline(t);let n=this._sharedRenderPipelineCache[i];return n||(n={resource:this.device._createSharedRenderPipelineWebGL(t),useCount:0},this._sharedRenderPipelineCache[i]=n),n.useCount++,n.resource}releaseSharedRenderPipeline(t){if(!t.sharedRenderPipeline)return;const i=this._hashSharedRenderPipeline(t.sharedRenderPipeline.props),n=this._sharedRenderPipelineCache[i];n&&(n.useCount--,n.useCount===0&&(n.resource.destroy(),delete this._sharedRenderPipelineCache[i]))}_destroyPipeline(t){const i=this._getCache(t);return this.device.props._destroyPipelines?(delete i[t.hash],t.destroy(),t instanceof bt&&this.releaseSharedRenderPipeline(t),!0):!1}_getCache(t){let i;if(t instanceof ir&&(i=this._computePipelineCache),t instanceof bt&&(i=this._renderPipelineCache),!i)throw new Error(`${this}`);if(!i[t.hash])throw new Error(`${this}: ${t} matched incorrect entry`);return i}_hashComputePipeline(t){const{type:i}=this.device,n=this._getHash(t.shader.source),r=this._getHash(JSON.stringify(t.shaderLayout));return`${i}/C/${n}SL${r}`}_hashRenderPipeline(t){const i=t.vs?this._getHash(t.vs.source):0,n=t.fs?this._getHash(t.fs.source):0,r=this._getWebGLVaryingHash(t),s=this._getHash(JSON.stringify(t.shaderLayout)),o=this._getHash(JSON.stringify(t.bufferLayout)),{type:a}=this.device;switch(a){case"webgl":const l=this._getHash(JSON.stringify(t.parameters));return`${a}/R/${i}/${n}V${r}T${t.topology}P${l}SL${s}BL${o}`;case"webgpu":default:const c=this._getHash(JSON.stringify({vertexEntryPoint:t.vertexEntryPoint,fragmentEntryPoint:t.fragmentEntryPoint})),u=this._getHash(JSON.stringify(t.parameters)),d=this._getWebGPUAttachmentHash(t);return`${a}/R/${i}/${n}V${r}T${t.topology}EP${c}P${u}SL${s}BL${o}A${d}`}}_hashSharedRenderPipeline(t){const i=t.vs?this._getHash(t.vs.source):0,n=t.fs?this._getHash(t.fs.source):0,r=this._getWebGLVaryingHash(t);return`webgl/S/${i}/${n}V${r}`}_getHash(t){return this._hashes[t]===void 0&&(this._hashes[t]=this._hashCounter++),this._hashes[t]}_getWebGLVaryingHash(t){const{varyings:i=[],bufferMode:n=null}=t;return this._getHash(JSON.stringify({varyings:i,bufferMode:n}))}_getWebGPUAttachmentHash(t){var r;const i=t.colorAttachmentFormats??[this.device.preferredColorFormat],n=(r=t.parameters)!=null&&r.depthWriteEnabled?t.depthStencilAttachmentFormat||this.device.preferredDepthFormat:null;return this._getHash(JSON.stringify({colorAttachmentFormats:i,depthStencilAttachmentFormat:n}))}};f(wr,"defaultProps",{...bt.defaultProps});let Js=wr;const Er=class Er{constructor(t){f(this,"device");f(this,"_cache",{});this.device=t}static getDefaultShaderFactory(t){const i=t.getModuleData("@luma.gl/core");return i.defaultShaderFactory||(i.defaultShaderFactory=new Er(t)),i.defaultShaderFactory}get[Symbol.toStringTag](){return"ShaderFactory"}toString(){return`${this[Symbol.toStringTag]}(${this.device.id})`}createShader(t){if(!this.device.props._cacheShaders)return this.device.createShader(t);const i=this._hashShader(t);let n=this._cache[i];if(n)n.useCount++,this.device.props.debugFactories&&C.log(3,`${this}: Reusing shader ${n.resource.id} count=${n.useCount}`)();else{const r=this.device.createShader({...t,id:t.id?`${t.id}-cached`:void 0});this._cache[i]=n={resource:r,useCount:1},this.device.props.debugFactories&&C.log(3,`${this}: Created new shader ${r.id}`)()}return n.resource}release(t){if(!this.device.props._cacheShaders){t.destroy();return}const i=this._hashShader(t),n=this._cache[i];if(n)if(n.useCount--,n.useCount===0)this.device.props._destroyShaders&&(delete this._cache[i],n.resource.destroy(),this.device.props.debugFactories&&C.log(3,`${this}: Releasing shader ${t.id}, destroyed`)());else{if(n.useCount<0)throw new Error(`ShaderFactory: Shader ${t.id} released too many times`);this.device.props.debugFactories&&C.log(3,`${this}: Releasing shader ${t.id} count=${n.useCount}`)()}}_hashShader(t){return`${t.stage}:${t.source}`}};f(Er,"defaultProps",{...er.defaultProps});let eo=Er;function x0(e,t,i){const n=e.bindings.find(r=>r.name===t||`${r.name.toLocaleLowerCase()}uniforms`===t.toLocaleLowerCase());return n||C.warn(`Binding ${t} not set: Not found in shader layout.`)(),n||null}function Hc(e,t){if(!t)return{};if(S0(t))return Object.fromEntries(Object.entries(t).map(([r,s])=>[Number(r),{...s}]));const i={};for(const[n,r]of Object.entries(t)){const s=x0(e,n),o=(s==null?void 0:s.group)??0;i[o]||(i[o]={}),i[o][n]=r}return i}function $c(e){const t={};for(const i of Object.values(e))Object.assign(t,i);return t}function S0(e){const t=Object.keys(e);return t.length>0&&t.every(i=>/^\d+$/.test(i))}const Qe=class Qe extends Z{get[Symbol.toStringTag](){return"RenderPass"}constructor(t,i){i=Qe.normalizeProps(t,i),super(t,i,Qe.defaultProps)}static normalizeProps(t,i){return i}};f(Qe,"defaultClearColor",[0,0,0,1]),f(Qe,"defaultClearDepth",1),f(Qe,"defaultClearStencil",0),f(Qe,"defaultProps",{...Z.defaultProps,framebuffer:null,parameters:void 0,clearColor:Qe.defaultClearColor,clearColors:void 0,clearDepth:Qe.defaultClearDepth,clearStencil:Qe.defaultClearStencil,depthReadOnly:!1,stencilReadOnly:!1,discard:!1,occlusionQuerySet:void 0,timestampQuerySet:void 0,beginTimestampIndex:void 0,endTimestampIndex:void 0});let to=Qe;const Ir=class Ir extends Z{constructor(i,n){super(i,n,Ir.defaultProps);f(this,"_timeProfilingQuerySet",null);f(this,"_timeProfilingSlotCount",0);f(this,"_gpuTimeMs");this._timeProfilingQuerySet=n.timeProfilingQuerySet??null,this._timeProfilingSlotCount=0,this._gpuTimeMs=void 0}get[Symbol.toStringTag](){return"CommandEncoder"}async resolveTimeProfilingQuerySet(){if(this._gpuTimeMs=void 0,!this._timeProfilingQuerySet)return;const i=Math.floor(this._timeProfilingSlotCount/2);if(i<=0)return;const n=i*2,r=await this._timeProfilingQuerySet.readResults({firstQuery:0,queryCount:n});let s=0n;for(let o=0;o<n;o+=2)s+=r[o+1]-r[o];this._gpuTimeMs=Number(s)/1e6}getTimeProfilingSlotCount(){return this._timeProfilingSlotCount}getTimeProfilingQuerySet(){return this._timeProfilingQuerySet}_applyTimeProfilingToPassProps(i){const n=i||{};if(!this._supportsTimestampQueries()||!this._timeProfilingQuerySet||n.timestampQuerySet!==void 0||n.beginTimestampIndex!==void 0||n.endTimestampIndex!==void 0)return n;const r=this._timeProfilingSlotCount;return r+1>=this._timeProfilingQuerySet.props.count?n:(this._timeProfilingSlotCount+=2,{...n,timestampQuerySet:this._timeProfilingQuerySet,beginTimestampIndex:r,endTimestampIndex:r+1})}_supportsTimestampQueries(){return this.device.features.has("timestamp-query")}};f(Ir,"defaultProps",{...Z.defaultProps,measureExecutionTime:void 0,timeProfilingQuerySet:void 0});let io=Ir;const kr=class kr extends Z{get[Symbol.toStringTag](){return"CommandBuffer"}constructor(t,i){super(t,i,kr.defaultProps)}};f(kr,"defaultProps",{...Z.defaultProps});let no=kr;function ro(e){const t=so(e),i=C0[t];if(!i)throw new Error(`Unsupported variable shader type: ${e}`);return i}function y0(e){const t=Xc(e),i=P0[t];if(!i)throw new Error(`Unsupported attribute shader type: ${e}`);const[n,r]=i,s=n==="i32"||n==="u32",o=n!=="u32",a=v0[n]*r;return{primitiveType:n,components:r,byteLength:a,integer:s,signed:o}}class _0{getVariableShaderTypeInfo(t){return ro(t)}getAttributeShaderTypeInfo(t){return y0(t)}makeShaderAttributeType(t,i){return b0(t,i)}resolveAttributeShaderTypeAlias(t){return Xc(t)}resolveVariableShaderTypeAlias(t){return so(t)}}function b0(e,t){return t===1?e:`vec${t}<${e}>`}function Xc(e){return A0[e]||e}function so(e){return R0[e]||e}const T0=new _0,v0={f32:4,f16:2,i32:4,u32:4},P0={f32:["f32",1],"vec2<f32>":["f32",2],"vec3<f32>":["f32",3],"vec4<f32>":["f32",4],f16:["f16",1],"vec2<f16>":["f16",2],"vec3<f16>":["f16",3],"vec4<f16>":["f16",4],i32:["i32",1],"vec2<i32>":["i32",2],"vec3<i32>":["i32",3],"vec4<i32>":["i32",4],u32:["u32",1],"vec2<u32>":["u32",2],"vec3<u32>":["u32",3],"vec4<u32>":["u32",4]},C0={f32:{type:"f32",components:1},f16:{type:"f16",components:1},i32:{type:"i32",components:1},u32:{type:"u32",components:1},"vec2<f32>":{type:"f32",components:2},"vec3<f32>":{type:"f32",components:3},"vec4<f32>":{type:"f32",components:4},"vec2<f16>":{type:"f16",components:2},"vec3<f16>":{type:"f16",components:3},"vec4<f16>":{type:"f16",components:4},"vec2<i32>":{type:"i32",components:2},"vec3<i32>":{type:"i32",components:3},"vec4<i32>":{type:"i32",components:4},"vec2<u32>":{type:"u32",components:2},"vec3<u32>":{type:"u32",components:3},"vec4<u32>":{type:"u32",components:4},"mat2x2<f32>":{type:"f32",components:4},"mat2x3<f32>":{type:"f32",components:6},"mat2x4<f32>":{type:"f32",components:8},"mat3x2<f32>":{type:"f32",components:6},"mat3x3<f32>":{type:"f32",components:9},"mat3x4<f32>":{type:"f32",components:12},"mat4x2<f32>":{type:"f32",components:8},"mat4x3<f32>":{type:"f32",components:12},"mat4x4<f32>":{type:"f32",components:16},"mat2x2<f16>":{type:"f16",components:4},"mat2x3<f16>":{type:"f16",components:6},"mat2x4<f16>":{type:"f16",components:8},"mat3x2<f16>":{type:"f16",components:6},"mat3x3<f16>":{type:"f16",components:9},"mat3x4<f16>":{type:"f16",components:12},"mat4x2<f16>":{type:"f16",components:8},"mat4x3<f16>":{type:"f16",components:12},"mat4x4<f16>":{type:"f16",components:16},"mat2x2<i32>":{type:"i32",components:4},"mat2x3<i32>":{type:"i32",components:6},"mat2x4<i32>":{type:"i32",components:8},"mat3x2<i32>":{type:"i32",components:6},"mat3x3<i32>":{type:"i32",components:9},"mat3x4<i32>":{type:"i32",components:12},"mat4x2<i32>":{type:"i32",components:8},"mat4x3<i32>":{type:"i32",components:12},"mat4x4<i32>":{type:"i32",components:16},"mat2x2<u32>":{type:"u32",components:4},"mat2x3<u32>":{type:"u32",components:6},"mat2x4<u32>":{type:"u32",components:8},"mat3x2<u32>":{type:"u32",components:6},"mat3x3<u32>":{type:"u32",components:9},"mat3x4<u32>":{type:"u32",components:12},"mat4x2<u32>":{type:"u32",components:8},"mat4x3<u32>":{type:"u32",components:12},"mat4x4<u32>":{type:"u32",components:16}},A0={vec2i:"vec2<i32>",vec3i:"vec3<i32>",vec4i:"vec4<i32>",vec2u:"vec2<u32>",vec3u:"vec3<u32>",vec4u:"vec4<u32>",vec2f:"vec2<f32>",vec3f:"vec3<f32>",vec4f:"vec4<f32>",vec2h:"vec2<f16>",vec3h:"vec3<f16>",vec4h:"vec4<f16>"},R0={vec2i:"vec2<i32>",vec3i:"vec3<i32>",vec4i:"vec4<i32>",vec2u:"vec2<u32>",vec3u:"vec3<u32>",vec4u:"vec4<u32>",vec2f:"vec2<f32>",vec3f:"vec3<f32>",vec4f:"vec4<f32>",vec2h:"vec2<f16>",vec3h:"vec3<f16>",vec4h:"vec4<f16>",mat2x2f:"mat2x2<f32>",mat2x3f:"mat2x3<f32>",mat2x4f:"mat2x4<f32>",mat3x2f:"mat3x2<f32>",mat3x3f:"mat3x3<f32>",mat3x4f:"mat3x4<f32>",mat4x2f:"mat4x2<f32>",mat4x3f:"mat4x3<f32>",mat4x4f:"mat4x4<f32>",mat2x2i:"mat2x2<i32>",mat2x3i:"mat2x3<i32>",mat2x4i:"mat2x4<i32>",mat3x2i:"mat3x2<i32>",mat3x3i:"mat3x3<i32>",mat3x4i:"mat3x4<i32>",mat4x2i:"mat4x2<i32>",mat4x3i:"mat4x3<i32>",mat4x4i:"mat4x4<i32>",mat2x2u:"mat2x2<u32>",mat2x3u:"mat2x3<u32>",mat2x4u:"mat2x4<u32>",mat3x2u:"mat3x2<u32>",mat3x3u:"mat3x3<u32>",mat3x4u:"mat3x4<u32>",mat4x2u:"mat4x2<u32>",mat4x3u:"mat4x3<u32>",mat4x4u:"mat4x4<u32>",mat2x2h:"mat2x2<f16>",mat2x3h:"mat2x3<f16>",mat2x4h:"mat2x4<f16>",mat3x2h:"mat3x2<f16>",mat3x3h:"mat3x3<f16>",mat3x4h:"mat3x4<f16>",mat4x2h:"mat4x2<f16>",mat4x3h:"mat4x3<f16>",mat4x4h:"mat4x4<f16>"};function Yc(e,t){const i={};for(const n of e.attributes){const r=E0(e,t,n.name);r&&(i[n.name]=r)}return i}function w0(e,t,i=16){const n=Yc(e,t),r=new Array(i).fill(null);for(const s of Object.values(n))r[s.location]=s;return r}function E0(e,t,i){const n=I0(e,i),r=k0(t,i);if(!n)return null;const s=T0.getAttributeShaderTypeInfo(n.type),o=Li.getCompatibleVertexFormat(s),a=(r==null?void 0:r.vertexFormat)||o,l=Li.getVertexFormatInfo(a);return{attributeName:(r==null?void 0:r.attributeName)||n.name,bufferName:(r==null?void 0:r.bufferName)||n.name,location:n.location,shaderType:n.type,primitiveType:s.primitiveType,shaderComponents:s.components,vertexFormat:a,bufferDataType:l.type,bufferComponents:l.components,normalized:l.normalized,integer:s.integer,stepMode:(r==null?void 0:r.stepMode)||n.stepMode||"vertex",byteOffset:(r==null?void 0:r.byteOffset)||0,byteStride:(r==null?void 0:r.byteStride)||0}}function I0(e,t){const i=e.attributes.find(n=>n.name===t);return i||C.warn(`shader layout attribute "${t}" not present in shader`),i||null}function k0(e,t){D0(e);let i=F0(e,t);return i||(i=M0(e,t),i)?i:(C.warn(`layout for attribute "${t}" not present in buffer layout`),null)}function D0(e){for(const t of e)(t.attributes&&t.format||!t.attributes&&!t.format)&&C.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`)}function F0(e,t){for(const i of e)if(i.format&&i.name===t)return{attributeName:i.name,bufferName:t,stepMode:i.stepMode,vertexFormat:i.format,byteOffset:0,byteStride:i.byteStride||0};return null}function M0(e,t){var i;for(const n of e){let r=n.byteStride;if(typeof n.byteStride!="number")for(const o of n.attributes||[]){const a=Li.getVertexFormatInfo(o.format);r+=a.byteLength}const s=(i=n.attributes)==null?void 0:i.find(o=>o.attribute===t);if(s)return{attributeName:s.attribute,bufferName:n.name,stepMode:n.stepMode,vertexFormat:s.format,byteOffset:s.byteOffset,byteStride:r}}return null}const Dr=class Dr extends Z{constructor(i,n){super(i,n,Dr.defaultProps);f(this,"maxVertexAttributes");f(this,"attributeInfos");f(this,"indexBuffer",null);f(this,"attributes");this.maxVertexAttributes=i.limits.maxVertexAttributes,this.attributes=new Array(this.maxVertexAttributes).fill(null),this.attributeInfos=w0(n.shaderLayout,n.bufferLayout,this.maxVertexAttributes)}get[Symbol.toStringTag](){return"VertexArray"}setConstantWebGL(i,n){this.device.reportError(new Error("constant attributes not supported"),this)()}};f(Dr,"defaultProps",{...Z.defaultProps,shaderLayout:void 0,bufferLayout:[]});let oo=Dr;const Fr=class Fr extends Z{get[Symbol.toStringTag](){return"TransformFeedback"}constructor(t,i){super(t,i,Fr.defaultProps)}};f(Fr,"defaultProps",{...Z.defaultProps,layout:void 0,buffers:{}});let ao=Fr;const Mr=class Mr extends Z{get[Symbol.toStringTag](){return"QuerySet"}constructor(t,i){super(t,i,Mr.defaultProps)}};f(Mr,"defaultProps",{...Z.defaultProps,type:void 0,count:void 0});let lo=Mr;const Nr=class Nr extends Z{get[Symbol.toStringTag](){return"Fence"}constructor(t,i={}){super(t,i,Nr.defaultProps)}};f(Nr,"defaultProps",{...Z.defaultProps});let co=Nr;function pt(e,t){switch(t){case 1:return e;case 2:return e+e%2;default:return e+(4-e%4)%4}}function N0(e){const[,,,,t]=B0[e];return t}const B0={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]};function O0(e,t={}){const i={...e},n=t.layout??"std140",r={};let s=0;for(const[o,a]of Object.entries(i))s=uo(r,o,a,s,n);return s=pt(s,Tt(i,n)),{layout:n,byteLength:s*4,uniformTypes:i,fields:r}}function nr(e,t){const i=so(e),n=ro(i),r=/^mat(\d)x(\d)<.+>$/.exec(i);if(r){const o=Number(r[1]),a=Number(r[2]),l=qc(a,i,n.type),c=z0(l.size,l.alignment,t);return{alignment:l.alignment,size:o*c,components:o*a,columns:o,rows:a,columnStride:c,shaderType:i,type:n.type}}const s=/^vec(\d)<.+>$/.exec(i);return s?qc(Number(s[1]),i,n.type):{alignment:1,size:1,components:1,columns:1,rows:1,columnStride:1,shaderType:i,type:n.type}}function jc(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function uo(e,t,i,n,r){if(typeof i=="string"){const s=nr(i,r),o=pt(n,s.alignment);return e[t]={offset:o,...s},o+s.size}if(Array.isArray(i)){if(Array.isArray(i[0]))throw new Error(`Nested arrays are not supported for ${t}`);const s=i[0],o=i[1],a=Gc(s,r),l=pt(n,Tt(i,r));for(let c=0;c<o;c++)uo(e,`${t}[${c}]`,s,l+c*a,r);return l+a*o}if(jc(i)){const s=Tt(i,r);let o=pt(n,s);for(const[a,l]of Object.entries(i))o=uo(e,`${t}.${a}`,l,o,r);return pt(o,s)}throw new Error(`Unsupported CompositeShaderType for ${t}`)}function Kc(e,t){if(typeof e=="string")return nr(e,t).size;if(Array.isArray(e)){const n=e[0],r=e[1];if(Array.isArray(n))throw new Error("Nested arrays are not supported");return Gc(n,t)*r}let i=0;for(const n of Object.values(e)){const r=n;i=pt(i,Tt(r,t)),i+=Kc(r,t)}return pt(i,Tt(e,t))}function Tt(e,t){if(typeof e=="string")return nr(e,t).alignment;if(Array.isArray(e)){const n=e[0],r=Tt(n,t);return Zc(t)?Math.max(r,4):r}let i=1;for(const n of Object.values(e)){const r=Tt(n,t);i=Math.max(i,r)}return L0(t)?Math.max(i,4):i}function qc(e,t,i,n){return{alignment:e===2?2:4,size:e===3?3:e,components:e,columns:1,rows:e,columnStride:e===3?3:e,shaderType:t,type:i}}function Gc(e,t){const i=Kc(e,t),n=Tt(e,t);return U0(i,n,t)}function U0(e,t,i){return pt(e,Zc(i)?4:t)}function z0(e,t,i){return i==="std140"?4:pt(e,t)}function Zc(e){return e==="std140"||e==="wgsl-uniform"}function L0(e){return e==="std140"||e==="wgsl-uniform"}let rr;function Qc(e){return(!rr||rr.byteLength<e)&&(rr=new ArrayBuffer(e)),rr}function W0(e,t){const i=Qc(e.BYTES_PER_ELEMENT*t);return new e(i,0,t)}function V0(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function sr(e){return Array.isArray(e)?e.length===0||typeof e[0]=="number":V0(e)}class H0{constructor(t){f(this,"layout");this.layout=t}has(t){return!!this.layout.fields[t]}get(t){const i=this.layout.fields[t];return i?{offset:i.offset,size:i.size}:void 0}getFlatUniformValues(t){const i={};for(const[n,r]of Object.entries(t)){const s=this.layout.uniformTypes[n];s?this._flattenCompositeValue(i,n,s,r):this.layout.fields[n]&&(i[n]=r)}return i}getData(t){const i=Qc(this.layout.byteLength);new Uint8Array(i,0,this.layout.byteLength).fill(0);const n={i32:new Int32Array(i),u32:new Uint32Array(i),f32:new Float32Array(i),f16:new Uint16Array(i)},r=this.getFlatUniformValues(t);for(const[s,o]of Object.entries(r))this._writeLeafValue(n,s,o);return new Uint8Array(i,0,this.layout.byteLength)}_flattenCompositeValue(t,i,n,r){if(r!==void 0){if(typeof n=="string"||this.layout.fields[i]){t[i]=r;return}if(Array.isArray(n)){const s=n[0],o=n[1];if(Array.isArray(s))throw new Error(`Nested arrays are not supported for ${i}`);if(typeof s=="string"&&sr(r)){this._flattenPackedArray(t,i,s,o,r);return}if(!Array.isArray(r)){C.warn(`Unsupported uniform array value for ${i}:`,r)();return}for(let a=0;a<Math.min(r.length,o);a++){const l=r[a];l!==void 0&&this._flattenCompositeValue(t,`${i}[${a}]`,s,l)}return}if(jc(n)&&$0(r)){for(const[s,o]of Object.entries(r)){if(o===void 0)continue;const a=`${i}.${s}`;this._flattenCompositeValue(t,a,n[s],o)}return}C.warn(`Unsupported uniform value for ${i}:`,r)()}}_flattenPackedArray(t,i,n,r,s){const o=s,l=nr(n,this.layout.layout).components;for(let c=0;c<r;c++){const u=c*l;if(u>=o.length)break;l===1?t[`${i}[${c}]`]=Number(o[u]):t[`${i}[${c}]`]=X0(s,u,u+l)}}_writeLeafValue(t,i,n){const r=this.layout.fields[i];if(!r){C.warn(`Uniform ${i} not found in layout`)();return}const{type:s,components:o,columns:a,rows:l,offset:c,columnStride:u}=r,d=t[s];if(o===1){d[c]=Number(n);return}const h=n;if(a===1){for(let g=0;g<o;g++)d[c+g]=Number(h[g]??0);return}let p=0;for(let g=0;g<a;g++){const x=c+g*u;for(let T=0;T<l;T++)d[x+T]=Number(h[p++]??0)}}}function $0(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&!ArrayBuffer.isView(e)}function X0(e,t,i){return Array.prototype.slice.call(e,t,i)}const Y0=128;function j0(e,t,i=16){if(e===t)return!0;const n=e,r=t;if(!sr(n)||!sr(r)||n.length!==r.length)return!1;const s=Math.min(i,Y0);if(n.length>s)return!1;for(let o=0;o<n.length;++o)if(r[o]!==n[o])return!1;return!0}function K0(e){return sr(e)?e.slice():e}class q0{constructor(t){f(this,"name");f(this,"uniforms",{});f(this,"modifiedUniforms",{});f(this,"modified",!0);f(this,"bindingLayout",{});f(this,"needsRedraw","initialized");var i;if(this.name=(t==null?void 0:t.name)||"unnamed",t!=null&&t.name&&(t!=null&&t.shaderLayout)){const n=(i=t==null?void 0:t.shaderLayout.bindings)==null?void 0:i.find(s=>s.type==="uniform"&&s.name===(t==null?void 0:t.name));if(!n)throw new Error(t==null?void 0:t.name);const r=n;for(const s of r.uniforms||[])this.bindingLayout[s.name]=s}}setUniforms(t){for(const[i,n]of Object.entries(t))this._setUniform(i,n),this.needsRedraw||this.setNeedsRedraw(`${this.name}.${i}=${n}`)}setNeedsRedraw(t){this.needsRedraw=this.needsRedraw||t}getAllUniforms(){return this.modifiedUniforms={},this.needsRedraw=!1,this.uniforms||{}}_setUniform(t,i){j0(this.uniforms[t],i)||(this.uniforms[t]=K0(i),this.modifiedUniforms[t]=!0,this.modified=!0)}}const G0=1024;class oe{constructor(t,i){f(this,"device");f(this,"uniformBlocks",new Map);f(this,"shaderBlockLayouts",new Map);f(this,"shaderBlockWriters",new Map);f(this,"uniformBuffers",new Map);this.device=t;for(const[n,r]of Object.entries(i)){const s=n,o=O0(r.uniformTypes??{},{layout:r.layout??Z0(t)}),a=new H0(o);this.shaderBlockLayouts.set(s,o),this.shaderBlockWriters.set(s,a);const l=new q0({name:n});l.setUniforms(a.getFlatUniformValues(r.defaultUniforms||{})),this.uniformBlocks.set(s,l)}}destroy(){for(const t of this.uniformBuffers.values())t.destroy()}setUniforms(t){var i;for(const[n,r]of Object.entries(t)){const s=n,o=this.shaderBlockWriters.get(s),a=o==null?void 0:o.getFlatUniformValues(r||{});(i=this.uniformBlocks.get(s))==null||i.setUniforms(a||{})}this.updateUniformBuffers()}getUniformBufferByteLength(t){var n;const i=((n=this.shaderBlockLayouts.get(t))==null?void 0:n.byteLength)||0;return Math.max(i,G0)}getUniformBufferData(t){var r;const i=((r=this.uniformBlocks.get(t))==null?void 0:r.getAllUniforms())||{},n=this.shaderBlockWriters.get(t);return(n==null?void 0:n.getData(i))||new Uint8Array(0)}createUniformBuffer(t,i){i&&this.setUniforms(i);const n=this.getUniformBufferByteLength(t),r=this.device.createBuffer({usage:B.UNIFORM|B.COPY_DST,byteLength:n}),s=this.getUniformBufferData(t);return r.write(s),r}getManagedUniformBuffer(t){if(!this.uniformBuffers.get(t)){const i=this.getUniformBufferByteLength(t),n=this.device.createBuffer({usage:B.UNIFORM|B.COPY_DST,byteLength:i});this.uniformBuffers.set(t,n)}return this.uniformBuffers.get(t)}updateUniformBuffers(){let t=!1;for(const i of this.uniformBlocks.keys()){const n=this.updateUniformBuffer(i);t||(t=n)}return t&&C.log(3,`UniformStore.updateUniformBuffers(): ${t}`)(),t}updateUniformBuffer(t){var s;const i=this.uniformBlocks.get(t);let n=this.uniformBuffers.get(t),r=!1;if(n&&(i!=null&&i.needsRedraw)){r||(r=i.needsRedraw);const o=this.getUniformBufferData(t);n=this.uniformBuffers.get(t),n==null||n.write(o);const a=(s=this.uniformBlocks.get(t))==null?void 0:s.getAllUniforms();C.log(4,`Writing to uniform buffer ${String(t)}`,o,a)()}return r}}function Z0(e){return e.type==="webgpu"?"wgsl-uniform":"std140"}function Wi(e,t){var i;if(!e){const n=new Error(t||"shadertools: assertion failed.");throw(i=Error.captureStackTrace)==null||i.call(Error,n,Wi),n}}const ho={number:{type:"number",validate(e,t){return Number.isFinite(e)&&typeof t=="object"&&(t.max===void 0||e<=t.max)&&(t.min===void 0||e>=t.min)}},array:{type:"array",validate(e,t){return Array.isArray(e)||ArrayBuffer.isView(e)}}};function Q0(e){const t={};for(const[i,n]of Object.entries(e))t[i]=J0(n);return t}function J0(e){let t=Jc(e);if(t!=="object")return{value:e,...ho[t],type:t};if(typeof e=="object")return e?e.type!==void 0?{...e,...ho[e.type],type:e.type}:e.value===void 0?{type:"object",value:e}:(t=Jc(e.value),{...e,...ho[t],type:t}):{type:"object",value:null};throw new Error("props")}function Jc(e){return Array.isArray(e)||ArrayBuffer.isView(e)?"array":typeof e}const ey={vertex:`#ifdef MODULE_LOGDEPTH + logdepth_adjustPosition(gl_Position); +#endif +`,fragment:`#ifdef MODULE_MATERIAL + fragColor = material_filterColor(fragColor); +#endif + +#ifdef MODULE_LIGHTING + fragColor = lighting_filterColor(fragColor); +#endif + +#ifdef MODULE_FOG + fragColor = fog_filterColor(fragColor); +#endif + +#ifdef MODULE_PICKING + fragColor = picking_filterHighlightColor(fragColor); + fragColor = picking_filterPickingColor(fragColor); +#endif + +#ifdef MODULE_LOGDEPTH + logdepth_setFragDepth(); +#endif +`},eu=/void\s+main\s*\([^)]*\)\s*\{\n?/,tu=/}\n?[^{}]*$/,fo=[],or="__LUMA_INJECT_DECLARATIONS__";function ty(e){const t={vertex:{},fragment:{}};for(const i in e){let n=e[i];const r=iy(i);typeof n=="string"&&(n={order:0,injection:n}),t[r][i]=n}return t}function iy(e){const t=e.slice(0,2);switch(t){case"vs":return"vertex";case"fs":return"fragment";default:throw new Error(t)}}function ar(e,t,i,n=!1){const r=t==="vertex";for(const s in i){const o=i[s];o.sort((l,c)=>l.order-c.order),fo.length=o.length;for(let l=0,c=o.length;l<c;++l)fo[l]=o[l].injection;const a=`${fo.join(` +`)} +`;switch(s){case"vs:#decl":r&&(e=e.replace(or,a));break;case"vs:#main-start":r&&(e=e.replace(eu,l=>l+a));break;case"vs:#main-end":r&&(e=e.replace(tu,l=>a+l));break;case"fs:#decl":r||(e=e.replace(or,a));break;case"fs:#main-start":r||(e=e.replace(eu,l=>l+a));break;case"fs:#main-end":r||(e=e.replace(tu,l=>a+l));break;default:e=e.replace(s,l=>l+a)}}return e=e.replace(or,""),n&&(e=e.replace(/\}\s*$/,s=>s+ey[t])),e}function lr(e){e.map(t=>ny(t))}function ny(e){if(e.instance)return;lr(e.dependencies||[]);const{propTypes:t={},deprecations:i=[],inject:n={}}=e,r={normalizedInjections:ty(n),parsedDeprecations:ry(i)};t&&(r.propValidators=Q0(t)),e.instance=r;let s={};t&&(s=Object.entries(t).reduce((o,[a,l])=>{const c=l==null?void 0:l.value;return c&&(o[a]=c),o},{})),e.defaultUniforms={...e.defaultUniforms,...s}}function iu(e,t,i){var n;(n=e.deprecations)==null||n.forEach(r=>{var s;(s=r.regex)!=null&&s.test(t)&&(r.deprecated?i.deprecated(r.old,r.new)():i.removed(r.old,r.new)())})}function ry(e){return e.forEach(t=>{switch(t.type){case"function":t.regex=new RegExp(`\\b${t.old}\\(`);break;default:t.regex=new RegExp(`${t.type} ${t.old};`)}}),e}function po(e){lr(e);const t={},i={};nu({modules:e,level:0,moduleMap:t,moduleDepth:i});const n=Object.keys(i).sort((r,s)=>i[s]-i[r]).map(r=>t[r]);return lr(n),n}function nu(e){const{modules:t,level:i,moduleMap:n,moduleDepth:r}=e;if(i>=5)throw new Error("Possible loop in shader dependency graph");for(const s of t)n[s.name]=s,(r[s.name]===void 0||r[s.name]<i)&&(r[s.name]=i);for(const s of t)s.dependencies&&nu({modules:s.dependencies,level:i+1,moduleMap:n,moduleDepth:r})}const sy=/^(?:uniform\s+)?(?:(?:lowp|mediump|highp)\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/,oy=/((?:layout\s*\([^)]*\)\s*)*)uniform\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{([\s\S]*?)\}\s*([A-Za-z_][A-Za-z0-9_]*)?\s*;/g;function ru(e){return`${e.name}Uniforms`}function ay(e,t){const i=t==="wgsl"?e.source:t==="vertex"?e.vs:e.fs;if(!i)return null;const n=ru(e);return dy(i,t==="wgsl"?"wgsl":"glsl",n)}function ly(e,t){const i=Object.keys(e.uniformTypes||{});if(!i.length)return null;const n=ay(e,t);return n?{moduleName:e.name,uniformBlockName:ru(e),stage:t,expectedUniformNames:i,actualUniformNames:n,matches:py(i,n)}:null}function cy(e,t,i={}){var s,o;const n=ly(e,t);if(!n||n.matches)return n;const r=gy(n);return(o=(s=i.log)==null?void 0:s.error)==null||o.call(s,r,n)(),i.throwOnError!==!1&&Wi(!1,r),n}function su(e){var n;const t=[],i=my(e);for(const r of i.matchAll(oy)){const s=((n=r[1])==null?void 0:n.trim())||null;t.push({blockName:r[2],body:r[3],instanceName:r[4]||null,layoutQualifier:s,hasLayoutQualifier:!!s,isStd140:!!(s&&/\blayout\s*\([^)]*\bstd140\b[^)]*\)/.exec(s))})}return t}function uy(e,t,i,n){var o;const r=su(e).filter(a=>!a.isStd140),s=new Set;for(const a of r){if(s.has(a.blockName))continue;s.add(a.blockName);const l="",c=a.hasLayoutQualifier?`declares ${xy(a.layoutQualifier)} instead of layout(std140)`:"does not declare layout(std140)",u=`${l}${t} shader uniform block ${a.blockName} ${c}. luma.gl host-side shader block packing assumes explicit layout(std140) for GLSL uniform blocks. Add \`layout(std140)\` to the block declaration.`;(o=i==null?void 0:i.warn)==null||o.call(i,u,a)()}return r}function dy(e,t,i){const n=t==="wgsl"?hy(e,i):fy(e,i);if(!n)return null;const r=[];for(const s of n.split(` +`)){const o=s.replace(/\/\/.*$/,"").trim();if(!o||o.startsWith("#"))continue;const a=t==="wgsl"?o.match(/^([A-Za-z0-9_]+)\s*:/):o.match(sy);a&&r.push(a[1])}return r}function hy(e,t){const i=new RegExp(`\\bstruct\\s+${t}\\b`,"m").exec(e);if(!i)return null;const n=e.indexOf("{",i.index);if(n<0)return null;let r=0;for(let s=n;s<e.length;s++){const o=e[s];if(o==="{"){r++;continue}if(o==="}"&&(r--,r===0))return e.slice(n+1,s)}return null}function fy(e,t){const i=su(e).find(n=>n.blockName===t);return(i==null?void 0:i.body)||null}function py(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(e[i]!==t[i])return!1;return!0}function gy(e){const{expectedUniformNames:t,actualUniformNames:i}=e,n=t.filter(a=>!i.includes(a)),r=i.filter(a=>!t.includes(a)),s=[`Expected ${t.length} fields, found ${i.length}.`],o=Sy(t,i);return o&&s.push(o),n.length&&s.push(`Missing from shader block (${n.length}): ${ou(n)}.`),r.length&&s.push(`Unexpected in shader block (${r.length}): ${ou(r)}.`),t.length<=12&&i.length<=12&&(n.length||r.length)&&(s.push(`Expected: ${t.join(", ")}.`),s.push(`Actual: ${i.join(", ")}.`)),`${e.moduleName}: ${e.stage} shader uniform block ${e.uniformBlockName} does not match module.uniformTypes. ${s.join(" ")}`}function my(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function xy(e){return e.replace(/\s+/g," ").trim()}function Sy(e,t){const i=Math.min(e.length,t.length);for(let n=0;n<i;n++)if(e[n]!==t[n])return`First mismatch at field ${n+1}: expected ${e[n]}, found ${t[n]}.`;return e.length>t.length?`Shader block ends after field ${t.length}; expected next field ${e[t.length]}.`:t.length>e.length?`Shader block has extra field ${t.length}: ${t[e.length]}.`:null}function ou(e,t=8){if(e.length<=t)return e.join(", ");const i=e.length-t;return`${e.slice(0,t).join(", ")}, ... (${i} more)`}function yy(e){switch(e==null?void 0:e.gpu.toLowerCase()){case"apple":return`#define APPLE_GPU +// Apple optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`;case"nvidia":return`#define NVIDIA_GPU +// Nvidia optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +`;case"intel":return`#define INTEL_GPU +// Intel optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +// Intel's built-in 'tan' function doesn't have acceptable precision +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`;case"amd":return`#define AMD_GPU +`;default:return`#define DEFAULT_GPU +// Prevent driver from optimizing away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +// Headless Chrome's software shader 'tan' function doesn't have acceptable precision +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// If the GPU doesn't have full 32 bits precision, will causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`}}function _y(e,t){var n;if(Number(((n=e.match(/^#version[ \t]+(\d+)/m))==null?void 0:n[1])||100)!==300)throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");switch(t){case"vertex":return e=lu(e,by),e;case"fragment":return e=lu(e,Ty),e;default:throw new Error(t)}}const au=[[/^(#version[ \t]+(100|300[ \t]+es))?[ \t]*\n/,`#version 300 es +`],[/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g,"textureLod("],[/\btexture(2D|2DProj|Cube)(EXT)?\(/g,"texture("]],by=[...au,[go("attribute"),"in $1"],[go("varying"),"out $1"]],Ty=[...au,[go("varying"),"in $1"]];function lu(e,t){for(const[i,n]of t)e=e.replace(i,n);return e}function go(e){return new RegExp(`\\b${e}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`,"g")}function cu(e,t){let i="";for(const n in e){const r=e[n];if(i+=`void ${r.signature} { +`,r.header&&(i+=` ${r.header}`),t[n]){const s=t[n];s.sort((o,a)=>o.order-a.order);for(const o of s)i+=` ${o.injection} +`}r.footer&&(i+=` ${r.footer}`),i+=`} +`}return i}function uu(e){const t={vertex:{},fragment:{}};for(const i of e){let n,r;typeof i!="string"?(n=i,r=n.hook):(n={},r=i),r=r.trim();const[s,o]=r.split(":"),a=r.replace(/\(.+/,""),l=Object.assign(n,{signature:o});switch(s){case"vs":t.vertex[a]=l;break;case"fs":t.fragment[a]=l;break;default:throw new Error(s)}}return t}function vy(e,t){return{name:Py(e,t),language:"glsl",version:Cy(e)}}function Py(e,t="unnamed"){const n=/#define[^\S\r\n]*SHADER_NAME[^\S\r\n]*([A-Za-z0-9_-]+)\s*/.exec(e);return n?n[1]:t}function Cy(e){let t=100;const i=e.match(/[^\s]+/g);if(i&&i.length>=2&&i[0]==="#version"){const n=parseInt(i[1],10);Number.isFinite(n)&&(t=n)}if(t!==100&&t!==300)throw new Error(`Invalid GLSL version ${t}`);return t}const He="(?:var<\\s*(uniform|storage(?:\\s*,\\s*[A-Za-z_][A-Za-z0-9_]*)?)\\s*>|var)\\s+([A-Za-z_][A-Za-z0-9_]*)",$e="\\s*",Vi=[new RegExp(`@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}@group\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${$e}@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}${He}`,"g")],mo=[new RegExp(`@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}@group\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${$e}@binding\\(\\s*(auto|\\d+)\\s*\\)${$e}${He}`,"g")],Ay=[new RegExp(`@binding\\(\\s*(\\d+)\\s*\\)${$e}@group\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${$e}@binding\\(\\s*(\\d+)\\s*\\)${$e}${He}`,"g")],Ry=[new RegExp(`@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)\\s*${He}`,"g"),new RegExp(`@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${He}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${He}`,"g")];function xo(e){const t=e.split("");let i=0,n=0,r=!1,s=!1,o=!1;for(;i<e.length;){const a=e[i],l=e[i+1];if(s){o?o=!1:a==="\\"?o=!0:a==='"'&&(s=!1),i++;continue}if(r){a===` +`||a==="\r"?r=!1:t[i]=" ",i++;continue}if(n>0){if(a==="/"&&l==="*"){t[i]=" ",t[i+1]=" ",n++,i+=2;continue}if(a==="*"&&l==="/"){t[i]=" ",t[i+1]=" ",n--,i+=2;continue}a!==` +`&&a!=="\r"&&(t[i]=" "),i++;continue}if(a==='"'){s=!0,i++;continue}if(a==="/"&&l==="/"){t[i]=" ",t[i+1]=" ",r=!0,i+=2;continue}if(a==="/"&&l==="*"){t[i]=" ",t[i+1]=" ",n=1,i+=2;continue}i++}return t.join("")}function ri(e,t){var r;const i=xo(e),n=[];for(const s of t){s.lastIndex=0;let o;for(o=s.exec(i);o;){const a=s===t[0],l=o.index,c=o[0].length;n.push({match:e.slice(l,l+c),index:l,length:c,bindingToken:o[a?1:2],groupToken:o[a?2:1],accessDeclaration:(r=o[3])==null?void 0:r.trim(),name:o[4]}),o=s.exec(i)}}return n.sort((s,o)=>s.index-o.index)}function du(e,t,i){const n=ri(e,t);if(!n.length)return e;let r="",s=0;for(const o of n)r+=e.slice(s,o.index),r+=i(o),s=o.index+o.length;return r+=e.slice(s),r}function hu(e){return/@binding\(\s*auto\s*\)/.test(xo(e))}function wy(e,t){return ri(e,t===Vi||t===mo?Ry:t).find(n=>n.bindingToken==="auto")}const fu=[new RegExp(`@binding\\(\\s*(\\d+)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${He}\\s*:\\s*([^;]+);`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(\\d+)\\s*\\)\\s*${He}\\s*:\\s*([^;]+);`,"g")];function pu(e,t=[]){var s;const i=xo(e),n=new Map;for(const o of t)n.set(gu(o.name,o.group,o.location),o.moduleName);const r=[];for(const o of fu){o.lastIndex=0;let a;for(a=o.exec(i);a;){const l=o===fu[0],c=Number(a[l?1:2]),u=Number(a[l?2:1]),d=(s=a[3])==null?void 0:s.trim(),h=a[4],p=a[5].trim(),g=n.get(gu(h,u,c));r.push(Ey({name:h,group:u,binding:c,owner:g?"module":"application",moduleName:g,accessDeclaration:d,resourceType:p})),a=o.exec(i)}}return r.sort((o,a)=>o.group!==a.group?o.group-a.group:o.binding!==a.binding?o.binding-a.binding:o.name.localeCompare(a.name))}function Ey(e){const t={name:e.name,group:e.group,binding:e.binding,owner:e.owner,kind:"unknown",moduleName:e.moduleName,resourceType:e.resourceType};if(e.accessDeclaration){const i=e.accessDeclaration.split(",").map(n=>n.trim());if(i[0]==="uniform")return{...t,kind:"uniform",access:"uniform"};if(i[0]==="storage"){const n=i[1]||"read_write";return{...t,kind:n==="read"?"read-only-storage":"storage",access:n}}}return e.resourceType==="sampler"||e.resourceType==="sampler_comparison"?{...t,kind:"sampler",samplerKind:e.resourceType==="sampler_comparison"?"comparison":"filtering"}:e.resourceType.startsWith("texture_storage_")?{...t,kind:"storage-texture",access:ky(e.resourceType),viewDimension:mu(e.resourceType)}:e.resourceType.startsWith("texture_")?{...t,kind:"texture",viewDimension:mu(e.resourceType),sampleType:Iy(e.resourceType),multisampled:e.resourceType.startsWith("texture_multisampled_")}:t}function gu(e,t,i){return`${t}:${i}:${e}`}function mu(e){if(e.includes("cube_array"))return"cube-array";if(e.includes("2d_array"))return"2d-array";if(e.includes("cube"))return"cube";if(e.includes("3d"))return"3d";if(e.includes("2d"))return"2d";if(e.includes("1d"))return"1d"}function Iy(e){if(e.startsWith("texture_depth_"))return"depth";if(e.includes("<i32>"))return"sint";if(e.includes("<u32>"))return"uint";if(e.includes("<f32>"))return"float"}function ky(e){const t=/,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(e);return t==null?void 0:t[1]}const So=` + +${or} +`,Hi=100,Dy=`precision highp float; +`;function Fy(e){const t=po(e.modules||[]),{source:i,bindingAssignments:n}=Ny(e.platformInfo,{...e,source:e.source,stage:"vertex",modules:t});return{source:i,getUniforms:Su(t),bindingAssignments:n,bindingTable:pu(i,n)}}function My(e){const{vs:t,fs:i}=e,n=po(e.modules||[]);return{vs:xu(e.platformInfo,{...e,source:t,stage:"vertex",modules:n}),fs:xu(e.platformInfo,{...e,source:i,stage:"fragment",modules:n}),getUniforms:Su(n)}}function Ny(e,t){var I;const{source:i,stage:n,modules:r,hookFunctions:s=[],inject:o={},log:a}=t;Wi(typeof i=="string","shader source must be a string");const l=i;let c="";const u=uu(s),d={},h={},p={};for(const y in o){const v=typeof o[y]=="string"?{injection:o[y],order:0}:o[y],E=/^(v|f)s:(#)?([\w-]+)$/.exec(y);if(E){const R=E[2],D=E[3];R?D==="decl"?h[y]=[v]:p[y]=[v]:d[y]=[v]}else p[y]=[v]}const g=r,x=Uy(l),T=Oy(x.source),S=Vy(g,t._bindingRegistry,T),P=[];for(const y of g){a&&iu(y,l,a);const v=zy(yu(y,"wgsl",a),y,{usedBindingsByGroup:T,bindingRegistry:t._bindingRegistry,reservedBindingKeysByGroup:S});P.push(...v.bindingAssignments);const E=v.source;c+=E;const R=((I=y.injections)==null?void 0:I[n])||{};for(const D in R){const z=/^(v|f)s:#([\w-]+)$/.exec(D);if(z){const F=z[2]==="decl"?h:p;F[D]=F[D]||[],F[D].push(R[D])}else d[D]=d[D]||[],d[D].push(R[D])}}return c+=So,c=ar(c,n,h),c+=cu(u[n],d),c+=jy(P),c+=x.source,c=ar(c,n,p),Yy(c),{source:c,bindingAssignments:P}}function xu(e,t){var E;const{source:i,stage:n,language:r="glsl",modules:s,defines:o={},hookFunctions:a=[],inject:l={},prologue:c=!0,log:u}=t;Wi(typeof i=="string","shader source must be a string");const d=r==="glsl"?vy(i).version:-1,h=e.shaderLanguageVersion,p=d===100?"#version 100":"#version 300 es",x=i.split(` +`).slice(1).join(` +`),T={};s.forEach(R=>{Object.assign(T,R.defines)}),Object.assign(T,o);let S="";switch(r){case"wgsl":break;case"glsl":S=c?`${p} + +// ----- PROLOGUE ------------------------- +${`#define SHADER_TYPE_${n.toUpperCase()}`} + +${yy(e)} +${n==="fragment"?Dy:""} + +// ----- APPLICATION DEFINES ------------------------- + +${By(T)} + +`:`${p} +`;break}const P=uu(a),I={},y={},v={};for(const R in l){const D=typeof l[R]=="string"?{injection:l[R],order:0}:l[R],z=/^(v|f)s:(#)?([\w-]+)$/.exec(R);if(z){const $=z[2],F=z[3];$?F==="decl"?y[R]=[D]:v[R]=[D]:I[R]=[D]}else v[R]=[D]}for(const R of s){u&&iu(R,x,u);const D=yu(R,n,u);S+=D;const z=((E=R.instance)==null?void 0:E.normalizedInjections[n])||{};for(const $ in z){const F=/^(v|f)s:#([\w-]+)$/.exec($);if(F){const X=F[2]==="decl"?y:v;X[$]=X[$]||[],X[$].push(z[$])}else I[$]=I[$]||[],I[$].push(z[$])}}return S+="// ----- MAIN SHADER SOURCE -------------------------",S+=So,S=ar(S,n,y),S+=cu(P[n],I),S+=x,S=ar(S,n,v),r==="glsl"&&d!==h&&(S=_y(S,n)),r==="glsl"&&uy(S,n,u),S.trim()}function Su(e){return function(i){var r;const n={};for(const s of e){const o=(r=s.getUniforms)==null?void 0:r.call(s,i,n);Object.assign(n,o)}return n}}function By(e={}){let t="";for(const i in e){const n=e[i];(n||Number.isFinite(n))&&(t+=`#define ${i.toUpperCase()} ${e[i]} +`)}return t}function yu(e,t,i){let n;switch(t){case"vertex":n=e.vs||"";break;case"fragment":n=e.fs||"";break;case"wgsl":n=e.source||"";break;default:Wi(!1)}if(!e.name)throw new Error("Shader module must have a name");cy(e,t,{log:i});const r=e.name.toUpperCase().replace(/[^0-9a-z]/gi,"_");let s=`// ----- MODULE ${e.name} --------------- + +`;return t!=="wgsl"&&(s+=`#define MODULE_${r} +`),s+=`${n} +`,s}function Oy(e){const t=new Map;for(const i of ri(e,Ay)){const n=Number(i.bindingToken),r=Number(i.groupToken);yo(r,n,i.name),si(t,r,n,`application binding "${i.name}"`)}return t}function Uy(e){const t=ri(e,mo),i=new Map;for(const s of t){if(s.bindingToken==="auto")continue;const o=Number(s.bindingToken),a=Number(s.groupToken);yo(a,o,s.name),si(i,a,o,`application binding "${s.name}"`)}const n={sawSupportedBindingDeclaration:t.length>0},r=du(e,mo,s=>Wy(s,i,n));if(hu(e)&&!n.sawSupportedBindingDeclaration)throw new Error('Unsupported @binding(auto) declaration form in application WGSL. Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.');return{source:r}}function zy(e,t,i){const n=[],s={sawSupportedBindingDeclaration:ri(e,Vi).length>0,nextHintedBindingLocation:typeof t.firstBindingSlot=="number"?t.firstBindingSlot:null},o=du(e,Vi,a=>Ly(a,{module:t,context:i,bindingAssignments:n,relocationState:s}));if(hu(e)&&!s.sawSupportedBindingDeclaration)throw new Error(`Unsupported @binding(auto) declaration form in module "${t.name}". Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.`);return{source:o,bindingAssignments:n}}function Ly(e,t){var h,p;const{module:i,context:n,bindingAssignments:r,relocationState:s}=t,{match:o,bindingToken:a,groupToken:l,name:c}=e,u=Number(l);if(a==="auto"){const g=Tu(u,i.name,c),x=(h=n.bindingRegistry)==null?void 0:h.get(g),T=x!==void 0?x:s.nextHintedBindingLocation===null?bu(u,n.usedBindingsByGroup):bu(u,n.usedBindingsByGroup,s.nextHintedBindingLocation);return _u(i.name,u,T,c),x!==void 0&&Hy(n.reservedBindingKeysByGroup,u,T,g)?(r.push({moduleName:i.name,name:c,group:u,location:T}),o.replace(/@binding\(\s*auto\s*\)/,`@binding(${T})`)):(si(n.usedBindingsByGroup,u,T,`module "${i.name}" binding "${c}"`),(p=n.bindingRegistry)==null||p.set(g,T),r.push({moduleName:i.name,name:c,group:u,location:T}),s.nextHintedBindingLocation!==null&&x===void 0&&(s.nextHintedBindingLocation=T+1),o.replace(/@binding\(\s*auto\s*\)/,`@binding(${T})`))}const d=Number(a);return _u(i.name,u,d,c),si(n.usedBindingsByGroup,u,d,`module "${i.name}" binding "${c}"`),r.push({moduleName:i.name,name:c,group:u,location:d}),o}function Wy(e,t,i){const{match:n,bindingToken:r,groupToken:s,name:o}=e,a=Number(s);if(r==="auto"){const l=Xy(a,t);return yo(a,l,o),si(t,a,l,`application binding "${o}"`),n.replace(/@binding\(\s*auto\s*\)/,`@binding(${l})`)}return i.sawSupportedBindingDeclaration=!0,n}function Vy(e,t,i){const n=new Map;if(!t)return n;for(const r of e)for(const s of $y(r)){const o=Tu(s.group,r.name,s.name),a=t.get(o);if(a!==void 0){const l=n.get(s.group)||new Map,c=l.get(a);if(c&&c!==o)throw new Error(`Duplicate WGSL binding reservation for modules "${c}" and "${o}": group ${s.group}, binding ${a}.`);si(i,s.group,a,`registered module binding "${o}"`),l.set(a,o),n.set(s.group,l)}}return n}function Hy(e,t,i,n){const r=e.get(t);if(!r)return!1;const s=r.get(i);if(!s)return!1;if(s!==n)throw new Error(`Registered module binding "${n}" collided with "${s}": group ${t}, binding ${i}.`);return!0}function $y(e){const t=[],i=e.source||"";for(const n of ri(i,Vi))t.push({name:n.name,group:Number(n.groupToken)});return t}function yo(e,t,i){if(e===0&&t>=Hi)throw new Error(`Application binding "${i}" in group 0 uses reserved binding ${t}. Application-owned explicit group-0 bindings must stay below ${Hi}.`)}function _u(e,t,i,n){if(t===0&&i<Hi)throw new Error(`Module "${e}" binding "${n}" in group 0 uses reserved application binding ${i}. Module-owned explicit group-0 bindings must be ${Hi} or higher.`)}function si(e,t,i,n){const r=e.get(t)||new Set;if(r.has(i))throw new Error(`Duplicate WGSL binding assignment for ${n}: group ${t}, binding ${i}.`);r.add(i),e.set(t,r)}function bu(e,t,i){const n=t.get(e)||new Set;let r=i??(e===0?Hi:n.size>0?Math.max(...n)+1:0);for(;n.has(r);)r++;return r}function Xy(e,t){const i=t.get(e)||new Set;let n=0;for(;i.has(n);)n++;return n}function Yy(e){const t=wy(e,Vi);if(!t)return;const i=Ky(e,t.index);throw i?new Error(`Unresolved @binding(auto) for module "${i}" binding "${t.name}" remained in assembled WGSL source.`):qy(e,t.index)?new Error(`Unresolved @binding(auto) for application binding "${t.name}" remained in assembled WGSL source.`):new Error(`Unresolved @binding(auto) remained in assembled WGSL source near "${Gy(t.match)}".`)}function jy(e){if(e.length===0)return"";let t=`// ----- MODULE WGSL BINDING ASSIGNMENTS --------------- +`;for(const i of e)t+=`// ${i.moduleName}.${i.name} -> @group(${i.group}) @binding(${i.location}) +`;return t+=` +`,t}function Tu(e,t,i){return`${e}:${t}:${i}`}function Ky(e,t){const i=/^\/\/ ----- MODULE ([^\n]+) ---------------$/gm;let n,r;for(r=i.exec(e);r&&r.index<=t;)n=r[1],r=i.exec(e);return n}function qy(e,t){const i=e.indexOf(So);return i>=0?t>i:!0}function Gy(e){return e.replace(/\s+/g," ").trim()}const _o="([a-zA-Z_][a-zA-Z0-9_]*)",Zy=new RegExp(`^\\s*\\#\\s*ifdef\\s*${_o}\\s*$`),Qy=new RegExp(`^\\s*\\#\\s*ifndef\\s*${_o}\\s*(?:\\/\\/.*)?$`),Jy=/^\s*\#\s*else\s*(?:\/\/.*)?$/,e_=/^\s*\#\s*endif\s*$/,t_=new RegExp(`^\\s*\\#\\s*ifdef\\s*${_o}\\s*(?:\\/\\/.*)?$`),i_=/^\s*\#\s*endif\s*(?:\/\/.*)?$/;function n_(e,t){var o,a;const i=e.split(` +`),n=[],r=[];let s=!0;for(const l of i){const c=l.match(t_)||l.match(Zy),u=l.match(Qy),d=l.match(Jy),h=l.match(i_)||l.match(e_);if(c||u){const p=(o=c||u)==null?void 0:o[1],g=!!((a=t==null?void 0:t.defines)!=null&&a[p]),x=c?g:!g,T=s&&x;r.push({parentActive:s,branchTaken:x,active:T}),s=T}else if(d){const p=r[r.length-1];if(!p)throw new Error("Encountered #else without matching #ifdef or #ifndef");p.active=p.parentActive&&!p.branchTaken,p.branchTaken=!0,s=p.active}else h?(r.pop(),s=r.length?r[r.length-1].active:!0):s&&n.push(l)}if(r.length>0)throw new Error("Unterminated conditional block in shader source");return n.join(` +`)}const Lt=class Lt{constructor(){f(this,"_hookFunctions",[]);f(this,"_defaultModules",[]);f(this,"_wgslBindingRegistry",new Map)}static getDefaultShaderAssembler(){return Lt.defaultShaderAssembler=Lt.defaultShaderAssembler||new Lt,Lt.defaultShaderAssembler}addDefaultModule(t){this._defaultModules.find(i=>i.name===(typeof t=="string"?t:t.name))||this._defaultModules.push(t)}removeDefaultModule(t){const i=typeof t=="string"?t:t.name;this._defaultModules=this._defaultModules.filter(n=>n.name!==i)}addShaderHook(t,i){i&&(t=Object.assign(i,{hook:t})),this._hookFunctions.push(t)}assembleWGSLShader(t){const i=this._getModuleList(t.modules),n=this._hookFunctions,{source:r,getUniforms:s,bindingAssignments:o}=Fy({...t,source:t.source,_bindingRegistry:this._wgslBindingRegistry,modules:i,hookFunctions:n}),a={...i.reduce((c,u)=>(Object.assign(c,u.defines),c),{}),...t.defines},l=t.platformInfo.shaderLanguage==="wgsl"?n_(r,{defines:a}):r;return{source:l,getUniforms:s,modules:i,bindingAssignments:o,bindingTable:pu(l,o)}}assembleGLSLShaderPair(t){const i=this._getModuleList(t.modules),n=this._hookFunctions;return{...My({...t,vs:t.vs,fs:t.fs,modules:i,hookFunctions:n}),modules:i}}_getModuleList(t=[]){const i=new Array(this._defaultModules.length+t.length),n={};let r=0;for(let s=0,o=this._defaultModules.length;s<o;++s){const a=this._defaultModules[s],l=a.name;i[r++]=a,n[l]=!0}for(let s=0,o=t.length;s<o;++s){const a=t[s],l=a.name;n[l]||(i[r++]=a,n[l]=!0)}return i.length=r,lr(i),i}};f(Lt,"defaultShaderAssembler");let bo=Lt;const To={};function vo(e="id"){To[e]=To[e]||1;const t=To[e]++;return`${e}-${t}`}class vu{constructor(t){f(this,"id");f(this,"userData",{});f(this,"topology");f(this,"bufferLayout",[]);f(this,"vertexCount");f(this,"indices");f(this,"attributes");if(this.id=t.id||vo("geometry"),this.topology=t.topology,this.indices=t.indices||null,this.attributes=t.attributes,this.vertexCount=t.vertexCount,this.bufferLayout=t.bufferLayout||[],this.indices&&!(this.indices.usage&B.INDEX))throw new Error("Index buffer must have INDEX usage")}destroy(){var t;(t=this.indices)==null||t.destroy();for(const i of Object.values(this.attributes))i.destroy()}getVertexCount(){return this.vertexCount}getAttributes(){return this.attributes}getIndexes(){return this.indices||null}_calculateVertexCount(t){return t.byteLength/12}}function r_(e,t){if(t instanceof vu)return t;const i=s_(e,t),{attributes:n,bufferLayout:r}=o_(e,t);return new vu({topology:t.topology||"triangle-list",bufferLayout:r,vertexCount:t.vertexCount,indices:i,attributes:n})}function s_(e,t){if(!t.indices)return;const i=t.indices.value;return e.createBuffer({usage:B.INDEX,data:i})}function o_(e,t){const i=[],n={};for(const[s,o]of Object.entries(t.attributes)){let a=s;switch(s){case"POSITION":a="positions";break;case"NORMAL":a="normals";break;case"TEXCOORD_0":a="texCoords";break;case"TEXCOORD_1":a="texCoords1";break;case"COLOR_0":a="colors";break}if(o){n[a]=e.createBuffer({data:o.value,id:`${s}-buffer`});const{value:l,size:c,normalized:u}=o;if(c===void 0)throw new Error(`Attribute ${s} is missing a size`);i.push({name:a,format:Li.getVertexFormatFromAttribute(l,c,u)})}}const r=t._calculateVertexCount(t.attributes,t.indices);return{attributes:n,bufferLayout:i,vertexCount:r}}function a_(e,t){var r;const i={},n="Values";if(e.attributes.length===0&&!((r=e.varyings)!=null&&r.length))return{"No attributes or varyings":{[n]:"N/A"}};for(const s of e.attributes)if(s){const o=`${s.location} ${s.name}: ${s.type}`;i[`in ${o}`]={[n]:s.stepMode||"vertex"}}for(const s of e.varyings||[]){const o=`${s.location} ${s.name}`;i[`out ${o}`]={[n]:JSON.stringify(s)}}return i}const cr="__debugFramebufferState",Po=8;function l_(e,t,i){if(e.device.type!=="webgl")return;const n=d_(e.device);if(!n.flushing){if(f_(e)){c_(e,i,n);return}t&&h_(t)&&t.handle!==null&&(n.queuedFramebuffers.includes(t)||n.queuedFramebuffers.push(t))}}function c_(e,t,i){if(i.queuedFramebuffers.length===0)return;const n=e.device,{gl:r}=n,s=r.getParameter(36010),o=r.getParameter(36006),[a,l]=e.device.getDefaultCanvasContext().getDrawingBufferSize();let c=Pu(t.top,Po);const u=Pu(t.left,Po);i.flushing=!0;try{for(const d of i.queuedFramebuffers){const[h,p,g,x,T]=u_({framebuffer:d,targetWidth:a,targetHeight:l,topPx:c,leftPx:u,minimap:t.minimap});r.bindFramebuffer(36008,d.handle),r.bindFramebuffer(36009,null),r.blitFramebuffer(0,0,d.width,d.height,h,p,g,x,16384,9728),c+=T+Po}}finally{r.bindFramebuffer(36008,s),r.bindFramebuffer(36009,o),i.flushing=!1}}function u_(e){const{framebuffer:t,targetWidth:i,targetHeight:n,topPx:r,leftPx:s}=e,o=Math.max(Math.floor(i/4),1),a=Math.max(Math.floor(n/4),1),l=Math.min(o/t.width,a/t.height),c=Math.max(Math.floor(t.width*l),1),u=Math.max(Math.floor(t.height*l),1),d=s,h=Math.max(n-r-u,0),p=d+c,g=h+u;return[d,h,p,g,u]}function d_(e){var t;return(t=e.userData)[cr]||(t[cr]={flushing:!1,queuedFramebuffers:[]}),e.userData[cr]}function h_(e){return"colorAttachments"in e}function f_(e){const t=e.props.framebuffer;return!t||t.handle===null}function Pu(e,t){if(!e)return t;const i=Number.parseInt(e,10);return Number.isFinite(i)?i:t}function Co(e,t,i){if(e===t)return!0;if(!i||!e||!t)return!1;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!Co(e[n],t[n],i-1))return!1;return!0}if(Array.isArray(t))return!1;if(typeof e=="object"&&typeof t=="object"){const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(const s of n)if(!t.hasOwnProperty(s)||!Co(e[s],t[s],i-1))return!1;return!0}return!1}class Ao{constructor(t){f(this,"bufferLayouts");this.bufferLayouts=t}getBufferLayout(t){return this.bufferLayouts.find(i=>i.name===t)||null}getAttributeNamesForBuffer(t){var i;return t.attributes?(i=t.attributes)==null?void 0:i.map(n=>n.attribute):[t.name]}mergeBufferLayouts(t,i){const n=[...t];for(const r of i){const s=n.findIndex(o=>o.name===r.name);s<0?n.push(r):n[s]=r}return n}getBufferIndex(t){const i=this.bufferLayouts.findIndex(n=>n.name===t);return i===-1&&C.warn(`BufferLayout: Missing buffer for "${t}".`)(),i}}function Cu(e,t){let i=1/0;for(const n of e){const r=t[n];r!==void 0&&(i=Math.min(i,r))}return i}function p_(e,t){const i=Object.fromEntries(e.attributes.map(r=>[r.name,r.location])),n=t.slice();return n.sort((r,s)=>{const o=r.attributes?r.attributes.map(u=>u.attribute):[r.name],a=s.attributes?s.attributes.map(u=>u.attribute):[s.name],l=Cu(o,i),c=Cu(a,i);return l-c}),n}function Au(e,t){if(!e||!t.some(n=>{var r;return(r=n.bindingLayout)==null?void 0:r.length}))return e;const i={...e,bindings:e.bindings.map(n=>({...n}))};"attributes"in(e||{})&&(i.attributes=(e==null?void 0:e.attributes)||[]);for(const n of t)for(const r of n.bindingLayout||[])for(const s of m_(r.name)){const o=i.bindings.find(a=>a.name===s);(o==null?void 0:o.group)===0&&(o.group=r.group)}return i}function g_(e){return!!(e.uniformTypes&&!x_(e.uniformTypes))}function m_(e){const t=new Set([e,`${e}Uniforms`]);return e.endsWith("Uniforms")||t.add(`${e}Sampler`),[...t]}function x_(e){for(const t in e)return!1;return!0}function S_(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function y_(e){return Array.isArray(e)?e.length===0||typeof e[0]=="number":!1}function __(e){return S_(e)||y_(e)}function b_(e){return __(e)||typeof e=="number"||typeof e=="boolean"}function T_(e,t={}){const i={bindings:{},uniforms:{}};return Object.keys(e).forEach(n=>{const r=e[n];Object.prototype.hasOwnProperty.call(t,n)||b_(r)?i.uniforms[n]=r:i.bindings[n]=r}),i}class v_{constructor(t,i){f(this,"options",{disableWarnings:!1});f(this,"modules");f(this,"moduleUniforms");f(this,"moduleBindings");Object.assign(this.options,i);const n=po(Object.values(t).filter(P_));for(const r of n)t[r.name]=r;C.log(1,"Creating ShaderInputs with modules",Object.keys(t))(),this.modules=t,this.moduleUniforms={},this.moduleBindings={};for(const[r,s]of Object.entries(t))s&&(this._addModule(s),s.name&&r!==s.name&&!this.options.disableWarnings&&C.warn(`Module name: ${r} vs ${s.name}`)())}destroy(){}setProps(t){var i;for(const n of Object.keys(t)){const r=n,s=t[r]||{},o=this.modules[r];if(!o)this.options.disableWarnings||C.warn(`Module ${n} not found`)();else{const a=this.moduleUniforms[r],l=this.moduleBindings[r],c=((i=o.getUniforms)==null?void 0:i.call(o,s,a))||s,{uniforms:u,bindings:d}=T_(c,o.uniformTypes);this.moduleUniforms[r]=Ru(a,u,o.uniformTypes),this.moduleBindings[r]={...l,...d}}}}getModules(){return Object.values(this.modules)}getUniformValues(){return this.moduleUniforms}getBindingValues(){const t={};for(const i of Object.values(this.moduleBindings))Object.assign(t,i);return t}getDebugTable(){var i;const t={};for(const[n,r]of Object.entries(this.moduleUniforms))for(const[s,o]of Object.entries(r))t[`${n}.${s}`]={type:(i=this.modules[n].uniformTypes)==null?void 0:i[s],value:String(o)};return t}_addModule(t){const i=t.name;this.moduleUniforms[i]=Ru({},t.defaultUniforms||{},t.uniformTypes),this.moduleBindings[i]={}}}function Ru(e={},t={},i={}){const n={...e};for(const[r,s]of Object.entries(t))s!==void 0&&(n[r]=Ro(e[r],s,i[r]));return n}function Ro(e,t,i){if(!i||typeof i=="string")return $i(t);if(Array.isArray(i)){if(wo(t)||!Array.isArray(t))return $i(t);const o=Array.isArray(e)&&!wo(e)?[...e]:[],a=o.slice();for(let l=0;l<t.length;l++){const c=t[l];c!==void 0&&(a[l]=Ro(o[l],c,i[0]))}return a}if(!Eo(t))return $i(t);const n=i,r=Eo(e)?e:{},s={...r};for(const[o,a]of Object.entries(t))a!==void 0&&(s[o]=Ro(r[o],a,n[o]));return s}function $i(e){return ArrayBuffer.isView(e)?Array.prototype.slice.call(e):Array.isArray(e)?wo(e)?e.slice():e.map(i=>i===void 0?void 0:$i(i)):Eo(e)?Object.fromEntries(Object.entries(e).map(([t,i])=>[t,i===void 0?void 0:$i(i)])):e}function wo(e){return ArrayBuffer.isView(e)||Array.isArray(e)&&(e.length===0||typeof e[0]=="number")}function Eo(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&!ArrayBuffer.isView(e)}function P_(e){return!!(e!=null&&e.dependencies)}const wu={"+X":0,"-X":1,"+Y":2,"-Y":3,"+Z":4,"-Z":5};function Xi(e){return e?Array.isArray(e)?e[0]??null:e:null}function C_(e){const{dimension:t,data:i}=e;if(!i)return null;switch(t){case"1d":{const n=Xi(i);if(!n)return null;const{width:r}=Yi(n);return{width:r,height:1}}case"2d":{const n=Xi(i);return n?Yi(n):null}case"3d":case"2d-array":{if(!Array.isArray(i)||i.length===0)return null;const n=Xi(i[0]);return n?Yi(n):null}case"cube":{const n=Object.keys(i)[0]??null;if(!n)return null;const r=i[n],s=Xi(r);return s?Yi(s):null}case"cube-array":{if(!Array.isArray(i)||i.length===0)return null;const n=i[0],r=Object.keys(n)[0]??null;if(!r)return null;const s=Xi(n[r]);return s?Yi(s):null}default:return null}}function Yi(e){if(qs(e))return Bc(e);if(typeof e=="object"&&"width"in e&&"height"in e)return{width:e.width,height:e.height};throw new Error("Unsupported mip-level data")}function A_(e){return typeof e=="object"&&e!==null&&"data"in e&&"width"in e&&"height"in e}function R_(e){return ArrayBuffer.isView(e)}function Eu(e){const{textureFormat:t,format:i}=e;if(t&&i&&t!==i)throw new Error(`Conflicting texture formats "${t}" and "${i}" provided for the same mip level`);return t??i}function Iu(e){const t=wu[e];if(t===void 0)throw new Error(`Invalid cube face: ${e}`);return t}function w_(e,t){return 6*e+Iu(t)}function ku(e){throw new Error("setTexture1DData not supported in WebGL.")}function E_(e){return Array.isArray(e)?e:[e]}function oi(e,t,i,n){const r=E_(t),s=e,o=[];for(let a=0;a<r.length;a++){const l=r[a];if(qs(l))o.push({type:"external-image",image:l,z:s,mipLevel:a});else if(A_(l))o.push({type:"texture-data",data:l,textureFormat:Eu(l),z:s,mipLevel:a});else if(R_(l)&&i)o.push({type:"texture-data",data:{data:l,width:Math.max(1,i.width>>a),height:Math.max(1,i.height>>a),...n?{format:n}:{}},textureFormat:n,z:s,mipLevel:a});else throw new Error("Unsupported 2D mip-level payload")}return o}function Du(e){const t=[];for(let i=0;i<e.length;i++)t.push(...oi(i,e[i]));return t}function Fu(e){const t=[];for(let i=0;i<e.length;i++)t.push(...oi(i,e[i]));return t}function Mu(e){const t=[];for(const[i,n]of Object.entries(e)){const r=Iu(i);t.push(...oi(r,n))}return t}function Nu(e){const t=[];return e.forEach((i,n)=>{for(const[r,s]of Object.entries(i)){const o=w_(n,r);t.push(...oi(o,s))}}),t}const Br=class Br{constructor(t,i){f(this,"device");f(this,"id");f(this,"props");f(this,"_texture",null);f(this,"_sampler",null);f(this,"_view",null);f(this,"ready");f(this,"isReady",!1);f(this,"destroyed",!1);f(this,"resolveReady",()=>{});f(this,"rejectReady",()=>{});this.device=t;const n=vo("dynamic-texture"),r=i;this.props={...Br.defaultProps,id:n,...i,data:null},this.id=this.props.id,this.ready=new Promise((s,o)=>{this.resolveReady=s,this.rejectReady=o}),this.initAsync(r)}get texture(){if(!this._texture)throw new Error("Texture not initialized yet");return this._texture}get sampler(){if(!this._sampler)throw new Error("Sampler not initialized yet");return this._sampler}get view(){if(!this._view)throw new Error("View not initialized yet");return this._view}get[Symbol.toStringTag](){return"DynamicTexture"}toString(){var n,r;const t=((n=this._texture)==null?void 0:n.width)??this.props.width??"?",i=((r=this._texture)==null?void 0:r.height)??this.props.height??"?";return`DynamicTexture:"${this.id}":${t}x${i}px:(${this.isReady?"ready":"loading..."})`}async initAsync(t){try{const i=await this._loadAllData(t);this._checkNotDestroyed();const n=i.data?I_({...i,width:t.width,height:t.height,format:t.format}):[],r="format"in t&&t.format!==void 0,s="usage"in t&&t.usage!==void 0,a=(()=>{if(this.props.width&&this.props.height)return{width:this.props.width,height:this.props.height};const x=C_(i);return x||{width:this.props.width||1,height:this.props.height||1}})();if(!a||a.width<=0||a.height<=0)throw new Error(`${this} size could not be determined or was zero`);const l=k_(this.device,n,a,{format:r?t.format:void 0}),c=l.format??this.props.format,u={...this.props,...a,format:c,mipLevels:1,data:void 0};this.device.isTextureFormatCompressed(c)&&!s&&(u.usage=M.SAMPLE|M.COPY_DST);const d=this.props.mipmaps&&!l.hasExplicitMipChain&&!this.device.isTextureFormatCompressed(c);if(this.device.type==="webgpu"&&d){const x=this.props.dimension==="3d"?M.SAMPLE|M.STORAGE|M.COPY_DST|M.COPY_SRC:M.SAMPLE|M.RENDER|M.COPY_DST|M.COPY_SRC;u.usage|=x}const h=this.device.getMipLevelCount(u.width,u.height),p=l.hasExplicitMipChain?l.mipLevels:this.props.mipLevels==="auto"?h:Math.max(1,Math.min(h,this.props.mipLevels??1)),g={...u,mipLevels:p};this._texture=this.device.createTexture(g),this._sampler=this.texture.sampler,this._view=this.texture.view,l.subresources.length&&this._setTextureSubresources(l.subresources),this.props.mipmaps&&!l.hasExplicitMipChain&&!d&&C.warn(`${this} skipping auto-generated mipmaps for compressed texture format`)(),d&&this.generateMipmaps(),this.isReady=!0,this.resolveReady(this.texture),C.info(0,`${this} created`)()}catch(i){const n=i instanceof Error?i:new Error(String(i));this.rejectReady(n)}}destroy(){this._texture&&(this._texture.destroy(),this._texture=null,this._sampler=null,this._view=null),this.destroyed=!0}generateMipmaps(){this.device.type==="webgl"?this.texture.generateMipmapsWebGL():this.device.type==="webgpu"?this.device.generateMipmapsWebGPU(this.texture):C.warn(`${this} mipmaps not supported on ${this.device.type}`)}setSampler(t={}){this._checkReady();const i=t instanceof ni?t:this.device.createSampler(t);this.texture.setSampler(i),this._sampler=i}async readBuffer(t={}){this.isReady||await this.ready;const i=t.width??this.texture.width,n=t.height??this.texture.height,r=t.depthOrArrayLayers??this.texture.depth,s=this.texture.computeMemoryLayout({width:i,height:n,depthOrArrayLayers:r}),o=this.device.createBuffer({byteLength:s.byteLength,usage:B.COPY_DST|B.MAP_READ});this.texture.readBuffer({...t,width:i,height:n,depthOrArrayLayers:r},o);const a=this.device.createFence();return await a.signaled,a.destroy(),o}async readAsync(t={}){this.isReady||await this.ready;const i=t.width??this.texture.width,n=t.height??this.texture.height,r=t.depthOrArrayLayers??this.texture.depth,s=this.texture.computeMemoryLayout({width:i,height:n,depthOrArrayLayers:r}),o=await this.readBuffer(t),a=await o.readAsync(0,s.byteLength);return o.destroy(),a.buffer}resize(t){if(this._checkReady(),t.width===this.texture.width&&t.height===this.texture.height)return!1;const i=this.texture;return this._texture=i.clone(t),this._sampler=this.texture.sampler,this._view=this.texture.view,i.destroy(),C.info(`${this} resized`),!0}getCubeFaceIndex(t){const i=wu[t];if(i===void 0)throw new Error(`Invalid cube face: ${t}`);return i}getCubeArrayFaceIndex(t,i){return 6*t+this.getCubeFaceIndex(i)}setTexture1DData(t){if(this._checkReady(),this.texture.props.dimension!=="1d")throw new Error(`${this} is not 1d`);const i=ku();this._setTextureSubresources(i)}setTexture2DData(t,i=0){if(this._checkReady(),this.texture.props.dimension!=="2d")throw new Error(`${this} is not 2d`);const n=oi(i,t);this._setTextureSubresources(n)}setTexture3DData(t){if(this.texture.props.dimension!=="3d")throw new Error(`${this} is not 3d`);const i=Du(t);this._setTextureSubresources(i)}setTextureArrayData(t){if(this.texture.props.dimension!=="2d-array")throw new Error(`${this} is not 2d-array`);const i=Fu(t);this._setTextureSubresources(i)}setTextureCubeData(t){if(this.texture.props.dimension!=="cube")throw new Error(`${this} is not cube`);const i=Mu(t);this._setTextureSubresources(i)}setTextureCubeArrayData(t){if(this.texture.props.dimension!=="cube-array")throw new Error(`${this} is not cube-array`);const i=Nu(t);this._setTextureSubresources(i)}_setTextureSubresources(t){for(const i of t){const{z:n,mipLevel:r}=i;switch(i.type){case"external-image":const{image:s,flipY:o}=i;this.texture.copyExternalImage({image:s,z:n,mipLevel:r,flipY:o});break;case"texture-data":const{data:a,textureFormat:l}=i;if(l&&l!==this.texture.format)throw new Error(`${this} mip level ${r} uses format "${l}" but texture format is "${this.texture.format}"`);this.texture.writeData(a.data,{x:0,y:0,z:n,width:a.width,height:a.height,depthOrArrayLayers:1,mipLevel:r});break;default:throw new Error("Unsupported 2D mip-level payload")}}}async _loadAllData(t){const i=await Io(t.data);return{dimension:t.dimension??"2d",data:i??null}}_checkNotDestroyed(){this.destroyed&&C.warn(`${this} already destroyed`)}_checkReady(){this.isReady||C.warn(`${this} Cannot perform this operation before ready`)}};f(Br,"defaultProps",{...M.defaultProps,dimension:"2d",data:null,mipmaps:!1});let ai=Br;function I_(e){if(!e.data)return[];const t=e.width&&e.height?{width:e.width,height:e.height}:void 0,i="format"in e?e.format:void 0;switch(e.dimension){case"1d":return ku();case"2d":return oi(0,e.data,t,i);case"3d":return Du(e.data);case"2d-array":return Fu(e.data);case"cube":return Mu(e.data);case"cube-array":return Nu(e.data);default:throw new Error(`Unhandled dimension ${e.dimension}`)}}function k_(e,t,i,n){if(t.length===0)return{subresources:t,mipLevels:1,format:n.format,hasExplicitMipChain:!1};const r=new Map;for(const u of t){const d=r.get(u.z)??[];d.push(u),r.set(u.z,d)}const s=t.some(u=>u.mipLevel>0);let o=n.format,a=Number.POSITIVE_INFINITY;const l=[];for(const[u,d]of r){const h=[...d].sort((P,I)=>P.mipLevel-I.mipLevel),p=h[0];if(!p||p.mipLevel!==0)throw new Error(`DynamicTexture: slice ${u} is missing mip level 0`);const g=Ou(e,p);if(g.width!==i.width||g.height!==i.height)throw new Error(`DynamicTexture: slice ${u} base level dimensions ${g.width}x${g.height} do not match expected ${i.width}x${i.height}`);const x=Bu(p);if(x){if(o&&o!==x)throw new Error(`DynamicTexture: slice ${u} base level format "${x}" does not match texture format "${o}"`);o=x}const T=o&&e.isTextureFormatCompressed(o)?D_(e,g.width,g.height,o):e.getMipLevelCount(g.width,g.height);let S=0;for(let P=0;P<h.length;P++){const I=h[P];if(!I||I.mipLevel!==P||P>=T)break;const y=Ou(e,I),v=Math.max(1,g.width>>P),E=Math.max(1,g.height>>P);if(y.width!==v||y.height!==E)break;const R=Bu(I);if(R&&(o||(o=R),R!==o))break;S++,l.push(I)}a=Math.min(a,S)}const c=Number.isFinite(a)?Math.max(1,a):1;return{subresources:l.filter(u=>u.mipLevel<c),mipLevels:c,format:o,hasExplicitMipChain:s}}function Bu(e){if(e.type==="texture-data")return e.textureFormat??Eu(e.data)}function Ou(e,t){switch(t.type){case"external-image":return e.getExternalImageSize(t.image);case"texture-data":return{width:t.data.width,height:t.data.height};default:throw new Error("Unsupported texture subresource")}}function D_(e,t,i,n){const{blockWidth:r=1,blockHeight:s=1}=e.getTextureFormatInfo(n);let o=1;for(let a=1;;a++){const l=Math.max(1,t>>a),c=Math.max(1,i>>a);if(l<r||c<s)break;o++}return o}async function Io(e){if(e=await e,Array.isArray(e))return await Promise.all(e.map(Io));if(e&&typeof e=="object"&&e.constructor===Object){const t=e,i=await Promise.all(Object.values(t).map(Io)),n=Object.keys(t),r={};for(let s=0;s<n.length;s++)r[n[s]]=i[s];return r}return e}const vt=2,F_=1e4,Uu="render pipeline initialization failed",Or=class Or{constructor(t,i){f(this,"device");f(this,"id");f(this,"source");f(this,"vs");f(this,"fs");f(this,"pipelineFactory");f(this,"shaderFactory");f(this,"userData",{});f(this,"parameters");f(this,"topology");f(this,"bufferLayout");f(this,"isInstanced");f(this,"instanceCount",0);f(this,"vertexCount");f(this,"indexBuffer",null);f(this,"bufferAttributes",{});f(this,"constantAttributes",{});f(this,"bindings",{});f(this,"vertexArray");f(this,"transformFeedback",null);f(this,"pipeline");f(this,"shaderInputs");f(this,"material",null);f(this,"_uniformStore");f(this,"_attributeInfos",{});f(this,"_gpuGeometry",null);f(this,"props");f(this,"_pipelineNeedsUpdate","newly created");f(this,"_needsRedraw","initializing");f(this,"_destroyed",!1);f(this,"_lastDrawTimestamp",-1);f(this,"_bindingTable",[]);f(this,"_lastLogTime",0);f(this,"_logOpen",!1);f(this,"_drawCount",0);var l,c,u,d;this.props={...Or.defaultProps,...i},i=this.props,this.id=i.id||vo("model"),this.device=t,Object.assign(this.userData,i.userData),this.material=i.material||null;const n=Object.fromEntries(((l=this.props.modules)==null?void 0:l.map(h=>[h.name,h]))||[]),r=i.shaderInputs||new v_(n,{disableWarnings:this.props.disableWarnings});this.setShaderInputs(r);const s=M_(t),o=(((c=this.props.modules)==null?void 0:c.length)>0?this.props.modules:(u=this.shaderInputs)==null?void 0:u.getModules())||[];if(this.props.shaderLayout=Au(this.props.shaderLayout,o)||null,this.device.type==="webgpu"&&this.props.source){const{source:h,getUniforms:p,bindingTable:g}=this.props.shaderAssembler.assembleWGSLShader({platformInfo:s,...this.props,modules:o});this.source=h,this._getModuleUniforms=p,this._bindingTable=g;const x=(d=t.getShaderLayout)==null?void 0:d.call(t,this.source);this.props.shaderLayout=Au(this.props.shaderLayout||x||null,o)||null}else{const{vs:h,fs:p,getUniforms:g}=this.props.shaderAssembler.assembleGLSLShaderPair({platformInfo:s,...this.props,modules:o});this.vs=h,this.fs=p,this._getModuleUniforms=g,this._bindingTable=[]}this.vertexCount=this.props.vertexCount,this.instanceCount=this.props.instanceCount,this.topology=this.props.topology,this.bufferLayout=this.props.bufferLayout,this.parameters=this.props.parameters,i.geometry&&this.setGeometry(i.geometry),this.pipelineFactory=i.pipelineFactory||Js.getDefaultPipelineFactory(this.device),this.shaderFactory=i.shaderFactory||eo.getDefaultShaderFactory(this.device),this.pipeline=this._updatePipeline(),this.vertexArray=t.createVertexArray({shaderLayout:this.pipeline.shaderLayout,bufferLayout:this.pipeline.bufferLayout}),this._gpuGeometry&&this._setGeometryAttributes(this._gpuGeometry),"isInstanced"in i&&(this.isInstanced=i.isInstanced),i.instanceCount&&this.setInstanceCount(i.instanceCount),i.vertexCount&&this.setVertexCount(i.vertexCount),i.indexBuffer&&this.setIndexBuffer(i.indexBuffer),i.attributes&&this.setAttributes(i.attributes),i.constantAttributes&&this.setConstantAttributes(i.constantAttributes),i.bindings&&this.setBindings(i.bindings),i.transformFeedback&&(this.transformFeedback=i.transformFeedback)}get[Symbol.toStringTag](){return"Model"}toString(){return`Model(${this.id})`}destroy(){var t;this._destroyed||(this.pipelineFactory.release(this.pipeline),this.shaderFactory.release(this.pipeline.vs),this.pipeline.fs&&this.pipeline.fs!==this.pipeline.vs&&this.shaderFactory.release(this.pipeline.fs),this._uniformStore.destroy(),(t=this._gpuGeometry)==null||t.destroy(),this._destroyed=!0)}needsRedraw(){this._getBindingsUpdateTimestamp()>this._lastDrawTimestamp&&this.setNeedsRedraw("contents of bound textures or buffers updated");const t=this._needsRedraw;return this._needsRedraw=!1,t}setNeedsRedraw(t){this._needsRedraw||(this._needsRedraw=t)}getBindingDebugTable(){return this._bindingTable}predraw(){this.updateShaderInputs(),this.pipeline=this._updatePipeline()}draw(t){const i=this._areBindingsLoading();if(i)return C.info(vt,`>>> DRAWING ABORTED ${this.id}: ${i} not loaded`)(),!1;try{t.pushDebugGroup(`${this}.predraw(${t})`),this.predraw()}finally{t.popDebugGroup()}let n,r=this.pipeline.isErrored;try{if(t.pushDebugGroup(`${this}.draw(${t})`),this._logDrawCallStart(),this.pipeline=this._updatePipeline(),r=this.pipeline.isErrored,r)C.info(vt,`>>> DRAWING ABORTED ${this.id}: ${Uu}`)(),n=!1;else{const s=this._getBindings(),o=this._getBindGroups(),{indexBuffer:a}=this.vertexArray,l=a?a.byteLength/(a.indexType==="uint32"?4:2):void 0;n=this.pipeline.draw({renderPass:t,vertexArray:this.vertexArray,isInstanced:this.isInstanced,vertexCount:this.vertexCount,instanceCount:this.instanceCount,indexCount:l,transformFeedback:this.transformFeedback||void 0,bindings:s,bindGroups:o,_bindGroupCacheKeys:this._getBindGroupCacheKeys(),uniforms:this.props.uniforms,parameters:this.parameters,topology:this.topology})}}finally{t.popDebugGroup(),this._logDrawCallEnd()}return this._logFramebuffer(t),n?(this._lastDrawTimestamp=this.device.timestamp,this._needsRedraw=!1):r?this._needsRedraw=Uu:this._needsRedraw="waiting for resource initialization",n}setGeometry(t){var n;(n=this._gpuGeometry)==null||n.destroy();const i=t&&r_(this.device,t);if(i){this.setTopology(i.topology||"triangle-list");const r=new Ao(this.bufferLayout);this.bufferLayout=r.mergeBufferLayouts(i.bufferLayout,this.bufferLayout),this.vertexArray&&this._setGeometryAttributes(i)}this._gpuGeometry=i}setTopology(t){t!==this.topology&&(this.topology=t,this._setPipelineNeedsUpdate("topology"))}setBufferLayout(t){const i=new Ao(this.bufferLayout);this.bufferLayout=this._gpuGeometry?i.mergeBufferLayouts(t,this._gpuGeometry.bufferLayout):t,this._setPipelineNeedsUpdate("bufferLayout"),this.pipeline=this._updatePipeline(),this.vertexArray=this.device.createVertexArray({shaderLayout:this.pipeline.shaderLayout,bufferLayout:this.pipeline.bufferLayout}),this._gpuGeometry&&this._setGeometryAttributes(this._gpuGeometry)}setParameters(t){Co(t,this.parameters,2)||(this.parameters=t,this._setPipelineNeedsUpdate("parameters"))}setInstanceCount(t){this.instanceCount=t,this.isInstanced===void 0&&t>0&&(this.isInstanced=!0),this.setNeedsRedraw("instanceCount")}setVertexCount(t){this.vertexCount=t,this.setNeedsRedraw("vertexCount")}setShaderInputs(t){var i;this.shaderInputs=t,this._uniformStore=new oe(this.device,this.shaderInputs.modules);for(const[n,r]of Object.entries(this.shaderInputs.modules))if(g_(r)&&!((i=this.material)!=null&&i.ownsModule(n))){const s=this._uniformStore.getManagedUniformBuffer(n);this.bindings[`${n}Uniforms`]=s}this.setNeedsRedraw("shaderInputs")}setMaterial(t){this.material=t,this.setNeedsRedraw("material")}updateShaderInputs(){this._uniformStore.setUniforms(this.shaderInputs.getUniformValues()),this.setBindings(this._getNonMaterialBindings(this.shaderInputs.getBindingValues())),this.setNeedsRedraw("shaderInputs")}setBindings(t){Object.assign(this.bindings,t),this.setNeedsRedraw("bindings")}setTransformFeedback(t){this.transformFeedback=t,this.setNeedsRedraw("transformFeedback")}setIndexBuffer(t){this.vertexArray.setIndexBuffer(t),this.setNeedsRedraw("indexBuffer")}setAttributes(t,i){const n=(i==null?void 0:i.disableWarnings)??this.props.disableWarnings;t.indices&&C.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)(),this.bufferLayout=p_(this.pipeline.shaderLayout,this.bufferLayout);const r=new Ao(this.bufferLayout);for(const[s,o]of Object.entries(t)){const a=r.getBufferLayout(s);if(!a){n||C.warn(`Model(${this.id}): Missing layout for buffer "${s}".`)();continue}const l=r.getAttributeNamesForBuffer(a);let c=!1;for(const u of l){const d=this._attributeInfos[u];if(d){const h=this.device.type==="webgpu"?r.getBufferIndex(d.bufferName):d.location;this.vertexArray.setBuffer(h,o),c=!0}}!c&&!n&&C.warn(`Model(${this.id}): Ignoring buffer "${o.id}" for unknown attribute "${s}"`)()}this.setNeedsRedraw("attributes")}setConstantAttributes(t,i){for(const[n,r]of Object.entries(t)){const s=this._attributeInfos[n];s?this.vertexArray.setConstantWebGL(s.location,r):((i==null?void 0:i.disableWarnings)??this.props.disableWarnings)||C.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${n}"`)()}this.setNeedsRedraw("constants")}_areBindingsLoading(){var t;for(const i of Object.values(this.bindings))if(i instanceof ai&&!i.isReady)return i.id;for(const i of Object.values(((t=this.material)==null?void 0:t.bindings)||{}))if(i instanceof ai&&!i.isReady)return i.id;return!1}_getBindings(){const t={};for(const[i,n]of Object.entries(this.bindings))n instanceof ai?n.isReady&&(t[i]=n.texture):t[i]=n;return t}_getBindGroups(){var n;const t=((n=this.pipeline)==null?void 0:n.shaderLayout)||this.props.shaderLayout||{bindings:[]},i=t.bindings.length?Hc(t,this._getBindings()):{0:this._getBindings()};if(!this.material)return i;for(const[r,s]of Object.entries(this.material.getBindingsByGroup())){const o=Number(r);i[o]={...i[o]||{},...s}}return i}_getBindGroupCacheKeys(){var i;const t=(i=this.material)==null?void 0:i.getBindGroupCacheKey(3);return t?{3:t}:{}}_getBindingsUpdateTimestamp(){var i;let t=0;for(const n of Object.values(this.bindings))n instanceof Jn?t=Math.max(t,n.texture.updateTimestamp):n instanceof B||n instanceof M?t=Math.max(t,n.updateTimestamp):n instanceof ai?t=n.texture?Math.max(t,n.texture.updateTimestamp):1/0:n instanceof ni||(t=Math.max(t,n.buffer.updateTimestamp));return Math.max(t,((i=this.material)==null?void 0:i.getBindingsUpdateTimestamp())||0)}_setGeometryAttributes(t){const i={...t.attributes};for(const[n]of Object.entries(i))!this.pipeline.shaderLayout.attributes.find(r=>r.name===n)&&n!=="positions"&&delete i[n];this.vertexCount=t.vertexCount,this.setIndexBuffer(t.indices||null),this.setAttributes(t.attributes,{disableWarnings:!0}),this.setAttributes(i,{disableWarnings:this.props.disableWarnings}),this.setNeedsRedraw("geometry attributes")}_setPipelineNeedsUpdate(t){this._pipelineNeedsUpdate||(this._pipelineNeedsUpdate=t),this.setNeedsRedraw(t)}_updatePipeline(){if(this._pipelineNeedsUpdate){let t=null,i=null;this.pipeline&&(C.log(1,`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)(),t=this.pipeline.vs,i=this.pipeline.fs),this._pipelineNeedsUpdate=!1;const n=this.shaderFactory.createShader({id:`${this.id}-vertex`,stage:"vertex",source:this.source||this.vs,debugShaders:this.props.debugShaders});let r=null;this.source?r=n:this.fs&&(r=this.shaderFactory.createShader({id:`${this.id}-fragment`,stage:"fragment",source:this.source||this.fs,debugShaders:this.props.debugShaders})),this.pipeline=this.pipelineFactory.createRenderPipeline({...this.props,bindings:void 0,bufferLayout:this.bufferLayout,topology:this.topology,parameters:this.parameters,bindGroups:this._getBindGroups(),vs:n,fs:r}),this._attributeInfos=Yc(this.pipeline.shaderLayout,this.bufferLayout),t&&this.shaderFactory.release(t),i&&i!==t&&this.shaderFactory.release(i)}return this.pipeline}_logDrawCallStart(){const t=C.level>3?0:F_;C.level<2||Date.now()-this._lastLogTime<t||(this._lastLogTime=Date.now(),this._logOpen=!0,C.group(vt,`>>> DRAWING MODEL ${this.id}`,{collapsed:C.level<=2})())}_logDrawCallEnd(){if(this._logOpen){const t=a_(this.pipeline.shaderLayout,this.id);C.table(vt,t)();const i=this.shaderInputs.getDebugTable();C.table(vt,i)();const n=this._getAttributeDebugTable();C.table(vt,this._attributeInfos)(),C.table(vt,n)(),C.groupEnd(vt)(),this._logOpen=!1}}_logFramebuffer(t){const i=this.device.props.debugFramebuffers;if(this._drawCount++,!i)return;const n=t.props.framebuffer;l_(t,n,{id:(n==null?void 0:n.id)||`${this.id}-framebuffer`,minimap:!0})}_getAttributeDebugTable(){const t={};for(const[i,n]of Object.entries(this._attributeInfos)){const r=this.vertexArray.attributes[n.location];t[n.location]={name:i,type:n.shaderType,values:r?this._getBufferOrConstantValues(r,n.bufferDataType):"null"}}if(this.vertexArray.indexBuffer){const{indexBuffer:i}=this.vertexArray,n=i.indexType==="uint32"?new Uint32Array(i.debugData):new Uint16Array(i.debugData);t.indices={name:"indices",type:i.indexType,values:n.toString()}}return t}_getBufferOrConstantValues(t,i){const n=Nt.getTypedArrayConstructor(i);return(t instanceof B?new n(t.debugData):t).toString()}_getNonMaterialBindings(t){if(!this.material)return t;const i={};for(const[n,r]of Object.entries(t))this.material.ownsBinding(n)||(i[n]=r);return i}};f(Or,"defaultProps",{...bt.defaultProps,source:void 0,vs:null,fs:null,id:"unnamed",handle:void 0,userData:{},defines:{},modules:[],geometry:null,indexBuffer:null,attributes:{},constantAttributes:{},bindings:{},uniforms:{},varyings:[],isInstanced:void 0,instanceCount:0,vertexCount:0,shaderInputs:void 0,material:void 0,pipelineFactory:void 0,shaderFactory:void 0,transformFeedback:void 0,shaderAssembler:bo.getDefaultShaderAssembler(),debugShaders:void 0,disableWarnings:void 0});let ee=Or;function M_(e){return{type:e.type,shaderLanguage:e.info.shadingLanguage,shaderLanguageVersion:e.info.shadingLanguageVersion,gpu:e.info.gpu,features:e.features}}const te=Object.freeze({blend:!1,depthWriteEnabled:!1,depthCompare:"always",stencilCompare:"always",cullMode:"none",frontFace:"ccw"});class gt{constructor(t,i,n,r,s){this._debugRandomNumber=Math.floor(Math.random()*1e3),this.device=t,this.config=i,this.store=n,this.data=r,s&&(this.points=s)}}const zu={name:"conicParametricCurve",vs:` +vec2 conicParametricCurve(vec2 A, vec2 B, vec2 ControlPoint, float t, float w) { + vec2 divident = (1.0 - t) * (1.0 - t) * A + 2.0 * (1.0 - t) * t * w * ControlPoint + t * t * B; + float divisor = (1.0 - t) * (1.0 - t) + 2.0 * (1.0 - t) * t * w + t * t; + return divident / divisor; +} +`},ur={name:"pickingColor",fs:` +vec3 encodePickingColor(float index) { + float i = index + 1.0; + return vec3(mod(i, 256.0), mod(floor(i / 256.0), 256.0), floor(i / 65536.0)) / 255.0; +} +`},N_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgbaColor; +in vec2 pos; +in float arrowLength; +in float useArrow; +in float smoothing; +in float arrowWidthFactor; +in float linkIndex; +flat in float vLinkStyle; +flat in float vLinkDashSpan; +flat in float vLinkDashWidth; +flat in vec4 vEndpointColorA; +flat in vec4 vEndpointColorB; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawLineFragmentUniforms { + float renderMode; + float linkDashLength; + float linkDashGap; + float linkColorInterpolateFromEndpoints; + float hoveredLinkIndex; + vec4 hoveredLinkColor; + float linkBlending; + float pickingAlpha; + float pickingIndexOffset; +} drawLineFrag; + +#define renderMode drawLineFrag.renderMode +#define linkDashLength drawLineFrag.linkDashLength +#define linkDashGap drawLineFrag.linkDashGap +#define linkColorInterpolateFromEndpoints drawLineFrag.linkColorInterpolateFromEndpoints +#define hoveredLinkIndex drawLineFrag.hoveredLinkIndex +#define hoveredLinkColor drawLineFrag.hoveredLinkColor +#define linkBlending drawLineFrag.linkBlending +#define pickingAlpha drawLineFrag.pickingAlpha +#define pickingIndexOffset drawLineFrag.pickingIndexOffset +#else +// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking, 3.0 = host picking colors +uniform float renderMode; +uniform float linkDashLength; +uniform float linkDashGap; +uniform float linkColorInterpolateFromEndpoints; +uniform float hoveredLinkIndex; +uniform vec4 hoveredLinkColor; +uniform float linkBlending; +uniform float pickingAlpha; +uniform float pickingIndexOffset; +#endif + +out vec4 fragColor; + +float map(float value, float min1, float max1, float min2, float max2) { + return min2 + (value - min1) * (max2 - min2) / (max1 - min1); +} + +// LinkStyle enum values (must match \`LinkStyle\` in modules/GraphData). Compared with +// exact equality, like the point shapes: the CPU sanitizer guarantees exact integers +// and vLinkStyle is flat, so an unknown future style matches nothing and renders solid. +const float LINK_STYLE_DASHED = 1.0; +const float LINK_STYLE_DOTTED = 2.0; + +// Anti-aliased on/off mask for one dash period. \`phase\` is distance-along-line in px, +// \`on\` is the lit dash length, \`period\` is on + gap, \`aa\` is the smoothing half-width in px. +float strokeMask(float phase, float on, float period, float aa) { + float m = mod(phase, period); + return smoothstep(-aa, aa, m) * (1.0 - smoothstep(on - aa, on + aa, m)); +} + +void main() { + // Geometric coverage only (stroke / arrow / dash). Color alpha is applied after. + float coverage = 1.0; + vec3 color = rgbaColor.rgb; + + // Arrowhead extent along the link (pos.x space) — used by the arrow rendering + // and by the dash mask, which leaves the arrowhead solid. + float end_arrow = 0.5 + arrowLength / 2.0; + float start_arrow = end_arrow - arrowLength; + + // Gradient links: interpolate RGB from the source point color to the target point color + // along the link. Opacity (visibility / greyout) still comes from rgbaColor.a. + if (linkColorInterpolateFromEndpoints > 0.5) { + color = mix(vEndpointColorA.rgb, vEndpointColorB.rgb, clamp(pos.x, 0.0, 1.0)); + } + + if (useArrow > 0.5) { + // pos.y spans the quad, which is the arrow width plus a ramp. arrowWidthFactor is a fraction + // of the arrow width alone, so edges derived from it scale by (1 - smoothing) = arrow / quad. + float preRamp = 1.0 - smoothing; + float bodyEdge = (0.5 - arrowWidthFactor / 2.0) * preRamp; + float headBase = 0.5 * preRamp; + // Body edge, ramp centred on it as for the plain stroke. + float linkCoverage = smoothstep(bodyEdge + smoothing / 2.0, bodyEdge - smoothing / 2.0, abs(pos.y)); + float arrowCoverage = 1.0; + if (pos.x > start_arrow && pos.x < start_arrow + arrowLength) { + // Arrowhead taper, from headBase at its base to the centreline at its tip; ramp centred on it. + float taper = headBase * (1.0 - map(pos.x, start_arrow, end_arrow, 0.0, 1.0)); + arrowCoverage = 1.0 - smoothstep(taper - smoothing / 2.0, taper + smoothing / 2.0, abs(pos.y)); + if (linkCoverage != arrowCoverage) { + linkCoverage = max(linkCoverage, arrowCoverage); + } + } + coverage = linkCoverage; + } else coverage = smoothstep(0.5, 0.5 - smoothing, abs(pos.y)); + + // Dashed / dotted stroke patterns. Applied to the visible pass only (renderMode == 0.0) + // so that gaps stay fully pickable in the index pass. The arrowhead region is left solid. + if (renderMode < 0.5 && (vLinkStyle == LINK_STYLE_DASHED || vLinkStyle == LINK_STYLE_DOTTED)) { + bool inArrowHead = (useArrow > 0.5) && (pos.x > start_arrow) && (pos.x < end_arrow); + if (!inArrowHead) { + // Distance along the link in the dash pattern's space (screen px or world units; see the vertex shader). + // fwidth() gives the screen-space rate of change, so the ramp is EDGE_RAMP_PX device pixels in either space. + float phase = clamp(pos.x, 0.0, 1.0) * vLinkDashSpan; + if (vLinkStyle == LINK_STYLE_DASHED) { + float period = max(linkDashLength + linkDashGap, 0.001); + // Half a ramp in the pattern's units: fwidth(phase) is the change in phase per device pixel. + float aa = max(fwidth(phase), 1e-4) * (EDGE_RAMP_PX * 0.5); + coverage *= strokeMask(phase, linkDashLength, period, aa); + } else { + // Dotted: round dots sized to the stroke, the quad less its ramp; spaced by diameter + gap. + float diameter = vLinkDashWidth * (1.0 - smoothing); + if (linkBlending < 0.5) { + // Unblended keeps only pixels whose centre is inside the dot. A dot under √2 device + // px can miss every pixel centre and vanish; at √2 it always holds one. Pattern units + // per device pixel from the phase's gradient (the pattern space is isotropic). + float pxInPattern = max(length(vec2(dFdx(phase), dFdy(phase))), 1e-4); + diameter = max(diameter, 1.4142136 * pxInPattern); + } + float period = max(diameter + linkDashGap, 0.001); + float localX = mod(phase, period) - period * 0.5; + float localY = pos.y * vLinkDashWidth; + float r = length(vec2(localX, localY)); + // Half a ramp in the pattern's units: fwidth(r) is the change in r per device pixel. + float aa = max(fwidth(r), 1e-4) * (EDGE_RAMP_PX * 0.5); + coverage *= 1.0 - smoothstep(diameter * 0.5 - aa, diameter * 0.5 + aa, r); + } + } + } + + float opacity = rgbaColor.a * coverage; + + // Apply hover color if this is the hovered link and hover color is defined. + // Done last — after the gradient and the dash mask — so hover wins over every + // color source (per-link color from the vertex stage and the endpoint gradient + // alike), while the dash pattern and AA stay intact in the hover color. + if (hoveredLinkIndex == linkIndex && hoveredLinkColor.a > -0.5) { + color = hoveredLinkColor.rgb; + opacity *= hoveredLinkColor.a; + } + + if (renderMode > 2.5) { + // Host picking: the link's index and the host's alpha, where the stroke covers at + // least half the fragment and the link is not fully transparent; dash gaps stay + // pickable, as in the engine's own index pass + if (coverage < 0.5 || rgbaColor.a <= 0.0) discard; + fragColor = vec4(encodePickingColor(linkIndex + pickingIndexOffset), pickingAlpha); + } else if (renderMode > 0.0) { + if (opacity <= 0.0) discard; + fragColor = vec4(linkIndex, 0.0, 0.0, 1.0); + } else if (linkBlending < 0.5) { + // Unblended: opaque, hard edges. Soft fringes would write full RGB with partial + // alpha; canvas compositing treats that as premultiplied and the edge reads + // brighter than the solid core. Every fade is centred on its geometric edge, so + // coverage 0.5 is that edge: keep the pixels whose centre is inside the stroke. + // The vertex stage keeps unblended strokes at least a device pixel wide. + if (coverage < 0.5 || opacity <= 0.0) discard; + fragColor = vec4(color, 1.0); + } else { + fragColor = vec4(color, opacity); + } + +} +`,B_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 position, pointA, pointB; +in vec4 sourceColor; +in vec4 targetColor; +in float sourceWidth; +in float targetWidth; +in float arrow; +in float linkIndices; +in float linkStyle; + +uniform sampler2D positionsTexture; +uniform sampler2D linkStatus; +uniform sampler2D exitTexture; +uniform sampler2D pointColorsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawLineUniforms { + mat4 transformationMatrix; + float widthScale; + float linkArrowsSizeScale; + float spaceSize; + vec2 screenSize; + vec2 linkVisibilityDistanceRange; + float linkVisibilityMinTransparency; + float linkOpacity; + float greyoutOpacity; + float curvedWeight; + float curvedLinkControlPointDistance; + float curvedLinkSegments; + float scaleLinksOnZoom; + float maxPointSize; + float renderMode; + float hoveredLinkIndex; + float hoveredLinkWidthIncrease; + float isLinkHighlightingActive; + float linkStatusTextureSize; + float focusedLinkIndex; + float focusedLinkWidthIncrease; + float transitionProgress; + float animateColors; + float animateWidths; + float animatePositions; + vec4 pointDefaultColor; + float linkColorInterpolateFromEndpoints; + float linkBlending; + float pixelRatio; +} drawLine; + +#define transformationMatrix drawLine.transformationMatrix +#define widthScale drawLine.widthScale +#define linkArrowsSizeScale drawLine.linkArrowsSizeScale +#define spaceSize drawLine.spaceSize +#define screenSize drawLine.screenSize +#define linkVisibilityDistanceRange drawLine.linkVisibilityDistanceRange +#define linkVisibilityMinTransparency drawLine.linkVisibilityMinTransparency +#define linkOpacity drawLine.linkOpacity +#define greyoutOpacity drawLine.greyoutOpacity +#define curvedWeight drawLine.curvedWeight +#define curvedLinkControlPointDistance drawLine.curvedLinkControlPointDistance +#define curvedLinkSegments drawLine.curvedLinkSegments +#define scaleLinksOnZoom drawLine.scaleLinksOnZoom +#define maxPointSize drawLine.maxPointSize +#define renderMode drawLine.renderMode +#define hoveredLinkIndex drawLine.hoveredLinkIndex +#define hoveredLinkWidthIncrease drawLine.hoveredLinkWidthIncrease +#define isLinkHighlightingActive drawLine.isLinkHighlightingActive +#define linkStatusTextureSize drawLine.linkStatusTextureSize +#define focusedLinkIndex drawLine.focusedLinkIndex +#define focusedLinkWidthIncrease drawLine.focusedLinkWidthIncrease +#define transitionProgress drawLine.transitionProgress +#define animateColors drawLine.animateColors +#define animateWidths drawLine.animateWidths +#define animatePositions drawLine.animatePositions +#define pointDefaultColor drawLine.pointDefaultColor +#define linkColorInterpolateFromEndpoints drawLine.linkColorInterpolateFromEndpoints +#define linkBlending drawLine.linkBlending +#define pixelRatio drawLine.pixelRatio +#else +uniform mat3 transformationMatrix; +uniform float widthScale; +uniform float linkArrowsSizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform vec2 linkVisibilityDistanceRange; +uniform float linkVisibilityMinTransparency; +uniform float linkOpacity; +uniform float greyoutOpacity; +uniform float curvedWeight; +uniform float curvedLinkControlPointDistance; +uniform float curvedLinkSegments; +uniform bool scaleLinksOnZoom; +uniform float maxPointSize; +// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking +uniform float renderMode; +uniform float hoveredLinkIndex; +uniform float hoveredLinkWidthIncrease; +uniform float isLinkHighlightingActive; +uniform float linkStatusTextureSize; +uniform float focusedLinkIndex; +uniform float focusedLinkWidthIncrease; +uniform float transitionProgress; +uniform float animateColors; +uniform float animateWidths; +uniform float animatePositions; +uniform vec4 pointDefaultColor; +uniform float linkColorInterpolateFromEndpoints; +uniform float linkBlending; +uniform float pixelRatio; +#endif + +out vec4 rgbaColor; +out vec2 pos; +out float arrowLength; +out float useArrow; +out float smoothing; +out float arrowWidthFactor; +out float linkIndex; +// Per-instance constants (no per-vertex variation), so \`flat\` skips interpolation. +flat out float vLinkStyle; +flat out float vLinkDashSpan; +flat out float vLinkDashWidth; +flat out vec4 vEndpointColorA; +flat out vec4 vEndpointColorB; + +float map(float value, float min1, float max1, float min2, float max2) { + return min2 + (value - min1) * (max2 - min2) / (max1 - min1); +} + +// Resolves NaN color channels the way the point draw shader does: NaN means "use the +// default" — the config default, blended toward the exit default as the endpoint fades +// out. Mirrors resolveColor in draw-points.vert. +vec4 resolveColor(vec4 color, float exitRamp) { + vec4 defaultColor = mix(pointDefaultColor, vec4(EXIT_DEFAULT_COLOR_CHANNEL), exitRamp); + return mix(color, defaultColor, isnan(color)); +} + +float calculateLinkWidth(float width) { + float linkWidth; + if (scaleLinksOnZoom > 0.0) { + // Use original width if links should scale with zoom + linkWidth = width; + } else { + // Adjust width based on zoom level to maintain visual size + linkWidth = width / transformationMatrix[0][0]; + // Apply a non-linear scaling to avoid extreme widths + linkWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01)); + } + // Limit link width based on whether it has an arrow + if (useArrow > 0.5) { + return min(linkWidth, (maxPointSize * 2.0) / transformationMatrix[0][0]); + } else { + return min(linkWidth, maxPointSize / transformationMatrix[0][0]); + } +} + +float calculateArrowWidth(float arrowWidth) { + if (scaleLinksOnZoom > 0.0) { + return arrowWidth; + } else { + // Apply the same scaling logic as calculateLinkWidth to maintain proportionality + arrowWidth = arrowWidth / transformationMatrix[0][0]; + // Apply the same non-linear scaling to avoid extreme widths + arrowWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01)); + return arrowWidth; + } +} + +void main() { + pos = position; + linkIndex = linkIndices; + vLinkStyle = linkStyle; + + ivec2 pointTexelA = ivec2(pointA); + ivec2 pointTexelB = ivec2(pointB); + + vec4 pointPositionA = texelFetch(positionsTexture, pointTexelA, 0); + vec4 pointPositionB = texelFetch(positionsTexture, pointTexelB, 0); + vec2 a = pointPositionA.xy; + vec2 b = pointPositionB.xy; + + // Skip links touching an absent (NaN position) point — interpolating from a NaN + // endpoint would produce garbage geometry. Collapse the link off-screen. This only + // catches snap removals: an animated removal freezes the endpoint at its last real + // position, so absence must be read from the exit texture below. + if (isnan(a.x) || isnan(a.y) || isnan(b.x) || isnan(b.y)) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Exit status of both endpoints (R = previous absence, G = current absence). A link + // is only as present as its endpoints. + vec4 exitStatusA = texelFetch(exitTexture, pointTexelA, 0); + vec4 exitStatusB = texelFetch(exitTexture, pointTexelB, 0); + + // Picking must not report a link to a removed point even mid-fade — same rule as + // point picking, which excludes on current absence. + if (renderMode > 0.0 && (exitStatusA.g > 0.5 || exitStatusB.g > 0.5)) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Visible pass: fade the link with the same animated exit ramp the point fade uses + // (blend R→G during a position transition, settled G otherwise), so a removed + // point's links fade out in sync with it instead of dangling at full opacity. + float exitA = animatePositions > 0.0 ? mix(exitStatusA.r, exitStatusA.g, transitionProgress) : exitStatusA.g; + float exitB = animatePositions > 0.0 ? mix(exitStatusB.r, exitStatusB.g, transitionProgress) : exitStatusB.g; + float exitPresence = (1.0 - exitA) * (1.0 - exitB); + if (exitPresence <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Sample the source/target point colors so the fragment shader can build a gradient + // along the link. Skipped entirely when the gradient is off — the fragment shader + // only reads these varyings inside its own gradient branch, keyed on the same flag. + // The texture mirrors GraphData.pointColors, so channels may be NaN ("use the + // default") — resolve them with the endpoint's exit ramp, like the point draw. + if (linkColorInterpolateFromEndpoints > 0.5) { + vEndpointColorA = resolveColor(texelFetch(pointColorsTexture, pointTexelA, 0), exitA); + vEndpointColorB = resolveColor(texelFetch(pointColorsTexture, pointTexelB, 0), exitB); + } + + // Calculate direction vector and its perpendicular + vec2 xBasis = b - a; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + + // Calculate link distance and control point for curved link + float linkDist = length(xBasis); + float h = curvedLinkControlPointDistance; + vec2 controlPoint = (a + b) / 2.0 + yBasis * linkDist * h; + + // Convert link distance to screen pixels + float linkDistPx = linkDist * transformationMatrix[0][0]; + + // Dash/dot pattern space. When links keep a constant on-screen size (scaleLinksOnZoom = false) + // the pattern is measured in screen pixels (fixed dash size, but it slides as the link's + // on-screen length changes with zoom). When links scale with zoom it is measured in world units, + // which locks the pattern to the link so it scales with zoom instead of crawling. + float dashUnitScale = scaleLinksOnZoom > 0.0 ? 1.0 : transformationMatrix[0][0]; + vLinkDashSpan = linkDist * dashUnitScale; + + float lineWidthBase = animateWidths > 0.0 + ? mix(sourceWidth, targetWidth, transitionProgress) + : targetWidth; + vec4 lineColor = animateColors > 0.0 + ? mix(sourceColor, targetColor, transitionProgress) + : targetColor; + + // Calculate line width using the width scale + float linkWidth = lineWidthBase * widthScale; + // A width of 0 draws nothing, as a point of size 0 does: culled here, before the hover and + // focus increases and the one-pixel floor could widen an absent link. Not pickable either. + if (linkWidth <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + float k = 2.0; + // Arrow width is proportionally larger than the line width + float arrowWidth = linkWidth * k; + arrowWidth *= linkArrowsSizeScale; + + // Ensure arrow width difference is non-negative to prevent unwanted changes to link width + float arrowWidthDifference = max(0.0, arrowWidth - linkWidth); + + // Calculate arrow width in pixels + float arrowWidthPx = calculateArrowWidth(arrowWidth); + + // Calculate arrow length proportional to its width + // 0.866 is approximately sqrt(3)/2 - related to equilateral triangle geometry + // Cap the length to avoid overly long arrows on short links + arrowLength = min(0.3, (0.866 * arrowWidthPx * 2.0) / linkDist); + + useArrow = arrow; + if (useArrow > 0.5) { + linkWidth += arrowWidthDifference; + } + + arrowWidthFactor = arrowWidthDifference / linkWidth; + + // Calculate final link width in pixels with smoothing + float linkWidthPx = calculateLinkWidth(linkWidth); + + if (renderMode > 0.0) { + // Add 5 pixels padding for better hover detection + linkWidthPx += 5.0 / transformationMatrix[0][0]; + // Match the visible-pass width increases so the pickable area covers the full rendered link + if (hoveredLinkIndex == linkIndex) { + linkWidthPx += hoveredLinkWidthIncrease / transformationMatrix[0][0]; + } + if (focusedLinkIndex == linkIndex) { + linkWidthPx += focusedLinkWidthIncrease / transformationMatrix[0][0]; + } + } else { + // Add pixel increase if this is the hovered link + if (hoveredLinkIndex == linkIndex) { + linkWidthPx += hoveredLinkWidthIncrease / transformationMatrix[0][0]; + } + // Add pixel increase if this is the focused link + if (focusedLinkIndex == linkIndex) { + linkWidthPx += focusedLinkWidthIncrease / transformationMatrix[0][0]; + } + } + // Center a one-ramp-wide fade on each stroke edge. + // Strokes thinner than the ramp use the ramp width with reduced alpha. + // Units: EDGE_RAMP_PX is device px; / pixelRatio → CSS px; / k → world, k = transformationMatrix[0][0] + // (the matrix carries no DPR). Widths are extruded in world space, so unlike gl_PointSize they + // never multiply by pixelRatio. The *Px values below are world units. + float smoothingPx = (EDGE_RAMP_PX / pixelRatio) / transformationMatrix[0][0]; + float thinAlpha = min(linkWidthPx / smoothingPx, 1.0); + float minWidthPx = smoothingPx; + if (linkBlending < 0.5) { + // Unblended strokes cannot be dimmed: the fragment cuts them at the edge instead, and a + // stroke under a device pixel is drawn one pixel wide (its body, when it has an arrowhead). + thinAlpha = 1.0; + float bodyShare = useArrow > 0.5 ? 1.0 - arrowWidthFactor : 1.0; + // One device px → world, the same chain as the ramp. + minWidthPx = (1.0 / pixelRatio) / transformationMatrix[0][0] / bodyShare; + } + linkWidthPx = max(linkWidthPx, minWidthPx) + smoothingPx; + smoothing = smoothingPx / linkWidthPx; + + // Quad width (stroke + ramp) in vLinkDashSpan's pattern-space units; the fragment takes the ramp back off. + vLinkDashWidth = linkWidthPx * dashUnitScale; + + + + // Calculate final color with opacity based on link distance + vec3 rgbColor = lineColor.rgb; + // Adjust opacity based on link distance + float opacity = lineColor.a * linkOpacity * max(linkVisibilityMinTransparency, map(linkDistPx, linkVisibilityDistanceRange.g, linkVisibilityDistanceRange.r, 0.0, 1.0)); + // Fade with the exit ramp of the endpoints (1 = both fully present). + opacity *= exitPresence; + // A stroke drawn at ramp width: alpha scales it back to its true width. + opacity *= thinAlpha; + + // Apply greyed-out status from the link status texture. Blended rendering dims + // greyed links by greyoutOpacity. Unblended rendering hides them instead: alpha is + // ignored at write time, links render opaque and can only overwrite each other, so a + // dimmed link drawn later would cut into highlighted links; collapsing the instance + // also skips its fill cost. Runs in the picking pass too — a hidden link is not + // hoverable, matching what is on screen. + if (isLinkHighlightingActive > 0.0 && linkStatusTextureSize > 0.0) { + int statusTexSize = int(linkStatusTextureSize); + int statusIndex = int(linkIndices); + ivec2 statusTexel = ivec2(statusIndex % statusTexSize, statusIndex / statusTexSize); + vec4 linkStatusValue = texelFetch(linkStatus, statusTexel, 0); + if (linkStatusValue.r > 0.0) { + if (linkBlending < 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + opacity *= greyoutOpacity; + } + } + + // Pass final color to fragment shader. Hover color is applied in the fragment + // shader, after the endpoint gradient, so it wins for gradient links too. + rgbaColor = vec4(rgbColor, opacity); + + // Calculate position on the curved path + float t = position.x; + float w = curvedWeight; + + float tPrev = t - 1.0 / curvedLinkSegments; + float tNext = t + 1.0 / curvedLinkSegments; + + vec2 pointCurr = conicParametricCurve(a, b, controlPoint, t, w); + + vec2 pointPrev = conicParametricCurve(a, b, controlPoint, max(0.0, tPrev), w); + vec2 pointNext = conicParametricCurve(a, b, controlPoint, min(tNext, 1.0), w); + + vec2 xBasisCurved = pointNext - pointPrev; + vec2 yBasisCurved = normalize(vec2(-xBasisCurved.y, xBasisCurved.x)); + + pointCurr += yBasisCurved * linkWidthPx * position.y; + + // Transform to clip space coordinates + vec2 p = 2.0 * pointCurr / spaceSize - 1.0; + p *= spaceSize / screenSize; + + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + gl_Position = vec4(final.rg, 0, 1); +}`,O_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + fragColor = rgba; +} +`,U_=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 pointA; +in vec2 pointB; +in float linkIndices; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform fillSampledLinksUniforms { + mat4 transformationMatrix; + float spaceSize; + vec2 screenSize; + float curvedWeight; + float curvedLinkControlPointDistance; + float curvedLinkSegments; +} fillSampledLinks; + +#define transformationMatrix fillSampledLinks.transformationMatrix +#define spaceSize fillSampledLinks.spaceSize +#define screenSize fillSampledLinks.screenSize +#define curvedWeight fillSampledLinks.curvedWeight +#define curvedLinkControlPointDistance fillSampledLinks.curvedLinkControlPointDistance +#define curvedLinkSegments fillSampledLinks.curvedLinkSegments +#else +uniform float spaceSize; +uniform vec2 screenSize; +uniform float curvedWeight; +uniform float curvedLinkControlPointDistance; +uniform float curvedLinkSegments; +uniform mat3 transformationMatrix; +#endif + +out vec4 rgba; + +void main() { + ivec2 pointTexelA = ivec2(pointA); + ivec2 pointTexelB = ivec2(pointB); + + // Skip a link touching an absent (faded-out) point. exit.G = current absence. + if (texelFetch(exitTexture, pointTexelA, 0).g > 0.5 || + texelFetch(exitTexture, pointTexelB, 0).g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 posA = texelFetch(positionsTexture, pointTexelA, 0); + vec4 posB = texelFetch(positionsTexture, pointTexelB, 0); + vec2 a = posA.rg; + vec2 b = posB.rg; + + vec2 tangent = b - a; + float angle = -atan(tangent.y, tangent.x); + + vec2 mid; + if (curvedLinkSegments <= 1.0) { + mid = (a + b) * 0.5; + } else if (curvedLinkControlPointDistance != 0.0 && curvedWeight != 0.0) { + vec2 xBasis = b - a; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + float linkDist = length(xBasis); + float h = curvedLinkControlPointDistance; + vec2 controlPoint = (a + b) / 2.0 + yBasis * linkDist * h; + mid = conicParametricCurve(a, b, controlPoint, 0.5, curvedWeight); + } else { + mid = (a + b) * 0.5; + } + + vec2 p = 2.0 * mid / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + vec2 pointScreenPosition = (final.xy + 1.0) * screenSize / 2.0; + rgba = vec4(linkIndices, mid.x, mid.y, angle); + float i = (pointScreenPosition.x + 0.5) / screenSize.x; + float j = (pointScreenPosition.y + 0.5) / screenSize.y; + gl_Position = vec4(2.0 * vec2(i, j) - 1.0, 0.0, 1.0); + + gl_PointSize = 1.0; +} +`;class dr{constructor(t,i){this.buffer=null,this.sync=null,this.isInFlight=!1,this.gl=t,this.data=new Float32Array(i)}get inFlight(){return this.isInFlight}issue(t,i,n,r,s){if(this.isInFlight)return!1;const{gl:o}=this;if(r*s*4>this.data.length||(this.buffer||(this.buffer=o.createBuffer()),!this.buffer))return!1;const a=o.getParameter(o.READ_FRAMEBUFFER_BINDING);return o.bindFramebuffer(o.READ_FRAMEBUFFER,t),o.bindBuffer(o.PIXEL_PACK_BUFFER,this.buffer),o.bufferData(o.PIXEL_PACK_BUFFER,this.data.byteLength,o.STREAM_READ),o.readPixels(i,n,r,s,o.RGBA,o.FLOAT,0),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),o.bindFramebuffer(o.READ_FRAMEBUFFER,a),this.sync=o.fenceSync(o.SYNC_GPU_COMMANDS_COMPLETE,0),o.flush(),this.isInFlight=this.sync!==null,this.isInFlight}poll(){if(!this.isInFlight||!this.sync||!this.buffer)return null;const{gl:t}=this,i=t.clientWaitSync(this.sync,0,0);return i===t.TIMEOUT_EXPIRED||(t.deleteSync(this.sync),this.sync=null,this.isInFlight=!1,i!==t.ALREADY_SIGNALED&&i!==t.CONDITION_SATISFIED)?null:(t.bindBuffer(t.PIXEL_PACK_BUFFER,this.buffer),t.getBufferSubData(t.PIXEL_PACK_BUFFER,0,this.data),t.bindBuffer(t.PIXEL_PACK_BUFFER,null),this.data)}cancel(){this.sync&&(this.gl.deleteSync(this.sync),this.sync=null),this.isInFlight=!1}destroy(){this.cancel(),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null)}}const ko=.5,z_=1536,Fe=9;function L_(e,t){if(e.length!==t.length)return!1;for(const[i,n]of e.entries())if(n!==t[i])return!1;return!0}function W_(e,t){const i=Math.min(ko,z_/Math.max(e,t));return{width:Math.max(Fe,Math.ceil(e*i)),height:Math.max(Fe,Math.ceil(t*i))}}function V_(e,t,i,n,r,s){const o=i*(e/r),a=n*(t/s),l=Math.floor(Fe/2),c=Math.min(Math.max(Math.round(o)-l,0),e-Fe),u=Math.min(Math.max(Math.round(a)-l,0),t-Fe);return{x:c,y:u,centerX:o,centerY:a}}function Lu(e){const t=e[0];return e[3]>0&&t>=0?t:void 0}function Wu(e,t,i){let n=-1,r=[0,0],s=1/0;for(let o=0;o<Fe;o+=1)for(let a=0;a<Fe;a+=1){const l=(o*Fe+a)*4,c=e[l];if(c<0)continue;const u=a+.5-t,d=o+.5-i,h=u*u+d*d;h<s&&(s=h,n=c,r=[e[l+1],e[l+2]])}if(!(n<0))return{index:n,position:r}}const H_=e=>{const t=Vl().exponent(2).range([0,1]).domain([-1,1]),i=km(0,e).map(r=>-.5+r/e);i.push(.5);const n=new Array(i.length*2);return i.forEach((r,s)=>{n[s*2]=[t(r*2),.5],n[s*2+1]=[t(r*2),-.5]}),n};function ji(e){const t=new Float32Array(e*e*2);for(let i=0;i<e;i++)for(let n=0;n<e;n++){const r=i*e*2+n*2;t[r+0]=n,t[r+1]=i}return t}function Vu(e,t,i){return!t||t.byteLength!==i.byteLength?(t&&!t.destroyed&&t.destroy(),e.createBuffer({data:i,usage:B.VERTEX|B.COPY_DST})):(t.write(i),t)}function hr(e,t,i,n,r,s){const o=r?r.length/s:0,a=t.length/s;if(o===a&&i&&!i.destroyed&&n&&!n.destroyed){const d=n,h=i;return h.write(t),{source:d,target:h,previous:new Float32Array(t),sourceData:r??new Float32Array(t)}}const c=new Float32Array(t.length),u=Math.min(o,a);for(let d=0;d<u*s;d+=1)c[d]=(r==null?void 0:r[d])??t[d]??0;for(let d=u*s;d<t.length;d+=1)c[d]=t[d]??0;return i&&!i.destroyed&&i.destroy(),n&&!n.destroyed&&n.destroy(),{source:e.createBuffer({data:c,usage:B.VERTEX|B.COPY_DST}),target:e.createBuffer({data:t,usage:B.VERTEX|B.COPY_DST}),previous:new Float32Array(t),sourceData:c}}function q(e,t){const i=Ve.getInfo(e);return t*(i.bytesPerPixel??0)}function ie(e,t){return!e||e.length!==2?t:[e[0],e[1]]}function ge(e,t){return!e||e.length!==4?t:[e[0],e[1],e[2],e[3]]}const li=e=>Number.isInteger(e)?e.toFixed(1):String(e);class $_ extends gt{constructor(){super(...arguments),this.isLinkIndexBufferStale=!0,this.linkStatusTextureSize=0,this.transitionProgress=1,this.shouldAnimateLinkColors=!1,this.shouldAnimateLinkWidths=!1,this.shouldAnimatePositions=!1}get hasPendingPickReadback(){var t;return((t=this.pickingReadback)==null?void 0:t.inFlight)??!1}initPrograms(){const{device:t,config:i,store:n,data:r}=this;this.updateLinkIndexFbo(),this.isLinkIndexBufferStale=!0,this.curveLineGeometry||this.updateCurveLineGeometry();const s=this.data.linksNumber??0;this.pointABuffer||(this.pointABuffer=t.createBuffer({data:new Float32Array(s*2),usage:B.VERTEX|B.COPY_DST})),this.pointBBuffer||(this.pointBBuffer=t.createBuffer({data:new Float32Array(s*2),usage:B.VERTEX|B.COPY_DST})),this.arrowBuffer||(this.arrowBuffer=t.createBuffer({data:new Float32Array(s),usage:B.VERTEX|B.COPY_DST})),this.linkStyleBuffer||(this.linkStyleBuffer=t.createBuffer({data:new Float32Array(s),usage:B.VERTEX|B.COPY_DST})),this.linkIndexBuffer||(this.linkIndexBuffer=t.createBuffer({data:new Float32Array(s),usage:B.VERTEX|B.COPY_DST})),this.drawLineUniformStore||(this.drawLineUniformStore=new oe(t,{drawLineUniforms:{uniformTypes:{transformationMatrix:"mat4x4<f32>",widthScale:"f32",linkArrowsSizeScale:"f32",spaceSize:"f32",screenSize:"vec2<f32>",linkVisibilityDistanceRange:"vec2<f32>",linkVisibilityMinTransparency:"f32",linkOpacity:"f32",greyoutOpacity:"f32",curvedWeight:"f32",curvedLinkControlPointDistance:"f32",curvedLinkSegments:"f32",scaleLinksOnZoom:"f32",maxPointSize:"f32",renderMode:"f32",hoveredLinkIndex:"f32",hoveredLinkWidthIncrease:"f32",isLinkHighlightingActive:"f32",linkStatusTextureSize:"f32",focusedLinkIndex:"f32",focusedLinkWidthIncrease:"f32",transitionProgress:"f32",animateColors:"f32",animateWidths:"f32",animatePositions:"f32",pointDefaultColor:"vec4<f32>",linkColorInterpolateFromEndpoints:"f32",linkBlending:"f32",pixelRatio:"f32"},defaultUniforms:{transformationMatrix:n.transformationMatrix4x4,widthScale:i.linkWidthScale,linkArrowsSizeScale:i.linkArrowsSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),linkVisibilityDistanceRange:ie(i.linkVisibilityDistanceRange,[0,0]),linkVisibilityMinTransparency:i.linkVisibilityMinTransparency,linkOpacity:i.linkOpacity,greyoutOpacity:i.linkGreyoutOpacity,curvedWeight:i.curvedLinkWeight,curvedLinkControlPointDistance:i.curvedLinkControlPointDistance,curvedLinkSegments:i.curvedLinks?i.curvedLinkSegments:1,scaleLinksOnZoom:i.scaleLinksOnZoom?1:0,maxPointSize:n.maxPointSize,renderMode:0,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkWidthIncrease:i.hoveredLinkWidthIncrease,isLinkHighlightingActive:0,linkStatusTextureSize:0,focusedLinkIndex:i.focusedLinkIndex??-1,focusedLinkWidthIncrease:i.focusedLinkWidthIncrease,transitionProgress:1,animateColors:0,animateWidths:0,animatePositions:0,pointDefaultColor:ge(We(i.pointDefaultColor),[0,0,0,1]),linkColorInterpolateFromEndpoints:i.linkColorInterpolateFromEndpoints?1:0,linkBlending:i.linkBlending?1:0,pixelRatio:i.pixelRatio}},drawLineFragmentUniforms:{uniformTypes:{renderMode:"f32",linkDashLength:"f32",linkDashGap:"f32",linkColorInterpolateFromEndpoints:"f32",hoveredLinkIndex:"f32",hoveredLinkColor:"vec4<f32>",linkBlending:"f32",pickingAlpha:"f32",pickingIndexOffset:"f32"},defaultUniforms:{pickingAlpha:1,pickingIndexOffset:0,renderMode:0,linkDashLength:i.linkDashLength,linkDashGap:i.linkDashGap,linkColorInterpolateFromEndpoints:i.linkColorInterpolateFromEndpoints?1:0,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkColor:ge(n.hoveredLinkColor,[-1,-1,-1,-1]),linkBlending:i.linkBlending?1:0}}})),this.drawCurveCommand||(this.drawCurveCommand=this.createDrawCurveCommand(this.getLinkBlendParameters(this.config.linkBlending))),this.isLinkBlendingActive=this.config.linkBlending,this.fillSampledLinksUniformStore||(this.fillSampledLinksUniformStore=new oe(t,{fillSampledLinksUniforms:{uniformTypes:{transformationMatrix:"mat4x4<f32>",spaceSize:"f32",screenSize:"vec2<f32>",curvedWeight:"f32",curvedLinkControlPointDistance:"f32",curvedLinkSegments:"f32"},defaultUniforms:{transformationMatrix:n.transformationMatrix4x4,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),curvedWeight:i.curvedLinkWeight,curvedLinkControlPointDistance:i.curvedLinkControlPointDistance,curvedLinkSegments:i.curvedLinks?i.curvedLinkSegments:1}}})),this.fillSampledLinksFboCommand||(this.fillSampledLinksFboCommand=new ee(t,{fs:O_,vs:U_,modules:[zu],topology:"point-list",vertexCount:r.linksNumber??0,attributes:{...this.pointABuffer&&{pointA:this.pointABuffer},...this.pointBBuffer&&{pointB:this.pointBBuffer},...this.linkIndexBuffer&&{linkIndices:this.linkIndexBuffer}},bufferLayout:[{name:"pointA",format:"float32x2"},{name:"pointB",format:"float32x2"},{name:"linkIndices",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{fillSampledLinksUniforms:this.fillSampledLinksUniformStore.getManagedUniformBuffer("fillSampledLinksUniforms")},parameters:te})),this.updateSampledLinksGrid(),this.updateLinkStatus()}drawPicking(t,i,n=0){var o;const{points:r}=this;if(!r||!r.currentPositionTexture||r.currentPositionTexture.destroyed||(r.exitTexture||r.updateExit(),!r.exitTexture||r.exitTexture.destroyed)||((!this.pointABuffer||!this.pointBBuffer)&&this.updatePointsBuffer(),this.targetColorBuffer||this.updateColor(),this.targetWidthBuffer||this.updateWidth(),this.arrowBuffer||this.updateArrow(),this.linkStyleBuffer||this.updateStyle(),this.curveLineGeometry||this.updateCurveLineGeometry(),!this.drawLineUniformStore||!this.linkStatusTexture)||!this.data.linksNumber)return;this.drawPickingCommand||(this.drawPickingCommand=this.createDrawCurveCommand(te)),this.drawPickingCommand.setAttributes(this.getDrawCurveCommandAttributes()),this.drawPickingCommand.setVertexCount(((o=this.curveLineGeometry)==null?void 0:o.length)??0);const s=this.getDrawUniforms();this.drawLineUniformStore.setUniforms({drawLineUniforms:{...s.drawLineUniforms,renderMode:3},drawLineFragmentUniforms:{...s.drawLineFragmentUniforms,renderMode:3,pickingAlpha:i,pickingIndexOffset:n}}),this.drawPickingCommand.setBindings(this.getDrawBindings(r)),this.drawPickingCommand.setInstanceCount(this.data.linksNumber),this.drawPickingCommand.draw(t)}draw(t){const{points:i}=this;i&&(!i.currentPositionTexture||i.currentPositionTexture.destroyed||(i.exitTexture||i.updateExit(),!(!i.exitTexture||i.exitTexture.destroyed)&&((!this.pointABuffer||!this.pointBBuffer)&&this.updatePointsBuffer(),this.targetColorBuffer||this.updateColor(),this.targetWidthBuffer||this.updateWidth(),this.arrowBuffer||this.updateArrow(),this.linkStyleBuffer||this.updateStyle(),this.curveLineGeometry||this.updateCurveLineGeometry(),!(!this.drawCurveCommand||!this.drawLineUniformStore||!this.linkStatusTexture)&&(this.updateLinkBlending(),this.drawLineUniformStore.setUniforms(this.getDrawUniforms()),this.drawCurveCommand.setBindings(this.getDrawBindings(i)),this.drawCurveCommand.setInstanceCount(this.data.linksNumber??0),this.drawCurveCommand.draw(t)))))}updateLinkIndexFbo(){var a,l,c;const{device:t,store:i}=this;if(!this.store.isLinkHoveringEnabled)return;const n=i.screenSize??[0,0],r=n[0],s=n[1];if(!r||!s)return;const o=((a=this.previousScreenSize)==null?void 0:a[0])!==r||((l=this.previousScreenSize)==null?void 0:l[1])!==s;(!this.linkIndexTexture||o)&&((c=this.pickingReadback)==null||c.cancel(),this.linkIndexFbo&&!this.linkIndexFbo.destroyed&&this.linkIndexFbo.destroy(),this.linkIndexTexture&&!this.linkIndexTexture.destroyed&&this.linkIndexTexture.destroy(),this.linkIndexTexture=t.createTexture({width:r,height:s,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.linkIndexTexture.copyImageData({data:new Float32Array(r*s*4).fill(0),bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),this.linkIndexFbo=t.createFramebuffer({width:r,height:s,colorAttachments:[this.linkIndexTexture]}),this.previousScreenSize=[r,s],this.isLinkIndexBufferStale=!0)}updateSampledLinksGrid(){const{store:{screenSize:t},config:{linkSamplingDistance:i},device:n}=this;let r=i??Math.min(...t)/2;r===0&&(r=Ze.linkSamplingDistance);const s=Math.ceil(t[0]/r),o=Math.ceil(t[1]/r);s===0||o===0||(!this.sampledLinksFbo||this.sampledLinksFbo.width!==s||this.sampledLinksFbo.height!==o)&&(this.sampledLinksFbo&&!this.sampledLinksFbo.destroyed&&this.sampledLinksFbo.destroy(),this.sampledLinksFbo=n.createFramebuffer({width:s,height:o,colorAttachments:["rgba32float"]}))}updatePointsBuffer(){var l;const{device:t,data:i,store:n}=this;if(i.linksNumber===void 0||i.links===void 0||!n.pointsTextureSize)return;this.isLinkIndexBufferStale=!0,this.discardPendingPick();const r=new Float32Array(i.linksNumber*2),s=new Float32Array(i.linksNumber*2);for(let c=0;c<i.linksNumber;c++){const u=i.links[c*2],d=i.links[c*2+1],h=i.isPointIndex(u)&&i.isPointIndex(d),p=h?u:0,g=h?d:0,x=p%n.pointsTextureSize,T=Math.floor(p/n.pointsTextureSize),S=g%n.pointsTextureSize,P=Math.floor(g/n.pointsTextureSize);r[c*2]=x,r[c*2+1]=T,s[c*2]=S,s[c*2+1]=P}const o=(((l=this.pointABuffer)==null?void 0:l.byteLength)??0)/(Float32Array.BYTES_PER_ELEMENT*2);!this.pointABuffer||o!==i.linksNumber?(this.pointABuffer&&!this.pointABuffer.destroyed&&this.pointABuffer.destroy(),this.pointABuffer=t.createBuffer({data:r,usage:B.VERTEX|B.COPY_DST})):this.pointABuffer.write(r),!this.pointBBuffer||o!==i.linksNumber?(this.pointBBuffer&&!this.pointBBuffer.destroyed&&this.pointBBuffer.destroy(),this.pointBBuffer=t.createBuffer({data:s,usage:B.VERTEX|B.COPY_DST})):this.pointBBuffer.write(s);const a=new Float32Array(i.linksNumber);for(let c=0;c<i.linksNumber;c++)a[c]=c;!this.linkIndexBuffer||o!==i.linksNumber?(this.linkIndexBuffer&&!this.linkIndexBuffer.destroyed&&this.linkIndexBuffer.destroy(),this.linkIndexBuffer=t.createBuffer({data:a,usage:B.VERTEX|B.COPY_DST})):this.linkIndexBuffer.write(a),this.setDrawCurveCommandAttributes({pointA:this.pointABuffer,pointB:this.pointBBuffer,linkIndices:this.linkIndexBuffer}),this.fillSampledLinksFboCommand&&this.fillSampledLinksFboCommand.setAttributes({pointA:this.pointABuffer,pointB:this.pointBBuffer,linkIndices:this.linkIndexBuffer}),this.updateSampledLinksGrid(),this.config.highlightedLinkIndices!==void 0&&this.updateLinkStatus()}updateColor(){const{data:t}=this,i=t.linksNumber??0;this.isLinkIndexBufferStale=!0;const n=t.linkColors??new Float32Array(i*4).fill(0),{source:r,target:s,previous:o}=hr(this.device,n,this.sourceColorBuffer,this.targetColorBuffer,this.previousColorData,4);this.sourceColorBuffer=r,this.targetColorBuffer=s,this.previousColorData=o,this.setDrawCurveCommandAttributes({...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer}})}updateWidth(){const{data:t}=this,i=t.linksNumber??0;this.isLinkIndexBufferStale=!0;const n=t.linkWidths??new Float32Array(i).fill(0),{source:r,target:s,previous:o,sourceData:a}=hr(this.device,n,this.sourceWidthBuffer,this.targetWidthBuffer,this.previousWidthData,1);this.sourceWidthBuffer=r,this.targetWidthBuffer=s,this.previousWidthData=o,this.sourceWidthData=a,this.setDrawCurveCommandAttributes({...this.sourceWidthBuffer&&{sourceWidth:this.sourceWidthBuffer},...this.targetWidthBuffer&&{targetWidth:this.targetWidthBuffer}})}updateArrow(){const{device:t,data:i}=this;this.isLinkIndexBufferStale=!0;const n=i.linksNumber??0,r=i.linkArrows?new Float32Array(i.linkArrows):new Float32Array(n);this.arrowBuffer=Vu(t,this.arrowBuffer,r),this.setDrawCurveCommandAttributes({arrow:this.arrowBuffer})}updateStyle(){const{device:t,data:i}=this;i.linksNumber===void 0||i.linkStyles===void 0||(this.linkStyleBuffer=Vu(t,this.linkStyleBuffer,i.linkStyles),this.setDrawCurveCommandAttributes({linkStyle:this.linkStyleBuffer}))}updateLinkStatus(){const{device:t,config:i,data:n}=this,r=n.linksNumber??0;if(this.isLinkIndexBufferStale=!0,!r){this.linkStatusTexture||this.ensureLinkStatusPlaceholder();return}const{highlightedLinkIndices:s}=i;if(s===void 0){this.linkStatusTexture||this.ensureLinkStatusPlaceholder(),this.linkStatusTextureSize=0;return}const o=Math.ceil(Math.sqrt(r));this.linkStatusTextureSize=o;const a=new Float32Array(o*o*4);for(let c=0;c<r;c++)a[c*4]=1;for(const c of s)c>=0&&c<r&&(a[c*4]=0);const l={data:a,bytesPerRow:q("rgba32float",o),mipLevel:0,x:0,y:0};!this.linkStatusTexture||this.linkStatusTexture.width!==o||this.linkStatusTexture.height!==o?(this.linkStatusTexture&&!this.linkStatusTexture.destroyed&&this.linkStatusTexture.destroy(),this.linkStatusTexture=t.createTexture({width:o,height:o,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.linkStatusTexture.copyImageData(l)):this.linkStatusTexture.copyImageData(l)}updateCurveLineGeometry(){var s,o;const{device:t,config:{curvedLinks:i,curvedLinkSegments:n}}=this;this.isLinkIndexBufferStale=!0,this.curveLineGeometry=H_(i?n:1);const r=new Float32Array(this.curveLineGeometry.length*2);for(let a=0;a<this.curveLineGeometry.length;a++)r[a*2]=this.curveLineGeometry[a][0],r[a*2+1]=this.curveLineGeometry[a][1];!this.curveLineBuffer||this.curveLineBuffer.byteLength!==r.byteLength?(this.curveLineBuffer&&!this.curveLineBuffer.destroyed&&this.curveLineBuffer.destroy(),this.curveLineBuffer=t.createBuffer({data:r,usage:B.VERTEX|B.COPY_DST})):this.curveLineBuffer.write(r),this.setDrawCurveCommandAttributes({position:this.curveLineBuffer}),(s=this.drawCurveCommand)==null||s.setVertexCount(this.curveLineGeometry.length),(o=this.drawCurvePickingCommand)==null||o.setVertexCount(this.curveLineGeometry.length)}updateLinkBlending(){var i;const t=this.config.linkBlending;t!==this.isLinkBlendingActive&&((i=this.drawCurveCommand)==null||i.setParameters(this.getLinkBlendParameters(t)),this.isLinkBlendingActive=t,this.isLinkIndexBufferStale=!0)}getSampledLinkPositionsMap(){const t=new Map;if(!this.sampledLinksFbo||this.sampledLinksFbo.destroyed)return t;const i=this.points;if(!(i!=null&&i.currentPositionTexture)||i.currentPositionTexture.destroyed||!i.exitTexture||i.exitTexture.destroyed)return t;if(this.fillSampledLinksFboCommand&&this.fillSampledLinksUniformStore&&this.sampledLinksFbo){this.fillSampledLinksFboCommand.setVertexCount(this.data.linksNumber??0),this.fillSampledLinksUniformStore.setUniforms({fillSampledLinksUniforms:{transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),curvedWeight:this.config.curvedLinkWeight,curvedLinkControlPointDistance:this.config.curvedLinkControlPointDistance,curvedLinkSegments:this.config.curvedLinks?this.config.curvedLinkSegments:1}}),this.fillSampledLinksFboCommand.setBindings({positionsTexture:i.currentPositionTexture,exitTexture:i.exitTexture});const r=this.device.beginRenderPass({framebuffer:this.sampledLinksFbo,clearColor:[-1,-1,-1,-1]});this.fillSampledLinksFboCommand.draw(r),r.end()}const n=we(this.device,this.sampledLinksFbo);for(let r=0;r<n.length/4;r++){const s=n[r*4],o=n[r*4+1],a=n[r*4+2],l=n[r*4+3];s!==void 0&&s>=0&&o!==void 0&&a!==void 0&&l!==void 0&&t.set(Math.round(s),[o,a,l])}return t}getSampledLinks(){const t=[],i=[],n=[];if(!this.sampledLinksFbo||this.sampledLinksFbo.destroyed)return{indices:t,positions:i,angles:n};const r=this.points;if(!(r!=null&&r.currentPositionTexture)||r.currentPositionTexture.destroyed)return{indices:t,positions:i,angles:n};if(!r.exitTexture||r.exitTexture.destroyed)return{indices:t,positions:i,angles:n};if(this.fillSampledLinksFboCommand&&this.fillSampledLinksUniformStore&&this.sampledLinksFbo){this.fillSampledLinksFboCommand.setVertexCount(this.data.linksNumber??0),this.fillSampledLinksUniformStore.setUniforms({fillSampledLinksUniforms:{transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),curvedWeight:this.config.curvedLinkWeight,curvedLinkControlPointDistance:this.config.curvedLinkControlPointDistance,curvedLinkSegments:this.config.curvedLinks?this.config.curvedLinkSegments:1}}),this.fillSampledLinksFboCommand.setBindings({positionsTexture:r.currentPositionTexture,exitTexture:r.exitTexture});const o=this.device.beginRenderPass({framebuffer:this.sampledLinksFbo,clearColor:[-1,-1,-1,-1]});this.fillSampledLinksFboCommand.draw(o),o.end()}const s=we(this.device,this.sampledLinksFbo);for(let o=0;o<s.length/4;o++){const a=s[o*4],l=s[o*4+1],c=s[o*4+2],u=s[o*4+3];a!==void 0&&a>=0&&l!==void 0&&c!==void 0&&u!==void 0&&(t.push(Math.round(a)),i.push(l,c),n.push(u))}return{indices:t,positions:i,angles:n}}updateLinkIndexBuffer(){if(!this.isLinkIndexBufferStale)return;this.updateLinkIndexFbo();const{config:t,points:i,store:n}=this;if(!i||!i.currentPositionTexture||i.currentPositionTexture.destroyed||(i.exitTexture||i.updateExit(),!i.exitTexture||i.exitTexture.destroyed)||!this.data.linksNumber||!this.store.isLinkHoveringEnabled||!this.linkIndexFbo||!this.drawLineUniformStore||!this.linkStatusTexture||!this.linkIndexTexture||this.linkIndexTexture.destroyed)return;this.drawCurvePickingCommand||(this.drawCurvePickingCommand=this.createDrawCurveCommand(this.getLinkBlendParameters(!1)));const r=t.highlightedLinkIndices!==void 0;this.drawLineUniformStore.setUniforms({drawLineUniforms:{transformationMatrix:n.transformationMatrix4x4,widthScale:t.linkWidthScale,linkArrowsSizeScale:t.linkArrowsSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),linkVisibilityDistanceRange:ie(t.linkVisibilityDistanceRange,[0,0]),linkVisibilityMinTransparency:t.linkVisibilityMinTransparency,linkOpacity:t.linkOpacity,greyoutOpacity:t.linkGreyoutOpacity,curvedWeight:t.curvedLinkWeight,curvedLinkControlPointDistance:t.curvedLinkControlPointDistance,curvedLinkSegments:t.curvedLinks?t.curvedLinkSegments:1,scaleLinksOnZoom:t.scaleLinksOnZoom?1:0,maxPointSize:n.maxPointSize,renderMode:1,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkWidthIncrease:t.hoveredLinkWidthIncrease,isLinkHighlightingActive:r?1:0,linkStatusTextureSize:this.linkStatusTextureSize,focusedLinkIndex:t.focusedLinkIndex??-1,focusedLinkWidthIncrease:t.focusedLinkWidthIncrease,transitionProgress:this.transitionProgress,animateColors:this.shouldAnimateLinkColors?1:0,animateWidths:this.shouldAnimateLinkWidths?1:0,animatePositions:this.shouldAnimatePositions?1:0,pointDefaultColor:ge(this.data.defaultRgba,[0,0,0,1]),linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,linkBlending:t.linkBlending?1:0,pixelRatio:t.pixelRatio},drawLineFragmentUniforms:{renderMode:1,linkDashLength:t.linkDashLength,linkDashGap:t.linkDashGap,linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,hoveredLinkIndex:n.hoveredLinkIndex??-1,hoveredLinkColor:ge(n.hoveredLinkColor,[-1,-1,-1,-1]),linkBlending:t.linkBlending?1:0}}),this.drawCurvePickingCommand.setBindings({positionsTexture:i.currentPositionTexture,linkStatus:this.linkStatusTexture,exitTexture:i.exitTexture,pointColorsTexture:i.pointColorsTexture??i.currentPositionTexture}),this.drawCurvePickingCommand.setInstanceCount(this.data.linksNumber??0);const s=this.device.beginRenderPass({framebuffer:this.linkIndexFbo,clearColor:[0,0,0,0]});this.drawCurvePickingCommand.draw(s),s.end(),this.isLinkIndexBufferStale=!1}pickLinkSync(){this.updateLinkIndexBuffer();const t=this.getCursorPickingPixel();if(!t||!this.linkIndexFbo||this.linkIndexFbo.destroyed)return;const i=we(this.device,this.linkIndexFbo,t.x,t.y,1,1);return Lu(i)}requestPickLink(){var r;if((r=this.pickingReadback)!=null&&r.inFlight)return!1;if(this.updateLinkIndexBuffer(),!this.linkIndexFbo||this.linkIndexFbo.destroyed)return!0;const t=this.device.gl,i=this.linkIndexFbo.handle;if(!t||!i)return!0;this.pickingReadback||(this.pickingReadback=new dr(t,4));const n=this.getCursorPickingPixel();return n?this.pickingReadback.issue(i,n.x,n.y,1,1):!0}discardPendingPick(){var t;(t=this.pickingReadback)==null||t.cancel()}takePickLinkResult(){if(!this.pickingReadback)return;const t=this.pickingReadback.poll();if(t)return Lu(t)??null}getAnimatedWidth(t,i){var s,o;const n=((s=this.data.linkWidths)==null?void 0:s[t])??this.config.linkDefaultWidth,r=(o=this.sourceWidthData)==null?void 0:o[t];return r===void 0?n:r+(n-r)*i}setTransitionProgress(t,i=!1,n=!1,r=!1){t!==this.transitionProgress&&(i||n||r)&&(this.isLinkIndexBufferStale=!0),this.transitionProgress=t,this.shouldAnimateLinkColors=i,this.shouldAnimateLinkWidths=n,this.shouldAnimatePositions=r}destroy(){var t,i,n,r,s,o,a;(t=this.drawCurveCommand)==null||t.destroy(),this.drawCurveCommand=void 0,(i=this.drawPickingCommand)==null||i.destroy(),this.drawPickingCommand=void 0,(n=this.drawCurvePickingCommand)==null||n.destroy(),this.drawCurvePickingCommand=void 0,this.isLinkBlendingActive=void 0,(r=this.fillSampledLinksFboCommand)==null||r.destroy(),this.fillSampledLinksFboCommand=void 0,(s=this.pickingReadback)==null||s.destroy(),this.pickingReadback=void 0,this.linkIndexFbo&&!this.linkIndexFbo.destroyed&&this.linkIndexFbo.destroy(),this.linkIndexFbo=void 0,this.sampledLinksFbo&&!this.sampledLinksFbo.destroyed&&this.sampledLinksFbo.destroy(),this.sampledLinksFbo=void 0,this.linkIndexTexture&&!this.linkIndexTexture.destroyed&&this.linkIndexTexture.destroy(),this.linkIndexTexture=void 0,this.linkStatusTexture&&!this.linkStatusTexture.destroyed&&this.linkStatusTexture.destroy(),this.linkStatusTexture=void 0,(o=this.drawLineUniformStore)==null||o.destroy(),this.drawLineUniformStore=void 0,(a=this.fillSampledLinksUniformStore)==null||a.destroy(),this.fillSampledLinksUniformStore=void 0,this.pointABuffer&&!this.pointABuffer.destroyed&&this.pointABuffer.destroy(),this.pointABuffer=void 0,this.pointBBuffer&&!this.pointBBuffer.destroyed&&this.pointBBuffer.destroy(),this.pointBBuffer=void 0,this.sourceColorBuffer&&!this.sourceColorBuffer.destroyed&&this.sourceColorBuffer.destroy(),this.sourceColorBuffer=void 0,this.targetColorBuffer&&!this.targetColorBuffer.destroyed&&this.targetColorBuffer.destroy(),this.targetColorBuffer=void 0,this.previousColorData=void 0,this.sourceWidthBuffer&&!this.sourceWidthBuffer.destroyed&&this.sourceWidthBuffer.destroy(),this.sourceWidthBuffer=void 0,this.targetWidthBuffer&&!this.targetWidthBuffer.destroyed&&this.targetWidthBuffer.destroy(),this.targetWidthBuffer=void 0,this.previousWidthData=void 0,this.sourceWidthData=void 0,this.arrowBuffer&&!this.arrowBuffer.destroyed&&this.arrowBuffer.destroy(),this.arrowBuffer=void 0,this.linkStyleBuffer&&!this.linkStyleBuffer.destroyed&&this.linkStyleBuffer.destroy(),this.linkStyleBuffer=void 0,this.curveLineBuffer&&!this.curveLineBuffer.destroyed&&this.curveLineBuffer.destroy(),this.curveLineBuffer=void 0,this.linkIndexBuffer&&!this.linkIndexBuffer.destroyed&&this.linkIndexBuffer.destroy(),this.linkIndexBuffer=void 0}getCursorPickingPixel(){if(!this.linkIndexFbo||this.linkIndexFbo.destroyed)return;const[t,i]=this.store.screenSize;if(!t||!i)return;const n=Math.floor(this.store.screenMousePosition[0]*(this.linkIndexFbo.width/t)),r=Math.floor(this.store.screenMousePosition[1]*(this.linkIndexFbo.height/i));return{x:Math.min(Math.max(n,0),this.linkIndexFbo.width-1),y:Math.min(Math.max(r,0),this.linkIndexFbo.height-1)}}createDrawCurveCommand(t){var i;if(!this.drawLineUniformStore)throw new Error("Draw line uniforms must be initialized before creating link draw commands");return new ee(this.device,{vs:B_,fs:N_,modules:[zu,ur],topology:"triangle-strip",vertexCount:((i=this.curveLineGeometry)==null?void 0:i.length)??0,attributes:this.getDrawCurveCommandAttributes(),bufferLayout:[{name:"position",format:"float32x2"},{name:"pointA",format:"float32x2",stepMode:"instance"},{name:"pointB",format:"float32x2",stepMode:"instance"},{name:"sourceColor",format:"float32x4",stepMode:"instance"},{name:"targetColor",format:"float32x4",stepMode:"instance"},{name:"sourceWidth",format:"float32",stepMode:"instance"},{name:"targetWidth",format:"float32",stepMode:"instance"},{name:"arrow",format:"float32",stepMode:"instance"},{name:"linkIndices",format:"float32",stepMode:"instance"},{name:"linkStyle",format:"float32",stepMode:"instance"}],defines:{USE_UNIFORM_BUFFERS:!0,EXIT_DEFAULT_COLOR_CHANNEL:li(Xn),EDGE_RAMP_PX:li(Us)},bindings:{drawLineUniforms:this.drawLineUniformStore.getManagedUniformBuffer("drawLineUniforms"),drawLineFragmentUniforms:this.drawLineUniformStore.getManagedUniformBuffer("drawLineFragmentUniforms")},parameters:t})}getDrawCurveCommandAttributes(){const t={};return this.curveLineBuffer&&(t.position=this.curveLineBuffer),this.pointABuffer&&(t.pointA=this.pointABuffer),this.pointBBuffer&&(t.pointB=this.pointBBuffer),this.sourceColorBuffer&&(t.sourceColor=this.sourceColorBuffer),this.targetColorBuffer&&(t.targetColor=this.targetColorBuffer),this.sourceWidthBuffer&&(t.sourceWidth=this.sourceWidthBuffer),this.targetWidthBuffer&&(t.targetWidth=this.targetWidthBuffer),this.arrowBuffer&&(t.arrow=this.arrowBuffer),this.linkIndexBuffer&&(t.linkIndices=this.linkIndexBuffer),this.linkStyleBuffer&&(t.linkStyle=this.linkStyleBuffer),t}setDrawCurveCommandAttributes(t){var i,n;(i=this.drawCurveCommand)==null||i.setAttributes(t),(n=this.drawCurvePickingCommand)==null||n.setAttributes(t)}getLinkBlendParameters(t){const i={...te,cullMode:"back"};return t?{...i,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"src-alpha",blendColorDstFactor:"one-minus-src-alpha",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one-minus-src-alpha"}:{...i,blend:!1}}ensureLinkStatusPlaceholder(){this.linkStatusTexture&&!this.linkStatusTexture.destroyed||(this.linkStatusTexture=this.device.createTexture({width:1,height:1,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST,data:new Float32Array(4).fill(0)}),this.linkStatusTextureSize=0)}getDrawUniforms(){const{config:t,store:i}=this,n=t.highlightedLinkIndices!==void 0,r=i.hostHoveredLinkIndex??i.hoveredLinkIndex??-1;return{drawLineUniforms:{transformationMatrix:i.transformationMatrix4x4,widthScale:t.linkWidthScale,linkArrowsSizeScale:t.linkArrowsSizeScale,spaceSize:i.adjustedSpaceSize,screenSize:ie(i.screenSize,[0,0]),linkVisibilityDistanceRange:ie(t.linkVisibilityDistanceRange,[0,0]),linkVisibilityMinTransparency:t.linkVisibilityMinTransparency,linkOpacity:t.linkOpacity,greyoutOpacity:t.linkGreyoutOpacity,curvedWeight:t.curvedLinkWeight,curvedLinkControlPointDistance:t.curvedLinkControlPointDistance,curvedLinkSegments:t.curvedLinks?t.curvedLinkSegments:1,scaleLinksOnZoom:t.scaleLinksOnZoom?1:0,maxPointSize:i.maxPointSize,renderMode:0,hoveredLinkIndex:r,hoveredLinkWidthIncrease:t.hoveredLinkWidthIncrease,isLinkHighlightingActive:n?1:0,linkStatusTextureSize:this.linkStatusTextureSize,focusedLinkIndex:t.focusedLinkIndex??-1,focusedLinkWidthIncrease:t.focusedLinkWidthIncrease,transitionProgress:this.transitionProgress,animateColors:this.shouldAnimateLinkColors?1:0,animateWidths:this.shouldAnimateLinkWidths?1:0,animatePositions:this.shouldAnimatePositions?1:0,pointDefaultColor:ge(this.data.defaultRgba,[0,0,0,1]),linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,linkBlending:t.linkBlending?1:0,pixelRatio:t.pixelRatio},drawLineFragmentUniforms:{renderMode:0,linkDashLength:t.linkDashLength,linkDashGap:t.linkDashGap,linkColorInterpolateFromEndpoints:t.linkColorInterpolateFromEndpoints?1:0,hoveredLinkIndex:r,hoveredLinkColor:ge(i.hoveredLinkColor,[-1,-1,-1,-1]),linkBlending:t.linkBlending?1:0}}}getDrawBindings(t){return{positionsTexture:t.currentPositionTexture,linkStatus:this.linkStatusTexture,exitTexture:t.exitTexture,pointColorsTexture:t.pointColorsTexture??t.currentPositionTexture}}}class X_{constructor(t,i){this.eventTransform=jt,this.behavior=Xg().scaleExtent([.001,1/0]).filter(n=>!this.config.enableZoom&&(n.type==="wheel"||n.type==="dblclick"||n.type==="touchend"||"touches"in n&&n.touches.length>1)?!1:(!n.ctrlKey||n.type==="wheel")&&(n.button??0)===0).on("start",n=>{var s,o;this.isRunning=!0;const r=!!n.sourceEvent;r&&(this.shouldEnableSimulationDuringZoomOverride=void 0),(o=(s=this.config).onZoomStart)==null||o.call(s,n,r)}).on("zoom",n=>{var s,o;this.applyEventTransform(n.transform);const r=!!n.sourceEvent;(o=(s=this.config).onZoom)==null||o.call(s,n,r)}).on("end",n=>{var s,o;this.isRunning=!1;const r=!!n.sourceEvent;(o=(s=this.config).onZoomEnd)==null||o.call(s,n,r)}),this.isRunning=!1,this.shouldEnableSimulationDuringZoomOverride=void 0,this.store=t,this.config=i}applyEventTransform(t){this.eventTransform=t;const{eventTransform:{x:i,y:n,k:r},store:{transform:s,screenSize:o}}=this,a=o[0],l=o[1];!a||!l||(ex(s,a,l),$l(s,s,[i,n]),Rs(s,s,[r,r]),$l(s,s,[a/2,l/2]),Rs(s,s,[a/2,l/2]),Rs(s,s,[1,-1]))}getTransform(t,i,n=.1){if(t.length===0)return this.eventTransform;const{store:{screenSize:r}}=this,s=r[0],o=r[1];let a=1/0,l=-1/0,c=1/0,u=-1/0;for(let v=0;v<t.length;v+=2){const E=t[v],R=t[v+1];!Number.isFinite(E)||!Number.isFinite(R)||(E<a&&(a=E),E>l&&(l=E),R<c&&(c=R),R>u&&(u=R))}if(!Number.isFinite(a)||!Number.isFinite(c))return this.eventTransform;const d=[this.store.scaleX(a),this.store.scaleX(l)],h=[this.store.scaleY(c),this.store.scaleY(u)];d[0]===d[1]&&(d[0]-=.5,d[1]+=.5),h[0]===h[1]&&(h[0]+=.5,h[1]-=.5);const p=s*(1-n*2)/(d[1]-d[0]),g=o*(1-n*2)/(h[0]-h[1]),x=lc(i??Math.min(p,g),...this.behavior.scaleExtent()),T=(d[1]+d[0])/2,S=(h[1]+h[0])/2,P=s/2-T*x,I=o/2-S*x;return jt.translate(P,I).scale(x)}getDistanceToPoint(t){const{x:i,y:n,k:r}=this.eventTransform,s=this.getTransform(t,r),o=i-s.x,a=n-s.y;return Math.sqrt(o*o+a*a)}getMiddlePointTransform(t){if(!Number.isFinite(t[0])||!Number.isFinite(t[1]))return this.eventTransform;const{store:{screenSize:i},eventTransform:{x:n,y:r,k:s}}=this,o=i[0],a=i[1],l=(o/2-n)/s,c=(a/2-r)/s,u=this.store.scaleX(t[0]),d=this.store.scaleY(t[1]),h=(l+u)/2,p=(c+d)/2,g=1,x=o/2-h*g,T=a/2-p*g;return jt.translate(x,T).scale(g)}convertScreenToSpacePosition(t){const{eventTransform:{x:i,y:n,k:r},store:{screenSize:s}}=this,o=s[0],a=s[1],l=(t[0]-i)/r,c=(t[1]-n)/r,u=[l,a-c];return u[0]-=(o-this.store.adjustedSpaceSize)/2,u[1]-=(a-this.store.adjustedSpaceSize)/2,u}convertSpaceToScreenPosition(t){const i=this.eventTransform.applyX(this.store.scaleX(t[0])),n=this.eventTransform.applyY(this.store.scaleY(t[1]));return[i,n]}convertSpaceToScreenRadius(t){const{config:{scalePointsOnZoom:i,pixelRatio:n},store:{maxPointSize:r},eventTransform:{k:s}}=this;let o=t*2;return i?o*=s:o*=Math.min(5,Math.max(1,s*.01)),o<=0?0:Math.min(Math.max(o,1/n),r)/2}}class Y_{constructor(t,i,n){this.isActive=!1,this.behavior=Ug().subject(r=>{if(!(this.transition.isActiveFor(le.Positions)||this.transition.isActiveFor(le.PointSizes)))return this.store.hoveredPoint&&!this.store.isSpaceKeyPressed?{x:r.x,y:r.y}:void 0}).on("start",r=>{var s,o;this.store.hoveredPoint&&(this.store.draggingPointIndex=this.store.hoveredPoint.index,this.isActive=!0,(o=(s=this.config).onDragStart)==null||o.call(s,r))}).on("drag",r=>{var s,o;(o=(s=this.config).onDrag)==null||o.call(s,r)}).on("end",r=>{var s,o;this.isActive=!1,this.store.draggingPointIndex=void 0,(o=(s=this.config).onDragEnd)==null||o.call(s,r)}),this.store=t,this.config=i,this.transition=n}}var ci;(function(e){e[e.DEPTH_BUFFER_BIT=256]="DEPTH_BUFFER_BIT",e[e.STENCIL_BUFFER_BIT=1024]="STENCIL_BUFFER_BIT",e[e.COLOR_BUFFER_BIT=16384]="COLOR_BUFFER_BIT",e[e.POINTS=0]="POINTS",e[e.LINES=1]="LINES",e[e.LINE_LOOP=2]="LINE_LOOP",e[e.LINE_STRIP=3]="LINE_STRIP",e[e.TRIANGLES=4]="TRIANGLES",e[e.TRIANGLE_STRIP=5]="TRIANGLE_STRIP",e[e.TRIANGLE_FAN=6]="TRIANGLE_FAN",e[e.ZERO=0]="ZERO",e[e.ONE=1]="ONE",e[e.SRC_COLOR=768]="SRC_COLOR",e[e.ONE_MINUS_SRC_COLOR=769]="ONE_MINUS_SRC_COLOR",e[e.SRC_ALPHA=770]="SRC_ALPHA",e[e.ONE_MINUS_SRC_ALPHA=771]="ONE_MINUS_SRC_ALPHA",e[e.DST_ALPHA=772]="DST_ALPHA",e[e.ONE_MINUS_DST_ALPHA=773]="ONE_MINUS_DST_ALPHA",e[e.DST_COLOR=774]="DST_COLOR",e[e.ONE_MINUS_DST_COLOR=775]="ONE_MINUS_DST_COLOR",e[e.SRC_ALPHA_SATURATE=776]="SRC_ALPHA_SATURATE",e[e.CONSTANT_COLOR=32769]="CONSTANT_COLOR",e[e.ONE_MINUS_CONSTANT_COLOR=32770]="ONE_MINUS_CONSTANT_COLOR",e[e.CONSTANT_ALPHA=32771]="CONSTANT_ALPHA",e[e.ONE_MINUS_CONSTANT_ALPHA=32772]="ONE_MINUS_CONSTANT_ALPHA",e[e.FUNC_ADD=32774]="FUNC_ADD",e[e.FUNC_SUBTRACT=32778]="FUNC_SUBTRACT",e[e.FUNC_REVERSE_SUBTRACT=32779]="FUNC_REVERSE_SUBTRACT",e[e.BLEND_EQUATION=32777]="BLEND_EQUATION",e[e.BLEND_EQUATION_RGB=32777]="BLEND_EQUATION_RGB",e[e.BLEND_EQUATION_ALPHA=34877]="BLEND_EQUATION_ALPHA",e[e.BLEND_DST_RGB=32968]="BLEND_DST_RGB",e[e.BLEND_SRC_RGB=32969]="BLEND_SRC_RGB",e[e.BLEND_DST_ALPHA=32970]="BLEND_DST_ALPHA",e[e.BLEND_SRC_ALPHA=32971]="BLEND_SRC_ALPHA",e[e.BLEND_COLOR=32773]="BLEND_COLOR",e[e.ARRAY_BUFFER_BINDING=34964]="ARRAY_BUFFER_BINDING",e[e.ELEMENT_ARRAY_BUFFER_BINDING=34965]="ELEMENT_ARRAY_BUFFER_BINDING",e[e.LINE_WIDTH=2849]="LINE_WIDTH",e[e.ALIASED_POINT_SIZE_RANGE=33901]="ALIASED_POINT_SIZE_RANGE",e[e.ALIASED_LINE_WIDTH_RANGE=33902]="ALIASED_LINE_WIDTH_RANGE",e[e.CULL_FACE_MODE=2885]="CULL_FACE_MODE",e[e.FRONT_FACE=2886]="FRONT_FACE",e[e.DEPTH_RANGE=2928]="DEPTH_RANGE",e[e.DEPTH_WRITEMASK=2930]="DEPTH_WRITEMASK",e[e.DEPTH_CLEAR_VALUE=2931]="DEPTH_CLEAR_VALUE",e[e.DEPTH_FUNC=2932]="DEPTH_FUNC",e[e.STENCIL_CLEAR_VALUE=2961]="STENCIL_CLEAR_VALUE",e[e.STENCIL_FUNC=2962]="STENCIL_FUNC",e[e.STENCIL_FAIL=2964]="STENCIL_FAIL",e[e.STENCIL_PASS_DEPTH_FAIL=2965]="STENCIL_PASS_DEPTH_FAIL",e[e.STENCIL_PASS_DEPTH_PASS=2966]="STENCIL_PASS_DEPTH_PASS",e[e.STENCIL_REF=2967]="STENCIL_REF",e[e.STENCIL_VALUE_MASK=2963]="STENCIL_VALUE_MASK",e[e.STENCIL_WRITEMASK=2968]="STENCIL_WRITEMASK",e[e.STENCIL_BACK_FUNC=34816]="STENCIL_BACK_FUNC",e[e.STENCIL_BACK_FAIL=34817]="STENCIL_BACK_FAIL",e[e.STENCIL_BACK_PASS_DEPTH_FAIL=34818]="STENCIL_BACK_PASS_DEPTH_FAIL",e[e.STENCIL_BACK_PASS_DEPTH_PASS=34819]="STENCIL_BACK_PASS_DEPTH_PASS",e[e.STENCIL_BACK_REF=36003]="STENCIL_BACK_REF",e[e.STENCIL_BACK_VALUE_MASK=36004]="STENCIL_BACK_VALUE_MASK",e[e.STENCIL_BACK_WRITEMASK=36005]="STENCIL_BACK_WRITEMASK",e[e.VIEWPORT=2978]="VIEWPORT",e[e.SCISSOR_BOX=3088]="SCISSOR_BOX",e[e.COLOR_CLEAR_VALUE=3106]="COLOR_CLEAR_VALUE",e[e.COLOR_WRITEMASK=3107]="COLOR_WRITEMASK",e[e.UNPACK_ALIGNMENT=3317]="UNPACK_ALIGNMENT",e[e.PACK_ALIGNMENT=3333]="PACK_ALIGNMENT",e[e.MAX_TEXTURE_SIZE=3379]="MAX_TEXTURE_SIZE",e[e.MAX_VIEWPORT_DIMS=3386]="MAX_VIEWPORT_DIMS",e[e.SUBPIXEL_BITS=3408]="SUBPIXEL_BITS",e[e.RED_BITS=3410]="RED_BITS",e[e.GREEN_BITS=3411]="GREEN_BITS",e[e.BLUE_BITS=3412]="BLUE_BITS",e[e.ALPHA_BITS=3413]="ALPHA_BITS",e[e.DEPTH_BITS=3414]="DEPTH_BITS",e[e.STENCIL_BITS=3415]="STENCIL_BITS",e[e.POLYGON_OFFSET_UNITS=10752]="POLYGON_OFFSET_UNITS",e[e.POLYGON_OFFSET_FACTOR=32824]="POLYGON_OFFSET_FACTOR",e[e.TEXTURE_BINDING_2D=32873]="TEXTURE_BINDING_2D",e[e.SAMPLE_BUFFERS=32936]="SAMPLE_BUFFERS",e[e.SAMPLES=32937]="SAMPLES",e[e.SAMPLE_COVERAGE_VALUE=32938]="SAMPLE_COVERAGE_VALUE",e[e.SAMPLE_COVERAGE_INVERT=32939]="SAMPLE_COVERAGE_INVERT",e[e.COMPRESSED_TEXTURE_FORMATS=34467]="COMPRESSED_TEXTURE_FORMATS",e[e.VENDOR=7936]="VENDOR",e[e.RENDERER=7937]="RENDERER",e[e.VERSION=7938]="VERSION",e[e.IMPLEMENTATION_COLOR_READ_TYPE=35738]="IMPLEMENTATION_COLOR_READ_TYPE",e[e.IMPLEMENTATION_COLOR_READ_FORMAT=35739]="IMPLEMENTATION_COLOR_READ_FORMAT",e[e.BROWSER_DEFAULT_WEBGL=37444]="BROWSER_DEFAULT_WEBGL",e[e.STATIC_DRAW=35044]="STATIC_DRAW",e[e.STREAM_DRAW=35040]="STREAM_DRAW",e[e.DYNAMIC_DRAW=35048]="DYNAMIC_DRAW",e[e.ARRAY_BUFFER=34962]="ARRAY_BUFFER",e[e.ELEMENT_ARRAY_BUFFER=34963]="ELEMENT_ARRAY_BUFFER",e[e.BUFFER_SIZE=34660]="BUFFER_SIZE",e[e.BUFFER_USAGE=34661]="BUFFER_USAGE",e[e.CURRENT_VERTEX_ATTRIB=34342]="CURRENT_VERTEX_ATTRIB",e[e.VERTEX_ATTRIB_ARRAY_ENABLED=34338]="VERTEX_ATTRIB_ARRAY_ENABLED",e[e.VERTEX_ATTRIB_ARRAY_SIZE=34339]="VERTEX_ATTRIB_ARRAY_SIZE",e[e.VERTEX_ATTRIB_ARRAY_STRIDE=34340]="VERTEX_ATTRIB_ARRAY_STRIDE",e[e.VERTEX_ATTRIB_ARRAY_TYPE=34341]="VERTEX_ATTRIB_ARRAY_TYPE",e[e.VERTEX_ATTRIB_ARRAY_NORMALIZED=34922]="VERTEX_ATTRIB_ARRAY_NORMALIZED",e[e.VERTEX_ATTRIB_ARRAY_POINTER=34373]="VERTEX_ATTRIB_ARRAY_POINTER",e[e.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING=34975]="VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",e[e.CULL_FACE=2884]="CULL_FACE",e[e.FRONT=1028]="FRONT",e[e.BACK=1029]="BACK",e[e.FRONT_AND_BACK=1032]="FRONT_AND_BACK",e[e.BLEND=3042]="BLEND",e[e.DEPTH_TEST=2929]="DEPTH_TEST",e[e.DITHER=3024]="DITHER",e[e.POLYGON_OFFSET_FILL=32823]="POLYGON_OFFSET_FILL",e[e.SAMPLE_ALPHA_TO_COVERAGE=32926]="SAMPLE_ALPHA_TO_COVERAGE",e[e.SAMPLE_COVERAGE=32928]="SAMPLE_COVERAGE",e[e.SCISSOR_TEST=3089]="SCISSOR_TEST",e[e.STENCIL_TEST=2960]="STENCIL_TEST",e[e.NO_ERROR=0]="NO_ERROR",e[e.INVALID_ENUM=1280]="INVALID_ENUM",e[e.INVALID_VALUE=1281]="INVALID_VALUE",e[e.INVALID_OPERATION=1282]="INVALID_OPERATION",e[e.OUT_OF_MEMORY=1285]="OUT_OF_MEMORY",e[e.CONTEXT_LOST_WEBGL=37442]="CONTEXT_LOST_WEBGL",e[e.CW=2304]="CW",e[e.CCW=2305]="CCW",e[e.DONT_CARE=4352]="DONT_CARE",e[e.FASTEST=4353]="FASTEST",e[e.NICEST=4354]="NICEST",e[e.GENERATE_MIPMAP_HINT=33170]="GENERATE_MIPMAP_HINT",e[e.BYTE=5120]="BYTE",e[e.UNSIGNED_BYTE=5121]="UNSIGNED_BYTE",e[e.SHORT=5122]="SHORT",e[e.UNSIGNED_SHORT=5123]="UNSIGNED_SHORT",e[e.INT=5124]="INT",e[e.UNSIGNED_INT=5125]="UNSIGNED_INT",e[e.FLOAT=5126]="FLOAT",e[e.DOUBLE=5130]="DOUBLE",e[e.DEPTH_COMPONENT=6402]="DEPTH_COMPONENT",e[e.ALPHA=6406]="ALPHA",e[e.RGB=6407]="RGB",e[e.RGBA=6408]="RGBA",e[e.LUMINANCE=6409]="LUMINANCE",e[e.LUMINANCE_ALPHA=6410]="LUMINANCE_ALPHA",e[e.UNSIGNED_SHORT_4_4_4_4=32819]="UNSIGNED_SHORT_4_4_4_4",e[e.UNSIGNED_SHORT_5_5_5_1=32820]="UNSIGNED_SHORT_5_5_5_1",e[e.UNSIGNED_SHORT_5_6_5=33635]="UNSIGNED_SHORT_5_6_5",e[e.FRAGMENT_SHADER=35632]="FRAGMENT_SHADER",e[e.VERTEX_SHADER=35633]="VERTEX_SHADER",e[e.COMPILE_STATUS=35713]="COMPILE_STATUS",e[e.DELETE_STATUS=35712]="DELETE_STATUS",e[e.LINK_STATUS=35714]="LINK_STATUS",e[e.VALIDATE_STATUS=35715]="VALIDATE_STATUS",e[e.ATTACHED_SHADERS=35717]="ATTACHED_SHADERS",e[e.ACTIVE_ATTRIBUTES=35721]="ACTIVE_ATTRIBUTES",e[e.ACTIVE_UNIFORMS=35718]="ACTIVE_UNIFORMS",e[e.MAX_VERTEX_ATTRIBS=34921]="MAX_VERTEX_ATTRIBS",e[e.MAX_VERTEX_UNIFORM_VECTORS=36347]="MAX_VERTEX_UNIFORM_VECTORS",e[e.MAX_VARYING_VECTORS=36348]="MAX_VARYING_VECTORS",e[e.MAX_COMBINED_TEXTURE_IMAGE_UNITS=35661]="MAX_COMBINED_TEXTURE_IMAGE_UNITS",e[e.MAX_VERTEX_TEXTURE_IMAGE_UNITS=35660]="MAX_VERTEX_TEXTURE_IMAGE_UNITS",e[e.MAX_TEXTURE_IMAGE_UNITS=34930]="MAX_TEXTURE_IMAGE_UNITS",e[e.MAX_FRAGMENT_UNIFORM_VECTORS=36349]="MAX_FRAGMENT_UNIFORM_VECTORS",e[e.SHADER_TYPE=35663]="SHADER_TYPE",e[e.SHADING_LANGUAGE_VERSION=35724]="SHADING_LANGUAGE_VERSION",e[e.CURRENT_PROGRAM=35725]="CURRENT_PROGRAM",e[e.NEVER=512]="NEVER",e[e.LESS=513]="LESS",e[e.EQUAL=514]="EQUAL",e[e.LEQUAL=515]="LEQUAL",e[e.GREATER=516]="GREATER",e[e.NOTEQUAL=517]="NOTEQUAL",e[e.GEQUAL=518]="GEQUAL",e[e.ALWAYS=519]="ALWAYS",e[e.KEEP=7680]="KEEP",e[e.REPLACE=7681]="REPLACE",e[e.INCR=7682]="INCR",e[e.DECR=7683]="DECR",e[e.INVERT=5386]="INVERT",e[e.INCR_WRAP=34055]="INCR_WRAP",e[e.DECR_WRAP=34056]="DECR_WRAP",e[e.NEAREST=9728]="NEAREST",e[e.LINEAR=9729]="LINEAR",e[e.NEAREST_MIPMAP_NEAREST=9984]="NEAREST_MIPMAP_NEAREST",e[e.LINEAR_MIPMAP_NEAREST=9985]="LINEAR_MIPMAP_NEAREST",e[e.NEAREST_MIPMAP_LINEAR=9986]="NEAREST_MIPMAP_LINEAR",e[e.LINEAR_MIPMAP_LINEAR=9987]="LINEAR_MIPMAP_LINEAR",e[e.TEXTURE_MAG_FILTER=10240]="TEXTURE_MAG_FILTER",e[e.TEXTURE_MIN_FILTER=10241]="TEXTURE_MIN_FILTER",e[e.TEXTURE_WRAP_S=10242]="TEXTURE_WRAP_S",e[e.TEXTURE_WRAP_T=10243]="TEXTURE_WRAP_T",e[e.TEXTURE_2D=3553]="TEXTURE_2D",e[e.TEXTURE=5890]="TEXTURE",e[e.TEXTURE_CUBE_MAP=34067]="TEXTURE_CUBE_MAP",e[e.TEXTURE_BINDING_CUBE_MAP=34068]="TEXTURE_BINDING_CUBE_MAP",e[e.TEXTURE_CUBE_MAP_POSITIVE_X=34069]="TEXTURE_CUBE_MAP_POSITIVE_X",e[e.TEXTURE_CUBE_MAP_NEGATIVE_X=34070]="TEXTURE_CUBE_MAP_NEGATIVE_X",e[e.TEXTURE_CUBE_MAP_POSITIVE_Y=34071]="TEXTURE_CUBE_MAP_POSITIVE_Y",e[e.TEXTURE_CUBE_MAP_NEGATIVE_Y=34072]="TEXTURE_CUBE_MAP_NEGATIVE_Y",e[e.TEXTURE_CUBE_MAP_POSITIVE_Z=34073]="TEXTURE_CUBE_MAP_POSITIVE_Z",e[e.TEXTURE_CUBE_MAP_NEGATIVE_Z=34074]="TEXTURE_CUBE_MAP_NEGATIVE_Z",e[e.MAX_CUBE_MAP_TEXTURE_SIZE=34076]="MAX_CUBE_MAP_TEXTURE_SIZE",e[e.TEXTURE0=33984]="TEXTURE0",e[e.ACTIVE_TEXTURE=34016]="ACTIVE_TEXTURE",e[e.REPEAT=10497]="REPEAT",e[e.CLAMP_TO_EDGE=33071]="CLAMP_TO_EDGE",e[e.MIRRORED_REPEAT=33648]="MIRRORED_REPEAT",e[e.TEXTURE_WIDTH=4096]="TEXTURE_WIDTH",e[e.TEXTURE_HEIGHT=4097]="TEXTURE_HEIGHT",e[e.FLOAT_VEC2=35664]="FLOAT_VEC2",e[e.FLOAT_VEC3=35665]="FLOAT_VEC3",e[e.FLOAT_VEC4=35666]="FLOAT_VEC4",e[e.INT_VEC2=35667]="INT_VEC2",e[e.INT_VEC3=35668]="INT_VEC3",e[e.INT_VEC4=35669]="INT_VEC4",e[e.BOOL=35670]="BOOL",e[e.BOOL_VEC2=35671]="BOOL_VEC2",e[e.BOOL_VEC3=35672]="BOOL_VEC3",e[e.BOOL_VEC4=35673]="BOOL_VEC4",e[e.FLOAT_MAT2=35674]="FLOAT_MAT2",e[e.FLOAT_MAT3=35675]="FLOAT_MAT3",e[e.FLOAT_MAT4=35676]="FLOAT_MAT4",e[e.SAMPLER_2D=35678]="SAMPLER_2D",e[e.SAMPLER_CUBE=35680]="SAMPLER_CUBE",e[e.LOW_FLOAT=36336]="LOW_FLOAT",e[e.MEDIUM_FLOAT=36337]="MEDIUM_FLOAT",e[e.HIGH_FLOAT=36338]="HIGH_FLOAT",e[e.LOW_INT=36339]="LOW_INT",e[e.MEDIUM_INT=36340]="MEDIUM_INT",e[e.HIGH_INT=36341]="HIGH_INT",e[e.FRAMEBUFFER=36160]="FRAMEBUFFER",e[e.RENDERBUFFER=36161]="RENDERBUFFER",e[e.RGBA4=32854]="RGBA4",e[e.RGB5_A1=32855]="RGB5_A1",e[e.RGB565=36194]="RGB565",e[e.DEPTH_COMPONENT16=33189]="DEPTH_COMPONENT16",e[e.STENCIL_INDEX=6401]="STENCIL_INDEX",e[e.STENCIL_INDEX8=36168]="STENCIL_INDEX8",e[e.DEPTH_STENCIL=34041]="DEPTH_STENCIL",e[e.RENDERBUFFER_WIDTH=36162]="RENDERBUFFER_WIDTH",e[e.RENDERBUFFER_HEIGHT=36163]="RENDERBUFFER_HEIGHT",e[e.RENDERBUFFER_INTERNAL_FORMAT=36164]="RENDERBUFFER_INTERNAL_FORMAT",e[e.RENDERBUFFER_RED_SIZE=36176]="RENDERBUFFER_RED_SIZE",e[e.RENDERBUFFER_GREEN_SIZE=36177]="RENDERBUFFER_GREEN_SIZE",e[e.RENDERBUFFER_BLUE_SIZE=36178]="RENDERBUFFER_BLUE_SIZE",e[e.RENDERBUFFER_ALPHA_SIZE=36179]="RENDERBUFFER_ALPHA_SIZE",e[e.RENDERBUFFER_DEPTH_SIZE=36180]="RENDERBUFFER_DEPTH_SIZE",e[e.RENDERBUFFER_STENCIL_SIZE=36181]="RENDERBUFFER_STENCIL_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE=36048]="FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",e[e.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME=36049]="FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",e[e.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL=36050]="FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",e[e.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE=36051]="FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",e[e.COLOR_ATTACHMENT0=36064]="COLOR_ATTACHMENT0",e[e.DEPTH_ATTACHMENT=36096]="DEPTH_ATTACHMENT",e[e.STENCIL_ATTACHMENT=36128]="STENCIL_ATTACHMENT",e[e.DEPTH_STENCIL_ATTACHMENT=33306]="DEPTH_STENCIL_ATTACHMENT",e[e.NONE=0]="NONE",e[e.FRAMEBUFFER_COMPLETE=36053]="FRAMEBUFFER_COMPLETE",e[e.FRAMEBUFFER_INCOMPLETE_ATTACHMENT=36054]="FRAMEBUFFER_INCOMPLETE_ATTACHMENT",e[e.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT=36055]="FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",e[e.FRAMEBUFFER_INCOMPLETE_DIMENSIONS=36057]="FRAMEBUFFER_INCOMPLETE_DIMENSIONS",e[e.FRAMEBUFFER_UNSUPPORTED=36061]="FRAMEBUFFER_UNSUPPORTED",e[e.FRAMEBUFFER_BINDING=36006]="FRAMEBUFFER_BINDING",e[e.RENDERBUFFER_BINDING=36007]="RENDERBUFFER_BINDING",e[e.READ_FRAMEBUFFER=36008]="READ_FRAMEBUFFER",e[e.DRAW_FRAMEBUFFER=36009]="DRAW_FRAMEBUFFER",e[e.MAX_RENDERBUFFER_SIZE=34024]="MAX_RENDERBUFFER_SIZE",e[e.INVALID_FRAMEBUFFER_OPERATION=1286]="INVALID_FRAMEBUFFER_OPERATION",e[e.UNPACK_FLIP_Y_WEBGL=37440]="UNPACK_FLIP_Y_WEBGL",e[e.UNPACK_PREMULTIPLY_ALPHA_WEBGL=37441]="UNPACK_PREMULTIPLY_ALPHA_WEBGL",e[e.UNPACK_COLORSPACE_CONVERSION_WEBGL=37443]="UNPACK_COLORSPACE_CONVERSION_WEBGL",e[e.READ_BUFFER=3074]="READ_BUFFER",e[e.UNPACK_ROW_LENGTH=3314]="UNPACK_ROW_LENGTH",e[e.UNPACK_SKIP_ROWS=3315]="UNPACK_SKIP_ROWS",e[e.UNPACK_SKIP_PIXELS=3316]="UNPACK_SKIP_PIXELS",e[e.PACK_ROW_LENGTH=3330]="PACK_ROW_LENGTH",e[e.PACK_SKIP_ROWS=3331]="PACK_SKIP_ROWS",e[e.PACK_SKIP_PIXELS=3332]="PACK_SKIP_PIXELS",e[e.TEXTURE_BINDING_3D=32874]="TEXTURE_BINDING_3D",e[e.UNPACK_SKIP_IMAGES=32877]="UNPACK_SKIP_IMAGES",e[e.UNPACK_IMAGE_HEIGHT=32878]="UNPACK_IMAGE_HEIGHT",e[e.MAX_3D_TEXTURE_SIZE=32883]="MAX_3D_TEXTURE_SIZE",e[e.MAX_ELEMENTS_VERTICES=33e3]="MAX_ELEMENTS_VERTICES",e[e.MAX_ELEMENTS_INDICES=33001]="MAX_ELEMENTS_INDICES",e[e.MAX_TEXTURE_LOD_BIAS=34045]="MAX_TEXTURE_LOD_BIAS",e[e.MAX_FRAGMENT_UNIFORM_COMPONENTS=35657]="MAX_FRAGMENT_UNIFORM_COMPONENTS",e[e.MAX_VERTEX_UNIFORM_COMPONENTS=35658]="MAX_VERTEX_UNIFORM_COMPONENTS",e[e.MAX_ARRAY_TEXTURE_LAYERS=35071]="MAX_ARRAY_TEXTURE_LAYERS",e[e.MIN_PROGRAM_TEXEL_OFFSET=35076]="MIN_PROGRAM_TEXEL_OFFSET",e[e.MAX_PROGRAM_TEXEL_OFFSET=35077]="MAX_PROGRAM_TEXEL_OFFSET",e[e.MAX_VARYING_COMPONENTS=35659]="MAX_VARYING_COMPONENTS",e[e.FRAGMENT_SHADER_DERIVATIVE_HINT=35723]="FRAGMENT_SHADER_DERIVATIVE_HINT",e[e.RASTERIZER_DISCARD=35977]="RASTERIZER_DISCARD",e[e.VERTEX_ARRAY_BINDING=34229]="VERTEX_ARRAY_BINDING",e[e.MAX_VERTEX_OUTPUT_COMPONENTS=37154]="MAX_VERTEX_OUTPUT_COMPONENTS",e[e.MAX_FRAGMENT_INPUT_COMPONENTS=37157]="MAX_FRAGMENT_INPUT_COMPONENTS",e[e.MAX_SERVER_WAIT_TIMEOUT=37137]="MAX_SERVER_WAIT_TIMEOUT",e[e.MAX_ELEMENT_INDEX=36203]="MAX_ELEMENT_INDEX",e[e.RED=6403]="RED",e[e.RGB8=32849]="RGB8",e[e.RGBA8=32856]="RGBA8",e[e.RGB10_A2=32857]="RGB10_A2",e[e.TEXTURE_3D=32879]="TEXTURE_3D",e[e.TEXTURE_WRAP_R=32882]="TEXTURE_WRAP_R",e[e.TEXTURE_MIN_LOD=33082]="TEXTURE_MIN_LOD",e[e.TEXTURE_MAX_LOD=33083]="TEXTURE_MAX_LOD",e[e.TEXTURE_BASE_LEVEL=33084]="TEXTURE_BASE_LEVEL",e[e.TEXTURE_MAX_LEVEL=33085]="TEXTURE_MAX_LEVEL",e[e.TEXTURE_COMPARE_MODE=34892]="TEXTURE_COMPARE_MODE",e[e.TEXTURE_COMPARE_FUNC=34893]="TEXTURE_COMPARE_FUNC",e[e.SRGB=35904]="SRGB",e[e.SRGB8=35905]="SRGB8",e[e.SRGB8_ALPHA8=35907]="SRGB8_ALPHA8",e[e.COMPARE_REF_TO_TEXTURE=34894]="COMPARE_REF_TO_TEXTURE",e[e.RGBA32F=34836]="RGBA32F",e[e.RGB32F=34837]="RGB32F",e[e.RGBA16F=34842]="RGBA16F",e[e.RGB16F=34843]="RGB16F",e[e.TEXTURE_2D_ARRAY=35866]="TEXTURE_2D_ARRAY",e[e.TEXTURE_BINDING_2D_ARRAY=35869]="TEXTURE_BINDING_2D_ARRAY",e[e.R11F_G11F_B10F=35898]="R11F_G11F_B10F",e[e.RGB9_E5=35901]="RGB9_E5",e[e.RGBA32UI=36208]="RGBA32UI",e[e.RGB32UI=36209]="RGB32UI",e[e.RGBA16UI=36214]="RGBA16UI",e[e.RGB16UI=36215]="RGB16UI",e[e.RGBA8UI=36220]="RGBA8UI",e[e.RGB8UI=36221]="RGB8UI",e[e.RGBA32I=36226]="RGBA32I",e[e.RGB32I=36227]="RGB32I",e[e.RGBA16I=36232]="RGBA16I",e[e.RGB16I=36233]="RGB16I",e[e.RGBA8I=36238]="RGBA8I",e[e.RGB8I=36239]="RGB8I",e[e.RED_INTEGER=36244]="RED_INTEGER",e[e.RGB_INTEGER=36248]="RGB_INTEGER",e[e.RGBA_INTEGER=36249]="RGBA_INTEGER",e[e.R8=33321]="R8",e[e.RG8=33323]="RG8",e[e.R16F=33325]="R16F",e[e.R32F=33326]="R32F",e[e.RG16F=33327]="RG16F",e[e.RG32F=33328]="RG32F",e[e.R8I=33329]="R8I",e[e.R8UI=33330]="R8UI",e[e.R16I=33331]="R16I",e[e.R16UI=33332]="R16UI",e[e.R32I=33333]="R32I",e[e.R32UI=33334]="R32UI",e[e.RG8I=33335]="RG8I",e[e.RG8UI=33336]="RG8UI",e[e.RG16I=33337]="RG16I",e[e.RG16UI=33338]="RG16UI",e[e.RG32I=33339]="RG32I",e[e.RG32UI=33340]="RG32UI",e[e.R8_SNORM=36756]="R8_SNORM",e[e.RG8_SNORM=36757]="RG8_SNORM",e[e.RGB8_SNORM=36758]="RGB8_SNORM",e[e.RGBA8_SNORM=36759]="RGBA8_SNORM",e[e.RGB10_A2UI=36975]="RGB10_A2UI",e[e.TEXTURE_IMMUTABLE_FORMAT=37167]="TEXTURE_IMMUTABLE_FORMAT",e[e.TEXTURE_IMMUTABLE_LEVELS=33503]="TEXTURE_IMMUTABLE_LEVELS",e[e.UNSIGNED_INT_2_10_10_10_REV=33640]="UNSIGNED_INT_2_10_10_10_REV",e[e.UNSIGNED_INT_10F_11F_11F_REV=35899]="UNSIGNED_INT_10F_11F_11F_REV",e[e.UNSIGNED_INT_5_9_9_9_REV=35902]="UNSIGNED_INT_5_9_9_9_REV",e[e.FLOAT_32_UNSIGNED_INT_24_8_REV=36269]="FLOAT_32_UNSIGNED_INT_24_8_REV",e[e.UNSIGNED_INT_24_8=34042]="UNSIGNED_INT_24_8",e[e.HALF_FLOAT=5131]="HALF_FLOAT",e[e.RG=33319]="RG",e[e.RG_INTEGER=33320]="RG_INTEGER",e[e.INT_2_10_10_10_REV=36255]="INT_2_10_10_10_REV",e[e.CURRENT_QUERY=34917]="CURRENT_QUERY",e[e.QUERY_RESULT=34918]="QUERY_RESULT",e[e.QUERY_RESULT_AVAILABLE=34919]="QUERY_RESULT_AVAILABLE",e[e.ANY_SAMPLES_PASSED=35887]="ANY_SAMPLES_PASSED",e[e.ANY_SAMPLES_PASSED_CONSERVATIVE=36202]="ANY_SAMPLES_PASSED_CONSERVATIVE",e[e.MAX_DRAW_BUFFERS=34852]="MAX_DRAW_BUFFERS",e[e.DRAW_BUFFER0=34853]="DRAW_BUFFER0",e[e.DRAW_BUFFER1=34854]="DRAW_BUFFER1",e[e.DRAW_BUFFER2=34855]="DRAW_BUFFER2",e[e.DRAW_BUFFER3=34856]="DRAW_BUFFER3",e[e.DRAW_BUFFER4=34857]="DRAW_BUFFER4",e[e.DRAW_BUFFER5=34858]="DRAW_BUFFER5",e[e.DRAW_BUFFER6=34859]="DRAW_BUFFER6",e[e.DRAW_BUFFER7=34860]="DRAW_BUFFER7",e[e.DRAW_BUFFER8=34861]="DRAW_BUFFER8",e[e.DRAW_BUFFER9=34862]="DRAW_BUFFER9",e[e.DRAW_BUFFER10=34863]="DRAW_BUFFER10",e[e.DRAW_BUFFER11=34864]="DRAW_BUFFER11",e[e.DRAW_BUFFER12=34865]="DRAW_BUFFER12",e[e.DRAW_BUFFER13=34866]="DRAW_BUFFER13",e[e.DRAW_BUFFER14=34867]="DRAW_BUFFER14",e[e.DRAW_BUFFER15=34868]="DRAW_BUFFER15",e[e.MAX_COLOR_ATTACHMENTS=36063]="MAX_COLOR_ATTACHMENTS",e[e.COLOR_ATTACHMENT1=36065]="COLOR_ATTACHMENT1",e[e.COLOR_ATTACHMENT2=36066]="COLOR_ATTACHMENT2",e[e.COLOR_ATTACHMENT3=36067]="COLOR_ATTACHMENT3",e[e.COLOR_ATTACHMENT4=36068]="COLOR_ATTACHMENT4",e[e.COLOR_ATTACHMENT5=36069]="COLOR_ATTACHMENT5",e[e.COLOR_ATTACHMENT6=36070]="COLOR_ATTACHMENT6",e[e.COLOR_ATTACHMENT7=36071]="COLOR_ATTACHMENT7",e[e.COLOR_ATTACHMENT8=36072]="COLOR_ATTACHMENT8",e[e.COLOR_ATTACHMENT9=36073]="COLOR_ATTACHMENT9",e[e.COLOR_ATTACHMENT10=36074]="COLOR_ATTACHMENT10",e[e.COLOR_ATTACHMENT11=36075]="COLOR_ATTACHMENT11",e[e.COLOR_ATTACHMENT12=36076]="COLOR_ATTACHMENT12",e[e.COLOR_ATTACHMENT13=36077]="COLOR_ATTACHMENT13",e[e.COLOR_ATTACHMENT14=36078]="COLOR_ATTACHMENT14",e[e.COLOR_ATTACHMENT15=36079]="COLOR_ATTACHMENT15",e[e.SAMPLER_3D=35679]="SAMPLER_3D",e[e.SAMPLER_2D_SHADOW=35682]="SAMPLER_2D_SHADOW",e[e.SAMPLER_2D_ARRAY=36289]="SAMPLER_2D_ARRAY",e[e.SAMPLER_2D_ARRAY_SHADOW=36292]="SAMPLER_2D_ARRAY_SHADOW",e[e.SAMPLER_CUBE_SHADOW=36293]="SAMPLER_CUBE_SHADOW",e[e.INT_SAMPLER_2D=36298]="INT_SAMPLER_2D",e[e.INT_SAMPLER_3D=36299]="INT_SAMPLER_3D",e[e.INT_SAMPLER_CUBE=36300]="INT_SAMPLER_CUBE",e[e.INT_SAMPLER_2D_ARRAY=36303]="INT_SAMPLER_2D_ARRAY",e[e.UNSIGNED_INT_SAMPLER_2D=36306]="UNSIGNED_INT_SAMPLER_2D",e[e.UNSIGNED_INT_SAMPLER_3D=36307]="UNSIGNED_INT_SAMPLER_3D",e[e.UNSIGNED_INT_SAMPLER_CUBE=36308]="UNSIGNED_INT_SAMPLER_CUBE",e[e.UNSIGNED_INT_SAMPLER_2D_ARRAY=36311]="UNSIGNED_INT_SAMPLER_2D_ARRAY",e[e.MAX_SAMPLES=36183]="MAX_SAMPLES",e[e.SAMPLER_BINDING=35097]="SAMPLER_BINDING",e[e.PIXEL_PACK_BUFFER=35051]="PIXEL_PACK_BUFFER",e[e.PIXEL_UNPACK_BUFFER=35052]="PIXEL_UNPACK_BUFFER",e[e.PIXEL_PACK_BUFFER_BINDING=35053]="PIXEL_PACK_BUFFER_BINDING",e[e.PIXEL_UNPACK_BUFFER_BINDING=35055]="PIXEL_UNPACK_BUFFER_BINDING",e[e.COPY_READ_BUFFER=36662]="COPY_READ_BUFFER",e[e.COPY_WRITE_BUFFER=36663]="COPY_WRITE_BUFFER",e[e.COPY_READ_BUFFER_BINDING=36662]="COPY_READ_BUFFER_BINDING",e[e.COPY_WRITE_BUFFER_BINDING=36663]="COPY_WRITE_BUFFER_BINDING",e[e.FLOAT_MAT2x3=35685]="FLOAT_MAT2x3",e[e.FLOAT_MAT2x4=35686]="FLOAT_MAT2x4",e[e.FLOAT_MAT3x2=35687]="FLOAT_MAT3x2",e[e.FLOAT_MAT3x4=35688]="FLOAT_MAT3x4",e[e.FLOAT_MAT4x2=35689]="FLOAT_MAT4x2",e[e.FLOAT_MAT4x3=35690]="FLOAT_MAT4x3",e[e.UNSIGNED_INT_VEC2=36294]="UNSIGNED_INT_VEC2",e[e.UNSIGNED_INT_VEC3=36295]="UNSIGNED_INT_VEC3",e[e.UNSIGNED_INT_VEC4=36296]="UNSIGNED_INT_VEC4",e[e.UNSIGNED_NORMALIZED=35863]="UNSIGNED_NORMALIZED",e[e.SIGNED_NORMALIZED=36764]="SIGNED_NORMALIZED",e[e.VERTEX_ATTRIB_ARRAY_INTEGER=35069]="VERTEX_ATTRIB_ARRAY_INTEGER",e[e.VERTEX_ATTRIB_ARRAY_DIVISOR=35070]="VERTEX_ATTRIB_ARRAY_DIVISOR",e[e.TRANSFORM_FEEDBACK_BUFFER_MODE=35967]="TRANSFORM_FEEDBACK_BUFFER_MODE",e[e.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS=35968]="MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",e[e.TRANSFORM_FEEDBACK_VARYINGS=35971]="TRANSFORM_FEEDBACK_VARYINGS",e[e.TRANSFORM_FEEDBACK_BUFFER_START=35972]="TRANSFORM_FEEDBACK_BUFFER_START",e[e.TRANSFORM_FEEDBACK_BUFFER_SIZE=35973]="TRANSFORM_FEEDBACK_BUFFER_SIZE",e[e.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN=35976]="TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",e[e.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS=35978]="MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",e[e.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS=35979]="MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",e[e.INTERLEAVED_ATTRIBS=35980]="INTERLEAVED_ATTRIBS",e[e.SEPARATE_ATTRIBS=35981]="SEPARATE_ATTRIBS",e[e.TRANSFORM_FEEDBACK_BUFFER=35982]="TRANSFORM_FEEDBACK_BUFFER",e[e.TRANSFORM_FEEDBACK_BUFFER_BINDING=35983]="TRANSFORM_FEEDBACK_BUFFER_BINDING",e[e.TRANSFORM_FEEDBACK=36386]="TRANSFORM_FEEDBACK",e[e.TRANSFORM_FEEDBACK_PAUSED=36387]="TRANSFORM_FEEDBACK_PAUSED",e[e.TRANSFORM_FEEDBACK_ACTIVE=36388]="TRANSFORM_FEEDBACK_ACTIVE",e[e.TRANSFORM_FEEDBACK_BINDING=36389]="TRANSFORM_FEEDBACK_BINDING",e[e.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING=33296]="FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",e[e.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE=33297]="FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",e[e.FRAMEBUFFER_ATTACHMENT_RED_SIZE=33298]="FRAMEBUFFER_ATTACHMENT_RED_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE=33299]="FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE=33300]="FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE=33301]="FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE=33302]="FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",e[e.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE=33303]="FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",e[e.FRAMEBUFFER_DEFAULT=33304]="FRAMEBUFFER_DEFAULT",e[e.DEPTH24_STENCIL8=35056]="DEPTH24_STENCIL8",e[e.DRAW_FRAMEBUFFER_BINDING=36006]="DRAW_FRAMEBUFFER_BINDING",e[e.READ_FRAMEBUFFER_BINDING=36010]="READ_FRAMEBUFFER_BINDING",e[e.RENDERBUFFER_SAMPLES=36011]="RENDERBUFFER_SAMPLES",e[e.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER=36052]="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",e[e.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE=36182]="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",e[e.UNIFORM_BUFFER=35345]="UNIFORM_BUFFER",e[e.UNIFORM_BUFFER_BINDING=35368]="UNIFORM_BUFFER_BINDING",e[e.UNIFORM_BUFFER_START=35369]="UNIFORM_BUFFER_START",e[e.UNIFORM_BUFFER_SIZE=35370]="UNIFORM_BUFFER_SIZE",e[e.MAX_VERTEX_UNIFORM_BLOCKS=35371]="MAX_VERTEX_UNIFORM_BLOCKS",e[e.MAX_FRAGMENT_UNIFORM_BLOCKS=35373]="MAX_FRAGMENT_UNIFORM_BLOCKS",e[e.MAX_COMBINED_UNIFORM_BLOCKS=35374]="MAX_COMBINED_UNIFORM_BLOCKS",e[e.MAX_UNIFORM_BUFFER_BINDINGS=35375]="MAX_UNIFORM_BUFFER_BINDINGS",e[e.MAX_UNIFORM_BLOCK_SIZE=35376]="MAX_UNIFORM_BLOCK_SIZE",e[e.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS=35377]="MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",e[e.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS=35379]="MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",e[e.UNIFORM_BUFFER_OFFSET_ALIGNMENT=35380]="UNIFORM_BUFFER_OFFSET_ALIGNMENT",e[e.ACTIVE_UNIFORM_BLOCKS=35382]="ACTIVE_UNIFORM_BLOCKS",e[e.UNIFORM_TYPE=35383]="UNIFORM_TYPE",e[e.UNIFORM_SIZE=35384]="UNIFORM_SIZE",e[e.UNIFORM_BLOCK_INDEX=35386]="UNIFORM_BLOCK_INDEX",e[e.UNIFORM_OFFSET=35387]="UNIFORM_OFFSET",e[e.UNIFORM_ARRAY_STRIDE=35388]="UNIFORM_ARRAY_STRIDE",e[e.UNIFORM_MATRIX_STRIDE=35389]="UNIFORM_MATRIX_STRIDE",e[e.UNIFORM_IS_ROW_MAJOR=35390]="UNIFORM_IS_ROW_MAJOR",e[e.UNIFORM_BLOCK_BINDING=35391]="UNIFORM_BLOCK_BINDING",e[e.UNIFORM_BLOCK_DATA_SIZE=35392]="UNIFORM_BLOCK_DATA_SIZE",e[e.UNIFORM_BLOCK_ACTIVE_UNIFORMS=35394]="UNIFORM_BLOCK_ACTIVE_UNIFORMS",e[e.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES=35395]="UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",e[e.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER=35396]="UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",e[e.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER=35398]="UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",e[e.OBJECT_TYPE=37138]="OBJECT_TYPE",e[e.SYNC_CONDITION=37139]="SYNC_CONDITION",e[e.SYNC_STATUS=37140]="SYNC_STATUS",e[e.SYNC_FLAGS=37141]="SYNC_FLAGS",e[e.SYNC_FENCE=37142]="SYNC_FENCE",e[e.SYNC_GPU_COMMANDS_COMPLETE=37143]="SYNC_GPU_COMMANDS_COMPLETE",e[e.UNSIGNALED=37144]="UNSIGNALED",e[e.SIGNALED=37145]="SIGNALED",e[e.ALREADY_SIGNALED=37146]="ALREADY_SIGNALED",e[e.TIMEOUT_EXPIRED=37147]="TIMEOUT_EXPIRED",e[e.CONDITION_SATISFIED=37148]="CONDITION_SATISFIED",e[e.WAIT_FAILED=37149]="WAIT_FAILED",e[e.SYNC_FLUSH_COMMANDS_BIT=1]="SYNC_FLUSH_COMMANDS_BIT",e[e.COLOR=6144]="COLOR",e[e.DEPTH=6145]="DEPTH",e[e.STENCIL=6146]="STENCIL",e[e.MIN=32775]="MIN",e[e.MAX=32776]="MAX",e[e.DEPTH_COMPONENT24=33190]="DEPTH_COMPONENT24",e[e.STREAM_READ=35041]="STREAM_READ",e[e.STREAM_COPY=35042]="STREAM_COPY",e[e.STATIC_READ=35045]="STATIC_READ",e[e.STATIC_COPY=35046]="STATIC_COPY",e[e.DYNAMIC_READ=35049]="DYNAMIC_READ",e[e.DYNAMIC_COPY=35050]="DYNAMIC_COPY",e[e.DEPTH_COMPONENT32F=36012]="DEPTH_COMPONENT32F",e[e.DEPTH32F_STENCIL8=36013]="DEPTH32F_STENCIL8",e[e.INVALID_INDEX=4294967295]="INVALID_INDEX",e[e.TIMEOUT_IGNORED=-1]="TIMEOUT_IGNORED",e[e.MAX_CLIENT_WAIT_TIMEOUT_WEBGL=37447]="MAX_CLIENT_WAIT_TIMEOUT_WEBGL",e[e.UNMASKED_VENDOR_WEBGL=37445]="UNMASKED_VENDOR_WEBGL",e[e.UNMASKED_RENDERER_WEBGL=37446]="UNMASKED_RENDERER_WEBGL",e[e.MAX_TEXTURE_MAX_ANISOTROPY_EXT=34047]="MAX_TEXTURE_MAX_ANISOTROPY_EXT",e[e.TEXTURE_MAX_ANISOTROPY_EXT=34046]="TEXTURE_MAX_ANISOTROPY_EXT",e[e.R16_EXT=33322]="R16_EXT",e[e.RG16_EXT=33324]="RG16_EXT",e[e.RGB16_EXT=32852]="RGB16_EXT",e[e.RGBA16_EXT=32859]="RGBA16_EXT",e[e.R16_SNORM_EXT=36760]="R16_SNORM_EXT",e[e.RG16_SNORM_EXT=36761]="RG16_SNORM_EXT",e[e.RGB16_SNORM_EXT=36762]="RGB16_SNORM_EXT",e[e.RGBA16_SNORM_EXT=36763]="RGBA16_SNORM_EXT",e[e.COMPRESSED_RGB_S3TC_DXT1_EXT=33776]="COMPRESSED_RGB_S3TC_DXT1_EXT",e[e.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777]="COMPRESSED_RGBA_S3TC_DXT1_EXT",e[e.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778]="COMPRESSED_RGBA_S3TC_DXT3_EXT",e[e.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779]="COMPRESSED_RGBA_S3TC_DXT5_EXT",e[e.COMPRESSED_SRGB_S3TC_DXT1_EXT=35916]="COMPRESSED_SRGB_S3TC_DXT1_EXT",e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT=35917]="COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT",e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT=35918]="COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT",e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT=35919]="COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT",e[e.COMPRESSED_RED_RGTC1_EXT=36283]="COMPRESSED_RED_RGTC1_EXT",e[e.COMPRESSED_SIGNED_RED_RGTC1_EXT=36284]="COMPRESSED_SIGNED_RED_RGTC1_EXT",e[e.COMPRESSED_RED_GREEN_RGTC2_EXT=36285]="COMPRESSED_RED_GREEN_RGTC2_EXT",e[e.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT=36286]="COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT",e[e.COMPRESSED_RGBA_BPTC_UNORM_EXT=36492]="COMPRESSED_RGBA_BPTC_UNORM_EXT",e[e.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT=36493]="COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT",e[e.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT=36494]="COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT",e[e.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT=36495]="COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT",e[e.COMPRESSED_R11_EAC=37488]="COMPRESSED_R11_EAC",e[e.COMPRESSED_SIGNED_R11_EAC=37489]="COMPRESSED_SIGNED_R11_EAC",e[e.COMPRESSED_RG11_EAC=37490]="COMPRESSED_RG11_EAC",e[e.COMPRESSED_SIGNED_RG11_EAC=37491]="COMPRESSED_SIGNED_RG11_EAC",e[e.COMPRESSED_RGB8_ETC2=37492]="COMPRESSED_RGB8_ETC2",e[e.COMPRESSED_RGBA8_ETC2_EAC=37493]="COMPRESSED_RGBA8_ETC2_EAC",e[e.COMPRESSED_SRGB8_ETC2=37494]="COMPRESSED_SRGB8_ETC2",e[e.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC=37495]="COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",e[e.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2=37496]="COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",e[e.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2=37497]="COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",e[e.COMPRESSED_RGB_PVRTC_4BPPV1_IMG=35840]="COMPRESSED_RGB_PVRTC_4BPPV1_IMG",e[e.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG=35842]="COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",e[e.COMPRESSED_RGB_PVRTC_2BPPV1_IMG=35841]="COMPRESSED_RGB_PVRTC_2BPPV1_IMG",e[e.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG=35843]="COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",e[e.COMPRESSED_RGB_ETC1_WEBGL=36196]="COMPRESSED_RGB_ETC1_WEBGL",e[e.COMPRESSED_RGB_ATC_WEBGL=35986]="COMPRESSED_RGB_ATC_WEBGL",e[e.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL=35986]="COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL",e[e.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL=34798]="COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL",e[e.COMPRESSED_RGBA_ASTC_4x4_KHR=37808]="COMPRESSED_RGBA_ASTC_4x4_KHR",e[e.COMPRESSED_RGBA_ASTC_5x4_KHR=37809]="COMPRESSED_RGBA_ASTC_5x4_KHR",e[e.COMPRESSED_RGBA_ASTC_5x5_KHR=37810]="COMPRESSED_RGBA_ASTC_5x5_KHR",e[e.COMPRESSED_RGBA_ASTC_6x5_KHR=37811]="COMPRESSED_RGBA_ASTC_6x5_KHR",e[e.COMPRESSED_RGBA_ASTC_6x6_KHR=37812]="COMPRESSED_RGBA_ASTC_6x6_KHR",e[e.COMPRESSED_RGBA_ASTC_8x5_KHR=37813]="COMPRESSED_RGBA_ASTC_8x5_KHR",e[e.COMPRESSED_RGBA_ASTC_8x6_KHR=37814]="COMPRESSED_RGBA_ASTC_8x6_KHR",e[e.COMPRESSED_RGBA_ASTC_8x8_KHR=37815]="COMPRESSED_RGBA_ASTC_8x8_KHR",e[e.COMPRESSED_RGBA_ASTC_10x5_KHR=37816]="COMPRESSED_RGBA_ASTC_10x5_KHR",e[e.COMPRESSED_RGBA_ASTC_10x6_KHR=37817]="COMPRESSED_RGBA_ASTC_10x6_KHR",e[e.COMPRESSED_RGBA_ASTC_10x8_KHR=37818]="COMPRESSED_RGBA_ASTC_10x8_KHR",e[e.COMPRESSED_RGBA_ASTC_10x10_KHR=37819]="COMPRESSED_RGBA_ASTC_10x10_KHR",e[e.COMPRESSED_RGBA_ASTC_12x10_KHR=37820]="COMPRESSED_RGBA_ASTC_12x10_KHR",e[e.COMPRESSED_RGBA_ASTC_12x12_KHR=37821]="COMPRESSED_RGBA_ASTC_12x12_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR=37840]="COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR=37841]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR=37842]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR=37843]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR=37844]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR=37845]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR=37846]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR=37847]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR=37848]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR=37849]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR=37850]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR=37851]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR=37852]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",e[e.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR=37853]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",e[e.QUERY_COUNTER_BITS_EXT=34916]="QUERY_COUNTER_BITS_EXT",e[e.CURRENT_QUERY_EXT=34917]="CURRENT_QUERY_EXT",e[e.QUERY_RESULT_EXT=34918]="QUERY_RESULT_EXT",e[e.QUERY_RESULT_AVAILABLE_EXT=34919]="QUERY_RESULT_AVAILABLE_EXT",e[e.TIME_ELAPSED_EXT=35007]="TIME_ELAPSED_EXT",e[e.TIMESTAMP_EXT=36392]="TIMESTAMP_EXT",e[e.GPU_DISJOINT_EXT=36795]="GPU_DISJOINT_EXT",e[e.COMPLETION_STATUS_KHR=37297]="COMPLETION_STATUS_KHR",e[e.DEPTH_CLAMP_EXT=34383]="DEPTH_CLAMP_EXT",e[e.FIRST_VERTEX_CONVENTION_WEBGL=36429]="FIRST_VERTEX_CONVENTION_WEBGL",e[e.LAST_VERTEX_CONVENTION_WEBGL=36430]="LAST_VERTEX_CONVENTION_WEBGL",e[e.PROVOKING_VERTEX_WEBL=36431]="PROVOKING_VERTEX_WEBL",e[e.POLYGON_MODE_WEBGL=2880]="POLYGON_MODE_WEBGL",e[e.POLYGON_OFFSET_LINE_WEBGL=10754]="POLYGON_OFFSET_LINE_WEBGL",e[e.LINE_WEBGL=6913]="LINE_WEBGL",e[e.FILL_WEBGL=6914]="FILL_WEBGL",e[e.MAX_CLIP_DISTANCES_WEBGL=3378]="MAX_CLIP_DISTANCES_WEBGL",e[e.MAX_CULL_DISTANCES_WEBGL=33529]="MAX_CULL_DISTANCES_WEBGL",e[e.MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL=33530]="MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL",e[e.CLIP_DISTANCE0_WEBGL=12288]="CLIP_DISTANCE0_WEBGL",e[e.CLIP_DISTANCE1_WEBGL=12289]="CLIP_DISTANCE1_WEBGL",e[e.CLIP_DISTANCE2_WEBGL=12290]="CLIP_DISTANCE2_WEBGL",e[e.CLIP_DISTANCE3_WEBGL=12291]="CLIP_DISTANCE3_WEBGL",e[e.CLIP_DISTANCE4_WEBGL=12292]="CLIP_DISTANCE4_WEBGL",e[e.CLIP_DISTANCE5_WEBGL=12293]="CLIP_DISTANCE5_WEBGL",e[e.CLIP_DISTANCE6_WEBGL=12294]="CLIP_DISTANCE6_WEBGL",e[e.CLIP_DISTANCE7_WEBGL=12295]="CLIP_DISTANCE7_WEBGL",e[e.POLYGON_OFFSET_CLAMP_EXT=36379]="POLYGON_OFFSET_CLAMP_EXT",e[e.LOWER_LEFT_EXT=36001]="LOWER_LEFT_EXT",e[e.UPPER_LEFT_EXT=36002]="UPPER_LEFT_EXT",e[e.NEGATIVE_ONE_TO_ONE_EXT=37726]="NEGATIVE_ONE_TO_ONE_EXT",e[e.ZERO_TO_ONE_EXT=37727]="ZERO_TO_ONE_EXT",e[e.CLIP_ORIGIN_EXT=37724]="CLIP_ORIGIN_EXT",e[e.CLIP_DEPTH_MODE_EXT=37725]="CLIP_DEPTH_MODE_EXT",e[e.SRC1_COLOR_WEBGL=35065]="SRC1_COLOR_WEBGL",e[e.SRC1_ALPHA_WEBGL=34185]="SRC1_ALPHA_WEBGL",e[e.ONE_MINUS_SRC1_COLOR_WEBGL=35066]="ONE_MINUS_SRC1_COLOR_WEBGL",e[e.ONE_MINUS_SRC1_ALPHA_WEBGL=35067]="ONE_MINUS_SRC1_ALPHA_WEBGL",e[e.MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL=35068]="MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL",e[e.MIRROR_CLAMP_TO_EDGE_EXT=34627]="MIRROR_CLAMP_TO_EDGE_EXT"})(ci||(ci={}));const j_={WEBGL_depth_texture:{UNSIGNED_INT_24_8_WEBGL:34042},OES_element_index_uint:{},OES_texture_float:{},OES_texture_half_float:{HALF_FLOAT_OES:5131},EXT_color_buffer_float:{},OES_standard_derivatives:{FRAGMENT_SHADER_DERIVATIVE_HINT_OES:35723},EXT_frag_depth:{},EXT_blend_minmax:{MIN_EXT:32775,MAX_EXT:32776},EXT_shader_texture_lod:{}},K_=e=>({drawBuffersWEBGL(t){return e.drawBuffers(t)},COLOR_ATTACHMENT0_WEBGL:36064,COLOR_ATTACHMENT1_WEBGL:36065,COLOR_ATTACHMENT2_WEBGL:36066,COLOR_ATTACHMENT3_WEBGL:36067}),q_=e=>({VERTEX_ARRAY_BINDING_OES:34229,createVertexArrayOES(){return e.createVertexArray()},deleteVertexArrayOES(t){return e.deleteVertexArray(t)},isVertexArrayOES(t){return e.isVertexArray(t)},bindVertexArrayOES(t){return e.bindVertexArray(t)}}),G_=e=>({VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:35070,drawArraysInstancedANGLE(...t){return e.drawArraysInstanced(...t)},drawElementsInstancedANGLE(...t){return e.drawElementsInstanced(...t)},vertexAttribDivisorANGLE(...t){return e.vertexAttribDivisor(...t)}});function Z_(e=!0){const t=HTMLCanvasElement.prototype;if(!e&&t.originalGetContext){t.getContext=t.originalGetContext,t.originalGetContext=void 0;return}t.originalGetContext=t.getContext,t.getContext=function(i,n){if(i==="webgl"||i==="experimental-webgl"){const r=this.originalGetContext("webgl2",n);return r instanceof HTMLElement&&Q_(r),r}return this.originalGetContext(i,n)}}function Q_(e){e.getExtension("EXT_color_buffer_float");const t={...j_,WEBGL_disjoint_timer_query:e.getExtension("EXT_disjoint_timer_query_webgl2"),WEBGL_draw_buffers:K_(e),OES_vertex_array_object:q_(e),ANGLE_instanced_arrays:G_(e)},i=e.getExtension;e.getExtension=function(r){const s=i.call(e,r);return s||(r in t?t[r]:null)};const n=e.getSupportedExtensions;e.getSupportedExtensions=function(){const r=n.apply(e)||[];return r==null?void 0:r.concat(Object.keys(t))}}async function Hu(e,t){const i=document.getElementsByTagName("head")[0];if(!i)throw new Error("loadScript");const n=document.createElement("script");return n.setAttribute("type","text/javascript"),n.setAttribute("src",e),new Promise((r,s)=>{n.onload=r,n.onerror=o=>s(new Error(`Unable to load script '${e}': ${o}`)),i.appendChild(n)})}function fr(e){const t=e.luma||{_polyfilled:!1,extensions:{},softwareRenderer:!1};return t._polyfilled??(t._polyfilled=!1),t.extensions||(t.extensions={}),e.luma=t,t}const J_=1;let se=null,$u=!1;const Do={debugSpectorJS:C.get("debug-spectorjs"),debugSpectorJSUrl:"https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js",gl:void 0};async function eb(e){if(!globalThis.SPECTOR)try{await Hu(e.debugSpectorJSUrl||Do.debugSpectorJSUrl)}catch(t){C.warn(String(t))}}function tb(e){var t;if(e={...Do,...e},!e.debugSpectorJS)return null;if(!se&&globalThis.SPECTOR&&!((t=globalThis.luma)!=null&&t.spector)){C.probe(J_,"SPECTOR found and initialized. Start with `luma.spector.displayUI()`")();const{Spector:i}=globalThis.SPECTOR;se=new i,globalThis.luma&&(globalThis.luma.spector=se)}if(!se)return null;if($u||($u=!0,se.spyCanvases(),se==null||se.onCaptureStarted.add(i=>C.info("Spector capture started:",i)()),se==null||se.onCapture.add(i=>{C.info("Spector capture complete:",i)(),se==null||se.getResultUI(),se==null||se.resultView.display(),se==null||se.resultView.addCapture(i)})),e.gl){const i=e.gl,n=fr(i),r=n.device;se==null||se.startCapture(e.gl,500),n.device=r,new Promise(s=>setTimeout(s,2e3)).then(s=>{C.info("Spector capture stopped after 2 seconds")(),se==null||se.stopCapture()})}return se}const ib="https://unpkg.com/webgl-debug@2.0.1/index.js";function Xu(e){return e.luma=e.luma||{},e.luma}async function nb(){Mt()&&!globalThis.WebGLDebugUtils&&(globalThis.global=globalThis.global||globalThis,globalThis.global.module={},await Hu(ib))}function rb(e,t={}){return t.debugWebGL||t.traceWebGL?ob(e,t):sb(e)}function sb(e){const t=Xu(e);return t.realContext?t.realContext:e}function ob(e,t){if(!globalThis.WebGLDebugUtils)return C.warn("webgl-debug not loaded")(),e;const i=Xu(e);if(i.debugContext)return i.debugContext;globalThis.WebGLDebugUtils.init({...ci,...e});const n=globalThis.WebGLDebugUtils.makeDebugContext(e,ab.bind(null,t),lb.bind(null,t));for(const o in ci)!(o in n)&&typeof ci[o]=="number"&&(n[o]=ci[o]);class r{}Object.setPrototypeOf(n,Object.getPrototypeOf(e)),Object.setPrototypeOf(r,n);const s=Object.create(r);return i.realContext=e,i.debugContext=s,s.luma=i,s.debug=!0,s}function Yu(e,t){t=Array.from(t).map(n=>n===void 0?"undefined":n);let i=globalThis.WebGLDebugUtils.glFunctionArgsToString(e,t);return i=`${i.slice(0,100)}${i.length>100?"...":""}`,`gl.${e}(${i})`}function ab(e,t,i,n){n=Array.from(n).map(a=>a===void 0?"undefined":a);const r=globalThis.WebGLDebugUtils.glEnumToString(t),s=globalThis.WebGLDebugUtils.glFunctionArgsToString(i,n),o=`${r} in gl.${i}(${s})`;C.error("%cWebGL","color: white; background: red; padding: 2px 6px; border-radius: 3px;",o)();debugger;throw new Error(o)}function lb(e,t,i){let n="";e.traceWebGL&&C.level>=1&&(n=Yu(t,i),C.info(1,"%cWebGL","color: white; background: blue; padding: 2px 6px; border-radius: 3px;",n)());for(const r of i)if(r===void 0){n=n||Yu(t,i);debugger}}const Ki=1;class cb extends QS{constructor(){super();f(this,"type","webgl");Bt.defaultProps={...Bt.defaultProps,...Do}}enforceWebGL2(i){Z_(i)}isSupported(){return typeof WebGL2RenderingContext<"u"}isDeviceHandle(i){return typeof WebGL2RenderingContext<"u"&&i instanceof WebGL2RenderingContext?!0:(typeof WebGLRenderingContext<"u"&&i instanceof WebGLRenderingContext&&C.warn("WebGL1 is not supported",i)(),!1)}async attach(i,n={}){const{WebGLDevice:r}=await Promise.resolve().then(()=>bd);if(i instanceof r)return i;const s=r.getDeviceFromContext(i);if(s)return s;if(!ub(i))throw new Error("Invalid WebGL2RenderingContext");const o=n.createCanvasContext===!0?{}:n.createCanvasContext;return new r({...n,_handle:i,createCanvasContext:{canvas:i.canvas,autoResize:!1,...o}})}async create(i={}){const{WebGLDevice:n}=await Promise.resolve().then(()=>bd),r=[];(i.debugWebGL||i.debug)&&r.push(nb()),i.debugSpectorJS&&r.push(eb(i));const s=await Promise.allSettled(r);for(const o of s)o.status==="rejected"&&C.error(`Failed to initialize debug libraries ${o.reason}`)();try{const o=new n(i);C.groupCollapsed(Ki,`WebGLDevice ${o.id} created`)();const a=`${o._reused?"Reusing":"Created"} device with WebGL2 ${o.props.debug?"debug ":""}context: ${o.info.vendor}, ${o.info.renderer} for canvas: ${o.canvasContext.id}`;return C.probe(Ki,a)(),C.table(Ki,o.info)(),o}finally{C.groupEnd(Ki)(),C.info(Ki,"%cWebGL call tracing: luma.log.set('debug-webgl') ","color: white; background: blue; padding: 2px 6px; border-radius: 3px;")()}}}function ub(e){return typeof WebGL2RenderingContext<"u"&&e instanceof WebGL2RenderingContext?!0:!!(e&&typeof e.createVertexArray=="function")}const db=new cb,Fo={3042:!1,32773:new Float32Array([0,0,0,0]),32777:32774,34877:32774,32969:1,32968:0,32971:1,32970:0,3106:new Float32Array([0,0,0,0]),3107:[!0,!0,!0,!0],2884:!1,2885:1029,2929:!1,2931:1,2932:513,2928:new Float32Array([0,1]),2930:!0,3024:!0,35725:null,36006:null,36007:null,34229:null,34964:null,2886:2305,33170:4352,2849:1,32823:!1,32824:0,10752:0,32926:!1,32928:!1,32938:1,32939:!1,3089:!1,3088:new Int32Array([0,0,1024,1024]),2960:!1,2961:0,2968:4294967295,36005:4294967295,2962:519,2967:0,2963:4294967295,34816:519,36003:0,36004:4294967295,2964:7680,2965:7680,2966:7680,34817:7680,34818:7680,34819:7680,2978:[0,0,1024,1024],36389:null,36662:null,36663:null,35053:null,35055:null,35723:4352,36010:null,35977:!1,3333:4,3317:4,37440:!1,37441:!1,37443:37444,3330:0,3332:0,3331:0,3314:0,32878:0,3316:0,3315:0,32877:0},xe=(e,t,i)=>t?e.enable(i):e.disable(i),ju=(e,t,i)=>e.hint(i,t),Ue=(e,t,i)=>e.pixelStorei(i,t),Ku=(e,t,i)=>{const n=i===36006?36009:36008;return e.bindFramebuffer(n,t)},qi=(e,t,i)=>{const r={34964:34962,36662:36662,36663:36663,35053:35051,35055:35052}[i];e.bindBuffer(r,t)};function Mo(e){return Array.isArray(e)||ArrayBuffer.isView(e)&&!(e instanceof DataView)}const hb={3042:xe,32773:(e,t)=>e.blendColor(...t),32777:"blendEquation",34877:"blendEquation",32969:"blendFunc",32968:"blendFunc",32971:"blendFunc",32970:"blendFunc",3106:(e,t)=>e.clearColor(...t),3107:(e,t)=>e.colorMask(...t),2884:xe,2885:(e,t)=>e.cullFace(t),2929:xe,2931:(e,t)=>e.clearDepth(t),2932:(e,t)=>e.depthFunc(t),2928:(e,t)=>e.depthRange(...t),2930:(e,t)=>e.depthMask(t),3024:xe,35723:ju,35725:(e,t)=>e.useProgram(t),36007:(e,t)=>e.bindRenderbuffer(36161,t),36389:(e,t)=>{var i;return(i=e.bindTransformFeedback)==null?void 0:i.call(e,36386,t)},34229:(e,t)=>e.bindVertexArray(t),36006:Ku,36010:Ku,34964:qi,36662:qi,36663:qi,35053:qi,35055:qi,2886:(e,t)=>e.frontFace(t),33170:ju,2849:(e,t)=>e.lineWidth(t),32823:xe,32824:"polygonOffset",10752:"polygonOffset",35977:xe,32926:xe,32928:xe,32938:"sampleCoverage",32939:"sampleCoverage",3089:xe,3088:(e,t)=>e.scissor(...t),2960:xe,2961:(e,t)=>e.clearStencil(t),2968:(e,t)=>e.stencilMaskSeparate(1028,t),36005:(e,t)=>e.stencilMaskSeparate(1029,t),2962:"stencilFuncFront",2967:"stencilFuncFront",2963:"stencilFuncFront",34816:"stencilFuncBack",36003:"stencilFuncBack",36004:"stencilFuncBack",2964:"stencilOpFront",2965:"stencilOpFront",2966:"stencilOpFront",34817:"stencilOpBack",34818:"stencilOpBack",34819:"stencilOpBack",2978:(e,t)=>e.viewport(...t),34383:xe,10754:xe,12288:xe,12289:xe,12290:xe,12291:xe,12292:xe,12293:xe,12294:xe,12295:xe,3333:Ue,3317:Ue,37440:Ue,37441:Ue,37443:Ue,3330:Ue,3332:Ue,3331:Ue,3314:Ue,32878:Ue,3316:Ue,3315:Ue,32877:Ue,framebuffer:(e,t)=>{const i=t&&"handle"in t?t.handle:t;return e.bindFramebuffer(36160,i)},blend:(e,t)=>t?e.enable(3042):e.disable(3042),blendColor:(e,t)=>e.blendColor(...t),blendEquation:(e,t)=>{const i=typeof t=="number"?[t,t]:t;e.blendEquationSeparate(...i)},blendFunc:(e,t)=>{const i=(t==null?void 0:t.length)===2?[...t,...t]:t;e.blendFuncSeparate(...i)},clearColor:(e,t)=>e.clearColor(...t),clearDepth:(e,t)=>e.clearDepth(t),clearStencil:(e,t)=>e.clearStencil(t),colorMask:(e,t)=>e.colorMask(...t),cull:(e,t)=>t?e.enable(2884):e.disable(2884),cullFace:(e,t)=>e.cullFace(t),depthTest:(e,t)=>t?e.enable(2929):e.disable(2929),depthFunc:(e,t)=>e.depthFunc(t),depthMask:(e,t)=>e.depthMask(t),depthRange:(e,t)=>e.depthRange(...t),dither:(e,t)=>t?e.enable(3024):e.disable(3024),derivativeHint:(e,t)=>{e.hint(35723,t)},frontFace:(e,t)=>e.frontFace(t),mipmapHint:(e,t)=>e.hint(33170,t),lineWidth:(e,t)=>e.lineWidth(t),polygonOffsetFill:(e,t)=>t?e.enable(32823):e.disable(32823),polygonOffset:(e,t)=>e.polygonOffset(...t),sampleCoverage:(e,t)=>e.sampleCoverage(t[0],t[1]||!1),scissorTest:(e,t)=>t?e.enable(3089):e.disable(3089),scissor:(e,t)=>e.scissor(...t),stencilTest:(e,t)=>t?e.enable(2960):e.disable(2960),stencilMask:(e,t)=>{t=Mo(t)?t:[t,t];const[i,n]=t;e.stencilMaskSeparate(1028,i),e.stencilMaskSeparate(1029,n)},stencilFunc:(e,t)=>{t=Mo(t)&&t.length===3?[...t,...t]:t;const[i,n,r,s,o,a]=t;e.stencilFuncSeparate(1028,i,n,r),e.stencilFuncSeparate(1029,s,o,a)},stencilOp:(e,t)=>{t=Mo(t)&&t.length===3?[...t,...t]:t;const[i,n,r,s,o,a]=t;e.stencilOpSeparate(1028,i,n,r),e.stencilOpSeparate(1029,s,o,a)},viewport:(e,t)=>e.viewport(...t)};function fe(e,t,i){return t[e]!==void 0?t[e]:i[e]}const fb={blendEquation:(e,t,i)=>e.blendEquationSeparate(fe(32777,t,i),fe(34877,t,i)),blendFunc:(e,t,i)=>e.blendFuncSeparate(fe(32969,t,i),fe(32968,t,i),fe(32971,t,i),fe(32970,t,i)),polygonOffset:(e,t,i)=>e.polygonOffset(fe(32824,t,i),fe(10752,t,i)),sampleCoverage:(e,t,i)=>e.sampleCoverage(fe(32938,t,i),fe(32939,t,i)),stencilFuncFront:(e,t,i)=>e.stencilFuncSeparate(1028,fe(2962,t,i),fe(2967,t,i),fe(2963,t,i)),stencilFuncBack:(e,t,i)=>e.stencilFuncSeparate(1029,fe(34816,t,i),fe(36003,t,i),fe(36004,t,i)),stencilOpFront:(e,t,i)=>e.stencilOpSeparate(1028,fe(2964,t,i),fe(2965,t,i),fe(2966,t,i)),stencilOpBack:(e,t,i)=>e.stencilOpSeparate(1029,fe(34817,t,i),fe(34818,t,i),fe(34819,t,i))},qu={enable:(e,t)=>e({[t]:!0}),disable:(e,t)=>e({[t]:!1}),pixelStorei:(e,t,i)=>e({[t]:i}),hint:(e,t,i)=>e({[t]:i}),useProgram:(e,t)=>e({35725:t}),bindRenderbuffer:(e,t,i)=>e({36007:i}),bindTransformFeedback:(e,t,i)=>e({36389:i}),bindVertexArray:(e,t)=>e({34229:t}),bindFramebuffer:(e,t,i)=>{switch(t){case 36160:return e({36006:i,36010:i});case 36009:return e({36006:i});case 36008:return e({36010:i});default:return null}},bindBuffer:(e,t,i)=>{const n={34962:[34964],36662:[36662],36663:[36663],35051:[35053],35052:[35055]}[t];return n?e({[n]:i}):{valueChanged:!0}},blendColor:(e,t,i,n,r)=>e({32773:new Float32Array([t,i,n,r])}),blendEquation:(e,t)=>e({32777:t,34877:t}),blendEquationSeparate:(e,t,i)=>e({32777:t,34877:i}),blendFunc:(e,t,i)=>e({32969:t,32968:i,32971:t,32970:i}),blendFuncSeparate:(e,t,i,n,r)=>e({32969:t,32968:i,32971:n,32970:r}),clearColor:(e,t,i,n,r)=>e({3106:new Float32Array([t,i,n,r])}),clearDepth:(e,t)=>e({2931:t}),clearStencil:(e,t)=>e({2961:t}),colorMask:(e,t,i,n,r)=>e({3107:[t,i,n,r]}),cullFace:(e,t)=>e({2885:t}),depthFunc:(e,t)=>e({2932:t}),depthRange:(e,t,i)=>e({2928:new Float32Array([t,i])}),depthMask:(e,t)=>e({2930:t}),frontFace:(e,t)=>e({2886:t}),lineWidth:(e,t)=>e({2849:t}),polygonOffset:(e,t,i)=>e({32824:t,10752:i}),sampleCoverage:(e,t,i)=>e({32938:t,32939:i}),scissor:(e,t,i,n,r)=>e({3088:new Int32Array([t,i,n,r])}),stencilMask:(e,t)=>e({2968:t,36005:t}),stencilMaskSeparate:(e,t,i)=>e({[t===1028?2968:36005]:i}),stencilFunc:(e,t,i,n)=>e({2962:t,2967:i,2963:n,34816:t,36003:i,36004:n}),stencilFuncSeparate:(e,t,i,n,r)=>e({[t===1028?2962:34816]:i,[t===1028?2967:36003]:n,[t===1028?2963:36004]:r}),stencilOp:(e,t,i,n)=>e({2964:t,2965:i,2966:n,34817:t,34818:i,34819:n}),stencilOpSeparate:(e,t,i,n,r)=>e({[t===1028?2964:34817]:i,[t===1028?2965:34818]:n,[t===1028?2966:34819]:r}),viewport:(e,t,i,n,r)=>e({2978:[t,i,n,r]})},st=(e,t)=>e.isEnabled(t),Gu={3042:st,2884:st,2929:st,3024:st,32823:st,32926:st,32928:st,3089:st,2960:st,35977:st},pb=new Set([34016,36388,36387,35983,35368,34965,35739,35738,3074,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,35097,32873,35869,32874,34068]);function ui(e,t){var r;if(mb(t))return;const i={};for(const s in t){const o=Number(s),a=hb[s];a&&(typeof a=="string"?i[a]=!0:a(e,t[s],o))}const n=(r=e.lumaState)==null?void 0:r.cache;if(n)for(const s in i){const o=fb[s];o(e,t,n)}}function Zu(e,t=Fo){if(typeof t=="number"){const r=t,s=Gu[r];return s?s(e,r):e.getParameter(r)}const i=Array.isArray(t)?t:Object.keys(t),n={};for(const r of i){const s=Gu[r];n[r]=s?s(e,Number(r)):e.getParameter(Number(r))}return n}function gb(e){ui(e,Fo)}function mb(e){for(const t in e)return!1;return!0}function xb(e,t){if(e===t)return!0;if(Qu(e)&&Qu(t)&&e.length===t.length){for(let i=0;i<e.length;++i)if(e[i]!==t[i])return!1;return!0}return!1}function Qu(e){return Array.isArray(e)||ArrayBuffer.isView(e)}class Pt{constructor(t,i){f(this,"gl");f(this,"program",null);f(this,"stateStack",[]);f(this,"enable",!0);f(this,"cache",null);f(this,"log");f(this,"initialized",!1);this.gl=t,this.log=(i==null?void 0:i.log)||(()=>{}),this._updateCache=this._updateCache.bind(this),Object.seal(this)}static get(t){return t.lumaState}push(t={}){this.stateStack.push({})}pop(){const t=this.stateStack[this.stateStack.length-1];ui(this.gl,t),this.stateStack.pop()}trackState(t,i){if(this.cache=i!=null&&i.copyState?Zu(t):Object.assign({},Fo),this.initialized)throw new Error("WebGLStateTracker");this.initialized=!0,this.gl.lumaState=this,yb(t);for(const n in qu){const r=qu[n];Sb(t,n,r)}Ju(t,"getParameter"),Ju(t,"isEnabled")}_updateCache(t){let i=!1,n;const r=this.stateStack.length>0?this.stateStack[this.stateStack.length-1]:null;for(const s in t){const o=t[s],a=this.cache[s];xb(o,a)||(i=!0,n=a,r&&!(s in r)&&(r[s]=a),this.cache[s]=o)}return{valueChanged:i,oldValue:n}}}function Ju(e,t){const i=e[t].bind(e);e[t]=function(r){if(r===void 0||pb.has(r))return i(r);const s=Pt.get(e);return r in s.cache||(s.cache[r]=i(r)),s.enable?s.cache[r]:i(r)},Object.defineProperty(e[t],"name",{value:`${t}-from-cache`,configurable:!1})}function Sb(e,t,i){if(!e[t])return;const n=e[t].bind(e);e[t]=function(...s){const o=Pt.get(e),{valueChanged:a,oldValue:l}=i(o._updateCache,...s);return a&&n(...s),l},Object.defineProperty(e[t],"name",{value:`${t}-to-cache`,configurable:!1})}function yb(e){const t=e.useProgram.bind(e);e.useProgram=function(n){const r=Pt.get(e);r.program!==n&&(t(n),r.program=n)}}function _b(e,t,i){let n="";const r=l=>{const c=l.statusMessage;c&&(n||(n=c))};e.addEventListener("webglcontextcreationerror",r,!1);const s=i.failIfMajorPerformanceCaveat!==!0,o={preserveDrawingBuffer:!0,...i,failIfMajorPerformanceCaveat:!0};let a=null;try{a||(a=e.getContext("webgl2",o)),!a&&o.failIfMajorPerformanceCaveat&&(n||(n="Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow."));let l=!1;if(!a&&s&&(o.failIfMajorPerformanceCaveat=!1,a=e.getContext("webgl2",o),l=!0),a||(a=e.getContext("webgl",{}),a&&(a=null,n||(n="Your browser only supports WebGL1"))),!a)throw n||(n="Your browser does not support WebGL"),new Error(`Failed to create WebGL context: ${n}`);const c=fr(a);c.softwareRenderer=l;const{onContextLost:u,onContextRestored:d}=t;return e.addEventListener("webglcontextlost",h=>u(h),!1),e.addEventListener("webglcontextrestored",h=>d(h),!1),a}finally{e.removeEventListener("webglcontextcreationerror",r,!1)}}function Ot(e,t,i){return i[t]===void 0&&(i[t]=e.getExtension(t)||null),i[t]}function bb(e,t){const i=e.getParameter(7936),n=e.getParameter(7937);Ot(e,"WEBGL_debug_renderer_info",t);const r=t.WEBGL_debug_renderer_info,s=e.getParameter(r?r.UNMASKED_VENDOR_WEBGL:7936),o=e.getParameter(r?r.UNMASKED_RENDERER_WEBGL:7937),a=s||i,l=o||n,c=e.getParameter(7938),u=ed(a,l),d=Tb(a,l),h=vb(a,l);return{type:"webgl",gpu:u,gpuType:h,gpuBackend:d,vendor:a,renderer:l,version:c,shadingLanguage:"glsl",shadingLanguageVersion:300}}function ed(e,t){return/NVIDIA/i.exec(e)||/NVIDIA/i.exec(t)?"nvidia":/INTEL/i.exec(e)||/INTEL/i.exec(t)?"intel":/Apple/i.exec(e)||/Apple/i.exec(t)?"apple":/AMD/i.exec(e)||/AMD/i.exec(t)||/ATI/i.exec(e)||/ATI/i.exec(t)?"amd":/SwiftShader/i.exec(e)||/SwiftShader/i.exec(t)?"software":"unknown"}function Tb(e,t){return/Metal/i.exec(e)||/Metal/i.exec(t)?"metal":/ANGLE/i.exec(e)||/ANGLE/i.exec(t)?"opengl":"unknown"}function vb(e,t){if(/SwiftShader/i.exec(e)||/SwiftShader/i.exec(t))return"cpu";switch(ed(e,t)){case"apple":return Pb(e,t)?"integrated":"unknown";case"intel":return"integrated";case"software":return"cpu";case"unknown":return"unknown";default:return"discrete"}}function Pb(e,t){return/Apple (M\d|A\d|GPU)/i.test(`${e} ${t}`)}function td(e){switch(e){case"uint8":return 5121;case"sint8":return 5120;case"unorm8":return 5121;case"snorm8":return 5120;case"uint16":return 5123;case"sint16":return 5122;case"unorm16":return 5123;case"snorm16":return 5122;case"uint32":return 5125;case"sint32":return 5124;case"float16":return 5131;case"float32":return 5126}throw new Error(String(e))}const Gi="WEBGL_compressed_texture_s3tc",Zi="WEBGL_compressed_texture_s3tc_srgb",di="EXT_texture_compression_rgtc",hi="EXT_texture_compression_bptc",Cb="WEBGL_compressed_texture_etc",Ab="WEBGL_compressed_texture_astc",Rb="WEBGL_compressed_texture_etc1",wb="WEBGL_compressed_texture_pvrtc",Eb="WEBGL_compressed_texture_atc",Ib="EXT_texture_norm16",id="EXT_render_snorm",nd="EXT_color_buffer_float",No="snorm8-renderable-webgl",Bo="norm16-renderable-webgl",Oo="snorm16-renderable-webgl",Uo="float16-renderable-webgl",pr="float32-renderable-webgl",kb="rgb9e5ufloat-renderable-webgl",zo={"float32-renderable-webgl":{extensions:[nd]},"float16-renderable-webgl":{extensions:["EXT_color_buffer_half_float"]},"rgb9e5ufloat-renderable-webgl":{extensions:["WEBGL_render_shared_exponent"]},"snorm8-renderable-webgl":{extensions:[id]},"norm16-webgl":{extensions:[Ib]},"norm16-renderable-webgl":{features:["norm16-webgl"]},"snorm16-renderable-webgl":{features:["norm16-webgl"],extensions:[id]},"float32-filterable":{extensions:["OES_texture_float_linear"]},"float16-filterable-webgl":{extensions:["OES_texture_half_float_linear"]},"texture-filterable-anisotropic-webgl":{extensions:["EXT_texture_filter_anisotropic"]},"texture-blend-float-webgl":{extensions:["EXT_float_blend"]},"texture-compression-bc":{extensions:[Gi,Zi,di,hi]},"texture-compression-bc5-webgl":{extensions:[di]},"texture-compression-bc7-webgl":{extensions:[hi]},"texture-compression-etc2":{extensions:[Cb]},"texture-compression-astc":{extensions:[Ab]},"texture-compression-etc1-webgl":{extensions:[Rb]},"texture-compression-pvrtc-webgl":{extensions:[wb]},"texture-compression-atc-webgl":{extensions:[Eb]}};function Db(e){return e in zo}function rd(e,t,i){return sd(e,t,i,new Set)}function sd(e,t,i,n){const r=zo[t];if(!r||n.has(t))return!1;n.add(t);const s=(r.features||[]).every(o=>sd(e,o,i,n));return n.delete(t),s?(r.extensions||[]).every(o=>!!Ot(e,o,i)):!1}const gr={r8unorm:{gl:33321,rb:!0},r8snorm:{gl:36756,r:No},r8uint:{gl:33330,rb:!0},r8sint:{gl:33329,rb:!0},rg8unorm:{gl:33323,rb:!0},rg8snorm:{gl:36757,r:No},rg8uint:{gl:33336,rb:!0},rg8sint:{gl:33335,rb:!0},r16uint:{gl:33332,rb:!0},r16sint:{gl:33331,rb:!0},r16float:{gl:33325,rb:!0,r:Uo},r16unorm:{gl:33322,rb:!0,r:Bo},r16snorm:{gl:36760,r:Oo},"rgba4unorm-webgl":{gl:32854,rb:!0},"rgb565unorm-webgl":{gl:36194,rb:!0},"rgb5a1unorm-webgl":{gl:32855,rb:!0},"rgb8unorm-webgl":{gl:32849},"rgb8snorm-webgl":{gl:36758},rgba8unorm:{gl:32856},"rgba8unorm-srgb":{gl:35907},rgba8snorm:{gl:36759,r:No},rgba8uint:{gl:36220},rgba8sint:{gl:36238},bgra8unorm:{},"bgra8unorm-srgb":{},rg16uint:{gl:33338},rg16sint:{gl:33337},rg16float:{gl:33327,rb:!0,r:Uo},rg16unorm:{gl:33324,r:Bo},rg16snorm:{gl:36761,r:Oo},r32uint:{gl:33334,rb:!0},r32sint:{gl:33333,rb:!0},r32float:{gl:33326,r:pr},rgb9e5ufloat:{gl:35901,r:kb},rg11b10ufloat:{gl:35898,rb:!0},rgb10a2unorm:{gl:32857,rb:!0},rgb10a2uint:{gl:36975,rb:!0},"rgb16unorm-webgl":{gl:32852,r:!1},"rgb16snorm-webgl":{gl:36762,r:!1},rg32uint:{gl:33340,rb:!0},rg32sint:{gl:33339,rb:!0},rg32float:{gl:33328,rb:!0,r:pr},rgba16uint:{gl:36214,rb:!0},rgba16sint:{gl:36232,rb:!0},rgba16float:{gl:34842,r:Uo},rgba16unorm:{gl:32859,rb:!0,r:Bo},rgba16snorm:{gl:36763,r:Oo},"rgb32float-webgl":{gl:34837,x:nd,r:pr,dataFormat:6407,types:[5126]},rgba32uint:{gl:36208,rb:!0},rgba32sint:{gl:36226,rb:!0},rgba32float:{gl:34836,rb:!0,r:pr},stencil8:{gl:36168,rb:!0},depth16unorm:{gl:33189,dataFormat:6402,types:[5123],rb:!0},depth24plus:{gl:33190,dataFormat:6402,types:[5125]},depth32float:{gl:36012,dataFormat:6402,types:[5126],rb:!0},"depth24plus-stencil8":{gl:35056,rb:!0,depthTexture:!0,dataFormat:34041,types:[34042]},"depth32float-stencil8":{gl:36013,dataFormat:34041,types:[36269],rb:!0},"bc1-rgb-unorm-webgl":{gl:33776,x:Gi},"bc1-rgb-unorm-srgb-webgl":{gl:35916,x:Zi},"bc1-rgba-unorm":{gl:33777,x:Gi},"bc1-rgba-unorm-srgb":{gl:35916,x:Zi},"bc2-rgba-unorm":{gl:33778,x:Gi},"bc2-rgba-unorm-srgb":{gl:35918,x:Zi},"bc3-rgba-unorm":{gl:33779,x:Gi},"bc3-rgba-unorm-srgb":{gl:35919,x:Zi},"bc4-r-unorm":{gl:36283,x:di},"bc4-r-snorm":{gl:36284,x:di},"bc5-rg-unorm":{gl:36285,x:di},"bc5-rg-snorm":{gl:36286,x:di},"bc6h-rgb-ufloat":{gl:36495,x:hi},"bc6h-rgb-float":{gl:36494,x:hi},"bc7-rgba-unorm":{gl:36492,x:hi},"bc7-rgba-unorm-srgb":{gl:36493,x:hi},"etc2-rgb8unorm":{gl:37492},"etc2-rgb8unorm-srgb":{gl:37494},"etc2-rgb8a1unorm":{gl:37496},"etc2-rgb8a1unorm-srgb":{gl:37497},"etc2-rgba8unorm":{gl:37493},"etc2-rgba8unorm-srgb":{gl:37495},"eac-r11unorm":{gl:37488},"eac-r11snorm":{gl:37489},"eac-rg11unorm":{gl:37490},"eac-rg11snorm":{gl:37491},"astc-4x4-unorm":{gl:37808},"astc-4x4-unorm-srgb":{gl:37840},"astc-5x4-unorm":{gl:37809},"astc-5x4-unorm-srgb":{gl:37841},"astc-5x5-unorm":{gl:37810},"astc-5x5-unorm-srgb":{gl:37842},"astc-6x5-unorm":{gl:37811},"astc-6x5-unorm-srgb":{gl:37843},"astc-6x6-unorm":{gl:37812},"astc-6x6-unorm-srgb":{gl:37844},"astc-8x5-unorm":{gl:37813},"astc-8x5-unorm-srgb":{gl:37845},"astc-8x6-unorm":{gl:37814},"astc-8x6-unorm-srgb":{gl:37846},"astc-8x8-unorm":{gl:37815},"astc-8x8-unorm-srgb":{gl:37847},"astc-10x5-unorm":{gl:37816},"astc-10x5-unorm-srgb":{gl:37848},"astc-10x6-unorm":{gl:37817},"astc-10x6-unorm-srgb":{gl:37849},"astc-10x8-unorm":{gl:37818},"astc-10x8-unorm-srgb":{gl:37850},"astc-10x10-unorm":{gl:37819},"astc-10x10-unorm-srgb":{gl:37851},"astc-12x10-unorm":{gl:37820},"astc-12x10-unorm-srgb":{gl:37852},"astc-12x12-unorm":{gl:37821},"astc-12x12-unorm-srgb":{gl:37853},"pvrtc-rgb4unorm-webgl":{gl:35840},"pvrtc-rgba4unorm-webgl":{gl:35842},"pvrtc-rgb2unorm-webgl":{gl:35841},"pvrtc-rgba2unorm-webgl":{gl:35843},"etc1-rbg-unorm-webgl":{gl:36196},"atc-rgb-unorm-webgl":{gl:35986},"atc-rgba-unorm-webgl":{gl:35986},"atc-rgbai-unorm-webgl":{gl:34798}};function Fb(e,t,i){let n=t.create;const r=gr[t.format];(r==null?void 0:r.gl)===void 0&&(n=!1),r!=null&&r.x&&(n=n&&!!Ot(e,r.x,i)),t.format==="stencil8"&&(n=!1);const s=(r==null?void 0:r.r)===!1?!1:(r==null?void 0:r.r)===void 0||rd(e,r.r,i),o=n&&t.render&&s&&Mb(e,t.format,i);return{format:t.format,create:n&&t.create,render:o,filter:n&&t.filter,blend:n&&t.blend,store:n&&t.store}}function Mb(e,t,i){const n=gr[t],r=n==null?void 0:n.gl;if(r===void 0||n!=null&&n.x&&!Ot(e,n.x,i))return!1;const s=e.getParameter(32873),o=e.getParameter(36006),a=e.createTexture(),l=e.createFramebuffer();if(!a||!l)return!1;const c=0;let u=Number(e.getError());for(;u!==c;)u=e.getError();let d=!1;try{if(e.bindTexture(3553,a),e.texStorage2D(3553,1,r,1,1),Number(e.getError())!==c)return!1;e.bindFramebuffer(36160,l),e.framebufferTexture2D(36160,36064,3553,a,0),d=Number(e.checkFramebufferStatus(36160))===36053&&Number(e.getError())===c}finally{e.bindFramebuffer(36160,o),e.deleteFramebuffer(l),e.bindTexture(3553,s),e.deleteTexture(a)}return d}function od(e){var r;const t=gr[e],i=Ob(e),n=Ve.getInfo(e);return n.compressed&&(t.dataFormat=i),{internalFormat:i,format:(t==null?void 0:t.dataFormat)||Bb(n.channels,n.integer,n.normalized,i),type:n.dataType?td(n.dataType):((r=t==null?void 0:t.types)==null?void 0:r[0])||5121,compressed:n.compressed||!1}}function Nb(e){switch(Ve.getInfo(e).attachment){case"depth":return 36096;case"stencil":return 36128;case"depth-stencil":return 33306;default:throw new Error(`Not a depth stencil format: ${e}`)}}function Bb(e,t,i,n){if(n===6408||n===6407)return n;switch(e){case"r":return t&&!i?36244:6403;case"rg":return t&&!i?33320:33319;case"rgb":return t&&!i?36248:6407;case"rgba":return t&&!i?36249:6408;case"bgra":throw new Error("bgra pixels not supported by WebGL");default:return 6408}}function Ob(e){const t=gr[e],i=t==null?void 0:t.gl;if(i===void 0)throw new Error(`Unsupported texture format ${e}`);return i}const ad={"depth-clip-control":"EXT_depth_clamp","timestamp-query":"EXT_disjoint_timer_query_webgl2","compilation-status-async-webgl":"KHR_parallel_shader_compile","polygon-mode-webgl":"WEBGL_polygon_mode","provoking-vertex-webgl":"WEBGL_provoking_vertex","shader-clip-cull-distance-webgl":"WEBGL_clip_cull_distance","shader-noperspective-interpolation-webgl":"NV_shader_noperspective_interpolation","shader-conservative-depth-webgl":"EXT_conservative_depth"};class Ub extends YS{constructor(i,n,r){super([],r);f(this,"gl");f(this,"extensions");f(this,"testedFeatures",new Set);this.gl=i,this.extensions=n,Ot(i,"EXT_color_buffer_float",n)}*[Symbol.iterator](){const i=this.getFeatures();for(const n of i)this.has(n)&&(yield n);return[]}has(i){var n;return(n=this.disabledFeatures)!=null&&n[i]?!1:(this.testedFeatures.has(i)||(this.testedFeatures.add(i),Db(i)&&rd(this.gl,i,this.extensions)&&this.features.add(i),this.getWebGLFeature(i)&&this.features.add(i)),this.features.has(i))}initializeFeatures(){const i=this.getFeatures().filter(n=>n!=="polygon-mode-webgl");for(const n of i)this.has(n)}getFeatures(){return[...Object.keys(ad),...Object.keys(zo)]}getWebGLFeature(i){const n=ad[i];return typeof n=="string"?!!Ot(this.gl,n,this.extensions):!!n}}class zb extends WS{constructor(i){super();f(this,"gl");f(this,"limits",{});this.gl=i}get maxTextureDimension1D(){return 0}get maxTextureDimension2D(){return this.getParameter(3379)}get maxTextureDimension3D(){return this.getParameter(32883)}get maxTextureArrayLayers(){return this.getParameter(35071)}get maxBindGroups(){return 0}get maxDynamicUniformBuffersPerPipelineLayout(){return 0}get maxDynamicStorageBuffersPerPipelineLayout(){return 0}get maxSampledTexturesPerShaderStage(){return this.getParameter(35660)}get maxSamplersPerShaderStage(){return this.getParameter(35661)}get maxStorageBuffersPerShaderStage(){return 0}get maxStorageTexturesPerShaderStage(){return 0}get maxUniformBuffersPerShaderStage(){return this.getParameter(35375)}get maxUniformBufferBindingSize(){return this.getParameter(35376)}get maxStorageBufferBindingSize(){return 0}get minUniformBufferOffsetAlignment(){return this.getParameter(35380)}get minStorageBufferOffsetAlignment(){return 0}get maxVertexBuffers(){return 16}get maxVertexAttributes(){return this.getParameter(34921)}get maxVertexBufferArrayStride(){return 2048}get maxInterStageShaderVariables(){return this.getParameter(35659)}get maxComputeWorkgroupStorageSize(){return 0}get maxComputeInvocationsPerWorkgroup(){return 0}get maxComputeWorkgroupSizeX(){return 0}get maxComputeWorkgroupSizeY(){return 0}get maxComputeWorkgroupSizeZ(){return 0}get maxComputeWorkgroupsPerDimension(){return 0}getParameter(i){return this.limits[i]===void 0&&(this.limits[i]=this.gl.getParameter(i)),this.limits[i]||0}}class Qi extends tr{constructor(i,n){super(i,n);f(this,"device");f(this,"gl");f(this,"handle");f(this,"colorAttachments",[]);f(this,"depthStencilAttachment",null);const r=n.handle===null;this.device=i,this.gl=i.gl,this.handle=this.props.handle||r?this.props.handle:this.gl.createFramebuffer(),r||(i._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),n.handle||(this.autoCreateAttachmentTextures(),this.updateAttachments()))}destroy(){super.destroy(),!this.destroyed&&this.handle!==null&&!this.props.handle&&this.gl.deleteFramebuffer(this.handle)}updateAttachments(){const i=this.gl.bindFramebuffer(36160,this.handle);for(let n=0;n<this.colorAttachments.length;++n){const r=this.colorAttachments[n];if(r){const s=36064+n;this._attachTextureView(s,r)}}if(this.depthStencilAttachment){const n=Nb(this.depthStencilAttachment.props.format);this._attachTextureView(n,this.depthStencilAttachment)}if(this.device.props.debug){const n=this.gl.checkFramebufferStatus(36160);if(n!==36053)throw new Error(`Framebuffer ${Wb(n)}`)}this.gl.bindFramebuffer(36160,i)}_attachTextureView(i,n){const{gl:r}=this.device,{texture:s}=n,o=n.props.baseMipLevel,a=n.props.baseArrayLayer;switch(r.bindTexture(s.glTarget,s.handle),s.glTarget){case 35866:case 32879:r.framebufferTextureLayer(36160,i,s.handle,o,a);break;case 34067:const l=Lb(a);r.framebufferTexture2D(36160,i,l,s.handle,o);break;case 3553:r.framebufferTexture2D(36160,i,3553,s.handle,o);break;default:throw new Error("Illegal texture type")}r.bindTexture(s.glTarget,null)}resizeAttachments(i,n){if(this.handle===null){this.width=i,this.height=n;return}super.resizeAttachments(i,n)}}function Lb(e){return e<34069?e+34069:e}function Wb(e){switch(e){case 36053:return"success";case 36054:return"Mismatched attachments";case 36055:return"No attachments";case 36057:return"Height/width mismatch";case 36061:return"Unsupported or split attachments";case 36182:return"Samples mismatch";default:return`${e}`}}class Vb extends Wc{constructor(i,n){super(n);f(this,"device");f(this,"handle",null);f(this,"_framebuffer",null);this.device=i,this._setAutoCreatedCanvasId(`${this.device.id}-canvas`),this._configureDevice()}get[Symbol.toStringTag](){return"WebGLCanvasContext"}_configureDevice(){var n,r,s;(this.drawingBufferWidth!==((n=this._framebuffer)==null?void 0:n.width)||this.drawingBufferHeight!==((r=this._framebuffer)==null?void 0:r.height))&&((s=this._framebuffer)==null||s.resize([this.drawingBufferWidth,this.drawingBufferHeight]))}_getCurrentFramebuffer(){return this._framebuffer||(this._framebuffer=new Qi(this.device,{id:"canvas-context-framebuffer",handle:null,width:this.drawingBufferWidth,height:this.drawingBufferHeight})),this._framebuffer}}class Hb extends l0{constructor(i,n={}){super(n);f(this,"device");f(this,"handle",null);f(this,"context2d");this.device=i;const r=`${this[Symbol.toStringTag]}(${this.id})`;if(!this.device.getDefaultCanvasContext().offscreenCanvas)throw new Error(`${r}: WebGL PresentationContext requires the default CanvasContext canvas to be an OffscreenCanvas`);const o=this.canvas.getContext("2d");if(!o)throw new Error(`${r}: Failed to create 2d presentation context`);this.context2d=o,this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`),this._configureDevice(),this._startObservers()}get[Symbol.toStringTag](){return"WebGLPresentationContext"}present(){this._resizeDrawingBufferIfNeeded(),this.device.submit();const i=this.device.getDefaultCanvasContext(),[n,r]=i.getDrawingBufferSize();if(!(this.drawingBufferWidth===0||this.drawingBufferHeight===0||n===0||r===0||i.canvas.width===0||i.canvas.height===0)){if(n!==this.drawingBufferWidth||r!==this.drawingBufferHeight||i.canvas.width!==this.drawingBufferWidth||i.canvas.height!==this.drawingBufferHeight)throw new Error(`${this[Symbol.toStringTag]}(${this.id}): Default canvas context size ${n}x${r} does not match presentation size ${this.drawingBufferWidth}x${this.drawingBufferHeight}`);this.context2d.clearRect(0,0,this.drawingBufferWidth,this.drawingBufferHeight),this.context2d.drawImage(i.canvas,0,0)}}_configureDevice(){}_getCurrentFramebuffer(i){const n=this.device.getDefaultCanvasContext();return n.setDrawingBufferSize(this.drawingBufferWidth,this.drawingBufferHeight),n.getCurrentFramebuffer(i)}}const Lo={};function $b(e="id"){Lo[e]=Lo[e]||1;const t=Lo[e]++;return`${e}-${t}`}class Ji extends B{constructor(i,n={}){super(i,n);f(this,"device");f(this,"gl");f(this,"handle");f(this,"glTarget");f(this,"glUsage");f(this,"glIndexType",5123);f(this,"byteLength",0);f(this,"bytesUsed",0);this.device=i,this.gl=this.device.gl;const r=typeof n=="object"?n.handle:void 0;this.handle=r||this.gl.createBuffer(),i._setWebGLDebugMetadata(this.handle,this,{spector:{...this.props,data:typeof this.props.data}}),this.glTarget=Xb(this.props.usage),this.glUsage=Yb(this.props.usage),this.glIndexType=this.props.indexType==="uint32"?5125:5123,n.data?this._initWithData(n.data,n.byteOffset,n.byteLength):this._initWithByteLength(n.byteLength||0)}destroy(){!this.destroyed&&this.handle&&(this.removeStats(),this.props.handle?this.trackDeallocatedReferencedMemory("Buffer"):(this.trackDeallocatedMemory(),this.gl.deleteBuffer(this.handle)),this.destroyed=!0,this.handle=null)}_initWithData(i,n=0,r=i.byteLength+n){const s=this.glTarget;this.gl.bindBuffer(s,this.handle),this.gl.bufferData(s,r,this.glUsage),this.gl.bufferSubData(s,n,i),this.gl.bindBuffer(s,null),this.bytesUsed=r,this.byteLength=r,this._setDebugData(i,n,r),this.props.handle?this.trackReferencedMemory(r,"Buffer"):this.trackAllocatedMemory(r)}_initWithByteLength(i){let n=i;i===0&&(n=new Float32Array(0));const r=this.glTarget;return this.gl.bindBuffer(r,this.handle),this.gl.bufferData(r,n,this.glUsage),this.gl.bindBuffer(r,null),this.bytesUsed=i,this.byteLength=i,this._setDebugData(null,0,i),this.props.handle?this.trackReferencedMemory(i,"Buffer"):this.trackAllocatedMemory(i),this}write(i,n=0){const r=ArrayBuffer.isView(i)?i:new Uint8Array(i),s=36663;this.gl.bindBuffer(s,this.handle),this.gl.bufferSubData(s,n,r),this.gl.bindBuffer(s,null),this._setDebugData(i,n,i.byteLength)}async mapAndWriteAsync(i,n=0,r=this.byteLength-n){const s=new ArrayBuffer(r);await i(s,"copied"),this.write(s,n)}async readAsync(i=0,n){return this.readSyncWebGL(i,n)}async mapAndReadAsync(i,n=0,r){const s=await this.readAsync(n,r);return await i(s.buffer,"copied")}readSyncWebGL(i=0,n){n=n??this.byteLength-i;const r=new Uint8Array(n),s=0;return this.gl.bindBuffer(36662,this.handle),this.gl.getBufferSubData(36662,i,r,s,n),this.gl.bindBuffer(36662,null),this._setDebugData(r,i,n),r}}function Xb(e){return e&B.INDEX?34963:e&B.VERTEX?34962:e&B.UNIFORM?35345:34962}function Yb(e){return e&B.INDEX||e&B.VERTEX?35044:e&B.UNIFORM?35048:35044}function jb(e){var n;const t=e.split(/\r?\n/),i=[];for(const r of t){if(r.length<=1)continue;const s=r.trim(),o=r.split(":"),a=(n=o[0])==null?void 0:n.trim();if(o.length===2){const[g,x]=o;if(!g||!x){i.push({message:s,type:mr(a||"info"),lineNum:0,linePos:0});continue}i.push({message:x.trim(),type:mr(g),lineNum:0,linePos:0});continue}const[l,c,u,...d]=o;if(!l||!c||!u){i.push({message:o.slice(1).join(":").trim()||s,type:mr(a||"info"),lineNum:0,linePos:0});continue}let h=parseInt(u,10);Number.isNaN(h)&&(h=0);let p=parseInt(c,10);Number.isNaN(p)&&(p=0),i.push({message:d.join(":").trim(),type:mr(l),lineNum:h,linePos:p})}return i}function mr(e){const t=["warning","error","info"],i=e.toLowerCase();return t.includes(i)?i:"info"}class Kb extends er{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");switch(this.device=i,this.props.stage){case"vertex":this.handle=this.props.handle||this.device.gl.createShader(35633);break;case"fragment":this.handle=this.props.handle||this.device.gl.createShader(35632);break;default:throw new Error(this.props.stage)}i._setWebGLDebugMetadata(this.handle,this,{spector:this.props});const r=this._compile(this.source);r&&typeof r.catch=="function"&&r.catch(()=>{this.compilationStatus="error"})}destroy(){this.handle&&(this.removeStats(),this.device.gl.deleteShader(this.handle),this.destroyed=!0,this.handle.destroyed=!0)}get asyncCompilationStatus(){return this._waitForCompilationComplete().then(()=>(this._getCompilationStatus(),this.compilationStatus))}async getCompilationInfo(){return await this._waitForCompilationComplete(),this.getCompilationInfoSync()}getCompilationInfoSync(){const i=this.device.gl.getShaderInfoLog(this.handle);return i?jb(i):[]}getTranslatedSource(){const n=this.device.getExtension("WEBGL_debug_shaders").WEBGL_debug_shaders;return(n==null?void 0:n.getTranslatedShaderSource(this.handle))||null}_compile(i){i=i.startsWith("#version ")?i:`#version 300 es +${i}`;const{gl:n}=this.device;if(n.shaderSource(this.handle,i),n.compileShader(this.handle),!this.device.props.debug){this.compilationStatus="pending";return}if(!this.device.features.has("compilation-status-async-webgl")){if(this._getCompilationStatus(),this.debugShader(),this.compilationStatus==="error")throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);return}return C.once(1,"Shader compilation is asynchronous")(),this._waitForCompilationComplete().then(()=>{C.info(2,`Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)(),this._getCompilationStatus(),this.debugShader()})}async _waitForCompilationComplete(){const i=async s=>await new Promise(o=>setTimeout(o,s));if(!this.device.features.has("compilation-status-async-webgl")){await i(10);return}const{gl:r}=this.device;for(;;){if(r.getShaderParameter(this.handle,37297))return;await i(10)}}_getCompilationStatus(){this.compilationStatus=this.device.gl.getShaderParameter(this.handle,35713)?"success":"error"}}function qb(e,t,i,n){if(Jb(t))return n(e);const r=e;r.pushState();try{return Gb(e,t),ui(r.gl,i),n(e)}finally{r.popState()}}function Gb(e,t){const i=e,{gl:n}=i;if(t.cullMode)switch(t.cullMode){case"none":n.disable(2884);break;case"front":n.enable(2884),n.cullFace(1028);break;case"back":n.enable(2884),n.cullFace(1029);break}if(t.frontFace&&n.frontFace(Ut("frontFace",t.frontFace,{ccw:2305,cw:2304})),t.unclippedDepth&&e.features.has("depth-clip-control")&&n.enable(34383),t.depthBias!==void 0&&(n.enable(32823),n.polygonOffset(t.depthBias,t.depthBiasSlopeScale||0)),t.provokingVertex&&e.features.has("provoking-vertex-webgl")){const s=i.getExtension("WEBGL_provoking_vertex").WEBGL_provoking_vertex,o=Ut("provokingVertex",t.provokingVertex,{first:36429,last:36430});s==null||s.provokingVertexWEBGL(o)}if((t.polygonMode||t.polygonOffsetLine)&&e.features.has("polygon-mode-webgl")){if(t.polygonMode){const s=i.getExtension("WEBGL_polygon_mode").WEBGL_polygon_mode,o=Ut("polygonMode",t.polygonMode,{fill:6914,line:6913});s==null||s.polygonModeWEBGL(1028,o),s==null||s.polygonModeWEBGL(1029,o)}t.polygonOffsetLine&&n.enable(10754)}if(e.features.has("shader-clip-cull-distance-webgl")&&(t.clipDistance0&&n.enable(12288),t.clipDistance1&&n.enable(12289),t.clipDistance2&&n.enable(12290),t.clipDistance3&&n.enable(12291),t.clipDistance4&&n.enable(12292),t.clipDistance5&&n.enable(12293),t.clipDistance6&&n.enable(12294),t.clipDistance7&&n.enable(12295)),t.depthWriteEnabled!==void 0&&n.depthMask(Qb("depthWriteEnabled",t.depthWriteEnabled)),t.depthCompare&&(t.depthCompare!=="always"?n.enable(2929):n.disable(2929),n.depthFunc(Wo("depthCompare",t.depthCompare))),t.clearDepth!==void 0&&n.clearDepth(t.clearDepth),t.stencilWriteMask){const r=t.stencilWriteMask;n.stencilMaskSeparate(1028,r),n.stencilMaskSeparate(1029,r)}if(t.stencilReadMask&&C.warn("stencilReadMask not supported under WebGL"),t.stencilCompare){const r=t.stencilReadMask||4294967295,s=Wo("depthCompare",t.stencilCompare);t.stencilCompare!=="always"?n.enable(2960):n.disable(2960),n.stencilFuncSeparate(1028,s,0,r),n.stencilFuncSeparate(1029,s,0,r)}if(t.stencilPassOperation&&t.stencilFailOperation&&t.stencilDepthFailOperation){const r=Vo("stencilPassOperation",t.stencilPassOperation),s=Vo("stencilFailOperation",t.stencilFailOperation),o=Vo("stencilDepthFailOperation",t.stencilDepthFailOperation);n.stencilOpSeparate(1028,s,o,r),n.stencilOpSeparate(1029,s,o,r)}switch(t.blend){case!0:n.enable(3042);break;case!1:n.disable(3042);break}if(t.blendColorOperation||t.blendAlphaOperation){const r=ld("blendColorOperation",t.blendColorOperation||"add"),s=ld("blendAlphaOperation",t.blendAlphaOperation||"add");n.blendEquationSeparate(r,s);const o=xr("blendColorSrcFactor",t.blendColorSrcFactor||"one"),a=xr("blendColorDstFactor",t.blendColorDstFactor||"zero"),l=xr("blendAlphaSrcFactor",t.blendAlphaSrcFactor||"one"),c=xr("blendAlphaDstFactor",t.blendAlphaDstFactor||"zero");n.blendFuncSeparate(o,a,l,c)}}function Wo(e,t){return Ut(e,t,{never:512,less:513,equal:514,"less-equal":515,greater:516,"not-equal":517,"greater-equal":518,always:519})}function Vo(e,t){return Ut(e,t,{keep:7680,zero:0,replace:7681,invert:5386,"increment-clamp":7682,"decrement-clamp":7683,"increment-wrap":34055,"decrement-wrap":34056})}function ld(e,t){return Ut(e,t,{add:32774,subtract:32778,"reverse-subtract":32779,min:32775,max:32776})}function xr(e,t,i="color"){return Ut(e,t,{one:1,zero:0,src:768,"one-minus-src":769,dst:774,"one-minus-dst":775,"src-alpha":770,"one-minus-src-alpha":771,"dst-alpha":772,"one-minus-dst-alpha":773,"src-alpha-saturated":776,constant:i==="color"?32769:32771,"one-minus-constant":i==="color"?32770:32772,src1:768,"one-minus-src1":769,"src1-alpha":770,"one-minus-src1-alpha":771})}function Zb(e,t){return`Illegal parameter ${t} for ${e}`}function Ut(e,t,i){if(!(t in i))throw new Error(Zb(e,t));return i[t]}function Qb(e,t){return t}function Jb(e){let t=!0;for(const i in e){t=!1;break}return t}function cd(e){const t={};return e.addressModeU&&(t[10242]=Ho(e.addressModeU)),e.addressModeV&&(t[10243]=Ho(e.addressModeV)),e.addressModeW&&(t[32882]=Ho(e.addressModeW)),e.magFilter&&(t[10240]=$o(e.magFilter)),(e.minFilter||e.mipmapFilter)&&(t[10241]=eT(e.minFilter||"linear",e.mipmapFilter)),e.lodMinClamp!==void 0&&(t[33082]=e.lodMinClamp),e.lodMaxClamp!==void 0&&(t[33083]=e.lodMaxClamp),e.type==="comparison-sampler"&&(t[34892]=34894),e.compare&&(t[34893]=Wo("compare",e.compare)),e.maxAnisotropy&&(t[34046]=e.maxAnisotropy),t}function Ho(e){switch(e){case"clamp-to-edge":return 33071;case"repeat":return 10497;case"mirror-repeat":return 33648}}function $o(e){switch(e){case"nearest":return 9728;case"linear":return 9729}}function eT(e,t="none"){if(!t)return $o(e);switch(t){case"none":return $o(e);case"nearest":switch(e){case"nearest":return 9984;case"linear":return 9985}break;case"linear":switch(e){case"nearest":return 9986;case"linear":return 9987}}}class tT extends ni{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"parameters");this.device=i,this.parameters=cd(n),this.handle=n.handle||this.device.gl.createSampler(),this._setSamplerParameters(this.parameters)}destroy(){this.handle&&(this.device.gl.deleteSampler(this.handle),this.handle=void 0)}toString(){return`Sampler(${this.id},${JSON.stringify(this.props)})`}_setSamplerParameters(i){for(const[n,r]of Object.entries(i)){const s=Number(n);switch(s){case 33082:case 33083:this.device.gl.samplerParameterf(this.handle,s,r);break;default:this.device.gl.samplerParameteri(this.handle,s,r);break}}}}function zt(e,t,i){if(iT(t))return i(e);const{nocatch:n=!0}=t,r=Pt.get(e);r.push(),ui(e,t);let s;if(n)s=i(e),r.pop();else try{s=i(e)}finally{r.pop()}return s}function iT(e){for(const t in e)return!1;return!0}class fi extends Jn{constructor(i,n){super(i,{...M.defaultProps,...n});f(this,"device");f(this,"gl");f(this,"handle");f(this,"texture");this.device=i,this.gl=this.device.gl,this.handle=null,this.texture=n.texture}}function ud(e){return nT[e]}const nT={5124:"sint32",5125:"uint32",5122:"sint16",5123:"uint16",5120:"sint8",5121:"uint8",5126:"float32",5131:"float16",33635:"uint16",32819:"uint16",32820:"uint16",33640:"uint32",35899:"uint32",35902:"uint32",34042:"uint32",36269:"uint32"};class en extends M{constructor(i,n){super(i,n,{byteAlignment:1});f(this,"device");f(this,"gl");f(this,"handle");f(this,"sampler");f(this,"view");f(this,"glTarget");f(this,"glFormat");f(this,"glType");f(this,"glInternalFormat");f(this,"compressed");f(this,"_textureUnit",0);f(this,"_framebuffer",null);f(this,"_framebufferAttachmentKey",null);this.device=i,this.gl=this.device.gl;const r=od(this.props.format);this.glTarget=oT(this.props.dimension),this.glInternalFormat=r.internalFormat,this.glFormat=r.format,this.glType=r.type,this.compressed=r.compressed,this.handle=this.props.handle||this.gl.createTexture(),this.device._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),this.gl.bindTexture(this.glTarget,this.handle);const{dimension:s,width:o,height:a,depth:l,mipLevels:c,glTarget:u,glInternalFormat:d}=this;if(!this.compressed)switch(s){case"2d":case"cube":this.gl.texStorage2D(u,c,d,o,a);break;case"2d-array":case"3d":this.gl.texStorage3D(u,c,d,o,a,l);break;default:throw new Error(s)}this.gl.bindTexture(this.glTarget,null),this._initializeData(n.data),this.props.handle?this.trackReferencedMemory(this.getAllocatedByteLength(),"Texture"):this.trackAllocatedMemory(this.getAllocatedByteLength(),"Texture"),this.setSampler(this.props.sampler),this.view=new fi(this.device,{...this.props,texture:this}),Object.seal(this)}destroy(){var i;this.handle&&((i=this._framebuffer)==null||i.destroy(),this._framebuffer=null,this._framebufferAttachmentKey=null,this.removeStats(),this.props.handle?this.trackDeallocatedReferencedMemory("Texture"):(this.gl.deleteTexture(this.handle),this.trackDeallocatedMemory("Texture")),this.destroyed=!0)}createView(i){return new fi(this.device,{...i,texture:this})}setSampler(i={}){super.setSampler(i);const n=cd(this.sampler.props);this._setSamplerParameters(n)}copyExternalImage(i){const n=this._normalizeCopyExternalImageOptions(i);if(n.sourceX||n.sourceY)throw new Error("WebGL does not support sourceX/sourceY)");const{glFormat:r,glType:s}=this,{image:o,depth:a,mipLevel:l,x:c,y:u,z:d,width:h,height:p}=n,g=Sr(this.glTarget,this.dimension,d),x=n.flipY?{37440:!0}:{};return this.gl.bindTexture(this.glTarget,this.handle),zt(this.gl,x,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(g,l,c,u,h,p,r,s,o);break;case"2d-array":case"3d":this.gl.texSubImage3D(g,l,c,u,d,h,p,a,r,s,o);break;default:}}),this.gl.bindTexture(this.glTarget,null),{width:n.width,height:n.height}}copyImageData(i){super.copyImageData(i)}readBuffer(i={},n){if(!n)throw new Error(`${this} readBuffer requires a destination buffer`);const r=this._getSupportedColorReadOptions(i),s=i.byteOffset??0,o=this.computeMemoryLayout(r);if(n.byteLength<s+o.byteLength)throw new Error(`${this} readBuffer target is too small (${n.byteLength} < ${s+o.byteLength})`);const a=n;this.gl.bindBuffer(35051,a.handle);try{this._readColorTextureLayers(r,o,l=>{this.gl.readPixels(r.x,r.y,r.width,r.height,this.glFormat,this.glType,s+l)})}finally{this.gl.bindBuffer(35051,null)}return n}async readDataAsync(i={}){throw new Error(`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`)}writeBuffer(i,n={}){const r=this._normalizeTextureWriteOptions(n),{width:s,height:o,depthOrArrayLayers:a,mipLevel:l,byteOffset:c,x:u,y:d,z:h}=r,{glFormat:p,glType:g,compressed:x}=this,T=Sr(this.glTarget,this.dimension,h);if(x)throw new Error("writeBuffer for compressed textures is not implemented in WebGL");const{bytesPerPixel:S}=this.device.getTextureFormatInfo(this.format),P=S?r.bytesPerRow/S:void 0,I={3317:this.byteAlignment,...P!==void 0?{3314:P}:{},32878:r.rowsPerImage};this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,i.handle),zt(this.gl,I,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(T,l,u,d,s,o,p,g,c);break;case"2d-array":case"3d":this.gl.texSubImage3D(T,l,u,d,h,s,o,a,p,g,c);break;default:}}),this.gl.bindBuffer(35052,null),this.gl.bindTexture(this.glTarget,null)}writeData(i,n={}){const r=this._normalizeTextureWriteOptions(n),s=ArrayBuffer.isView(i)?i:new Uint8Array(i),{width:o,height:a,depthOrArrayLayers:l,mipLevel:c,x:u,y:d,z:h,byteOffset:p}=r,{glFormat:g,glType:x,compressed:T}=this,S=Sr(this.glTarget,this.dimension,h);let P;if(!T){const{bytesPerPixel:D}=this.device.getTextureFormatInfo(this.format);D&&(P=r.bytesPerRow/D)}const I=this.compressed?{}:{3317:this.byteAlignment,...P!==void 0?{3314:P}:{},32878:r.rowsPerImage},y=sT(s,p),v=T?rT(s,p):s,E=this._getMipLevelSize(c),R=u===0&&d===0&&h===0&&o===E.width&&a===E.height&&l===E.depthOrArrayLayers;this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,null),zt(this.gl,I,()=>{switch(this.dimension){case"2d":case"cube":T?R?this.gl.compressedTexImage2D(S,c,g,o,a,0,v):this.gl.compressedTexSubImage2D(S,c,u,d,o,a,g,v):this.gl.texSubImage2D(S,c,u,d,o,a,g,x,s,y);break;case"2d-array":case"3d":T?R?this.gl.compressedTexImage3D(S,c,g,o,a,l,0,v):this.gl.compressedTexSubImage3D(S,c,u,d,h,o,a,l,g,v):this.gl.texSubImage3D(S,c,u,d,h,o,a,l,g,x,s,y);break;default:}}),this.gl.bindTexture(this.glTarget,null)}_getRowByteAlignment(i,n){return 1}_getFramebuffer(){return this._framebuffer||(this._framebuffer=this.device.createFramebuffer({id:`framebuffer-for-${this.id}`,width:this.width,height:this.height,colorAttachments:[this]})),this._framebuffer}readDataSyncWebGL(i={}){const n=this._getSupportedColorReadOptions(i),r=this.computeMemoryLayout(n),s=ud(this.glType),o=N0(s),a=new o(r.byteLength/o.BYTES_PER_ELEMENT);return this._readColorTextureLayers(n,r,l=>{const c=new o(a.buffer,a.byteOffset+l,r.bytesPerImage/o.BYTES_PER_ELEMENT);this.gl.readPixels(n.x,n.y,n.width,n.height,this.glFormat,this.glType,c)}),a.buffer}_readColorTextureLayers(i,n,r){const s=this._getFramebuffer(),o=n.bytesPerRow/n.bytesPerPixel,a={3333:this.byteAlignment,...o!==i.width?{3330:o}:{}},l=this.gl.getParameter(3074),c=this.gl.bindFramebuffer(36160,s.handle);try{this.gl.readBuffer(36064),zt(this.gl,a,()=>{for(let u=0;u<i.depthOrArrayLayers;u++)this._attachReadSubresource(s,i.mipLevel,i.z+u),r(u*n.bytesPerImage)})}finally{this.gl.bindFramebuffer(36160,c||null),this.gl.readBuffer(l)}}_attachReadSubresource(i,n,r){const s=`${n}:${r}`;if(this._framebufferAttachmentKey!==s){switch(this.dimension){case"2d":this.gl.framebufferTexture2D(36160,36064,3553,this.handle,n);break;case"cube":this.gl.framebufferTexture2D(36160,36064,Sr(this.glTarget,this.dimension,r),this.handle,n);break;case"2d-array":case"3d":this.gl.framebufferTextureLayer(36160,36064,this.handle,n,r);break;default:throw new Error(`${this} color readback does not support ${this.dimension} textures`)}if(this.device.props.debug){const o=Number(this.gl.checkFramebufferStatus(36160));if(o!==36053)throw new Error(`${i} incomplete for ${this} readback (${o})`)}this._framebufferAttachmentKey=s}}generateMipmapsWebGL(i){if(!(!(this.device.isTextureFormatRenderable(this.props.format)&&this.device.isTextureFormatFilterable(this.props.format))&&(C.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)(),!(i!=null&&i.force))))try{this.gl.bindTexture(this.glTarget,this.handle),this.gl.generateMipmap(this.glTarget)}catch(r){C.warn(`Error generating mipmap for ${this}: ${r.message}`)()}finally{this.gl.bindTexture(this.glTarget,null)}}_setSamplerParameters(i){C.log(2,`${this.id} sampler parameters`,this.device.getGLKeys(i))(),this.gl.bindTexture(this.glTarget,this.handle);for(const[n,r]of Object.entries(i)){const s=Number(n),o=r;switch(s){case 33082:case 33083:this.gl.texParameterf(this.glTarget,s,o);break;case 10240:case 10241:this.gl.texParameteri(this.glTarget,s,o);break;case 10242:case 10243:case 32882:this.gl.texParameteri(this.glTarget,s,o);break;case 34046:this.device.features.has("texture-filterable-anisotropic-webgl")&&this.gl.texParameteri(this.glTarget,s,o);break;case 34892:case 34893:this.gl.texParameteri(this.glTarget,s,o);break}}this.gl.bindTexture(this.glTarget,null)}_getActiveUnit(){return this.gl.getParameter(34016)-33984}_bind(i){const{gl:n}=this;return i!==void 0&&(this._textureUnit=i,n.activeTexture(33984+i)),n.bindTexture(this.glTarget,this.handle),i}_unbind(i){const{gl:n}=this;return i!==void 0&&(this._textureUnit=i,n.activeTexture(33984+i)),n.bindTexture(this.glTarget,null),i}}function rT(e,t=0){return t?new e.constructor(e.buffer,e.byteOffset+t,(e.byteLength-t)/e.BYTES_PER_ELEMENT):e}function sT(e,t){if(t%e.BYTES_PER_ELEMENT!==0)throw new Error(`Texture byteOffset ${t} must align to typed array element size ${e.BYTES_PER_ELEMENT}`);return t/e.BYTES_PER_ELEMENT}function oT(e){switch(e){case"1d":break;case"2d":return 3553;case"3d":return 32879;case"cube":return 34067;case"2d-array":return 35866}throw new Error(e)}function Sr(e,t,i){return t==="cube"?34069+i:e}function aT(e,t,i,n){const r=e;let s=n;s===!0&&(s=1),s===!1&&(s=0);const o=typeof s=="number"?[s]:s;switch(i){case 35678:case 35680:case 35679:case 35682:case 36289:case 36292:case 36293:case 36298:case 36299:case 36300:case 36303:case 36306:case 36307:case 36308:case 36311:if(typeof n!="number")throw new Error("samplers must be set to integers");return e.uniform1i(t,n);case 5126:return e.uniform1fv(t,o);case 35664:return e.uniform2fv(t,o);case 35665:return e.uniform3fv(t,o);case 35666:return e.uniform4fv(t,o);case 5124:return e.uniform1iv(t,o);case 35667:return e.uniform2iv(t,o);case 35668:return e.uniform3iv(t,o);case 35669:return e.uniform4iv(t,o);case 35670:return e.uniform1iv(t,o);case 35671:return e.uniform2iv(t,o);case 35672:return e.uniform3iv(t,o);case 35673:return e.uniform4iv(t,o);case 5125:return r.uniform1uiv(t,o,1);case 36294:return r.uniform2uiv(t,o,2);case 36295:return r.uniform3uiv(t,o,3);case 36296:return r.uniform4uiv(t,o,4);case 35674:return e.uniformMatrix2fv(t,!1,o);case 35675:return e.uniformMatrix3fv(t,!1,o);case 35676:return e.uniformMatrix4fv(t,!1,o);case 35685:return r.uniformMatrix2x3fv(t,!1,o);case 35686:return r.uniformMatrix2x4fv(t,!1,o);case 35687:return r.uniformMatrix3x2fv(t,!1,o);case 35688:return r.uniformMatrix3x4fv(t,!1,o);case 35689:return r.uniformMatrix4x2fv(t,!1,o);case 35690:return r.uniformMatrix4x3fv(t,!1,o)}throw new Error("Illegal uniform")}function lT(e){switch(e){case"point-list":return 0;case"line-list":return 1;case"line-strip":return 3;case"triangle-list":return 4;case"triangle-strip":return 5;default:throw new Error(e)}}function cT(e){switch(e){case"point-list":return 0;case"line-list":return 1;case"line-strip":return 1;case"triangle-list":return 4;case"triangle-strip":return 4;default:throw new Error(e)}}class uT extends bt{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"vs");f(this,"fs");f(this,"introspectedLayout");f(this,"bindings",{});f(this,"uniforms",{});f(this,"varyings",null);f(this,"_uniformCount",0);f(this,"_uniformSetters",{});this.device=i;const r=this.sharedRenderPipeline||this.device._createSharedRenderPipelineWebGL(n);this.sharedRenderPipeline=r,this.handle=r.handle,this.vs=r.vs,this.fs=r.fs,this.linkStatus=r.linkStatus,this.introspectedLayout=r.introspectedLayout,this.device._setWebGLDebugMetadata(this.handle,this,{spector:{id:this.props.id}}),this.shaderLayout=n.shaderLayout?dT(this.introspectedLayout,n.shaderLayout):this.introspectedLayout}get[Symbol.toStringTag](){return"WEBGLRenderPipeline"}destroy(){this.destroyed||(this.sharedRenderPipeline&&!this.props._sharedRenderPipeline&&this.sharedRenderPipeline.destroy(),this.destroyResource())}setBindings(i,n){const r=$c(Hc(this.shaderLayout,i));for(const[s,o]of Object.entries(r)){const a=dd(this.shaderLayout,s);if(a){switch(o||C.warn(`Unsetting binding "${s}" in render pipeline "${this.id}"`)(),a.type){case"uniform":if(!(o instanceof Ji)&&!(o.buffer instanceof Ji))throw new Error("buffer value");break;case"texture":if(!(o instanceof fi||o instanceof en||o instanceof Qi))throw new Error(`${this} Bad texture binding for ${s}`);break;case"sampler":C.warn(`Ignoring sampler ${s}`)();break;default:throw new Error(a.type)}this.bindings[s]=o}else{const l=this.shaderLayout.bindings.map(c=>`"${c.name}"`).join(", ");n!=null&&n.disableWarnings||C.warn(`No binding "${s}" in render pipeline "${this.id}", expected one of ${l}`,o)()}}}draw(i){var P;this._syncLinkStatus();const n=i.bindGroups?$c(i.bindGroups):i.bindings||this.bindings,{renderPass:r,parameters:s=this.props.parameters,topology:o=this.props.topology,vertexArray:a,vertexCount:l,instanceCount:c,isInstanced:u=!1,firstVertex:d=0,transformFeedback:h,uniforms:p=this.uniforms}=i,g=lT(o),x=!!a.indexBuffer,T=(P=a.indexBuffer)==null?void 0:P.glIndexType;if(this.linkStatus!=="success")return C.info(2,`RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)(),!1;if(!this._areTexturesRenderable(n))return C.info(2,`RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)(),!1;this.device.gl.useProgram(this.handle),a.bindBeforeRender(r),h&&h.begin(this.props.topology),this._applyBindings(n,{disableWarnings:this.props.disableWarnings}),this._applyUniforms(p);const S=r;return qb(this.device,s,S.glParameters,()=>{x&&u?this.device.gl.drawElementsInstanced(g,l||0,T,d,c||0):x?this.device.gl.drawElements(g,l||0,T,d):u?this.device.gl.drawArraysInstanced(g,d,l||0,c||0):this.device.gl.drawArrays(g,d,l||0),h&&h.end()}),a.unbindAfterRender(r),!0}_areTexturesRenderable(i){let n=!0;for(const r of this.shaderLayout.bindings)hd(i,r.name)||(C.warn(`Binding ${r.name} not found in ${this.id}`)(),n=!1);return n}_applyBindings(i,n){if(this._syncLinkStatus(),this.linkStatus!=="success")return;const{gl:r}=this.device;r.useProgram(this.handle);let s=0,o=0;for(const a of this.shaderLayout.bindings){const l=hd(i,a.name);if(!l)throw new Error(`No value for binding ${a.name} in ${this.id}`);switch(a.type){case"uniform":const{name:c}=a,u=r.getUniformBlockIndex(this.handle,c);if(u===4294967295)throw new Error(`Invalid uniform block name ${c}`);if(r.uniformBlockBinding(this.handle,u,o),l instanceof Ji)r.bindBufferBase(35345,o,l.handle);else{const h=l;r.bindBufferRange(35345,o,h.buffer.handle,h.offset||0,h.size||h.buffer.byteLength-(h.offset||0))}o+=1;break;case"texture":if(!(l instanceof fi||l instanceof en||l instanceof Qi))throw new Error("texture");let d;if(l instanceof fi)d=l.texture;else if(l instanceof en)d=l;else if(l instanceof Qi&&l.colorAttachments[0]instanceof fi)C.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")(),d=l.colorAttachments[0].texture;else throw new Error("No texture");r.activeTexture(33984+s),r.bindTexture(d.glTarget,d.handle),s+=1;break;case"sampler":break;case"storage":case"read-only-storage":throw new Error(`binding type '${a.type}' not supported in WebGL`)}}}_applyUniforms(i){for(const n of this.shaderLayout.uniforms||[]){const{name:r,location:s,type:o,textureUnit:a}=n,l=i[r]??a;l!==void 0&&aT(this.device.gl,s,o,l)}}_syncLinkStatus(){this.linkStatus=this.sharedRenderPipeline.linkStatus}}function dT(e,t){const i={...e,attributes:e.attributes.map(n=>({...n})),bindings:e.bindings.map(n=>({...n}))};for(const n of(t==null?void 0:t.attributes)||[]){const r=i.attributes.find(s=>s.name===n.name);r?(r.type=n.type||r.type,r.stepMode=n.stepMode||r.stepMode):C.warn(`shader layout attribute ${n.name} not present in shader`)}for(const n of(t==null?void 0:t.bindings)||[]){const r=dd(i,n.name);if(!r){C.warn(`shader layout binding ${n.name} not present in shader`);continue}Object.assign(r,n)}return i}function dd(e,t){return e.bindings.find(i=>i.name===t||i.name===`${t}Uniforms`||`${i.name}Uniforms`===t)}function hd(e,t){return e[t]||e[`${t}Uniforms`]||e[t.replace(/Uniforms$/,"")]}function hT(e){return gT[e]}function Xo(e){return pT[e]}function fd(e){return!!pd[e]}function fT(e){return pd[e]}const pT={5126:"f32",35664:"vec2<f32>",35665:"vec3<f32>",35666:"vec4<f32>",5124:"i32",35667:"vec2<i32>",35668:"vec3<i32>",35669:"vec4<i32>",5125:"u32",36294:"vec2<u32>",36295:"vec3<u32>",36296:"vec4<u32>",35670:"f32",35671:"vec2<f32>",35672:"vec3<f32>",35673:"vec4<f32>",35674:"mat2x2<f32>",35685:"mat2x3<f32>",35686:"mat2x4<f32>",35687:"mat3x2<f32>",35675:"mat3x3<f32>",35688:"mat3x4<f32>",35689:"mat4x2<f32>",35690:"mat4x3<f32>",35676:"mat4x4<f32>"},pd={35678:{viewDimension:"2d",sampleType:"float"},35680:{viewDimension:"cube",sampleType:"float"},35679:{viewDimension:"3d",sampleType:"float"},35682:{viewDimension:"3d",sampleType:"depth"},36289:{viewDimension:"2d-array",sampleType:"float"},36292:{viewDimension:"2d-array",sampleType:"depth"},36293:{viewDimension:"cube",sampleType:"float"},36298:{viewDimension:"2d",sampleType:"sint"},36299:{viewDimension:"3d",sampleType:"sint"},36300:{viewDimension:"cube",sampleType:"sint"},36303:{viewDimension:"2d-array",sampleType:"uint"},36306:{viewDimension:"2d",sampleType:"uint"},36307:{viewDimension:"3d",sampleType:"uint"},36308:{viewDimension:"cube",sampleType:"uint"},36311:{viewDimension:"2d-array",sampleType:"uint"}},gT={uint8:5121,sint8:5120,unorm8:5121,snorm8:5120,uint16:5123,sint16:5122,unorm16:5123,snorm16:5122,uint32:5125,sint32:5124,float16:5131,float32:5126};function mT(e,t){const i={attributes:[],bindings:[]};i.attributes=xT(e,t);const n=_T(e,t);for(const a of n){const l=a.uniforms.map(c=>({name:c.name,format:c.format,byteOffset:c.byteOffset,byteStride:c.byteStride,arrayLength:c.arrayLength}));i.bindings.push({type:"uniform",name:a.name,group:0,location:a.location,visibility:(a.vertex?1:0)&(a.fragment?2:0),minBindingSize:a.byteLength,uniforms:l})}const r=yT(e,t);let s=0;for(const a of r)if(fd(a.type)){const{viewDimension:l,sampleType:c}=fT(a.type);i.bindings.push({type:"texture",name:a.name,group:0,location:s,viewDimension:l,sampleType:c}),a.textureUnit=s,s+=1}r.length&&(i.uniforms=r);const o=ST(e,t);return o!=null&&o.length&&(i.varyings=o),i}function xT(e,t){const i=[],n=e.getProgramParameter(t,35721);for(let r=0;r<n;r++){const s=e.getActiveAttrib(t,r);if(!s)throw new Error("activeInfo");const{name:o,type:a}=s,l=e.getAttribLocation(t,o);if(l>=0){const c=Xo(a),u=/instance/i.test(o)?"instance":"vertex";i.push({name:o,location:l,stepMode:u,type:c})}}return i.sort((r,s)=>r.location-s.location),i}function ST(e,t){const i=[],n=e.getProgramParameter(t,35971);for(let r=0;r<n;r++){const s=e.getTransformFeedbackVarying(t,r);if(!s)throw new Error("activeInfo");const{name:o,type:a,size:l}=s,c=Xo(a),{type:u,components:d}=ro(c);i.push({location:r,name:o,type:u,size:l*d})}return i.sort((r,s)=>r.location-s.location),i}function yT(e,t){const i=[],n=e.getProgramParameter(t,35718);for(let r=0;r<n;r++){const s=e.getActiveUniform(t,r);if(!s)throw new Error("activeInfo");const{name:o,size:a,type:l}=s,{name:c,isArray:u}=bT(o);let d=e.getUniformLocation(t,c);const h={location:d,name:c,size:a,type:l,isArray:u};if(i.push(h),h.size>1)for(let p=0;p<h.size;p++){const g=`${c}[${p}]`;d=e.getUniformLocation(t,g);const x={...h,name:g,location:d};i.push(x)}}return i}function _T(e,t){const i=(s,o)=>e.getActiveUniformBlockParameter(t,s,o),n=[],r=e.getProgramParameter(t,35382);for(let s=0;s<r;s++){const o={name:e.getActiveUniformBlockName(t,s)||"",location:i(s,35391),byteLength:i(s,35392),vertex:i(s,35396),fragment:i(s,35398),uniformCount:i(s,35394),uniforms:[]},a=i(s,35395)||[],l=e.getActiveUniforms(t,a,35383),c=e.getActiveUniforms(t,a,35384),u=e.getActiveUniforms(t,a,35387),d=e.getActiveUniforms(t,a,35388);for(let g=0;g<o.uniformCount;++g){const x=a[g];if(x!==void 0){const T=e.getActiveUniform(t,x);if(!T)throw new Error("activeInfo");const S=Xo(l[g]);o.uniforms.push({name:T.name,format:S,type:l[g],arrayLength:c[g],byteOffset:u[g],byteStride:d[g]})}}const h=new Set(o.uniforms.map(g=>g.name.split(".")[0]).filter(g=>!!g)),p=o.name.replace(/Uniforms$/,"");if(h.size===1&&!h.has(o.name)&&!h.has(p)){const[g]=h;C.warn(`Uniform block "${o.name}" uses GLSL instance "${g}". luma.gl binds uniform buffers by block name ("${o.name}") and alias ("${p}"). Prefer matching the instance name to one of those to avoid confusing silent mismatches.`)()}n.push(o)}return n.sort((s,o)=>s.location-o.location),n}function bT(e){if(e[e.length-1]!=="]")return{name:e,length:1,isArray:!1};const i=/([^[]*)(\[[0-9]+\])?/.exec(e);return{name:Qn(i==null?void 0:i[1],`Failed to parse GLSL uniform name ${e}`),length:i!=null&&i[2]?1:0,isArray:!!(i!=null&&i[2])}}const gd=4;class TT extends m0{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"vs");f(this,"fs");f(this,"introspectedLayout",{attributes:[],bindings:[],uniforms:[]});f(this,"linkStatus","pending");this.device=i,this.handle=n.handle||this.device.gl.createProgram(),this.vs=n.vs,this.fs=n.fs,n.varyings&&n.varyings.length>0&&this.device.gl.transformFeedbackVaryings(this.handle,n.varyings,n.bufferMode||35981),this._linkShaders(),C.time(3,`RenderPipeline ${this.id} - shaderLayout introspection`)(),this.introspectedLayout=mT(this.device.gl,this.handle),C.timeEnd(3,`RenderPipeline ${this.id} - shaderLayout introspection`)()}destroy(){this.destroyed||(this.device.gl.useProgram(null),this.device.gl.deleteProgram(this.handle),this.handle.destroyed=!0,this.destroyResource())}async _linkShaders(){const{gl:i}=this.device;if(i.attachShader(this.handle,this.vs.handle),i.attachShader(this.handle,this.fs.handle),C.time(gd,`linkProgram for ${this.id}`)(),i.linkProgram(this.handle),C.timeEnd(gd,`linkProgram for ${this.id}`)(),!this.device.features.has("compilation-status-async-webgl")){const r=this._getLinkStatus();this._reportLinkStatus(r);return}C.once(1,"RenderPipeline linking is asynchronous")(),await this._waitForLinkComplete(),C.info(2,`RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();const n=this._getLinkStatus();this._reportLinkStatus(n)}async _reportLinkStatus(i){var n;switch(i){case"success":return;default:const r=i==="link-error"?"Link error":"Validation error";switch(this.vs.compilationStatus){case"error":throw this.vs.debugShader(),new Error(`${this} ${r} during compilation of ${this.vs}`);case"pending":await this.vs.asyncCompilationStatus,this.vs.debugShader();break}switch((n=this.fs)==null?void 0:n.compilationStatus){case"error":throw this.fs.debugShader(),new Error(`${this} ${r} during compilation of ${this.fs}`);case"pending":await this.fs.asyncCompilationStatus,this.fs.debugShader();break}const s=this.device.gl.getProgramInfoLog(this.handle);this.device.reportError(new Error(`${r} during ${i}: ${s}`),this)(),this.device.debug()}}_getLinkStatus(){const{gl:i}=this.device;return i.getProgramParameter(this.handle,35714)?(this._initializeSamplerUniforms(),i.validateProgram(this.handle),i.getProgramParameter(this.handle,35715)?(this.linkStatus="success","success"):(this.linkStatus="error","validation-error")):(this.linkStatus="error","link-error")}_initializeSamplerUniforms(){const{gl:i}=this.device;i.useProgram(this.handle);let n=0;const r=i.getProgramParameter(this.handle,35718);for(let s=0;s<r;s++){const o=i.getActiveUniform(this.handle,s);if(o&&fd(o.type)){const a=o.name.endsWith("[0]"),l=a?o.name.slice(0,-3):o.name,c=i.getUniformLocation(this.handle,l);c!==null&&(n=this._assignSamplerUniform(c,o,a,n))}}}_assignSamplerUniform(i,n,r,s){const{gl:o}=this.device;if(r&&n.size>1){const a=Int32Array.from({length:n.size},(l,c)=>s+c);return o.uniform1iv(i,a),s+n.size}return o.uniform1i(i,s),s+1}async _waitForLinkComplete(){const i=async s=>await new Promise(o=>setTimeout(o,s));if(!this.device.features.has("compilation-status-async-webgl")){await i(10);return}const{gl:r}=this.device;for(;;){if(r.getProgramParameter(this.handle,37297))return;await i(10)}}}class vT extends no{constructor(i,n={}){super(i,n);f(this,"device");f(this,"handle",null);f(this,"commands",[]);this.device=i}_executeCommands(i=this.commands){for(const n of i)switch(n.name){case"copy-buffer-to-buffer":PT(this.device,n.options);break;case"copy-buffer-to-texture":CT(this.device,n.options);break;case"copy-texture-to-buffer":AT(this.device,n.options);break;case"copy-texture-to-texture":RT(this.device,n.options);break;default:throw new Error(n.name)}}}function PT(e,t){const i=t.sourceBuffer,n=t.destinationBuffer;e.gl.bindBuffer(36662,i.handle),e.gl.bindBuffer(36663,n.handle),e.gl.copyBufferSubData(36662,36663,t.sourceOffset??0,t.destinationOffset??0,t.size),e.gl.bindBuffer(36662,null),e.gl.bindBuffer(36663,null)}function CT(e,t){throw new Error("copyBufferToTexture is not supported in WebGL")}function AT(e,t){const{sourceTexture:i,mipLevel:n=0,aspect:r="all",width:s=t.sourceTexture.width,height:o=t.sourceTexture.height,depthOrArrayLayers:a,origin:l=[0,0,0],destinationBuffer:c,byteOffset:u=0,bytesPerRow:d,rowsPerImage:h}=t;if(i instanceof M){i.readBuffer({x:l[0]??0,y:l[1]??0,z:l[2]??0,width:s,height:o,depthOrArrayLayers:a,mipLevel:n,aspect:r,byteOffset:u},c);return}if(r!=="all")throw new Error("aspect not supported in WebGL");if(n!==0||a!==void 0||d||h)throw new Error("not implemented");const{framebuffer:p,destroyFramebuffer:g}=md(i);let x;try{const T=c,S=s||p.width,P=o||p.height,I=Qn(p.colorAttachments[0]),y=od(I.texture.props.format),v=y.format,E=y.type;e.gl.bindBuffer(35051,T.handle),x=e.gl.bindFramebuffer(36160,p.handle),e.gl.readPixels(l[0],l[1],S,P,v,E,u)}finally{e.gl.bindBuffer(35051,null),x!==void 0&&e.gl.bindFramebuffer(36160,x),g&&p.destroy()}}function RT(e,t){const{sourceTexture:i,destinationMipLevel:n=0,origin:r=[0,0],destinationOrigin:s=[0,0,0],destinationTexture:o}=t;let{width:a=t.destinationTexture.width,height:l=t.destinationTexture.height}=t;const{framebuffer:c,destroyFramebuffer:u}=md(i),[d=0,h=0]=r,[p,g,x]=s,T=e.gl.bindFramebuffer(36160,c.handle);let S,P;if(o instanceof en)S=o,a=Number.isFinite(a)?a:S.width,l=Number.isFinite(l)?l:S.height,S._bind(0),P=S.glTarget;else throw new Error("invalid destination");switch(P){case 3553:case 34067:e.gl.copyTexSubImage2D(P,n,p,g,d,h,a,l);break;case 35866:case 32879:e.gl.copyTexSubImage3D(P,n,p,g,x,d,h,a,l);break}S&&S._unbind(),e.gl.bindFramebuffer(36160,T),u&&c.destroy()}function md(e){if(e instanceof M){const{width:t,height:i,id:n}=e;return{framebuffer:e.device.createFramebuffer({id:`framebuffer-for-${n}`,width:t,height:i,colorAttachments:[e]}),destroyFramebuffer:!0}}return{framebuffer:e,destroyFramebuffer:!1}}const wT=[1,2,4,8];class ET extends to{constructor(i,n){var a;super(i,n);f(this,"device");f(this,"handle",null);f(this,"glParameters",{});this.device=i;const r=this.props.framebuffer,s=!r||r.handle===null;s&&i.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();let o;if(!((a=n==null?void 0:n.parameters)!=null&&a.viewport))if(!s&&r){const{width:l,height:c}=r;o=[0,0,l,c]}else{const[l,c]=i.getDefaultCanvasContext().getDrawingBufferSize();o=[0,0,l,c]}if(this.device.pushState(),this.setParameters({viewport:o,...this.props.parameters}),!s&&(r!=null&&r.colorAttachments.length)){const l=r.colorAttachments.map((c,u)=>36064+u);this.device.gl.drawBuffers(l)}else s&&this.device.gl.drawBuffers([1029]);this.clear(),this.props.timestampQuerySet&&this.props.beginTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.beginTimestampIndex)}end(){this.destroyed||(this.props.timestampQuerySet&&this.props.endTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.endTimestampIndex),this.device.popState(),this.destroy())}pushDebugGroup(i){}popDebugGroup(){}insertDebugMarker(i){}setParameters(i={}){const n={...this.glParameters};n.framebuffer=this.props.framebuffer||null,this.props.depthReadOnly&&(n.depthMask=!this.props.depthReadOnly),n.stencilMask=this.props.stencilReadOnly?0:1,n[35977]=this.props.discard,i.viewport&&(i.viewport.length>=6?(n.viewport=i.viewport.slice(0,4),n.depthRange=[i.viewport[4],i.viewport[5]]):n.viewport=i.viewport),i.scissorRect&&(n.scissorTest=!0,n.scissor=i.scissorRect),i.blendConstant&&(n.blendColor=i.blendConstant),i.stencilReference!==void 0&&(n[2967]=i.stencilReference,n[36003]=i.stencilReference),"colorMask"in i&&(n.colorMask=wT.map(r=>!!(r&i.colorMask))),this.glParameters=n,ui(this.device.gl,n)}beginOcclusionQuery(i){const n=this.props.occlusionQuerySet;n==null||n.beginOcclusionQuery()}endOcclusionQuery(){const i=this.props.occlusionQuerySet;i==null||i.endOcclusionQuery()}clear(){const i={...this.glParameters};let n=0;this.props.clearColors&&this.props.clearColors.forEach((r,s)=>{r&&this.clearColorBuffer(s,r)}),this.props.clearColor!==!1&&this.props.clearColors===void 0&&(n|=16384,i.clearColor=this.props.clearColor),this.props.clearDepth!==!1&&(n|=256,i.clearDepth=this.props.clearDepth),this.props.clearStencil!==!1&&(n|=1024,i.clearStencil=this.props.clearStencil),n!==0&&zt(this.device.gl,i,()=>{this.device.gl.clear(n)})}clearColorBuffer(i=0,n=[0,0,0,0]){zt(this.device.gl,{framebuffer:this.props.framebuffer},()=>{switch(n.constructor){case Int8Array:case Int16Array:case Int32Array:this.device.gl.clearBufferiv(6144,i,n);break;case Uint8Array:case Uint8ClampedArray:case Uint16Array:case Uint32Array:this.device.gl.clearBufferuiv(6144,i,n);break;case Float32Array:this.device.gl.clearBufferfv(6144,i,n);break;default:throw new Error("clearColorBuffer: color must be typed array")}})}}class xd extends io{constructor(i,n){super(i,n);f(this,"device");f(this,"handle",null);f(this,"commandBuffer");this.device=i,this.commandBuffer=new vT(i,{id:`${this.props.id}-command-buffer`})}destroy(){this.destroyResource()}finish(i){return i!=null&&i.id&&this.commandBuffer.id!==i.id&&(this.commandBuffer.id=i.id,this.commandBuffer.props.id=i.id),this.destroy(),this.commandBuffer}beginRenderPass(i={}){return new ET(this.device,this._applyTimeProfilingToPassProps(i))}beginComputePass(i={}){throw new Error("ComputePass not supported in WebGL")}copyBufferToBuffer(i){this.commandBuffer.commands.push({name:"copy-buffer-to-buffer",options:i})}copyBufferToTexture(i){this.commandBuffer.commands.push({name:"copy-buffer-to-texture",options:i})}copyTextureToBuffer(i){this.commandBuffer.commands.push({name:"copy-texture-to-buffer",options:i})}copyTextureToTexture(i){this.commandBuffer.commands.push({name:"copy-texture-to-texture",options:i})}pushDebugGroup(i){}popDebugGroup(){}insertDebugMarker(i){}resolveQuerySet(i,n,r){throw new Error("resolveQuerySet is not supported in WebGL")}writeTimestamp(i,n){i.writeTimestamp(n)}}function IT(e){const{target:t,source:i,start:n=0,count:r=1}=e,s=i.length,o=r*s;let a=0;for(let l=n;a<s;a++)t[l++]=i[a]??0;for(;a<o;)a<o-a?(t.copyWithin(n+a,n,n+a),a*=2):(t.copyWithin(n+a,n,n+o-a),a=o);return e.target}class Yo extends oo{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"buffer",null);f(this,"bufferValue",null);this.device=i,this.handle=this.device.gl.createVertexArray()}get[Symbol.toStringTag](){return"VertexArray"}static isConstantAttributeZeroSupported(i){return sS()==="Chrome"}destroy(){var i;super.destroy(),this.buffer&&((i=this.buffer)==null||i.destroy()),this.handle&&(this.device.gl.deleteVertexArray(this.handle),this.handle=void 0)}setIndexBuffer(i){const n=i;if(n&&n.glTarget!==34963)throw new Error("Use .setBuffer()");this.device.gl.bindVertexArray(this.handle),this.device.gl.bindBuffer(34963,n?n.handle:null),this.indexBuffer=n,this.device.gl.bindVertexArray(null)}setBuffer(i,n){const r=n;if(r.glTarget===34963)throw new Error("Use .setIndexBuffer()");const{size:s,type:o,stride:a,offset:l,normalized:c,integer:u,divisor:d}=this._getAccessor(i);this.device.gl.bindVertexArray(this.handle),this.device.gl.bindBuffer(34962,r.handle),u?this.device.gl.vertexAttribIPointer(i,s,o,a,l):this.device.gl.vertexAttribPointer(i,s,o,c,a,l),this.device.gl.bindBuffer(34962,null),this.device.gl.enableVertexAttribArray(i),this.device.gl.vertexAttribDivisor(i,d||0),this.attributes[i]=r,this.device.gl.bindVertexArray(null)}setConstantWebGL(i,n){this._enable(i,!1),this.attributes[i]=n}bindBeforeRender(){this.device.gl.bindVertexArray(this.handle),this._applyConstantAttributes()}unbindAfterRender(){this.device.gl.bindVertexArray(null)}_applyConstantAttributes(){for(let i=0;i<this.maxVertexAttributes;++i){const n=this.attributes[i];ArrayBuffer.isView(n)&&this.device.setConstantAttributeWebGL(i,n)}}_getAccessor(i){const n=this.attributeInfos[i];if(!n)throw new Error(`Unknown attribute location ${i}`);const r=td(n.bufferDataType);return{size:n.bufferComponents,type:r,stride:n.byteStride,offset:n.byteOffset,normalized:n.normalized,integer:n.integer,divisor:n.stepMode==="instance"?1:0}}_enable(i,n=!0){const s=Yo.isConstantAttributeZeroSupported(this.device)||i!==0;(n||s)&&(i=Number(i),this.device.gl.bindVertexArray(this.handle),n?this.device.gl.enableVertexAttribArray(i):this.device.gl.disableVertexAttribArray(i),this.device.gl.bindVertexArray(null))}getConstantBuffer(i,n){const r=kT(n),s=r.byteLength*i,o=r.length*i;if(this.buffer&&s!==this.buffer.byteLength)throw new Error(`Buffer size is immutable, byte length ${s} !== ${this.buffer.byteLength}.`);let a=!this.buffer;if(this.buffer=this.buffer||this.device.createBuffer({byteLength:s}),a||(a=!DT(r,this.bufferValue)),a){const l=W0(n.constructor,o);IT({target:l,source:r,start:0,count:o}),this.buffer.write(l),this.bufferValue=n}return this.buffer}}function kT(e){return Array.isArray(e)?new Float32Array(e):e}function DT(e,t){if(!e||!t||e.length!==t.length||e.constructor!==t.constructor)return!1;for(let i=0;i<e.length;++i)if(e[i]!==t[i])return!1;return!0}class FT extends ao{constructor(i,n){super(i,n);f(this,"device");f(this,"gl");f(this,"handle");f(this,"layout");f(this,"buffers",{});f(this,"unusedBuffers",{});f(this,"bindOnUse",!0);f(this,"_bound",!1);this.device=i,this.gl=i.gl,this.handle=this.props.handle||this.gl.createTransformFeedback(),this.layout=this.props.layout,n.buffers&&this.setBuffers(n.buffers),Object.seal(this)}destroy(){this.gl.deleteTransformFeedback(this.handle),super.destroy()}begin(i="point-list"){this.gl.bindTransformFeedback(36386,this.handle),this.bindOnUse&&this._bindBuffers(),this.gl.beginTransformFeedback(cT(i))}end(){this.gl.endTransformFeedback(),this.bindOnUse&&this._unbindBuffers(),this.gl.bindTransformFeedback(36386,null)}setBuffers(i){this.buffers={},this.unusedBuffers={},this.bind(()=>{for(const[n,r]of Object.entries(i))this.setBuffer(n,r)})}setBuffer(i,n){const r=this._getVaryingIndex(i),{buffer:s,byteLength:o,byteOffset:a}=this._getBufferRange(n);if(r<0){this.unusedBuffers[i]=s,C.warn(`${this.id} unusedBuffers varying buffer ${i}`)();return}this.buffers[r]={buffer:s,byteLength:o,byteOffset:a},this.bindOnUse||this._bindBuffer(r,s,a,o)}getBuffer(i){if(Sd(i))return this.buffers[i]||null;const n=this._getVaryingIndex(i);return this.buffers[n]??null}bind(i=this.handle){if(typeof i!="function")return this.gl.bindTransformFeedback(36386,i),this;let n;return this._bound?n=i():(this.gl.bindTransformFeedback(36386,this.handle),this._bound=!0,n=i(),this._bound=!1,this.gl.bindTransformFeedback(36386,null)),n}unbind(){this.bind(null)}_getBufferRange(i){if(i instanceof Ji)return{buffer:i,byteOffset:0,byteLength:i.byteLength};const{buffer:n,byteOffset:r=0,byteLength:s=i.buffer.byteLength}=i;return{buffer:n,byteOffset:r,byteLength:s}}_getVaryingIndex(i){if(Sd(i))return Number(i);for(const n of this.layout.varyings||[])if(i===n.name)return n.location;return-1}_bindBuffers(){for(const[i,n]of Object.entries(this.buffers)){const{buffer:r,byteLength:s,byteOffset:o}=this._getBufferRange(n);this._bindBuffer(Number(i),r,o,s)}}_unbindBuffers(){for(const i in this.buffers)this.gl.bindBufferBase(35982,Number(i),null)}_bindBuffer(i,n,r=0,s){const o=n&&n.handle;!o||s===void 0?this.gl.bindBufferBase(35982,i,o):this.gl.bindBufferRange(35982,i,o,r,s)}}function Sd(e){return typeof e=="number"?Number.isInteger(e):/^\d+$/.test(e)}class MT extends lo{constructor(i,n){super(i,n);f(this,"device");f(this,"handle");f(this,"_timestampPairs",[]);f(this,"_pendingReads",new Set);f(this,"_occlusionQuery",null);f(this,"_occlusionActive",!1);if(this.device=i,n.type==="timestamp"){if(n.count<2)throw new Error("Timestamp QuerySet requires at least two query slots");this._timestampPairs=new Array(Math.ceil(n.count/2)).fill(null).map(()=>({activeQuery:null,completedQueries:[]})),this.handle=null}else{if(n.count>1)throw new Error("WebGL occlusion QuerySet can only have one value");const r=this.device.gl.createQuery();if(!r)throw new Error("WebGL query not supported");this.handle=r}Object.seal(this)}get[Symbol.toStringTag](){return"QuerySet"}destroy(){if(!this.destroyed){this.handle&&this.device.gl.deleteQuery(this.handle);for(const i of this._timestampPairs){i.activeQuery&&(this._cancelPendingQuery(i.activeQuery),this.device.gl.deleteQuery(i.activeQuery.handle));for(const n of i.completedQueries)this._cancelPendingQuery(n),this.device.gl.deleteQuery(n.handle)}this._occlusionQuery&&(this._cancelPendingQuery(this._occlusionQuery),this.device.gl.deleteQuery(this._occlusionQuery.handle));for(const i of Array.from(this._pendingReads))this._cancelPendingQuery(i);this.destroyResource()}}isResultAvailable(i){return this.props.type==="timestamp"?i===void 0?this._timestampPairs.some((n,r)=>this._isTimestampPairAvailable(r)):this._isTimestampPairAvailable(this._getTimestampPairIndex(i)):this._occlusionQuery?this._pollQueryAvailability(this._occlusionQuery):!1}async readResults(i){const n=(i==null?void 0:i.firstQuery)||0,r=(i==null?void 0:i.queryCount)||this.props.count-n;if(this._validateRange(n,r),this.props.type==="timestamp"){const s=new Array(r).fill(0n),o=Math.floor(n/2),a=Math.floor((n+r-1)/2);for(let l=o;l<=a;l++){const c=await this._consumeTimestampPairResult(l),u=l*2,d=u+1;u>=n&&u<n+r&&(s[u-n]=0n),d>=n&&d<n+r&&(s[d-n]=c)}return s}if(!this._occlusionQuery)throw new Error("Occlusion query has not been started");return[await this._consumeQueryResult(this._occlusionQuery)]}async readTimestampDuration(i,n){if(this.props.type!=="timestamp")throw new Error("Timestamp durations require a timestamp QuerySet");if(i<0||n>=this.props.count||n<=i)throw new Error("Timestamp duration range is out of bounds");if(i%2!==0||n!==i+1)throw new Error("WebGL timestamp durations require adjacent even/odd query indices");const r=await this._consumeTimestampPairResult(this._getTimestampPairIndex(i));return Number(r)/1e6}beginOcclusionQuery(){if(this.props.type!=="occlusion")throw new Error("Occlusion queries require an occlusion QuerySet");if(!this.handle)throw new Error("WebGL occlusion query is not available");if(this._occlusionActive)throw new Error("Occlusion query is already active");this.device.gl.beginQuery(35887,this.handle),this._occlusionQuery={handle:this.handle,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null},this._occlusionActive=!0}endOcclusionQuery(){if(!this._occlusionActive)throw new Error("Occlusion query is not active");this.device.gl.endQuery(35887),this._occlusionActive=!1}writeTimestamp(i){if(this.props.type!=="timestamp")throw new Error("Timestamp writes require a timestamp QuerySet");const n=this._getTimestampPairIndex(i),r=this._timestampPairs[n];if(i%2===0){if(r.activeQuery)throw new Error("Timestamp query pair is already active");const s=this.device.gl.createQuery();if(!s)throw new Error("WebGL query not supported");const o={handle:s,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null};this.device.gl.beginQuery(35007,s),r.activeQuery=o;return}if(!r.activeQuery)throw new Error("Timestamp query pair was ended before it was started");this.device.gl.endQuery(35007),r.completedQueries.push(r.activeQuery),r.activeQuery=null}_validateRange(i,n){if(i<0||n<0||i+n>this.props.count)throw new Error("Query read range is out of bounds")}_getTimestampPairIndex(i){if(i<0||i>=this.props.count)throw new Error("Query index is out of bounds");return Math.floor(i/2)}_isTimestampPairAvailable(i){const n=this._timestampPairs[i];return!n||n.completedQueries.length===0?!1:this._pollQueryAvailability(n.completedQueries[0])}_pollQueryAvailability(i){if(i.cancelled||this.destroyed)return i.result=0n,!0;if(i.result!==null||i.disjoint)return!0;if(!this.device.gl.getQueryParameter(i.handle,34919))return!1;const r=!!this.device.gl.getParameter(36795);return i.disjoint=r,i.result=r?0n:BigInt(this.device.gl.getQueryParameter(i.handle,34918)),!0}async _consumeTimestampPairResult(i){const n=this._timestampPairs[i];if(!n||n.completedQueries.length===0)throw new Error("Timestamp query pair has no completed result");const r=n.completedQueries.shift();try{return await this._consumeQueryResult(r)}finally{this.device.gl.deleteQuery(r.handle)}}_consumeQueryResult(i){return i.promise||(this._pendingReads.add(i),i.promise=new Promise((n,r)=>{i.resolve=n,i.reject=r;const s=()=>{if(i.pollRequestId=null,i.cancelled||this.destroyed){this._pendingReads.delete(i),i.promise=null,i.resolve=null,i.reject=null,n(0n);return}if(!this._pollQueryAvailability(i)){i.pollRequestId=this._requestAnimationFrame(s);return}this._pendingReads.delete(i),i.promise=null,i.resolve=null,i.reject=null,i.disjoint?r(new Error("GPU timestamp query was invalidated by a disjoint event")):n(i.result||0n)};s()})),i.promise}_cancelPendingQuery(i){if(this._pendingReads.delete(i),i.cancelled=!0,i.pollRequestId!==null&&(this._cancelAnimationFrame(i.pollRequestId),i.pollRequestId=null),i.resolve){const n=i.resolve;i.promise=null,i.resolve=null,i.reject=null,n(0n)}}_requestAnimationFrame(i){return requestAnimationFrame(i)}_cancelAnimationFrame(i){cancelAnimationFrame(i)}}class NT extends co{constructor(i,n={}){super(i,{});f(this,"device");f(this,"gl");f(this,"handle");f(this,"signaled");f(this,"_signaled",!1);this.device=i,this.gl=i.gl;const r=this.props.handle||this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE,0);if(!r)throw new Error("Failed to create WebGL fence");this.handle=r,this.signaled=new Promise(s=>{const o=()=>{const a=this.gl.clientWaitSync(this.handle,0,0);a===this.gl.ALREADY_SIGNALED||a===this.gl.CONDITION_SATISFIED?(this._signaled=!0,s()):setTimeout(o,1)};o()})}isSignaled(){if(this._signaled)return!0;const i=this.gl.getSyncParameter(this.handle,this.gl.SYNC_STATUS);return this._signaled=i===this.gl.SIGNALED,this._signaled}destroy(){this.destroyed||this.gl.deleteSync(this.handle)}}function yd(e){switch(e){case 6406:case 33326:case 6403:case 36244:return 1;case 33339:case 33340:case 33328:case 33320:case 33319:return 2;case 6407:case 36248:case 34837:return 3;case 6408:case 36249:case 34836:return 4;default:return 0}}function BT(e){switch(e){case 5121:return 1;case 33635:case 32819:case 32820:return 2;case 5126:return 4;default:return 0}}function OT(e,t){var P;const{sourceX:i=0,sourceY:n=0,sourceAttachment:r=0}=t||{};let{target:s=null,sourceWidth:o,sourceHeight:a,sourceDepth:l,sourceFormat:c,sourceType:u}=t||{};const{framebuffer:d,deleteFramebuffer:h}=_d(e),{gl:p,handle:g}=d;o||(o=d.width),a||(a=d.height);const x=(P=d.colorAttachments[r])==null?void 0:P.texture;if(!x)throw new Error(`Invalid framebuffer attachment ${r}`);l=(x==null?void 0:x.depth)||1,c||(c=(x==null?void 0:x.glFormat)||6408),u||(u=(x==null?void 0:x.glType)||5121),s=LT(s,u,c,o,a);const T=Nt.getDataType(s);u=u||hT(T);const S=p.bindFramebuffer(36160,g);return p.readBuffer(36064+r),p.readPixels(i,n,o,a,c,u,s),p.readBuffer(36064),p.bindFramebuffer(36160,S||null),h&&d.destroy(),s}function UT(e,t){const{target:i,sourceX:n=0,sourceY:r=0,sourceFormat:s=6408,targetByteOffset:o=0}=t||{};let{sourceWidth:a,sourceHeight:l,sourceType:c}=t||{};const{framebuffer:u,deleteFramebuffer:d}=_d(e);a=a||u.width,l=l||u.height;const h=u;c=c||5121;let p=i;if(!p){const x=yd(s),T=BT(c),S=o+a*l*x*T;p=h.device.createBuffer({byteLength:S})}const g=e.device.createCommandEncoder();return g.copyTextureToBuffer({sourceTexture:e,width:a,height:l,origin:[n,r],destinationBuffer:p,byteOffset:o}),g.destroy(),d&&u.destroy(),p}function _d(e){return e instanceof tr?{framebuffer:e,deleteFramebuffer:!1}:{framebuffer:zT(e),deleteFramebuffer:!0}}function zT(e,t){const{device:i,width:n,height:r,id:s}=e;return i.createFramebuffer({...t,id:`framebuffer-for-${s}`,width:n,height:r,colorAttachments:[e]})}function LT(e,t,i,n,r,s){if(e)return e;t||(t=5121);const o=ud(t),a=Nt.getTypedArrayConstructor(o),l=yd(i);return new a(n*r*l)}class yr extends Bt{constructor(i){var d;super({...i,id:i.id||$b("webgl-device")});f(this,"type","webgl");f(this,"handle");f(this,"features");f(this,"limits");f(this,"info");f(this,"canvasContext");f(this,"preferredColorFormat","rgba8unorm");f(this,"preferredDepthFormat","depth24plus");f(this,"commandEncoder");f(this,"lost");f(this,"_resolveContextLost");f(this,"gl");f(this,"_constants");f(this,"extensions");f(this,"_polyfilled",!1);f(this,"spectorJS");const n=Bt._getCanvasContextProps(i);if(!n)throw new Error("WebGLDevice requires props.createCanvasContext to be set");const r=((d=n.canvas)==null?void 0:d.gl)??null;let s=yr.getDeviceFromContext(r);if(s)throw new Error(`WebGL context already attached to device ${s.id}`);this.canvasContext=new Vb(this,n),this.lost=new Promise(h=>{this._resolveContextLost=h});const o={...i.webgl};n.alphaMode==="premultiplied"&&(o.premultipliedAlpha=!0),i.powerPreference!==void 0&&(o.powerPreference=i.powerPreference),i.failIfMajorPerformanceCaveat!==void 0&&(o.failIfMajorPerformanceCaveat=i.failIfMajorPerformanceCaveat);const l=this.props._handle||_b(this.canvasContext.canvas,{onContextLost:h=>{var p;return(p=this._resolveContextLost)==null?void 0:p.call(this,{reason:"destroyed",message:"Entered sleep mode, or too many apps or browser tabs are using the GPU."})},onContextRestored:h=>console.log("WebGL context restored")},o);if(!l)throw new Error("WebGL context creation failed");if(s=yr.getDeviceFromContext(l),s){if(i._reuseDevices)return C.log(1,`Not creating a new Device, instead returning a reference to Device ${s.id} already attached to WebGL context`,s)(),this.canvasContext.destroy(),s._reused=!0,s;throw new Error(`WebGL context already attached to device ${s.id}`)}this.handle=l,this.gl=l,this.spectorJS=tb({...this.props,gl:this.handle});const c=fr(this.handle);c.device=this,c.extensions||(c.extensions={}),this.extensions=c.extensions,this.info=bb(this.gl,this.extensions),this.limits=new zb(this.gl),this.features=new Ub(this.gl,this.extensions,this.props._disabledFeatures),this.props._initializeFeatures&&this.features.initializeFeatures(),new Pt(this.gl,{log:(...h)=>C.log(1,...h)()}).trackState(this.gl,{copyState:!1}),(i.debug||i.debugWebGL)&&(this.gl=rb(this.gl,{debugWebGL:!0,traceWebGL:i.debugWebGL}),C.warn("WebGL debug mode activated. Performance reduced.")()),i.debugWebGL&&(C.level=Math.max(C.level,1)),this.commandEncoder=new xd(this,{id:`${this}-command-encoder`}),this.canvasContext._startObservers()}static getDeviceFromContext(i){var n;return i?((n=i.luma)==null?void 0:n.device)??null:null}get[Symbol.toStringTag](){return"WebGLDevice"}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}isVertexFormatSupported(i){switch(i){case"unorm8x4-bgra":return!1;default:return!0}}destroy(){var i;if((i=this.commandEncoder)==null||i.destroy(),!this.props._reuseDevices&&!this._reused){const n=fr(this.handle);n.device=null}}get isLost(){return this.gl.isContextLost()}createCanvasContext(i){throw new Error("WebGL only supports a single canvas")}createPresentationContext(i){return new Hb(this,i||{})}createBuffer(i){const n=this._normalizeBufferProps(i);return new Ji(this,n)}createTexture(i){return new en(this,i)}createExternalTexture(i){throw new Error("createExternalTexture() not implemented")}createSampler(i){return new tT(this,i)}createShader(i){return new Kb(this,i)}createFramebuffer(i){return new Qi(this,i)}createVertexArray(i){return new Yo(this,i)}createTransformFeedback(i){return new FT(this,i)}createQuerySet(i){return new MT(this,i)}createFence(){return new NT(this)}createRenderPipeline(i){return new uT(this,i)}_createSharedRenderPipelineWebGL(i){return new TT(this,i)}createComputePipeline(i){throw new Error("ComputePipeline not supported in WebGL")}createCommandEncoder(i={}){return new xd(this,i)}submit(i){let n=null;i||({submittedCommandEncoder:n,commandBuffer:i}=this._finalizeDefaultCommandEncoderForSubmit());try{i._executeCommands(),n&&n.resolveTimeProfilingQuerySet().then(()=>{this.commandEncoder._gpuTimeMs=n._gpuTimeMs}).catch(()=>{})}finally{i.destroy()}}_finalizeDefaultCommandEncoderForSubmit(){const i=this.commandEncoder,n=i.finish();return this.commandEncoder.destroy(),this.commandEncoder=this.createCommandEncoder({id:i.props.id,timeProfilingQuerySet:i.getTimeProfilingQuerySet()}),{submittedCommandEncoder:i,commandBuffer:n}}readPixelsToArrayWebGL(i,n){return OT(i,n)}readPixelsToBufferWebGL(i,n){return UT(i,n)}setParametersWebGL(i){ui(this.gl,i)}getParametersWebGL(i){return Zu(this.gl,i)}withParametersWebGL(i,n){return zt(this.gl,i,n)}resetWebGL(){C.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")(),gb(this.gl)}_getDeviceSpecificTextureFormatCapabilities(i){return Fb(this.gl,i,this.extensions)}loseDevice(){var s;let i=!1;const r=this.getExtension("WEBGL_lose_context").WEBGL_lose_context;return r&&(i=!0,r.loseContext()),(s=this._resolveContextLost)==null||s.call(this,{reason:"destroyed",message:"Application triggered context loss"}),i}pushState(){Pt.get(this.gl).push()}popState(){Pt.get(this.gl).pop()}getGLKey(i,n){const r=Number(i);for(const s in this.gl)if(this.gl[s]===r)return`GL.${s}`;return n!=null&&n.emptyIfUnknown?"":String(i)}getGLKeys(i){const n={emptyIfUnknown:!0};return Object.entries(i).reduce((r,[s,o])=>(r[`${s}:${this.getGLKey(s,n)}`]=`${o}:${this.getGLKey(o,n)}`,r),{})}setConstantAttributeWebGL(i,n){const r=this.limits.maxVertexAttributes;this._constants=this._constants||new Array(r).fill(null);const s=this._constants[i];switch(s&&$T(s,n)&&C.info(1,`setConstantAttributeWebGL(${i}) could have been skipped, value unchanged`)(),this._constants[i]=n,n.constructor){case Float32Array:WT(this,i,n);break;case Int32Array:VT(this,i,n);break;case Uint32Array:HT(this,i,n);break;default:throw new Error("constant")}}getExtension(i){return Ot(this.gl,i,this.extensions),this.extensions}_setWebGLDebugMetadata(i,n,r){i.luma=n;const s={props:r.spector,id:r.spector.id};i.__SPECTOR_Metadata=s}}function WT(e,t,i){switch(i.length){case 1:e.gl.vertexAttrib1fv(t,i);break;case 2:e.gl.vertexAttrib2fv(t,i);break;case 3:e.gl.vertexAttrib3fv(t,i);break;case 4:e.gl.vertexAttrib4fv(t,i);break}}function VT(e,t,i){e.gl.vertexAttribI4iv(t,i)}function HT(e,t,i){e.gl.vertexAttribI4uiv(t,i)}function $T(e,t){if(!e||!t||e.length!==t.length||e.constructor!==t.constructor)return!1;for(let i=0;i<e.length;++i)if(e[i]!==t[i])return!1;return!0}const bd=Object.freeze(Object.defineProperty({__proto__:null,WebGLDevice:yr},Symbol.toStringTag,{value:"Module"})),XT=`#version 300 es +precision highp float; + +in vec4 rgba; +out vec4 fragColor; + +void main() { + fragColor = rgba; +}`,YT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +in vec2 pointIndices; + +out vec4 rgba; + +void main() { + rgba = vec4(0.0); + + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not contribute to the centroid — a NaN position would + // poison the sum and break the force for every point. (exit.G = current absence) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + rgba = vec4(pointPosition.xy, 1.0, 0.0); + + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,jT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D centermassTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceCenterUniforms { + float centerForce; + float alpha; +} forceCenter; + +#define centerForce forceCenter.centerForce +#define alpha forceCenter.alpha +#else +uniform float centerForce; +uniform float alpha; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + vec4 centermassValues = texelFetch(centermassTexture, ivec2(0), 0); + vec2 centermassPosition = centermassValues.xy / centermassValues.b; + vec2 distVector = centermassPosition - pointPosition.xy; + float dist = sqrt(dot(distVector, distVector)); + if (dist > 0.0) { + float angle = atan(distVector.y, distVector.x); + float addV = alpha * centerForce * dist * 0.01; + velocity.rg += addV * vec2(cos(angle), sin(angle)); + } + + fragColor = velocity; +}`,Ee=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 vertexCoord; // Vertex coordinates in normalized device coordinates + +void main() { + gl_Position = vec4(vertexCoord, 0, 1); +} +`;class KT extends gt{create(){var r;const{device:t,store:i}=this,{pointsTextureSize:n}=i;if(n){if(this.centermassTexture||(this.centermassTexture=t.createTexture({width:1,height:1,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST})),this.centermassTexture.copyImageData({data:new Float32Array(4).fill(0),bytesPerRow:q("rgba32float",1),mipLevel:0,x:0,y:0}),this.centermassFbo||(this.centermassFbo=t.createFramebuffer({width:1,height:1,colorAttachments:[this.centermassTexture]})),!this.pointIndices||this.previousPointsTextureSize!==i.pointsTextureSize){this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy();const s=ji(i.pointsTextureSize);this.pointIndices=t.createBuffer({data:s,usage:B.VERTEX|B.COPY_DST}),(r=this.calculateCentermassCommand)==null||r.setAttributes({pointIndices:this.pointIndices})}this.previousPointsTextureSize=n}}initPrograms(){const{device:t,store:i,points:n}=this;!n||!i.pointsTextureSize||!this.centermassFbo||this.centermassFbo.destroyed||!this.centermassTexture||this.centermassTexture.destroyed||(this.forceVertexCoordBuffer||(this.forceVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.forceUniformStore||(this.forceUniformStore=new oe(t,{forceCenterUniforms:{uniformTypes:{centerForce:"f32",alpha:"f32"}}})),this.calculateCentermassCommand||(this.calculateCentermassCommand=new ee(t,{fs:XT,vs:YT,topology:"point-list",attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber??0),this.runCommand||(this.runCommand=new ee(t,{fs:jT,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceCenterUniforms:this.forceUniformStore.getManagedUniformBuffer("forceCenterUniforms")},parameters:te})))}run(){const{device:t,store:i,points:n}=this;if(!n||!this.calculateCentermassCommand||!this.runCommand||!this.forceUniformStore||!this.centermassFbo||!this.centermassTexture||!n.previousPositionTexture||n.previousPositionTexture.destroyed||!n.velocityFbo||n.velocityFbo.destroyed||!n.exitTexture||n.exitTexture.destroyed||i.pointsTextureSize!==this.previousPointsTextureSize||!this.pointIndices)return;const r=t.beginRenderPass({framebuffer:this.centermassFbo,clearColor:[0,0,0,0]});this.calculateCentermassCommand.setBindings({positionsTexture:n.previousPositionTexture,exitTexture:n.exitTexture}),this.calculateCentermassCommand.draw(r),r.end(),this.forceUniformStore.setUniforms({forceCenterUniforms:{centerForce:this.config.simulationCenter,alpha:i.alpha}}),this.runCommand.setBindings({positionsTexture:n.previousPositionTexture,centermassTexture:this.centermassTexture});const s=t.beginRenderPass({framebuffer:n.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(s),s.end()}destroy(){var t,i,n;(t=this.calculateCentermassCommand)==null||t.destroy(),this.calculateCentermassCommand=void 0,(i=this.runCommand)==null||i.destroy(),this.runCommand=void 0,this.centermassFbo&&!this.centermassFbo.destroyed&&this.centermassFbo.destroy(),this.centermassFbo=void 0,this.centermassTexture&&!this.centermassTexture.destroyed&&this.centermassTexture.destroy(),this.centermassTexture=void 0,(n=this.forceUniformStore)==null||n.destroy(),this.forceUniformStore=void 0,this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=void 0,this.forceVertexCoordBuffer&&!this.forceVertexCoordBuffer.destroyed&&this.forceVertexCoordBuffer.destroy(),this.forceVertexCoordBuffer=void 0,this.previousPointsTextureSize=void 0}}const qT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D sizeTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform buildGridUniforms { + float gridTextureSize; + float cellSize; + vec2 gridOffset; // Offset for multi-pass (0-1 range, multiplied by cellSize) +} buildGrid; + +#define gridTextureSize buildGrid.gridTextureSize +#define cellSize buildGrid.cellSize +#define gridOffset buildGrid.gridOffset +#else +uniform float gridTextureSize; +uniform float cellSize; +uniform vec2 gridOffset; +#endif + +in vec2 pointIndices; + +out vec4 cellData; // xy = position, z = size, w = count (1.0) + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not enter the grid — a NaN position bins to a NaN cell and + // poisons the accumulated position/size sum for every point in that cell. (exit.g = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 pointSize = texelFetch(sizeTexture, pointTexel, 0); + + // Output: position sum, size sum, count + cellData = vec4(pointPosition.xy, pointSize.r, 1.0); + + // Apply grid offset for multi-pass collision detection + vec2 offsetPosition = pointPosition.xy + gridOffset * cellSize; + + // Calculate which grid cell this point belongs to + float cellX = floor(offsetPosition.x / cellSize); + float cellY = floor(offsetPosition.y / cellSize); + + // Clamp to grid bounds + cellX = clamp(cellX, 0.0, gridTextureSize - 1.0); + cellY = clamp(cellY, 0.0, gridTextureSize - 1.0); + + // Convert to clip space coordinates + vec2 gridPosition = 2.0 * (vec2(cellX, cellY) + 0.5) / gridTextureSize - 1.0; + + gl_Position = vec4(gridPosition, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,GT=`#version 300 es +precision highp float; + +in vec4 cellData; +out vec4 fragColor; + +void main() { + // Output accumulated cell data (blended additively) + // xy = sum of positions, z = sum of sizes, w = count + fragColor = cellData; +} +`,ZT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D sizeTexture; +uniform sampler2D gridTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceCollisionUniforms { + float gridTextureSize; + float cellSize; + float alpha; + float collisionStrength; + float collisionRadius; + float collisionPadding; + float pointsNumber; + vec2 gridOffset; // Must match the offset used when building the grid +} forceCollision; + +#define gridTextureSize forceCollision.gridTextureSize +#define cellSize forceCollision.cellSize +#define alpha forceCollision.alpha +#define collisionStrength forceCollision.collisionStrength +#define collisionRadius forceCollision.collisionRadius +#define collisionPadding forceCollision.collisionPadding +#define pointsNumber forceCollision.pointsNumber +#define gridOffset forceCollision.gridOffset +#else +uniform float gridTextureSize; +uniform float cellSize; +uniform float alpha; +uniform float collisionStrength; +uniform float collisionRadius; +uniform float collisionPadding; +uniform float pointsNumber; +uniform vec2 gridOffset; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + + // Get current point's index + float currentIndex = pointPosition.b; + + // Skip if this is an empty texel + if (currentIndex < 0.0 || currentIndex >= pointsNumber) { + fragColor = velocity; + return; + } + + // Get current point's size for collision radius + vec4 currentSizeData = texelFetch(sizeTexture, pointTexel, 0); + float currentSize = currentSizeData.r; + float currentCollisionRadius = (collisionRadius > 0.0 ? collisionRadius : currentSize * 0.5) + collisionPadding; + + vec2 currentPos = pointPosition.rg; + + // Apply the same offset used when building the grid + vec2 offsetPos = currentPos + gridOffset * cellSize; + + // Calculate which grid cell this point is in (with offset). + // Clamp to the grid bounds to match build-grid.vert, so a point that drifts + // outside the space still reads the edge cell it was binned into. + float myCellX = clamp(floor(offsetPos.x / cellSize), 0.0, gridTextureSize - 1.0); + float myCellY = clamp(floor(offsetPos.y / cellSize), 0.0, gridTextureSize - 1.0); + + // Track total neighbor count for damping + float totalNeighbors = 0.0; + + // Check 3x3 neighborhood of cells + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + float neighborCellX = myCellX + float(dx); + float neighborCellY = myCellY + float(dy); + + // Skip cells outside grid bounds + if (neighborCellX < 0.0 || neighborCellX >= gridTextureSize || + neighborCellY < 0.0 || neighborCellY >= gridTextureSize) { + continue; + } + + // Sample the grid cell (the bounds check above keeps the fetch in range) + ivec2 cell = ivec2(neighborCellX, neighborCellY); + vec4 cellData = texelFetch(gridTexture, cell, 0); + + float cellCount = cellData.w; + if (cellCount < 0.5) continue; // Empty cell + + // The own cell's sums include this point, which drags the average toward + // it and halves the measured distance for a two-point cell. Remove the + // self-contribution before averaging, and skip a cell holding only self. + float effectiveCount = cellCount; + vec2 sumPos = cellData.xy; + float sumSize = cellData.z; + if (dx == 0 && dy == 0) { + effectiveCount = cellCount - 1.0; + sumPos -= currentPos; + sumSize -= currentSize; + } + if (effectiveCount < 0.5) continue; + + totalNeighbors += effectiveCount; + + // Average position and size of the *other* points in this cell + vec2 avgPos = sumPos / effectiveCount; + float avgSize = sumSize / effectiveCount; + float otherCollisionRadius = (collisionRadius > 0.0 ? collisionRadius : avgSize * 0.5) + collisionPadding; + + // Calculate combined collision radius + float combinedRadius = currentCollisionRadius + otherCollisionRadius; + + // Calculate distance vector to average position (using original positions) + vec2 distVector = currentPos - avgPos; + float dist = length(distVector); + + // Check for collision + if (dist < combinedRadius && dist > 0.001) { + // Calculate overlap ratio (0 = just touching, 1 = fully overlapping) + float overlapRatio = (combinedRadius - dist) / combinedRadius; + + // Soft collision curve: use square root for gentler force near edges + // This prevents the "ping-pong" effect at boundaries + float softOverlap = sqrt(overlapRatio) * combinedRadius * 0.5; + + // Direction to push apart (normalized) + vec2 direction = distVector / dist; + + // Apply repulsion force with soft curve + // Divide by 4 since we run 4 passes with different offsets + float force = alpha * collisionStrength * softOverlap * 0.25 * effectiveCount; + + // Clamp maximum force to prevent instability + force = min(force, combinedRadius * 0.5); + + velocity.rg += force * direction; + } else if (dist <= 0.001 && effectiveCount > 0.0) { + // Points at same position - push based on index + float angle = currentIndex * 0.618033988749895; + float force = min(alpha * collisionStrength * combinedRadius * 0.1, combinedRadius * 0.3); + velocity.rg += force * effectiveCount * vec2(cos(angle), sin(angle)); + } + } + } + + // Apply density-based damping: reduce force when surrounded by many neighbors + // This prevents chaotic oscillations in dense clusters + if (totalNeighbors > 2.0) { + float damping = 2.0 / totalNeighbors; + velocity.rg *= damping; + } + + // Cap the per-pass correction so overlaps resolve by relaxation over a few + // frames instead of overshooting in one. Across the 4 offset passes the + // total displacement stays within ~40% of this point's collision radius, + // which converges without the ping-pong of full-overlap corrections. + float maxCorrection = currentCollisionRadius * 0.1; + float correction = length(velocity.rg); + if (correction > maxCorrection) { + velocity.rg *= maxCorrection / correction; + } + + fragColor = velocity; +} +`,tn=[[0,0],[.5,0],[0,.5],[.5,.5]];class QT extends gt{constructor(){super(...arguments),this.gridTargets=[],this.gridTextureSize=0,this.cellSize=0}create(){var p;const{device:t,store:i,data:n,config:r}=this;if(!i.pointsTextureSize||n.pointsNumber===void 0)return;let o=r.pointDefaultSize??Ze.pointDefaultSize;if(n.pointSizes&&n.pointsNumber!==void 0)for(let g=0;g<n.pointsNumber;g++)o=Math.max(o,n.getResolvedPointSize(g));const a=r.simulationCollisionRadius??0,l=r.simulationCollisionPadding??0,c=(a>0?a:o*.5)+l;this.cellSize=Math.max(c*2,8),this.gridTextureSize=Math.min(512,Math.max(1,Math.floor(i.adjustedSpaceSize/this.cellSize))),this.cellSize=i.adjustedSpaceSize/this.gridTextureSize,this.gridTargets.length===tn.length&&this.gridTargets.every(g=>!g.texture.destroyed&&!g.fbo.destroyed&&g.texture.width===this.gridTextureSize)||(this.destroyGridTargets(),this.gridTargets=tn.map(()=>{const g=t.createTexture({width:this.gridTextureSize,height:this.gridTextureSize,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),x=t.createFramebuffer({width:this.gridTextureSize,height:this.gridTextureSize,colorAttachments:[g]});return{texture:g,fbo:x}}));const d=new Float32Array(i.pointsTextureSize*i.pointsTextureSize*4);for(let g=0;g<n.pointsNumber;g++)d[g*4]=n.getResolvedPointSize(g);(!this.sizeTexture||this.sizeTexture.destroyed||this.sizeTexture.width!==i.pointsTextureSize||this.sizeTexture.height!==i.pointsTextureSize)&&(this.sizeTexture&&!this.sizeTexture.destroyed&&this.sizeTexture.destroy(),this.sizeTexture=t.createTexture({width:i.pointsTextureSize,height:i.pointsTextureSize,format:"rgba32float",usage:M.SAMPLE|M.COPY_DST})),this.sizeTexture.copyImageData({data:d,bytesPerRow:q("rgba32float",i.pointsTextureSize),mipLevel:0,x:0,y:0}),(!this.pointIndices||this.previousPointsTextureSize!==i.pointsTextureSize)&&(this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=t.createBuffer({data:ji(i.pointsTextureSize),usage:B.VERTEX|B.COPY_DST}),(p=this.buildGridCommand)==null||p.setAttributes({pointIndices:this.pointIndices})),this.previousPointsTextureSize=i.pointsTextureSize,this.previousSpaceSize=i.adjustedSpaceSize}initPrograms(){const{device:t,store:i,data:n}=this;!n.pointsNumber||!i.pointsTextureSize||(this.buildGridUniformStore||(this.buildGridUniformStore=new oe(t,{buildGridUniforms:{uniformTypes:{gridTextureSize:"f32",cellSize:"f32",gridOffset:"vec2<f32>"}}})),this.buildGridCommand||(this.buildGridCommand=new ee(t,{fs:GT,vs:qT,topology:"point-list",vertexCount:n.pointsNumber,attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{buildGridUniforms:this.buildGridUniformStore.getManagedUniformBuffer("buildGridUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.forceUniformStore||(this.forceUniformStore=new oe(t,{forceCollisionUniforms:{uniformTypes:{gridTextureSize:"f32",cellSize:"f32",alpha:"f32",collisionStrength:"f32",collisionRadius:"f32",collisionPadding:"f32",pointsNumber:"f32",gridOffset:"vec2<f32>"}}})),this.forceVertexCoordBuffer||(this.forceVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.forceCommand||(this.forceCommand=new ee(t,{fs:ZT,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceCollisionUniforms:this.forceUniformStore.getManagedUniformBuffer("forceCollisionUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})))}run(){const{device:t,store:i,data:n,points:r,config:s}=this;if(!r||!this.buildGridCommand||!this.buildGridUniformStore||!this.forceCommand||!this.forceUniformStore||!this.pointIndices||n.pointsNumber===void 0||!r.previousPositionTexture||r.previousPositionTexture.destroyed||!r.exitTexture||r.exitTexture.destroyed||!r.velocityFbo||r.velocityFbo.destroyed||!this.sizeTexture||this.sizeTexture.destroyed||this.gridTargets.length!==tn.length||i.pointsTextureSize!==this.previousPointsTextureSize||i.adjustedSpaceSize!==this.previousSpaceSize)return;const o=s.simulationCollisionRadius??0,a=s.simulationCollisionPadding??0;this.buildGridCommand.setVertexCount(n.pointsNumber),this.buildGridCommand.setBindings({positionsTexture:r.previousPositionTexture,sizeTexture:this.sizeTexture,exitTexture:r.exitTexture});for(const[c,u]of tn.entries()){const d=this.gridTargets[c];if(!d||d.fbo.destroyed||d.texture.destroyed)continue;this.buildGridUniformStore.setUniforms({buildGridUniforms:{gridTextureSize:this.gridTextureSize,cellSize:this.cellSize,gridOffset:u}});const h=t.beginRenderPass({framebuffer:d.fbo,clearColor:[0,0,0,0]});this.buildGridCommand.draw(h),h.end()}this.forceCommand.setBindings({positionsTexture:r.previousPositionTexture,sizeTexture:this.sizeTexture});const l=t.beginRenderPass({framebuffer:r.velocityFbo,clearColor:[0,0,0,0]});for(const[c,u]of tn.entries()){const d=this.gridTargets[c];!d||d.texture.destroyed||(this.forceUniformStore.setUniforms({forceCollisionUniforms:{gridTextureSize:this.gridTextureSize,cellSize:this.cellSize,alpha:i.alpha,collisionStrength:s.simulationCollision??0,collisionRadius:o,collisionPadding:a,pointsNumber:n.pointsNumber,gridOffset:u}}),this.forceCommand.setBindings({gridTexture:d.texture}),this.forceCommand.draw(l))}l.end()}destroy(){var t,i,n,r;(t=this.buildGridCommand)==null||t.destroy(),this.buildGridCommand=void 0,(i=this.forceCommand)==null||i.destroy(),this.forceCommand=void 0,this.destroyGridTargets(),this.sizeTexture&&!this.sizeTexture.destroyed&&this.sizeTexture.destroy(),this.sizeTexture=void 0,(n=this.buildGridUniformStore)==null||n.destroy(),this.buildGridUniformStore=void 0,(r=this.forceUniformStore)==null||r.destroy(),this.forceUniformStore=void 0,this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=void 0,this.forceVertexCoordBuffer&&!this.forceVertexCoordBuffer.destroyed&&this.forceVertexCoordBuffer.destroy(),this.forceVertexCoordBuffer=void 0}destroyGridTargets(){for(const t of this.gridTargets)t.fbo&&!t.fbo.destroyed&&t.fbo.destroy();for(const t of this.gridTargets)t.texture&&!t.texture.destroyed&&t.texture.destroy();this.gridTargets=[]}}const JT=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceGravityUniforms { + float gravity; + float spaceSize; + float alpha; +} forceGravity; + +#define gravity forceGravity.gravity +#define spaceSize forceGravity.spaceSize +#define alpha forceGravity.alpha +#else +uniform float gravity; +uniform float spaceSize; +uniform float alpha; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + + vec4 velocity = vec4(0.0); + + vec2 centerPosition = vec2(spaceSize * 0.5); + vec2 distVector = centerPosition - pointPosition.rg; + float dist = sqrt(dot(distVector, distVector)); + if (dist > 0.0) { + float angle = atan(distVector.y, distVector.x); + float additionalVelocity = alpha * gravity * dist * 0.1; + velocity.rg += additionalVelocity * vec2(cos(angle), sin(angle)); + } + + fragColor = velocity; +}`;class ev extends gt{initPrograms(){const{device:t,points:i,store:n}=this;!i||!n.pointsTextureSize||(this.vertexCoordBuffer||(this.vertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.uniformStore||(this.uniformStore=new oe(t,{forceGravityUniforms:{uniformTypes:{gravity:"f32",spaceSize:"f32",alpha:"f32"}}})),this.runCommand||(this.runCommand=new ee(t,{fs:JT,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.vertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceGravityUniforms:this.uniformStore.getManagedUniformBuffer("forceGravityUniforms")},parameters:te})))}run(){const{device:t,points:i,store:n}=this;if(!i||!this.runCommand||!this.uniformStore||!i.previousPositionTexture||i.previousPositionTexture.destroyed||!i.velocityFbo||i.velocityFbo.destroyed)return;this.uniformStore.setUniforms({forceGravityUniforms:{gravity:this.config.simulationGravity,spaceSize:n.adjustedSpaceSize,alpha:n.alpha}}),this.runCommand.setBindings({positionsTexture:i.previousPositionTexture});const r=t.beginRenderPass({framebuffer:i.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(r),r.end()}destroy(){var t,i;(t=this.runCommand)==null||t.destroy(),this.runCommand=void 0,(i=this.uniformStore)==null||i.destroy(),this.uniformStore=void 0,this.vertexCoordBuffer&&!this.vertexCoordBuffer.destroyed&&this.vertexCoordBuffer.destroy(),this.vertexCoordBuffer=void 0}}function tv(e){return`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; +uniform sampler2D linkInfoTexture; // Texture storing first link indices and amount +uniform sampler2D linkIndicesTexture; +uniform sampler2D linkPropertiesTexture; // Texture storing link bias and strength +uniform sampler2D linkRandomDistanceTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceLinkUniforms { + float linkSpring; + float linkDistance; + vec2 linkDistRandomVariationRange; + float linksTextureSize; + float alpha; +} forceLink; + +#define linkSpring forceLink.linkSpring +#define linkDistance forceLink.linkDistance +#define linkDistRandomVariationRange forceLink.linkDistRandomVariationRange +#define linksTextureSize forceLink.linksTextureSize +#define alpha forceLink.alpha +#else +uniform float linkSpring; +uniform float linkDistance; +uniform vec2 linkDistRandomVariationRange; +uniform float linksTextureSize; +uniform float alpha; +#endif + +out vec4 fragColor; + +const float MAX_LINKS = ${e}.0; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + + vec4 linkInfo = texelFetch(linkInfoTexture, pointTexel, 0); + float iCount = linkInfo.r; + float jCount = linkInfo.g; + float linkAmount = linkInfo.b; + if (linkAmount > 0.0) { + for (float i = 0.0; i < MAX_LINKS; i += 1.0) { + if (i < linkAmount) { + if (iCount >= linksTextureSize) { + iCount = 0.0; + jCount += 1.0; + } + ivec2 linkTexel = ivec2(iCount, jCount); + vec4 connectedPointIndex = texelFetch(linkIndicesTexture, linkTexel, 0); + vec4 biasAndStrength = texelFetch(linkPropertiesTexture, linkTexel, 0); + vec4 randomMinDistance = texelFetch(linkRandomDistanceTexture, linkTexel, 0); + float bias = biasAndStrength.r; + float strength = biasAndStrength.g; + float randomMinLinkDist = randomMinDistance.r * (linkDistRandomVariationRange.g - linkDistRandomVariationRange.r) + linkDistRandomVariationRange.r; + randomMinLinkDist *= linkDistance; + + iCount += 1.0; + + // linkIndicesTexture stores whole texel coordinates, so truncating is exact. + ivec2 connectedTexel = ivec2(connectedPointIndex.rg); + + // Skip a link to an absent point — its position would poison the spring + // force. (exit.G = current absence) + vec4 connectedExit = texelFetch(exitTexture, connectedTexel, 0); + if (connectedExit.g > 0.5) { + continue; + } + + vec4 connectedPointPosition = texelFetch(positionsTexture, connectedTexel, 0); + float x = connectedPointPosition.x - (pointPosition.x + velocity.x); + float y = connectedPointPosition.y - (pointPosition.y + velocity.y); + float l = sqrt(x * x + y * y); + + // Apply the link force + l = max(l, randomMinLinkDist * 0.99); + l = (l - randomMinLinkDist) / l; + l *= linkSpring * alpha; + l *= strength; + l *= bias; + x *= l; + y *= l; + velocity.x += x; + velocity.y += y; + } + } + } + + fragColor = vec4(velocity.rg, 0.0, 0.0); +} + `}var jo=(e=>(e.OUTGOING="outgoing",e.INCOMING="incoming",e))(jo||{});class Td extends gt{constructor(){super(...arguments),this.linkFirstIndicesAndAmount=new Float32Array,this.indices=new Float32Array,this.maxPointDegree=0}create(t){var d,h,p,g;const{device:i,store:{pointsTextureSize:n,linksTextureSize:r},data:s}=this;if(!n||!r)return;this.linkFirstIndicesAndAmount=new Float32Array(n*n*4),this.indices=new Float32Array(r*r*4);const o=new Float32Array(r*r*4),a=new Float32Array(r*r*4),l=t==="incoming"?s.linksBySource:s.linksByTarget;if(this.maxPointDegree=0,l){const{offsets:x,neighbors:T,linkIndices:S}=l;for(let P=0;P<x.length-1;P++){const I=x[P],y=x[P+1],v=y-I;if(v!==0){this.linkFirstIndicesAndAmount[P*4+0]=I%r,this.linkFirstIndicesAndAmount[P*4+1]=Math.floor(I/r),this.linkFirstIndicesAndAmount[P*4+2]=v;for(let E=I;E<y;E++){const R=T[E],D=S[E];this.indices[E*4+0]=R%n,this.indices[E*4+1]=Math.floor(R/n);const z=((d=s.degree)==null?void 0:d[R])??0,$=((h=s.degree)==null?void 0:h[P])??0,F=z+$,Q=F!==0?z/F:.5,X=Math.min(z,$);let b=(p=s.linkStrength)==null?void 0:p[D];(b===void 0||!Number.isFinite(b)||b<0)&&(b=1/Math.max(X,1)),b=Math.sqrt(b),o[E*4+0]=Q,o[E*4+1]=b,a[E*4]=this.store.getRandomFloat(0,1)}this.maxPointDegree=Math.max(this.maxPointDegree,v)}}}const c=!this.linkFirstIndicesAndAmountTexture||this.linkFirstIndicesAndAmountTexture.width!==n||this.linkFirstIndicesAndAmountTexture.height!==n,u=!this.indicesTexture||this.indicesTexture.width!==r||this.indicesTexture.height!==r;c&&(this.linkFirstIndicesAndAmountTexture&&!this.linkFirstIndicesAndAmountTexture.destroyed&&this.linkFirstIndicesAndAmountTexture.destroy(),this.linkFirstIndicesAndAmountTexture=i.createTexture({width:n,height:n,format:"rgba32float",usage:M.SAMPLE|M.COPY_DST})),this.linkFirstIndicesAndAmountTexture.copyImageData({data:this.linkFirstIndicesAndAmount,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0}),u&&(this.indicesTexture&&!this.indicesTexture.destroyed&&this.indicesTexture.destroy(),this.biasAndStrengthTexture&&!this.biasAndStrengthTexture.destroyed&&this.biasAndStrengthTexture.destroy(),this.randomDistanceTexture&&!this.randomDistanceTexture.destroyed&&this.randomDistanceTexture.destroy(),this.indicesTexture=i.createTexture({width:r,height:r,format:"rgba32float",usage:M.SAMPLE|M.COPY_DST}),this.biasAndStrengthTexture=i.createTexture({width:r,height:r,format:"rgba32float",usage:M.SAMPLE|M.COPY_DST}),this.randomDistanceTexture=i.createTexture({width:r,height:r,format:"rgba32float",usage:M.SAMPLE|M.COPY_DST})),this.indicesTexture.copyImageData({data:this.indices,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),this.biasAndStrengthTexture.copyImageData({data:o,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),this.randomDistanceTexture.copyImageData({data:a,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),this.previousMaxPointDegree!==void 0&&this.previousMaxPointDegree!==this.maxPointDegree&&((g=this.runCommand)==null||g.destroy(),this.runCommand=void 0),this.previousMaxPointDegree=this.maxPointDegree,this.previousPointsTextureSize=n,this.previousLinksTextureSize=r}initPrograms(){const{device:t,store:i,points:n}=this;!n||!i.pointsTextureSize||!i.linksTextureSize||!this.linkFirstIndicesAndAmountTexture||!this.indicesTexture||!this.biasAndStrengthTexture||!this.randomDistanceTexture||(this.vertexCoordBuffer||(this.vertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.uniformStore||(this.uniformStore=new oe(t,{forceLinkUniforms:{uniformTypes:{linkSpring:"f32",linkDistance:"f32",linkDistRandomVariationRange:"vec2<f32>",linksTextureSize:"f32",alpha:"f32"}}})),this.runCommand||(this.runCommand=new ee(t,{fs:tv(this.maxPointDegree),vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.vertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceLinkUniforms:this.uniformStore.getManagedUniformBuffer("forceLinkUniforms")},parameters:te})))}run(){const{device:t,store:i,points:n}=this;if(!n||!this.runCommand||!this.uniformStore||!n.previousPositionTexture||n.previousPositionTexture.destroyed||!n.exitTexture||n.exitTexture.destroyed||!this.linkFirstIndicesAndAmountTexture||!this.indicesTexture||!this.biasAndStrengthTexture||!this.randomDistanceTexture||!n.velocityFbo||n.velocityFbo.destroyed||i.pointsTextureSize!==this.previousPointsTextureSize||i.linksTextureSize!==this.previousLinksTextureSize)return;this.uniformStore.setUniforms({forceLinkUniforms:{linkSpring:this.config.simulationLinkSpring,linkDistance:this.config.simulationLinkDistance,linkDistRandomVariationRange:ie(this.config.simulationLinkDistRandomVariationRange,[0,0]),linksTextureSize:i.linksTextureSize,alpha:i.alpha}}),this.runCommand.setBindings({positionsTexture:n.previousPositionTexture,exitTexture:n.exitTexture,linkInfoTexture:this.linkFirstIndicesAndAmountTexture,linkIndicesTexture:this.indicesTexture,linkPropertiesTexture:this.biasAndStrengthTexture,linkRandomDistanceTexture:this.randomDistanceTexture});const r=t.beginRenderPass({framebuffer:n.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(r),r.end()}destroy(){var t,i;(t=this.runCommand)==null||t.destroy(),this.runCommand=void 0,this.linkFirstIndicesAndAmountTexture&&!this.linkFirstIndicesAndAmountTexture.destroyed&&this.linkFirstIndicesAndAmountTexture.destroy(),this.linkFirstIndicesAndAmountTexture=void 0,this.indicesTexture&&!this.indicesTexture.destroyed&&this.indicesTexture.destroy(),this.indicesTexture=void 0,this.biasAndStrengthTexture&&!this.biasAndStrengthTexture.destroyed&&this.biasAndStrengthTexture.destroy(),this.biasAndStrengthTexture=void 0,this.randomDistanceTexture&&!this.randomDistanceTexture.destroyed&&this.randomDistanceTexture.destroy(),this.randomDistanceTexture=void 0,(i=this.uniformStore)==null||i.destroy(),this.uniformStore=void 0,this.vertexCoordBuffer&&!this.vertexCoordBuffer.destroyed&&this.vertexCoordBuffer.destroy(),this.vertexCoordBuffer=void 0}}const iv=`#version 300 es +precision highp float; + +in vec4 vColor; +out vec4 fragColor; + +void main() { + fragColor = vColor; +}`,nv=`#version 300 es +precision highp float; + +// Aggregates each point into its grid cell. A level is a plain 2D grid of +// \`levelGridSize\` cells per axis rendered one texel per cell; additive blending +// accumulates [sum(x), sum(y), count, 0] per cell via calculate-level.frag. + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform calculateLevelsPreciseUniforms { + float levelGridSize; + float cellSize; +} calculateLevelsPrecise; + +#define levelGridSize calculateLevelsPrecise.levelGridSize +#define cellSize calculateLevelsPrecise.cellSize +#else +uniform float levelGridSize; +uniform float cellSize; +#endif + +in vec2 pointIndices; + +out vec4 vColor; + +void main() { + vColor = vec4(0.0); + + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not enter the grid — a NaN position bins to a NaN cell and + // poisons the centermass that drives repulsion for every point. (exit.G = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vColor = vec4(pointPosition.rg, 1.0, 0.0); + + // The clamp must match the force shaders exactly, or boundary points fall out + // of the level decomposition's exactly-once coverage. + int gridSize = int(levelGridSize); + ivec2 cell = clamp(ivec2(floor(pointPosition.rg / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + vec2 levelPosition = 2.0 * (vec2(cell) + 0.5) / levelGridSize - 1.0; + gl_Position = vec4(levelPosition, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,rv=`#version 300 es +precision highp float; + +// One grid level of precise many-body repulsion (Barnes-Hut-style approximation). +// +// Levels are 2D grids of increasing resolution (4², 8², …) holding +// [sum(x), sum(y), count, 0] per cell. The decomposition tiles space exactly +// once across the level passes: after level L the only un-accumulated region is +// the 3×3 Chebyshev-1 neighborhood of the point's cell, which the next level +// refines (its aligned 6×6 child block), and which force-nearfield.frag finally +// covers at the finest level. The exclusion shell is fixed at Chebyshev +// distance 1. + +uniform sampler2D positionsTexture; +uniform sampler2D levelTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceLevelPreciseUniforms { + float levelGridSize; + float cellSize; + float isFirstLevel; + float alpha; + float repulsion; +} forceLevelPrecise; + +#define levelGridSize forceLevelPrecise.levelGridSize +#define cellSize forceLevelPrecise.cellSize +#define isFirstLevel forceLevelPrecise.isFirstLevel +#define alpha forceLevelPrecise.alpha +#define repulsion forceLevelPrecise.repulsion +#else +uniform float levelGridSize; +uniform float cellSize; +uniform float isFirstLevel; +uniform float alpha; +uniform float repulsion; +#endif + +out vec4 fragColor; + +// Repulsion from one cell's center of mass — a d3-style clamped +// inverse-distance falloff. +vec2 cellVelocity(ivec2 cell, vec2 position) { + vec4 centermass = texelFetch(levelTexture, cell, 0); + // Count-only guard: zero coordinate sums are legitimate, but dividing by a zero + // count would produce NaN that additive blending propagates into the velocity FBO. + if (centermass.b <= 0.0) return vec2(0.0); + vec2 centermassPosition = centermass.rg / centermass.b; + vec2 distVector = position - centermassPosition; + float l = dot(distVector, distVector); + if (l <= 0.0) return vec2(0.0); + float distanceMin2 = 1.0; + if (l < distanceMin2) l = sqrt(distanceMin2 * l); + float addV = alpha * repulsion * centermass.b / sqrt(l); + return addV * normalize(distVector); +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 position = pointPosition.rg; + + int gridSize = int(levelGridSize); + // Must match the aggregation shader's cell formula exactly. + ivec2 pointCell = clamp(ivec2(floor(position / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + vec2 velocity = vec2(0.0); + + if (isFirstLevel > 0.5) { + // Coarsest level: every cell except the 3×3 neighborhood, which finer levels refine. + for (int j = 0; j < gridSize; j += 1) { + for (int i = 0; i < gridSize; i += 1) { + ivec2 cell = ivec2(i, j); + ivec2 cellDist = abs(cell - pointCell); + if (max(cellDist.x, cellDist.y) <= 1) continue; + velocity += cellVelocity(cell, position); + } + } + } else { + // The coarser level left its 3×3 neighborhood unhandled; those cells refine to + // the aligned 6×6 child block at this level. Sample it minus this level's own + // 3×3 neighborhood (always strictly inside the block). + ivec2 base = (pointCell / 2) * 2 - 2; + for (int j = 0; j < 6; j += 1) { + for (int i = 0; i < 6; i += 1) { + ivec2 cell = base + ivec2(i, j); + // Bounds check must precede texelFetch (out-of-range fetches are undefined). + if (any(lessThan(cell, ivec2(0))) || any(greaterThanEqual(cell, ivec2(gridSize)))) continue; + ivec2 cellDist = abs(cell - pointCell); + if (max(cellDist.x, cellDist.y) <= 1) continue; + velocity += cellVelocity(cell, position); + } + } + } + + fragColor = vec4(velocity, 0.0, 0.0); +} +`,sv=`#version 300 es +precision highp float; +// Fragment shaders default int to mediump, guaranteed only to 32767 — +// point indices go far higher. +precision highp int; + +// Near-field pass of the precise grid repulsion (P3M-style). After the finest +// level pass, the only un-accumulated region is the 3×3 neighborhood of the +// point's cell. +// +// Cell centroids exert a purely radial force there, which flattens dense hubs +// into disks and petals — even as a residual for unsampled mass, the centroid +// bias dominates (tangential repulsion scaled by ~K/n never spreads a dense +// clump before alpha decays). So the near field is a pure Monte-Carlo estimator +// instead: the K depth-peeled points of a cell are a uniform random subset +// (re-drawn every tick by build-nearfield-slots.vert), and weighting each +// sampled pairwise force by count/sampled makes the expected force equal the +// exact all-pairs sum — unbiased, no centroid term. Cells holding ≤ K points +// are sampled exhaustively, so their forces are exact. The per-tick sampling +// noise acts as annealed jitter: it shrinks with alpha and is precisely what +// breaks clumps apart. The point itself is excluded from both the sample and +// the count. + +uniform sampler2D positionsTexture; +uniform sampler2D levelTexture; +uniform sampler2D randomValues; +// All near-field slots live in one array texture (one layer per depth-peeling +// pass), so the slot count is a runtime uniform instead of a hard-wired list +// of sampler2Ds. Float data — highp, the default sampler precision is lowp. +uniform highp sampler2DArray slotsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceNearFieldUniforms { + float pointsTextureSize; + float levelGridSize; + float cellSize; + float alpha; + float repulsion; + float slotCount; +} forceNearField; + +#define pointsTextureSize forceNearField.pointsTextureSize +#define levelGridSize forceNearField.levelGridSize +#define cellSize forceNearField.cellSize +#define alpha forceNearField.alpha +#define repulsion forceNearField.repulsion +#define slotCount forceNearField.slotCount +#else +uniform float pointsTextureSize; +uniform float levelGridSize; +uniform float cellSize; +uniform float alpha; +uniform float repulsion; +uniform float slotCount; +#endif + +out vec4 fragColor; + +// Same clamped inverse-distance falloff as the level passes (must stay identical). +vec2 pairwiseVelocity(vec2 position, vec2 otherPosition, vec2 randomDir) { + vec2 distVector = position - otherPosition; + float l = dot(distVector, distVector); + if (l <= 0.0) { + // Exactly coincident points have no separation direction, so an inverse-distance + // force is undefined and they would stay stacked forever — a stack's cell count + // then repels everything around it, carving a void ring. Kick along this point's + // random vector instead (each point has a different one, so a pile disperses). + distVector = randomDir; + l = dot(distVector, distVector); + if (l <= 0.0) return vec2(0.0); + } + float distanceMin2 = 1.0; + if (l < distanceMin2) l = sqrt(distanceMin2 * l); + float addV = alpha * repulsion / sqrt(l); + return addV * normalize(distVector); +} + +// One peeled slot of a cell: the unweighted pairwise force from the sampled +// point, counting it toward the sample size. Empty slots and the point itself +// contribute nothing. +vec2 slotVelocity(vec2 slot, vec2 position, float selfIndex, vec2 randomDir, inout float sampled) { + float index = slot.x; + // Skip empty slots (index -1) and the point itself. This exact \`==\` — and the + // texel math just below — count on a point index fitting exactly in a float, + // which only holds for whole numbers up to ~16.7M (2^24). That's every + // realistic graph; you'd need a points texture bigger than 4096² to get there. + // Past that, indices start rounding, so a point could sample the wrong texel or + // fail to skip itself — but you'd hit memory limits long before it matters. + if (index < 0.0 || index == selfIndex) return vec2(0.0); + int size = int(pointsTextureSize); + int i = int(index); + vec4 other = texelFetch(positionsTexture, ivec2(i % size, i / size), 0); + sampled += 1.0; + return pairwiseVelocity(position, other.rg, randomDir); +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 position = pointPosition.rg; + // One fragment per point: the fragment's pixel is the point's texel. + float selfIndex = floor(gl_FragCoord.y) * pointsTextureSize + floor(gl_FragCoord.x); + vec4 random = texelFetch(randomValues, pointTexel, 0); + + int gridSize = int(levelGridSize); + ivec2 pointCell = clamp(ivec2(floor(position / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + vec2 velocity = vec2(0.0); + + for (int j = -1; j <= 1; j += 1) { + for (int i = -1; i <= 1; i += 1) { + ivec2 cell = pointCell + ivec2(i, j); + if (any(lessThan(cell, ivec2(0))) || any(greaterThanEqual(cell, ivec2(gridSize)))) continue; + + // [sum(x), sum(y), count, 0] — only the count is used here. + vec4 aggregate = texelFetch(levelTexture, cell, 0); + // The count never includes the point itself in the estimate. + bool ownCell = (i == 0 && j == 0); + float others = aggregate.b - (ownCell ? 1.0 : 0.0); + if (others <= 0.0) continue; + + vec2 pairSum = vec2(0.0); + float sampled = 0.0; + // One layer per depth-peeling pass. An exhausted cell peels empty slots + // (index -1) for the remaining layers; the early break skips them — + // empty layers can't be followed by occupied ones within a cell. + int slots = int(slotCount); + for (int s = 0; s < slots; s += 1) { + vec2 slot = texelFetch(slotsTexture, ivec3(cell, s), 0).rg; + if (slot.x < 0.0) break; + pairSum += slotVelocity(slot, position, selfIndex, random.rg, sampled); + } + + // Horvitz–Thompson weighting: the sample is uniform among the cell's + // other points (conditioned on whether the point itself was peeled), + // so scaling by others/sampled gives E[force] = exact all-pairs sum. + // Exhaustively peeled cells (others == sampled) are exact. + if (sampled > 0.0) velocity += (others / sampled) * pairSum; + } + } + + // Random jitter proportional to the velocity, to keep points from sticking. + velocity += velocity * random.rg; + + // Bound the per-tick kick to the neighborhood scale. The estimator is unbiased + // but high-variance: in a cell holding far more points than sampled slots, the + // count/sampled weight can turn a few close samples into a huge one-tick kick. + // Unbounded, that flings points across the screen at startup and — because the + // weight is largest where density is highest — ejects points from dense cluster + // centers, leaving voids. Clamping the magnitude keeps the spreading direction + // while capping the fling; genuine spreading kicks are far below this bound and + // pass through untouched. The far-field grid levels still drive bulk expansion. + float maxStep = 2.0 * cellSize; + float speed = length(velocity); + if (speed > maxStep) velocity *= maxStep / speed; + + fragColor = vec4(velocity, 0.0, 0.0); +} +`,ov=`#version 300 es +precision highp float; +// Fragment shaders default int to mediump, guaranteed only to 32767 — +// point indices go far higher. +precision highp int; + +// Exact all-pairs repulsion for small graphs. One fragment per point, looping +// over every other point — O(n²) total, but below the brute-force threshold a +// single pass is both cheaper than the grid pyramid's sequential depth-peeling +// passes and exact at any cell occupancy: no Monte-Carlo sampling, hence none +// of the per-tick re-sampling noise that shows up as shimmer in dense layouts +// (see force-nearfield.frag for the sampled path used above the threshold). + +uniform sampler2D positionsTexture; +uniform sampler2D randomValues; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceAllPairsUniforms { + float pointsTextureSize; + float pointsNumber; + float alpha; + float repulsion; + float maxStep; +} forceAllPairs; + +#define pointsTextureSize forceAllPairs.pointsTextureSize +#define pointsNumber forceAllPairs.pointsNumber +#define alpha forceAllPairs.alpha +#define repulsion forceAllPairs.repulsion +#define maxStep forceAllPairs.maxStep +#else +uniform float pointsTextureSize; +uniform float pointsNumber; +uniform float alpha; +uniform float repulsion; +uniform float maxStep; +#endif + +out vec4 fragColor; + +// Same clamped inverse-distance falloff as the grid-path shaders (must stay identical). +vec2 pairwiseVelocity(vec2 position, vec2 otherPosition, vec2 randomDir) { + vec2 distVector = position - otherPosition; + float l = dot(distVector, distVector); + if (l <= 0.0) { + // Exactly coincident points have no separation direction, so an + // inverse-distance force is undefined and they would stay stacked forever. + // Kick along this point's random vector instead (each point has a + // different one, so a pile disperses). + distVector = randomDir; + l = dot(distVector, distVector); + if (l <= 0.0) return vec2(0.0); + } + float distanceMin2 = 1.0; + if (l < distanceMin2) l = sqrt(distanceMin2 * l); + float addV = alpha * repulsion / sqrt(l); + return addV * normalize(distVector); +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + int size = int(pointsTextureSize); + int selfIndex = pointTexel.y * size + pointTexel.x; + int count = int(pointsNumber); + + // Fragments beyond the point count are unused texture pixels. + if (selfIndex >= count) { + fragColor = vec4(0.0); + return; + } + + // An absent point must neither move nor repel (its position is NaN). + vec4 selfExit = texelFetch(exitTexture, pointTexel, 0); + if (selfExit.g > 0.5) { + fragColor = vec4(0.0); + return; + } + + vec2 position = texelFetch(positionsTexture, pointTexel, 0).rg; + vec4 random = texelFetch(randomValues, pointTexel, 0); + + // Pairs are split at the grid path's near-field scale (maxStep = 2 × the + // finest cell size it would use at this point count): closer pairs + // correspond to its 3×3 near-field pass — jittered and bounded below, the + // way that pass bounds its own sum — farther pairs to its level passes, + // which it leaves unbounded. The same split keeps the dynamics continuous + // across the point-count threshold between the two paths. + vec2 nearVelocity = vec2(0.0); + vec2 farVelocity = vec2(0.0); + float nearRadius2 = maxStep * maxStep; + for (int i = 0; i < count; i += 1) { + if (i == selfIndex) continue; + ivec2 texel = ivec2(i % size, i / size); + if (texelFetch(exitTexture, texel, 0).g > 0.5) continue; + vec2 otherPosition = texelFetch(positionsTexture, texel, 0).rg; + vec2 distVector = position - otherPosition; + vec2 pairVelocity = pairwiseVelocity(position, otherPosition, random.rg); + if (dot(distVector, distVector) < nearRadius2) nearVelocity += pairVelocity; + else farVelocity += pairVelocity; + } + + // Random jitter proportional to the near velocity, to keep points from + // sticking (same as the near-field pass). + nearVelocity += nearVelocity * random.rg; + + // Bound the per-tick near kick. Exactness alone does not bound it: the + // falloff still diverges at near-zero separations, and a coincident stack + // sums n−1 same-direction random kicks into one fling. The clamp caps the + // magnitude and keeps the direction. + float speed = length(nearVelocity); + if (speed > maxStep) nearVelocity *= maxStep / speed; + + fragColor = vec4(farVelocity + nearVelocity, 0.0, 0.0); +} +`,av=`#version 300 es +precision highp float; + +// One depth-peeling pass of the near-field point-slot build. +// +// The precise grid's near field needs actual point-to-point forces (cell +// centroids alone exert a purely radial force that flattens dense hubs into +// disks and spikes). Each peeling pass selects, per finest-level cell, the +// not-yet-peeled point with the smallest per-tick random hash: the depth test +// keeps the smallest \`hashValue\` among eligible points, and eligibility excludes +// points already captured by the previous slot (hash <= previous slot's hash). +// Running K passes yields a uniform random K-subset per cell, re-randomized +// every tick via \`randomSeed\`; force-nearfield.frag turns it into an unbiased +// estimate of the cell's exact all-pairs repulsion (Monte-Carlo P3M). + +uniform sampler2D positionsTexture; +uniform sampler2D previousSlot; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform buildNearFieldSlotsUniforms { + float pointsTextureSize; + float levelGridSize; + float cellSize; + float hasPreviousSlot; + float randomSeed; +} buildNearFieldSlots; + +#define pointsTextureSize buildNearFieldSlots.pointsTextureSize +#define levelGridSize buildNearFieldSlots.levelGridSize +#define cellSize buildNearFieldSlots.cellSize +#define hasPreviousSlot buildNearFieldSlots.hasPreviousSlot +#define randomSeed buildNearFieldSlots.randomSeed +#else +uniform float pointsTextureSize; +uniform float levelGridSize; +uniform float cellSize; +uniform float hasPreviousSlot; +uniform float randomSeed; +#endif + +in vec2 pointIndices; + +out vec2 slotData; // [point index, hash] + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not be captured as neighbors — a NaN position bins to an + // undefined cell and its distance poisons the force of every point sampling + // that slot. Same guard as calculate-level.vert. (exit.G = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + slotData = vec2(-1.0, 1.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 1.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + float index = pointIndices.y * pointsTextureSize + pointIndices.x; + + // Per-tick random ordering via an integer hash (lowbias32). A fract(sin(...)) + // hash breaks down here: at large point indices GPU sin() loses precision + // (differently per vendor), producing correlated or colliding hashes — and a + // hash collision makes the peeling test below silently drop a point from the + // sample. Integer ops are exact everywhere, and both inputs are exact (the + // index is an integer-valued float; floatBitsToUint reinterprets seed bits). + uint h = uint(index) ^ floatBitsToUint(randomSeed); + h ^= h >> 16u; + h *= 0x7feb352du; + h ^= h >> 15u; + h *= 0x846ca68bu; + h ^= h >> 16u; + // Top 24 bits only, so the value is exactly representable in a float32 and + // round-trips bit-exactly through the slot texture into the next pass's + // comparison. Kept strictly inside (0, 1) so the depth range is safe. + float hashValue = (float(h >> 8u) + 0.5) / 16777216.0; + hashValue = 0.001 + hashValue * 0.998; + + // Must match the cell formula of the aggregation and force shaders exactly. + int gridSize = int(levelGridSize); + ivec2 cell = clamp(ivec2(floor(pointPosition.rg / cellSize)), ivec2(0), ivec2(gridSize - 1)); + + if (hasPreviousSlot > 0.5) { + vec2 previous = texelFetch(previousSlot, cell, 0).rg; + // Eligible only if the previous slot captured a point with a smaller hash. + // An empty previous slot (index -1) means the cell is exhausted — otherwise + // this pass would re-capture already-peeled points and double-count them. + if (previous.x < 0.0 || hashValue <= previous.y) { + slotData = vec2(-1.0, 1.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 1.0; + return; + } + } + + slotData = vec2(index, hashValue); + vec2 ndc = 2.0 * (vec2(cell) + 0.5) / levelGridSize - 1.0; + // The depth test (less) keeps the eligible point with the smallest hash. + gl_Position = vec4(ndc, hashValue * 2.0 - 1.0, 1.0); + gl_PointSize = 1.0; +} +`,lv=`#version 300 es +precision highp float; + +in vec2 slotData; +out vec4 fragColor; + +void main() { + fragColor = vec4(slotData, 0.0, 0.0); +} +`,cv=512,vd=e=>Math.min(cv,Math.max(8,Math.pow(2,Math.ceil(Math.log2(2*Math.sqrt(e)))))),uv=e=>e<=16384?32:e<=65536?16:8,dv=4096,pi=2;class hv extends gt{constructor(){super(...arguments),this.levels=0,this.levelTargets=new Map,this.nearFieldSlots=0,this.peelTargets=[]}get usesAllPairs(){return(this.data.pointsNumber??0)<=dv}create(){var o,a;const{device:t,store:i}=this;if(!i.pointsTextureSize)return;this.usesAllPairs?(this.destroyLevelTargets(),this.levels=0):this.createLevels();const n=i.pointsTextureSize*i.pointsTextureSize,r=new Float32Array(n*4);for(let l=0;l<n;++l)r[l*4]=i.getRandomFloat(-1,1)*1e-5,r[l*4+1]=i.getRandomFloat(-1,1)*1e-5;if((!this.randomValuesTexture||this.randomValuesTexture.destroyed||this.randomValuesTexture.width!==i.pointsTextureSize||this.randomValuesTexture.height!==i.pointsTextureSize)&&(this.randomValuesTexture&&!this.randomValuesTexture.destroyed&&this.randomValuesTexture.destroy(),this.randomValuesTexture=t.createTexture({width:i.pointsTextureSize,height:i.pointsTextureSize,format:"rgba32float",usage:M.SAMPLE|M.COPY_DST})),this.randomValuesTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",i.pointsTextureSize),mipLevel:0,x:0,y:0}),!this.pointIndices||this.previousPointsTextureSize!==i.pointsTextureSize){this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy();const l=ji(i.pointsTextureSize);this.pointIndices=t.createBuffer({data:l,usage:B.VERTEX|B.COPY_DST}),(o=this.calculateLevelsCommand)==null||o.setAttributes({pointIndices:this.pointIndices}),(a=this.buildNearFieldSlotsCommand)==null||a.setAttributes({pointIndices:this.pointIndices})}this.previousPointsTextureSize=i.pointsTextureSize,this.previousPointsNumber=this.data.pointsNumber}initPrograms(){const{device:t,store:i,data:n,points:r}=this;!n.pointsNumber||!r||!i.pointsTextureSize||(this.forceVertexCoordBuffer||(this.forceVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.calculateLevelsUniformStore||(this.calculateLevelsUniformStore=new oe(t,{calculateLevelsPreciseUniforms:{uniformTypes:{levelGridSize:"f32",cellSize:"f32"},defaultUniforms:{levelGridSize:0,cellSize:0}}})),this.calculateLevelsCommand||(this.calculateLevelsCommand=new ee(t,{fs:iv,vs:nv,topology:"point-list",vertexCount:n.pointsNumber,attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{calculateLevelsPreciseUniforms:this.calculateLevelsUniformStore.getManagedUniformBuffer("calculateLevelsPreciseUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.forceLevelUniformStore||(this.forceLevelUniformStore=new oe(t,{forceLevelPreciseUniforms:{uniformTypes:{levelGridSize:"f32",cellSize:"f32",isFirstLevel:"f32",alpha:"f32",repulsion:"f32"},defaultUniforms:{levelGridSize:0,cellSize:0,isFirstLevel:0,alpha:i.alpha,repulsion:this.config.simulationRepulsion}}})),this.forceLevelCommand||(this.forceLevelCommand=new ee(t,{fs:rv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceLevelPreciseUniforms:this.forceLevelUniformStore.getManagedUniformBuffer("forceLevelPreciseUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.buildNearFieldSlotsUniformStore||(this.buildNearFieldSlotsUniformStore=new oe(t,{buildNearFieldSlotsUniforms:{uniformTypes:{pointsTextureSize:"f32",levelGridSize:"f32",cellSize:"f32",hasPreviousSlot:"f32",randomSeed:"f32"},defaultUniforms:{pointsTextureSize:i.pointsTextureSize,levelGridSize:0,cellSize:0,hasPreviousSlot:0,randomSeed:0}}})),this.buildNearFieldSlotsCommand||(this.buildNearFieldSlotsCommand=new ee(t,{fs:lv,vs:av,topology:"point-list",vertexCount:n.pointsNumber,attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{buildNearFieldSlotsUniforms:this.buildNearFieldSlotsUniformStore.getManagedUniformBuffer("buildNearFieldSlotsUniforms")},parameters:{...te,blend:!1,depthWriteEnabled:!0,depthCompare:"less"}})),this.forceNearFieldUniformStore||(this.forceNearFieldUniformStore=new oe(t,{forceNearFieldUniforms:{uniformTypes:{pointsTextureSize:"f32",levelGridSize:"f32",cellSize:"f32",alpha:"f32",repulsion:"f32",slotCount:"f32"},defaultUniforms:{pointsTextureSize:i.pointsTextureSize,levelGridSize:0,cellSize:0,alpha:i.alpha,repulsion:this.config.simulationRepulsion,slotCount:0}}})),this.forceAllPairsUniformStore||(this.forceAllPairsUniformStore=new oe(t,{forceAllPairsUniforms:{uniformTypes:{pointsTextureSize:"f32",pointsNumber:"f32",alpha:"f32",repulsion:"f32",maxStep:"f32"},defaultUniforms:{pointsTextureSize:i.pointsTextureSize,pointsNumber:n.pointsNumber,alpha:i.alpha,repulsion:this.config.simulationRepulsion,maxStep:0}}})),this.forceAllPairsCommand||(this.forceAllPairsCommand=new ee(t,{fs:ov,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceAllPairsUniforms:this.forceAllPairsUniformStore.getManagedUniformBuffer("forceAllPairsUniforms")},parameters:te})),this.forceNearFieldCommand||(this.forceNearFieldCommand=new ee(t,{fs:sv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.forceVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceNearFieldUniforms:this.forceNearFieldUniformStore.getManagedUniformBuffer("forceNearFieldUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})))}run(){if(!(this.store.pointsTextureSize!==this.previousPointsTextureSize||this.data.pointsNumber!==this.previousPointsNumber)){if(this.usesAllPairs){this.drawAllPairsForce();return}this.levelTargets.size===0||this.peelTargets.length!==pi||!this.slotsArrayTexture||(this.drawLevels(),this.drawNearFieldSlots(),this.drawForces())}}destroy(){var t,i,n,r,s,o,a,l,c,u;(t=this.calculateLevelsCommand)==null||t.destroy(),this.calculateLevelsCommand=void 0,(i=this.forceLevelCommand)==null||i.destroy(),this.forceLevelCommand=void 0,(n=this.buildNearFieldSlotsCommand)==null||n.destroy(),this.buildNearFieldSlotsCommand=void 0,(r=this.forceNearFieldCommand)==null||r.destroy(),this.forceNearFieldCommand=void 0,(s=this.forceAllPairsCommand)==null||s.destroy(),this.forceAllPairsCommand=void 0,this.randomValuesTexture&&!this.randomValuesTexture.destroyed&&this.randomValuesTexture.destroy(),this.randomValuesTexture=void 0,this.destroyLevelTargets(),(o=this.calculateLevelsUniformStore)==null||o.destroy(),this.calculateLevelsUniformStore=void 0,(a=this.forceLevelUniformStore)==null||a.destroy(),this.forceLevelUniformStore=void 0,(l=this.buildNearFieldSlotsUniformStore)==null||l.destroy(),this.buildNearFieldSlotsUniformStore=void 0,(c=this.forceNearFieldUniformStore)==null||c.destroy(),this.forceNearFieldUniformStore=void 0,(u=this.forceAllPairsUniformStore)==null||u.destroy(),this.forceAllPairsUniformStore=void 0,this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=void 0,this.forceVertexCoordBuffer&&!this.forceVertexCoordBuffer.destroyed&&this.forceVertexCoordBuffer.destroy(),this.forceVertexCoordBuffer=void 0}drawAllPairsForce(){const{device:t,store:i,data:n,points:r}=this;if(!r||!this.forceAllPairsCommand||!this.forceAllPairsUniformStore||!r.previousPositionTexture||r.previousPositionTexture.destroyed||!r.exitTexture||r.exitTexture.destroyed||!this.randomValuesTexture||this.randomValuesTexture.destroyed||!r.velocityFbo||r.velocityFbo.destroyed||!n.pointsNumber)return;this.forceAllPairsUniformStore.setUniforms({forceAllPairsUniforms:{pointsTextureSize:i.pointsTextureSize??0,pointsNumber:n.pointsNumber,alpha:i.alpha,repulsion:this.config.simulationRepulsion,maxStep:2*(i.adjustedSpaceSize/vd(n.pointsNumber))}}),this.forceAllPairsCommand.setBindings({positionsTexture:r.previousPositionTexture,randomValues:this.randomValuesTexture,exitTexture:r.exitTexture});const s=t.beginRenderPass({framebuffer:r.velocityFbo,clearColor:[0,0,0,0]});this.forceAllPairsCommand.draw(s),s.end()}drawLevels(){const{device:t,store:i,data:n,points:r}=this;if(r&&!(!this.calculateLevelsCommand||!this.calculateLevelsUniformStore)&&!(!r.previousPositionTexture||r.previousPositionTexture.destroyed)&&!(!r.exitTexture||r.exitTexture.destroyed)&&n.pointsNumber&&this.pointIndices)for(let s=0;s<this.levels;s+=1){const o=this.levelTargets.get(s);if(!o||o.fbo.destroyed||o.texture.destroyed)continue;this.calculateLevelsUniformStore.setUniforms({calculateLevelsPreciseUniforms:{levelGridSize:o.gridSize,cellSize:i.adjustedSpaceSize/o.gridSize}}),this.calculateLevelsCommand.setVertexCount(n.pointsNumber),this.calculateLevelsCommand.setBindings({positionsTexture:r.previousPositionTexture,exitTexture:r.exitTexture});const a=t.beginRenderPass({framebuffer:o.fbo,clearColor:[0,0,0,0]});this.calculateLevelsCommand.draw(a),a.end()}}drawNearFieldSlots(){const{device:t,store:i,data:n,points:r}=this;if(!r||!this.buildNearFieldSlotsCommand||!this.buildNearFieldSlotsUniformStore||!r.previousPositionTexture||r.previousPositionTexture.destroyed||!r.exitTexture||r.exitTexture.destroyed||!n.pointsNumber||!this.pointIndices||!this.slotsArrayTexture||this.slotsArrayTexture.destroyed)return;const s=this.levelTargets.get(this.levels-1);if(!s||s.texture.destroyed)return;const o=i.getRandomFloat(0,1);for(let a=0;a<this.nearFieldSlots;a+=1){const l=this.peelTargets[a%pi],c=this.peelTargets[(a+1)%pi];if(!l||l.fbo.destroyed||!c||c.texture.destroyed)continue;this.buildNearFieldSlotsUniformStore.setUniforms({buildNearFieldSlotsUniforms:{pointsTextureSize:i.pointsTextureSize??0,levelGridSize:s.gridSize,cellSize:i.adjustedSpaceSize/s.gridSize,hasPreviousSlot:a===0?0:1,randomSeed:o}}),this.buildNearFieldSlotsCommand.setVertexCount(n.pointsNumber),this.buildNearFieldSlotsCommand.setBindings({positionsTexture:r.previousPositionTexture,exitTexture:r.exitTexture,previousSlot:a===0?r.previousPositionTexture:c.texture});const u=t.beginRenderPass({framebuffer:l.fbo,clearColor:[-1,1,0,0],clearDepth:1});this.buildNearFieldSlotsCommand.draw(u),u.end();const d=t.createCommandEncoder();d.copyTextureToTexture({sourceTexture:l.texture,destinationTexture:this.slotsArrayTexture,destinationOrigin:[0,0,a],width:s.gridSize,height:s.gridSize}),t.submit(d.finish())}}drawForces(){const{device:t,store:i,points:n}=this;if(!n||!this.forceLevelCommand||!this.forceLevelUniformStore||!this.forceNearFieldCommand||!this.forceNearFieldUniformStore||this.peelTargets.length!==pi||!this.slotsArrayTexture||this.slotsArrayTexture.destroyed||!n.previousPositionTexture||n.previousPositionTexture.destroyed||!this.randomValuesTexture||this.randomValuesTexture.destroyed||!n.velocityFbo||n.velocityFbo.destroyed)return;const r=t.beginRenderPass({framebuffer:n.velocityFbo,clearColor:[0,0,0,0]});for(let s=0;s<this.levels;s+=1){const o=this.levelTargets.get(s);if(!o||o.texture.destroyed)continue;const a=i.adjustedSpaceSize/o.gridSize;this.forceLevelUniformStore.setUniforms({forceLevelPreciseUniforms:{levelGridSize:o.gridSize,cellSize:a,isFirstLevel:s===0?1:0,alpha:i.alpha,repulsion:this.config.simulationRepulsion}}),this.forceLevelCommand.setBindings({positionsTexture:n.previousPositionTexture,levelTexture:o.texture}),this.forceLevelCommand.draw(r),s===this.levels-1&&(this.forceNearFieldUniformStore.setUniforms({forceNearFieldUniforms:{pointsTextureSize:i.pointsTextureSize??0,levelGridSize:o.gridSize,cellSize:a,alpha:i.alpha,repulsion:this.config.simulationRepulsion,slotCount:this.nearFieldSlots}}),this.forceNearFieldCommand.setBindings({positionsTexture:n.previousPositionTexture,levelTexture:o.texture,randomValues:this.randomValuesTexture,slotsTexture:this.slotsArrayTexture}),this.forceNearFieldCommand.draw(r))}r.end()}createLevels(){const{device:t}=this,i=this.data.pointsNumber??0,n=vd(i);this.levels=Math.log2(n)-1;for(let s=0;s<this.levels;s+=1){if(this.levelTargets.has(s))continue;const o=Math.pow(2,s+2),a=t.createTexture({width:o,height:o,format:"rgba32float",usage:M.SAMPLE|M.RENDER}),l=t.createFramebuffer({width:o,height:o,colorAttachments:[a]});this.levelTargets.set(s,{texture:a,fbo:l,gridSize:o})}for(const[s,o]of Array.from(this.levelTargets.entries()))s>=this.levels&&(o.fbo.destroyed||o.fbo.destroy(),o.texture.destroyed||o.texture.destroy(),this.levelTargets.delete(s));const r=this.levelTargets.get(this.levels-1);r&&this.createNearFieldSlotTargets(r)}createNearFieldSlotTargets(t){const{device:i}=this,n=uv(this.data.pointsNumber??0),r=this.peelTargets[0];if(!(r&&!r.texture.destroyed&&r.texture.width===t.gridSize&&r.texture.height===t.gridSize&&this.peelTargets.length===pi&&this.slotsArrayTexture&&!this.slotsArrayTexture.destroyed&&this.nearFieldSlots===n)){this.destroyNearFieldSlotTargets(),this.nearFieldSlots=n;for(let s=0;s<pi;s+=1){const o=i.createTexture({width:t.gridSize,height:t.gridSize,format:"rg32float",usage:M.SAMPLE|M.RENDER|M.COPY_SRC}),a=i.createFramebuffer({width:t.gridSize,height:t.gridSize,colorAttachments:[o],depthStencilAttachment:"depth24plus"});this.peelTargets.push({texture:o,fbo:a})}this.slotsArrayTexture=i.createTexture({dimension:"2d-array",width:t.gridSize,height:t.gridSize,depth:n,format:"rg32float",usage:M.SAMPLE|M.COPY_DST})}}destroyNearFieldSlotTargets(){for(const t of this.peelTargets)t.fbo.destroyed||t.fbo.destroy(),t.texture.destroyed||t.texture.destroy();this.peelTargets=[],this.slotsArrayTexture&&!this.slotsArrayTexture.destroyed&&this.slotsArrayTexture.destroy(),this.slotsArrayTexture=void 0,this.nearFieldSlots=0}destroyLevelTargets(){for(const t of this.levelTargets.values())t.fbo.destroyed||t.fbo.destroy(),t.texture.destroyed||t.texture.destroy();this.levelTargets.clear(),this.destroyNearFieldSlotTargets()}}const fv=`#version 300 es +precision highp float; + +uniform sampler2D positionsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform forceMouseUniforms { + float repulsion; + vec2 mousePos; +} forceMouse; + +#define repulsion forceMouse.repulsion +#define mousePos forceMouse.mousePos +#else +uniform float repulsion; +uniform vec2 mousePos; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + vec2 mouse = mousePos; + // Move particles away from the mouse position using a repulsive force + vec2 distVector = mouse - pointPosition.rg; + float dist = sqrt(dot(distVector, distVector)); + dist = max(dist, 10.0); + float angle = atan(distVector.y, distVector.x); + float addV = 100.0 * repulsion / (dist * dist); + velocity.rg -= addV * vec2(cos(angle), sin(angle)); + + fragColor = velocity; +}`;class pv extends gt{initPrograms(){const{device:t,points:i}=this;i&&(this.vertexCoordBuffer||(this.vertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.uniformStore||(this.uniformStore=new oe(t,{forceMouseUniforms:{uniformTypes:{repulsion:"f32",mousePos:"vec2<f32>"}}})),this.runCommand||(this.runCommand=new ee(t,{fs:fv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.vertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{forceMouseUniforms:this.uniformStore.getManagedUniformBuffer("forceMouseUniforms")},parameters:te})))}run(){const{device:t,points:i,store:n}=this;if(!i||!this.runCommand||!this.uniformStore||!i.previousPositionTexture||i.previousPositionTexture.destroyed||!i.velocityFbo||i.velocityFbo.destroyed)return;this.uniformStore.setUniforms({forceMouseUniforms:{repulsion:this.config.simulationRepulsionFromMouse,mousePos:ie(n.mousePosition,[0,0])}}),this.runCommand.setBindings({positionsTexture:i.previousPositionTexture});const r=t.beginRenderPass({framebuffer:i.velocityFbo,clearColor:[0,0,0,0]});this.runCommand.draw(r),r.end()}destroy(){var t,i;(t=this.runCommand)==null||t.destroy(),this.runCommand=void 0,(i=this.uniformStore)==null||i.destroy(),this.uniformStore=void 0,this.vertexCoordBuffer&&!this.vertexCoordBuffer.destroyed&&this.vertexCoordBuffer.destroy(),this.vertexCoordBuffer=void 0}}const gv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + fragColor = rgba; +}`,mv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D clusterTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform calculateCentermassUniforms { + float clustersTextureSize; +} calculateCentermass; + +#define clustersTextureSize calculateCentermass.clustersTextureSize +#else +uniform float clustersTextureSize; +#endif + +in vec2 pointIndices; + +out vec4 rgba; + +void main() { + rgba = vec4(0.0); + + ivec2 pointTexel = ivec2(pointIndices); + + // Absent points must not contribute to their cluster's centroid. (exit.G = absent) + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Unclustered points ([-1, -1]) must not contribute mass to any cluster — + // a default position of (0, 0) is the framebuffer's center texel, a real + // cluster's slot, so cull them off-screen instead. + vec4 pointClusterIndices = texelFetch(clusterTexture, pointTexel, 0); + if (pointClusterIndices.x < 0.0 || pointClusterIndices.y < 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + rgba = vec4(pointPosition.xy, 1.0, 0.0); + + vec2 xy = 2.0 * (pointClusterIndices.xy + 0.5) / clustersTextureSize - 1.0; + gl_Position = vec4(xy, 0.0, 1.0); + gl_PointSize = 1.0; +} +`,xv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D centermassTexture; +uniform sampler2D clusterTexture; +uniform sampler2D clusterPositionsTexture; +uniform sampler2D clusterForceCoefficient; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform applyForcesUniforms { + float alpha; + float clusterCoefficient; +} applyForces; + +#define alpha applyForces.alpha +#define clusterCoefficient applyForces.clusterCoefficient +#else +uniform float alpha; +uniform float clusterCoefficient; +#endif + +out vec4 fragColor; + + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 velocity = vec4(0.0); + vec4 pointClusterIndices = texelFetch(clusterTexture, pointTexel, 0); + // no cluster, so no forces + if (pointClusterIndices.x >= 0.0 && pointClusterIndices.y >= 0.0) { + // clusterTexture stores whole texel coordinates, so truncating to int is exact. + ivec2 clusterTexel = ivec2(pointClusterIndices.xy); + // positioning points to custom cluster position or either to the center of mass + vec2 clusterPositions = texelFetch(clusterPositionsTexture, clusterTexel, 0).xy; + if (clusterPositions.x < 0.0 || clusterPositions.y < 0.0) { + vec4 centermassValues = texelFetch(centermassTexture, clusterTexel, 0); + clusterPositions = centermassValues.xy / centermassValues.b; + } + vec4 clusterCustomCoeff = texelFetch(clusterForceCoefficient, pointTexel, 0); + vec2 distVector = clusterPositions.xy - pointPosition.xy; + float dist = length(distVector); + if (dist > 0.0) { + float addV = alpha * dist * clusterCoefficient * clusterCustomCoeff.r; + velocity.rg += addV * normalize(distVector); + } + } + + fragColor = velocity; +}`;class Sv extends gt{constructor(){super(...arguments),this.cachedCentroidPositions=null,this.isCentroidReadbackWanted=!1}get hasPendingCentroidReadback(){var t;return((t=this.centroidReadback)==null?void 0:t.inFlight)??!1}get needsCentroidReadback(){var t;return this.isCentroidReadbackWanted&&((t=this.points)==null?void 0:t.areClusterCentroidsUpToDate)===!1}create(){var d,h,p;this.cachedCentroidPositions=null,(d=this.centroidReadback)==null||d.destroy(),this.centroidReadback=void 0;const{device:t,store:i,data:n}=this,{pointsTextureSize:r}=i;if(n.pointsNumber===void 0||!n.pointClusters&&!n.clusterPositions)return;this.clusterCount=(n.pointClusters??[]).reduce((g,x)=>x===void 0||x<0?g:Math.max(g,x),0)+1,this.clustersTextureSize=Math.ceil(Math.sqrt(this.clusterCount));const s=this.previousPointsTextureSize!==r||this.previousClustersTextureSize!==this.clustersTextureSize||this.previousClusterCount!==this.clusterCount,o=r*r*4,a=this.clustersTextureSize*this.clustersTextureSize*4,l=new Float32Array(o),c=new Float32Array(a).fill(-1),u=new Float32Array(o).fill(1);if(n.clusterPositions)for(let g=0;g<this.clusterCount;++g)c[g*4+0]=n.clusterPositions[g*2+0]??-1,c[g*4+1]=n.clusterPositions[g*2+1]??-1;for(let g=0;g<n.pointsNumber;++g){const x=(h=n.pointClusters)==null?void 0:h[g];x===void 0?(l[g*4+0]=-1,l[g*4+1]=-1):(l[g*4+0]=x%this.clustersTextureSize,l[g*4+1]=Math.floor(x/this.clustersTextureSize)),n.clusterStrength&&(u[g*4+0]=n.clusterStrength[g]??1)}if(!this.clusterTexture||s?(this.clusterTexture&&!this.clusterTexture.destroyed&&this.clusterTexture.destroy(),this.clusterTexture=t.createTexture({width:r,height:r,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.clusterTexture.copyImageData({data:l,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0})):this.clusterTexture.copyImageData({data:l,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),!this.clusterPositionsTexture||s?(this.clusterPositionsTexture&&!this.clusterPositionsTexture.destroyed&&this.clusterPositionsTexture.destroy(),this.clusterPositionsTexture=t.createTexture({width:this.clustersTextureSize,height:this.clustersTextureSize,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.clusterPositionsTexture.copyImageData({data:c,bytesPerRow:q("rgba32float",this.clustersTextureSize),mipLevel:0,x:0,y:0})):this.clusterPositionsTexture.copyImageData({data:c,bytesPerRow:q("rgba32float",this.clustersTextureSize),mipLevel:0,x:0,y:0}),!this.clusterForceCoefficientTexture||s?(this.clusterForceCoefficientTexture&&!this.clusterForceCoefficientTexture.destroyed&&this.clusterForceCoefficientTexture.destroy(),this.clusterForceCoefficientTexture=t.createTexture({width:r,height:r,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.clusterForceCoefficientTexture.copyImageData({data:u,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0})):this.clusterForceCoefficientTexture.copyImageData({data:u,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0}),!this.centermassTexture||this.previousClustersTextureSize!==this.clustersTextureSize?(this.centermassFbo&&!this.centermassFbo.destroyed&&this.centermassFbo.destroy(),this.centermassTexture&&!this.centermassTexture.destroyed&&this.centermassTexture.destroy(),this.centermassTexture=t.createTexture({width:this.clustersTextureSize,height:this.clustersTextureSize,format:"rgba32float",usage:M.SAMPLE|M.RENDER|M.COPY_DST}),this.centermassTexture.copyImageData({data:new Float32Array(a).fill(0),bytesPerRow:q("rgba32float",this.clustersTextureSize),mipLevel:0,x:0,y:0}),this.centermassFbo=t.createFramebuffer({width:this.clustersTextureSize,height:this.clustersTextureSize,colorAttachments:[this.centermassTexture]})):this.centermassTexture.copyImageData({data:new Float32Array(a).fill(0),bytesPerRow:q("rgba32float",this.clustersTextureSize),mipLevel:0,x:0,y:0}),!this.pointIndices||this.previousPointsTextureSize!==r){this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy();const g=ji(i.pointsTextureSize);this.pointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST}),(p=this.calculateCentermassCommand)==null||p.setAttributes({pointIndices:this.pointIndices})}this.previousPointsTextureSize=r,this.previousClustersTextureSize=this.clustersTextureSize,this.previousClusterCount=this.clusterCount}initPrograms(){const{device:t,store:i,data:n}=this;n.pointsNumber===void 0||!n.pointClusters&&!n.clusterPositions||(this.calculateCentermassUniformStore||(this.calculateCentermassUniformStore=new oe(t,{calculateCentermassUniforms:{uniformTypes:{clustersTextureSize:"f32"},defaultUniforms:{clustersTextureSize:this.clustersTextureSize??0}}})),this.calculateCentermassCommand||(this.calculateCentermassCommand=new ee(t,{fs:gv,vs:mv,topology:"point-list",vertexCount:n.pointsNumber??0,attributes:{...this.pointIndices&&{pointIndices:this.pointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{calculateCentermassUniforms:this.calculateCentermassUniformStore.getManagedUniformBuffer("calculateCentermassUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",depthWriteEnabled:!1,depthCompare:"always"}})),this.applyForcesUniformStore||(this.applyForcesUniformStore=new oe(t,{applyForcesUniforms:{uniformTypes:{alpha:"f32",clusterCoefficient:"f32"},defaultUniforms:{alpha:i.alpha,clusterCoefficient:this.config.simulationCluster}}})),this.applyForcesVertexCoordBuffer||(this.applyForcesVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.applyForcesCommand||(this.applyForcesCommand=new ee(t,{fs:xv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.applyForcesVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{applyForcesUniforms:this.applyForcesUniformStore.getManagedUniformBuffer("applyForcesUniforms")},parameters:te})))}calculateCentermass(t){const{device:i,points:n}=this;if(!n||!this.calculateCentermassCommand||!this.calculateCentermassUniformStore||!this.pointIndices||!this.centermassFbo||this.centermassFbo.destroyed||!this.clusterTexture||this.clusterTexture.destroyed||!t||t.destroyed||!n.exitTexture||n.exitTexture.destroyed)return!1;this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber??0),this.calculateCentermassUniformStore.setUniforms({calculateCentermassUniforms:{clustersTextureSize:this.clustersTextureSize??0}}),this.calculateCentermassCommand.setBindings({clusterTexture:this.clusterTexture,positionsTexture:t,exitTexture:n.exitTexture});const r=i.beginRenderPass({framebuffer:this.centermassFbo,clearColor:[0,0,0,0]});return this.calculateCentermassCommand.draw(r),r.end(),!0}getCentroidPositions(t=!1){var n,r,s;if((n=this.points)!=null&&n.areClusterCentroidsUpToDate&&this.cachedCentroidPositions&&!this.hasPendingCentroidReadback)return this.cachedCentroidPositions;if(t&&this.cachedCentroidPositions)return this.isCentroidReadbackWanted=!0,this.cachedCentroidPositions;if(this.isCentroidReadbackWanted=!1,(r=this.centroidReadback)==null||r.cancel(),this.calculateCentermass((s=this.points)==null?void 0:s.currentPositionTexture),!this.centermassFbo||this.centermassFbo.destroyed||this.clusterCount===void 0)return[];const i=this.cacheCentroidPositions(we(this.device,this.centermassFbo));return this.points&&(this.points.areClusterCentroidsUpToDate=!0),i}requestCentroidReadback(){var s,o,a;if(!this.isCentroidReadbackWanted||((s=this.points)==null?void 0:s.areClusterCentroidsUpToDate)!==!1||(o=this.centroidReadback)!=null&&o.inFlight||!this.centermassFbo||this.centermassFbo.destroyed||this.clusterCount===void 0)return;const t=this.device.gl,i=this.centermassFbo.handle;if(!t||!i||!this.calculateCentermass((a=this.points)==null?void 0:a.currentPositionTexture))return;const{width:n,height:r}=this.centermassFbo;this.centroidReadback||(this.centroidReadback=new dr(t,n*r*4)),this.centroidReadback.issue(i,0,0,n,r)&&(this.isCentroidReadbackWanted=!1,this.points&&(this.points.areClusterCentroidsUpToDate=!0))}resolveCentroidReadback(){var i;if(!((i=this.centroidReadback)!=null&&i.inFlight))return;const t=this.centroidReadback.poll();t?this.cacheCentroidPositions(t):!this.centroidReadback.inFlight&&this.points&&(this.points.areClusterCentroidsUpToDate=!1)}run(){var i,n;if(!this.data.pointClusters&&!this.data.clusterPositions||(this.calculateCentermass((i=this.points)==null?void 0:i.previousPositionTexture),!this.applyForcesCommand||!this.applyForcesUniformStore)||!this.clusterTexture||this.clusterTexture.destroyed||!this.centermassTexture||this.centermassTexture.destroyed||!this.clusterPositionsTexture||this.clusterPositionsTexture.destroyed||!this.clusterForceCoefficientTexture||this.clusterForceCoefficientTexture.destroyed||!((n=this.points)!=null&&n.previousPositionTexture)||this.points.previousPositionTexture.destroyed||!this.points.velocityFbo||this.points.velocityFbo.destroyed)return;this.applyForcesUniformStore.setUniforms({applyForcesUniforms:{alpha:this.store.alpha,clusterCoefficient:this.config.simulationCluster}}),this.applyForcesCommand.setBindings({clusterTexture:this.clusterTexture,centermassTexture:this.centermassTexture,clusterPositionsTexture:this.clusterPositionsTexture,clusterForceCoefficient:this.clusterForceCoefficientTexture,positionsTexture:this.points.previousPositionTexture});const t=this.device.beginRenderPass({framebuffer:this.points.velocityFbo,clearColor:[0,0,0,0]});this.applyForcesCommand.draw(t),t.end()}destroy(){var t,i,n,r,s;this.cachedCentroidPositions=null,(t=this.centroidReadback)==null||t.destroy(),this.centroidReadback=void 0,(i=this.calculateCentermassCommand)==null||i.destroy(),this.calculateCentermassCommand=void 0,(n=this.applyForcesCommand)==null||n.destroy(),this.applyForcesCommand=void 0,this.centermassFbo&&!this.centermassFbo.destroyed&&this.centermassFbo.destroy(),this.centermassFbo=void 0,this.clusterTexture&&!this.clusterTexture.destroyed&&this.clusterTexture.destroy(),this.clusterTexture=void 0,this.clusterPositionsTexture&&!this.clusterPositionsTexture.destroyed&&this.clusterPositionsTexture.destroy(),this.clusterPositionsTexture=void 0,this.clusterForceCoefficientTexture&&!this.clusterForceCoefficientTexture.destroyed&&this.clusterForceCoefficientTexture.destroy(),this.clusterForceCoefficientTexture=void 0,this.centermassTexture&&!this.centermassTexture.destroyed&&this.centermassTexture.destroy(),this.centermassTexture=void 0,(r=this.calculateCentermassUniformStore)==null||r.destroy(),this.calculateCentermassUniformStore=void 0,(s=this.applyForcesUniformStore)==null||s.destroy(),this.applyForcesUniformStore=void 0,this.pointIndices&&!this.pointIndices.destroyed&&this.pointIndices.destroy(),this.pointIndices=void 0,this.applyForcesVertexCoordBuffer&&!this.applyForcesVertexCoordBuffer.destroyed&&this.applyForcesVertexCoordBuffer.destroy(),this.applyForcesVertexCoordBuffer=void 0}cacheCentroidPositions(t){const i=[];i.length=(this.clusterCount??0)*2;for(let n=0;n<i.length/2;n+=1){const r=t[n*4+0],s=t[n*4+1],o=t[n*4+2];r!==void 0&&s!==void 0&&o!==void 0&&(i[n*2]=r/o,i[n*2+1]=s/o)}return this.cachedCentroidPositions=i,i}}const Ko=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D imageAtlasTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawFragmentUniforms { + float greyoutOpacity; + float pointOpacity; + float isDarkenGreyout; + vec4 backgroundColor; + vec4 outlineColor; + float outlineWidth; + float renderMode; + float pickingAlpha; + float pickingIndexOffset; +} drawFragment; + +#define greyoutOpacity drawFragment.greyoutOpacity +#define pointOpacity drawFragment.pointOpacity +#define isDarkenGreyout drawFragment.isDarkenGreyout +#define backgroundColor drawFragment.backgroundColor +#define outlineColor drawFragment.outlineColor +#define outlineWidth drawFragment.outlineWidth +#define renderMode drawFragment.renderMode +#define pickingAlpha drawFragment.pickingAlpha +#define pickingIndexOffset drawFragment.pickingIndexOffset +#else +uniform float greyoutOpacity; +uniform float pointOpacity; +uniform float isDarkenGreyout; +uniform vec4 backgroundColor; +uniform vec4 outlineColor; +uniform float outlineWidth; +uniform float renderMode; +uniform float pickingAlpha; +uniform float pickingIndexOffset; +#endif + + +in float pointShape; +in float isGreyedOut; +in float isOutlined; +in vec4 shapeColor; +in vec4 imageAtlasUV; +in float shapeSize; +in float imageSizeVarying; +in float overallSize; +flat in float vPointIndex; + +out vec4 fragColor; + +// Occlusion culling splits fragments between the opaque core pass (renderMode 1) +// and the blended fringe pass (renderMode 2) at this final-alpha threshold +const float OPAQUE_ALPHA_THRESHOLD = 0.999; + +// Shape constants +const float CIRCLE = 0.0; +const float SQUARE = 1.0; +const float TRIANGLE = 2.0; +const float DIAMOND = 3.0; +const float PENTAGON = 4.0; +const float HEXAGON = 5.0; +const float STAR = 6.0; +const float CROSS = 7.0; +const float NONE = 8.0; + +// Distance functions for different shapes +float circleDistance(vec2 p) { + return dot(p, p); +} + +// Function to apply greyout logic to image colors +vec4 applyGreyoutToImage(vec4 imageColor, float isGreyedOutValue) { + vec3 finalColor = imageColor.rgb; + float finalAlpha = imageColor.a; + + if (isGreyedOutValue > 0.0) { + float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color) + + if (isDarkenGreyout > 0.0) { + finalColor = mix(finalColor, vec3(0.2), blendFactor); + } else { + finalColor = mix(finalColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + + return vec4(finalColor, finalAlpha); +} + +float squareDistance(vec2 p) { + vec2 d = abs(p) - vec2(0.8); + return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); +} + +float triangleDistance(vec2 p) { + const float k = sqrt(3.0); // ≈1.732; slope of 60° lines for an equilateral triangle + const float r = 0.9; // half the edge length; each edge is 2r + p.x = abs(p.x) - r; // fold the X axis and shift: the base corner is at the origin + p.y += 0.55; // move the base (y = -0.55 in the core) to y = 0. The centred offset is + // r/k = 0.52; 0.55 keeps the apex at 1.01 rather than 1.04 + + // Reflect across the corner's bisector: the slanted edge maps onto the x axis, + // corner at x = 0, apex at x = -2r + if (p.x + k * p.y > 0.0) + p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0; + + // Distance to the edge as the segment [-2r, 0] on the x axis + p.x -= clamp(p.x, -2.0 * r, 0.0); + + // Return signed distance: negative = inside; positive = outside + return -length(p) * sign(p.y); +} + +float diamondDistance(vec2 p) { + // aspect > 1 → taller diamond + const float aspect = 1.2; + return abs(p.x) + abs(p.y) / aspect - 0.8; +} + +float pentagonDistance(vec2 p) { + // Regular pentagon signed-distance (Inigo Quilez) + const vec3 k = vec3(0.809016994, 0.587785252, 0.726542528); // cos 36°, sin 36°, tan 36° + const float r = 0.726542528; // apothem: the flat edge is at y = r; equal to k.z by + // coincidence of the chosen size, not by construction + p.x = abs(p.x); + + // Reflect across the two tilted edges ─ only if point is outside + p -= 2.0 * min(dot(vec2(-k.x, k.y), p), 0.0) * vec2(-k.x, k.y); + p -= 2.0 * min(dot(vec2( k.x, k.y), p), 0.0) * vec2( k.x, k.y); + + // distance to the flat edge as a segment: every corner folds onto x = ±r·tan 36° + p -= vec2(clamp(p.x, -r * k.z, r * k.z), r); + + // Return signed distance (negative → inside, positive → outside) + return length(p) * sign(p.y); +} + +float hexagonDistance(vec2 p) { + const vec3 k = vec3(-0.866025404, 0.5, 0.577350269); + p = abs(p); + p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy; + p -= vec2(clamp(p.x, -k.z * 0.8, k.z * 0.8), 0.8); + return length(p) * sign(p.y); +} + +float starDistance(vec2 p) { + // 5-point star signed-distance function (adapted from Inigo Quilez) + // r – outer radius, rf – inner/outer radius ratio + const float r = 0.9; + const float rf = 0.45; + + // Pre-computed rotation vectors for the star arms (36° increments) + const vec2 k1 = vec2(0.809016994, -0.587785252); + const vec2 k2 = vec2(-k1.x, k1.y); + + // Fold the plane into a single arm sector + p.x = abs(p.x); + p -= 2.0 * max(dot(k1, p), 0.0) * k1; + p -= 2.0 * max(dot(k2, p), 0.0) * k2; + p.x = abs(p.x); + + // Translate so the top tip of the star lies on the X-axis + p.y -= r; + + // Vector describing the edge between an outer tip and its adjacent inner point + vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0); + // Project the point onto that edge and clamp the projection to the segment + float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r); + + // Return signed distance (negative => inside, positive => outside) + return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y); +} + +float crossDistance(vec2 p) { + // Signed distance function for a cross (union of two rectangles) + // Adapted from Inigo Quilez (https://iquilezles.org/) + // Each arm has half-sizes 0.3 (thickness) and 0.8 (length) + p = abs(p); + if (p.y > p.x) p = p.yx; // exploit symmetry + + vec2 q = p - vec2(0.8, 0.3); // subtract half-sizes (length, thickness) + + // Standard rectangle SDF, then take union of the two arms + return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0); +} + +float getShapeDistance(vec2 p, float shape) { + if (shape == SQUARE) return squareDistance(p); + else if (shape == TRIANGLE) return triangleDistance(p); + else if (shape == DIAMOND) return diamondDistance(p); + else if (shape == PENTAGON) return pentagonDistance(p); + else if (shape == HEXAGON) return hexagonDistance(p); + else if (shape == STAR) return starDistance(p); + else if (shape == CROSS) return crossDistance(p); + else return circleDistance(p); // Default to circle +} + +void main() { + // Discard the fragment if the point is fully transparent and has no image + if (shapeColor.a == 0.0 && imageAtlasUV.x == -1.0) { + discard; + } + + // Discard the fragment if the point has no shape and no image + if (pointShape == NONE && imageAtlasUV.x == -1.0) { + discard; + } + + // Calculate coordinates within the point + vec2 pointCoord = 2.0 * gl_PointCoord - 1.0; + + // pointCoord covers the full sprite, which is larger than the shape when the point is + // outlined, carries a bigger image, or is under a pixel. Rescale it so the shape keeps + // its intended size. + vec2 shapeCoord = pointCoord; + float shapeDiameterPx = overallSize; + if (overallSize > shapeSize && shapeSize > 0.0) { + shapeCoord = pointCoord * (overallSize / shapeSize); + shapeDiameterPx = shapeSize; + } + + vec4 finalShapeColor = vec4(0.0); + vec4 finalImageColor = vec4(0.0); + // Geometric coverage, before color alpha: what the host picking pass decides on + float shapeCoverage = 0.0; + bool imageCovered = false; + + // Ramp of EDGE_RAMP_PX device pixels centred on the shape edge. The sprite is the shape's own + // size: the outer half of the ramp is clipped only where the shape touches the sprite's sides. + // A shape under one device pixel is drawn as a one-pixel core with alpha shape² / core², the + // ink of its true area; a size of 0 has no shape. + if (pointShape != NONE && shapeSize > 0.0) { + float coreDiameterPx = max(shapeDiameterPx, 1.0); + float smallAlpha = min(1.0, (shapeDiameterPx * shapeDiameterPx) / (coreDiameterPx * coreDiameterPx)); + vec2 coreCoord = shapeCoord * (shapeDiameterPx / coreDiameterPx); // -1..1 across the core + float halfRampPx = EDGE_RAMP_PX * 0.5; + + float opacity; + if (pointShape == CIRCLE) { + // Along the radius: a ramp in r² skews coverage outward on small discs. + float rPx = length(coreCoord) * coreDiameterPx * 0.5; + opacity = 1.0 - smoothstep(coreDiameterPx * 0.5 - halfRampPx, coreDiameterPx * 0.5 + halfRampPx, rPx); + } else { + float shapeDistance = getShapeDistance(coreCoord, pointShape); + // Half a ramp in field units, via the field's gradient per pixel: exact for a field that + // is linear across the ramp, as every polygon field is at its edge. All fragments of a + // sprite share pointShape, so the derivative is taken in coherent control flow. + float shapeHalfRamp = max(halfRampPx * length(vec2(dFdx(shapeDistance), dFdy(shapeDistance))), 1e-6); + opacity = 1.0 - smoothstep(-shapeHalfRamp, shapeHalfRamp, shapeDistance); + } + shapeCoverage = opacity; + opacity *= smallAlpha * shapeColor.a; + + finalShapeColor = vec4(shapeColor.rgb, opacity); + } + + // Handle image rendering with centering logic + if (imageAtlasUV.x != -1.0) { + // Calculate image coordinates with centering + vec2 imageCoord = pointCoord; + if (overallSize > imageSizeVarying && imageSizeVarying > 0.0) { + // Image is smaller than overall size, center it + float scale = imageSizeVarying / overallSize; + imageCoord = pointCoord / scale; + + // Check if we're outside the valid image area + if (abs(imageCoord.x) > 1.0 || abs(imageCoord.y) > 1.0) { + // We're outside the image bounds, don't render the image + finalImageColor = vec4(0.0); + } else { + // Sample from texture atlas + vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5); + vec4 imageColor = texture(imageAtlasTexture, atlasUV); + finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut); + imageCovered = true; + } + } else { + // Image is same size or larger than overall size, no scaling needed + // Sample from texture atlas + vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5); + vec4 imageColor = texture(imageAtlasTexture, atlasUV); + finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut); + imageCovered = true; + } + } + + // Host picking: a fragment counts where the shape covers at least half of it (and the + // point is not fully transparent) or an image does; it carries the index and the host's + // alpha, with no blending and no ramp — the hard edge is the picked outline + if (renderMode > 2.5) { + bool covered = (shapeCoverage >= 0.5 && shapeColor.a > 0.0) || imageCovered; + if (!covered) discard; + fragColor = vec4(encodePickingColor(vPointIndex + pickingIndexOffset), pickingAlpha); + return; + } + + float finalPointAlpha = max(finalShapeColor.a, finalImageColor.a); + if (isGreyedOut > 0.0 && greyoutOpacity != -1.0) { + finalPointAlpha *= greyoutOpacity; + } else { + finalPointAlpha *= pointOpacity; + } + + // Blend image color above point color + fragColor = vec4( + mix(finalShapeColor.rgb, finalImageColor.rgb, finalImageColor.a), + finalPointAlpha + ); + + // Outline ring: band [outlineWidth × R, R], R = POINT_RING_SCALE × point radius, device px. + // Core at least a ramp wide, centred on the band, ramp centred on both edges. A ring is an + // interface mark: thinner than the ramp it is widened at full alpha, not dimmed. + // + // inner R outer R + // ────────░░┤░░████████░░├░░──────── + // fade core fade + if (isOutlined > 0.0) { + // Sized from the drawn core (a shape under a pixel is drawn as one), inside the sprite, + // which the hardware cap can clamp: the ring then tightens onto the body. + float ringOuterPx = min(POINT_RING_SCALE * max(max(shapeSize, 1.0), imageSizeVarying), overallSize - EDGE_RAMP_PX) * 0.5; + float ringInnerPx = outlineWidth * ringOuterPx; + float ringCentrePx = (ringOuterPx + ringInnerPx) * 0.5; + float ringHalfCorePx = max(ringOuterPx - ringInnerPx, EDGE_RAMP_PX) * 0.5; + float rPx = length(pointCoord) * overallSize * 0.5; + float ringAlpha = 1.0 - smoothstep(-EDGE_RAMP_PX * 0.5, EDGE_RAMP_PX * 0.5, abs(rPx - ringCentrePx) - ringHalfCorePx); + + // Grey out the ring color when the point is greyed + vec3 ringColor = outlineColor.rgb; + if (isGreyedOut > 0.0) { + float blendFactor = 0.65; + if (isDarkenGreyout > 0.0) { + ringColor = mix(ringColor, vec3(0.2), blendFactor); + } else { + ringColor = mix(ringColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + + float ringOpacity = ringAlpha * outlineColor.a; + // Source-over of the ring onto the fragment. A plain mix would tint the ring with a + // transparent body's colour, and the blend would then apply the ring's alpha twice. + float outAlpha = ringOpacity + fragColor.a * (1.0 - ringOpacity); + vec3 outRgb = outAlpha > 0.0 + ? (ringColor * ringOpacity + fragColor.rgb * fragColor.a * (1.0 - ringOpacity)) / outAlpha + : fragColor.rgb; + fragColor = vec4(outRgb, outAlpha); + } + + // Occlusion culling: split every fragment between the opaque core pass + // (depth-writing, unblended) and the blended fringe pass. The same + // final-alpha rule runs in both passes so each fragment renders exactly once. + if (renderMode > 1.5) { + if (fragColor.a >= OPAQUE_ALPHA_THRESHOLD) discard; // already drawn by core pass + } else if (renderMode > 0.5) { + if (fragColor.a < OPAQUE_ALPHA_THRESHOLD) discard; // left for fringe pass + } +} +`,qo=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 pointIndices; +in float sourceSize; +in float targetSize; +in vec4 sourceColor; +in vec4 targetColor; +in float shape; +in float imageIndex; +in float imageSize; + +uniform sampler2D positionsTexture; +uniform sampler2D pointStatus; +uniform sampler2D exitTexture; +uniform sampler2D imageAtlasCoords; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawVertexUniforms { + float ratio; + mat4 transformationMatrix; + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + vec4 greyoutColor; + vec4 backgroundColor; + float scalePointsOnZoom; + float maxPointSize; + float isDarkenGreyout; + float skipHighlighted; + float skipGreyed; + float hasImages; + float imageCount; + float imageAtlasCoordsTextureSize; + float transitionProgress; + float animateColors; + float animateSizes; + float animatePositions; + vec4 pointDefaultColor; + float pointDefaultSize; + float pointsNumber; +} drawVertex; + +#define ratio drawVertex.ratio +#define transformationMatrix drawVertex.transformationMatrix +#define pointsTextureSize drawVertex.pointsTextureSize +#define sizeScale drawVertex.sizeScale +#define spaceSize drawVertex.spaceSize +#define screenSize drawVertex.screenSize +#define greyoutColor drawVertex.greyoutColor +#define backgroundColor drawVertex.backgroundColor +#define scalePointsOnZoom drawVertex.scalePointsOnZoom +#define maxPointSize drawVertex.maxPointSize +#define isDarkenGreyout drawVertex.isDarkenGreyout +#define skipHighlighted drawVertex.skipHighlighted +#define skipGreyed drawVertex.skipGreyed +#define hasImages drawVertex.hasImages +#define imageCount drawVertex.imageCount +#define imageAtlasCoordsTextureSize drawVertex.imageAtlasCoordsTextureSize +#define transitionProgress drawVertex.transitionProgress +#define animateColors drawVertex.animateColors +#define animateSizes drawVertex.animateSizes +#define animatePositions drawVertex.animatePositions +#define pointDefaultColor drawVertex.pointDefaultColor +#define pointDefaultSize drawVertex.pointDefaultSize +#define pointsNumber drawVertex.pointsNumber +#else +uniform float ratio; +uniform mat3 transformationMatrix; +uniform float pointsTextureSize; +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform vec4 greyoutColor; +uniform vec4 backgroundColor; +uniform float scalePointsOnZoom; +uniform float maxPointSize; +uniform float isDarkenGreyout; +uniform float skipHighlighted; +uniform float skipGreyed; +uniform float hasImages; +uniform float imageCount; +uniform float imageAtlasCoordsTextureSize; +uniform float transitionProgress; +uniform float animateColors; +uniform float animateSizes; +uniform float animatePositions; +uniform vec4 pointDefaultColor; +uniform float pointDefaultSize; +uniform float pointsNumber; +#endif + +out float pointShape; +out float isGreyedOut; +out float isOutlined; +out vec4 shapeColor; +out vec4 imageAtlasUV; +out float shapeSize; +out float imageSizeVarying; +out float overallSize; +// The point's index, for the host picking pass +flat out float vPointIndex; + +// The size rule is the shared pointSize module, so drawing, picking and selection agree on it. +float calculatePointSize(float size) { + return pointSizePx(size, ratio, transformationMatrix[0][0], scalePointsOnZoom, maxPointSize); +} + +// Read-time resolution of NaN channels — input arrays are used verbatim and never +// edited, so "use the default" stays encoded as NaN all the way to the GPU. A NaN +// resolves to the config default blended toward the exit default along the animated +// exit ramp (0 = present, 1 = gone), so the enter/exit fade of default-valued +// channels drives itself — no size/color transition needed for a removal. Explicit +// (real) values pass through. EXIT_DEFAULT_* are #defines injected from variables.ts, +// shared with the CPU resolvers (GraphData.getResolvedPoint*). The ramp and the size +// rule are the shared exitRamp module (exit-ramp.glsl), which the hover/focus ring +// draws by too; only the sprite resolves colors. +vec4 resolveColor(vec4 color, float exit) { + vec4 defaultColor = mix(pointDefaultColor, vec4(EXIT_DEFAULT_COLOR_CHANNEL), exit); + return mix(color, defaultColor, isnan(color)); +} + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Read point status texture: R = greyout, G = outlined + vec4 status = texelFetch(pointStatus, pointTexel, 0); + isGreyedOut = status.r; + isOutlined = status.g; + float isHighlighted = (status.r == 0.0) ? 1.0 : 0.0; + + // Discard point based on rendering mode + if (skipHighlighted > 0.0 && isHighlighted > 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + if (skipGreyed > 0.0 && isHighlighted <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Exit ramp (exit-ramp.glsl): 0 = present, 1 = gone. The caller drives the visual + // fade via setPointSizes/setPointColors; here we only remove the point once it is + // fully gone. + float exit = exitRamp(texelFetch(exitTexture, pointTexel, 0), animatePositions, transitionProgress); + if (exit >= 1.0) { + // Fully gone — skip. Also avoids using a NaN position on the snapped path. + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Position + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 point = pointPosition.rg; + + // Transform point position to normalized device coordinates + // Convert from space coordinates [0, spaceSize] to normalized [-1, 1] + vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0; + + // Apply aspect ratio correction - this is needed to map the square space to the rectangular screen + // The transformation matrix handles zoom/pan, but we need this to handle aspect ratio + normalizedPosition *= spaceSize / screenSize; + + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1); + #else + vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1); + #endif + // Depth encodes stacking order: higher point index = drawn on top = nearer + // (smaller z). Harmless when depth testing is off (depthCompare 'always'). + float linearIndex = pointIndices.y * pointsTextureSize + pointIndices.x; + vPointIndex = linearIndex; + float depthZ = 1.0 - 2.0 * (linearIndex + 0.5) / max(pointsNumber, 1.0); + gl_Position = vec4(finalPosition.rg, depthZ, 1.0); + + // Resolve NaN channels against the animated exit ramp before mixing — default + // sizes/colors of an entering or leaving point fade with the ramp regardless of + // whether a size/color transition is active. + float pointSize = transitionedSize(sourceSize, targetSize, animateSizes, transitionProgress, exit, pointDefaultSize); + vec4 pointColor = animateColors > 0.0 + ? mix(resolveColor(sourceColor, exit), resolveColor(targetColor, exit), transitionProgress) + : resolveColor(targetColor, exit); + + + // Calculate sizes for shape and image. A point without an image has no image + // size: the attribute still holds a value (a copy of the target point size when + // none was given), and letting it into the sprite footprint would hold the + // outline ring at the target while the shape is still transitioning. + bool hasImage = hasImages > 0.0 && imageIndex >= 0.0 && imageIndex < imageCount; + float shapeSizeValue = calculatePointSize(pointSize * sizeScale); + float imageSizeValue = hasImage ? calculatePointSize(imageSize * sizeScale) : 0.0; + + // A size of 0 draws nothing; the sprite below is never smaller than a pixel. + if (max(shapeSizeValue, imageSizeValue) <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + // Use the larger of the shape, image, and 1-pixel minimum. The sprite is the shape's own size: + // the ramp stays centred on the edge, and its outer half is clipped where the shape meets the + // sprite's sides. + float overallSizeValue = max(max(shapeSizeValue, 1.0), imageSizeValue); + + // Outlined: scale the drawn core (a shape is never under a pixel) to the ring size, then add + // ramp room on both sides. + if (isOutlined > 0.0) { + overallSizeValue = POINT_RING_SCALE * max(max(shapeSizeValue, 1.0), imageSizeValue) + 2.0 * EDGE_RAMP_PX; + } + // Clamp to the hardware limit; the fragment shader preserves the shape size. + overallSizeValue = min(overallSizeValue, maxPointSize * ratio); + + gl_PointSize = overallSizeValue; + + // Pass size information to fragment shader + shapeSize = shapeSizeValue; + imageSizeVarying = imageSizeValue; + overallSize = overallSizeValue; + + shapeColor = pointColor; + pointShape = shape; + + // Adjust color of greyed-out points + if (isGreyedOut > 0.0) { + if (greyoutColor[0] != -1.0) { + shapeColor = greyoutColor; + } else { + // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout + float blendFactor = 0.65; + + if (isDarkenGreyout > 0.0) { + shapeColor.rgb = mix(shapeColor.rgb, vec3(0.2), blendFactor); + } else { + shapeColor.rgb = mix(shapeColor.rgb, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + } + + if (!hasImage) { + imageAtlasUV = vec4(-1.0); + } else { + int atlasTexSize = int(imageAtlasCoordsTextureSize); + int atlasCoordIndex = int(imageIndex); + ivec2 atlasTexel = ivec2(atlasCoordIndex % atlasTexSize, atlasCoordIndex / atlasTexSize); + vec4 atlasCoords = texelFetch(imageAtlasCoords, atlasTexel, 0); + imageAtlasUV = atlasCoords; + } +} +`,yv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D pointSize; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform findPointsInRectUniforms { + float sizeScale; + float spaceSize; + vec2 screenSize; + float ratio; + mat4 transformationMatrix; + vec2 rect0; + vec2 rect1; + float scalePointsOnZoom; + float maxPointSize; +} findPointsInRect; + +#define sizeScale findPointsInRect.sizeScale +#define spaceSize findPointsInRect.spaceSize +#define screenSize findPointsInRect.screenSize +#define ratio findPointsInRect.ratio +#define transformationMatrix findPointsInRect.transformationMatrix +#define rect0 findPointsInRect.rect0 +#define rect1 findPointsInRect.rect1 +#define scalePointsOnZoom findPointsInRect.scalePointsOnZoom +#define maxPointSize findPointsInRect.maxPointSize +#else +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform float ratio; +uniform mat3 transformationMatrix; +uniform vec2 rect0; +uniform vec2 rect1; +uniform float scalePointsOnZoom; +uniform float maxPointSize; +#endif + +out vec4 fragColor; + +// The drawn size (draw-points.vert), so the selection footprint is the rendered point: a shape +// under a device pixel is drawn as one. In CSS px, the units of the rectangle and screenSize. +float pointSizeF(float size) { + return max(pointSizePx(size, ratio, transformationMatrix[0][0], scalePointsOnZoom, maxPointSize), 1.0) / ratio; +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + // Skip absent (faded-out) points — never select a removed point. exit.G = absent. + if (texelFetch(exitTexture, pointTexel, 0).g > 0.5) { + fragColor = vec4(0.0); + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + // Convert mat4 to mat3 for vec3 multiplication + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + vec4 pSize = texelFetch(pointSize, pointTexel, 0); + float size = pSize.r * sizeScale; + // A size of 0 draws nothing (draw-points.vert), so it is not selectable either. + if (size <= 0.0) { + fragColor = vec4(0.0); + return; + } + + float left = 2.0 * (rect0.x - 0.5 * pointSizeF(size)) / screenSize.x - 1.0; + float right = 2.0 * (rect1.x + 0.5 * pointSizeF(size)) / screenSize.x - 1.0; + float top = 2.0 * (rect0.y - 0.5 * pointSizeF(size)) / screenSize.y - 1.0; + float bottom = 2.0 * (rect1.y + 0.5 * pointSizeF(size)) / screenSize.y - 1.0; + + fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g); + if (final.x >= left && final.x <= right && final.y >= top && final.y <= bottom) { + fragColor.r = 1.0; + } +} + +`,_v=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D polygonPathTexture; // Texture containing polygon path points +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform findPointsInPolygonUniforms { + float spaceSize; + vec2 screenSize; + mat4 transformationMatrix; + float polygonPathLength; +} findPointsInPolygon; + +#define spaceSize findPointsInPolygon.spaceSize +#define screenSize findPointsInPolygon.screenSize +#define transformationMatrix findPointsInPolygon.transformationMatrix +#define polygonPathLength int(findPointsInPolygon.polygonPathLength) +#else +uniform int polygonPathLength; +uniform float spaceSize; +uniform vec2 screenSize; +uniform mat3 transformationMatrix; +#endif + +out vec4 fragColor; + +// Get a point from the polygon path texture at a specific index +vec2 getPolygonPoint(sampler2D pathTexture, int index, int pathLength) { + if (index >= pathLength) return vec2(0.0); + + // The path is written row-major into a square texture. Ask the texture how wide it + // is rather than re-deriving ceil(sqrt(pathLength)) — that duplicates the formula + // the allocation used, and a local named textureSize would shadow this builtin. + int width = textureSize(pathTexture, 0).x; + + vec4 pathData = texelFetch(pathTexture, ivec2(index % width, index / width), 0); + + return pathData.xy; +} + +// Point-in-polygon algorithm using ray casting +bool pointInPolygon(vec2 point, sampler2D pathTexture, int pathLength) { + bool inside = false; + + for (int i = 0; i < 2048; i++) { + if (i >= pathLength) break; + + int j = (i + 1) % pathLength; + + vec2 pi = getPolygonPoint(pathTexture, i, pathLength); + vec2 pj = getPolygonPoint(pathTexture, j, pathLength); + + if (((pi.y > point.y) != (pj.y > point.y)) && + (point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x)) { + inside = !inside; + } + } + + return inside; +} + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + // Skip absent (faded-out) points — never select a removed point. exit.G = absent. + if (texelFetch(exitTexture, pointTexel, 0).g > 0.5) { + fragColor = vec4(0.0); + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + // Convert mat4 to mat3 for vec3 multiplication + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + // Convert to screen coordinates for polygon check + vec2 screenPos = (final.xy + 1.0) * screenSize / 2.0; + + fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g); + + // Check if point center is inside the polygon + if (pointInPolygon(screenPos, polygonPathTexture, polygonPathLength)) { + fragColor.r = 1.0; + } +} `,bv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawHighlightedUniforms { + float sourceSize; + float targetSize; + float imageSize; + mat4 transformationMatrix; + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + float scalePointsOnZoom; + float pointIndex; + float maxPointSize; + vec4 color; + float universalPointOpacity; + float greyoutOpacity; + float isDarkenGreyout; + vec4 backgroundColor; + vec4 greyoutColor; + float animatePositions; + float transitionProgress; + float animateSizes; + float pointDefaultSize; + float width; + float pixelRatio; +} drawHighlighted; + +#define width drawHighlighted.width +#else +uniform float width; +uniform float pixelRatio; +#endif + +in vec2 vertexPosition; +in float pointOpacity; +in vec3 rgbColor; +flat in float ringRadiusPx; +flat in float quadHalfPx; + +out vec4 fragColor; + +// Ring band [sqrt(width) × R, R], R the outer radius in device px (\`width\` is the inner +// edge as a squared radius). Core at least EDGE_RAMP_PX wide, centred on the band, ramp +// centred on both edges. A ring is an interface mark: thinner than the ramp it is widened +// at full alpha, not dimmed. +void main () { + float rPx = length(vertexPosition) * quadHalfPx; + float innerPx = sqrt(width) * ringRadiusPx; + float centrePx = (ringRadiusPx + innerPx) * 0.5; + float halfCorePx = max(ringRadiusPx - innerPx, EDGE_RAMP_PX) * 0.5; + float ring = 1.0 - smoothstep(-EDGE_RAMP_PX * 0.5, EDGE_RAMP_PX * 0.5, abs(rPx - centrePx) - halfCorePx); + fragColor = vec4(rgbColor, ring * pointOpacity); +}`,Tv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 vertexCoord; + +uniform sampler2D positionsTexture; +uniform sampler2D pointStatus; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform drawHighlightedUniforms { + float sourceSize; + float targetSize; + float imageSize; + mat4 transformationMatrix; + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + float scalePointsOnZoom; + float pointIndex; + float maxPointSize; + vec4 color; + float universalPointOpacity; + float greyoutOpacity; + float isDarkenGreyout; + vec4 backgroundColor; + vec4 greyoutColor; + float animatePositions; + float transitionProgress; + float animateSizes; + float pointDefaultSize; + float width; + float pixelRatio; +} drawHighlighted; + +#define sourceSize drawHighlighted.sourceSize +#define targetSize drawHighlighted.targetSize +#define imageSize drawHighlighted.imageSize +#define pixelRatio drawHighlighted.pixelRatio +#define transformationMatrix drawHighlighted.transformationMatrix +#define pointsTextureSize drawHighlighted.pointsTextureSize +#define sizeScale drawHighlighted.sizeScale +#define spaceSize drawHighlighted.spaceSize +#define screenSize drawHighlighted.screenSize +#define scalePointsOnZoom drawHighlighted.scalePointsOnZoom +#define pointIndex drawHighlighted.pointIndex +#define maxPointSize drawHighlighted.maxPointSize +#define color drawHighlighted.color +#define universalPointOpacity drawHighlighted.universalPointOpacity +#define greyoutOpacity drawHighlighted.greyoutOpacity +#define isDarkenGreyout drawHighlighted.isDarkenGreyout +#define backgroundColor drawHighlighted.backgroundColor +#define greyoutColor drawHighlighted.greyoutColor +#define animatePositions drawHighlighted.animatePositions +#define transitionProgress drawHighlighted.transitionProgress +#define animateSizes drawHighlighted.animateSizes +#define pointDefaultSize drawHighlighted.pointDefaultSize +#else +uniform float sourceSize; +uniform float targetSize; +uniform float imageSize; +uniform mat3 transformationMatrix; +uniform float pointsTextureSize; +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform float scalePointsOnZoom; +uniform float pointIndex; +uniform float maxPointSize; +uniform vec4 color; +uniform float universalPointOpacity; +uniform float greyoutOpacity; +uniform float isDarkenGreyout; +uniform vec4 backgroundColor; +uniform vec4 greyoutColor; +uniform float animatePositions; +uniform float transitionProgress; +uniform float animateSizes; +uniform float pointDefaultSize; +uniform float width; +uniform float pixelRatio; +#endif +out vec2 vertexPosition; +out float pointOpacity; +out vec3 rgbColor; +// Ring outer radius and quad half-size, device px: the ring plus a full ramp per side. +flat out float ringRadiusPx; +flat out float quadHalfPx; + +// The drawn size (draw-points.vert), so the ring follows it. The sizes are uniforms here. +float calculatePointSize(float pointSize) { + return pointSizePx(pointSize, pixelRatio, transformationMatrix[0][0], scalePointsOnZoom, maxPointSize); +} + +void main () { + vertexPosition = vertexCoord; + + int pointTexSize = int(pointsTextureSize); + int pointLinearIndex = int(pointIndex); + // Integer % and / are undefined on a negative or zero operand, and pointIndex + // defaults to -1 (no point highlighted). Nothing to draw in that case anyway. + if (pointLinearIndex < 0 || pointTexSize <= 0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + ivec2 pointTexel = ivec2(pointLinearIndex % pointTexSize, pointLinearIndex / pointTexSize); + + // Exit ramp (exit-ramp.glsl), the sprite's: drop the ring only once the point is fully + // gone, so it stays on the body while that fades out or in. + float exit = exitRamp(texelFetch(exitTexture, pointTexel, 0), animatePositions, transitionProgress); + if (exit >= 1.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + + rgbColor = color.rgb; + pointOpacity = color.a * universalPointOpacity; + vec4 greyoutStatus = texelFetch(pointStatus, pointTexel, 0); + if (greyoutStatus.r > 0.0) { + if (greyoutColor[0] != -1.0) { + rgbColor = greyoutColor.rgb; + pointOpacity = greyoutColor.a; + } else { + // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout + float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color) + + if (isDarkenGreyout > 0.0) { + // Darken the color + rgbColor = mix(rgbColor, vec3(0.2), blendFactor); + } else { + // Lighten the color + rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor); + } + } + + if (greyoutOpacity != -1.0) { + pointOpacity *= greyoutOpacity; + } + } + + // The sprite's footprint this frame: its size by the shared rule (exit-ramp.glsl), and + // the image size (0 for a point without an image) when larger. + float pointSize = transitionedSize(sourceSize, targetSize, animateSizes, transitionProgress, exit, pointDefaultSize); + float footprint = max(calculatePointSize(pointSize * sizeScale), calculatePointSize(imageSize * sizeScale)); + + // A size of 0 draws nothing (draw-points.vert culls the sprite), so it has no ring; the + // quad below is never narrower than the ramp. + if (footprint <= 0.0) { + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + return; + } + + // Ring radius from the drawn core, device px: a shape under a device pixel is drawn as one. + ringRadiusPx = max(footprint, 1.0) * POINT_RING_SCALE * 0.5; + quadHalfPx = ringRadiusPx + EDGE_RAMP_PX; + float radius = quadHalfPx / pixelRatio / transformationMatrix[0][0]; + + // Calculate point position in screen space + vec2 a = pointPosition.xy; + vec2 b = pointPosition.xy + vec2(0.0, radius); + vec2 xBasis = b - a; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + vec2 pointPositionInScreenSpace = a + xBasis * vertexCoord.x + yBasis * radius * vertexCoord.y; + + // Transform point position to normalized device coordinates + vec2 p = 2.0 * pointPositionInScreenSpace / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + gl_Position = vec4(final.rg, 0, 1); +}`,vv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + // Circular sprite: hover is radius-based, like the rendered point shape. + vec2 fromCenter = 2.0 * gl_PointCoord - 1.0; + if (dot(fromCenter, fromCenter) > 1.0) discard; + fragColor = rgba; +} +`,Pv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +// Fills the screen-space picking buffer: every point rasterizes its sprite at +// its projected screen position, carrying [index, x, y] to the fragment shader. +// Hover detection then only reads a small window of this buffer under the +// cursor — it never has to touch the point set again until the scene changes +// (see Points.updatePickingBuffer / Graph.findHoveredItem). +// +// The two-pass highlight priority mirrors the draw order: greyed first, then +// highlighted (top-most wins), since later points overwrite earlier ones with +// the depth test off. + +in vec2 pointIndices; +in float size; +in float imageSize; +in float imageIndex; + +uniform sampler2D positionsTexture; +uniform sampler2D pointStatus; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform fillPickingBufferUniforms { + float pointsTextureSize; + float sizeScale; + float spaceSize; + vec2 screenSize; + float ratio; + float pickingPixelRatio; + mat4 transformationMatrix; + float scalePointsOnZoom; + float maxPointSize; + float skipHighlighted; + float skipGreyed; + float pointDefaultSize; + float hasImages; + float imageCount; +} fillPickingBuffer; + +#define pointsTextureSize fillPickingBuffer.pointsTextureSize +#define sizeScale fillPickingBuffer.sizeScale +#define spaceSize fillPickingBuffer.spaceSize +#define screenSize fillPickingBuffer.screenSize +#define ratio fillPickingBuffer.ratio +#define pickingPixelRatio fillPickingBuffer.pickingPixelRatio +#define transformationMatrix fillPickingBuffer.transformationMatrix +#define scalePointsOnZoom fillPickingBuffer.scalePointsOnZoom +#define maxPointSize fillPickingBuffer.maxPointSize +#define skipHighlighted fillPickingBuffer.skipHighlighted +#define skipGreyed fillPickingBuffer.skipGreyed +#define pointDefaultSize fillPickingBuffer.pointDefaultSize +#define hasImages fillPickingBuffer.hasImages +#define imageCount fillPickingBuffer.imageCount +#else +uniform float pointsTextureSize; +uniform float sizeScale; +uniform float spaceSize; +uniform vec2 screenSize; +uniform float ratio; +uniform float pickingPixelRatio; +uniform mat3 transformationMatrix; +uniform float scalePointsOnZoom; +uniform float maxPointSize; +uniform float skipHighlighted; +uniform float skipGreyed; +uniform float pointDefaultSize; +uniform float hasImages; +uniform float imageCount; +#endif + +out vec4 rgba; + +// Keep tiny points pickable: below this sprite footprint (in picking-buffer +// pixels) a point could fall between the buffer's texels. +const float minPickingSize = 2.0; + +// The drawn size (draw-points.vert), so the pickable footprint is the rendered point. +float calculatePointSize(float size, float pxPerUnit) { + return pointSizePx(size, ratio, pxPerUnit, scalePointsOnZoom, maxPointSize); +} + +void main() { + // Fully clipped: a skipped point must not rasterize anywhere in the buffer. + rgba = vec4(-1.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 1.0; + + ivec2 pointTexel = ivec2(pointIndices); + + // Skip absent (faded-out) points so hover never lands on a removed one. Their + // size/position may still look hittable mid-fade (only alpha faded), so the exit + // status is the reliable signal. exit.G = current absence. + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) return; + + vec4 greyoutStatus = texelFetch(pointStatus, pointTexel, 0); + float isHighlighted = (greyoutStatus.r == 0.0) ? 1.0 : 0.0; + + if (skipHighlighted > 0.0 && isHighlighted > 0.0) return; + if (skipGreyed > 0.0 && isHighlighted <= 0.0) return; + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 point = pointPosition.rg; + + vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0; + normalizedPosition *= spaceSize / screenSize; + + #ifdef USE_UNIFORM_BUFFERS + mat3 transformMat3 = mat3(transformationMatrix); + vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1); + #else + vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1); + #endif + float pxPerUnit = transformationMatrix[0][0]; + vec2 ndc = finalPosition.xy; + + // Resolve a NaN size at read time. The absent-point guard above already returned, + // so a NaN here means "use the config default". + float resolvedSize = isnan(size) ? pointDefaultSize : size; + + // Same footprint as draw-points.vert: the image size counts only for a point + // that draws an image. + bool hasImage = hasImages > 0.0 && imageIndex >= 0.0 && imageIndex < imageCount; + float shapeSizeValue = calculatePointSize(resolvedSize * sizeScale, pxPerUnit); + float imageSizeValue = hasImage ? calculatePointSize(imageSize * sizeScale, pxPerUnit) : 0.0; + // A size of 0 draws nothing (draw-points.vert), so it is not hoverable either. + if (max(shapeSizeValue, imageSizeValue) <= 0.0) return; + + // Device px → CSS px → picking-buffer px (the buffer is smaller than the screen) + float spriteSize = max(shapeSizeValue, imageSizeValue) / ratio * pickingPixelRatio; + + float index = pointIndices.g * pointsTextureSize + pointIndices.r; + rgba = vec4(index, pointPosition.rg, 0.0); + gl_PointSize = max(spriteSize, minPickingSize); + // 2D: later points overwrite earlier ones (depth test off), matching draw order. + gl_Position = vec4(ndc, 0.0, 1.0); +} +`,Pd=`// A point's size in device pixels: the size (CSS px) by the pixel ratio and the zoom — 1:1 with +// scalePointsOnZoom, otherwise held near constant — capped at the hardware sprite limit. +// pxPerUnit is the zoom scale. Module code precedes each shader's own uniforms, so they come in +// as parameters. +float pointSizePx(float size, float ratio, float pxPerUnit, float scalePointsOnZoom, float maxPointSize) { + float zoom = scalePointsOnZoom > 0.0 ? pxPerUnit : min(5.0, max(1.0, pxPerUnit * 0.01)); + return min(size * ratio * zoom, maxPointSize * ratio); +} +`,gi={name:"pointSize",vs:Pd,fs:Pd},_r={name:"exitRamp",vs:`// Shared by draw-points.vert and draw-highlighted.vert, so the sprite and its hover/focus ring +// fade and mix sizes by one rule. Module code precedes each shader's own uniforms, so they come +// in as parameters; EXIT_DEFAULT_SIZE is a #define injected from variables.ts. + +// How gone a point is, 0 = present, 1 = gone, from its exit-texture texel (R = previous absence, +// G = current absence). During a position transition the enter/exit fade blends R→G; otherwise +// the settled G, so an unrelated color or size transition cannot replay the fade. +float exitRamp(vec4 exitStatus, float animatePositions, float transitionProgress) { + return animatePositions > 0.0 ? mix(exitStatus.r, exitStatus.g, transitionProgress) : exitStatus.g; +} + +// A NaN size means "use the default": the config default blended toward the exit default along +// the ramp, so a default-sized point grows in and shrinks out with its fade. Explicit values +// pass through. +float resolveSize(float size, float exit, float pointDefaultSize) { + return isnan(size) ? mix(pointDefaultSize, EXIT_DEFAULT_SIZE, exit) : size; +} + +// The point's size this frame: the source→target mix by progress during a size transition, +// else the target, each resolved along the exit ramp. +float transitionedSize(float sourceSize, float targetSize, float animateSizes, float transitionProgress, float exit, float pointDefaultSize) { + return animateSizes > 0.0 + ? mix(resolveSize(sourceSize, exit, pointDefaultSize), resolveSize(targetSize, exit, pointDefaultSize), transitionProgress) + : resolveSize(targetSize, exit, pointDefaultSize); +} +`},Cv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec4 rgba; + +out vec4 fragColor; + +void main() { + fragColor = rgba; +}`,Av=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +in vec2 pointIndices; + +uniform sampler2D positionsTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform fillSampledPointsUniforms { + float pointsTextureSize; + mat4 transformationMatrix; + float spaceSize; + vec2 screenSize; +} fillSampledPoints; + +#define pointsTextureSize fillSampledPoints.pointsTextureSize +#define transformationMatrix fillSampledPoints.transformationMatrix +#define spaceSize fillSampledPoints.spaceSize +#define screenSize fillSampledPoints.screenSize +#else +uniform float pointsTextureSize; +uniform float spaceSize; +uniform vec2 screenSize; +uniform mat3 transformationMatrix; +#endif + +out vec4 rgba; + +void main() { + ivec2 pointTexel = ivec2(pointIndices); + + // Keep absent (faded-out) points out of the sample. exit.G = current absence. + if (texelFetch(exitTexture, pointTexel, 0).g > 0.5) { + rgba = vec4(0.0); + gl_Position = vec4(2.0, 2.0, 2.0, 1.0); + gl_PointSize = 0.0; + return; + } + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0; + p *= spaceSize / screenSize; + #ifdef USE_UNIFORM_BUFFERS + // Convert mat4 to mat3 for vec3 multiplication + mat3 transformMat3 = mat3(transformationMatrix); + vec3 final = transformMat3 * vec3(p, 1); + #else + vec3 final = transformationMatrix * vec3(p, 1); + #endif + + vec2 pointScreenPosition = (final.xy + 1.0) * screenSize / 2.0; + float index = pointIndices.g * pointsTextureSize + pointIndices.r; + rgba = vec4(index, 1.0, pointPosition.xy); + float i = (pointScreenPosition.x + 0.5) / screenSize.x; + float j = (pointScreenPosition.y + 0.5) / screenSize.y; + gl_Position = vec4(2.0 * vec2(i, j) - 1.0, 0.0, 1.0); + + gl_PointSize = 1.0; +}`,Rv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D velocity; +uniform sampler2D pinnedStatusTexture; +uniform sampler2D exitTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform updatePositionUniforms { + float friction; + float spaceSize; +} updatePosition; + +#define friction updatePosition.friction +#define spaceSize updatePosition.spaceSize +#else +uniform float friction; +uniform float spaceSize; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + vec4 pointVelocity = texelFetch(velocity, pointTexel, 0); + + // Check if point is pinned + // pinnedStatusTexture has the same size and layout as positionsTexture + // Each pixel corresponds to a point: red channel > 0.5 means the point is pinned + vec4 pinnedStatus = texelFetch(pinnedStatusTexture, pointTexel, 0); + + // If pinned, don't update position + if (pinnedStatus.r > 0.5) { + fragColor = pointPosition; + return; + } + + // If absent (current absence = exit.G), leave it untouched — don't integrate or + // clamp it (clamping NaN is undefined and could resurrect the point at (0,0)). + vec4 exitStatus = texelFetch(exitTexture, pointTexel, 0); + if (exitStatus.g > 0.5) { + fragColor = pointPosition; + return; + } + + // Friction + pointVelocity.rg *= friction; + + pointPosition.rg += pointVelocity.rg; + + pointPosition.r = clamp(pointPosition.r, 0.0, spaceSize); + pointPosition.g = clamp(pointPosition.g, 0.0, spaceSize); + + fragColor = pointPosition; +}`,wv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D sourceTexture; +uniform sampler2D targetTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform interpolatePositionUniforms { + float progress; +} interpolatePosition; + +#define progress interpolatePosition.progress +#else +uniform float progress; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 source = texelFetch(sourceTexture, pointTexel, 0); + vec4 target = texelFetch(targetTexture, pointTexel, 0); + // NaN means absent (ingest normalizes half-NaN to full-NaN, so checking one + // channel suffices). Hold the real side so the point stays put while it fades, + // never interpolating to/from NaN: + // · exiting (target NaN): freeze at source. + // · entering (source NaN): appear at target (no slide in from NaN). + vec2 src = isnan(source.r) ? target.rg : source.rg; + vec2 tgt = isnan(target.r) ? src : target.rg; + vec2 position = mix(src, tgt, progress); + fragColor = vec4(position, source.b, 1.0); +} +`,Ev=`#version 300 es +#ifdef GL_ES +precision highp float; +// Fragment shaders default int to mediump, guaranteed only to 32767 — +// point indices go far higher. +precision highp int; +#endif + +uniform sampler2D positionsTexture; +uniform sampler2D trackedIndices; + +out vec4 fragColor; + +void main() { + ivec2 trackedTexel = ivec2(gl_FragCoord.xy); + + // The table holds raw point indices (-1 = unused slot). The texel is derived + // here, from the width the positions texture has right now — the grid relayouts + // when the point count changes, so a texel computed at bake time would keep + // addressing the old layout. textureSize() is valid here because this shader + // samples positionsTexture itself. + float index = texelFetch(trackedIndices, trackedTexel, 0).r; + if (index < 0.0) discard; + + int i = int(index); + int w = textureSize(positionsTexture, 0).x; + // An index past the point count fetches out of range and yields zeros; the + // CPU readback owns range validation and drops such entries. + vec4 pointPosition = texelFetch(positionsTexture, ivec2(i % w, i / w), 0); + + fragColor = vec4(pointPosition.rg, 1.0, 1.0); +} +`,Iv=`#version 300 es +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D positionsTexture; + +#ifdef USE_UNIFORM_BUFFERS +layout(std140) uniform dragPointUniforms { + vec2 mousePos; + float index; +} dragPoint; + +#define mousePos dragPoint.mousePos +#define index dragPoint.index +#else +uniform vec2 mousePos; +uniform float index; +#endif + +out vec4 fragColor; + +void main() { + ivec2 pointTexel = ivec2(gl_FragCoord.xy); + + vec4 pointPosition = texelFetch(positionsTexture, pointTexel, 0); + + // Check if a point is being dragged + if (index >= 0.0 && index == pointPosition.b) { + pointPosition.rg = mousePos.rg; + } + + fragColor = pointPosition; +}`;function kv(e,t=16384){if(!(e!=null&&e.length))return null;let i=0;for(const c of e){const u=Math.max(c.width,c.height);u>i&&(i=u)}if(i===0)return console.warn("Invalid image dimensions: all images have zero width or height"),null;const n=i,r=Math.ceil(Math.sqrt(e.length));let s=r*i,o=1;s>t&&(o=t/s,i=Math.max(1,Math.floor(i*o)),s=Math.max(1,Math.floor(s*o)),console.warn(`🖼️ Atlas scaling required: Original size ${(n*r).toLocaleString()}px exceeds WebGL limit ${t.toLocaleString()}px. Scaling down to ${s.toLocaleString()}px (${Math.round(o*100)}% of original quality)`));const a=new Uint8Array(s*s*4).fill(0),l=new Float32Array(r*r*4).fill(-1);for(const[c,u]of e.entries()){const d=u.width,h=u.height;if(d===0||h===0)continue;const p=Math.min(1,i/Math.max(d,h)),g=Math.floor(d*p),x=Math.floor(h*p),T=Math.floor(c/r),P=c%r*i,I=T*i;l[c*4]=P/s,l[c*4+1]=I/s,l[c*4+2]=(P+g)/s,l[c*4+3]=(I+x)/s;for(let y=0;y<x;y++)for(let v=0;v<g;v++){const E=Math.floor(v*(d/g)),D=(Math.floor(y*(h/x))*d+E)*4,z=((I+y)*s+(P+v))*4;a[z]=u.data[D]??0,a[z+1]=u.data[D+1]??0,a[z+2]=u.data[D+2]??0,a[z+3]=u.data[D+3]??255}}return{atlasData:a,atlasSize:s,atlasCoords:l,atlasCoordsSize:r}}function Dv(e,t,i){const n=new Float32Array(t*t*4);if(!e)return n;for(let r=0;r<i;++r){const s=De(e,r);n[r*4+0]=s?NaN:e[r*2+0],n[r*4+1]=s?NaN:e[r*2+1],n[r*4+2]=r}return n}function Fv(e,t,i,n,r){const s=new Float32Array(r*r*4);for(let o=0;o<i;o+=1)s[o*4+0]=e[o*4+0],s[o*4+1]=e[o*4+1],s[o*4+2]=o;for(let o=i;o<n;o+=1)s[o*4+0]=t[o*4+0],s[o*4+1]=t[o*4+1],s[o*4+2]=o;return s}const Cd={blend:!0,blendColorOperation:"add",blendColorSrcFactor:"src-alpha",blendColorDstFactor:"one-minus-src-alpha",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one-minus-src-alpha"},Ad={...te,...Cd},Mv={...te,blend:!1,depthWriteEnabled:!0,depthCompare:"less"},Nv={...te,...Cd,depthCompare:"less"},br={EXIT_DEFAULT_SIZE:li(Os),EXIT_DEFAULT_COLOR_CHANNEL:li(Xn),EDGE_RAMP_PX:li(Us),POINT_RING_SCALE:li(fc)};class Bv extends gt{constructor(){super(...arguments),this.isPickingBufferStale=!0,this.imageCount=0,this.positionVersion=0,this.pointListVersion=0,this.areClusterCentroidsUpToDate=!1,this.hasAnyAbsentPoint=!1,this.pointListCount=0,this.trackers=new Set,this.isSizeTextureStale=!0,this.polygonPathLength=0,this.isOcclusionCullingActive=!1,this.transitionProgress=1,this.shouldAnimatePointColors=!1,this.shouldAnimatePointSizes=!1,this.shouldAnimatePointPositions=!1}get hasPendingPickReadback(){var t;return((t=this.pickingReadback)==null?void 0:t.inFlight)??!1}get hasPendingTrackedReadback(){for(const t of this.trackers)if(t.hasPendingReadback)return!0;return!1}updatePositions(){var T,S;const{device:t,store:i,data:n,config:{rescalePositions:r,enableSimulation:s}}=this,{pointsTextureSize:o}=i;if(!o||!n.pointPositions||n.pointsNumber===void 0)return this.pointListCount!==0&&(this.pointListCount=0,this.pointListVersion++),!1;let a=r;r===void 0&&!s&&(a=!0),this.shouldSkipRescale&&(a=!1),a?this.rescaleInitialNodePositions():this.shouldSkipRescale||(this.scaleX=void 0,this.scaleY=void 0),this.shouldSkipRescale=void 0;const l=n.sourcePointsNumber,c=n.targetPointsNumber,u=l===c,d=((T=this.transition)==null?void 0:T.isPendingFor(le.Positions))===!0&&(((S=this.transition)==null?void 0:S.duration)??this.config.transitionDuration)>0&&!!this.currentPositionTexture,h=Dv(n.pointPositions,o,c);let p;if(d&&(this.createTransitionResources(),this.sourcePositionTexture&&this.targetPositionTexture)){if(u){const P=this.currentPositionTexture;if(P&&!P.destroyed){const I=this.device.createCommandEncoder();I.copyTextureToTexture({sourceTexture:P,destinationTexture:this.sourcePositionTexture,width:o,height:o}),this.device.submit(I.finish())}}else if(this.currentPositionFbo){const P=we(t,this.currentPositionFbo);p=Fv(P,h,Math.min(l,c),c,o),this.writePositionTexture(this.sourcePositionTexture,p,o)}else this.writePositionTexture(this.sourcePositionTexture,h,o);this.writePositionTexture(this.targetPositionTexture,h,o)}this.ensurePositionTextures(o),d?p&&(this.writePositionTexture(this.currentPositionTexture,p,o),this.writePositionTexture(this.previousPositionTexture,p,o)):(this.writePositionTexture(this.currentPositionTexture,h,o),this.writePositionTexture(this.previousPositionTexture,h,o)),this.areClusterCentroidsUpToDate=!1,this.markPositionsChanged(),this.config.enableSimulation&&this.ensureSimulationResources(),!this.searchTexture||this.searchTexture.width!==o||this.searchTexture.height!==o?(this.searchTexture&&!this.searchTexture.destroyed&&this.searchTexture.destroy(),this.searchFbo&&!this.searchFbo.destroyed&&this.searchFbo.destroy(),this.searchTexture=t.createTexture({width:o,height:o,format:"rgba32float"}),this.searchTexture.copyImageData({data:h,bytesPerRow:q("rgba32float",o),mipLevel:0,x:0,y:0}),this.searchFbo=t.createFramebuffer({width:o,height:o,colorAttachments:[this.searchTexture]})):this.searchTexture.copyImageData({data:h,bytesPerRow:q("rgba32float",o),mipLevel:0,x:0,y:0}),this.isPickingBufferStale=!0,this.discardPendingPick();const g=ji(i.pointsTextureSize),x=g.byteLength;return!this.drawPointIndices||this.drawPointIndices.byteLength!==x?(this.drawPointIndices&&!this.drawPointIndices.destroyed&&this.drawPointIndices.destroy(),this.drawPointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST})):this.drawPointIndices.write(g),this.drawCommand&&this.drawCommand.setAttributes({pointIndices:this.drawPointIndices}),this.drawCoreCommand&&this.drawCoreCommand.setAttributes({pointIndices:this.drawPointIndices}),this.updateReversedPointIndexBuffer(),!this.hoveredPointIndices||this.hoveredPointIndices.byteLength!==x?(this.hoveredPointIndices&&!this.hoveredPointIndices.destroyed&&this.hoveredPointIndices.destroy(),this.hoveredPointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST})):this.hoveredPointIndices.write(g),!this.sampledPointIndices||this.sampledPointIndices.byteLength!==x?(this.sampledPointIndices&&!this.sampledPointIndices.destroyed&&this.sampledPointIndices.destroy(),this.sampledPointIndices=t.createBuffer({data:g,usage:B.VERTEX|B.COPY_DST})):this.sampledPointIndices.write(g),this.fillSampledPointsFboCommand&&this.fillSampledPointsFboCommand.setAttributes({pointIndices:this.sampledPointIndices}),this.updatePointStatus(),this.updatePinnedStatus(),this.updateExit(),this.updateSampledPointsGrid(),d||this.gatherTrackers(),d}initPrograms(){var s,o,a;const{device:t,config:i,store:n,data:r}=this;(!this.imageAtlasCoordsTexture||!this.imageAtlasTexture)&&this.createAtlas(),this.targetColorBuffer||this.updateColor(),this.targetSizeBuffer||this.updateSize(),this.shapeBuffer||this.updateShape(),this.imageIndicesBuffer||this.updateImageIndices(),this.imageSizesBuffer||this.updateImageSizes(),this.pointStatusTexture||this.updatePointStatus(),i.enableSimulation&&this.ensureUpdatePositionProgram(),this.dragPointVertexCoordBuffer||(this.dragPointVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.dragPointUniformStore||(this.dragPointUniformStore=new oe(t,{dragPointUniforms:{uniformTypes:{mousePos:"vec2<f32>",index:"f32"},defaultUniforms:{mousePos:ie(n.mousePosition,[0,0]),index:((s=n.hoveredPoint)==null?void 0:s.index)??-1}}})),this.dragPointCommand||(this.dragPointCommand=new ee(t,{fs:Iv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.dragPointVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{dragPointUniforms:this.dragPointUniformStore.getManagedUniformBuffer("dragPointUniforms")},parameters:te})),this.drawUniformStore||(this.drawUniformStore=new oe(t,{drawVertexUniforms:{uniformTypes:{ratio:"f32",transformationMatrix:"mat4x4<f32>",pointsTextureSize:"f32",sizeScale:"f32",spaceSize:"f32",screenSize:"vec2<f32>",greyoutColor:"vec4<f32>",backgroundColor:"vec4<f32>",scalePointsOnZoom:"f32",maxPointSize:"f32",isDarkenGreyout:"f32",skipHighlighted:"f32",skipGreyed:"f32",hasImages:"f32",imageCount:"f32",imageAtlasCoordsTextureSize:"f32",transitionProgress:"f32",animateColors:"f32",animateSizes:"f32",animatePositions:"f32",pointDefaultColor:"vec4<f32>",pointDefaultSize:"f32",pointsNumber:"f32"},defaultUniforms:{ratio:i.pixelRatio,transformationMatrix:(()=>{const l=n.transform??[1,0,0,0,1,0,0,0,1];return[l[0],l[1],l[2],0,l[3],l[4],l[5],0,l[6],l[7],l[8],0,0,0,0,1]})(),pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),greyoutColor:ge(n.greyoutPointColor,[0,0,0,1]),backgroundColor:ge(n.backgroundColor,[0,0,0,1]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,skipHighlighted:0,skipGreyed:0,hasImages:this.imageCount>0?1:0,imageCount:this.imageCount,imageAtlasCoordsTextureSize:this.imageAtlasCoordsTextureSize??0,transitionProgress:1,animateColors:0,animateSizes:0,animatePositions:0,pointDefaultColor:ge(We(i.pointDefaultColor),[0,0,0,1]),pointDefaultSize:i.pointDefaultSize,pointsNumber:r.pointsNumber??0}},drawFragmentUniforms:{uniformTypes:{greyoutOpacity:"f32",pointOpacity:"f32",isDarkenGreyout:"f32",backgroundColor:"vec4<f32>",outlineColor:"vec4<f32>",outlineWidth:"f32",renderMode:"f32",pickingAlpha:"f32",pickingIndexOffset:"f32"},defaultUniforms:{pickingAlpha:1,pickingIndexOffset:0,greyoutOpacity:i.pointGreyoutOpacity??-1,pointOpacity:i.pointOpacity,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,backgroundColor:ge(n.backgroundColor,[0,0,0,1]),outlineColor:ge(n.outlinedPointRingColor,[1,1,1,1]),outlineWidth:.9,renderMode:0}}})),this.drawCommand||(this.drawCommand=new ee(t,{fs:Ko,vs:qo,modules:[gi,_r,ur],topology:"point-list",vertexCount:r.pointsNumber??0,attributes:{...this.drawPointIndices&&{pointIndices:this.drawPointIndices},...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer},...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer},...this.shapeBuffer&&{shape:this.shapeBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer}},bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"sourceSize",format:"float32"},{name:"targetSize",format:"float32"},{name:"sourceColor",format:"float32x4"},{name:"targetColor",format:"float32x4"},{name:"shape",format:"float32"},{name:"imageIndex",format:"float32"},{name:"imageSize",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawVertexUniforms:this.drawUniformStore.getManagedUniformBuffer("drawVertexUniforms"),drawFragmentUniforms:this.drawUniformStore.getManagedUniformBuffer("drawFragmentUniforms")},parameters:Ad})),this.updateReversedPointIndexBuffer(),this.drawCoreCommand||(this.drawCoreCommand=new ee(t,{fs:Ko,vs:qo,modules:[gi,_r,ur],topology:"point-list",vertexCount:r.pointsNumber??0,indexBuffer:this.reversedPointIndexBuffer??null,attributes:{...this.drawPointIndices&&{pointIndices:this.drawPointIndices},...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer},...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer},...this.shapeBuffer&&{shape:this.shapeBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer}},bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"sourceSize",format:"float32"},{name:"targetSize",format:"float32"},{name:"sourceColor",format:"float32x4"},{name:"targetColor",format:"float32x4"},{name:"shape",format:"float32"},{name:"imageIndex",format:"float32"},{name:"imageSize",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawVertexUniforms:this.drawUniformStore.getManagedUniformBuffer("drawVertexUniforms"),drawFragmentUniforms:this.drawUniformStore.getManagedUniformBuffer("drawFragmentUniforms")},parameters:Mv})),this.findPointsInRectVertexCoordBuffer||(this.findPointsInRectVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.findPointsInRectUniformStore||(this.findPointsInRectUniformStore=new oe(t,{findPointsInRectUniforms:{uniformTypes:{sizeScale:"f32",spaceSize:"f32",screenSize:"vec2<f32>",ratio:"f32",transformationMatrix:"mat4x4<f32>",rect0:"vec2<f32>",rect1:"vec2<f32>",scalePointsOnZoom:"f32",maxPointSize:"f32"},defaultUniforms:{sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),ratio:i.pixelRatio,transformationMatrix:n.transformationMatrix4x4,rect0:ie((o=n.searchArea)==null?void 0:o[0],[0,0]),rect1:ie((a=n.searchArea)==null?void 0:a[1],[0,0]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize}}})),this.findPointsInRectCommand||(this.findPointsInRectCommand=new ee(t,{fs:yv,vs:Ee,modules:[gi],topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.findPointsInRectVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{findPointsInRectUniforms:this.findPointsInRectUniformStore.getManagedUniformBuffer("findPointsInRectUniforms")},parameters:te})),this.findPointsInPolygonVertexCoordBuffer||(this.findPointsInPolygonVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.findPointsInPolygonUniformStore||(this.findPointsInPolygonUniformStore=new oe(t,{findPointsInPolygonUniforms:{uniformTypes:{spaceSize:"f32",screenSize:"vec2<f32>",transformationMatrix:"mat4x4<f32>",polygonPathLength:"f32"},defaultUniforms:{spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),transformationMatrix:n.transformationMatrix4x4,polygonPathLength:this.polygonPathLength}}})),this.findPointsInPolygonCommand||(this.findPointsInPolygonCommand=new ee(t,{fs:_v,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.findPointsInPolygonVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{findPointsInPolygonUniforms:this.findPointsInPolygonUniformStore.getManagedUniformBuffer("findPointsInPolygonUniforms")},parameters:te})),this.fillPickingBufferUniformStore||(this.fillPickingBufferUniformStore=new oe(t,{fillPickingBufferUniforms:{uniformTypes:{pointsTextureSize:"f32",sizeScale:"f32",spaceSize:"f32",screenSize:"vec2<f32>",ratio:"f32",pickingPixelRatio:"f32",transformationMatrix:"mat4x4<f32>",scalePointsOnZoom:"f32",maxPointSize:"f32",skipHighlighted:"f32",skipGreyed:"f32",pointDefaultSize:"f32",hasImages:"f32",imageCount:"f32"},defaultUniforms:{pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),ratio:i.pixelRatio,pickingPixelRatio:ko,transformationMatrix:n.transformationMatrix4x4,scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize,skipHighlighted:0,skipGreyed:0,pointDefaultSize:i.pointDefaultSize,hasImages:0,imageCount:0}}})),this.fillPickingBufferCommand||(this.fillPickingBufferCommand=new ee(t,{fs:vv,vs:Pv,modules:[gi],topology:"point-list",vertexCount:r.pointsNumber??0,attributes:{...this.hoveredPointIndices&&{pointIndices:this.hoveredPointIndices},...this.targetSizeBuffer&&{size:this.targetSizeBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer}},bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"size",format:"float32"},{name:"imageSize",format:"float32"},{name:"imageIndex",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{fillPickingBufferUniforms:this.fillPickingBufferUniformStore.getManagedUniformBuffer("fillPickingBufferUniforms")},parameters:te})),this.fillSampledPointsUniformStore||(this.fillSampledPointsUniformStore=new oe(t,{fillSampledPointsUniforms:{uniformTypes:{pointsTextureSize:"f32",transformationMatrix:"mat4x4<f32>",spaceSize:"f32",screenSize:"vec2<f32>"},defaultUniforms:{pointsTextureSize:n.pointsTextureSize??0,transformationMatrix:n.transformationMatrix4x4,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0])}}})),this.fillSampledPointsFboCommand||(this.fillSampledPointsFboCommand=new ee(t,{fs:Cv,vs:Av,topology:"point-list",vertexCount:r.pointsNumber??0,attributes:{...this.sampledPointIndices&&{pointIndices:this.sampledPointIndices}},bufferLayout:[{name:"pointIndices",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{fillSampledPointsUniforms:this.fillSampledPointsUniformStore.getManagedUniformBuffer("fillSampledPointsUniforms")},parameters:te})),this.drawHighlightedVertexCoordBuffer||(this.drawHighlightedVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.drawHighlightedUniformStore||(this.drawHighlightedUniformStore=new oe(t,{drawHighlightedUniforms:{uniformTypes:{sourceSize:"f32",targetSize:"f32",imageSize:"f32",transformationMatrix:"mat4x4<f32>",pointsTextureSize:"f32",sizeScale:"f32",spaceSize:"f32",screenSize:"vec2<f32>",scalePointsOnZoom:"f32",pointIndex:"f32",maxPointSize:"f32",color:"vec4<f32>",universalPointOpacity:"f32",greyoutOpacity:"f32",isDarkenGreyout:"f32",backgroundColor:"vec4<f32>",greyoutColor:"vec4<f32>",animatePositions:"f32",transitionProgress:"f32",animateSizes:"f32",pointDefaultSize:"f32",width:"f32",pixelRatio:"f32"},defaultUniforms:{sourceSize:1,targetSize:1,imageSize:0,transformationMatrix:n.transformationMatrix4x4,pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,pointIndex:-1,maxPointSize:n.maxPointSize,color:[0,0,0,1],universalPointOpacity:i.pointOpacity,greyoutOpacity:i.pointGreyoutOpacity??-1,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,backgroundColor:ge(n.backgroundColor,[0,0,0,1]),greyoutColor:ge(n.greyoutPointColor,[0,0,0,1]),animatePositions:0,transitionProgress:1,animateSizes:0,pointDefaultSize:i.pointDefaultSize,width:.85,pixelRatio:i.pixelRatio}}})),this.drawHighlightedCommand||(this.drawHighlightedCommand=new ee(t,{fs:bv,vs:Tv,modules:[gi,_r],topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.drawHighlightedVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawHighlightedUniforms:this.drawHighlightedUniformStore.getManagedUniformBuffer("drawHighlightedUniforms")},parameters:{...te,blend:!0,blendColorOperation:"add",blendColorSrcFactor:"src-alpha",blendColorDstFactor:"one-minus-src-alpha",blendAlphaOperation:"add",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one-minus-src-alpha",depthWriteEnabled:!1,depthCompare:"always"}})),this.trackPointsVertexCoordBuffer||(this.trackPointsVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.trackPointsCommand||(this.trackPointsCommand=new ee(t,{fs:Ev,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.trackPointsVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{},parameters:te}))}updateColor(){const{device:t,store:{pointsTextureSize:i},data:n}=this;if(!i)return;const r=n.pointColors,{source:s,target:o,previous:a}=hr(this.device,r,this.sourceColorBuffer,this.targetColorBuffer,this.previousColorData,4);this.sourceColorBuffer=s,this.targetColorBuffer=o,this.previousColorData=a;const l={...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer}};if(this.drawCommand&&this.drawCommand.setAttributes(l),this.drawCoreCommand&&this.drawCoreCommand.setAttributes(l),this.config.linkColorInterpolateFromEndpoints){const c=new Float32Array(i*i*4);c.set(r.subarray(0,Math.min(r.length,c.length))),(!this.pointColorsTexture||this.pointColorsTexture.width!==i||this.pointColorsTexture.height!==i)&&(this.pointColorsTexture&&!this.pointColorsTexture.destroyed&&this.pointColorsTexture.destroy(),this.pointColorsTexture=t.createTexture({width:i,height:i,format:"rgba32float"})),this.pointColorsTexture.copyImageData({data:c,bytesPerRow:q("rgba32float",i),mipLevel:0,x:0,y:0})}else this.pointColorsTexture&&(this.pointColorsTexture.destroyed||this.pointColorsTexture.destroy(),this.pointColorsTexture=void 0)}updatePointStatus(){const{device:t,config:i,data:n,store:{pointsTextureSize:r}}=this;if(!r||n.pointsNumber===void 0)return;this.isPickingBufferStale=!0;const{highlightedPointIndices:s,outlinedPointIndices:o}=i,a=s!==void 0,l=o!==void 0,c=new Float32Array(r*r*4);if(a){for(let d=0;d<c.length;d+=4)c[d]=1;for(const d of s)d>=0&&d<n.pointsNumber&&(c[d*4]=0)}if(l)for(const d of o)d>=0&&d<n.pointsNumber&&(c[d*4+1]=1);const u={data:c,bytesPerRow:q("rgba32float",r),mipLevel:0,x:0,y:0};!this.pointStatusTexture||this.pointStatusTexture.width!==r||this.pointStatusTexture.height!==r?(this.pointStatusTexture&&!this.pointStatusTexture.destroyed&&this.pointStatusTexture.destroy(),this.pointStatusTexture=t.createTexture({width:r,height:r,format:"rgba32float"}),this.pointStatusTexture.copyImageData(u)):this.pointStatusTexture.copyImageData(u)}updatePinnedStatus(){const{device:t,store:{pointsTextureSize:i},data:n}=this;if(!i)return;const r=new Float32Array(i*i*4).fill(0);if(n.inputPinnedPoints&&n.pointsNumber!==void 0)for(const s of n.inputPinnedPoints)s>=0&&s<n.pointsNumber&&(r[s*4]=1);!this.pinnedStatusTexture||this.pinnedStatusTexture.width!==i||this.pinnedStatusTexture.height!==i?(this.pinnedStatusTexture&&!this.pinnedStatusTexture.destroyed&&this.pinnedStatusTexture.destroy(),this.pinnedStatusTexture=t.createTexture({width:i,height:i,format:"rgba32float"}),this.pinnedStatusTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",i),mipLevel:0,x:0,y:0})):this.pinnedStatusTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",i),mipLevel:0,x:0,y:0})}updateExit(){const{device:t,store:{pointsTextureSize:i},data:n}=this;if(!i)return;const r=n.pointsNumber??0,s=this.previousExitData,o=this.hasAnyAbsentPoint,a=new Float32Array(r);let l=!1,c=r!==this.pointListCount;for(let h=0;h<r;h++){const p=n.pointPositions&&De(n.pointPositions,h)?1:0;a[h]=p,p&&(l=!0),!c&&(s==null?void 0:s[h])!==p&&(c=!0)}if(this.previousExitData=a,this.hasAnyAbsentPoint=l,c&&(this.pointListCount=r,this.pointListVersion++),!l&&!o){if(this.exitTexture&&!this.exitTexture.destroyed&&this.exitTexture.width===1)return;this.exitTexture&&!this.exitTexture.destroyed&&this.exitTexture.destroy(),this.exitTexture=t.createTexture({width:1,height:1,format:"rg32float"}),this.exitTexture.copyImageData({data:new Float32Array(2),bytesPerRow:q("rg32float",1),mipLevel:0,x:0,y:0});return}const u=new Float32Array(i*i*2);for(let h=0;h<r;h++){const p=a[h],g=h<((s==null?void 0:s.length)??0)?s[h]:p;u[h*2]=g,u[h*2+1]=p}const d=!!this.exitTexture&&this.exitTexture.width===i&&this.exitTexture.height===i;(!this.exitTexture||!d)&&(this.exitTexture&&!this.exitTexture.destroyed&&this.exitTexture.destroy(),this.exitTexture=t.createTexture({width:i,height:i,format:"rg32float"})),this.exitTexture.copyImageData({data:u,bytesPerRow:q("rg32float",i),mipLevel:0,x:0,y:0})}updateSize(){const{store:{pointsTextureSize:t},data:i}=this;if(!t||i.pointsNumber===void 0)return;this.markFootprintsStale();const n=i.pointSizes,{source:r,target:s,previous:o,sourceData:a}=hr(this.device,n,this.sourceSizeBuffer,this.targetSizeBuffer,this.previousSizeData,1);this.sourceSizeBuffer=r,this.targetSizeBuffer=s,this.previousSizeData=o,this.sourceSizeData=a;const l={...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer}};this.drawCommand&&this.drawCommand.setAttributes(l),this.drawCoreCommand&&this.drawCoreCommand.setAttributes(l)}updateShape(){const{device:t,data:i}=this;if(i.pointsNumber===void 0||i.pointShapes===void 0)return;const n=i.pointShapes,r=n.byteLength;!this.shapeBuffer||this.shapeBuffer.byteLength!==r?(this.shapeBuffer&&!this.shapeBuffer.destroyed&&this.shapeBuffer.destroy(),this.shapeBuffer=t.createBuffer({data:n,usage:B.VERTEX|B.COPY_DST})):this.shapeBuffer.write(n),this.drawCommand&&this.drawCommand.setAttributes({shape:this.shapeBuffer}),this.drawCoreCommand&&this.drawCoreCommand.setAttributes({shape:this.shapeBuffer})}updateImageIndices(){const{device:t,data:i}=this;if(i.pointsNumber===void 0||i.pointImageIndices===void 0)return;const n=i.pointImageIndices,r=n.byteLength;!this.imageIndicesBuffer||this.imageIndicesBuffer.byteLength!==r?(this.imageIndicesBuffer&&!this.imageIndicesBuffer.destroyed&&this.imageIndicesBuffer.destroy(),this.imageIndicesBuffer=t.createBuffer({data:n,usage:B.VERTEX|B.COPY_DST})):this.imageIndicesBuffer.write(n),this.drawCommand&&this.drawCommand.setAttributes({imageIndex:this.imageIndicesBuffer}),this.drawCoreCommand&&this.drawCoreCommand.setAttributes({imageIndex:this.imageIndicesBuffer}),this.fillPickingBufferCommand&&this.fillPickingBufferCommand.setAttributes({imageIndex:this.imageIndicesBuffer}),this.markFootprintsStale()}updateImageSizes(){const{device:t,data:i}=this;if(i.pointsNumber===void 0||i.pointImageSizes===void 0)return;const n=i.pointImageSizes,r=n.byteLength;!this.imageSizesBuffer||this.imageSizesBuffer.byteLength!==r?(this.imageSizesBuffer&&!this.imageSizesBuffer.destroyed&&this.imageSizesBuffer.destroy(),this.imageSizesBuffer=t.createBuffer({data:n,usage:B.VERTEX|B.COPY_DST})):this.imageSizesBuffer.write(n),this.drawCommand&&this.drawCommand.setAttributes({imageSize:this.imageSizesBuffer}),this.drawCoreCommand&&this.drawCoreCommand.setAttributes({imageSize:this.imageSizesBuffer}),this.fillPickingBufferCommand&&this.fillPickingBufferCommand.setAttributes({imageSize:this.imageSizesBuffer}),this.markFootprintsStale()}createAtlas(){var c;const{device:t,data:i,store:n}=this;if(this.markFootprintsStale(),!((c=i.inputImageData)!=null&&c.length))return this.imageCount=0,this.imageAtlasCoordsTextureSize=0,this.imageAtlasCoordsTexture||(this.imageAtlasCoordsTexture=t.createTexture({data:new Float32Array(4).fill(0),width:1,height:1,format:"rgba32float"})),this.imageAtlasTexture||(this.imageAtlasTexture=t.createTexture({data:new Uint8Array(4).fill(0),width:1,height:1,format:"rgba8unorm"})),!0;const r=kv(i.inputImageData,n.webglMaxTextureSize);if(!r)return console.warn("Failed to create atlas from image data"),!1;this.imageCount=i.inputImageData.length;const{atlasData:s,atlasSize:o,atlasCoords:a,atlasCoordsSize:l}=r;return this.imageAtlasCoordsTextureSize=l,this.imageAtlasTexture&&!this.imageAtlasTexture.destroyed&&this.imageAtlasTexture.destroy(),this.imageAtlasTexture=t.createTexture({width:o,height:o,format:"rgba8unorm"}),this.imageAtlasTexture.copyImageData({data:s,bytesPerRow:q("rgba8unorm",o),rowsPerImage:o,mipLevel:0,x:0,y:0}),this.imageAtlasCoordsTexture&&!this.imageAtlasCoordsTexture.destroyed&&this.imageAtlasCoordsTexture.destroy(),this.imageAtlasCoordsTexture=t.createTexture({width:l,height:l,format:"rgba32float"}),this.imageAtlasCoordsTexture.copyImageData({data:a,bytesPerRow:q("rgba32float",l),rowsPerImage:l,mipLevel:0,x:0,y:0}),!0}updateSampledPointsGrid(){const{store:{screenSize:t},config:{pointSamplingDistance:i},device:n}=this;let r=i??Math.min(...t)/2;r===0&&(r=Ze.pointSamplingDistance);const s=Math.ceil(t[0]/r),o=Math.ceil(t[1]/r);s===0||o===0||(!this.sampledPointsFbo||this.sampledPointsFbo.width!==s||this.sampledPointsFbo.height!==o)&&(this.sampledPointsFbo&&!this.sampledPointsFbo.destroyed&&this.sampledPointsFbo.destroy(),this.sampledPointsFbo=n.createFramebuffer({width:s,height:o,colorAttachments:["rgba32float"]}))}gatherTrackers(){for(const t of this.trackers)t.gather()}gatherTrackedPositions(t,i){if(!this.trackPointsCommand||!this.currentPositionTexture||this.currentPositionTexture.destroyed)return!1;const n=this.trackPointsCommand,r=this.currentPositionTexture,s=()=>{n.setBindings({positionsTexture:r,trackedIndices:t});const o=this.device.beginRenderPass({framebuffer:i});n.draw(o),o.end()};return this.withHostState?this.withHostState(s):s(),!0}addTracker(t){t.attach(this)&&this.trackers.add(t)}removeTracker(t){this.trackers.delete(t)}getAnimatedSize(t,i){var o;const n=this.data.getResolvedPointSize(t),r=(o=this.sourceSizeData)==null?void 0:o[t];if(r===void 0)return n;const s=this.data.resolvePointSize(t,r);return s+(n-s)*i}setTransitionProgress(t,i=!1,n=!1,r=!1){this.transitionProgress=t,this.shouldAnimatePointColors=i,this.shouldAnimatePointSizes=n,this.shouldAnimatePointPositions=r}drawPicking(t,i,n=0){const{data:r,store:s}=this;if(this.targetColorBuffer||this.updateColor(),this.targetSizeBuffer||this.updateSize(),this.exitTexture||this.updateExit(),this.shapeBuffer||this.updateShape(),this.imageIndicesBuffer||this.updateImageIndices(),this.imageSizesBuffer||this.updateImageSizes(),!this.drawCommand||!this.drawUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.pointStatusTexture||this.pointStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed||((!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)&&this.createAtlas(),!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)||this.imageAtlasTexture.destroyed||this.imageAtlasCoordsTexture.destroyed||!r.pointsNumber||!s.screenSize||s.screenSize[0]===0||s.screenSize[1]===0)return;this.drawPickingCommand||(this.drawPickingCommand=new ee(this.device,{fs:Ko,vs:qo,modules:[gi,_r,ur],topology:"point-list",vertexCount:r.pointsNumber,attributes:this.getDrawCommandAttributes(),bufferLayout:[{name:"pointIndices",format:"float32x2"},{name:"sourceSize",format:"float32"},{name:"targetSize",format:"float32"},{name:"sourceColor",format:"float32x4"},{name:"targetColor",format:"float32x4"},{name:"shape",format:"float32"},{name:"imageIndex",format:"float32"},{name:"imageSize",format:"float32"}],defines:{USE_UNIFORM_BUFFERS:!0,...br},bindings:{drawVertexUniforms:this.drawUniformStore.getManagedUniformBuffer("drawVertexUniforms"),drawFragmentUniforms:this.drawUniformStore.getManagedUniformBuffer("drawFragmentUniforms")},parameters:te})),this.drawPickingCommand.setAttributes(this.getDrawCommandAttributes()),this.drawPickingCommand.setVertexCount(r.pointsNumber);const{vertex:o,fragment:a}=this.getDrawUniforms();this.drawUniformStore.setUniforms({drawVertexUniforms:{...o,skipHighlighted:0,skipGreyed:0},drawFragmentUniforms:{...a,renderMode:3,pickingAlpha:i,pickingIndexOffset:n}}),this.drawPickingCommand.setBindings(this.getDrawTextureBindings()),this.drawPickingCommand.draw(t)}draw(t){var p,g;const{data:i,config:n,store:r}=this;if(this.targetColorBuffer||this.updateColor(),this.targetSizeBuffer||this.updateSize(),this.exitTexture||this.updateExit(),this.shapeBuffer||this.updateShape(),this.imageIndicesBuffer||this.updateImageIndices(),this.imageSizesBuffer||this.updateImageSizes(),!this.drawCommand||!this.drawUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.pointStatusTexture||this.pointStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed||(!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)&&(this.createAtlas(),!this.imageAtlasTexture||!this.imageAtlasCoordsTexture)||this.imageAtlasTexture.destroyed||this.imageAtlasCoordsTexture.destroyed||!i.pointsNumber||i.pointsNumber===0||!r.screenSize||r.screenSize[0]===0||r.screenSize[1]===0)return;this.drawCommand.setVertexCount(i.pointsNumber);const{vertex:s,fragment:o}=this.getDrawUniforms(),a=this.getDrawTextureBindings(),l=n.highlightedPointIndices!==void 0,c=n.pointOcclusionCulling&&n.pointOpacity>=1&&!l&&!!this.drawCoreCommand&&((p=this.reversedPointIndexBuffer)==null?void 0:p.byteLength)===i.pointsNumber*4;c!==this.isOcclusionCullingActive&&(this.drawCommand.setParameters(c?Nv:Ad),this.isOcclusionCullingActive=c),c&&this.drawCoreCommand?(this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:0,skipGreyed:0},drawFragmentUniforms:{...o,renderMode:1}}),this.drawCoreCommand.setVertexCount(i.pointsNumber),this.drawCoreCommand.setBindings(a),this.drawCoreCommand.draw(t),this.drawUniformStore.setUniforms({drawFragmentUniforms:{...o,renderMode:2}}),this.drawCommand.setBindings(a),this.drawCommand.draw(t)):l?(this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:1,skipGreyed:0},drawFragmentUniforms:o}),this.drawCommand.setBindings(a),this.drawCommand.draw(t),this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:0,skipGreyed:1},drawFragmentUniforms:o}),this.drawCommand.setBindings(a),this.drawCommand.draw(t)):(this.drawUniformStore.setUniforms({drawVertexUniforms:{...s,skipHighlighted:0,skipGreyed:0},drawFragmentUniforms:o}),this.drawCommand.setBindings(a),this.drawCommand.draw(t));const u=n.renderHoveredPointRing?(g=r.hoveredPoint)==null?void 0:g.index:void 0,d=r.hostHoveredPointIndex,h=d!==void 0&&Number.isInteger(d)&&d>=0&&d<(this.data.pointsNumber??0)?d:void 0;u!==void 0&&this.drawPointRing(t,u,r.hoveredPointRingColor),h!==void 0&&h!==u&&this.drawPointRing(t,h,r.hoveredPointRingColor),r.focusedPoint&&this.drawPointRing(t,r.focusedPoint.index,r.focusedPointRingColor)}updatePosition(){if(!this.updatePositionCommand||!this.updatePositionUniformStore||!this.currentPositionFbo||this.currentPositionFbo.destroyed||!this.previousPositionTexture||this.previousPositionTexture.destroyed||!this.velocityTexture||this.velocityTexture.destroyed||!this.pinnedStatusTexture||this.pinnedStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed)return;this.updatePositionUniformStore.setUniforms({updatePositionUniforms:{friction:this.config.simulationFriction,spaceSize:this.store.adjustedSpaceSize}}),this.updatePositionCommand.setBindings({positionsTexture:this.previousPositionTexture,velocity:this.velocityTexture,pinnedStatusTexture:this.pinnedStatusTexture,exitTexture:this.exitTexture});const t=this.device.beginRenderPass({framebuffer:this.currentPositionFbo});this.updatePositionCommand.draw(t),t.end(),this.markPositionsChanged()}drag(){var i;if(!this.dragPointCommand||!this.dragPointUniformStore||!this.currentPositionFbo||this.currentPositionFbo.destroyed||!this.previousPositionTexture||this.previousPositionTexture.destroyed)return;this.dragPointUniformStore.setUniforms({dragPointUniforms:{mousePos:ie(this.store.mousePosition,[0,0]),index:((i=this.store.hoveredPoint)==null?void 0:i.index)??-1}}),this.dragPointCommand.setBindings({positionsTexture:this.previousPositionTexture});const t=this.device.beginRenderPass({framebuffer:this.currentPositionFbo});this.dragPointCommand.draw(t),t.end(),this.markPositionsChanged()}setPointPositionsByIndices(t,i){var l,c;const{store:{pointsTextureSize:n},data:r}=this;if(!n||r.pointsNumber===void 0||!this.currentPositionTexture||this.currentPositionTexture.destroyed)return;const s=[this.currentPositionTexture];if(((l=this.transition)==null?void 0:l.isActiveFor(le.Positions))||((c=this.transition)==null?void 0:c.isPendingFor(le.Positions)))for(const u of[this.sourcePositionTexture,this.targetPositionTexture])u&&!u.destroyed&&s.push(u);const a=new Float32Array(4);for(let u=0,d=t.length;u<d;u+=1){const h=t[u];if(!(!Number.isInteger(h)||h<0||h>=r.pointsNumber)&&!(r.pointPositions&&De(r.pointPositions,h))){a[0]=i[u*2],a[1]=i[u*2+1],a[2]=h;for(const p of s)p.copyImageData({data:a,x:h%n,y:Math.floor(h/n),width:1,height:1,bytesPerRow:q("rgba32float",1),mipLevel:0})}}this.markPositionsChanged(),this.areClusterCentroidsUpToDate=!1}setPointPinnedStatus(t,i){const{store:{pointsTextureSize:n},data:r}=this;if(!(!n||r.pointsNumber===void 0)&&!(t<0||t>=r.pointsNumber)){if(!this.pinnedStatusTexture||this.pinnedStatusTexture.destroyed||this.pinnedStatusTexture.width!==n||this.pinnedStatusTexture.height!==n){this.updatePinnedStatus();return}this.pinnedStatusTexture.copyImageData({data:new Float32Array([i?1:0,0,0,0]),x:t%n,y:Math.floor(t/n),width:1,height:1,bytesPerRow:q("rgba32float",1),mipLevel:0})}}async readPositionPixelsAsync(){const{device:t,store:{pointsTextureSize:i},data:{pointsNumber:n}}=this;if(!i||!this.currentPositionFbo||this.currentPositionFbo.destroyed)return;const r=i*i*4*4,s=t.createBuffer({byteLength:r,usage:B.COPY_DST|B.MAP_READ});try{const o=t.createCommandEncoder();if(o.copyTextureToBuffer({sourceTexture:this.currentPositionFbo,width:i,height:i,destinationBuffer:s}),t.submit(o.finish()),await this.waitForGpu(),this.store.pointsTextureSize!==i||this.data.pointsNumber!==n||!this.currentPositionFbo||this.currentPositionFbo.destroyed)return;const a=await s.readAsync();return new Float32Array(a.buffer,a.byteOffset,r/4)}finally{s.destroy()}}findPointsInRect(){var i,n;if(!this.findPointsInRectCommand||!this.findPointsInRectUniformStore||!this.searchFbo||this.searchFbo.destroyed||!this.currentPositionTexture||this.currentPositionTexture.destroyed||(this.isSizeTextureStale&&this.updateSizeTexture(),!this.sizeTexture||this.sizeTexture.destroyed)||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return!1;this.findPointsInRectUniformStore.setUniforms({findPointsInRectUniforms:{spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),sizeScale:this.config.pointSizeScale,transformationMatrix:this.store.transformationMatrix4x4,ratio:this.config.pixelRatio,rect0:ie((i=this.store.searchArea)==null?void 0:i[0],[0,0]),rect1:ie((n=this.store.searchArea)==null?void 0:n[1],[0,0]),scalePointsOnZoom:this.config.scalePointsOnZoom?1:0,maxPointSize:this.store.maxPointSize}}),this.findPointsInRectCommand.setBindings({positionsTexture:this.currentPositionTexture,pointSize:this.sizeTexture,exitTexture:this.exitTexture});const t=this.device.beginRenderPass({framebuffer:this.searchFbo});return this.findPointsInRectCommand.draw(t),t.end(),!0}findPointsInPolygon(){if(!this.findPointsInPolygonCommand||!this.findPointsInPolygonUniformStore||!this.searchFbo||this.searchFbo.destroyed||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.polygonPathTexture||this.polygonPathTexture.destroyed||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return!1;this.findPointsInPolygonUniformStore.setUniforms({findPointsInPolygonUniforms:{spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0]),transformationMatrix:this.store.transformationMatrix4x4,polygonPathLength:this.polygonPathLength}}),this.findPointsInPolygonCommand.setBindings({positionsTexture:this.currentPositionTexture,polygonPathTexture:this.polygonPathTexture,exitTexture:this.exitTexture});const t=this.device.beginRenderPass({framebuffer:this.searchFbo});return this.findPointsInPolygonCommand.draw(t),t.end(),!0}updatePolygonPath(t){const{device:i}=this;if(this.polygonPathLength=t.length,t.length===0){this.polygonPathTexture&&!this.polygonPathTexture.destroyed&&this.polygonPathTexture.destroy(),this.polygonPathTexture=void 0;return}const n=Math.ceil(Math.sqrt(t.length)),r=new Float32Array(n*n*4);for(const[s,o]of t.entries()){const[a,l]=o;r[s*4]=a,r[s*4+1]=l,r[s*4+2]=0,r[s*4+3]=0}!this.polygonPathTexture||this.polygonPathTexture.width!==n||this.polygonPathTexture.height!==n?(this.polygonPathTexture&&!this.polygonPathTexture.destroyed&&this.polygonPathTexture.destroy(),this.polygonPathTexture=i.createTexture({width:n,height:n,format:"rgba32float"}),this.polygonPathTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0})):this.polygonPathTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0})}updatePickingBuffer(){if(!this.isPickingBufferStale||!this.ensurePickingBuffer()||!this.pickingFbo||this.pickingFbo.destroyed||!this.fillPickingBufferCommand||!this.fillPickingBufferUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||(this.pointStatusTexture||this.updatePointStatus(),!this.pointStatusTexture||this.pointStatusTexture.destroyed)||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return;this.fillPickingBufferCommand.setVertexCount(this.data.pointsNumber??0),this.fillPickingBufferCommand.setAttributes({...this.hoveredPointIndices&&{pointIndices:this.hoveredPointIndices},...this.targetSizeBuffer&&{size:this.targetSizeBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer}});const t=ie(this.store.screenSize,[0,0]),i={ratio:this.config.pixelRatio,sizeScale:this.config.pointSizeScale,pointsTextureSize:this.store.pointsTextureSize??0,transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:t,scalePointsOnZoom:this.config.scalePointsOnZoom?1:0,pickingPixelRatio:t[0]>0?this.pickingFbo.width/t[0]:ko,maxPointSize:this.store.maxPointSize,pointDefaultSize:this.config.pointDefaultSize,hasImages:this.imageCount>0?1:0,imageCount:this.imageCount},n={positionsTexture:this.currentPositionTexture,pointStatus:this.pointStatusTexture,exitTexture:this.exitTexture},r=this.device.beginRenderPass({framebuffer:this.pickingFbo,clearColor:[-1,0,0,0],clearDepth:1});this.config.highlightedPointIndices!==void 0?(this.fillPickingBufferUniformStore.setUniforms({fillPickingBufferUniforms:{...i,skipHighlighted:1,skipGreyed:0}}),this.fillPickingBufferCommand.setBindings(n),this.fillPickingBufferCommand.draw(r),this.fillPickingBufferUniformStore.setUniforms({fillPickingBufferUniforms:{...i,skipHighlighted:0,skipGreyed:1}}),this.fillPickingBufferCommand.setBindings(n),this.fillPickingBufferCommand.draw(r)):(this.fillPickingBufferUniformStore.setUniforms({fillPickingBufferUniforms:{...i,skipHighlighted:0,skipGreyed:0}}),this.fillPickingBufferCommand.setBindings(n),this.fillPickingBufferCommand.draw(r)),r.end(),this.isPickingBufferStale=!1}pickPointSync(){this.updatePickingBuffer();const t=this.getCursorPickingWindow();if(!t||!this.pickingFbo||this.pickingFbo.destroyed)return;const i=we(this.device,this.pickingFbo,t.x,t.y,Fe,Fe);return Wu(i,t.centerX-t.x,t.centerY-t.y)}requestPickPoint(){var r;if((r=this.pickingReadback)!=null&&r.inFlight)return!1;if(this.updatePickingBuffer(),!this.pickingFbo||this.pickingFbo.destroyed)return!0;const t=this.device.gl,i=this.pickingFbo.handle;if(!t||!i)return!0;this.pickingReadback||(this.pickingReadback=new dr(t,Fe*Fe*4));const n=this.getCursorPickingWindow();return n?this.pickingReadback.issue(i,n.x,n.y,Fe,Fe)?(this.issuedPickingWindow=n,!0):!1:!0}discardPendingPick(){var t;(t=this.pickingReadback)==null||t.cancel(),this.issuedPickingWindow=void 0}takePickResult(){if(!this.pickingReadback||!this.issuedPickingWindow)return;const t=this.pickingReadback.poll();if(!t)return;const i=this.issuedPickingWindow;return this.issuedPickingWindow=void 0,Wu(t,i.centerX-i.x,i.centerY-i.y)??null}requestTrackedPositionsReadback(){for(const t of this.trackers)t.requestReadback()}resolveTrackedPositionsReadback(){for(const t of this.trackers)t.resolveReadback()}getSampledPointPositionsMap(){const t=new Map;if(!this.sampledPointsFbo||this.sampledPointsFbo.destroyed)return t;if(this.fillSampledPointsFboCommand&&this.fillSampledPointsUniformStore&&this.sampledPointsFbo){if(!this.currentPositionTexture||this.currentPositionTexture.destroyed||(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed))return t;this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber??0),this.fillSampledPointsUniformStore.setUniforms({fillSampledPointsUniforms:{pointsTextureSize:this.store.pointsTextureSize??0,transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0])}}),this.fillSampledPointsFboCommand.setBindings({positionsTexture:this.currentPositionTexture,exitTexture:this.exitTexture});const n=this.device.beginRenderPass({framebuffer:this.sampledPointsFbo,clearColor:[0,0,0,0]});this.fillSampledPointsFboCommand.draw(n),n.end()}const i=we(this.device,this.sampledPointsFbo);for(let n=0;n<i.length/4;n++){const r=i[n*4],s=!!i[n*4+1],o=i[n*4+2],a=i[n*4+3];s&&r!==void 0&&o!==void 0&&a!==void 0&&t.set(r,[o,a])}return t}getSampledPoints(){const t=[],i=[];if(!this.sampledPointsFbo||this.sampledPointsFbo.destroyed)return{indices:t,positions:i};if(this.fillSampledPointsFboCommand&&this.fillSampledPointsUniformStore&&this.sampledPointsFbo){if(!this.currentPositionTexture||this.currentPositionTexture.destroyed)return{indices:t,positions:i};if(this.exitTexture||this.updateExit(),!this.exitTexture||this.exitTexture.destroyed)return{indices:t,positions:i};this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber??0),this.fillSampledPointsUniformStore.setUniforms({fillSampledPointsUniforms:{pointsTextureSize:this.store.pointsTextureSize??0,transformationMatrix:this.store.transformationMatrix4x4,spaceSize:this.store.adjustedSpaceSize,screenSize:ie(this.store.screenSize,[0,0])}}),this.fillSampledPointsFboCommand.setBindings({positionsTexture:this.currentPositionTexture,exitTexture:this.exitTexture});const r=this.device.beginRenderPass({framebuffer:this.sampledPointsFbo,clearColor:[0,0,0,0]});this.fillSampledPointsFboCommand.draw(r),r.end()}const n=we(this.device,this.sampledPointsFbo);for(let r=0;r<n.length/4;r++){const s=n[r*4],o=!!n[r*4+1],a=n[r*4+2],l=n[r*4+3];o&&s!==void 0&&a!==void 0&&l!==void 0&&(t.push(s),i.push(a,l))}return{indices:t,positions:i}}destroy(){var t,i,n,r,s,o,a,l,c,u,d,h,p,g,x,T,S,P,I,y,v,E;(t=this.drawCommand)==null||t.destroy(),(i=this.drawPickingCommand)==null||i.destroy(),this.drawPickingCommand=void 0,this.drawCommand=void 0,(n=this.drawCoreCommand)==null||n.destroy(),this.drawCoreCommand=void 0,this.isOcclusionCullingActive=!1,(r=this.drawHighlightedCommand)==null||r.destroy(),this.drawHighlightedCommand=void 0,(s=this.interpolatePositionCommand)==null||s.destroy(),this.interpolatePositionCommand=void 0,(o=this.updatePositionCommand)==null||o.destroy(),this.updatePositionCommand=void 0,(a=this.dragPointCommand)==null||a.destroy(),this.dragPointCommand=void 0,(l=this.findPointsInRectCommand)==null||l.destroy(),this.findPointsInRectCommand=void 0,(c=this.findPointsInPolygonCommand)==null||c.destroy(),this.findPointsInPolygonCommand=void 0,(u=this.fillPickingBufferCommand)==null||u.destroy(),this.fillPickingBufferCommand=void 0,(d=this.fillSampledPointsFboCommand)==null||d.destroy(),this.fillSampledPointsFboCommand=void 0,(h=this.trackPointsCommand)==null||h.destroy(),this.trackPointsCommand=void 0,(p=this.pickingReadback)==null||p.destroy(),this.pickingReadback=void 0;for(const R of this.trackers)R.release();this.trackers.clear(),this.issuedPickingWindow=void 0,this.currentPositionFbo&&!this.currentPositionFbo.destroyed&&this.currentPositionFbo.destroy(),this.currentPositionFbo=void 0,this.previousPositionFbo&&!this.previousPositionFbo.destroyed&&this.previousPositionFbo.destroy(),this.previousPositionFbo=void 0,this.sourcePositionFbo&&!this.sourcePositionFbo.destroyed&&this.sourcePositionFbo.destroy(),this.sourcePositionFbo=void 0,this.targetPositionFbo&&!this.targetPositionFbo.destroyed&&this.targetPositionFbo.destroy(),this.targetPositionFbo=void 0,this.velocityFbo&&!this.velocityFbo.destroyed&&this.velocityFbo.destroy(),this.velocityFbo=void 0,this.searchFbo&&!this.searchFbo.destroyed&&this.searchFbo.destroy(),this.searchFbo=void 0,this.pickingFbo&&!this.pickingFbo.destroyed&&this.pickingFbo.destroy(),this.pickingFbo=void 0,this.sampledPointsFbo&&!this.sampledPointsFbo.destroyed&&this.sampledPointsFbo.destroy(),this.sampledPointsFbo=void 0,this.currentPositionTexture&&!this.currentPositionTexture.destroyed&&this.currentPositionTexture.destroy(),this.currentPositionTexture=void 0,this.previousPositionTexture&&!this.previousPositionTexture.destroyed&&this.previousPositionTexture.destroy(),this.previousPositionTexture=void 0,this.sourcePositionTexture&&!this.sourcePositionTexture.destroyed&&this.sourcePositionTexture.destroy(),this.sourcePositionTexture=void 0,this.targetPositionTexture&&!this.targetPositionTexture.destroyed&&this.targetPositionTexture.destroy(),this.targetPositionTexture=void 0,this.velocityTexture&&!this.velocityTexture.destroyed&&this.velocityTexture.destroy(),this.velocityTexture=void 0,this.searchTexture&&!this.searchTexture.destroyed&&this.searchTexture.destroy(),this.searchTexture=void 0,this.pickingTexture&&!this.pickingTexture.destroyed&&this.pickingTexture.destroy(),this.pickingTexture=void 0,this.pointStatusTexture&&!this.pointStatusTexture.destroyed&&this.pointStatusTexture.destroy(),this.pointStatusTexture=void 0,this.pointColorsTexture&&!this.pointColorsTexture.destroyed&&this.pointColorsTexture.destroy(),this.pointColorsTexture=void 0,this.sizeTexture&&!this.sizeTexture.destroyed&&this.sizeTexture.destroy(),this.sizeTexture=void 0,this.isSizeTextureStale=!0,this.polygonPathTexture&&!this.polygonPathTexture.destroyed&&this.polygonPathTexture.destroy(),this.polygonPathTexture=void 0,this.imageAtlasTexture&&!this.imageAtlasTexture.destroyed&&this.imageAtlasTexture.destroy(),this.imageAtlasTexture=void 0,this.imageAtlasCoordsTexture&&!this.imageAtlasCoordsTexture.destroyed&&this.imageAtlasCoordsTexture.destroy(),this.imageAtlasCoordsTexture=void 0,this.pinnedStatusTexture&&!this.pinnedStatusTexture.destroyed&&this.pinnedStatusTexture.destroy(),this.pinnedStatusTexture=void 0,this.exitTexture&&!this.exitTexture.destroyed&&this.exitTexture.destroy(),this.exitTexture=void 0,this.hasAnyAbsentPoint=!1,(g=this.interpolatePositionUniformStore)==null||g.destroy(),this.interpolatePositionUniformStore=void 0,(x=this.updatePositionUniformStore)==null||x.destroy(),this.updatePositionUniformStore=void 0,(T=this.dragPointUniformStore)==null||T.destroy(),this.dragPointUniformStore=void 0,(S=this.drawUniformStore)==null||S.destroy(),this.drawUniformStore=void 0,(P=this.findPointsInRectUniformStore)==null||P.destroy(),this.findPointsInRectUniformStore=void 0,(I=this.findPointsInPolygonUniformStore)==null||I.destroy(),this.findPointsInPolygonUniformStore=void 0,(y=this.fillPickingBufferUniformStore)==null||y.destroy(),this.fillPickingBufferUniformStore=void 0,(v=this.fillSampledPointsUniformStore)==null||v.destroy(),this.fillSampledPointsUniformStore=void 0,(E=this.drawHighlightedUniformStore)==null||E.destroy(),this.drawHighlightedUniformStore=void 0,this.sourceColorBuffer&&!this.sourceColorBuffer.destroyed&&this.sourceColorBuffer.destroy(),this.sourceColorBuffer=void 0,this.targetColorBuffer&&!this.targetColorBuffer.destroyed&&this.targetColorBuffer.destroy(),this.targetColorBuffer=void 0,this.previousColorData=void 0,this.sourceSizeBuffer&&!this.sourceSizeBuffer.destroyed&&this.sourceSizeBuffer.destroy(),this.sourceSizeBuffer=void 0,this.targetSizeBuffer&&!this.targetSizeBuffer.destroyed&&this.targetSizeBuffer.destroy(),this.targetSizeBuffer=void 0,this.previousSizeData=void 0,this.sourceSizeData=void 0,this.previousExitData=void 0,this.shapeBuffer&&!this.shapeBuffer.destroyed&&this.shapeBuffer.destroy(),this.shapeBuffer=void 0,this.imageIndicesBuffer&&!this.imageIndicesBuffer.destroyed&&this.imageIndicesBuffer.destroy(),this.imageIndicesBuffer=void 0,this.imageSizesBuffer&&!this.imageSizesBuffer.destroyed&&this.imageSizesBuffer.destroy(),this.imageSizesBuffer=void 0,this.drawPointIndices&&!this.drawPointIndices.destroyed&&this.drawPointIndices.destroy(),this.drawPointIndices=void 0,this.reversedPointIndexBuffer&&!this.reversedPointIndexBuffer.destroyed&&this.reversedPointIndexBuffer.destroy(),this.reversedPointIndexBuffer=void 0,this.hoveredPointIndices&&!this.hoveredPointIndices.destroyed&&this.hoveredPointIndices.destroy(),this.hoveredPointIndices=void 0,this.sampledPointIndices&&!this.sampledPointIndices.destroyed&&this.sampledPointIndices.destroy(),this.sampledPointIndices=void 0,this.updatePositionVertexCoordBuffer&&!this.updatePositionVertexCoordBuffer.destroyed&&this.updatePositionVertexCoordBuffer.destroy(),this.updatePositionVertexCoordBuffer=void 0,this.interpolatePositionVertexCoordBuffer&&!this.interpolatePositionVertexCoordBuffer.destroyed&&this.interpolatePositionVertexCoordBuffer.destroy(),this.interpolatePositionVertexCoordBuffer=void 0,this.dragPointVertexCoordBuffer&&!this.dragPointVertexCoordBuffer.destroyed&&this.dragPointVertexCoordBuffer.destroy(),this.dragPointVertexCoordBuffer=void 0,this.findPointsInRectVertexCoordBuffer&&!this.findPointsInRectVertexCoordBuffer.destroyed&&this.findPointsInRectVertexCoordBuffer.destroy(),this.findPointsInRectVertexCoordBuffer=void 0,this.findPointsInPolygonVertexCoordBuffer&&!this.findPointsInPolygonVertexCoordBuffer.destroyed&&this.findPointsInPolygonVertexCoordBuffer.destroy(),this.findPointsInPolygonVertexCoordBuffer=void 0,this.drawHighlightedVertexCoordBuffer&&!this.drawHighlightedVertexCoordBuffer.destroyed&&this.drawHighlightedVertexCoordBuffer.destroy(),this.drawHighlightedVertexCoordBuffer=void 0,this.trackPointsVertexCoordBuffer&&!this.trackPointsVertexCoordBuffer.destroyed&&this.trackPointsVertexCoordBuffer.destroy(),this.trackPointsVertexCoordBuffer=void 0}ensureSimulationResources(){const{store:{pointsTextureSize:t},device:i}=this;if(!t)return;this.ensureUpdatePositionProgram();const n=new Float32Array(t*t*4).fill(0);!this.velocityTexture||this.velocityTexture.width!==t||this.velocityTexture.height!==t?(this.velocityFbo&&!this.velocityFbo.destroyed&&this.velocityFbo.destroy(),this.velocityTexture&&!this.velocityTexture.destroyed&&this.velocityTexture.destroy(),this.velocityTexture=i.createTexture({width:t,height:t,format:"rgba32float"}),this.velocityTexture.copyImageData({data:n,bytesPerRow:q("rgba32float",t),mipLevel:0,x:0,y:0}),this.velocityFbo=i.createFramebuffer({width:t,height:t,colorAttachments:[this.velocityTexture]})):this.velocityTexture.copyImageData({data:n,bytesPerRow:q("rgba32float",t),mipLevel:0,x:0,y:0})}createTransitionResources(){const{store:{pointsTextureSize:t},device:i}=this;if(!t)return;const n=new Float32Array(t*t*4).fill(0),r=M.SAMPLE|M.RENDER|M.COPY_SRC|M.COPY_DST;(!this.sourcePositionTexture||this.sourcePositionTexture.width!==t||this.sourcePositionTexture.height!==t)&&(this.sourcePositionFbo&&!this.sourcePositionFbo.destroyed&&this.sourcePositionFbo.destroy(),this.sourcePositionTexture&&!this.sourcePositionTexture.destroyed&&this.sourcePositionTexture.destroy(),this.sourcePositionTexture=i.createTexture({width:t,height:t,format:"rgba32float",usage:r}),this.sourcePositionFbo=i.createFramebuffer({width:t,height:t,colorAttachments:[this.sourcePositionTexture]})),this.sourcePositionTexture.copyImageData({data:n,bytesPerRow:q("rgba32float",t),mipLevel:0,x:0,y:0}),(!this.targetPositionTexture||this.targetPositionTexture.width!==t||this.targetPositionTexture.height!==t)&&(this.targetPositionFbo&&!this.targetPositionFbo.destroyed&&this.targetPositionFbo.destroy(),this.targetPositionTexture&&!this.targetPositionTexture.destroyed&&this.targetPositionTexture.destroy(),this.targetPositionTexture=i.createTexture({width:t,height:t,format:"rgba32float",usage:r}),this.targetPositionFbo=i.createFramebuffer({width:t,height:t,colorAttachments:[this.targetPositionTexture]})),this.targetPositionTexture.copyImageData({data:n,bytesPerRow:q("rgba32float",t),mipLevel:0,x:0,y:0}),this.interpolatePositionVertexCoordBuffer||(this.interpolatePositionVertexCoordBuffer=i.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.interpolatePositionUniformStore||(this.interpolatePositionUniformStore=new oe(i,{interpolatePositionUniforms:{uniformTypes:{progress:"f32"},defaultUniforms:{progress:0}}})),this.interpolatePositionCommand||(this.interpolatePositionCommand=new ee(i,{fs:wv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.interpolatePositionVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{interpolatePositionUniforms:this.interpolatePositionUniformStore.getManagedUniformBuffer("interpolatePositionUniforms")},parameters:te}))}destroyTransitionResources(){var t,i;(t=this.interpolatePositionCommand)==null||t.destroy(),this.interpolatePositionCommand=void 0,(i=this.interpolatePositionUniformStore)==null||i.destroy(),this.interpolatePositionUniformStore=void 0,this.interpolatePositionVertexCoordBuffer&&!this.interpolatePositionVertexCoordBuffer.destroyed&&this.interpolatePositionVertexCoordBuffer.destroy(),this.interpolatePositionVertexCoordBuffer=void 0,this.sourcePositionFbo&&!this.sourcePositionFbo.destroyed&&this.sourcePositionFbo.destroy(),this.sourcePositionFbo=void 0,this.sourcePositionTexture&&!this.sourcePositionTexture.destroyed&&this.sourcePositionTexture.destroy(),this.sourcePositionTexture=void 0,this.targetPositionFbo&&!this.targetPositionFbo.destroyed&&this.targetPositionFbo.destroy(),this.targetPositionFbo=void 0,this.targetPositionTexture&&!this.targetPositionTexture.destroyed&&this.targetPositionTexture.destroy(),this.targetPositionTexture=void 0}interpolatePosition(t){if(!this.interpolatePositionCommand||!this.interpolatePositionUniformStore||!this.sourcePositionTexture||this.sourcePositionTexture.destroyed||!this.targetPositionTexture||this.targetPositionTexture.destroyed||!this.currentPositionFbo||this.currentPositionFbo.destroyed)return;this.interpolatePositionUniformStore.setUniforms({interpolatePositionUniforms:{progress:t}}),this.interpolatePositionCommand.setBindings({sourceTexture:this.sourcePositionTexture,targetTexture:this.targetPositionTexture});const i=this.device.beginRenderPass({framebuffer:this.currentPositionFbo});this.interpolatePositionCommand.draw(i),i.end(),this.markPositionsChanged(),this.areClusterCentroidsUpToDate=!1}destroySimulationResources(){var t,i;(t=this.updatePositionCommand)==null||t.destroy(),this.updatePositionCommand=void 0,(i=this.updatePositionUniformStore)==null||i.destroy(),this.updatePositionUniformStore=void 0,this.updatePositionVertexCoordBuffer&&!this.updatePositionVertexCoordBuffer.destroyed&&this.updatePositionVertexCoordBuffer.destroy(),this.updatePositionVertexCoordBuffer=void 0,this.velocityFbo&&!this.velocityFbo.destroyed&&this.velocityFbo.destroy(),this.velocityFbo=void 0,this.velocityTexture&&!this.velocityTexture.destroyed&&this.velocityTexture.destroy(),this.velocityTexture=void 0}swapFbo(){if(!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.previousPositionTexture||this.previousPositionTexture.destroyed||!this.currentPositionFbo||this.currentPositionFbo.destroyed||!this.previousPositionFbo||this.previousPositionFbo.destroyed)return;const t=this.previousPositionTexture,i=this.previousPositionFbo;this.previousPositionTexture=this.currentPositionTexture,this.previousPositionFbo=this.currentPositionFbo,this.currentPositionTexture=t,this.currentPositionFbo=i,this.areClusterCentroidsUpToDate=!1,this.positionVersion++}markFootprintsStale(){this.isPickingBufferStale=!0,this.isSizeTextureStale=!0}updateSizeTexture(){const{device:t,store:{pointsTextureSize:i},data:n}=this;if(!i||n.pointsNumber===void 0)return;const r=new Float32Array(i*i*4);for(let s=0;s<n.pointsNumber;s++)r[s*4]=n.getResolvedPointFootprint(s);(!this.sizeTexture||this.sizeTexture.width!==i||this.sizeTexture.height!==i)&&(this.sizeTexture&&!this.sizeTexture.destroyed&&this.sizeTexture.destroy(),this.sizeTexture=t.createTexture({width:i,height:i,format:"rgba32float"})),this.sizeTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",i),mipLevel:0,x:0,y:0}),this.isSizeTextureStale=!1}markPositionsChanged(){this.positionVersion++}drawPointRing(t,i,n){const{config:r,store:s}=this;!this.drawHighlightedCommand||!this.drawHighlightedUniformStore||!this.currentPositionTexture||this.currentPositionTexture.destroyed||!this.pointStatusTexture||this.pointStatusTexture.destroyed||!this.exitTexture||this.exitTexture.destroyed||(this.drawHighlightedUniformStore.setUniforms({drawHighlightedUniforms:{...this.getRingSizeUniforms(i),transformationMatrix:s.transformationMatrix4x4,pointsTextureSize:s.pointsTextureSize??0,sizeScale:r.pointSizeScale,spaceSize:s.adjustedSpaceSize,screenSize:ie(s.screenSize,[0,0]),scalePointsOnZoom:r.scalePointsOnZoom?1:0,pointIndex:i,maxPointSize:s.maxPointSize,color:ge(n,[0,0,0,1]),universalPointOpacity:r.pointOpacity,greyoutOpacity:r.pointGreyoutOpacity??-1,isDarkenGreyout:s.isDarkenGreyout??!1?1:0,backgroundColor:ge(s.backgroundColor,[0,0,0,1]),greyoutColor:ge(s.greyoutPointColor,[0,0,0,1]),animatePositions:this.shouldAnimatePointPositions?1:0,transitionProgress:this.transitionProgress,animateSizes:this.shouldAnimatePointSizes?1:0,pointDefaultSize:r.pointDefaultSize,width:.85,pixelRatio:r.pixelRatio}}),this.drawHighlightedCommand.setBindings({positionsTexture:this.currentPositionTexture,pointStatus:this.pointStatusTexture,exitTexture:this.exitTexture}),this.drawHighlightedCommand.draw(t))}getRingSizeUniforms(t){var r,s,o;const{data:i}=this,n=((r=i.pointSizes)==null?void 0:r[t])??NaN;return{sourceSize:((s=this.sourceSizeData)==null?void 0:s[t])??n,targetSize:n,imageSize:i.pointDrawsImage(t)?((o=i.pointImageSizes)==null?void 0:o[t])??0:0}}ensurePositionTextures(t){(!this.currentPositionTexture||this.currentPositionTexture.width!==t||this.currentPositionTexture.height!==t)&&(this.currentPositionTexture&&!this.currentPositionTexture.destroyed&&this.currentPositionTexture.destroy(),this.currentPositionFbo&&!this.currentPositionFbo.destroyed&&this.currentPositionFbo.destroy(),this.currentPositionTexture=this.device.createTexture({width:t,height:t,format:"rgba32float"}),this.currentPositionFbo=this.device.createFramebuffer({width:t,height:t,colorAttachments:[this.currentPositionTexture]})),(!this.previousPositionTexture||this.previousPositionTexture.width!==t||this.previousPositionTexture.height!==t)&&(this.previousPositionTexture&&!this.previousPositionTexture.destroyed&&this.previousPositionTexture.destroy(),this.previousPositionFbo&&!this.previousPositionFbo.destroyed&&this.previousPositionFbo.destroy(),this.previousPositionTexture=this.device.createTexture({width:t,height:t,format:"rgba32float"}),this.previousPositionFbo=this.device.createFramebuffer({width:t,height:t,colorAttachments:[this.previousPositionTexture]}))}async waitForGpu(t=1e3){const i=this.device.createFence();let n;try{await Promise.race([i.signaled,new Promise(r=>{n=setTimeout(r,t)})])}finally{clearTimeout(n),i.destroy()}}writePositionTexture(t,i,n){t.copyImageData({data:i,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0})}ensurePickingBuffer(){var a;const{device:t,store:i}=this,[n,r]=i.screenSize;if(!n||!r)return!1;const{width:s,height:o}=W_(n,r);return this.pickingTexture&&!this.pickingTexture.destroyed&&this.pickingTexture.width===s&&this.pickingTexture.height===o||((a=this.pickingReadback)==null||a.cancel(),this.issuedPickingWindow=void 0,this.pickingFbo&&!this.pickingFbo.destroyed&&this.pickingFbo.destroy(),this.pickingTexture&&!this.pickingTexture.destroyed&&this.pickingTexture.destroy(),this.pickingTexture=t.createTexture({width:s,height:o,format:"rgba32float",usage:M.SAMPLE|M.RENDER}),this.pickingFbo=t.createFramebuffer({width:s,height:o,colorAttachments:[this.pickingTexture],depthStencilAttachment:"depth16unorm"}),this.isPickingBufferStale=!0),!0}getCursorPickingWindow(){if(!this.pickingFbo||this.pickingFbo.destroyed)return;const[t,i]=this.store.screenSize;if(!(!t||!i))return V_(this.pickingFbo.width,this.pickingFbo.height,this.store.screenMousePosition[0],this.store.screenMousePosition[1],t,i)}ensureUpdatePositionProgram(){const{device:t,config:i,store:n}=this;this.updatePositionVertexCoordBuffer||(this.updatePositionVertexCoordBuffer=t.createBuffer({data:new Float32Array([-1,-1,1,-1,-1,1,1,1])})),this.updatePositionUniformStore||(this.updatePositionUniformStore=new oe(t,{updatePositionUniforms:{uniformTypes:{friction:"f32",spaceSize:"f32"},defaultUniforms:{friction:i.simulationFriction,spaceSize:n.adjustedSpaceSize}}})),this.updatePositionCommand||(this.updatePositionCommand=new ee(t,{fs:Rv,vs:Ee,topology:"triangle-strip",vertexCount:4,attributes:{vertexCoord:this.updatePositionVertexCoordBuffer},bufferLayout:[{name:"vertexCoord",format:"float32x2"}],defines:{USE_UNIFORM_BUFFERS:!0},bindings:{updatePositionUniforms:this.updatePositionUniformStore.getManagedUniformBuffer("updatePositionUniforms")},parameters:te}))}rescaleInitialNodePositions(){const{config:{spaceSize:t}}=this;if(!this.data.pointPositions||!t)return;const i=this.data.pointPositions,n=i.length/2;let r=1/0,s=-1/0,o=1/0,a=-1/0;for(let S=0;S<i.length;S+=2){const P=i[S],I=i[S+1];De(i,S/2)||(r=Math.min(r,P),s=Math.max(s,P),o=Math.min(o,I),a=Math.max(a,I))}if(!Number.isFinite(r)){this.scaleX=void 0,this.scaleY=void 0;return}const l=s-r,c=a-o,u=Math.max(l,c);if(u===0){const S=t/2;this.scaleX=P=>P-r+S,this.scaleY=P=>P-o+S;for(let P=0;P<n;P++)De(i,P)||(this.data.pointPositions[P*2]=this.scaleX(i[P*2]),this.data.pointPositions[P*2+1]=this.scaleY(i[P*2+1]));return}if(u>t){this.scaleX=void 0,this.scaleY=void 0;return}const d=t*t*.001,h=n>d?t*Math.max(1.2,Math.sqrt(n)/t):t*.1,p=h/u,g=(t-h)/2,x=(u-l)/2*p+g,T=(u-c)/2*p+g;this.scaleX=S=>(S-r)*p+x,this.scaleY=S=>(S-o)*p+T;for(let S=0;S<n;S++)De(i,S)||(this.data.pointPositions[S*2]=this.scaleX(i[S*2]),this.data.pointPositions[S*2+1]=this.scaleY(i[S*2+1]))}updateReversedPointIndexBuffer(){var o,a;const{device:t,data:i}=this,n=i.pointsNumber??0;if(n===0)return;const r=n*4;if(((o=this.reversedPointIndexBuffer)==null?void 0:o.byteLength)===r)return;const s=new Uint32Array(n);for(let l=0;l<n;l++)s[l]=n-1-l;this.reversedPointIndexBuffer&&!this.reversedPointIndexBuffer.destroyed&&this.reversedPointIndexBuffer.destroy(),this.reversedPointIndexBuffer=t.createBuffer({data:s,usage:B.INDEX|B.COPY_DST}),(a=this.drawCoreCommand)==null||a.setIndexBuffer(this.reversedPointIndexBuffer)}getDrawUniforms(){const{data:t,config:i,store:n}=this,r={ratio:i.pixelRatio,transformationMatrix:n.transformationMatrix4x4,pointsTextureSize:n.pointsTextureSize??0,sizeScale:i.pointSizeScale,spaceSize:n.adjustedSpaceSize,screenSize:ie(n.screenSize,[0,0]),greyoutColor:ge(n.greyoutPointColor,[-1,-1,-1,-1]),backgroundColor:ge(n.backgroundColor,[0,0,0,1]),scalePointsOnZoom:i.scalePointsOnZoom?1:0,maxPointSize:n.maxPointSize,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,hasImages:this.imageCount>0?1:0,imageCount:this.imageCount,imageAtlasCoordsTextureSize:this.imageAtlasCoordsTextureSize??0,transitionProgress:this.transitionProgress,animateColors:this.shouldAnimatePointColors?1:0,animateSizes:this.shouldAnimatePointSizes?1:0,animatePositions:this.shouldAnimatePointPositions?1:0,pointDefaultColor:ge(t.defaultRgba,[0,0,0,1]),pointDefaultSize:i.pointDefaultSize,pointsNumber:t.pointsNumber},s={greyoutOpacity:i.pointGreyoutOpacity??-1,pointOpacity:i.pointOpacity,isDarkenGreyout:n.isDarkenGreyout??!1?1:0,backgroundColor:ge(n.backgroundColor,[0,0,0,1]),outlineColor:ge(n.outlinedPointRingColor,[1,1,1,1]),outlineWidth:.9,renderMode:0};return{vertex:r,fragment:s}}getDrawTextureBindings(){return{positionsTexture:this.currentPositionTexture,pointStatus:this.pointStatusTexture,exitTexture:this.exitTexture,imageAtlasTexture:this.imageAtlasTexture,imageAtlasCoords:this.imageAtlasCoordsTexture}}getDrawCommandAttributes(){return{...this.drawPointIndices&&{pointIndices:this.drawPointIndices},...this.sourceSizeBuffer&&{sourceSize:this.sourceSizeBuffer},...this.targetSizeBuffer&&{targetSize:this.targetSizeBuffer},...this.sourceColorBuffer&&{sourceColor:this.sourceColorBuffer},...this.targetColorBuffer&&{targetColor:this.targetColorBuffer},...this.shapeBuffer&&{shape:this.shapeBuffer},...this.imageIndicesBuffer&&{imageIndex:this.imageIndicesBuffer},...this.imageSizesBuffer&&{imageSize:this.imageSizesBuffer}}}}class Ov{constructor(t){this.isDestroyed=!1,this.gatheredVersion=-1,this.cachedVersion=-1,this.cachedPointList=-1,this.issuedVersion=-1,this.issuedPointList=-1,this.isReadbackWanted=!1,this.indices=[...t]}get hasPendingReadback(){var t;return((t=this.readback)==null?void 0:t.inFlight)??!1}positions(t){var s,o;const{host:i}=this;if(!i||!this.indices.length)return new Map;this.resolveReadback();const n=i.positionVersion,r=i.pointListVersion;return this.cached&&this.cachedVersion===n&&this.cachedPointList===r?this.cached:t!=null&&t.nonBlocking&&this.cached?(this.cachedPointList!==r&&this.dropGonePoints(),this.isReadbackWanted=!0,this.issuedVersion!==n&&!(((s=i.requestTick)==null?void 0:s.call(i))??!1)&&this.requestReadback(),this.cached):!this.positionsFbo||this.positionsFbo.destroyed?new Map:(this.isReadbackWanted=!1,(o=this.readback)==null||o.cancel(),this.gather(),this.cached=this.buildMap(we(i.device,this.positionsFbo)),this.cachedVersion=n,this.cachedPointList=r,this.issuedVersion=n,this.cached)}positionsArray(){const{host:t,indices:i}=this;if(!t||!i.length||!this.positionsFbo||this.positionsFbo.destroyed)return[];const n=new Array(i.length*2);this.gather();const r=we(t.device,this.positionsFbo);for(let s=0,o=i.length;s<o;s+=1){const a=i[s],l=!t.data.isPointIndex(a)||t.data.pointPositions!==void 0&&De(t.data.pointPositions,a);n[s*2]=l?NaN:r[s*4],n[s*2+1]=l?NaN:r[s*4+1]}return n}setIndices(t){var i;this.indices=[...t],this.cached=void 0,this.cachedVersion=-1,this.issuedVersion=-1,this.isReadbackWanted=!1,(i=this.readback)==null||i.destroy(),this.readback=void 0,this.allocate()}destroy(){if(this.isDestroyed)return;this.isDestroyed=!0;const{host:t}=this;this.release(),t==null||t.removeTracker(this)}attach(t){return this.isDestroyed?!1:(this.host=t,this.allocate(),!0)}release(){var t;(t=this.readback)==null||t.destroy(),this.readback=void 0,this.positionsFbo&&!this.positionsFbo.destroyed&&this.positionsFbo.destroy(),this.positionsFbo=void 0,this.indicesTexture&&!this.indicesTexture.destroyed&&this.indicesTexture.destroy(),this.indicesTexture=void 0,this.cached=void 0,this.host=void 0}gather(){const{host:t}=this;!t||!this.indices.length||this.gatheredVersion!==t.positionVersion&&(!this.indicesTexture||this.indicesTexture.destroyed||!this.positionsFbo||this.positionsFbo.destroyed||t.gatherTrackedPositions(this.indicesTexture,this.positionsFbo)&&(this.gatheredVersion=t.positionVersion))}requestReadback(){const{host:t}=this;if(!t||!this.isReadbackWanted||!this.indices.length)return;const i=t.positionVersion;if(this.issuedVersion===i||!this.positionsFbo||this.positionsFbo.destroyed)return;const n=t.device.gl,r=this.positionsFbo.handle;if(!n||!r)return;this.gather();const{width:s,height:o}=this.positionsFbo;this.readback||(this.readback=new dr(n,s*o*4)),this.readback.issue(r,0,0,s,o)&&(this.issuedVersion=i,this.issuedPointList=t.pointListVersion,this.isReadbackWanted=!1)}resolveReadback(){var n;const{host:t}=this;if(!t||!((n=this.readback)!=null&&n.inFlight))return;if(this.issuedPointList!==t.pointListVersion){this.readback.cancel(),this.issuedVersion=-1,this.isReadbackWanted=!0;return}const i=this.readback.poll();i?(this.cached=this.buildMap(i),this.cachedVersion=this.issuedVersion,this.cachedPointList=this.issuedPointList):this.readback.inFlight||(this.issuedVersion=-1)}allocate(){const{host:t,indices:i}=this;if(!t||!i.length)return;const n=Math.ceil(Math.sqrt(i.length)),r=new Float32Array(n*n*4).fill(-1);for(const[s,o]of i.entries())r[s*4]=o;(!this.indicesTexture||this.indicesTexture.destroyed||this.indicesTexture.width!==n)&&(this.indicesTexture&&!this.indicesTexture.destroyed&&this.indicesTexture.destroy(),this.indicesTexture=t.device.createTexture({width:n,height:n,format:"rgba32float"})),this.indicesTexture.copyImageData({data:r,bytesPerRow:q("rgba32float",n),mipLevel:0,x:0,y:0}),(!this.positionsFbo||this.positionsFbo.destroyed||this.positionsFbo.width!==n)&&(this.positionsFbo&&!this.positionsFbo.destroyed&&this.positionsFbo.destroy(),this.positionsFbo=t.device.createFramebuffer({width:n,height:n,colorAttachments:["rgba32float"]})),this.gatheredVersion=-1,this.gather()}dropGonePoints(){const{host:t,cached:i}=this;if(!t||!i)return;const n=new Map;for(const[r,s]of i)t.data.isPointIndex(r)&&(t.data.pointPositions&&De(t.data.pointPositions,r)||n.set(r,s));this.cached=n,this.cachedPointList=t.pointListVersion}buildMap(t){const{host:i,indices:n}=this,r=new Map;if(!i)return r;for(let s=0,o=n.length;s<o;s+=1){const a=n[s],l=t[s*4],c=t[s*4+1];l===void 0||c===void 0||i.data.isPointIndex(a)&&(i.data.pointPositions&&De(i.data.pointPositions,a)||r.set(a,[l,c]))}return r}}class Rd{constructor(t,i,n){if(this.isReady=!1,this.isPointPositionsUpdateNeeded=!1,this.isPointSizeUpdateNeeded=!1,this.isForceManyBodyUpdateNeeded=!1,this.isForceLinkUpdateNeeded=!1,this.isForceCenterUpdateNeeded=!1,this.isPointClusterUpdateNeeded=!1,this.isForceCollisionReady=!1,this._isDestroyed=!1,n?this.config=n:(this.config=zs(),t&&Bi(this.config,t)),this.store=new Hx,this.data=new Xx(this.config),i)this.deviceInitPromise=i,this.shouldDestroyDevice=!1;else{const s=document.createElement("canvas");this.deviceInitPromise=this.createDevice(s),this.shouldDestroyDevice=!0}const r=this.deviceInitPromise.then(s=>{var o;return this._isDestroyed?(this.shouldDestroyDevice&&((o=s.canvasContext)==null||o.destroy(),s.destroy()),s):(this._device=s,this.store.adjustSpaceSize(this.config.spaceSize,s.limits.maxTextureDimension2D),this.store.setWebGLMaxTextureSize(s.limits.maxTextureDimension2D),this.store.maxPointSize=Fs(s,this.config.pixelRatio),this.store.isSimulationRunning=this.config.enableSimulation,this.points=new Bv(s,this.config,this.store,this.data),this.points.withHostState=a=>this.withExternalDeviceState(a),this.config.enableSimulation&&this.ensureSimulationModules(),this.clusters=new Sv(s,this.config,this.store,this.data,this.points),this.config.randomSeed!==void 0&&this.store.addRandomSeed(this.config.randomSeed),this.isReady=!0,s)}).catch(s=>{throw this._device=void 0,this.isReady=!1,console.error("Device initialization failed:",s),s});this.ready=r.then(()=>{})}get device(){return this._device}get ownsDevice(){return this.shouldDestroyDevice}get progress(){return this._isDestroyed?0:this.store.simulationProgress}get isSimulationRunning(){return this._isDestroyed?!1:this.store.isSimulationRunning}get hasPendingCentroidReadback(){var t;return((t=this.clusters)==null?void 0:t.hasPendingCentroidReadback)??!1}setConfig(t){var n,r;if(this._isDestroyed||this.ensureDevice(()=>this.setConfig(t)))return;const i={...this.config};Bi(this.config,t,!0),this.applyEnableSimulationConfigChange(i),i.pointDefaultSize!==this.config.pointDefaultSize&&(this.data.updatePointSize(),(n=this.points)==null||n.updateSize()),(i.simulationCollisionRadius!==this.config.simulationCollisionRadius||i.simulationCollisionPadding!==this.config.simulationCollisionPadding||(this.config.simulationCollisionRadius===void 0||this.config.simulationCollisionRadius===0)&&i.pointDefaultSize!==this.config.pointDefaultSize)&&(this.isForceCollisionReady=!1),i.spaceSize!==this.config.spaceSize&&(this.store.adjustSpaceSize(this.config.spaceSize,((r=this._device)==null?void 0:r.limits.maxTextureDimension2D)??4096),this.isForceCollisionReady=!1,this.update(this.store.isSimulationRunning?this.store.alpha:0))}setPointPositions(t,i){this._isDestroyed||this.ensureDevice(()=>this.setPointPositions(t,i))||(this.data.inputPointPositions=t,this.points&&(this.points.shouldSkipRescale=i),this.isPointPositionsUpdateNeeded=!0,this.isPointSizeUpdateNeeded=!0,this.isPointClusterUpdateNeeded=!0,this.isForceManyBodyUpdateNeeded=!0,this.isForceLinkUpdateNeeded=!0,this.isForceCenterUpdateNeeded=!0)}setPointSizes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointSizes(t))||(this.data.inputPointSizes=t,this.isPointSizeUpdateNeeded=!0)}setLinks(t){this._isDestroyed||this.ensureDevice(()=>this.setLinks(t))||(this.data.inputLinks=t,this.isForceLinkUpdateNeeded=!0)}setLinkStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkStrength(t))||(this.data.inputLinkStrength=t,this.isForceLinkUpdateNeeded=!0)}setPointClusters(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusters(t))||(this.data.inputPointClusters=t,this.isPointClusterUpdateNeeded=!0)}setClusterPositions(t){this._isDestroyed||this.ensureDevice(()=>this.setClusterPositions(t))||(this.data.inputClusterPositions=t,this.isPointClusterUpdateNeeded=!0)}setPointClusterStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusterStrength(t))||(this.data.inputClusterStrength=t,this.isPointClusterUpdateNeeded=!0)}setPinnedPoints(t){var r;if(this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoints(t)))return;const i=t==null?void 0:t.filter(s=>Number.isInteger(s)&&s>=0),n=i&&i.length>0?[...new Set(i)]:void 0;this.data.inputPinnedPoints=n,(r=this.points)==null||r.updatePinnedStatus()}setPinnedPoint(t,i){var r;if(this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoint(t,i))||!Number.isInteger(t)||t<0)return;const n=new Set(this.data.inputPinnedPoints);i?n.add(t):n.delete(t),this.data.inputPinnedPoints=n.size>0?[...n]:void 0,(r=this.points)==null||r.setPointPinnedStatus(t,i)}isPointPinned(t){var i;return this._isDestroyed?!1:((i=this.data.inputPinnedPoints)==null?void 0:i.includes(t))??!1}setPointPosition(t,i,n){this.setPointPositionsByIndices([t],[i,n])}setPointPositionsByIndices(t,i){if(this._isDestroyed||this.ensureDevice(()=>this.setPointPositionsByIndices(t,i)))return;if(t.length*2!==i.length){console.warn(`setPointPositionsByIndices: expected ${t.length*2} coordinates for ${t.length} indices, got ${i.length}. Call ignored.`);return}const n=this.points;n&&this.withExternalDeviceState(()=>{n.setPointPositionsByIndices(t,i),n.gatherTrackers()})}applyData(t){this._isDestroyed||this.ensureDevice(()=>this.applyData(t))||(this.data.update(),this.update(t))}start(t=1){var n,r;if(this._isDestroyed||this.ensureDevice(()=>this.start(t))||!this.config.enableSimulation||!this.data.pointsNumber)return;const i=this.store.isSimulationRunning;this.store.isSimulationRunning=!0,this.store.simulationProgress=0,this.store.alpha=t,i||(r=(n=this.config).onSimulationStart)==null||r.call(n)}stop(){var i,n;if(this._isDestroyed||this.ensureDevice(()=>this.stop()))return;const t=this.store.isSimulationRunning||this.store.alpha>0||this.store.simulationProgress>0;this.store.isSimulationRunning=!1,this.store.simulationProgress=0,this.store.alpha=0,t&&((n=(i=this.config).onSimulationEnd)==null||n.call(i))}pause(){var t,i;this._isDestroyed||this.ensureDevice(()=>this.pause())||this.store.isSimulationRunning&&(this.store.isSimulationRunning=!1,(i=(t=this.config).onSimulationPause)==null||i.call(t))}unpause(){var t,i;this._isDestroyed||this.ensureDevice(()=>this.unpause())||this.config.enableSimulation&&(this.store.isSimulationRunning||(this.store.isSimulationRunning=!0,(i=(t=this.config).onSimulationUnpause)==null||i.call(t)))}step(){this._isDestroyed||this.ensureDevice(()=>this.step())||this.config.enableSimulation&&this.store.pointsTextureSize&&(this.runSimulationStep(!0),this.store.alpha<Qt&&this.store.isSimulationRunning&&this.end())}getPointPositions(){return Array.from(this.getPointPositionsArray())}getPointPositionsArray(t){if(this._isDestroyed||!this._device||!this.points)return new Float32Array(0);if(this.data.pointsNumber===void 0||!this.points.currentPositionFbo)return new Float32Array(0);const i=we(this._device,this.points.currentPositionFbo);return this.composePointPositions(i,t)}async getPointPositionsAsync(t){if(this._isDestroyed||!this._device||!this.points)return new Float32Array(0);if(this.data.pointsNumber===void 0)return new Float32Array(0);const i=await this.points.readPositionPixelsAsync();return!i||this._isDestroyed?new Float32Array(0):this.composePointPositions(i,t)}getPointPositionTexture(){if(this._isDestroyed||!this.points)return;const t=this.points.currentPositionTexture;if(!(!t||t.destroyed||!this.store.pointsTextureSize))return{texture:t,pointCount:this.data.pointsNumber??0,textureSize:this.store.pointsTextureSize,version:this.points.positionVersion}}trackPoints(t){const i=new Ov(t);if(this._isDestroyed)return i;const n=()=>{var r;return(r=this.points)==null?void 0:r.addTracker(i)};return this.isReady?n():this.ensureDevice(n),i}getClusterPositions(t){if(this._isDestroyed||!this._device||!this.clusters)return[];if(this.data.pointClusters===void 0||this.clusters.clusterCount===void 0)return[];const i=this.clusters;return this.withExternalDeviceState(()=>{var r,s;t!=null&&t.nonBlocking&&i.resolveCentroidReadback();const n=i.getCentroidPositions(t==null?void 0:t.nonBlocking);return t!=null&&t.nonBlocking&&i.needsCentroidReadback&&!(((s=(r=this.points)==null?void 0:r.requestTick)==null?void 0:s.call(r))??!1)&&i.requestCentroidReadback(),n})}collectReadbacks(){var t,i;(t=this.points)==null||t.resolveTrackedPositionsReadback(),(i=this.clusters)==null||i.resolveCentroidReadback()}issueReadbacks(){var t,i;(t=this.points)==null||t.requestTrackedPositionsReadback(),(i=this.clusters)==null||i.requestCentroidReadback()}destroy(){var t,i,n,r;this._isDestroyed||(this._isDestroyed=!0,this.isReady=!1,(t=this.points)==null||t.destroy(),(i=this.clusters)==null||i.destroy(),this.destroySimulationModules(),(n=this.forceMouse)==null||n.destroy(),this.forceMouse=void 0,this._device&&this.shouldDestroyDevice&&(this._device.beginRenderPass({clearColor:this.store.backgroundColor,clearDepth:1,clearStencil:0}).end(),this._device.submit(),(r=this._device.canvasContext)==null||r.destroy(),this._device.destroy()))}updateTextureSizes(){this.store.pointsTextureSize=Math.ceil(Math.sqrt(this.data.pointsNumber??0)),this.store.linksTextureSize=Math.ceil(Math.sqrt((this.data.linksNumber??0)*2))}applyDataUpdates(){var i,n,r,s,o;const t=this.isPointPositionsUpdateNeeded;return this.points?(this.isPointPositionsUpdateNeeded&&this.points.updatePositions(),this.isPointSizeUpdateNeeded&&this.points.updateSize(),this.isForceManyBodyUpdateNeeded&&((i=this.forceManyBody)==null||i.create()),(this.isForceManyBodyUpdateNeeded||this.isPointSizeUpdateNeeded)&&(this.isForceCollisionReady=!1),this.isForceLinkUpdateNeeded&&((n=this.forceLinkIncoming)==null||n.create(jo.INCOMING),(r=this.forceLinkOutgoing)==null||r.create(jo.OUTGOING)),this.isForceCenterUpdateNeeded&&((s=this.forceCenter)==null||s.create()),this.isPointClusterUpdateNeeded&&((o=this.clusters)==null||o.create()),this.isPointPositionsUpdateNeeded=!1,this.isPointSizeUpdateNeeded=!1,this.isForceManyBodyUpdateNeeded=!1,this.isForceLinkUpdateNeeded=!1,this.isForceCenterUpdateNeeded=!1,this.isPointClusterUpdateNeeded=!1,{positionsUpdated:t}):{positionsUpdated:!1}}initPrograms(){var t,i,n,r,s,o;this._isDestroyed||!this.points||!this.clusters||(this.points.initPrograms(),(t=this.forceGravity)==null||t.initPrograms(),(i=this.forceManyBody)==null||i.initPrograms(),(n=this.forceCenter)==null||n.initPrograms(),(r=this.forceLinkIncoming)==null||r.initPrograms(),(s=this.forceLinkOutgoing)==null||s.initPrograms(),(o=this.forceMouse)==null||o.initPrograms(),this.clusters.initPrograms())}runSimulationStep(t=!1,i){return this.config.enableSimulation?this.withExternalDeviceState(()=>this.runStepPasses(t,i)):!1}end(){var t,i;this.store.isSimulationRunning=!1,this.store.simulationProgress=1,(i=(t=this.config).onSimulationEnd)==null||i.call(t)}withExternalDeviceState(t){const i=this._device;if(this.shouldDestroyDevice||!i)return t();const n=i.gl,r=n?Pt.get(n):void 0,s=(r==null?void 0:r.stateStack.length)??0;try{return i.withParametersWebGL({blend:!1,depthTest:!1,depthMask:!0,scissorTest:!1,stencilTest:!1,cull:!1,colorMask:[!0,!0,!0,!0],nocatch:!0},t)}finally{if(r)for(;r.stateStack.length>s;)r.pop()}}ensureSimulationModules(){!this._device||!this.points||(this.forceGravity||(this.forceGravity=new ev(this._device,this.config,this.store,this.data,this.points)),this.forceCenter||(this.forceCenter=new KT(this._device,this.config,this.store,this.data,this.points)),this.forceManyBody||(this.forceManyBody=new hv(this._device,this.config,this.store,this.data,this.points)),this.forceLinkIncoming||(this.forceLinkIncoming=new Td(this._device,this.config,this.store,this.data,this.points)),this.forceLinkOutgoing||(this.forceLinkOutgoing=new Td(this._device,this.config,this.store,this.data,this.points)),this.forceMouse||(this.forceMouse=new pv(this._device,this.config,this.store,this.data,this.points)),this.forceCollision||(this.forceCollision=new QT(this._device,this.config,this.store,this.data,this.points)))}destroySimulationModules(){var t,i,n,r,s,o,a,l;(t=this.forceGravity)==null||t.destroy(),this.forceGravity=void 0,(i=this.forceCenter)==null||i.destroy(),this.forceCenter=void 0,(n=this.forceManyBody)==null||n.destroy(),this.forceManyBody=void 0,(r=this.forceLinkIncoming)==null||r.destroy(),this.forceLinkIncoming=void 0,(s=this.forceLinkOutgoing)==null||s.destroy(),this.forceLinkOutgoing=void 0,(o=this.forceMouse)==null||o.destroy(),this.forceMouse=void 0,(a=this.forceCollision)==null||a.destroy(),this.forceCollision=void 0,this.isForceCollisionReady=!1,(l=this.points)==null||l.destroySimulationResources()}markForcesDirty(){this.isForceManyBodyUpdateNeeded=!0,this.isForceLinkUpdateNeeded=!0,this.isForceCenterUpdateNeeded=!0}invalidateCollisionResources(){this.isForceCollisionReady=!1}runStepPasses(t,i){var l,c,u,d,h,p,g,x,T,S,P,I,y,v,E,R,D,z,$,F,Q,X,b,N,A,O,V,L,Y,J,H;const{config:{simulationGravity:n,simulationCenter:r,simulationCollision:s},store:{isSimulationRunning:o}}=this;i!=null&&i.applyMouseRepulsion&&((l=this.points)==null||l.swapFbo(),(c=this.forceMouse)==null||c.run(),(u=this.points)==null||u.updatePosition());const a=t||o&&!(i!=null&&i.blockedByInteraction);return a&&(n&&((d=this.points)==null||d.swapFbo(),(h=this.forceGravity)==null||h.run(),(p=this.points)==null||p.updatePosition()),r&&((g=this.points)==null||g.swapFbo(),(x=this.forceCenter)==null||x.run(),(T=this.points)==null||T.updatePosition()),(S=this.points)==null||S.swapFbo(),(P=this.forceManyBody)==null||P.run(),(I=this.points)==null||I.updatePosition(),this.store.linksTextureSize&&((y=this.points)==null||y.swapFbo(),(v=this.forceLinkIncoming)==null||v.run(),(E=this.points)==null||E.updatePosition(),(R=this.points)==null||R.swapFbo(),(D=this.forceLinkOutgoing)==null||D.run(),(z=this.points)==null||z.updatePosition()),(this.data.pointClusters||this.data.clusterPositions)&&(($=this.points)==null||$.swapFbo(),(F=this.clusters)==null||F.run(),(Q=this.points)==null||Q.updatePosition()),s&&(this.isForceCollisionReady||((X=this.forceCollision)==null||X.create(),(b=this.forceCollision)==null||b.initPrograms(),this.isForceCollisionReady=!0),(N=this.points)==null||N.swapFbo(),(A=this.forceCollision)==null||A.run(),(O=this.points)==null||O.updatePosition()),this.store.alpha+=this.store.addAlpha(this.config.simulationDecay),i!=null&&i.applyMouseRepulsion&&(this.store.alpha=Math.max(this.store.alpha,.1)),this.store.simulationProgress=Math.sqrt(Math.min(1,Qt/this.store.alpha)),(J=(Y=this.config).onSimulationTick)==null||J.call(Y,this.store.alpha,(V=this.store.hoveredPoint)==null?void 0:V.index,(L=this.store.hoveredPoint)==null?void 0:L.position)),(H=this.points)==null||H.gatherTrackers(),a}applyEnableSimulationConfigChange(t){var n,r,s,o,a;if(t.enableSimulation===this.config.enableSimulation)return;if(this.config.enableSimulation){this.ensureSimulationModules(),(n=this.points)==null||n.ensureSimulationResources(),this.markForcesDirty(),this.applyDataUpdates(),this.initPrograms(),this.store.simulationProgress=0,this.store.alpha=1,this.store.isSimulationRunning=!0,(s=(r=this.config).onSimulationStart)==null||s.call(r);return}const i=this.store.isSimulationRunning||this.store.alpha>0||this.store.simulationProgress>0;this.store.isSimulationRunning=!1,this.store.alpha=0,this.store.simulationProgress=0,i&&((a=(o=this.config).onSimulationEnd)==null||a.call(o)),this.destroySimulationModules()}update(t=this.store.alpha){this.updateTextureSizes(),this.applyDataUpdates(),this.initPrograms(),this.store.alpha=t}ensureDevice(t){return this.isReady?!1:(this.ready.then(()=>{this._isDestroyed||t()}).catch(i=>{console.error("Device initialization failed",i)}),!0)}async createDevice(t){return await ZS.createDevice({type:"webgl",adapters:[db],webgl:{antialias:!1},createCanvasContext:{canvas:t,useDevicePixels:this.config.pixelRatio,autoResize:!0,width:void 0,height:void 0}})}composePointPositions(t,i){const n=this.data.pointsNumber??0,r=i&&i.length>=n*2?i:new Float32Array(n*2);for(let s=0;s<n;s+=1){if(this.data.pointPositions&&De(this.data.pointPositions,s)){r[s*2]=NaN,r[s*2+1]=NaN;continue}r[s*2]=t[s*4+0],r[s*2+1]=t[s*4+1]}return r}}const Uv=500,wd=10;class zv{constructor(t,i,n){this.config=zs(),this.isReady=!1,this.requestAnimationFrameId=0,this._shouldSyncScreenSize=!1,this.isRightClickMouse=!1,this._longPressStartX=0,this._longPressStartY=0,this._shouldSuppressNextClick=!1,this._instanceId=ac(),this._findHoveredItemExecutionCount=0,this._isPointerOnCanvas=!1,this._lastMouseX=0,this._lastMouseY=0,this._lastCheckedMouseX=0,this._lastCheckedMouseY=0,this._shouldForceHoverDetection=!1,this._lastPickingMatrix=[],this._isFirstRenderAfterInit=!0,this.isPointColorUpdateNeeded=!1,this.isPointShapeUpdateNeeded=!1,this.isPointImageIndicesUpdateNeeded=!1,this.isLinksUpdateNeeded=!1,this.isLinkColorUpdateNeeded=!1,this.isLinkWidthUpdateNeeded=!1,this.isLinkArrowUpdateNeeded=!1,this.isLinkStyleUpdateNeeded=!1,this.isPointImageSizesUpdateNeeded=!1,this._isDestroyed=!1,i&&Bi(this.config,i),this._isHeadless=!t,this.simulation=new Rd(void 0,n,this.config),this.store=this.simulation.store,this.graph=this.simulation.data,this.zoomInstance=new X_(this.store,this.config),this.transition=new jx(this.config),this.dragInstance=new Y_(this.store,this.config,this.transition);const r=this.simulation.ready.then(async()=>{const s=this.simulation.device;if(!(this._isDestroyed||!s)){if(this.device=s,!this._isHeadless){const o=this.validateDevice(s);n&&o.setProps({useDevicePixels:this.config.pixelRatio}),this.store.div=t;const a=o.canvas;if(a.parentNode!==this.store.div&&(a.parentNode&&a.parentNode.removeChild(a),this.store.div.appendChild(a)),this.addAttribution(),a.style.width="100%",a.style.height="100%",this.canvas=a,this.updateCanvasTouchAction(),await Promise.race([o.initialized,new Promise(l=>{setTimeout(l,500)})]),this._isDestroyed)return;typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{this._shouldSyncScreenSize=!0,this.requestRender()}),this.resizeObserver.observe(this.canvas))}this._isHeadless||this.initInteractions(),this.points=this.simulation.points,this.points&&(this.points.transition=this.transition),this.points&&(this.points.requestTick=()=>this._isHeadless||!this.config.enableRenderLoop?!1:(this.requestRender(),!0)),this.lines=new $_(s,this.config,this.store,this.graph,this.points),this.store.backgroundColor=We(this.config.backgroundColor),this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor),this.store.setFocusedPointRingColor(this.config.focusedPointRingColor),this.config.focusedPointIndex!==void 0&&this.store.setFocusedPoint(this.config.focusedPointIndex),this.store.setGreyoutPointColor(this.config.pointGreyoutColor),this.store.setOutlinedPointRingColor(this.config.outlinedPointRingColor),this.store.setHighlightedPointSet(this.config.highlightedPointIndices),this.store.setOutlinedPointSet(this.config.outlinedPointIndices),this.store.setHoveredLinkColor(this.config.hoveredLinkColor),this.store.updateLinkHoveringEnabled(this.config),!this._isHeadless&&this.config.showFPSMonitor&&(this.fpsMonitor=new pc(this.canvas,this.store.div)),this.isReady=!0,this.setZoomLevel(this.config.initialZoomLevel??1)}}).catch(s=>{throw this.device=void 0,this.isReady=!1,console.error("Device initialization failed:",s),s});this.ready=r.then(()=>{})}get progress(){return this._isDestroyed?0:this.store.simulationProgress}get isSimulationRunning(){return this._isDestroyed?!1:this.store.isSimulationRunning}get maxPointSize(){return this._isDestroyed?0:this.store.maxPointSize}setConfig(t){if(this._isDestroyed||this.ensureDevice(()=>this.setConfig(t)))return;const i={...this.config};Kx(this.config),Bi(this.config,t),this.preserveInitOnlyFields(i),this.updateStateFromConfig(i)}setConfigPartial(t){if(this._isDestroyed||this.ensureDevice(()=>this.setConfigPartial(t)))return;const i={...this.config};Bi(this.config,t,!0),this.preserveInitOnlyFields(i),this.updateStateFromConfig(i)}setPointPositions(t,i){var r;if(this._isDestroyed||this.ensureDevice(()=>this.setPointPositions(t,i)))return;this.simulation.setPointPositions(t,i);const n=(r=this.points)==null?void 0:r.currentPositionTexture;n&&!n.destroyed&&this.transition.queue(le.Positions),this.isLinksUpdateNeeded=!0,this.isPointColorUpdateNeeded=!0,this.isPointShapeUpdateNeeded=!0,this.isPointImageIndicesUpdateNeeded=!0,this.isPointImageSizesUpdateNeeded=!0}setPointColors(t){this._isDestroyed||this.ensureDevice(()=>this.setPointColors(t))||(this.graph.inputPointColors=t,this.isPointColorUpdateNeeded=!0,this.transition.queue(le.PointColors))}getPointColors(){if(this._isDestroyed)return new Float32Array;if(this.graph.pointColors===void 0||this.graph.pointsNumber===void 0)return new Float32Array;const t=new Float32Array(this.graph.pointsNumber*4);for(let i=0;i<this.graph.pointsNumber;i++)for(let n=0;n<4;n++)t[i*4+n]=this.graph.getResolvedPointColorChannel(i,n);return t}setPointSizes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointSizes(t))||(this.simulation.setPointSizes(t),this.isPointImageSizesUpdateNeeded=!0,this.transition.queue(le.PointSizes))}setPointShapes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointShapes(t))||(this.graph.inputPointShapes=t,this.isPointShapeUpdateNeeded=!0)}setImageData(t){var n;if(this._isDestroyed||this.ensureDevice(()=>this.setImageData(t)))return;const i=this.graph.inputImageData;this.graph.inputImageData=t,((n=this.points)==null?void 0:n.createAtlas())===!1&&(this.graph.inputImageData=i),this.requestRender()}setPointImageIndices(t){this._isDestroyed||this.ensureDevice(()=>this.setPointImageIndices(t))||(this.graph.inputPointImageIndices=t,this.isPointImageIndicesUpdateNeeded=!0)}setPointImageSizes(t){this._isDestroyed||this.ensureDevice(()=>this.setPointImageSizes(t))||(this.graph.inputPointImageSizes=t,this.isPointImageSizesUpdateNeeded=!0)}getPointSizes(){if(this._isDestroyed)return new Float32Array;if(this.graph.pointSizes===void 0||this.graph.pointsNumber===void 0)return new Float32Array;const t=new Float32Array(this.graph.pointsNumber);for(let i=0;i<this.graph.pointsNumber;i++)t[i]=this.graph.getResolvedPointSize(i);return t}setLinks(t){this._isDestroyed||this.ensureDevice(()=>this.setLinks(t))||(this.simulation.setLinks(t),this.isLinksUpdateNeeded=!0,this.isLinkColorUpdateNeeded=!0,this.isLinkWidthUpdateNeeded=!0,this.isLinkArrowUpdateNeeded=!0,this.isLinkStyleUpdateNeeded=!0)}setLinkColors(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkColors(t))||(this.graph.inputLinkColors=t,this.isLinkColorUpdateNeeded=!0,this.transition.queue(le.LinkColors))}getLinkColors(){return this._isDestroyed?new Float32Array:this.graph.linkColors??new Float32Array}setLinkWidths(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkWidths(t))||(this.graph.inputLinkWidths=t,this.isLinkWidthUpdateNeeded=!0,this.transition.queue(le.LinkWidths))}getLinkWidths(){return this._isDestroyed?new Float32Array:this.graph.linkWidths??new Float32Array}getLinkWidthByIndex(t){var n;if(this._isDestroyed)return;const i=(n=this.graph.linkWidths)==null?void 0:n[t];if(i!==void 0)return this.lines&&this.transition.isActiveFor(le.LinkWidths)?this.lines.getAnimatedWidth(t,this.transition.progress):i}setLinkArrows(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkArrows(t))||(this.graph.linkArrowsBoolean=t,this.isLinkArrowUpdateNeeded=!0)}setLinkStyles(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkStyles(t))||(this.graph.inputLinkStyles=t,this.isLinkStyleUpdateNeeded=!0)}getLinkStyles(){return this._isDestroyed?new Float32Array:this.graph.linkStyles??new Float32Array}setLinkStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setLinkStrength(t))||this.simulation.setLinkStrength(t)}setPointClusters(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusters(t))||this.simulation.setPointClusters(t)}setClusterPositions(t){this._isDestroyed||this.ensureDevice(()=>this.setClusterPositions(t))||this.simulation.setClusterPositions(t)}setPointClusterStrength(t){this._isDestroyed||this.ensureDevice(()=>this.setPointClusterStrength(t))||this.simulation.setPointClusterStrength(t)}setPinnedPoints(t){this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoints(t))||(this.simulation.setPinnedPoints(t),this.requestRender())}setPinnedPoint(t,i){this._isDestroyed||this.ensureDevice(()=>this.setPinnedPoint(t,i))||(this.simulation.setPinnedPoint(t,i),this.requestRender())}isPointPinned(t){return this._isDestroyed?!1:this.simulation.isPointPinned(t)}setPointPosition(t,i,n){this.setPointPositionsByIndices([t],[i,n])}setPointPositionsByIndices(t,i){this._isDestroyed||this.ensureDevice(()=>this.setPointPositionsByIndices(t,i))||(this.simulation.setPointPositionsByIndices(t,i),this.markPickingBuffersStale(),this.requestRender())}render(t,i){var d,h,p;if(this._isDestroyed||this.ensureDevice(()=>this.render(t,i)))return;this.graph.update();const{fitViewOnInit:n,fitViewDelay:r,fitViewPadding:s,fitViewDuration:o,fitViewByPointsInRect:a,fitViewByPointIndices:l,initialZoomLevel:c}=this.config;if(!this.graph.pointsNumber&&!this.graph.linksNumber){this.stopFrames(),this._isHeadless||(ye(this.canvas).style("cursor",null),this.device&&(this.device.beginRenderPass({clearColor:this.store.backgroundColor,clearDepth:1,clearStencil:0}).end(),this.device.submit()));return}!this._isHeadless&&this._isFirstRenderAfterInit&&n&&c===void 0&&(this._fitViewOnInitTimeoutID=window.setTimeout(()=>{l?this.fitViewByPointIndices(l,o,s):a?this.setZoomTransformByPointPositions(new Float32Array(this.flatten(a)),o,void 0,s):this.fitView(o,s)},r)),this.transition.setDurationOverride(this._isHeadless?0:i),this.update(t),this.transition.isPendingFor(le.Positions)&&this.store.isSimulationRunning&&this.transition.duration>0&&!this._isFirstRenderAfterInit&&(this.store.isSimulationRunning=!1,(h=(d=this.config).onSimulationPause)==null||h.call(d));const u=(p=this.points)==null?void 0:p.currentPositionTexture;this.transition.isPending&&(!u||u.destroyed)&&this.transition.abort(),this.transition.start(),this._shouldForceHoverDetection=!0,this.requestRender(),this._isFirstRenderAfterInit=!1}zoomToPointByIndex(t,i=700,n=3,r=!0,s=!0){if(this._isDestroyed||this.ensureDevice(()=>this.zoomToPointByIndex(t,i,n,r,s))||!this.device||!this.points||!this.canvasD3Selection)return;const o=this.graph.pointPositions;if(!o||De(o,t))return;const{store:{screenSize:a}}=this,l=we(this.device,this.points.currentPositionFbo);if(t===void 0)return;const c=l[t*4+0],u=l[t*4+1];if(c===void 0||u===void 0)return;const d=this.zoomInstance.getDistanceToPoint([c,u]),h=r?n:Math.max(this.getZoomLevel(),n);if(d<Math.min(a[0],a[1]))this.setZoomTransformByPointPositions(new Float32Array([c,u]),i,h,void 0,s);else{this.zoomInstance.shouldEnableSimulationDuringZoomOverride=s;const p=this.zoomInstance.getTransform([c,u],h),g=this.zoomInstance.getMiddlePointTransform([c,u]);this.canvasD3Selection.transition().ease(Ja).duration(i/2).call(this.zoomInstance.behavior.transform,g).transition().ease(el).duration(i/2).call(this.zoomInstance.behavior.transform,p)}}zoom(t,i=0,n=!0){this._isDestroyed||this.setZoomLevel(t,i,n)}setZoomLevel(t,i=0,n=!0){this._isDestroyed||this.ensureDevice(()=>this.setZoomLevel(t,i,n))||this.canvasD3Selection&&(this.zoomInstance.shouldEnableSimulationDuringZoomOverride=n,i===0?this.canvasD3Selection.call(this.zoomInstance.behavior.scaleTo,t):this.canvasD3Selection.transition().duration(i).call(this.zoomInstance.behavior.scaleTo,t))}getZoomLevel(){return this._isDestroyed?0:this.zoomInstance.eventTransform.k}getPointPositions(){return this._isDestroyed?[]:this.simulation.getPointPositions()}getPointPositionsArray(t){return this._isDestroyed?new Float32Array(0):this.simulation.getPointPositionsArray(t)}async getPointPositionsAsync(t){return this._isDestroyed?new Float32Array(0):await this.simulation.getPointPositionsAsync(t)}getPointPositionTexture(){if(!this._isDestroyed)return this.simulation.getPointPositionTexture()}getClusterPositions(t){return this._isDestroyed?[]:this.simulation.getClusterPositions(t)}fitView(t=250,i=.1,n=!0){this._isDestroyed||this.ensureDevice(()=>this.fitView(t,i,n))||this.setZoomTransformByPointPositions(this.getFitViewPositions(),t,void 0,i,n)}fitViewByPointIndices(t,i=250,n=.1,r=!0){if(this._isDestroyed||this.ensureDevice(()=>this.fitViewByPointIndices(t,i,n,r)))return;const s=this.getFitViewPositions(),o=new Float32Array(t.length*2);for(const[a,l]of t.entries())o[a*2]=s[l*2],o[a*2+1]=s[l*2+1];this.setZoomTransformByPointPositions(o,i,void 0,n,r)}fitViewByPointPositions(t,i=250,n=.1,r=!0){this._isDestroyed||this.ensureDevice(()=>this.fitViewByPointPositions(t,i,n,r))||this.setZoomTransformByPointPositions(new Float32Array(t),i,void 0,n,r)}setZoomTransformByPointPositions(t,i=250,n,r=.1,s=!0){var a;if(this._isDestroyed||this.ensureDevice(()=>this.setZoomTransformByPointPositions(t,i,n,r,s)))return;this.zoomInstance.shouldEnableSimulationDuringZoomOverride=s,this.syncScreenSize();const o=this.zoomInstance.getTransform(t,n,r);(a=this.canvasD3Selection)==null||a.transition().ease(tl).duration(i).call(this.zoomInstance.behavior.transform,o)}findPointsInRect(t){if(this._isDestroyed)return[];if(!this.isReady||!this.device||!this.points)return[];const i=this.store.screenSize[1];return this.store.searchArea=[[t[0][0],i-t[1][1]],[t[1][0],i-t[0][1]]],this.points.findPointsInRect()?Ds(we(this.device,this.points.searchFbo),this.graph.pointsNumber):[]}findPointsInPolygon(t){if(this._isDestroyed)return[];if(!this.isReady||!this.device||!this.points)return[];if(t.length<3)return console.warn("Polygon path requires at least 3 points to form a polygon."),[];const i=this.store.screenSize[1],n=t.map(([r,s])=>[r,i-s]);return this.points.updatePolygonPath(n),this.points.findPointsInPolygon()?Ds(we(this.device,this.points.searchFbo),this.graph.pointsNumber):[]}getNeighboringPointIndices(t){return this._isDestroyed?[]:this.graph.getNeighboringPointIndices(t)}getConnectedLinkIndices(t){return this._isDestroyed?[]:this.graph.getConnectedLinkIndices(t)}getConnectedPointIndices(t){return this._isDestroyed?[]:this.graph.getConnectedPointIndices(t)}spaceToScreenPosition(t){return this._isDestroyed?[0,0]:this.zoomInstance.convertSpaceToScreenPosition(t)}screenToSpacePosition(t){return this._isDestroyed?[0,0]:this.zoomInstance.convertScreenToSpacePosition(t)}spaceToScreenRadius(t){return this._isDestroyed?0:this.zoomInstance.convertSpaceToScreenRadius(t)}getPointRadiusByIndex(t){if(this._isDestroyed||this.graph.pointSizes===void 0&&this.graph.pointImageSizes===void 0||!this.graph.isPointIndex(t))return;const i=this.points&&this.transition.isActiveFor(le.PointSizes)?this.points.getAnimatedSize(t,this.transition.progress):void 0;return this.graph.getResolvedPointFootprint(t,i)}trackPointPositionsByIndices(t){if(this._isDestroyed)return;const i=t??[];this.tracker?this.tracker.setIndices(i):this.tracker=this.simulation.trackPoints(i)}getTrackedPointPositionsMap(t){return this._isDestroyed||!this.tracker?new Map:this.tracker.positions(t)}getTrackedPointPositionsArray(){return this._isDestroyed||!this.tracker?[]:this.tracker.positionsArray()}getSampledPointPositionsMap(){return this._isDestroyed||!this.points?new Map:this.points.getSampledPointPositionsMap()}getSampledPoints(){return this._isDestroyed||!this.points?{indices:[],positions:[]}:this.points.getSampledPoints()}getSampledLinkPositionsMap(){return this._isDestroyed||!this.lines?new Map:this.lines.getSampledLinkPositionsMap()}getSampledLinks(){return this._isDestroyed||!this.lines?{indices:[],positions:[],angles:[]}:this.lines.getSampledLinks()}getScaleX(){if(!(this._isDestroyed||!this.points))return this.points.scaleX}getScaleY(){if(!(this._isDestroyed||!this.points))return this.points.scaleY}start(t=1){this._isDestroyed||this.ensureDevice(()=>this.start(t))||this.config.enableSimulation&&this.graph.pointsNumber&&(this.transition.isActiveFor(le.Positions)&&this.transition.end(!0),this.simulation.start(t),this.requestRender())}stop(){this._isDestroyed||this.simulation.stop()}pause(){this._isDestroyed||this.ensureDevice(()=>this.pause())||this.simulation.pause()}unpause(){this._isDestroyed||this.ensureDevice(()=>this.unpause())||this.config.enableSimulation&&(this.store.isSimulationRunning||(this.transition.isActiveFor(le.Positions)&&this.transition.end(!0),this.simulation.unpause(),this.requestRender()))}step(){this._isDestroyed||this.ensureDevice(()=>this.step())||this.config.enableSimulation&&this.store.pointsTextureSize&&(this.runSimulationStep(!0),(this._isHeadless||!this.config.enableRenderLoop)&&this.store.alpha<Qt&&this.store.isSimulationRunning&&this.end(),this.requestRender())}setViewTransform(t,i){this._isDestroyed||this.ensureDevice(()=>this.setViewTransform(t,i))||(i&&this.store.updateScreenSize(i[0],i[1]),this.zoomInstance.applyEventTransform(jt.translate(t.x,t.y).scale(t.k)),this.markPickingBuffersStale(),this.requestRender())}drawToRenderPass(t,i){var r,s,o,a;if(this._isDestroyed||!this.device||!this.store.pointsTextureSize)return;const n=((i==null?void 0:i.links)??!0)&&this.config.renderLinks!==!1&&!!this.store.linksTextureSize&&!!this.graph.linksNumber&&this.graph.linksNumber>0;if(i!=null&&i.picking){const{alpha:l,linkIndexOffset:c=0}=i.picking;n&&((r=this.lines)==null||r.drawPicking(t,l,c)),(i.points??!0)&&((s=this.points)==null||s.drawPicking(t,l));return}n&&((o=this.lines)==null||o.draw(t)),((i==null?void 0:i.points)??!0)&&((a=this.points)==null||a.draw(t))}setHostHoveredPoint(t){this._isDestroyed||(this.store.hostHoveredPointIndex=t,this.requestRender())}setHostHoveredLink(t){this._isDestroyed||(this.store.hostHoveredLinkIndex=t,this.requestRender())}renderOneFrame(){this._isDestroyed||this.ensureDevice(()=>this.renderOneFrame())||this._isHeadless||!this.store.pointsTextureSize||!this.graph.pointsNumber&&!this.graph.linksNumber||(this.store.alpha<Qt&&this.store.isSimulationRunning&&this.end(),this.renderFrame())}destroy(){var t,i,n,r,s;this._isDestroyed||(this._isDestroyed=!0,this.isReady=!1,this.transition.abort(),window.clearTimeout(this._fitViewOnInitTimeoutID),this.cancelLongPress(),this.stopFrames(),(t=this.resizeObserver)==null||t.disconnect(),this.resizeObserver=void 0,this.canvasD3Selection&&this.canvasD3Selection.on(".cosmos",null).on(".drag",null).on(".zoom",null),ye(document).on(`.cosmos-${this._instanceId}`,null),(i=this.zoomInstance)!=null&&i.behavior&&this.zoomInstance.behavior.on("start.detect",null).on("zoom.detect",null).on("end.detect",null),(n=this.dragInstance)!=null&&n.behavior&&this.dragInstance.behavior.on("start.detect",null).on("drag.detect",null).on("end.detect",null),(r=this.fpsMonitor)==null||r.destroy(),(s=this.lines)==null||s.destroy(),this.simulation.destroy(),this.simulation.ownsDevice&&this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas),this.attributionDivElement&&this.attributionDivElement.parentNode&&this.attributionDivElement.parentNode.removeChild(this.attributionDivElement),this.canvasD3Selection=void 0,this.attributionDivElement=void 0)}create(){if(this._isDestroyed||this.ensureDevice(()=>this.create())||!this.points||!this.lines)return;const{positionsUpdated:t}=this.simulation.applyDataUpdates();t&&(this.lines.isLinkIndexBufferStale=!0),this.isPointColorUpdateNeeded&&this.points.updateColor(),this.isPointShapeUpdateNeeded&&this.points.updateShape(),this.isPointImageIndicesUpdateNeeded&&this.points.updateImageIndices(),this.isPointImageSizesUpdateNeeded&&this.points.updateImageSizes(),this.isLinksUpdateNeeded&&this.lines.updatePointsBuffer(),this.isLinkColorUpdateNeeded&&this.lines.updateColor(),this.isLinkWidthUpdateNeeded&&this.lines.updateWidth(),this.isLinkArrowUpdateNeeded&&this.lines.updateArrow(),this.isLinkStyleUpdateNeeded&&this.lines.updateStyle(),this.isPointColorUpdateNeeded=!1,this.isPointShapeUpdateNeeded=!1,this.isPointImageIndicesUpdateNeeded=!1,this.isPointImageSizesUpdateNeeded=!1,this.isLinksUpdateNeeded=!1,this.isLinkColorUpdateNeeded=!1,this.isLinkWidthUpdateNeeded=!1,this.isLinkArrowUpdateNeeded=!1,this.isLinkStyleUpdateNeeded=!1,this.requestRender()}flatten(t){return t.flat()}pair(t){const i=Math.floor(t.length/2),n=new Array(i);for(let r=0;r<i;r++)n[r]=[t[r*2],t[r*2+1]];return n}preserveInitOnlyFields(t){this.config.initialZoomLevel=t.initialZoomLevel,this.config.randomSeed=t.randomSeed,this.config.attribution=t.attribution}getFitViewPositions(){return this.transition.isActive&&this.transition.isActiveFor(le.Positions)&&!!this.graph.pointPositions&&this.graph.pointPositions?new Float32Array(this.graph.pointPositions):new Float32Array(this.getPointPositions())}updateStateFromConfig(t){var i,n,r,s,o,a,l,c,u,d,h,p,g,x,T,S,P,I;this.applyEnableSimulationConfigChange(t),t.pointDefaultColor!==this.config.pointDefaultColor&&(this.graph.updatePointColor(),(i=this.points)==null||i.updateColor()),t.pointDefaultSize!==this.config.pointDefaultSize&&(this.graph.updatePointSize(),(n=this.points)==null||n.updateSize(),this.graph.updatePointImageSizes(),(r=this.points)==null||r.updateImageSizes()),t.pointDefaultShape!==this.config.pointDefaultShape&&(this.graph.updatePointShape(),(s=this.points)==null||s.updateShape()),t.linkDefaultColor!==this.config.linkDefaultColor&&(this.graph.updateLinkColor(),(o=this.lines)==null||o.updateColor()),t.linkDefaultWidth!==this.config.linkDefaultWidth&&(this.graph.updateLinkWidth(),(a=this.lines)==null||a.updateWidth()),t.linkDefaultArrows!==this.config.linkDefaultArrows&&(this.graph.updateArrows(),(l=this.lines)==null||l.updateArrow()),t.linkDefaultStyle!==this.config.linkDefaultStyle&&(this.graph.updateLinkStyles(),(c=this.lines)==null||c.updateStyle()),t.linkColorInterpolateFromEndpoints!==this.config.linkColorInterpolateFromEndpoints&&((u=this.points)==null||u.updateColor()),t.linkBlending!==this.config.linkBlending&&((d=this.lines)==null||d.updateLinkBlending()),(t.curvedLinkSegments!==this.config.curvedLinkSegments||t.curvedLinks!==this.config.curvedLinks)&&((h=this.lines)==null||h.updateCurveLineGeometry()),t.backgroundColor!==this.config.backgroundColor&&(this.store.backgroundColor=We(this.config.backgroundColor)),t.hoveredPointRingColor!==this.config.hoveredPointRingColor&&this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor),t.focusedPointRingColor!==this.config.focusedPointRingColor&&this.store.setFocusedPointRingColor(this.config.focusedPointRingColor),t.pointGreyoutColor!==this.config.pointGreyoutColor&&this.store.setGreyoutPointColor(this.config.pointGreyoutColor),t.hoveredLinkColor!==this.config.hoveredLinkColor&&this.store.setHoveredLinkColor(this.config.hoveredLinkColor),t.focusedPointIndex!==this.config.focusedPointIndex&&this.store.setFocusedPoint(this.config.focusedPointIndex),t.outlinedPointRingColor!==this.config.outlinedPointRingColor&&this.store.setOutlinedPointRingColor(this.config.outlinedPointRingColor),t.highlightedPointIndices!==this.config.highlightedPointIndices&&this.store.setHighlightedPointSet(this.config.highlightedPointIndices),t.outlinedPointIndices!==this.config.outlinedPointIndices&&this.store.setOutlinedPointSet(this.config.outlinedPointIndices),(t.highlightedPointIndices!==this.config.highlightedPointIndices||t.outlinedPointIndices!==this.config.outlinedPointIndices)&&((p=this.points)==null||p.updatePointStatus()),t.highlightedLinkIndices!==this.config.highlightedLinkIndices&&((g=this.lines)==null||g.updateLinkStatus()),(t.simulationCollisionRadius!==this.config.simulationCollisionRadius||t.simulationCollisionPadding!==this.config.simulationCollisionPadding||(this.config.simulationCollisionRadius===void 0||this.config.simulationCollisionRadius===0)&&t.pointDefaultSize!==this.config.pointDefaultSize)&&this.simulation.invalidateCollisionResources(),t.pixelRatio!==this.config.pixelRatio&&(x=this.device)!=null&&x.canvasContext&&(this.device.canvasContext.setProps({useDevicePixels:this.config.pixelRatio}),this.store.maxPointSize=Fs(this.device,this.config.pixelRatio)),t.spaceSize!==this.config.spaceSize&&(this.store.adjustSpaceSize(this.config.spaceSize,((T=this.device)==null?void 0:T.limits.maxTextureDimension2D)??4096),this.simulation.invalidateCollisionResources(),this.syncScreenSize(!0),this.update(this.store.isSimulationRunning?this.store.alpha:0)),t.showFPSMonitor!==this.config.showFPSMonitor&&!this._isHeadless&&(this.config.showFPSMonitor?this.fpsMonitor=new pc(this.canvas,this.store.div):((S=this.fpsMonitor)==null||S.destroy(),this.fpsMonitor=void 0)),t.enableRenderLoop!==this.config.enableRenderLoop&&!this.config.enableRenderLoop&&this.stopFrames(),(t.enableZoom!==this.config.enableZoom||t.enableDrag!==this.config.enableDrag)&&this.updateZoomDragBehaviors(),t.pointSamplingDistance!==this.config.pointSamplingDistance&&((P=this.points)==null||P.updateSampledPointsGrid()),t.linkSamplingDistance!==this.config.linkSamplingDistance&&((I=this.lines)==null||I.updateSampledLinksGrid()),(t.onLinkClick!==this.config.onLinkClick||t.onLinkContextMenu!==this.config.onLinkContextMenu||t.onLinkMouseOver!==this.config.onLinkMouseOver||t.onLinkMouseOut!==this.config.onLinkMouseOut)&&this.store.updateLinkHoveringEnabled(this.config),this.markPickingBuffersStale(),this.requestRender()}applyEnableSimulationConfigChange(t){var n,r,s,o,a;if(t.enableSimulation===this.config.enableSimulation)return;if(this.config.enableSimulation){this.transition.end(!0),this.transition.dequeue(le.Positions),this.simulation.ensureSimulationModules(),(n=this.points)==null||n.ensureSimulationResources(),this.simulation.markForcesDirty(),this.create(),this.initPrograms(),this.store.simulationProgress=0,this.store.alpha=1,this.store.isSimulationRunning=!0,this._shouldForceHoverDetection=!0,(s=(r=this.config).onSimulationStart)==null||s.call(r);return}const i=this.store.isSimulationRunning||this.store.alpha>0||this.store.simulationProgress>0;this.store.isSimulationRunning=!1,this.store.alpha=0,this.store.simulationProgress=0,this._shouldForceHoverDetection=!0,i&&((a=(o=this.config).onSimulationEnd)==null||a.call(o)),this.simulation.destroySimulationModules()}ensureDevice(t){return this.isReady?!1:(this.ready.then(()=>{this._isDestroyed||t()}).catch(i=>{console.error("Device initialization failed",i)}),!0)}initInteractions(){const t=this.canvas.clientWidth,i=this.canvas.clientHeight;this.store.updateScreenSize(t,i),this.canvasD3Selection=ye(this.canvas).call(this.dragInstance.behavior).call(this.zoomInstance.behavior).on("pointerenter.cosmos",n=>{n.isPrimary&&(this._isPointerOnCanvas=!0,this._lastMouseX=n.clientX,this._lastMouseY=n.clientY,this.requestRender())}).on("pointermove.cosmos",n=>{var r,s,o,a;if(n.isPrimary){if(this._isPointerOnCanvas=!0,this._lastMouseX=n.clientX,this._lastMouseY=n.clientY,this.currentEvent=n,this.updateMousePosition(n),this.isRightClickMouse=(n.buttons&2)!==0,this._longPressTimerId!==void 0){const l=Math.abs(n.clientX-this._longPressStartX),c=Math.abs(n.clientY-this._longPressStartY);(l>wd||c>wd)&&this.cancelLongPress()}(a=(o=this.config).onMouseMove)==null||a.call(o,(r=this.store.hoveredPoint)==null?void 0:r.index,(s=this.store.hoveredPoint)==null?void 0:s.position,this.currentEvent),this.requestRender()}}).on("pointerleave.cosmos pointercancel.cosmos",n=>{n.isPrimary&&(this.cancelLongPress(),this._isPointerOnCanvas=!1,n.pointerType==="mouse"&&(this.currentEvent=n,this.store.hoveredPoint!==void 0&&this.config.onPointMouseOut&&this.config.onPointMouseOut(n),this.store.hoveredLinkIndex!==void 0&&this.config.onLinkMouseOut&&this.config.onLinkMouseOut(n),this.isRightClickMouse=!1,this.store.hoveredPoint=void 0,this.store.hoveredLinkIndex=void 0,this.lines&&(this.lines.isLinkIndexBufferStale=!0),this.updateCanvasCursor(),this.requestRender()))}).on("pointerdown.cosmos",n=>{n.isPrimary&&(this.currentEvent=n,this._shouldSuppressNextClick=!1,this._lastMouseX=n.clientX,this._lastMouseY=n.clientY,this.updateMousePosition(n),this.findHoveredItem(!0),this.requestRender(),n.pointerType!=="mouse"&&(this._longPressStartX=n.clientX,this._longPressStartY=n.clientY,this.cancelLongPress(),this._longPressTimerId=window.setTimeout(()=>{this._longPressTimerId=void 0,!this._isDestroyed&&(this.findHoveredItem(!0),this.requestRender(),this._shouldSuppressNextClick=!0,this.fireContextMenu(n))},Uv)))}).on("pointerup.cosmos",n=>{n.isPrimary&&(this.cancelLongPress(),this.isRightClickMouse=(n.buttons&2)!==0)}).on("click.cosmos",this.onClick.bind(this)).on("contextmenu.cosmos",this.onContextMenu.bind(this)),ye(document).on(`keydown.cosmos-${this._instanceId}`,n=>{n.code==="Space"&&(this.store.isSpaceKeyPressed=!0)}).on(`keyup.cosmos-${this._instanceId}`,n=>{n.code==="Space"&&(this.store.isSpaceKeyPressed=!1)}),this.zoomInstance.behavior.on("start.detect",n=>{this.currentEvent=n,this.requestRender()}).on("zoom.detect",n=>{!!n.sourceEvent&&this.updateMousePosition(n.sourceEvent),this.currentEvent=n,this.requestRender()}).on("end.detect",n=>{this.currentEvent=n,this._shouldForceHoverDetection=!0,this.requestRender()}),this.dragInstance.behavior.on("start.detect",n=>{this.currentEvent=n,this.updateCanvasCursor(),this.requestRender()}).on("drag.detect",n=>{this.dragInstance.isActive&&this.updateMousePosition(n),this.currentEvent=n,this.requestRender()}).on("end.detect",n=>{this.currentEvent=n,this.updateCanvasCursor(),this.requestRender()}),(!this.config.enableZoom||!this.config.enableDrag)&&this.updateZoomDragBehaviors()}validateDevice(t){const i=t.canvasContext;if(i===null||i.type==="offscreen-canvas")throw new Error("Device must have an HTMLCanvasElement canvas context. OffscreenCanvas and compute-only devices are not supported.");return i}update(t=this.store.alpha){this.simulation.updateTextureSizes(),this.create(),this.initPrograms(),this.store.alpha=t}runSimulationStep(t=!1){if(!this.config.enableSimulation)return;const i=this.isRightClickMouse&&this.config.enableRightClickRepulsion,n=this.zoomInstance.shouldEnableSimulationDuringZoomOverride??this.config.enableSimulationDuringZoom,r=this.zoomInstance.isRunning&&!n;(this.simulation.runSimulationStep(t,{applyMouseRepulsion:i,blockedByInteraction:r})||i)&&this.markPickingBuffersStale()}initPrograms(){this._isDestroyed||!this.points||!this.lines||(this.simulation.initPrograms(),this.lines.initPrograms())}frame(){this._isDestroyed||this._isHeadless||!this.config.enableRenderLoop||this.requestAnimationFrameId||!this.store.pointsTextureSize||!this.graph.pointsNumber&&!this.graph.linksNumber||(this.requestAnimationFrameId=window.requestAnimationFrame(t=>{this.requestAnimationFrameId=0;const{store:{alpha:i,isSimulationRunning:n}}=this;i<Qt&&n&&this.end(),this.renderFrame(t),!this._isDestroyed&&this.shouldKeepRendering()&&this.frame()}))}requestRender(){this._isDestroyed||this.frame()}shouldKeepRendering(){var t,i,n;return!this.resizeObserver||this.fpsMonitor||this.store.isSimulationRunning||this.transition.isActive||this.dragInstance.isActive||this.zoomInstance.isRunning||this.isRightClickMouse&&this.config.enableRightClickRepulsion||(t=this.points)!=null&&t.hasPendingPickReadback||(i=this.lines)!=null&&i.hasPendingPickReadback||(n=this.points)!=null&&n.hasPendingTrackedReadback||this.simulation.hasPendingCentroidReadback?!0:this.hasPendingHoverWork()}hasPendingHoverWork(){if(!this._isPointerOnCanvas)return!1;if(this._shouldForceHoverDetection)return!0;const t=Math.abs(this._lastMouseX-this._lastCheckedMouseX),i=Math.abs(this._lastMouseY-this._lastCheckedMouseY);return t>$n||i>$n}renderFrame(t){this._isDestroyed||this.store.pointsTextureSize&&this.simulation.withExternalDeviceState(()=>this.drawFrame(t))}drawFrame(t){var l,c,u,d,h,p,g,x,T;const i=t??performance.now();(l=this.fpsMonitor)==null||l.begin(),(this._shouldSyncScreenSize||!this.resizeObserver)&&(this._shouldSyncScreenSize=!1,this.syncScreenSize()),this.simulation.collectReadbacks();const n=this.transition.isActiveFor(le.Positions),r=this.transition.isActiveFor(le.PointColors),s=this.transition.isActiveFor(le.PointSizes),o=this.transition.isActiveFor(le.LinkColors),a=this.transition.isActiveFor(le.LinkWidths);if(this.transition.isActive&&(this.transition.step(),n&&((c=this.points)==null||c.interpolatePosition(this.transition.progress),(u=this.points)==null||u.gatherTrackers(),this.markPickingBuffersStale())),(d=this.points)==null||d.setTransitionProgress(this.transition.progress,r,s,n),(h=this.lines)==null||h.setTransitionProgress(this.transition.progress,o,a,n),this.dragInstance.isActive||(this.resolvePendingPick(),this.findHoveredItem()),this.runSimulationStep(!1),this.device){const S=this.store.backgroundColor??[0,0,0,1],P=this.device.beginRenderPass({clearColor:S,clearDepth:1,clearStencil:0});this.drawToRenderPass(P),this.dragInstance.isActive&&((p=this.points)==null||p.swapFbo(),(g=this.points)==null||g.drag(),(x=this.points)==null||x.gatherTrackers(),this.markPickingBuffersStale()),P.end(),this.device.submit()}this.simulation.issueReadbacks(),(T=this.fpsMonitor)==null||T.end(i),this.currentEvent=void 0}stopFrames(){this.requestAnimationFrameId&&(window.cancelAnimationFrame(this.requestAnimationFrameId),this.requestAnimationFrameId=0)}end(){this.simulation.end(),this._shouldForceHoverDetection=!0}onClick(t){var i,n,r,s,o,a,l,c,u,d;if(this._shouldSuppressNextClick){this._shouldSuppressNextClick=!1;return}(s=(r=this.config).onClick)==null||s.call(r,(i=this.store.hoveredPoint)==null?void 0:i.index,(n=this.store.hoveredPoint)==null?void 0:n.position,t),this.store.hoveredPoint?(a=(o=this.config).onPointClick)==null||a.call(o,this.store.hoveredPoint.index,this.store.hoveredPoint.position,t):this.store.hoveredLinkIndex!==void 0?(c=(l=this.config).onLinkClick)==null||c.call(l,this.store.hoveredLinkIndex,t):(d=(u=this.config).onBackgroundClick)==null||d.call(u,t)}updateMousePosition(t){if(!t)return;const i=t.offsetX??t.x,n=t.offsetY??t.y;i===void 0||n===void 0||(this.store.mousePosition=this.zoomInstance.convertScreenToSpacePosition([i,n]),this.store.screenMousePosition=[i,this.store.screenSize[1]-n])}onContextMenu(t){t.preventDefault(),this.cancelLongPress(),this._shouldSuppressNextClick=!0,this.fireContextMenu(t)}cancelLongPress(){this._longPressTimerId!==void 0&&(window.clearTimeout(this._longPressTimerId),this._longPressTimerId=void 0)}fireContextMenu(t){var i,n,r,s,o,a,l,c,u,d;(s=(r=this.config).onContextMenu)==null||s.call(r,(i=this.store.hoveredPoint)==null?void 0:i.index,(n=this.store.hoveredPoint)==null?void 0:n.position,t),this.store.hoveredPoint?(a=(o=this.config).onPointContextMenu)==null||a.call(o,this.store.hoveredPoint.index,this.store.hoveredPoint.position,t):this.store.hoveredLinkIndex!==void 0?(c=(l=this.config).onLinkContextMenu)==null||c.call(l,this.store.hoveredLinkIndex,t):(d=(u=this.config).onBackgroundContextMenu)==null||d.call(u,t)}syncScreenSize(t=!1){var o,a,l,c;if(this._isHeadless||!this.canvas||this._isDestroyed)return;const i=this.canvas.clientWidth,n=this.canvas.clientHeight,[r,s]=this.store.screenSize;if(t||r!==i||s!==n){const{k:u}=this.zoomInstance.eventTransform,d=this.zoomInstance.convertScreenToSpacePosition([r/2,s/2]);this.store.updateScreenSize(i,n),(o=this.canvasD3Selection)==null||o.call(this.zoomInstance.behavior.transform,this.zoomInstance.getTransform(d,u)),(a=this.points)==null||a.updateSampledPointsGrid(),(l=this.lines)==null||l.updateSampledLinksGrid(),this.store.isLinkHoveringEnabled&&((c=this.lines)==null||c.updateLinkIndexFbo()),this.markPickingBuffersStale()}}updateZoomDragBehaviors(){var t,i,n,r;this._isHeadless||(this.config.enableDrag?(t=this.canvasD3Selection)==null||t.call(this.dragInstance.behavior):(i=this.canvasD3Selection)==null||i.call(this.dragInstance.behavior).on(".drag",null),this.config.enableZoom?(n=this.canvasD3Selection)==null||n.call(this.zoomInstance.behavior):(r=this.canvasD3Selection)==null||r.call(this.zoomInstance.behavior).on("wheel.zoom",null),this.updateCanvasTouchAction())}updateCanvasTouchAction(){this.canvas.style.touchAction=this.config.enableDrag||this.config.enableZoom?"none":""}findHoveredItem(t=!1){var o,a,l,c;if(this._isDestroyed||!t&&!this._isPointerOnCanvas||this.transition.isActiveFor(le.PointSizes))return;if(!t&&this._findHoveredItemExecutionCount<Vx){this._findHoveredItemExecutionCount+=1;return}const i=Math.abs(this._lastMouseX-this._lastCheckedMouseX),n=Math.abs(this._lastMouseY-this._lastCheckedMouseY),r=i>$n||n>$n;if(!t&&!r&&!this._shouldForceHoverDetection)return;this.updatePickingBufferStaleness();const s=!!this.graph.linksNumber&&this.store.isLinkHoveringEnabled;if(t){(o=this.points)==null||o.discardPendingPick(),(a=this.lines)==null||a.discardPendingPick();const u=((l=this.points)==null?void 0:l.pickPointSync())??null;let d;!u&&s&&(d=((c=this.lines)==null?void 0:c.pickLinkSync())??null),this.processHoverResult(u,d)}else{const u=this.points?this.points.requestPickPoint():!0,d=s&&this.lines?this.lines.requestPickLink():!0;if(!u||!d)return}this._findHoveredItemExecutionCount=0,this._lastCheckedMouseX=this._lastMouseX,this._lastCheckedMouseY=this._lastMouseY,this._shouldForceHoverDetection=!1}updatePickingBufferStaleness(){const t=this.store.transformationMatrix4x4;L_(this._lastPickingMatrix,t)||(this._lastPickingMatrix=Array.from(t),this.markPickingBuffersStale())}markPickingBuffersStale(){this.points&&(this.points.isPickingBufferStale=!0),this.lines&&(this.lines.isLinkIndexBufferStale=!0)}resolvePendingPick(){var n,r;const t=(n=this.points)==null?void 0:n.takePickResult(),i=(r=this.lines)==null?void 0:r.takePickLinkResult();t===void 0&&i===void 0||this._isPointerOnCanvas&&this.processHoverResult(t,i)}processHoverResult(t,i){var s,o,a,l,c,u,d,h,p,g;if(this._isDestroyed)return;const n=t===void 0?{mouseover:!1,mouseout:!1}:this.applyPickedPoint(t);let r={mouseover:!1,mouseout:!1};if(this.graph.linksNumber&&this.store.isLinkHoveringEnabled?this.store.hoveredPoint?r=this.applyPickedLink(null):i!==void 0&&(r=this.applyPickedLink(i)):this.store.hoveredLinkIndex!==void 0&&(r=this.applyPickedLink(null)),n.mouseout&&((o=(s=this.config).onPointMouseOut)==null||o.call(s,this.currentEvent)),r.mouseout&&((l=(a=this.config).onLinkMouseOut)==null||l.call(a,this.currentEvent)),n.mouseover&&this.store.hoveredPoint){const x=this.store.hoveredPoint.index;(h=(d=this.config).onPointMouseOver)==null||h.call(d,this.store.hoveredPoint.index,this.store.hoveredPoint.position,this.currentEvent,((c=this.store.highlightedPointSet)==null?void 0:c.has(x))??!1,((u=this.store.outlinedPointSet)==null?void 0:u.has(x))??!1)}r.mouseover&&this.store.hoveredLinkIndex!==void 0&&((g=(p=this.config).onLinkMouseOver)==null||g.call(p,this.store.hoveredLinkIndex)),this.updateCanvasCursor()}applyPickedPoint(t){let i=!1,n=!1;return t&&t.index>=(this.graph.pointsNumber??0)&&(t=null),t?((this.store.hoveredPoint===void 0||this.store.hoveredPoint.index!==t.index)&&(i=!0),this.store.hoveredPoint=t):(this.store.hoveredPoint&&(n=!0),this.store.hoveredPoint=void 0),{mouseover:i,mouseout:n}}applyPickedLink(t){let i=!1,n=!1;return t!==null&&t>=(this.graph.linksNumber??0)&&(t=null),t!==null?(this.store.hoveredLinkIndex!==t&&(i=!0),this.store.hoveredLinkIndex=t):(this.store.hoveredLinkIndex!==void 0&&(n=!0),this.store.hoveredLinkIndex=void 0),(i||n)&&this.lines&&(this.lines.isLinkIndexBufferStale=!0),{mouseover:i,mouseout:n}}updateCanvasCursor(){const{hoveredPointCursor:t,hoveredLinkCursor:i}=this.config;this.dragInstance.isActive?ye(this.canvas).style("cursor","grabbing"):this.store.hoveredPoint?!this.config.enableDrag||this.store.isSpaceKeyPressed?ye(this.canvas).style("cursor",t):ye(this.canvas).style("cursor","grab"):this.store.isLinkHoveringEnabled&&this.store.hoveredLinkIndex!==void 0?ye(this.canvas).style("cursor",i):ye(this.canvas).style("cursor",null)}addAttribution(){var t;this.config.attribution&&(this.attributionDivElement=document.createElement("div"),this.attributionDivElement.style.cssText=` + user-select: none; + position: absolute; + bottom: 0; + right: 0; + color: var(--cosmosgl-attribution-color); + margin: 0 0.6rem 0.6rem 0; + font-size: 0.7rem; + font-family: inherit; + `,this.attributionDivElement.innerHTML=cc(this.config.attribution,{ALLOWED_TAGS:["a","b","i","em","strong","span","div","p","br","img"],ALLOWED_ATTR:["href","target","class","id","style","src","alt","title"]}),(t=this.store.div)==null||t.appendChild(this.attributionDivElement))}}K.EDGE_RAMP_PX=Us,K.EXIT_DEFAULT_COLOR_CHANNEL=Xn,K.EXIT_DEFAULT_SIZE=Os,K.Graph=zv,K.GraphSimulation=Rd,K.LinkStyle=Ns,K.POINT_RING_SCALE=fc,K.PointShape=Ms,K.TransitionEasing=Bs,K.clamp=lc,K.defaultConfigValues=Ze,K.extractIndicesFromPixels=Ds,K.focusedPointRingOpacity=hc,K.generateRandomId=ac,K.getMaxPointSize=Fs,K.getRgbaColor=We,K.hoveredPointRingOpacity=dc,K.isAClassInstance=sc,K.isArray=ks,K.isFunction=nc,K.isNumber=ft,K.isObject=rc,K.isPlainObject=$x,K.isPointAbsent=De,K.readPixels=we,K.rgbToBrightness=oc,K.sanitizeHtml=cc,Object.defineProperty(K,Symbol.toStringTag,{value:"Module"})}); +//# sourceMappingURL=index.min.js.map diff --git a/internal/server/memorygraph/view.html b/internal/server/memorygraph/view.html index 7edc308..6b98771 100644 --- a/internal/server/memorygraph/view.html +++ b/internal/server/memorygraph/view.html @@ -6,7 +6,7 @@ <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Expires" content="0"> <title>MEMORY AURORA - +