@cosmos.gl/graph 3.0.0-beta.3 → 3.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/variables.ts","../node_modules/@luma.gl/constants/dist/webgl-constants.js","../src/modules/Store/index.ts","../src/helper.ts","../src/config.ts","../src/modules/core-module.ts","../src/modules/ForceCenter/calculate-centermass.frag?raw","../src/modules/ForceCenter/calculate-centermass.vert?raw","../src/modules/ForceCenter/force-center.frag?raw","../src/modules/Shared/buffer.ts","../src/modules/Shared/texture-utils.ts","../src/modules/Shared/quad.vert?raw","../src/modules/ForceCenter/index.ts","../src/modules/ForceGravity/force-gravity.frag?raw","../src/modules/ForceGravity/index.ts","../src/modules/ForceLink/force-spring.ts","../src/modules/Shared/uniform-utils.ts","../src/modules/ForceLink/index.ts","../src/modules/ForceManyBody/calculate-level.frag?raw","../src/modules/ForceManyBody/calculate-level.vert?raw","../src/modules/ForceManyBody/force-level.frag?raw","../src/modules/ForceManyBody/force-centermass.frag?raw","../src/modules/ForceManyBody/index.ts","../src/modules/ForceMouse/force-mouse.frag?raw","../src/modules/ForceMouse/index.ts","../src/modules/Clusters/calculate-centermass.frag?raw","../src/modules/Clusters/calculate-centermass.vert?raw","../src/modules/Clusters/force-cluster.frag?raw","../src/modules/Clusters/index.ts","../src/modules/FPSMonitor/css.ts","../src/modules/FPSMonitor/index.ts","../src/modules/GraphData/index.ts","../src/modules/Lines/draw-curve-line.frag?raw","../src/modules/Lines/draw-curve-line.vert?raw","../src/modules/Lines/hovered-line-index.frag?raw","../src/modules/Lines/hovered-line-index.vert?raw","../src/modules/Lines/geometry.ts","../src/modules/Lines/index.ts","../src/modules/Points/draw-points.frag?raw","../src/modules/Points/draw-points.vert?raw","../src/modules/Points/find-points-on-area-selection.frag?raw","../src/modules/Points/find-points-on-polygon-selection.frag?raw","../src/modules/Points/draw-highlighted.frag?raw","../src/modules/Points/draw-highlighted.vert?raw","../src/modules/Points/find-hovered-point.frag?raw","../src/modules/Points/find-hovered-point.vert?raw","../src/modules/Points/fill-sampled-points.frag?raw","../src/modules/Points/fill-sampled-points.vert?raw","../src/modules/Points/update-position.frag?raw","../src/modules/Points/track-positions.frag?raw","../src/modules/Points/drag-point.frag?raw","../src/modules/Points/atlas-utils.ts","../src/modules/Points/index.ts","../src/modules/Zoom/index.ts","../src/modules/Drag/index.ts","../src/index.ts"],"sourcesContent":["export const defaultPointColor = '#b3b3b3'\nexport const defaultGreyoutPointOpacity = undefined\nexport const defaultGreyoutPointColor = undefined\nexport const defaultPointOpacity = 1.0\nexport const defaultPointSize = 4\nexport const defaultLinkColor = '#666666'\nexport const defaultGreyoutLinkOpacity = 0.1\nexport const defaultLinkOpacity = 1.0\nexport const defaultLinkWidth = 1\nexport const defaultBackgroundColor = '#222222'\n\nexport const defaultConfigValues = {\n enableSimulation: true,\n spaceSize: 8192,\n pointSizeScale: 1,\n linkWidthScale: 1,\n linkArrowsSizeScale: 1,\n renderLinks: true,\n curvedLinks: false,\n curvedLinkSegments: 19,\n curvedLinkWeight: 0.8,\n curvedLinkControlPointDistance: 0.5,\n linkArrows: false,\n linkVisibilityDistanceRange: [50, 150],\n linkVisibilityMinTransparency: 0.25,\n hoveredPointCursor: 'auto',\n hoveredLinkCursor: 'auto',\n renderHoveredPointRing: false,\n hoveredPointRingColor: 'white',\n hoveredLinkColor: undefined,\n hoveredLinkWidthIncrease: 5,\n focusedPointRingColor: 'white',\n focusedPointIndex: undefined,\n simulation: {\n decay: 5000,\n gravity: 0.25,\n center: 0,\n repulsion: 1.0,\n repulsionTheta: 1.15,\n linkSpring: 1,\n linkDistance: 10,\n linkDistRandomVariationRange: [1, 1.2],\n repulsionFromMouse: 2,\n friction: 0.85,\n cluster: 0.1,\n },\n showFPSMonitor: false,\n pixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio || 2 : 2,\n scalePointsOnZoom: false,\n scaleLinksOnZoom: false,\n enableZoom: true,\n enableSimulationDuringZoom: false,\n enableDrag: false,\n fitViewOnInit: true,\n fitViewDelay: 250,\n fitViewPadding: 0.1,\n fitViewDuration: 250,\n pointSamplingDistance: 150,\n attribution: '',\n rescalePositions: undefined,\n enableRightClickRepulsion: false,\n}\n\nexport const hoveredPointRingOpacity = 0.7\nexport const focusedPointRingOpacity = 0.95\nexport const defaultScaleToZoom = 3\n","// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/* eslint-disable key-spacing, max-len, no-inline-comments, camelcase */\n/**\n * Standard WebGL, WebGL2 and extension constants (OpenGL constants)\n * @note (Most) of these constants are also defined on the WebGLRenderingContext interface.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants\n * @privateRemarks Locally called `GLEnum` instead of `GL`, because `babel-plugin-inline-webl-constants`\n * both depends on and processes this module, but shouldn't replace these declarations.\n */\n// eslint-disable-next-line no-shadow\nvar GLEnum;\n(function (GLEnum) {\n // Clearing buffers\n // Constants passed to clear() to clear buffer masks.\n /** Passed to clear to clear the current depth buffer. */\n GLEnum[GLEnum[\"DEPTH_BUFFER_BIT\"] = 256] = \"DEPTH_BUFFER_BIT\";\n /** Passed to clear to clear the current stencil buffer. */\n GLEnum[GLEnum[\"STENCIL_BUFFER_BIT\"] = 1024] = \"STENCIL_BUFFER_BIT\";\n /** Passed to clear to clear the current color buffer. */\n GLEnum[GLEnum[\"COLOR_BUFFER_BIT\"] = 16384] = \"COLOR_BUFFER_BIT\";\n // Rendering primitives\n // Constants passed to drawElements() or drawArrays() to specify what kind of primitive to render.\n /** Passed to drawElements or drawArrays to draw single points. */\n GLEnum[GLEnum[\"POINTS\"] = 0] = \"POINTS\";\n /** Passed to drawElements or drawArrays to draw lines. Each vertex connects to the one after it. */\n GLEnum[GLEnum[\"LINES\"] = 1] = \"LINES\";\n /** Passed to drawElements or drawArrays to draw lines. Each set of two vertices is treated as a separate line segment. */\n GLEnum[GLEnum[\"LINE_LOOP\"] = 2] = \"LINE_LOOP\";\n /** Passed to drawElements or drawArrays to draw a connected group of line segments from the first vertex to the last. */\n GLEnum[GLEnum[\"LINE_STRIP\"] = 3] = \"LINE_STRIP\";\n /** Passed to drawElements or drawArrays to draw triangles. Each set of three vertices creates a separate triangle. */\n GLEnum[GLEnum[\"TRIANGLES\"] = 4] = \"TRIANGLES\";\n /** Passed to drawElements or drawArrays to draw a connected group of triangles. */\n GLEnum[GLEnum[\"TRIANGLE_STRIP\"] = 5] = \"TRIANGLE_STRIP\";\n /** Passed to drawElements or drawArrays to draw a connected group of triangles. Each vertex connects to the previous and the first vertex in the fan. */\n GLEnum[GLEnum[\"TRIANGLE_FAN\"] = 6] = \"TRIANGLE_FAN\";\n // Blending modes\n // Constants passed to blendFunc() or blendFuncSeparate() to specify the blending mode (for both, RBG and alpha, or separately).\n /** Passed to blendFunc or blendFuncSeparate to turn off a component. */\n GLEnum[GLEnum[\"ZERO\"] = 0] = \"ZERO\";\n /** Passed to blendFunc or blendFuncSeparate to turn on a component. */\n GLEnum[GLEnum[\"ONE\"] = 1] = \"ONE\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the source elements color. */\n GLEnum[GLEnum[\"SRC_COLOR\"] = 768] = \"SRC_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the source elements color. */\n GLEnum[GLEnum[\"ONE_MINUS_SRC_COLOR\"] = 769] = \"ONE_MINUS_SRC_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the source's alpha. */\n GLEnum[GLEnum[\"SRC_ALPHA\"] = 770] = \"SRC_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the source's alpha. */\n GLEnum[GLEnum[\"ONE_MINUS_SRC_ALPHA\"] = 771] = \"ONE_MINUS_SRC_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the destination's alpha. */\n GLEnum[GLEnum[\"DST_ALPHA\"] = 772] = \"DST_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the destination's alpha. */\n GLEnum[GLEnum[\"ONE_MINUS_DST_ALPHA\"] = 773] = \"ONE_MINUS_DST_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the destination's color. */\n GLEnum[GLEnum[\"DST_COLOR\"] = 774] = \"DST_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the destination's color. */\n GLEnum[GLEnum[\"ONE_MINUS_DST_COLOR\"] = 775] = \"ONE_MINUS_DST_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the minimum of source's alpha or one minus the destination's alpha. */\n GLEnum[GLEnum[\"SRC_ALPHA_SATURATE\"] = 776] = \"SRC_ALPHA_SATURATE\";\n /** Passed to blendFunc or blendFuncSeparate to specify a constant color blend function. */\n GLEnum[GLEnum[\"CONSTANT_COLOR\"] = 32769] = \"CONSTANT_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to specify one minus a constant color blend function. */\n GLEnum[GLEnum[\"ONE_MINUS_CONSTANT_COLOR\"] = 32770] = \"ONE_MINUS_CONSTANT_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to specify a constant alpha blend function. */\n GLEnum[GLEnum[\"CONSTANT_ALPHA\"] = 32771] = \"CONSTANT_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to specify one minus a constant alpha blend function. */\n GLEnum[GLEnum[\"ONE_MINUS_CONSTANT_ALPHA\"] = 32772] = \"ONE_MINUS_CONSTANT_ALPHA\";\n // Blending equations\n // Constants passed to blendEquation() or blendEquationSeparate() to control\n // how the blending is calculated (for both, RBG and alpha, or separately).\n /** Passed to blendEquation or blendEquationSeparate to set an addition blend function. */\n /** Passed to blendEquation or blendEquationSeparate to specify a subtraction blend function (source - destination). */\n /** Passed to blendEquation or blendEquationSeparate to specify a reverse subtraction blend function (destination - source). */\n GLEnum[GLEnum[\"FUNC_ADD\"] = 32774] = \"FUNC_ADD\";\n GLEnum[GLEnum[\"FUNC_SUBTRACT\"] = 32778] = \"FUNC_SUBTRACT\";\n GLEnum[GLEnum[\"FUNC_REVERSE_SUBTRACT\"] = 32779] = \"FUNC_REVERSE_SUBTRACT\";\n // Getting GL parameter information\n // Constants passed to getParameter() to specify what information to return.\n /** Passed to getParameter to get the current RGB blend function. */\n GLEnum[GLEnum[\"BLEND_EQUATION\"] = 32777] = \"BLEND_EQUATION\";\n /** Passed to getParameter to get the current RGB blend function. Same as BLEND_EQUATION */\n GLEnum[GLEnum[\"BLEND_EQUATION_RGB\"] = 32777] = \"BLEND_EQUATION_RGB\";\n /** Passed to getParameter to get the current alpha blend function. Same as BLEND_EQUATION */\n GLEnum[GLEnum[\"BLEND_EQUATION_ALPHA\"] = 34877] = \"BLEND_EQUATION_ALPHA\";\n /** Passed to getParameter to get the current destination RGB blend function. */\n GLEnum[GLEnum[\"BLEND_DST_RGB\"] = 32968] = \"BLEND_DST_RGB\";\n /** Passed to getParameter to get the current destination RGB blend function. */\n GLEnum[GLEnum[\"BLEND_SRC_RGB\"] = 32969] = \"BLEND_SRC_RGB\";\n /** Passed to getParameter to get the current destination alpha blend function. */\n GLEnum[GLEnum[\"BLEND_DST_ALPHA\"] = 32970] = \"BLEND_DST_ALPHA\";\n /** Passed to getParameter to get the current source alpha blend function. */\n GLEnum[GLEnum[\"BLEND_SRC_ALPHA\"] = 32971] = \"BLEND_SRC_ALPHA\";\n /** Passed to getParameter to return a the current blend color. */\n GLEnum[GLEnum[\"BLEND_COLOR\"] = 32773] = \"BLEND_COLOR\";\n /** Passed to getParameter to get the array buffer binding. */\n GLEnum[GLEnum[\"ARRAY_BUFFER_BINDING\"] = 34964] = \"ARRAY_BUFFER_BINDING\";\n /** Passed to getParameter to get the current element array buffer. */\n GLEnum[GLEnum[\"ELEMENT_ARRAY_BUFFER_BINDING\"] = 34965] = \"ELEMENT_ARRAY_BUFFER_BINDING\";\n /** Passed to getParameter to get the current lineWidth (set by the lineWidth method). */\n GLEnum[GLEnum[\"LINE_WIDTH\"] = 2849] = \"LINE_WIDTH\";\n /** Passed to getParameter to get the current size of a point drawn with gl.POINTS */\n GLEnum[GLEnum[\"ALIASED_POINT_SIZE_RANGE\"] = 33901] = \"ALIASED_POINT_SIZE_RANGE\";\n /** Passed to getParameter to get the range of available widths for a line. Returns a length-2 array with the lo value at 0, and hight at 1. */\n GLEnum[GLEnum[\"ALIASED_LINE_WIDTH_RANGE\"] = 33902] = \"ALIASED_LINE_WIDTH_RANGE\";\n /** Passed to getParameter to get the current value of cullFace. Should return FRONT, BACK, or FRONT_AND_BACK */\n GLEnum[GLEnum[\"CULL_FACE_MODE\"] = 2885] = \"CULL_FACE_MODE\";\n /** Passed to getParameter to determine the current value of frontFace. Should return CW or CCW. */\n GLEnum[GLEnum[\"FRONT_FACE\"] = 2886] = \"FRONT_FACE\";\n /** Passed to getParameter to return a length-2 array of floats giving the current depth range. */\n GLEnum[GLEnum[\"DEPTH_RANGE\"] = 2928] = \"DEPTH_RANGE\";\n /** Passed to getParameter to determine if the depth write mask is enabled. */\n GLEnum[GLEnum[\"DEPTH_WRITEMASK\"] = 2930] = \"DEPTH_WRITEMASK\";\n /** Passed to getParameter to determine the current depth clear value. */\n GLEnum[GLEnum[\"DEPTH_CLEAR_VALUE\"] = 2931] = \"DEPTH_CLEAR_VALUE\";\n /** Passed to getParameter to get the current depth function. Returns NEVER, ALWAYS, LESS, EQUAL, LEQUAL, GREATER, GEQUAL, or NOTEQUAL. */\n GLEnum[GLEnum[\"DEPTH_FUNC\"] = 2932] = \"DEPTH_FUNC\";\n /** Passed to getParameter to get the value the stencil will be cleared to. */\n GLEnum[GLEnum[\"STENCIL_CLEAR_VALUE\"] = 2961] = \"STENCIL_CLEAR_VALUE\";\n /** Passed to getParameter to get the current stencil function. Returns NEVER, ALWAYS, LESS, EQUAL, LEQUAL, GREATER, GEQUAL, or NOTEQUAL. */\n GLEnum[GLEnum[\"STENCIL_FUNC\"] = 2962] = \"STENCIL_FUNC\";\n /** Passed to getParameter to get the current stencil fail function. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP. */\n GLEnum[GLEnum[\"STENCIL_FAIL\"] = 2964] = \"STENCIL_FAIL\";\n /** Passed to getParameter to get the current stencil fail function should the depth buffer test fail. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP. */\n GLEnum[GLEnum[\"STENCIL_PASS_DEPTH_FAIL\"] = 2965] = \"STENCIL_PASS_DEPTH_FAIL\";\n /** Passed to getParameter to get the current stencil fail function should the depth buffer test pass. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP. */\n GLEnum[GLEnum[\"STENCIL_PASS_DEPTH_PASS\"] = 2966] = \"STENCIL_PASS_DEPTH_PASS\";\n /** Passed to getParameter to get the reference value used for stencil tests. */\n GLEnum[GLEnum[\"STENCIL_REF\"] = 2967] = \"STENCIL_REF\";\n GLEnum[GLEnum[\"STENCIL_VALUE_MASK\"] = 2963] = \"STENCIL_VALUE_MASK\";\n GLEnum[GLEnum[\"STENCIL_WRITEMASK\"] = 2968] = \"STENCIL_WRITEMASK\";\n GLEnum[GLEnum[\"STENCIL_BACK_FUNC\"] = 34816] = \"STENCIL_BACK_FUNC\";\n GLEnum[GLEnum[\"STENCIL_BACK_FAIL\"] = 34817] = \"STENCIL_BACK_FAIL\";\n GLEnum[GLEnum[\"STENCIL_BACK_PASS_DEPTH_FAIL\"] = 34818] = \"STENCIL_BACK_PASS_DEPTH_FAIL\";\n GLEnum[GLEnum[\"STENCIL_BACK_PASS_DEPTH_PASS\"] = 34819] = \"STENCIL_BACK_PASS_DEPTH_PASS\";\n GLEnum[GLEnum[\"STENCIL_BACK_REF\"] = 36003] = \"STENCIL_BACK_REF\";\n GLEnum[GLEnum[\"STENCIL_BACK_VALUE_MASK\"] = 36004] = \"STENCIL_BACK_VALUE_MASK\";\n GLEnum[GLEnum[\"STENCIL_BACK_WRITEMASK\"] = 36005] = \"STENCIL_BACK_WRITEMASK\";\n /** An Int32Array with four elements for the current viewport dimensions. */\n GLEnum[GLEnum[\"VIEWPORT\"] = 2978] = \"VIEWPORT\";\n /** An Int32Array with four elements for the current scissor box dimensions. */\n GLEnum[GLEnum[\"SCISSOR_BOX\"] = 3088] = \"SCISSOR_BOX\";\n GLEnum[GLEnum[\"COLOR_CLEAR_VALUE\"] = 3106] = \"COLOR_CLEAR_VALUE\";\n GLEnum[GLEnum[\"COLOR_WRITEMASK\"] = 3107] = \"COLOR_WRITEMASK\";\n GLEnum[GLEnum[\"UNPACK_ALIGNMENT\"] = 3317] = \"UNPACK_ALIGNMENT\";\n GLEnum[GLEnum[\"PACK_ALIGNMENT\"] = 3333] = \"PACK_ALIGNMENT\";\n GLEnum[GLEnum[\"MAX_TEXTURE_SIZE\"] = 3379] = \"MAX_TEXTURE_SIZE\";\n GLEnum[GLEnum[\"MAX_VIEWPORT_DIMS\"] = 3386] = \"MAX_VIEWPORT_DIMS\";\n GLEnum[GLEnum[\"SUBPIXEL_BITS\"] = 3408] = \"SUBPIXEL_BITS\";\n GLEnum[GLEnum[\"RED_BITS\"] = 3410] = \"RED_BITS\";\n GLEnum[GLEnum[\"GREEN_BITS\"] = 3411] = \"GREEN_BITS\";\n GLEnum[GLEnum[\"BLUE_BITS\"] = 3412] = \"BLUE_BITS\";\n GLEnum[GLEnum[\"ALPHA_BITS\"] = 3413] = \"ALPHA_BITS\";\n GLEnum[GLEnum[\"DEPTH_BITS\"] = 3414] = \"DEPTH_BITS\";\n GLEnum[GLEnum[\"STENCIL_BITS\"] = 3415] = \"STENCIL_BITS\";\n GLEnum[GLEnum[\"POLYGON_OFFSET_UNITS\"] = 10752] = \"POLYGON_OFFSET_UNITS\";\n GLEnum[GLEnum[\"POLYGON_OFFSET_FACTOR\"] = 32824] = \"POLYGON_OFFSET_FACTOR\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_2D\"] = 32873] = \"TEXTURE_BINDING_2D\";\n GLEnum[GLEnum[\"SAMPLE_BUFFERS\"] = 32936] = \"SAMPLE_BUFFERS\";\n GLEnum[GLEnum[\"SAMPLES\"] = 32937] = \"SAMPLES\";\n GLEnum[GLEnum[\"SAMPLE_COVERAGE_VALUE\"] = 32938] = \"SAMPLE_COVERAGE_VALUE\";\n GLEnum[GLEnum[\"SAMPLE_COVERAGE_INVERT\"] = 32939] = \"SAMPLE_COVERAGE_INVERT\";\n GLEnum[GLEnum[\"COMPRESSED_TEXTURE_FORMATS\"] = 34467] = \"COMPRESSED_TEXTURE_FORMATS\";\n GLEnum[GLEnum[\"VENDOR\"] = 7936] = \"VENDOR\";\n GLEnum[GLEnum[\"RENDERER\"] = 7937] = \"RENDERER\";\n GLEnum[GLEnum[\"VERSION\"] = 7938] = \"VERSION\";\n GLEnum[GLEnum[\"IMPLEMENTATION_COLOR_READ_TYPE\"] = 35738] = \"IMPLEMENTATION_COLOR_READ_TYPE\";\n GLEnum[GLEnum[\"IMPLEMENTATION_COLOR_READ_FORMAT\"] = 35739] = \"IMPLEMENTATION_COLOR_READ_FORMAT\";\n GLEnum[GLEnum[\"BROWSER_DEFAULT_WEBGL\"] = 37444] = \"BROWSER_DEFAULT_WEBGL\";\n // Buffers\n // Constants passed to bufferData(), bufferSubData(), bindBuffer(), or\n // getBufferParameter().\n /** Passed to bufferData as a hint about whether the contents of the buffer are likely to be used often and not change often. */\n GLEnum[GLEnum[\"STATIC_DRAW\"] = 35044] = \"STATIC_DRAW\";\n /** Passed to bufferData as a hint about whether the contents of the buffer are likely to not be used often. */\n GLEnum[GLEnum[\"STREAM_DRAW\"] = 35040] = \"STREAM_DRAW\";\n /** Passed to bufferData as a hint about whether the contents of the buffer are likely to be used often and change often. */\n GLEnum[GLEnum[\"DYNAMIC_DRAW\"] = 35048] = \"DYNAMIC_DRAW\";\n /** Passed to bindBuffer or bufferData to specify the type of buffer being used. */\n GLEnum[GLEnum[\"ARRAY_BUFFER\"] = 34962] = \"ARRAY_BUFFER\";\n /** Passed to bindBuffer or bufferData to specify the type of buffer being used. */\n GLEnum[GLEnum[\"ELEMENT_ARRAY_BUFFER\"] = 34963] = \"ELEMENT_ARRAY_BUFFER\";\n /** Passed to getBufferParameter to get a buffer's size. */\n GLEnum[GLEnum[\"BUFFER_SIZE\"] = 34660] = \"BUFFER_SIZE\";\n /** Passed to getBufferParameter to get the hint for the buffer passed in when it was created. */\n GLEnum[GLEnum[\"BUFFER_USAGE\"] = 34661] = \"BUFFER_USAGE\";\n // Vertex attributes\n // Constants passed to getVertexAttrib().\n /** Passed to getVertexAttrib to read back the current vertex attribute. */\n GLEnum[GLEnum[\"CURRENT_VERTEX_ATTRIB\"] = 34342] = \"CURRENT_VERTEX_ATTRIB\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_ENABLED\"] = 34338] = \"VERTEX_ATTRIB_ARRAY_ENABLED\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_SIZE\"] = 34339] = \"VERTEX_ATTRIB_ARRAY_SIZE\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_STRIDE\"] = 34340] = \"VERTEX_ATTRIB_ARRAY_STRIDE\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_TYPE\"] = 34341] = \"VERTEX_ATTRIB_ARRAY_TYPE\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_NORMALIZED\"] = 34922] = \"VERTEX_ATTRIB_ARRAY_NORMALIZED\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_POINTER\"] = 34373] = \"VERTEX_ATTRIB_ARRAY_POINTER\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\"] = 34975] = \"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\";\n // Culling\n // Constants passed to cullFace().\n /** Passed to enable/disable to turn on/off culling. Can also be used with getParameter to find the current culling method. */\n GLEnum[GLEnum[\"CULL_FACE\"] = 2884] = \"CULL_FACE\";\n /** Passed to cullFace to specify that only front faces should be culled. */\n GLEnum[GLEnum[\"FRONT\"] = 1028] = \"FRONT\";\n /** Passed to cullFace to specify that only back faces should be culled. */\n GLEnum[GLEnum[\"BACK\"] = 1029] = \"BACK\";\n /** Passed to cullFace to specify that front and back faces should be culled. */\n GLEnum[GLEnum[\"FRONT_AND_BACK\"] = 1032] = \"FRONT_AND_BACK\";\n // Enabling and disabling\n // Constants passed to enable() or disable().\n /** Passed to enable/disable to turn on/off blending. Can also be used with getParameter to find the current blending method. */\n GLEnum[GLEnum[\"BLEND\"] = 3042] = \"BLEND\";\n /** Passed to enable/disable to turn on/off the depth test. Can also be used with getParameter to query the depth test. */\n GLEnum[GLEnum[\"DEPTH_TEST\"] = 2929] = \"DEPTH_TEST\";\n /** Passed to enable/disable to turn on/off dithering. Can also be used with getParameter to find the current dithering method. */\n GLEnum[GLEnum[\"DITHER\"] = 3024] = \"DITHER\";\n /** Passed to enable/disable to turn on/off the polygon offset. Useful for rendering hidden-line images, decals, and or solids with highlighted edges. Can also be used with getParameter to query the scissor test. */\n GLEnum[GLEnum[\"POLYGON_OFFSET_FILL\"] = 32823] = \"POLYGON_OFFSET_FILL\";\n /** Passed to enable/disable to turn on/off the alpha to coverage. Used in multi-sampling alpha channels. */\n GLEnum[GLEnum[\"SAMPLE_ALPHA_TO_COVERAGE\"] = 32926] = \"SAMPLE_ALPHA_TO_COVERAGE\";\n /** Passed to enable/disable to turn on/off the sample coverage. Used in multi-sampling. */\n GLEnum[GLEnum[\"SAMPLE_COVERAGE\"] = 32928] = \"SAMPLE_COVERAGE\";\n /** Passed to enable/disable to turn on/off the scissor test. Can also be used with getParameter to query the scissor test. */\n GLEnum[GLEnum[\"SCISSOR_TEST\"] = 3089] = \"SCISSOR_TEST\";\n /** Passed to enable/disable to turn on/off the stencil test. Can also be used with getParameter to query the stencil test. */\n GLEnum[GLEnum[\"STENCIL_TEST\"] = 2960] = \"STENCIL_TEST\";\n // Errors\n // Constants returned from getError().\n /** Returned from getError(). */\n GLEnum[GLEnum[\"NO_ERROR\"] = 0] = \"NO_ERROR\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"INVALID_ENUM\"] = 1280] = \"INVALID_ENUM\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"INVALID_VALUE\"] = 1281] = \"INVALID_VALUE\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"INVALID_OPERATION\"] = 1282] = \"INVALID_OPERATION\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"OUT_OF_MEMORY\"] = 1285] = \"OUT_OF_MEMORY\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"CONTEXT_LOST_WEBGL\"] = 37442] = \"CONTEXT_LOST_WEBGL\";\n // Front face directions\n // Constants passed to frontFace().\n /** Passed to frontFace to specify the front face of a polygon is drawn in the clockwise direction */\n GLEnum[GLEnum[\"CW\"] = 2304] = \"CW\";\n /** Passed to frontFace to specify the front face of a polygon is drawn in the counter clockwise direction */\n GLEnum[GLEnum[\"CCW\"] = 2305] = \"CCW\";\n // Hints\n // Constants passed to hint()\n /** There is no preference for this behavior. */\n GLEnum[GLEnum[\"DONT_CARE\"] = 4352] = \"DONT_CARE\";\n /** The most efficient behavior should be used. */\n GLEnum[GLEnum[\"FASTEST\"] = 4353] = \"FASTEST\";\n /** The most correct or the highest quality option should be used. */\n GLEnum[GLEnum[\"NICEST\"] = 4354] = \"NICEST\";\n /** Hint for the quality of filtering when generating mipmap images with WebGLRenderingContext.generateMipmap(). */\n GLEnum[GLEnum[\"GENERATE_MIPMAP_HINT\"] = 33170] = \"GENERATE_MIPMAP_HINT\";\n // Data types\n GLEnum[GLEnum[\"BYTE\"] = 5120] = \"BYTE\";\n GLEnum[GLEnum[\"UNSIGNED_BYTE\"] = 5121] = \"UNSIGNED_BYTE\";\n GLEnum[GLEnum[\"SHORT\"] = 5122] = \"SHORT\";\n GLEnum[GLEnum[\"UNSIGNED_SHORT\"] = 5123] = \"UNSIGNED_SHORT\";\n GLEnum[GLEnum[\"INT\"] = 5124] = \"INT\";\n GLEnum[GLEnum[\"UNSIGNED_INT\"] = 5125] = \"UNSIGNED_INT\";\n GLEnum[GLEnum[\"FLOAT\"] = 5126] = \"FLOAT\";\n GLEnum[GLEnum[\"DOUBLE\"] = 5130] = \"DOUBLE\";\n // Pixel formats\n GLEnum[GLEnum[\"DEPTH_COMPONENT\"] = 6402] = \"DEPTH_COMPONENT\";\n GLEnum[GLEnum[\"ALPHA\"] = 6406] = \"ALPHA\";\n GLEnum[GLEnum[\"RGB\"] = 6407] = \"RGB\";\n GLEnum[GLEnum[\"RGBA\"] = 6408] = \"RGBA\";\n GLEnum[GLEnum[\"LUMINANCE\"] = 6409] = \"LUMINANCE\";\n GLEnum[GLEnum[\"LUMINANCE_ALPHA\"] = 6410] = \"LUMINANCE_ALPHA\";\n // Pixel types\n // UNSIGNED_BYTE = 0x1401,\n GLEnum[GLEnum[\"UNSIGNED_SHORT_4_4_4_4\"] = 32819] = \"UNSIGNED_SHORT_4_4_4_4\";\n GLEnum[GLEnum[\"UNSIGNED_SHORT_5_5_5_1\"] = 32820] = \"UNSIGNED_SHORT_5_5_5_1\";\n GLEnum[GLEnum[\"UNSIGNED_SHORT_5_6_5\"] = 33635] = \"UNSIGNED_SHORT_5_6_5\";\n // Shaders\n // Constants passed to createShader() or getShaderParameter()\n /** Passed to createShader to define a fragment shader. */\n GLEnum[GLEnum[\"FRAGMENT_SHADER\"] = 35632] = \"FRAGMENT_SHADER\";\n /** Passed to createShader to define a vertex shader */\n GLEnum[GLEnum[\"VERTEX_SHADER\"] = 35633] = \"VERTEX_SHADER\";\n /** Passed to getShaderParameter to get the status of the compilation. Returns false if the shader was not compiled. You can then query getShaderInfoLog to find the exact error */\n GLEnum[GLEnum[\"COMPILE_STATUS\"] = 35713] = \"COMPILE_STATUS\";\n /** Passed to getShaderParameter to determine if a shader was deleted via deleteShader. Returns true if it was, false otherwise. */\n GLEnum[GLEnum[\"DELETE_STATUS\"] = 35712] = \"DELETE_STATUS\";\n /** Passed to getProgramParameter after calling linkProgram to determine if a program was linked correctly. Returns false if there were errors. Use getProgramInfoLog to find the exact error. */\n GLEnum[GLEnum[\"LINK_STATUS\"] = 35714] = \"LINK_STATUS\";\n /** Passed to getProgramParameter after calling validateProgram to determine if it is valid. Returns false if errors were found. */\n GLEnum[GLEnum[\"VALIDATE_STATUS\"] = 35715] = \"VALIDATE_STATUS\";\n /** Passed to getProgramParameter after calling attachShader to determine if the shader was attached correctly. Returns false if errors occurred. */\n GLEnum[GLEnum[\"ATTACHED_SHADERS\"] = 35717] = \"ATTACHED_SHADERS\";\n /** Passed to getProgramParameter to get the number of attributes active in a program. */\n GLEnum[GLEnum[\"ACTIVE_ATTRIBUTES\"] = 35721] = \"ACTIVE_ATTRIBUTES\";\n /** Passed to getProgramParameter to get the number of uniforms active in a program. */\n GLEnum[GLEnum[\"ACTIVE_UNIFORMS\"] = 35718] = \"ACTIVE_UNIFORMS\";\n /** The maximum number of entries possible in the vertex attribute list. */\n GLEnum[GLEnum[\"MAX_VERTEX_ATTRIBS\"] = 34921] = \"MAX_VERTEX_ATTRIBS\";\n GLEnum[GLEnum[\"MAX_VERTEX_UNIFORM_VECTORS\"] = 36347] = \"MAX_VERTEX_UNIFORM_VECTORS\";\n GLEnum[GLEnum[\"MAX_VARYING_VECTORS\"] = 36348] = \"MAX_VARYING_VECTORS\";\n GLEnum[GLEnum[\"MAX_COMBINED_TEXTURE_IMAGE_UNITS\"] = 35661] = \"MAX_COMBINED_TEXTURE_IMAGE_UNITS\";\n GLEnum[GLEnum[\"MAX_VERTEX_TEXTURE_IMAGE_UNITS\"] = 35660] = \"MAX_VERTEX_TEXTURE_IMAGE_UNITS\";\n /** Implementation dependent number of maximum texture units. At least 8. */\n GLEnum[GLEnum[\"MAX_TEXTURE_IMAGE_UNITS\"] = 34930] = \"MAX_TEXTURE_IMAGE_UNITS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_UNIFORM_VECTORS\"] = 36349] = \"MAX_FRAGMENT_UNIFORM_VECTORS\";\n GLEnum[GLEnum[\"SHADER_TYPE\"] = 35663] = \"SHADER_TYPE\";\n GLEnum[GLEnum[\"SHADING_LANGUAGE_VERSION\"] = 35724] = \"SHADING_LANGUAGE_VERSION\";\n GLEnum[GLEnum[\"CURRENT_PROGRAM\"] = 35725] = \"CURRENT_PROGRAM\";\n // Depth or stencil tests\n // Constants passed to depthFunc() or stencilFunc().\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass, i.e., nothing will be drawn. */\n GLEnum[GLEnum[\"NEVER\"] = 512] = \"NEVER\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value. */\n GLEnum[GLEnum[\"LESS\"] = 513] = \"LESS\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value. */\n GLEnum[GLEnum[\"EQUAL\"] = 514] = \"EQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value. */\n GLEnum[GLEnum[\"LEQUAL\"] = 515] = \"LEQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value. */\n GLEnum[GLEnum[\"GREATER\"] = 516] = \"GREATER\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value. */\n GLEnum[GLEnum[\"NOTEQUAL\"] = 517] = \"NOTEQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value. */\n GLEnum[GLEnum[\"GEQUAL\"] = 518] = \"GEQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass, i.e., pixels will be drawn in the order they are drawn. */\n GLEnum[GLEnum[\"ALWAYS\"] = 519] = \"ALWAYS\";\n // Stencil actions\n // Constants passed to stencilOp().\n GLEnum[GLEnum[\"KEEP\"] = 7680] = \"KEEP\";\n GLEnum[GLEnum[\"REPLACE\"] = 7681] = \"REPLACE\";\n GLEnum[GLEnum[\"INCR\"] = 7682] = \"INCR\";\n GLEnum[GLEnum[\"DECR\"] = 7683] = \"DECR\";\n GLEnum[GLEnum[\"INVERT\"] = 5386] = \"INVERT\";\n GLEnum[GLEnum[\"INCR_WRAP\"] = 34055] = \"INCR_WRAP\";\n GLEnum[GLEnum[\"DECR_WRAP\"] = 34056] = \"DECR_WRAP\";\n // Textures\n // Constants passed to texParameteri(),\n // texParameterf(), bindTexture(), texImage2D(), and others.\n GLEnum[GLEnum[\"NEAREST\"] = 9728] = \"NEAREST\";\n GLEnum[GLEnum[\"LINEAR\"] = 9729] = \"LINEAR\";\n GLEnum[GLEnum[\"NEAREST_MIPMAP_NEAREST\"] = 9984] = \"NEAREST_MIPMAP_NEAREST\";\n GLEnum[GLEnum[\"LINEAR_MIPMAP_NEAREST\"] = 9985] = \"LINEAR_MIPMAP_NEAREST\";\n GLEnum[GLEnum[\"NEAREST_MIPMAP_LINEAR\"] = 9986] = \"NEAREST_MIPMAP_LINEAR\";\n GLEnum[GLEnum[\"LINEAR_MIPMAP_LINEAR\"] = 9987] = \"LINEAR_MIPMAP_LINEAR\";\n /** The texture magnification function is used when the pixel being textured maps to an area less than or equal to one texture element. It sets the texture magnification function to either GL_NEAREST or GL_LINEAR (see below). GL_NEAREST is generally faster than GL_LINEAR, but it can produce textured images with sharper edges because the transition between texture elements is not as smooth. Default: GL_LINEAR. */\n GLEnum[GLEnum[\"TEXTURE_MAG_FILTER\"] = 10240] = \"TEXTURE_MAG_FILTER\";\n /** The texture minifying function is used whenever the pixel being textured maps to an area greater than one texture element. There are six defined minifying functions. Two of them use the nearest one or nearest four texture elements to compute the texture value. The other four use mipmaps. Default: GL_NEAREST_MIPMAP_LINEAR */\n GLEnum[GLEnum[\"TEXTURE_MIN_FILTER\"] = 10241] = \"TEXTURE_MIN_FILTER\";\n /** Sets the wrap parameter for texture coordinate to either GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT. G */\n GLEnum[GLEnum[\"TEXTURE_WRAP_S\"] = 10242] = \"TEXTURE_WRAP_S\";\n /** Sets the wrap parameter for texture coordinate to either GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT. G */\n GLEnum[GLEnum[\"TEXTURE_WRAP_T\"] = 10243] = \"TEXTURE_WRAP_T\";\n GLEnum[GLEnum[\"TEXTURE_2D\"] = 3553] = \"TEXTURE_2D\";\n GLEnum[GLEnum[\"TEXTURE\"] = 5890] = \"TEXTURE\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP\"] = 34067] = \"TEXTURE_CUBE_MAP\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_CUBE_MAP\"] = 34068] = \"TEXTURE_BINDING_CUBE_MAP\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_POSITIVE_X\"] = 34069] = \"TEXTURE_CUBE_MAP_POSITIVE_X\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_NEGATIVE_X\"] = 34070] = \"TEXTURE_CUBE_MAP_NEGATIVE_X\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_POSITIVE_Y\"] = 34071] = \"TEXTURE_CUBE_MAP_POSITIVE_Y\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_NEGATIVE_Y\"] = 34072] = \"TEXTURE_CUBE_MAP_NEGATIVE_Y\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_POSITIVE_Z\"] = 34073] = \"TEXTURE_CUBE_MAP_POSITIVE_Z\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_NEGATIVE_Z\"] = 34074] = \"TEXTURE_CUBE_MAP_NEGATIVE_Z\";\n GLEnum[GLEnum[\"MAX_CUBE_MAP_TEXTURE_SIZE\"] = 34076] = \"MAX_CUBE_MAP_TEXTURE_SIZE\";\n // TEXTURE0 - 31 0x84C0 - 0x84DF A texture unit.\n GLEnum[GLEnum[\"TEXTURE0\"] = 33984] = \"TEXTURE0\";\n GLEnum[GLEnum[\"ACTIVE_TEXTURE\"] = 34016] = \"ACTIVE_TEXTURE\";\n GLEnum[GLEnum[\"REPEAT\"] = 10497] = \"REPEAT\";\n GLEnum[GLEnum[\"CLAMP_TO_EDGE\"] = 33071] = \"CLAMP_TO_EDGE\";\n GLEnum[GLEnum[\"MIRRORED_REPEAT\"] = 33648] = \"MIRRORED_REPEAT\";\n // Emulation\n GLEnum[GLEnum[\"TEXTURE_WIDTH\"] = 4096] = \"TEXTURE_WIDTH\";\n GLEnum[GLEnum[\"TEXTURE_HEIGHT\"] = 4097] = \"TEXTURE_HEIGHT\";\n // Uniform types\n GLEnum[GLEnum[\"FLOAT_VEC2\"] = 35664] = \"FLOAT_VEC2\";\n GLEnum[GLEnum[\"FLOAT_VEC3\"] = 35665] = \"FLOAT_VEC3\";\n GLEnum[GLEnum[\"FLOAT_VEC4\"] = 35666] = \"FLOAT_VEC4\";\n GLEnum[GLEnum[\"INT_VEC2\"] = 35667] = \"INT_VEC2\";\n GLEnum[GLEnum[\"INT_VEC3\"] = 35668] = \"INT_VEC3\";\n GLEnum[GLEnum[\"INT_VEC4\"] = 35669] = \"INT_VEC4\";\n GLEnum[GLEnum[\"BOOL\"] = 35670] = \"BOOL\";\n GLEnum[GLEnum[\"BOOL_VEC2\"] = 35671] = \"BOOL_VEC2\";\n GLEnum[GLEnum[\"BOOL_VEC3\"] = 35672] = \"BOOL_VEC3\";\n GLEnum[GLEnum[\"BOOL_VEC4\"] = 35673] = \"BOOL_VEC4\";\n GLEnum[GLEnum[\"FLOAT_MAT2\"] = 35674] = \"FLOAT_MAT2\";\n GLEnum[GLEnum[\"FLOAT_MAT3\"] = 35675] = \"FLOAT_MAT3\";\n GLEnum[GLEnum[\"FLOAT_MAT4\"] = 35676] = \"FLOAT_MAT4\";\n GLEnum[GLEnum[\"SAMPLER_2D\"] = 35678] = \"SAMPLER_2D\";\n GLEnum[GLEnum[\"SAMPLER_CUBE\"] = 35680] = \"SAMPLER_CUBE\";\n // Shader precision-specified types\n GLEnum[GLEnum[\"LOW_FLOAT\"] = 36336] = \"LOW_FLOAT\";\n GLEnum[GLEnum[\"MEDIUM_FLOAT\"] = 36337] = \"MEDIUM_FLOAT\";\n GLEnum[GLEnum[\"HIGH_FLOAT\"] = 36338] = \"HIGH_FLOAT\";\n GLEnum[GLEnum[\"LOW_INT\"] = 36339] = \"LOW_INT\";\n GLEnum[GLEnum[\"MEDIUM_INT\"] = 36340] = \"MEDIUM_INT\";\n GLEnum[GLEnum[\"HIGH_INT\"] = 36341] = \"HIGH_INT\";\n // Framebuffers and renderbuffers\n GLEnum[GLEnum[\"FRAMEBUFFER\"] = 36160] = \"FRAMEBUFFER\";\n GLEnum[GLEnum[\"RENDERBUFFER\"] = 36161] = \"RENDERBUFFER\";\n GLEnum[GLEnum[\"RGBA4\"] = 32854] = \"RGBA4\";\n GLEnum[GLEnum[\"RGB5_A1\"] = 32855] = \"RGB5_A1\";\n GLEnum[GLEnum[\"RGB565\"] = 36194] = \"RGB565\";\n GLEnum[GLEnum[\"DEPTH_COMPONENT16\"] = 33189] = \"DEPTH_COMPONENT16\";\n GLEnum[GLEnum[\"STENCIL_INDEX\"] = 6401] = \"STENCIL_INDEX\";\n GLEnum[GLEnum[\"STENCIL_INDEX8\"] = 36168] = \"STENCIL_INDEX8\";\n GLEnum[GLEnum[\"DEPTH_STENCIL\"] = 34041] = \"DEPTH_STENCIL\";\n GLEnum[GLEnum[\"RENDERBUFFER_WIDTH\"] = 36162] = \"RENDERBUFFER_WIDTH\";\n GLEnum[GLEnum[\"RENDERBUFFER_HEIGHT\"] = 36163] = \"RENDERBUFFER_HEIGHT\";\n GLEnum[GLEnum[\"RENDERBUFFER_INTERNAL_FORMAT\"] = 36164] = \"RENDERBUFFER_INTERNAL_FORMAT\";\n GLEnum[GLEnum[\"RENDERBUFFER_RED_SIZE\"] = 36176] = \"RENDERBUFFER_RED_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_GREEN_SIZE\"] = 36177] = \"RENDERBUFFER_GREEN_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_BLUE_SIZE\"] = 36178] = \"RENDERBUFFER_BLUE_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_ALPHA_SIZE\"] = 36179] = \"RENDERBUFFER_ALPHA_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_DEPTH_SIZE\"] = 36180] = \"RENDERBUFFER_DEPTH_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_STENCIL_SIZE\"] = 36181] = \"RENDERBUFFER_STENCIL_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE\"] = 36048] = \"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME\"] = 36049] = \"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL\"] = 36050] = \"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE\"] = 36051] = \"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT0\"] = 36064] = \"COLOR_ATTACHMENT0\";\n GLEnum[GLEnum[\"DEPTH_ATTACHMENT\"] = 36096] = \"DEPTH_ATTACHMENT\";\n GLEnum[GLEnum[\"STENCIL_ATTACHMENT\"] = 36128] = \"STENCIL_ATTACHMENT\";\n GLEnum[GLEnum[\"DEPTH_STENCIL_ATTACHMENT\"] = 33306] = \"DEPTH_STENCIL_ATTACHMENT\";\n GLEnum[GLEnum[\"NONE\"] = 0] = \"NONE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_COMPLETE\"] = 36053] = \"FRAMEBUFFER_COMPLETE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_ATTACHMENT\"] = 36054] = \"FRAMEBUFFER_INCOMPLETE_ATTACHMENT\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\"] = 36055] = \"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_DIMENSIONS\"] = 36057] = \"FRAMEBUFFER_INCOMPLETE_DIMENSIONS\";\n GLEnum[GLEnum[\"FRAMEBUFFER_UNSUPPORTED\"] = 36061] = \"FRAMEBUFFER_UNSUPPORTED\";\n GLEnum[GLEnum[\"FRAMEBUFFER_BINDING\"] = 36006] = \"FRAMEBUFFER_BINDING\";\n GLEnum[GLEnum[\"RENDERBUFFER_BINDING\"] = 36007] = \"RENDERBUFFER_BINDING\";\n GLEnum[GLEnum[\"READ_FRAMEBUFFER\"] = 36008] = \"READ_FRAMEBUFFER\";\n GLEnum[GLEnum[\"DRAW_FRAMEBUFFER\"] = 36009] = \"DRAW_FRAMEBUFFER\";\n GLEnum[GLEnum[\"MAX_RENDERBUFFER_SIZE\"] = 34024] = \"MAX_RENDERBUFFER_SIZE\";\n GLEnum[GLEnum[\"INVALID_FRAMEBUFFER_OPERATION\"] = 1286] = \"INVALID_FRAMEBUFFER_OPERATION\";\n // Pixel storage modes\n // Constants passed to pixelStorei().\n GLEnum[GLEnum[\"UNPACK_FLIP_Y_WEBGL\"] = 37440] = \"UNPACK_FLIP_Y_WEBGL\";\n GLEnum[GLEnum[\"UNPACK_PREMULTIPLY_ALPHA_WEBGL\"] = 37441] = \"UNPACK_PREMULTIPLY_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"UNPACK_COLORSPACE_CONVERSION_WEBGL\"] = 37443] = \"UNPACK_COLORSPACE_CONVERSION_WEBGL\";\n // Additional constants defined WebGL 2\n // These constants are defined on the WebGL2RenderingContext interface.\n // All WebGL 1 constants are also available in a WebGL 2 context.\n // Getting GL parameter information\n // Constants passed to getParameter()\n // to specify what information to return.\n GLEnum[GLEnum[\"READ_BUFFER\"] = 3074] = \"READ_BUFFER\";\n GLEnum[GLEnum[\"UNPACK_ROW_LENGTH\"] = 3314] = \"UNPACK_ROW_LENGTH\";\n GLEnum[GLEnum[\"UNPACK_SKIP_ROWS\"] = 3315] = \"UNPACK_SKIP_ROWS\";\n GLEnum[GLEnum[\"UNPACK_SKIP_PIXELS\"] = 3316] = \"UNPACK_SKIP_PIXELS\";\n GLEnum[GLEnum[\"PACK_ROW_LENGTH\"] = 3330] = \"PACK_ROW_LENGTH\";\n GLEnum[GLEnum[\"PACK_SKIP_ROWS\"] = 3331] = \"PACK_SKIP_ROWS\";\n GLEnum[GLEnum[\"PACK_SKIP_PIXELS\"] = 3332] = \"PACK_SKIP_PIXELS\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_3D\"] = 32874] = \"TEXTURE_BINDING_3D\";\n GLEnum[GLEnum[\"UNPACK_SKIP_IMAGES\"] = 32877] = \"UNPACK_SKIP_IMAGES\";\n GLEnum[GLEnum[\"UNPACK_IMAGE_HEIGHT\"] = 32878] = \"UNPACK_IMAGE_HEIGHT\";\n GLEnum[GLEnum[\"MAX_3D_TEXTURE_SIZE\"] = 32883] = \"MAX_3D_TEXTURE_SIZE\";\n GLEnum[GLEnum[\"MAX_ELEMENTS_VERTICES\"] = 33000] = \"MAX_ELEMENTS_VERTICES\";\n GLEnum[GLEnum[\"MAX_ELEMENTS_INDICES\"] = 33001] = \"MAX_ELEMENTS_INDICES\";\n GLEnum[GLEnum[\"MAX_TEXTURE_LOD_BIAS\"] = 34045] = \"MAX_TEXTURE_LOD_BIAS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_UNIFORM_COMPONENTS\"] = 35657] = \"MAX_FRAGMENT_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_VERTEX_UNIFORM_COMPONENTS\"] = 35658] = \"MAX_VERTEX_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_ARRAY_TEXTURE_LAYERS\"] = 35071] = \"MAX_ARRAY_TEXTURE_LAYERS\";\n GLEnum[GLEnum[\"MIN_PROGRAM_TEXEL_OFFSET\"] = 35076] = \"MIN_PROGRAM_TEXEL_OFFSET\";\n GLEnum[GLEnum[\"MAX_PROGRAM_TEXEL_OFFSET\"] = 35077] = \"MAX_PROGRAM_TEXEL_OFFSET\";\n GLEnum[GLEnum[\"MAX_VARYING_COMPONENTS\"] = 35659] = \"MAX_VARYING_COMPONENTS\";\n GLEnum[GLEnum[\"FRAGMENT_SHADER_DERIVATIVE_HINT\"] = 35723] = \"FRAGMENT_SHADER_DERIVATIVE_HINT\";\n GLEnum[GLEnum[\"RASTERIZER_DISCARD\"] = 35977] = \"RASTERIZER_DISCARD\";\n GLEnum[GLEnum[\"VERTEX_ARRAY_BINDING\"] = 34229] = \"VERTEX_ARRAY_BINDING\";\n GLEnum[GLEnum[\"MAX_VERTEX_OUTPUT_COMPONENTS\"] = 37154] = \"MAX_VERTEX_OUTPUT_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_INPUT_COMPONENTS\"] = 37157] = \"MAX_FRAGMENT_INPUT_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_SERVER_WAIT_TIMEOUT\"] = 37137] = \"MAX_SERVER_WAIT_TIMEOUT\";\n GLEnum[GLEnum[\"MAX_ELEMENT_INDEX\"] = 36203] = \"MAX_ELEMENT_INDEX\";\n // Textures\n // Constants passed to texParameteri(),\n // texParameterf(), bindTexture(), texImage2D(), and others.\n GLEnum[GLEnum[\"RED\"] = 6403] = \"RED\";\n GLEnum[GLEnum[\"RGB8\"] = 32849] = \"RGB8\";\n GLEnum[GLEnum[\"RGBA8\"] = 32856] = \"RGBA8\";\n GLEnum[GLEnum[\"RGB10_A2\"] = 32857] = \"RGB10_A2\";\n GLEnum[GLEnum[\"TEXTURE_3D\"] = 32879] = \"TEXTURE_3D\";\n /** Sets the wrap parameter for texture coordinate to either GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT. G */\n GLEnum[GLEnum[\"TEXTURE_WRAP_R\"] = 32882] = \"TEXTURE_WRAP_R\";\n GLEnum[GLEnum[\"TEXTURE_MIN_LOD\"] = 33082] = \"TEXTURE_MIN_LOD\";\n GLEnum[GLEnum[\"TEXTURE_MAX_LOD\"] = 33083] = \"TEXTURE_MAX_LOD\";\n GLEnum[GLEnum[\"TEXTURE_BASE_LEVEL\"] = 33084] = \"TEXTURE_BASE_LEVEL\";\n GLEnum[GLEnum[\"TEXTURE_MAX_LEVEL\"] = 33085] = \"TEXTURE_MAX_LEVEL\";\n GLEnum[GLEnum[\"TEXTURE_COMPARE_MODE\"] = 34892] = \"TEXTURE_COMPARE_MODE\";\n GLEnum[GLEnum[\"TEXTURE_COMPARE_FUNC\"] = 34893] = \"TEXTURE_COMPARE_FUNC\";\n GLEnum[GLEnum[\"SRGB\"] = 35904] = \"SRGB\";\n GLEnum[GLEnum[\"SRGB8\"] = 35905] = \"SRGB8\";\n GLEnum[GLEnum[\"SRGB8_ALPHA8\"] = 35907] = \"SRGB8_ALPHA8\";\n GLEnum[GLEnum[\"COMPARE_REF_TO_TEXTURE\"] = 34894] = \"COMPARE_REF_TO_TEXTURE\";\n GLEnum[GLEnum[\"RGBA32F\"] = 34836] = \"RGBA32F\";\n GLEnum[GLEnum[\"RGB32F\"] = 34837] = \"RGB32F\";\n GLEnum[GLEnum[\"RGBA16F\"] = 34842] = \"RGBA16F\";\n GLEnum[GLEnum[\"RGB16F\"] = 34843] = \"RGB16F\";\n GLEnum[GLEnum[\"TEXTURE_2D_ARRAY\"] = 35866] = \"TEXTURE_2D_ARRAY\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_2D_ARRAY\"] = 35869] = \"TEXTURE_BINDING_2D_ARRAY\";\n GLEnum[GLEnum[\"R11F_G11F_B10F\"] = 35898] = \"R11F_G11F_B10F\";\n GLEnum[GLEnum[\"RGB9_E5\"] = 35901] = \"RGB9_E5\";\n GLEnum[GLEnum[\"RGBA32UI\"] = 36208] = \"RGBA32UI\";\n GLEnum[GLEnum[\"RGB32UI\"] = 36209] = \"RGB32UI\";\n GLEnum[GLEnum[\"RGBA16UI\"] = 36214] = \"RGBA16UI\";\n GLEnum[GLEnum[\"RGB16UI\"] = 36215] = \"RGB16UI\";\n GLEnum[GLEnum[\"RGBA8UI\"] = 36220] = \"RGBA8UI\";\n GLEnum[GLEnum[\"RGB8UI\"] = 36221] = \"RGB8UI\";\n GLEnum[GLEnum[\"RGBA32I\"] = 36226] = \"RGBA32I\";\n GLEnum[GLEnum[\"RGB32I\"] = 36227] = \"RGB32I\";\n GLEnum[GLEnum[\"RGBA16I\"] = 36232] = \"RGBA16I\";\n GLEnum[GLEnum[\"RGB16I\"] = 36233] = \"RGB16I\";\n GLEnum[GLEnum[\"RGBA8I\"] = 36238] = \"RGBA8I\";\n GLEnum[GLEnum[\"RGB8I\"] = 36239] = \"RGB8I\";\n GLEnum[GLEnum[\"RED_INTEGER\"] = 36244] = \"RED_INTEGER\";\n GLEnum[GLEnum[\"RGB_INTEGER\"] = 36248] = \"RGB_INTEGER\";\n GLEnum[GLEnum[\"RGBA_INTEGER\"] = 36249] = \"RGBA_INTEGER\";\n GLEnum[GLEnum[\"R8\"] = 33321] = \"R8\";\n GLEnum[GLEnum[\"RG8\"] = 33323] = \"RG8\";\n GLEnum[GLEnum[\"R16F\"] = 33325] = \"R16F\";\n GLEnum[GLEnum[\"R32F\"] = 33326] = \"R32F\";\n GLEnum[GLEnum[\"RG16F\"] = 33327] = \"RG16F\";\n GLEnum[GLEnum[\"RG32F\"] = 33328] = \"RG32F\";\n GLEnum[GLEnum[\"R8I\"] = 33329] = \"R8I\";\n GLEnum[GLEnum[\"R8UI\"] = 33330] = \"R8UI\";\n GLEnum[GLEnum[\"R16I\"] = 33331] = \"R16I\";\n GLEnum[GLEnum[\"R16UI\"] = 33332] = \"R16UI\";\n GLEnum[GLEnum[\"R32I\"] = 33333] = \"R32I\";\n GLEnum[GLEnum[\"R32UI\"] = 33334] = \"R32UI\";\n GLEnum[GLEnum[\"RG8I\"] = 33335] = \"RG8I\";\n GLEnum[GLEnum[\"RG8UI\"] = 33336] = \"RG8UI\";\n GLEnum[GLEnum[\"RG16I\"] = 33337] = \"RG16I\";\n GLEnum[GLEnum[\"RG16UI\"] = 33338] = \"RG16UI\";\n GLEnum[GLEnum[\"RG32I\"] = 33339] = \"RG32I\";\n GLEnum[GLEnum[\"RG32UI\"] = 33340] = \"RG32UI\";\n GLEnum[GLEnum[\"R8_SNORM\"] = 36756] = \"R8_SNORM\";\n GLEnum[GLEnum[\"RG8_SNORM\"] = 36757] = \"RG8_SNORM\";\n GLEnum[GLEnum[\"RGB8_SNORM\"] = 36758] = \"RGB8_SNORM\";\n GLEnum[GLEnum[\"RGBA8_SNORM\"] = 36759] = \"RGBA8_SNORM\";\n GLEnum[GLEnum[\"RGB10_A2UI\"] = 36975] = \"RGB10_A2UI\";\n /* covered by extension\n COMPRESSED_R11_EAC = 0x9270,\n COMPRESSED_SIGNED_R11_EAC = 0x9271,\n COMPRESSED_RG11_EAC = 0x9272,\n COMPRESSED_SIGNED_RG11_EAC = 0x9273,\n COMPRESSED_RGB8_ETC2 = 0x9274,\n COMPRESSED_SRGB8_ETC2 = 0x9275,\n COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276,\n COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC = 0x9277,\n COMPRESSED_RGBA8_ETC2_EAC = 0x9278,\n COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279,\n */\n GLEnum[GLEnum[\"TEXTURE_IMMUTABLE_FORMAT\"] = 37167] = \"TEXTURE_IMMUTABLE_FORMAT\";\n GLEnum[GLEnum[\"TEXTURE_IMMUTABLE_LEVELS\"] = 33503] = \"TEXTURE_IMMUTABLE_LEVELS\";\n // Pixel types\n GLEnum[GLEnum[\"UNSIGNED_INT_2_10_10_10_REV\"] = 33640] = \"UNSIGNED_INT_2_10_10_10_REV\";\n GLEnum[GLEnum[\"UNSIGNED_INT_10F_11F_11F_REV\"] = 35899] = \"UNSIGNED_INT_10F_11F_11F_REV\";\n GLEnum[GLEnum[\"UNSIGNED_INT_5_9_9_9_REV\"] = 35902] = \"UNSIGNED_INT_5_9_9_9_REV\";\n GLEnum[GLEnum[\"FLOAT_32_UNSIGNED_INT_24_8_REV\"] = 36269] = \"FLOAT_32_UNSIGNED_INT_24_8_REV\";\n GLEnum[GLEnum[\"UNSIGNED_INT_24_8\"] = 34042] = \"UNSIGNED_INT_24_8\";\n GLEnum[GLEnum[\"HALF_FLOAT\"] = 5131] = \"HALF_FLOAT\";\n GLEnum[GLEnum[\"RG\"] = 33319] = \"RG\";\n GLEnum[GLEnum[\"RG_INTEGER\"] = 33320] = \"RG_INTEGER\";\n GLEnum[GLEnum[\"INT_2_10_10_10_REV\"] = 36255] = \"INT_2_10_10_10_REV\";\n // Queries\n GLEnum[GLEnum[\"CURRENT_QUERY\"] = 34917] = \"CURRENT_QUERY\";\n /** Returns a GLuint containing the query result. */\n GLEnum[GLEnum[\"QUERY_RESULT\"] = 34918] = \"QUERY_RESULT\";\n /** Whether query result is available. */\n GLEnum[GLEnum[\"QUERY_RESULT_AVAILABLE\"] = 34919] = \"QUERY_RESULT_AVAILABLE\";\n /** Occlusion query (if drawing passed depth test) */\n GLEnum[GLEnum[\"ANY_SAMPLES_PASSED\"] = 35887] = \"ANY_SAMPLES_PASSED\";\n /** Occlusion query less accurate/faster version */\n GLEnum[GLEnum[\"ANY_SAMPLES_PASSED_CONSERVATIVE\"] = 36202] = \"ANY_SAMPLES_PASSED_CONSERVATIVE\";\n // Draw buffers\n GLEnum[GLEnum[\"MAX_DRAW_BUFFERS\"] = 34852] = \"MAX_DRAW_BUFFERS\";\n GLEnum[GLEnum[\"DRAW_BUFFER0\"] = 34853] = \"DRAW_BUFFER0\";\n GLEnum[GLEnum[\"DRAW_BUFFER1\"] = 34854] = \"DRAW_BUFFER1\";\n GLEnum[GLEnum[\"DRAW_BUFFER2\"] = 34855] = \"DRAW_BUFFER2\";\n GLEnum[GLEnum[\"DRAW_BUFFER3\"] = 34856] = \"DRAW_BUFFER3\";\n GLEnum[GLEnum[\"DRAW_BUFFER4\"] = 34857] = \"DRAW_BUFFER4\";\n GLEnum[GLEnum[\"DRAW_BUFFER5\"] = 34858] = \"DRAW_BUFFER5\";\n GLEnum[GLEnum[\"DRAW_BUFFER6\"] = 34859] = \"DRAW_BUFFER6\";\n GLEnum[GLEnum[\"DRAW_BUFFER7\"] = 34860] = \"DRAW_BUFFER7\";\n GLEnum[GLEnum[\"DRAW_BUFFER8\"] = 34861] = \"DRAW_BUFFER8\";\n GLEnum[GLEnum[\"DRAW_BUFFER9\"] = 34862] = \"DRAW_BUFFER9\";\n GLEnum[GLEnum[\"DRAW_BUFFER10\"] = 34863] = \"DRAW_BUFFER10\";\n GLEnum[GLEnum[\"DRAW_BUFFER11\"] = 34864] = \"DRAW_BUFFER11\";\n GLEnum[GLEnum[\"DRAW_BUFFER12\"] = 34865] = \"DRAW_BUFFER12\";\n GLEnum[GLEnum[\"DRAW_BUFFER13\"] = 34866] = \"DRAW_BUFFER13\";\n GLEnum[GLEnum[\"DRAW_BUFFER14\"] = 34867] = \"DRAW_BUFFER14\";\n GLEnum[GLEnum[\"DRAW_BUFFER15\"] = 34868] = \"DRAW_BUFFER15\";\n GLEnum[GLEnum[\"MAX_COLOR_ATTACHMENTS\"] = 36063] = \"MAX_COLOR_ATTACHMENTS\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT1\"] = 36065] = \"COLOR_ATTACHMENT1\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT2\"] = 36066] = \"COLOR_ATTACHMENT2\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT3\"] = 36067] = \"COLOR_ATTACHMENT3\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT4\"] = 36068] = \"COLOR_ATTACHMENT4\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT5\"] = 36069] = \"COLOR_ATTACHMENT5\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT6\"] = 36070] = \"COLOR_ATTACHMENT6\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT7\"] = 36071] = \"COLOR_ATTACHMENT7\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT8\"] = 36072] = \"COLOR_ATTACHMENT8\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT9\"] = 36073] = \"COLOR_ATTACHMENT9\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT10\"] = 36074] = \"COLOR_ATTACHMENT10\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT11\"] = 36075] = \"COLOR_ATTACHMENT11\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT12\"] = 36076] = \"COLOR_ATTACHMENT12\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT13\"] = 36077] = \"COLOR_ATTACHMENT13\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT14\"] = 36078] = \"COLOR_ATTACHMENT14\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT15\"] = 36079] = \"COLOR_ATTACHMENT15\";\n // Samplers\n GLEnum[GLEnum[\"SAMPLER_3D\"] = 35679] = \"SAMPLER_3D\";\n GLEnum[GLEnum[\"SAMPLER_2D_SHADOW\"] = 35682] = \"SAMPLER_2D_SHADOW\";\n GLEnum[GLEnum[\"SAMPLER_2D_ARRAY\"] = 36289] = \"SAMPLER_2D_ARRAY\";\n GLEnum[GLEnum[\"SAMPLER_2D_ARRAY_SHADOW\"] = 36292] = \"SAMPLER_2D_ARRAY_SHADOW\";\n GLEnum[GLEnum[\"SAMPLER_CUBE_SHADOW\"] = 36293] = \"SAMPLER_CUBE_SHADOW\";\n GLEnum[GLEnum[\"INT_SAMPLER_2D\"] = 36298] = \"INT_SAMPLER_2D\";\n GLEnum[GLEnum[\"INT_SAMPLER_3D\"] = 36299] = \"INT_SAMPLER_3D\";\n GLEnum[GLEnum[\"INT_SAMPLER_CUBE\"] = 36300] = \"INT_SAMPLER_CUBE\";\n GLEnum[GLEnum[\"INT_SAMPLER_2D_ARRAY\"] = 36303] = \"INT_SAMPLER_2D_ARRAY\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_2D\"] = 36306] = \"UNSIGNED_INT_SAMPLER_2D\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_3D\"] = 36307] = \"UNSIGNED_INT_SAMPLER_3D\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_CUBE\"] = 36308] = \"UNSIGNED_INT_SAMPLER_CUBE\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_2D_ARRAY\"] = 36311] = \"UNSIGNED_INT_SAMPLER_2D_ARRAY\";\n GLEnum[GLEnum[\"MAX_SAMPLES\"] = 36183] = \"MAX_SAMPLES\";\n GLEnum[GLEnum[\"SAMPLER_BINDING\"] = 35097] = \"SAMPLER_BINDING\";\n // Buffers\n GLEnum[GLEnum[\"PIXEL_PACK_BUFFER\"] = 35051] = \"PIXEL_PACK_BUFFER\";\n GLEnum[GLEnum[\"PIXEL_UNPACK_BUFFER\"] = 35052] = \"PIXEL_UNPACK_BUFFER\";\n GLEnum[GLEnum[\"PIXEL_PACK_BUFFER_BINDING\"] = 35053] = \"PIXEL_PACK_BUFFER_BINDING\";\n GLEnum[GLEnum[\"PIXEL_UNPACK_BUFFER_BINDING\"] = 35055] = \"PIXEL_UNPACK_BUFFER_BINDING\";\n GLEnum[GLEnum[\"COPY_READ_BUFFER\"] = 36662] = \"COPY_READ_BUFFER\";\n GLEnum[GLEnum[\"COPY_WRITE_BUFFER\"] = 36663] = \"COPY_WRITE_BUFFER\";\n GLEnum[GLEnum[\"COPY_READ_BUFFER_BINDING\"] = 36662] = \"COPY_READ_BUFFER_BINDING\";\n GLEnum[GLEnum[\"COPY_WRITE_BUFFER_BINDING\"] = 36663] = \"COPY_WRITE_BUFFER_BINDING\";\n // Data types\n GLEnum[GLEnum[\"FLOAT_MAT2x3\"] = 35685] = \"FLOAT_MAT2x3\";\n GLEnum[GLEnum[\"FLOAT_MAT2x4\"] = 35686] = \"FLOAT_MAT2x4\";\n GLEnum[GLEnum[\"FLOAT_MAT3x2\"] = 35687] = \"FLOAT_MAT3x2\";\n GLEnum[GLEnum[\"FLOAT_MAT3x4\"] = 35688] = \"FLOAT_MAT3x4\";\n GLEnum[GLEnum[\"FLOAT_MAT4x2\"] = 35689] = \"FLOAT_MAT4x2\";\n GLEnum[GLEnum[\"FLOAT_MAT4x3\"] = 35690] = \"FLOAT_MAT4x3\";\n GLEnum[GLEnum[\"UNSIGNED_INT_VEC2\"] = 36294] = \"UNSIGNED_INT_VEC2\";\n GLEnum[GLEnum[\"UNSIGNED_INT_VEC3\"] = 36295] = \"UNSIGNED_INT_VEC3\";\n GLEnum[GLEnum[\"UNSIGNED_INT_VEC4\"] = 36296] = \"UNSIGNED_INT_VEC4\";\n GLEnum[GLEnum[\"UNSIGNED_NORMALIZED\"] = 35863] = \"UNSIGNED_NORMALIZED\";\n GLEnum[GLEnum[\"SIGNED_NORMALIZED\"] = 36764] = \"SIGNED_NORMALIZED\";\n // Vertex attributes\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_INTEGER\"] = 35069] = \"VERTEX_ATTRIB_ARRAY_INTEGER\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_DIVISOR\"] = 35070] = \"VERTEX_ATTRIB_ARRAY_DIVISOR\";\n // Transform feedback\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_MODE\"] = 35967] = \"TRANSFORM_FEEDBACK_BUFFER_MODE\";\n GLEnum[GLEnum[\"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS\"] = 35968] = \"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_VARYINGS\"] = 35971] = \"TRANSFORM_FEEDBACK_VARYINGS\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_START\"] = 35972] = \"TRANSFORM_FEEDBACK_BUFFER_START\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_SIZE\"] = 35973] = \"TRANSFORM_FEEDBACK_BUFFER_SIZE\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN\"] = 35976] = \"TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN\";\n GLEnum[GLEnum[\"MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS\"] = 35978] = \"MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS\"] = 35979] = \"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS\";\n GLEnum[GLEnum[\"INTERLEAVED_ATTRIBS\"] = 35980] = \"INTERLEAVED_ATTRIBS\";\n GLEnum[GLEnum[\"SEPARATE_ATTRIBS\"] = 35981] = \"SEPARATE_ATTRIBS\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER\"] = 35982] = \"TRANSFORM_FEEDBACK_BUFFER\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_BINDING\"] = 35983] = \"TRANSFORM_FEEDBACK_BUFFER_BINDING\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK\"] = 36386] = \"TRANSFORM_FEEDBACK\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_PAUSED\"] = 36387] = \"TRANSFORM_FEEDBACK_PAUSED\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_ACTIVE\"] = 36388] = \"TRANSFORM_FEEDBACK_ACTIVE\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BINDING\"] = 36389] = \"TRANSFORM_FEEDBACK_BINDING\";\n // Framebuffers and renderbuffers\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING\"] = 33296] = \"FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE\"] = 33297] = \"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_RED_SIZE\"] = 33298] = \"FRAMEBUFFER_ATTACHMENT_RED_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_GREEN_SIZE\"] = 33299] = \"FRAMEBUFFER_ATTACHMENT_GREEN_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_BLUE_SIZE\"] = 33300] = \"FRAMEBUFFER_ATTACHMENT_BLUE_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE\"] = 33301] = \"FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE\"] = 33302] = \"FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE\"] = 33303] = \"FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_DEFAULT\"] = 33304] = \"FRAMEBUFFER_DEFAULT\";\n // DEPTH_STENCIL_ATTACHMENT = 0x821A,\n // DEPTH_STENCIL = 0x84F9,\n GLEnum[GLEnum[\"DEPTH24_STENCIL8\"] = 35056] = \"DEPTH24_STENCIL8\";\n GLEnum[GLEnum[\"DRAW_FRAMEBUFFER_BINDING\"] = 36006] = \"DRAW_FRAMEBUFFER_BINDING\";\n GLEnum[GLEnum[\"READ_FRAMEBUFFER_BINDING\"] = 36010] = \"READ_FRAMEBUFFER_BINDING\";\n GLEnum[GLEnum[\"RENDERBUFFER_SAMPLES\"] = 36011] = \"RENDERBUFFER_SAMPLES\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER\"] = 36052] = \"FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\"] = 36182] = \"FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\";\n // Uniforms\n GLEnum[GLEnum[\"UNIFORM_BUFFER\"] = 35345] = \"UNIFORM_BUFFER\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_BINDING\"] = 35368] = \"UNIFORM_BUFFER_BINDING\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_START\"] = 35369] = \"UNIFORM_BUFFER_START\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_SIZE\"] = 35370] = \"UNIFORM_BUFFER_SIZE\";\n GLEnum[GLEnum[\"MAX_VERTEX_UNIFORM_BLOCKS\"] = 35371] = \"MAX_VERTEX_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_UNIFORM_BLOCKS\"] = 35373] = \"MAX_FRAGMENT_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"MAX_COMBINED_UNIFORM_BLOCKS\"] = 35374] = \"MAX_COMBINED_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"MAX_UNIFORM_BUFFER_BINDINGS\"] = 35375] = \"MAX_UNIFORM_BUFFER_BINDINGS\";\n GLEnum[GLEnum[\"MAX_UNIFORM_BLOCK_SIZE\"] = 35376] = \"MAX_UNIFORM_BLOCK_SIZE\";\n GLEnum[GLEnum[\"MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS\"] = 35377] = \"MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS\"] = 35379] = \"MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_OFFSET_ALIGNMENT\"] = 35380] = \"UNIFORM_BUFFER_OFFSET_ALIGNMENT\";\n GLEnum[GLEnum[\"ACTIVE_UNIFORM_BLOCKS\"] = 35382] = \"ACTIVE_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"UNIFORM_TYPE\"] = 35383] = \"UNIFORM_TYPE\";\n GLEnum[GLEnum[\"UNIFORM_SIZE\"] = 35384] = \"UNIFORM_SIZE\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_INDEX\"] = 35386] = \"UNIFORM_BLOCK_INDEX\";\n GLEnum[GLEnum[\"UNIFORM_OFFSET\"] = 35387] = \"UNIFORM_OFFSET\";\n GLEnum[GLEnum[\"UNIFORM_ARRAY_STRIDE\"] = 35388] = \"UNIFORM_ARRAY_STRIDE\";\n GLEnum[GLEnum[\"UNIFORM_MATRIX_STRIDE\"] = 35389] = \"UNIFORM_MATRIX_STRIDE\";\n GLEnum[GLEnum[\"UNIFORM_IS_ROW_MAJOR\"] = 35390] = \"UNIFORM_IS_ROW_MAJOR\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_BINDING\"] = 35391] = \"UNIFORM_BLOCK_BINDING\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_DATA_SIZE\"] = 35392] = \"UNIFORM_BLOCK_DATA_SIZE\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_ACTIVE_UNIFORMS\"] = 35394] = \"UNIFORM_BLOCK_ACTIVE_UNIFORMS\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES\"] = 35395] = \"UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER\"] = 35396] = \"UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER\"] = 35398] = \"UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER\";\n // Sync objects\n GLEnum[GLEnum[\"OBJECT_TYPE\"] = 37138] = \"OBJECT_TYPE\";\n GLEnum[GLEnum[\"SYNC_CONDITION\"] = 37139] = \"SYNC_CONDITION\";\n GLEnum[GLEnum[\"SYNC_STATUS\"] = 37140] = \"SYNC_STATUS\";\n GLEnum[GLEnum[\"SYNC_FLAGS\"] = 37141] = \"SYNC_FLAGS\";\n GLEnum[GLEnum[\"SYNC_FENCE\"] = 37142] = \"SYNC_FENCE\";\n GLEnum[GLEnum[\"SYNC_GPU_COMMANDS_COMPLETE\"] = 37143] = \"SYNC_GPU_COMMANDS_COMPLETE\";\n GLEnum[GLEnum[\"UNSIGNALED\"] = 37144] = \"UNSIGNALED\";\n GLEnum[GLEnum[\"SIGNALED\"] = 37145] = \"SIGNALED\";\n GLEnum[GLEnum[\"ALREADY_SIGNALED\"] = 37146] = \"ALREADY_SIGNALED\";\n GLEnum[GLEnum[\"TIMEOUT_EXPIRED\"] = 37147] = \"TIMEOUT_EXPIRED\";\n GLEnum[GLEnum[\"CONDITION_SATISFIED\"] = 37148] = \"CONDITION_SATISFIED\";\n GLEnum[GLEnum[\"WAIT_FAILED\"] = 37149] = \"WAIT_FAILED\";\n GLEnum[GLEnum[\"SYNC_FLUSH_COMMANDS_BIT\"] = 1] = \"SYNC_FLUSH_COMMANDS_BIT\";\n // Miscellaneous constants\n GLEnum[GLEnum[\"COLOR\"] = 6144] = \"COLOR\";\n GLEnum[GLEnum[\"DEPTH\"] = 6145] = \"DEPTH\";\n GLEnum[GLEnum[\"STENCIL\"] = 6146] = \"STENCIL\";\n GLEnum[GLEnum[\"MIN\"] = 32775] = \"MIN\";\n GLEnum[GLEnum[\"MAX\"] = 32776] = \"MAX\";\n GLEnum[GLEnum[\"DEPTH_COMPONENT24\"] = 33190] = \"DEPTH_COMPONENT24\";\n GLEnum[GLEnum[\"STREAM_READ\"] = 35041] = \"STREAM_READ\";\n GLEnum[GLEnum[\"STREAM_COPY\"] = 35042] = \"STREAM_COPY\";\n GLEnum[GLEnum[\"STATIC_READ\"] = 35045] = \"STATIC_READ\";\n GLEnum[GLEnum[\"STATIC_COPY\"] = 35046] = \"STATIC_COPY\";\n GLEnum[GLEnum[\"DYNAMIC_READ\"] = 35049] = \"DYNAMIC_READ\";\n GLEnum[GLEnum[\"DYNAMIC_COPY\"] = 35050] = \"DYNAMIC_COPY\";\n GLEnum[GLEnum[\"DEPTH_COMPONENT32F\"] = 36012] = \"DEPTH_COMPONENT32F\";\n GLEnum[GLEnum[\"DEPTH32F_STENCIL8\"] = 36013] = \"DEPTH32F_STENCIL8\";\n GLEnum[GLEnum[\"INVALID_INDEX\"] = 4294967295] = \"INVALID_INDEX\";\n GLEnum[GLEnum[\"TIMEOUT_IGNORED\"] = -1] = \"TIMEOUT_IGNORED\";\n GLEnum[GLEnum[\"MAX_CLIENT_WAIT_TIMEOUT_WEBGL\"] = 37447] = \"MAX_CLIENT_WAIT_TIMEOUT_WEBGL\";\n // Constants defined in WebGL extensions\n // WEBGL_debug_renderer_info\n /** Passed to getParameter to get the vendor string of the graphics driver. */\n GLEnum[GLEnum[\"UNMASKED_VENDOR_WEBGL\"] = 37445] = \"UNMASKED_VENDOR_WEBGL\";\n /** Passed to getParameter to get the renderer string of the graphics driver. */\n GLEnum[GLEnum[\"UNMASKED_RENDERER_WEBGL\"] = 37446] = \"UNMASKED_RENDERER_WEBGL\";\n // EXT_texture_filter_anisotropic\n /** Returns the maximum available anisotropy. */\n GLEnum[GLEnum[\"MAX_TEXTURE_MAX_ANISOTROPY_EXT\"] = 34047] = \"MAX_TEXTURE_MAX_ANISOTROPY_EXT\";\n /** Passed to texParameter to set the desired maximum anisotropy for a texture. */\n GLEnum[GLEnum[\"TEXTURE_MAX_ANISOTROPY_EXT\"] = 34046] = \"TEXTURE_MAX_ANISOTROPY_EXT\";\n // EXT_texture_norm16 - https://khronos.org/registry/webgl/extensions/EXT_texture_norm16/\n GLEnum[GLEnum[\"R16_EXT\"] = 33322] = \"R16_EXT\";\n GLEnum[GLEnum[\"RG16_EXT\"] = 33324] = \"RG16_EXT\";\n GLEnum[GLEnum[\"RGB16_EXT\"] = 32852] = \"RGB16_EXT\";\n GLEnum[GLEnum[\"RGBA16_EXT\"] = 32859] = \"RGBA16_EXT\";\n GLEnum[GLEnum[\"R16_SNORM_EXT\"] = 36760] = \"R16_SNORM_EXT\";\n GLEnum[GLEnum[\"RG16_SNORM_EXT\"] = 36761] = \"RG16_SNORM_EXT\";\n GLEnum[GLEnum[\"RGB16_SNORM_EXT\"] = 36762] = \"RGB16_SNORM_EXT\";\n GLEnum[GLEnum[\"RGBA16_SNORM_EXT\"] = 36763] = \"RGBA16_SNORM_EXT\";\n // WEBGL_compressed_texture_s3tc (BC1, BC2, BC3)\n /** A DXT1-compressed image in an RGB image format. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_S3TC_DXT1_EXT\"] = 33776] = \"COMPRESSED_RGB_S3TC_DXT1_EXT\";\n /** A DXT1-compressed image in an RGB image format with a simple on/off alpha value. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_S3TC_DXT1_EXT\"] = 33777] = \"COMPRESSED_RGBA_S3TC_DXT1_EXT\";\n /** A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_S3TC_DXT3_EXT\"] = 33778] = \"COMPRESSED_RGBA_S3TC_DXT3_EXT\";\n /** A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_S3TC_DXT5_EXT\"] = 33779] = \"COMPRESSED_RGBA_S3TC_DXT5_EXT\";\n // WEBGL_compressed_texture_s3tc_srgb (BC1, BC2, BC3 - SRGB)\n GLEnum[GLEnum[\"COMPRESSED_SRGB_S3TC_DXT1_EXT\"] = 35916] = \"COMPRESSED_SRGB_S3TC_DXT1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT\"] = 35917] = \"COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT\"] = 35918] = \"COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT\"] = 35919] = \"COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT\";\n // WEBGL_compressed_texture_rgtc (BC4, BC5)\n GLEnum[GLEnum[\"COMPRESSED_RED_RGTC1_EXT\"] = 36283] = \"COMPRESSED_RED_RGTC1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_RED_RGTC1_EXT\"] = 36284] = \"COMPRESSED_SIGNED_RED_RGTC1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_RED_GREEN_RGTC2_EXT\"] = 36285] = \"COMPRESSED_RED_GREEN_RGTC2_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT\"] = 36286] = \"COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT\";\n // WEBGL_compressed_texture_bptc (BC6, BC7)\n GLEnum[GLEnum[\"COMPRESSED_RGBA_BPTC_UNORM_EXT\"] = 36492] = \"COMPRESSED_RGBA_BPTC_UNORM_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT\"] = 36493] = \"COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT\"] = 36494] = \"COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT\"] = 36495] = \"COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT\";\n // WEBGL_compressed_texture_es3\n /** One-channel (red) unsigned format compression. */\n GLEnum[GLEnum[\"COMPRESSED_R11_EAC\"] = 37488] = \"COMPRESSED_R11_EAC\";\n /** One-channel (red) signed format compression. */\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_R11_EAC\"] = 37489] = \"COMPRESSED_SIGNED_R11_EAC\";\n /** Two-channel (red and green) unsigned format compression. */\n GLEnum[GLEnum[\"COMPRESSED_RG11_EAC\"] = 37490] = \"COMPRESSED_RG11_EAC\";\n /** Two-channel (red and green) signed format compression. */\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_RG11_EAC\"] = 37491] = \"COMPRESSED_SIGNED_RG11_EAC\";\n /** Compresses RGB8 data with no alpha channel. */\n GLEnum[GLEnum[\"COMPRESSED_RGB8_ETC2\"] = 37492] = \"COMPRESSED_RGB8_ETC2\";\n /** Compresses RGBA8 data. The RGB part is encoded the same as RGB_ETC2, but the alpha part is encoded separately. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA8_ETC2_EAC\"] = 37493] = \"COMPRESSED_RGBA8_ETC2_EAC\";\n /** Compresses sRGB8 data with no alpha channel. */\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ETC2\"] = 37494] = \"COMPRESSED_SRGB8_ETC2\";\n /** Compresses sRGBA8 data. The sRGB part is encoded the same as SRGB_ETC2, but the alpha part is encoded separately. */\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC\"] = 37495] = \"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC\";\n /** Similar to RGB8_ETC, but with ability to punch through the alpha channel, which means to make it completely opaque or transparent. */\n GLEnum[GLEnum[\"COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2\"] = 37496] = \"COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2\";\n /** Similar to SRGB8_ETC, but with ability to punch through the alpha channel, which means to make it completely opaque or transparent. */\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2\"] = 37497] = \"COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2\";\n // WEBGL_compressed_texture_pvrtc\n /** RGB compression in 4-bit mode. One block for each 4×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_PVRTC_4BPPV1_IMG\"] = 35840] = \"COMPRESSED_RGB_PVRTC_4BPPV1_IMG\";\n /** RGBA compression in 4-bit mode. One block for each 4×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\"] = 35842] = \"COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\";\n /** RGB compression in 2-bit mode. One block for each 8×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_PVRTC_2BPPV1_IMG\"] = 35841] = \"COMPRESSED_RGB_PVRTC_2BPPV1_IMG\";\n /** RGBA compression in 2-bit mode. One block for each 8×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\"] = 35843] = \"COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\";\n // WEBGL_compressed_texture_etc1\n /** Compresses 24-bit RGB data with no alpha channel. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_ETC1_WEBGL\"] = 36196] = \"COMPRESSED_RGB_ETC1_WEBGL\";\n // WEBGL_compressed_texture_atc\n GLEnum[GLEnum[\"COMPRESSED_RGB_ATC_WEBGL\"] = 35986] = \"COMPRESSED_RGB_ATC_WEBGL\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL\"] = 35986] = \"COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL\"] = 34798] = \"COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL\";\n // WEBGL_compressed_texture_astc\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_4x4_KHR\"] = 37808] = \"COMPRESSED_RGBA_ASTC_4x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_5x4_KHR\"] = 37809] = \"COMPRESSED_RGBA_ASTC_5x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_5x5_KHR\"] = 37810] = \"COMPRESSED_RGBA_ASTC_5x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_6x5_KHR\"] = 37811] = \"COMPRESSED_RGBA_ASTC_6x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_6x6_KHR\"] = 37812] = \"COMPRESSED_RGBA_ASTC_6x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_8x5_KHR\"] = 37813] = \"COMPRESSED_RGBA_ASTC_8x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_8x6_KHR\"] = 37814] = \"COMPRESSED_RGBA_ASTC_8x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_8x8_KHR\"] = 37815] = \"COMPRESSED_RGBA_ASTC_8x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x5_KHR\"] = 37816] = \"COMPRESSED_RGBA_ASTC_10x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x6_KHR\"] = 37817] = \"COMPRESSED_RGBA_ASTC_10x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x8_KHR\"] = 37818] = \"COMPRESSED_RGBA_ASTC_10x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x10_KHR\"] = 37819] = \"COMPRESSED_RGBA_ASTC_10x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_12x10_KHR\"] = 37820] = \"COMPRESSED_RGBA_ASTC_12x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_12x12_KHR\"] = 37821] = \"COMPRESSED_RGBA_ASTC_12x12_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR\"] = 37840] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR\"] = 37841] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR\"] = 37842] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR\"] = 37843] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR\"] = 37844] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR\"] = 37845] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR\"] = 37846] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR\"] = 37847] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR\"] = 37848] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR\"] = 37849] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR\"] = 37850] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR\"] = 37851] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR\"] = 37852] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR\"] = 37853] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR\";\n // EXT_disjoint_timer_query\n /** The number of bits used to hold the query result for the given target. */\n GLEnum[GLEnum[\"QUERY_COUNTER_BITS_EXT\"] = 34916] = \"QUERY_COUNTER_BITS_EXT\";\n /** The currently active query. */\n GLEnum[GLEnum[\"CURRENT_QUERY_EXT\"] = 34917] = \"CURRENT_QUERY_EXT\";\n /** The query result. */\n GLEnum[GLEnum[\"QUERY_RESULT_EXT\"] = 34918] = \"QUERY_RESULT_EXT\";\n /** A Boolean indicating whether or not a query result is available. */\n GLEnum[GLEnum[\"QUERY_RESULT_AVAILABLE_EXT\"] = 34919] = \"QUERY_RESULT_AVAILABLE_EXT\";\n /** Elapsed time (in nanoseconds). */\n GLEnum[GLEnum[\"TIME_ELAPSED_EXT\"] = 35007] = \"TIME_ELAPSED_EXT\";\n /** The current time. */\n GLEnum[GLEnum[\"TIMESTAMP_EXT\"] = 36392] = \"TIMESTAMP_EXT\";\n /** A Boolean indicating whether or not the GPU performed any disjoint operation (lost context) */\n GLEnum[GLEnum[\"GPU_DISJOINT_EXT\"] = 36795] = \"GPU_DISJOINT_EXT\";\n // KHR_parallel_shader_compile https://registry.khronos.org/webgl/extensions/KHR_parallel_shader_compile\n /** a non-blocking poll operation, so that compile/link status availability can be queried without potentially incurring stalls */\n GLEnum[GLEnum[\"COMPLETION_STATUS_KHR\"] = 37297] = \"COMPLETION_STATUS_KHR\";\n // EXT_depth_clamp https://registry.khronos.org/webgl/extensions/EXT_depth_clamp/\n /** Disables depth clipping */\n GLEnum[GLEnum[\"DEPTH_CLAMP_EXT\"] = 34383] = \"DEPTH_CLAMP_EXT\";\n // WEBGL_provoking_vertex https://registry.khronos.org/webgl/extensions/WEBGL_provoking_vertex/\n /** Values of first vertex in primitive are used for flat shading */\n GLEnum[GLEnum[\"FIRST_VERTEX_CONVENTION_WEBGL\"] = 36429] = \"FIRST_VERTEX_CONVENTION_WEBGL\";\n /** Values of first vertex in primitive are used for flat shading */\n GLEnum[GLEnum[\"LAST_VERTEX_CONVENTION_WEBGL\"] = 36430] = \"LAST_VERTEX_CONVENTION_WEBGL\";\n /** Controls which vertex in primitive is used for flat shading */\n GLEnum[GLEnum[\"PROVOKING_VERTEX_WEBL\"] = 36431] = \"PROVOKING_VERTEX_WEBL\";\n // WEBGL_polygon_mode https://registry.khronos.org/webgl/extensions/WEBGL_polygon_mode/\n GLEnum[GLEnum[\"POLYGON_MODE_WEBGL\"] = 2880] = \"POLYGON_MODE_WEBGL\";\n GLEnum[GLEnum[\"POLYGON_OFFSET_LINE_WEBGL\"] = 10754] = \"POLYGON_OFFSET_LINE_WEBGL\";\n GLEnum[GLEnum[\"LINE_WEBGL\"] = 6913] = \"LINE_WEBGL\";\n GLEnum[GLEnum[\"FILL_WEBGL\"] = 6914] = \"FILL_WEBGL\";\n // WEBGL_clip_cull_distance https://registry.khronos.org/webgl/extensions/WEBGL_clip_cull_distance/\n /** Max clip distances */\n GLEnum[GLEnum[\"MAX_CLIP_DISTANCES_WEBGL\"] = 3378] = \"MAX_CLIP_DISTANCES_WEBGL\";\n /** Max cull distances */\n GLEnum[GLEnum[\"MAX_CULL_DISTANCES_WEBGL\"] = 33529] = \"MAX_CULL_DISTANCES_WEBGL\";\n /** Max clip and cull distances */\n GLEnum[GLEnum[\"MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL\"] = 33530] = \"MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL\";\n /** Enable gl_ClipDistance[0] and gl_CullDistance[0] */\n GLEnum[GLEnum[\"CLIP_DISTANCE0_WEBGL\"] = 12288] = \"CLIP_DISTANCE0_WEBGL\";\n /** Enable gl_ClipDistance[1] and gl_CullDistance[1] */\n GLEnum[GLEnum[\"CLIP_DISTANCE1_WEBGL\"] = 12289] = \"CLIP_DISTANCE1_WEBGL\";\n /** Enable gl_ClipDistance[2] and gl_CullDistance[2] */\n GLEnum[GLEnum[\"CLIP_DISTANCE2_WEBGL\"] = 12290] = \"CLIP_DISTANCE2_WEBGL\";\n /** Enable gl_ClipDistance[3] and gl_CullDistance[3] */\n GLEnum[GLEnum[\"CLIP_DISTANCE3_WEBGL\"] = 12291] = \"CLIP_DISTANCE3_WEBGL\";\n /** Enable gl_ClipDistance[4] and gl_CullDistance[4] */\n GLEnum[GLEnum[\"CLIP_DISTANCE4_WEBGL\"] = 12292] = \"CLIP_DISTANCE4_WEBGL\";\n /** Enable gl_ClipDistance[5] and gl_CullDistance[5] */\n GLEnum[GLEnum[\"CLIP_DISTANCE5_WEBGL\"] = 12293] = \"CLIP_DISTANCE5_WEBGL\";\n /** Enable gl_ClipDistance[6] and gl_CullDistance[6] */\n GLEnum[GLEnum[\"CLIP_DISTANCE6_WEBGL\"] = 12294] = \"CLIP_DISTANCE6_WEBGL\";\n /** Enable gl_ClipDistance[7] and gl_CullDistance[7] */\n GLEnum[GLEnum[\"CLIP_DISTANCE7_WEBGL\"] = 12295] = \"CLIP_DISTANCE7_WEBGL\";\n /** EXT_polygon_offset_clamp https://registry.khronos.org/webgl/extensions/EXT_polygon_offset_clamp/ */\n GLEnum[GLEnum[\"POLYGON_OFFSET_CLAMP_EXT\"] = 36379] = \"POLYGON_OFFSET_CLAMP_EXT\";\n /** EXT_clip_control https://registry.khronos.org/webgl/extensions/EXT_clip_control/ */\n GLEnum[GLEnum[\"LOWER_LEFT_EXT\"] = 36001] = \"LOWER_LEFT_EXT\";\n GLEnum[GLEnum[\"UPPER_LEFT_EXT\"] = 36002] = \"UPPER_LEFT_EXT\";\n GLEnum[GLEnum[\"NEGATIVE_ONE_TO_ONE_EXT\"] = 37726] = \"NEGATIVE_ONE_TO_ONE_EXT\";\n GLEnum[GLEnum[\"ZERO_TO_ONE_EXT\"] = 37727] = \"ZERO_TO_ONE_EXT\";\n GLEnum[GLEnum[\"CLIP_ORIGIN_EXT\"] = 37724] = \"CLIP_ORIGIN_EXT\";\n GLEnum[GLEnum[\"CLIP_DEPTH_MODE_EXT\"] = 37725] = \"CLIP_DEPTH_MODE_EXT\";\n /** WEBGL_blend_func_extended https://registry.khronos.org/webgl/extensions/WEBGL_blend_func_extended/ */\n GLEnum[GLEnum[\"SRC1_COLOR_WEBGL\"] = 35065] = \"SRC1_COLOR_WEBGL\";\n GLEnum[GLEnum[\"SRC1_ALPHA_WEBGL\"] = 34185] = \"SRC1_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"ONE_MINUS_SRC1_COLOR_WEBGL\"] = 35066] = \"ONE_MINUS_SRC1_COLOR_WEBGL\";\n GLEnum[GLEnum[\"ONE_MINUS_SRC1_ALPHA_WEBGL\"] = 35067] = \"ONE_MINUS_SRC1_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL\"] = 35068] = \"MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL\";\n /** EXT_texture_mirror_clamp_to_edge https://registry.khronos.org/webgl/extensions/EXT_texture_mirror_clamp_to_edge/ */\n GLEnum[GLEnum[\"MIRROR_CLAMP_TO_EDGE_EXT\"] = 34627] = \"MIRROR_CLAMP_TO_EDGE_EXT\";\n})(GLEnum || (GLEnum = {}));\nexport { GLEnum as GL };\n//# sourceMappingURL=webgl-constants.js.map","import { scaleLinear } from 'd3-scale'\nimport { mat3 } from 'gl-matrix'\nimport { Random } from 'random'\nimport { getRgbaColor, rgbToBrightness } from '@/graph/helper'\nimport { hoveredPointRingOpacity, focusedPointRingOpacity, defaultConfigValues } from '@/graph/variables'\nimport type { GraphConfigInterface } from '@/graph/config'\n\nexport const ALPHA_MIN = 0.001\nexport const MAX_POINT_SIZE = 64\n\n/**\n * Maximum number of executions to delay before performing hover detection.\n * This threshold prevents excessive hover detection calls for performance optimization.\n * The `findHoveredItem` method will skip actual detection until this count is reached.\n */\nexport const MAX_HOVER_DETECTION_DELAY = 4\n\n/**\n * Minimum mouse movement threshold (in pixels) to trigger hover detection.\n * If the mouse moves less than this distance, hover detection will be skipped to save performance.\n */\nexport const MIN_MOUSE_MOVEMENT_THRESHOLD = 2\n\nexport type Hovered = { index: number; position: [ number, number ] }\ntype Focused = { index: number }\n\n/**\n * Type alias for a 4x4 matrix stored as a 16-element array in column-major order.\n * Used for std140 uniform buffer layout compatibility.\n */\nexport type Mat4Array = [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]\n\nexport class Store {\n public pointsTextureSize = 0\n public linksTextureSize = 0\n public alpha = 1\n public transform = mat3.create()\n public screenSize: [number, number] = [0, 0]\n public mousePosition = [0, 0]\n public screenMousePosition = [0, 0]\n public selectedArea = [[0, 0], [0, 0]]\n public isSimulationRunning = false\n public simulationProgress = 0\n public selectedIndices: Float32Array | null = null\n public maxPointSize = MAX_POINT_SIZE\n public hoveredPoint: Hovered | undefined = undefined\n public focusedPoint: Focused | undefined = undefined\n public draggingPointIndex: number | undefined = undefined\n public hoveredLinkIndex: number | undefined = undefined\n public adjustedSpaceSize = defaultConfigValues.spaceSize\n public isSpaceKeyPressed = false\n public div: HTMLDivElement | undefined\n public webglMaxTextureSize = 16384 // Default fallback value\n\n public hoveredPointRingColor = [1, 1, 1, hoveredPointRingOpacity]\n public focusedPointRingColor = [1, 1, 1, focusedPointRingOpacity]\n public hoveredLinkColor = [-1, -1, -1, -1]\n // -1 means that the color is not set\n public greyoutPointColor = [-1, -1, -1, -1]\n // If backgroundColor is dark, isDarkenGreyout is true\n public isDarkenGreyout = false\n // Whether link hovering is enabled based on configured event handlers\n public isLinkHoveringEnabled = false\n private alphaTarget = 0\n private scalePointX = scaleLinear()\n private scalePointY = scaleLinear()\n private random = new Random()\n private _backgroundColor: [number, number, number, number] = [0, 0, 0, 0]\n\n public get backgroundColor (): [number, number, number, number] {\n return this._backgroundColor\n }\n\n /**\n * Gets the transformation matrix as a 4x4 matrix for std140 uniform buffer layout.\n *\n * This method converts the internal 3x3 transformation matrix (mat3) to a 4x4 matrix format\n * required by WebGPU uniform buffers using the std140 layout standard.\n *\n * ## Matrix Storage Format\n *\n * Matrices are stored in **column-major order** (GLSL convention). The internal `transform`\n * array is a 9-element array representing a 3x3 matrix:\n *\n * ```\n * [m00, m10, m20, m01, m11, m21, m02, m12, m22]\n * ```\n *\n * Which represents the matrix:\n * ```\n * [m00 m01 m02]\n * [m10 m11 m12]\n * [m20 m21 m22]\n * ```\n *\n * ## Why This Conversion Is Needed\n *\n * The internal `transform` property stores a 3x3 matrix (9 elements) which is sufficient for\n * 2D transformations (translation, rotation, scaling in x/y plane). However, when passing\n * transformation matrices to GPU shaders via uniform buffers, we must comply with the std140\n * layout standard.\n *\n * ### std140 Layout Requirements\n *\n * The std140 layout standard (used in both OpenGL and WebGPU) defines strict alignment rules:\n *\n * 1. **Matrix Alignment**: In std140, matrices are stored as arrays of column vectors\n * - `mat3` requires each column to be aligned to 16 bytes (vec4 alignment)\n * - This means `mat3` occupies 3 columns × 16 bytes = 48 bytes total\n * - `mat4` occupies 4 columns × 16 bytes = 64 bytes total\n *\n * 2. **Alignment Issues with mat3**:\n * - The 48-byte size of `mat3` creates awkward alignment and padding requirements\n * - Different GPU drivers may handle `mat3` padding inconsistently\n * - This can lead to data misalignment and incorrect transformations\n *\n * 3. **Why mat4 is Preferred**:\n * - `mat4` has clean 64-byte alignment (power of 2)\n * - Consistent behavior across all GPU drivers and platforms\n * - The shader can easily extract the 3x3 portion: `mat3 transformMat3 = mat3(transformationMatrix)`\n * - The 4th column is set to `[0, 0, 0, 1]` (homogeneous coordinate) which doesn't affect 2D transforms\n *\n * ### Conversion Process\n *\n * The 3x3 matrix is converted to 4x4 by:\n * - Placing the 3x3 values in the top-left corner (preserving column-major order)\n * - Setting the 4th column to `[0, 0, 0, 1]` (homogeneous coordinate)\n * - The 4th row is implicitly `[0, 0, 0, 1]` due to column-major storage\n *\n * This creates a valid 4x4 transformation matrix that:\n * - Maintains the same 2D transformation behavior\n * - Satisfies std140 alignment requirements\n * - Works consistently across all GPU platforms\n *\n * ### Usage in Shaders\n *\n * Shaders using uniform buffers receive this as `mat4` and extract the 3x3 portion:\n * ```glsl\n * layout(std140) uniform uniforms {\n * mat4 transformationMatrix;\n * } uniforms;\n *\n * mat3 transformMat3 = mat3(uniforms.transformationMatrix);\n * vec3 final = transformMat3 * vec3(position, 1);\n * ```\n *\n * @returns A 16-element array representing a 4x4 matrix in column-major order,\n * suitable for std140 uniform buffer layout. The matrix preserves the\n * 2D transformation from the original 3x3 matrix.\n *\n * @example\n * ```typescript\n * const matrix = store.transformationMatrix4x4;\n * uniformStore.setUniforms({\n * uniforms: {\n * transformationMatrix: matrix // Expects mat4x4<f32> in shader\n * }\n * });\n * ```\n */\n public get transformationMatrix4x4 (): Mat4Array {\n const t = this.transform\n\n // Validate transform array length\n if (t.length !== 9) {\n throw new Error(`Transform must be a 9-element array (3x3 matrix), got ${t.length} elements`)\n }\n\n // Convert 3x3 to 4x4 matrix in column-major order\n return [\n t[0], t[1], t[2], 0, // Column 0\n t[3], t[4], t[5], 0, // Column 1\n t[6], t[7], t[8], 0, // Column 2\n 0, 0, 0, 1, // Column 3 (homogeneous)\n ]\n }\n\n public set backgroundColor (color: [number, number, number, number]) {\n this._backgroundColor = color\n const brightness = rgbToBrightness(color[0], color[1], color[2])\n document.documentElement.style.setProperty('--cosmosgl-attribution-color', brightness > 0.65 ? 'black' : 'white')\n document.documentElement.style.setProperty('--cosmosgl-error-message-color', brightness > 0.65 ? 'black' : 'white')\n if (this.div) this.div.style.backgroundColor = `rgba(${color[0] * 255}, ${color[1] * 255}, ${color[2] * 255}, ${color[3]})`\n\n this.isDarkenGreyout = brightness < 0.65\n }\n\n public addRandomSeed (seed: number | string): void {\n this.random = this.random.clone(seed)\n }\n\n public getRandomFloat (min: number, max: number): number {\n return this.random.float(min, max)\n }\n\n /**\n * If the config parameter `spaceSize` exceeds the limits of WebGL,\n * it reduces the space size without changing the config parameter.\n * Ensures `spaceSize` is always a positive number >= 2 (required for Math.log2).\n */\n public adjustSpaceSize (configSpaceSize: number, webglMaxTextureSize: number): void {\n if (configSpaceSize <= 0 || !isFinite(configSpaceSize)) {\n console.error(`Invalid spaceSize value: ${configSpaceSize}. Using default value of ${defaultConfigValues.spaceSize}`)\n configSpaceSize = defaultConfigValues.spaceSize\n }\n // Enforce minimum value of 2 (since we use Math.log2, minimum should be 2^1 = 2)\n const minSpaceSize = 2\n if (configSpaceSize < minSpaceSize) {\n console.warn(`spaceSize (${configSpaceSize}) is too small. Using minimum value of ${minSpaceSize}`)\n configSpaceSize = minSpaceSize\n }\n\n // Validate webglMaxTextureSize (values below minSpaceSize are invalid; clamp would exceed limit)\n if (!Number.isFinite(webglMaxTextureSize) || webglMaxTextureSize <= 0 || webglMaxTextureSize < minSpaceSize) {\n console.warn(`Invalid webglMaxTextureSize: ${webglMaxTextureSize}. Using configSpaceSize without WebGL limit adjustment.`)\n this.adjustedSpaceSize = configSpaceSize\n return\n }\n\n // Handle WebGL limits - ensure result is still >= minSpaceSize\n if (configSpaceSize >= webglMaxTextureSize) {\n this.adjustedSpaceSize = Math.max(webglMaxTextureSize / 2, minSpaceSize)\n console.warn(`The \\`spaceSize\\` has been reduced to ${this.adjustedSpaceSize} due to WebGL limits`)\n } else this.adjustedSpaceSize = configSpaceSize\n }\n\n /**\n * Sets the WebGL texture size limit for use in atlas creation and other texture operations.\n */\n public setWebGLMaxTextureSize (webglMaxTextureSize: number): void {\n this.webglMaxTextureSize = webglMaxTextureSize\n }\n\n public updateScreenSize (width: number, height: number): void {\n const { adjustedSpaceSize } = this\n this.screenSize = [width, height]\n this.scalePointX\n .domain([0, adjustedSpaceSize])\n .range([(width - adjustedSpaceSize) / 2, (width + adjustedSpaceSize) / 2])\n this.scalePointY\n .domain([adjustedSpaceSize, 0])\n .range([(height - adjustedSpaceSize) / 2, (height + adjustedSpaceSize) / 2])\n }\n\n public scaleX (x: number): number {\n return this.scalePointX(x)\n }\n\n public scaleY (y: number): number {\n return this.scalePointY(y)\n }\n\n public setHoveredPointRingColor (color: string | [number, number, number, number]): void {\n const convertedRgba = getRgbaColor(color)\n this.hoveredPointRingColor[0] = convertedRgba[0]\n this.hoveredPointRingColor[1] = convertedRgba[1]\n this.hoveredPointRingColor[2] = convertedRgba[2]\n }\n\n public setFocusedPointRingColor (color: string | [number, number, number, number]): void {\n const convertedRgba = getRgbaColor(color)\n this.focusedPointRingColor[0] = convertedRgba[0]\n this.focusedPointRingColor[1] = convertedRgba[1]\n this.focusedPointRingColor[2] = convertedRgba[2]\n }\n\n public setGreyoutPointColor (color: string | [number, number, number, number] | undefined): void {\n if (color === undefined) {\n this.greyoutPointColor = [-1, -1, -1, -1]\n return\n }\n const convertedRgba = getRgbaColor(color)\n this.greyoutPointColor[0] = convertedRgba[0]\n this.greyoutPointColor[1] = convertedRgba[1]\n this.greyoutPointColor[2] = convertedRgba[2]\n this.greyoutPointColor[3] = convertedRgba[3]\n }\n\n public updateLinkHoveringEnabled (config: Pick<GraphConfigInterface, 'onLinkClick' | 'onLinkContextMenu' | 'onLinkMouseOver' | 'onLinkMouseOut'>): void {\n this.isLinkHoveringEnabled = !!(config.onLinkClick || config.onLinkContextMenu || config.onLinkMouseOver || config.onLinkMouseOut)\n if (!this.isLinkHoveringEnabled) {\n this.hoveredLinkIndex = undefined\n }\n }\n\n public setHoveredLinkColor (color?: string | [number, number, number, number]): void {\n if (color === undefined) {\n this.hoveredLinkColor = [-1, -1, -1, -1]\n return\n }\n const convertedRgba = getRgbaColor(color)\n this.hoveredLinkColor[0] = convertedRgba[0]\n this.hoveredLinkColor[1] = convertedRgba[1]\n this.hoveredLinkColor[2] = convertedRgba[2]\n this.hoveredLinkColor[3] = convertedRgba[3]\n }\n\n public setFocusedPoint (index?: number): void {\n if (index !== undefined) {\n this.focusedPoint = { index }\n } else this.focusedPoint = undefined\n }\n\n public addAlpha (decay: number): number {\n return (this.alphaTarget - this.alpha) * this.alphaDecay(decay)\n }\n\n private alphaDecay = (decay: number): number => 1 - Math.pow(ALPHA_MIN, 1 / decay)\n}\n","import { color as d3Color } from 'd3-color'\nimport { Device, Framebuffer } from '@luma.gl/core'\nimport { WebGLDevice } from '@luma.gl/webgl'\nimport { GL } from '@luma.gl/constants'\nimport DOMPurify from 'dompurify'\n\nimport { MAX_POINT_SIZE } from '@/graph/modules/Store'\n\nexport const isFunction = <T>(a: T): boolean => typeof a === 'function'\nexport const isArray = <T>(a: unknown | T[]): a is T[] => Array.isArray(a)\nexport const isObject = <T>(a: T): boolean => (a instanceof Object)\nexport const isAClassInstance = <T>(a: T): boolean => {\n if (a instanceof Object) {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (a as T & Object).constructor.name !== 'Function' && (a as T & Object).constructor.name !== 'Object'\n } else return false\n}\nexport const isPlainObject = <T>(a: T): boolean => isObject(a) && !isArray(a) && !isFunction(a) && !isAClassInstance(a)\n\nexport function getRgbaColor (value: string | [number, number, number, number]): [number, number, number, number] {\n let rgba: [number, number, number, number]\n if (isArray(value)) {\n rgba = value\n } else {\n const color = d3Color(value)\n const rgb = color?.rgb()\n rgba = [rgb?.r || 0, rgb?.g || 0, rgb?.b || 0, color?.opacity ?? 1]\n }\n\n return [\n rgba[0] / 255,\n rgba[1] / 255,\n rgba[2] / 255,\n rgba[3],\n ]\n}\n\nexport function rgbToBrightness (r: number, g: number, b: number): number {\n return 0.2126 * r + 0.7152 * g + 0.0722 * b\n}\n\n/**\n * TODO: Migrate from deprecated `readPixelsToArrayWebGL` to CommandEncoder API\n *\n * `readPixelsToArrayWebGL` is deprecated in luma.gl v9. The recommended modern approach is:\n *\n * 1. Create a buffer to hold the pixel data:\n * const buffer = device.createBuffer({\n * byteLength: width * height * 4 * 4, // RGBA, 4 bytes per float\n * usage: Buffer.COPY_DST | Buffer.MAP_READ\n * });\n *\n * 2. Copy texture/framebuffer to buffer using command encoder:\n * const commandEncoder = device.createCommandEncoder();\n * commandEncoder.copyTextureToBuffer({\n * sourceTexture: fbo, // Can be Texture or Framebuffer\n * width: sourceWidth ?? fbo.width,\n * height: sourceHeight ?? fbo.height,\n * origin: [sourceX, sourceY],\n * destinationBuffer: buffer\n * });\n * const commandBuffer = commandEncoder.finish();\n * device.submit(commandBuffer);\n *\n * 3. Read the data from the buffer (async):\n * const pixelData = await buffer.readAsync(); // Returns ArrayBuffer\n * return new Float32Array(pixelData);\n *\n * Note: The modern approach is asynchronous, so this function signature would need to change\n * to return Promise<Float32Array> or we'd need to handle async at all call sites (18 locations).\n *\n * Migration impact:\n * - This function is used in 18 places across the codebase\n * - All call sites would need to be updated to handle async\n * - Consider batching the migration to avoid inconsistencies\n *\n * Current status: Deprecated but still functional. Keeping for now until full migration can be planned.\n *\n * @note Cosmos currently supports WebGL only; support for other device types will be added later.\n */\nexport function readPixels (device: Device, fbo: Framebuffer, sourceX = 0, sourceY = 0, sourceWidth?: number, sourceHeight?: number): Float32Array {\n // Let luma.gl auto-allocate based on texture format\n // It will use Float32Array for rgba32float textures\n return device.readPixelsToArrayWebGL(fbo, {\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n }) as Float32Array\n}\n\n/**\n * Returns the maximum point size supported by the device, scaled by pixel ratio.\n * For WebGL devices, reads the limit from the context; for other device types, uses MAX_POINT_SIZE from Store.\n * @param device - The luma.gl device\n * @param pixelRatio - Device pixel ratio to scale the result\n * @returns Maximum point size (device limit / pixelRatio)\n */\nexport function getMaxPointSize (device: Device, pixelRatio: number): number {\n switch (device.info.type) {\n case 'webgl': {\n const range = (device as WebGLDevice).gl.getParameter(GL.ALIASED_POINT_SIZE_RANGE) as [number, number]\n return (range?.[1] ?? MAX_POINT_SIZE) / pixelRatio\n }\n case 'webgpu':\n // Will be implemented when WebGPU support is added\n return MAX_POINT_SIZE / pixelRatio\n default:\n return MAX_POINT_SIZE / pixelRatio\n }\n}\n\nexport function clamp (num: number, min: number, max: number): number {\n return Math.min(Math.max(num, min), max)\n}\n\nexport function isNumber (value: number | undefined | null | typeof NaN): boolean {\n return value !== undefined && value !== null && !Number.isNaN(value)\n}\n\n/**\n * Sanitizes HTML content to prevent XSS attacks using DOMPurify\n *\n * This function is used internally to sanitize HTML content before setting innerHTML,\n * such as in attribution text. It uses a safe default configuration that allows\n * only common safe HTML elements and attributes.\n *\n * @param html The HTML string to sanitize\n * @param options Optional DOMPurify configuration options to override defaults\n * @returns Sanitized HTML string safe for innerHTML usage\n */\nexport function sanitizeHtml (html: string, options?: DOMPurify.Config): string {\n return DOMPurify.sanitize(html, {\n // Default configuration: allow common safe HTML elements and attributes\n ALLOWED_TAGS: ['a', 'b', 'i', 'em', 'strong', 'span', 'div', 'p', 'br'],\n ALLOWED_ATTR: ['href', 'target', 'class', 'id', 'style'],\n ALLOW_DATA_ATTR: false,\n ...options,\n })\n}\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { D3ZoomEvent } from 'd3-zoom'\nimport { D3DragEvent } from 'd3-drag'\nimport {\n defaultPointColor,\n defaultGreyoutPointOpacity,\n defaultGreyoutPointColor,\n defaultPointOpacity,\n defaultPointSize,\n defaultLinkColor,\n defaultGreyoutLinkOpacity,\n defaultLinkOpacity,\n defaultLinkWidth,\n defaultBackgroundColor,\n defaultConfigValues,\n} from '@/graph/variables'\nimport { isPlainObject } from '@/graph/helper'\nimport { type Hovered } from '@/graph/modules/Store'\n\nexport interface GraphConfigInterface {\n /**\n * If set to `false`, the simulation will not run.\n * This property will be applied only on component initialization and it\n * can't be changed using the `setConfig` method.\n * Default value: `true`\n */\n enableSimulation?: boolean;\n /**\n * Canvas background color.\n * Can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values.\n * Default value: '#222222'\n */\n backgroundColor?: string | [number, number, number, number];\n /**\n * Simulation space size (max 8192).\n * Default value: `8192`\n */\n spaceSize?: number;\n\n /**\n * The default color to use for points when no point colors are provided,\n * or if the color value in the array is `undefined` or `null`.\n * This can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n * Default value: '#b3b3b3'\n */\n pointDefaultColor?: string | [number, number, number, number];\n\n /** @deprecated Use `pointDefaultColor` instead */\n pointColor?: string | [number, number, number, number];\n\n /**\n * The color to use for points when they are greyed out (when selection is active).\n * This can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n *\n * If not provided, the color will be the same as the point's original color,\n * but darkened or lightened depending on the background color.\n *\n * If `pointGreyoutOpacity` is also defined, it will override the alpha/opacity component\n * of this color.\n *\n * Default value: `undefined`\n */\n pointGreyoutColor?: string | [number, number, number, number];\n\n /**\n * Opacity value for points when they are greyed out (when selection is active).\n * Values range from 0 (completely transparent) to 1 (fully opaque).\n *\n * If defined, this value will override the alpha/opacity component of `pointGreyoutColor`.\n *\n * Default value: `undefined`\n */\n pointGreyoutOpacity?: number;\n\n /**\n * The default size value to use for points when no point sizes are provided or\n * if the size value in the array is `undefined` or `null`.\n * Default value: `4`\n */\n pointDefaultSize?: number;\n\n /** @deprecated Use `pointDefaultSize` instead */\n pointSize?: number;\n\n /**\n * Universal opacity value applied to all points.\n * This value multiplies with individual point alpha values (if set via setPointColors).\n * Useful for dynamically controlling opacity of all points without updating individual RGBA arrays.\n * Default value: `1.0`\n */\n pointOpacity?: number;\n\n /**\n * Scale factor for the point size.\n * Default value: `1`\n */\n pointSizeScale?: number;\n\n /**\n * Cursor style to use when hovering over a point\n * Default value: `auto`\n */\n hoveredPointCursor?: string;\n\n /**\n * Cursor style to use when hovering over a link\n * Default value: `auto`\n */\n hoveredLinkCursor?: string;\n\n /**\n * Turns ring rendering around a point on hover on / off\n * Default value: `false`\n */\n renderHoveredPointRing?: boolean;\n\n /**\n * Hovered point ring color hex value.\n * Can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values.\n * Default value: `white`\n */\n hoveredPointRingColor?: string | [number, number, number, number];\n\n /**\n * Focused point ring color hex value.\n * Can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values.\n * Default value: `white`\n */\n focusedPointRingColor?: string | [number, number, number, number];\n\n /**\n * Set focus on a point by index. A ring will be highlighted around the focused point.\n * When set to `undefined`, no point is focused.\n * Default value: `undefined`\n */\n focusedPointIndex?: number;\n\n /**\n * Turns link rendering on / off.\n * Default value: `true`\n */\n renderLinks?: boolean;\n\n /**\n * The default color to use for links when no link colors are provided,\n * or if the color value in the array is `undefined` or `null`.\n * This can be either a hex color string (e.g., '#666666') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n * Default value: '#666666'\n */\n linkDefaultColor?: string | [number, number, number, number];\n\n /** @deprecated Use `linkDefaultColor` instead */\n linkColor?: string | [number, number, number, number];\n\n /**\n * Universal opacity value applied to all links.\n * This value multiplies with individual link alpha values (if set via setLinkColors).\n * Useful for dynamically controlling opacity of all links without updating individual RGBA arrays.\n * Default value: `1.0`\n */\n linkOpacity?: number;\n\n /**\n * Greyed out link opacity value when the selection is active.\n * Default value: `0.1`\n */\n linkGreyoutOpacity?: number;\n /**\n * The default width value to use for links when no link widths are provided or if the width value in the array is `undefined` or `null`.\n * Default value: `1`\n */\n linkDefaultWidth?: number;\n\n /** @deprecated Use `linkDefaultWidth` instead */\n linkWidth?: number;\n /**\n * The color to use for links when they are hovered.\n * This can be either a hex color string (e.g., '#ff3333') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n * Default value: `undefined`\n */\n hoveredLinkColor?: string | [number, number, number, number];\n /**\n * Number of pixels to add to the link width when hovered.\n * The hovered width is calculated as: originalWidth + hoveredLinkWidthIncrease\n * Default value: `5`\n */\n hoveredLinkWidthIncrease?: number;\n /**\n * Scale factor for the link width.\n * Default value: `1`\n */\n linkWidthScale?: number;\n /**\n * Increase or decrease the size of the links when zooming in or out.\n * Default value: `false`\n */\n scaleLinksOnZoom?: boolean;\n /**\n * If set to true, links are rendered as curved lines.\n * Otherwise as straight lines.\n * Default value: `false`\n */\n curvedLinks?: boolean;\n /**\n * Number of segments in a curved line.\n * Default value: `19`.\n */\n curvedLinkSegments?: number;\n /**\n * Weight affects the shape of the curve.\n * Default value: `0.8`.\n */\n curvedLinkWeight?: number;\n /**\n * Defines the position of the control point of the curve on the normal from the centre of the line.\n * If set to 1 then the control point is at a distance equal to the length of the line.\n * Default value: `0.5`\n */\n curvedLinkControlPointDistance?: number;\n /**\n * The default link arrow value that controls whether or not to display link arrows.\n * Default value: `false`\n */\n linkDefaultArrows?: boolean;\n\n /** @deprecated Use `linkDefaultArrows` instead */\n linkArrows?: boolean;\n /**\n * Scale factor for the link arrows size.\n * Default value: `1`\n */\n linkArrowsSizeScale?: number;\n /**\n * The range defines the minimum and maximum link visibility distance in pixels.\n * The link will be fully opaque when its length is less than the first number in the array,\n * and will have `linkVisibilityMinTransparency` transparency when its length is greater than\n * the second number in the array.\n * This distance is defined in screen space coordinates and will change as you zoom in and out\n * (e.g. links become longer when you zoom in, and shorter when you zoom out).\n * Default value: `[50, 150]`\n */\n linkVisibilityDistanceRange?: number[];\n /**\n * The transparency value that the link will have when its length reaches\n * the maximum link distance value from `linkVisibilityDistanceRange`.\n * Default value: `0.25`\n */\n linkVisibilityMinTransparency?: number;\n\n /**\n * Decay coefficient. Use smaller values if you want the simulation to \"cool down\" slower.\n * Default value: `5000`\n */\n simulationDecay?: number;\n /**\n * Gravity force coefficient.\n * Default value: `0.25`\n */\n simulationGravity?: number;\n /**\n * Centering to center mass force coefficient.\n * Default value: `0`\n */\n simulationCenter?: number;\n /**\n * Repulsion force coefficient.\n * Default value: `1.0`\n */\n simulationRepulsion?: number;\n /**\n * Decreases / increases the detalization of the Many-Body force calculations.\n * Default value: `1.15`\n */\n simulationRepulsionTheta?: number;\n /**\n * Link spring force coefficient.\n * Default value: `1`\n */\n simulationLinkSpring?: number;\n /**\n * Minimum link distance.\n * Default value: `10`\n */\n simulationLinkDistance?: number;\n /**\n * Range of random link distance values.\n * Default value: `[1, 1.2]`\n */\n simulationLinkDistRandomVariationRange?: number[];\n /**\n * Repulsion coefficient from mouse position.\n * The repulsion force is activated by pressing the right mouse button.\n * Default value: `2`\n */\n simulationRepulsionFromMouse?: number;\n /**\n * Enable or disable the repulsion force from mouse when right-clicking.\n * When set to `true`, holding the right mouse button will activate the mouse repulsion force.\n * When set to `false`, right-clicking will not trigger any repulsion force.\n * Default value: `false`\n */\n enableRightClickRepulsion?: boolean;\n /**\n * Friction coefficient.\n * Values range from 0 (high friction, stops quickly) to 1 (no friction, keeps moving).\n * Default value: `0.85`\n */\n simulationFriction?: number;\n /**\n * Cluster coefficient.\n * Default value: `0.1`\n */\n simulationCluster?: number;\n\n /**\n * Callback function that will be called when the simulation starts.\n * Default value: `undefined`\n */\n onSimulationStart?: () => void;\n /**\n * Callback function that will be called on every simulation tick.\n * The value of the first argument `alpha` will decrease over time as the simulation \"cools down\".\n * If there's a point under the mouse pointer, its index will be passed as the second argument\n * and position as the third argument:\n * `(alpha: number, hoveredIndex: number | undefined, pointPosition: [number, number] | undefined) => void`.\n * Default value: `undefined`\n */\n onSimulationTick?: (\n alpha: number, hoveredIndex?: number, pointPosition?: [number, number]\n ) => void;\n /**\n * Callback function that will be called when the simulation stops.\n * Default value: `undefined`\n */\n onSimulationEnd?: () => void;\n /**\n * Callback function that will be called when the simulation gets paused.\n * Default value: `undefined`\n */\n onSimulationPause?: () => void;\n /**\n * Callback function that will be called when the simulation is restarted.\n * @deprecated Use `onSimulationUnpause` instead. This callback will be removed in a future version.\n * Default value: `undefined`\n */\n onSimulationRestart?: () => void;\n /**\n * Callback function that will be called when the simulation is unpaused.\n * Default value: `undefined`\n */\n onSimulationUnpause?: () => void;\n\n /**\n * Callback function that will be called on every canvas click.\n * If clicked on a point, its index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onClick?: (\n index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a point is clicked.\n * The point index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number, pointPosition: [number, number], event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onPointClick?: (\n index: number,\n pointPosition: [number, number],\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a link is clicked.\n * The link index will be passed as the first argument and the corresponding mouse event as the second argument:\n * `(linkIndex: number, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onLinkClick?: (\n linkIndex: number,\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when the background (empty space) is clicked.\n * The mouse event will be passed as the first argument:\n * `(event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onBackgroundClick?: (\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on the canvas.\n * If triggered on a point, its index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onContextMenu?: (\n index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on a point.\n * The point index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number, pointPosition: [number, number], event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onPointContextMenu?: (\n index: number,\n pointPosition: [number, number],\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on a link.\n * The link index will be passed as the first argument and the corresponding mouse event as the second argument:\n * `(linkIndex: number, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onLinkContextMenu?: (\n linkIndex: number,\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on the background (empty space).\n * The mouse event will be passed as the first argument:\n * `(event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onBackgroundContextMenu?: (\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when mouse movement happens.\n * If the mouse moves over a point, its index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onMouseMove?: (\n index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a point appears under the mouse\n * as a result of a mouse event, zooming and panning, or movement of points.\n * The point index will be passed as the first argument, position as the second argument,\n * the corresponding mouse event or D3's zoom event as the third argument, and whether\n * the hovered point is selected as the fourth argument:\n * `(index: number, pointPosition: [number, number], event: MouseEvent | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | D3ZoomEvent<HTMLCanvasElement, undefined> | undefined, isSelected: boolean) => void`.\n * Default value: `undefined`\n */\n onPointMouseOver?: (\n index: number,\n pointPosition: [number, number],\n event: MouseEvent | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | D3ZoomEvent<HTMLCanvasElement, undefined> | undefined,\n isSelected: boolean\n ) => void;\n\n /**\n * Callback function that will be called when a point is no longer underneath\n * the mouse pointer because of a mouse event, zoom/pan event, or movement of points.\n * The corresponding mouse event or D3's zoom event will be passed as the first argument:\n * `(event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void`.\n * Default value: `undefined`\n */\n onPointMouseOut?: (event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void;\n\n /**\n * Callback function that will be called when the mouse moves over a link.\n * The link index will be passed as the first argument:\n * `(linkIndex: number) => void`.\n * Default value: `undefined`\n */\n onLinkMouseOver?: (linkIndex: number) => void;\n\n /**\n * Callback function that will be called when the mouse moves out of a link.\n * The event will be passed as the first argument:\n * `(event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void`.\n * Default value: `undefined`\n */\n onLinkMouseOut?: (event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void;\n\n /**\n * Callback function that will be called when zooming or panning starts.\n * First argument is a D3 Zoom Event and second indicates whether\n * the event has been initiated by a user interaction (e.g. a mouse event):\n * `(event: D3ZoomEvent, userDriven: boolean) => void`.\n * Default value: `undefined`\n */\n onZoomStart?: (e: D3ZoomEvent<HTMLCanvasElement, undefined>, userDriven: boolean) => void;\n\n /**\n * Callback function that will be called continuously during zooming or panning.\n * First argument is a D3 Zoom Event and second indicates whether\n * the event has been initiated by a user interaction (e.g. a mouse event):\n * `(event: D3ZoomEvent, userDriven: boolean) => void`.\n * Default value: `undefined`\n */\n onZoom?: (e: D3ZoomEvent<HTMLCanvasElement, undefined>, userDriven: boolean) => void;\n\n /**\n * Callback function that will be called when zooming or panning ends.\n * First argument is a D3 Zoom Event and second indicates whether\n * the event has been initiated by a user interaction (e.g. a mouse event):\n * `(event: D3ZoomEvent, userDriven: boolean) => void`.\n * Default value: `undefined`\n */\n onZoomEnd?: (e: D3ZoomEvent<HTMLCanvasElement, undefined>, userDriven: boolean) => void;\n\n /**\n * Callback function that will be called when dragging starts.\n * First argument is a D3 Drag Event:\n * `(event: D3DragEvent) => void`.\n * Default value: `undefined`\n */\n onDragStart?: (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => void;\n\n /**\n * Callback function that will be called continuously during dragging.\n * First argument is a D3 Drag Event:\n * `(event: D3DragEvent) => void`.\n * Default value: `undefined`\n */\n onDrag?: (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => void;\n\n /**\n * Callback function that will be called when dragging ends.\n * First argument is a D3 Drag Event:\n * `(event: D3DragEvent) => void`.\n * Default value: `undefined`\n */\n onDragEnd?: (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => void;\n\n /**\n * Show WebGL performance monitor.\n * Default value: `false`\n */\n showFPSMonitor?: boolean;\n /**\n * Pixel ratio for the canvas. Higher values use more GPU memory but provide better quality on high-DPI displays.\n * Default value: `window.devicePixelRatio || 2`\n */\n pixelRatio?: number;\n /**\n * Increase or decrease the size of the points when zooming in or out.\n * Default value: `false`\n */\n scalePointsOnZoom?: boolean;\n /**\n * Initial zoom level. Can be set once during graph initialization.\n * If set, `fitViewOnInit` value will be ignored.\n * Default value: `undefined`\n */\n initialZoomLevel?: number;\n /**\n * Enables or disables zooming in and out.\n * Default: `true`\n */\n enableZoom?: boolean;\n /**\n * Controls whether the simulation remains active during zoom operations.\n * When set to `true`, the simulation continues running while zooming.\n * When set to `false`, the simulation pauses during zoom operations.\n * Default value: `false`\n */\n enableSimulationDuringZoom?: boolean;\n /**\n * Enables or disables dragging of points in the graph.\n * Default value: `false`\n */\n enableDrag?: boolean;\n /**\n * Whether to center and zoom the view to fit all points in the scene on initialization or not.\n * Ignored if `initialZoomLevel` is set.\n * Default: `true`\n */\n fitViewOnInit?: boolean;\n /**\n * Delay in milliseconds before fitting the view when `fitViewOnInit` is enabled.\n * Useful if you want the layout to stabilize a bit before fitting.\n * Default: `250`\n */\n fitViewDelay?: number;\n /**\n * Padding to apply when fitting the view to show all points.\n * This value is added to the calculated bounding box to provide some extra space around the points.\n * This is used when the `fitViewOnInit` option is enabled.\n * Default: `0.1`\n */\n fitViewPadding?: number;\n /**\n * Duration in milliseconds for fitting the view to show all points when fitViewOnInit is enabled.\n * Default: `250`\n */\n fitViewDuration?: number;\n /**\n * When `fitViewOnInit` is set to `true`, fits the view to show the points within a rectangle\n * defined by its two corner coordinates `[[left, bottom], [right, top]]` in the scene space.\n * Default: `undefined`\n */\n fitViewByPointsInRect?: [[number, number], [number, number]] | [number, number][];\n /**\n * When `fitViewOnInit` is set to `true`, fits the view to show only the specified points by their indices.\n * Takes precedence over `fitViewByPointsInRect` when both are provided.\n * Default: `undefined`\n */\n fitViewByPointIndices?: number[];\n /**\n * Providing a `randomSeed` value allows you to control\n * the randomness of the layout across different simulation runs.\n * It is useful when you want the graph to always look the same on same datasets.\n * This property will be applied only on component initialization and it\n * can't be changed using the `setConfig` method.\n * Default value: undefined\n */\n randomSeed?: number | string;\n /**\n * Point sampling distance in pixels between neighboring points when calling the `getSampledPointPositionsMap` method.\n * This parameter determines how many points will be included in the sample.\n * Default value: `150`\n */\n pointSamplingDistance?: number;\n /**\n * Controls automatic position adjustment of points in the visible space.\n *\n * When `undefined` (default):\n * - If simulation is disabled (`enableSimulation: false`), points will be automatically\n * repositioned to fit within the visible space\n * - If simulation is enabled, points will not be rescaled\n *\n * When explicitly set:\n * - `true`: Forces points positions to be rescaled\n * - `false`: Forces points positions to not be rescaled\n */\n rescalePositions?: boolean | undefined;\n /**\n * Controls the text shown in the bottom right corner.\n * - When a non-empty string is provided: Displays the string as HTML\n * - When empty string or not provided: No text is displayed\n */\n attribution?: string;\n}\n\nexport class GraphConfig implements GraphConfigInterface {\n public enableSimulation = defaultConfigValues.enableSimulation\n public backgroundColor = defaultBackgroundColor\n public spaceSize = defaultConfigValues.spaceSize\n public pointColor = defaultPointColor\n // TODO: When pointColor is removed, change this to:\n // public pointDefaultColor = defaultPointColor\n // Currently undefined to allow fallback to deprecated pointColor via nullish coalescing\n // in GraphData.updatePointColor() (see: this._config.pointDefaultColor ?? this._config.pointColor)\n public pointDefaultColor = undefined\n public pointGreyoutOpacity = defaultGreyoutPointOpacity\n public pointGreyoutColor = defaultGreyoutPointColor\n public pointSize = defaultPointSize\n // TODO: When pointSize is removed, change this to:\n // public pointDefaultSize = defaultPointSize\n // Currently undefined to allow fallback to deprecated pointSize via nullish coalescing\n // in GraphData.updatePointSize() (see: this._config.pointDefaultSize ?? this._config.pointSize)\n public pointDefaultSize = undefined\n public pointOpacity = defaultPointOpacity\n public pointSizeScale = defaultConfigValues.pointSizeScale\n public hoveredPointCursor = defaultConfigValues.hoveredPointCursor\n public hoveredLinkCursor = defaultConfigValues.hoveredLinkCursor\n public renderHoveredPointRing = defaultConfigValues.renderHoveredPointRing\n public hoveredPointRingColor = defaultConfigValues.hoveredPointRingColor\n public focusedPointRingColor = defaultConfigValues.focusedPointRingColor\n public focusedPointIndex = defaultConfigValues.focusedPointIndex\n public linkColor = defaultLinkColor\n // TODO: When linkColor is removed, change this to:\n // public linkDefaultColor = defaultLinkColor\n // Currently undefined to allow fallback to deprecated linkColor via nullish coalescing\n // in GraphData.updateLinkColor() (see: this._config.linkDefaultColor ?? this._config.linkColor)\n public linkDefaultColor = undefined\n public linkOpacity = defaultLinkOpacity\n public linkGreyoutOpacity = defaultGreyoutLinkOpacity\n public linkWidth = defaultLinkWidth\n // TODO: When linkWidth is removed, change this to:\n // public linkDefaultWidth = defaultLinkWidth\n // Currently undefined to allow fallback to deprecated linkWidth via nullish coalescing\n // in GraphData.updateLinkWidth() (see: this._config.linkDefaultWidth ?? this._config.linkWidth)\n public linkDefaultWidth = undefined\n public linkWidthScale = defaultConfigValues.linkWidthScale\n public hoveredLinkColor = defaultConfigValues.hoveredLinkColor\n public hoveredLinkWidthIncrease = defaultConfigValues.hoveredLinkWidthIncrease\n public renderLinks = defaultConfigValues.renderLinks\n public curvedLinks = defaultConfigValues.curvedLinks\n public curvedLinkSegments = defaultConfigValues.curvedLinkSegments\n public curvedLinkWeight = defaultConfigValues.curvedLinkWeight\n public curvedLinkControlPointDistance = defaultConfigValues.curvedLinkControlPointDistance\n public linkArrows = defaultConfigValues.linkArrows\n // TODO: When linkArrows is removed, change this to:\n // public linkDefaultArrows = defaultConfigValues.linkArrows\n // Currently undefined to allow fallback to deprecated linkArrows via nullish coalescing\n // in GraphData.updateArrows() (see: this._config.linkDefaultArrows ?? this._config.linkArrows)\n public linkDefaultArrows = undefined\n public linkArrowsSizeScale = defaultConfigValues.linkArrowsSizeScale\n public scaleLinksOnZoom = defaultConfigValues.scaleLinksOnZoom\n public linkVisibilityDistanceRange = defaultConfigValues.linkVisibilityDistanceRange\n public linkVisibilityMinTransparency = defaultConfigValues.linkVisibilityMinTransparency\n\n public simulationDecay = defaultConfigValues.simulation.decay\n public simulationGravity = defaultConfigValues.simulation.gravity\n public simulationCenter = defaultConfigValues.simulation.center\n public simulationRepulsion = defaultConfigValues.simulation.repulsion\n public simulationRepulsionTheta = defaultConfigValues.simulation.repulsionTheta\n public simulationLinkSpring = defaultConfigValues.simulation.linkSpring\n public simulationLinkDistance = defaultConfigValues.simulation.linkDistance\n public simulationLinkDistRandomVariationRange = defaultConfigValues.simulation.linkDistRandomVariationRange\n public simulationRepulsionFromMouse = defaultConfigValues.simulation.repulsionFromMouse\n public enableRightClickRepulsion = defaultConfigValues.enableRightClickRepulsion\n public simulationFriction = defaultConfigValues.simulation.friction\n public simulationCluster = defaultConfigValues.simulation.cluster\n\n public onSimulationStart: GraphConfigInterface['onSimulationStart'] = undefined\n public onSimulationTick: GraphConfigInterface['onSimulationTick'] = undefined\n public onSimulationEnd: GraphConfigInterface['onSimulationEnd'] = undefined\n public onSimulationPause: GraphConfigInterface['onSimulationPause'] = undefined\n public onSimulationRestart: GraphConfigInterface['onSimulationRestart'] = undefined\n public onSimulationUnpause: GraphConfigInterface['onSimulationUnpause'] = undefined\n\n public onClick: GraphConfigInterface['onClick'] = undefined\n public onPointClick: GraphConfigInterface['onPointClick'] = undefined\n public onLinkClick: GraphConfigInterface['onLinkClick'] = undefined\n public onBackgroundClick: GraphConfigInterface['onBackgroundClick'] = undefined\n public onContextMenu: GraphConfigInterface['onContextMenu'] = undefined\n public onPointContextMenu: GraphConfigInterface['onPointContextMenu'] = undefined\n public onLinkContextMenu: GraphConfigInterface['onLinkContextMenu'] = undefined\n public onBackgroundContextMenu: GraphConfigInterface['onBackgroundContextMenu'] = undefined\n public onMouseMove: GraphConfigInterface['onMouseMove'] = undefined\n public onPointMouseOver: GraphConfigInterface['onPointMouseOver'] = undefined\n public onPointMouseOut: GraphConfigInterface['onPointMouseOut'] = undefined\n public onLinkMouseOver: GraphConfigInterface['onLinkMouseOver'] = undefined\n public onLinkMouseOut: GraphConfigInterface['onLinkMouseOut'] = undefined\n public onZoomStart: GraphConfigInterface['onZoomStart'] = undefined\n public onZoom: GraphConfigInterface['onZoom'] = undefined\n public onZoomEnd: GraphConfigInterface['onZoomEnd'] = undefined\n public onDragStart: GraphConfigInterface['onDragStart'] = undefined\n public onDrag: GraphConfigInterface['onDrag'] = undefined\n public onDragEnd: GraphConfigInterface['onDragEnd'] = undefined\n\n public showFPSMonitor = defaultConfigValues.showFPSMonitor\n\n public pixelRatio = defaultConfigValues.pixelRatio\n\n public scalePointsOnZoom = defaultConfigValues.scalePointsOnZoom\n public initialZoomLevel = undefined\n public enableZoom = defaultConfigValues.enableZoom\n public enableSimulationDuringZoom = defaultConfigValues.enableSimulationDuringZoom\n public enableDrag = defaultConfigValues.enableDrag\n public fitViewOnInit = defaultConfigValues.fitViewOnInit\n public fitViewDelay = defaultConfigValues.fitViewDelay\n public fitViewPadding = defaultConfigValues.fitViewPadding\n public fitViewDuration = defaultConfigValues.fitViewDuration\n public fitViewByPointsInRect = undefined\n public fitViewByPointIndices = undefined\n\n public randomSeed = undefined\n public pointSamplingDistance = defaultConfigValues.pointSamplingDistance\n public attribution = defaultConfigValues.attribution\n public rescalePositions = defaultConfigValues.rescalePositions\n\n public init (config: GraphConfigInterface): void {\n (Object.keys(config) as (keyof GraphConfigInterface)[])\n .forEach(configParameter => {\n this.deepMergeConfig(this.getConfig(), config, configParameter)\n })\n }\n\n public deepMergeConfig <T> (current: T, next: T, key: keyof T): void {\n if (isPlainObject(current[key]) && isPlainObject(next[key])) {\n // eslint-disable-next-line @typescript-eslint/ban-types\n (Object.keys(next[key] as Object) as (keyof T[keyof T])[])\n .forEach(configParameter => {\n this.deepMergeConfig(current[key], next[key], configParameter)\n })\n } else current[key] = next[key]\n }\n\n private getConfig (): GraphConfigInterface {\n return this\n }\n}\n","import { Device } from '@luma.gl/core'\nimport { GraphConfigInterface } from '@/graph/config'\nimport { GraphData } from '@/graph/modules/GraphData'\nimport { Points } from '@/graph/modules/Points'\nimport { Store } from '@/graph/modules/Store'\n\nexport class CoreModule {\n public readonly device: Device\n public readonly config: GraphConfigInterface\n public readonly store: Store\n public readonly data: GraphData\n public readonly points: Points | undefined\n public _debugRandomNumber = Math.floor(Math.random() * 1000)\n\n public constructor (\n device: Device,\n config: GraphConfigInterface,\n store: Store,\n data: GraphData,\n points?: Points\n ) {\n this.device = device\n this.config = config\n this.store = store\n this.data = data\n if (points) this.points = points\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nin vec4 rgba;\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform calculateCentermassUniforms {\\n float pointsTextureSize;\\n} calculateCentermass;\\n\\n#define pointsTextureSize calculateCentermass.pointsTextureSize\\n#else\\nuniform float pointsTextureSize;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nout vec4 rgba;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, pointIndices / pointsTextureSize);\\n rgba = vec4(pointPosition.xy, 1.0, 0.0);\\n\\n gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n}\\n\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D centermassTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceCenterUniforms {\\n float centerForce;\\n float alpha;\\n} forceCenter;\\n\\n#define centerForce forceCenter.centerForce\\n#define alpha forceCenter.alpha\\n#else\\nuniform float centerForce;\\nuniform float alpha;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 velocity = vec4(0.0);\\n vec4 centermassValues = texture(centermassTexture, vec2(0.0));\\n vec2 centermassPosition = centermassValues.xy / centermassValues.b;\\n vec2 distVector = centermassPosition - pointPosition.xy;\\n float dist = sqrt(dot(distVector, distVector));\\n if (dist > 0.0) {\\n float angle = atan(distVector.y, distVector.x);\\n float addV = alpha * centerForce * dist * 0.01;\\n velocity.rg += addV * vec2(cos(angle), sin(angle));\\n }\\n\\n fragColor = velocity;\\n}\"","export function createIndexesForBuffer (textureSize: number): Float32Array {\n const indexes = new Float32Array(textureSize * textureSize * 2)\n for (let y = 0; y < textureSize; y++) {\n for (let x = 0; x < textureSize; x++) {\n const i = y * textureSize * 2 + x * 2\n indexes[i + 0] = x\n indexes[i + 1] = y\n }\n }\n return indexes\n}\n","import type { TextureFormat } from '@luma.gl/core'\nimport { textureFormatDecoder } from '@luma.gl/core'\n\n/**\n * Calculates bytesPerRow for texture uploads.\n * @param format - Texture format\n * @param width - Texture width in pixels\n * @returns bytesPerRow in bytes\n */\nexport function getBytesPerRow (format: TextureFormat, width: number): number {\n const formatInfo = textureFormatDecoder.getInfo(format)\n return width * (formatInfo.bytesPerPixel ?? 0)\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 vertexCoord; // Vertex coordinates in normalized device coordinates\\nout vec2 textureCoords; // Texture coordinates to pass to the fragment shader\\n\\nvoid main() {\\n // Convert vertex coordinates from [-1, 1] range to [0, 1] range for texture sampling\\n textureCoords = (vertexCoord + 1.0) / 2.0;\\n gl_Position = vec4(vertexCoord, 0, 1);\\n}\\n\"","import { Buffer, Framebuffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport calculateCentermassFrag from '@/graph/modules/ForceCenter/calculate-centermass.frag?raw'\nimport calculateCentermassVert from '@/graph/modules/ForceCenter/calculate-centermass.vert?raw'\nimport forceFrag from '@/graph/modules/ForceCenter/force-center.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport class ForceCenter extends CoreModule {\n private centermassTexture: Texture | undefined\n private centermassFbo: Framebuffer | undefined\n private pointIndices: Buffer | undefined\n\n private calculateCentermassCommand: Model | undefined\n private runCommand: Model | undefined\n\n private forceVertexCoordBuffer: Buffer | undefined\n\n private calculateUniformStore: UniformStore<{\n calculateCentermassUniforms: {\n pointsTextureSize: number;\n };\n }> | undefined\n\n private forceUniformStore: UniformStore<{\n forceCenterUniforms: {\n centerForce: number;\n alpha: number;\n };\n }> | undefined\n\n private previousPointsTextureSize: number | undefined\n\n public create (): void {\n const { device, store } = this\n const { pointsTextureSize } = store\n if (!pointsTextureSize) return\n\n this.centermassTexture ||= device.createTexture({\n width: 1,\n height: 1,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.centermassTexture.copyImageData({\n data: new Float32Array(4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', 1),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n this.centermassFbo ||= device.createFramebuffer({\n width: 1,\n height: 1,\n colorAttachments: [this.centermassTexture],\n })\n\n // Update pointIndices buffer if pointsTextureSize changed\n if (!this.pointIndices || this.previousPointsTextureSize !== store.pointsTextureSize) {\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n this.pointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.calculateCentermassCommand?.setAttributes({\n pointIndices: this.pointIndices,\n })\n }\n\n this.previousPointsTextureSize = pointsTextureSize\n }\n\n public initPrograms (): void {\n const { device, store, points } = this\n if (!points || !store.pointsTextureSize) return\n if (!this.centermassFbo || this.centermassFbo.destroyed || !this.centermassTexture || this.centermassTexture.destroyed) return\n\n this.forceVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.calculateUniformStore ||= new UniformStore({\n calculateCentermassUniforms: {\n uniformTypes: {\n pointsTextureSize: 'f32',\n },\n },\n })\n\n this.forceUniformStore ||= new UniformStore({\n forceCenterUniforms: {\n uniformTypes: {\n centerForce: 'f32',\n alpha: 'f32',\n },\n },\n })\n\n this.calculateCentermassCommand ||= new Model(device, {\n fs: calculateCentermassFrag,\n vs: calculateCentermassVert,\n topology: 'point-list',\n attributes: {\n ...this.pointIndices && { pointIndices: this.pointIndices },\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n calculateCentermassUniforms: this.calculateUniformStore.getManagedUniformBuffer(device, 'calculateCentermassUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.forceVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceCenterUniforms: this.forceUniformStore.getManagedUniformBuffer(device, 'forceCenterUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, store, points } = this\n if (!points) return\n if (!this.calculateCentermassCommand || !this.calculateUniformStore || !this.runCommand || !this.forceUniformStore) return\n if (!this.centermassFbo || !this.centermassTexture) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n // Skip if sizes changed and create() wasn't called yet\n if (store.pointsTextureSize !== this.previousPointsTextureSize) return\n\n // Ensure pointIndices is set (Model might exist but attributes not set yet)\n if (!this.pointIndices) return\n\n // Clear centermass framebuffer and accumulate point positions\n const centermassPass = device.beginRenderPass({\n framebuffer: this.centermassFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.calculateUniformStore.setUniforms({\n calculateCentermassUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n },\n })\n // Update texture bindings dynamically\n this.calculateCentermassCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n this.calculateCentermassCommand.draw(centermassPass)\n centermassPass.end()\n\n // Apply center force into velocity\n this.forceUniformStore.setUniforms({\n forceCenterUniforms: {\n centerForce: this.config.simulationCenter ?? 0,\n alpha: store.alpha,\n },\n })\n // Update texture bindings dynamically\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n centermassTexture: this.centermassTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.calculateCentermassCommand?.destroy()\n this.calculateCentermassCommand = undefined\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.centermassFbo && !this.centermassFbo.destroyed) {\n this.centermassFbo.destroy()\n }\n this.centermassFbo = undefined\n\n // 3. Destroy Textures\n if (this.centermassTexture && !this.centermassTexture.destroyed) {\n this.centermassTexture.destroy()\n }\n this.centermassTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.calculateUniformStore?.destroy()\n this.calculateUniformStore = undefined\n this.forceUniformStore?.destroy()\n this.forceUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n this.pointIndices = undefined\n if (this.forceVertexCoordBuffer && !this.forceVertexCoordBuffer.destroyed) {\n this.forceVertexCoordBuffer.destroy()\n }\n this.forceVertexCoordBuffer = undefined\n\n this.previousPointsTextureSize = undefined\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceGravityUniforms {\\n float gravity;\\n float spaceSize;\\n float alpha;\\n} forceGravity;\\n\\n#define gravity forceGravity.gravity\\n#define spaceSize forceGravity.spaceSize\\n#define alpha forceGravity.alpha\\n#else\\nuniform float gravity;\\nuniform float spaceSize;\\nuniform float alpha;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n\\n vec4 velocity = vec4(0.0);\\n\\n vec2 centerPosition = vec2(spaceSize * 0.5);\\n vec2 distVector = centerPosition - pointPosition.rg;\\n float dist = sqrt(dot(distVector, distVector));\\n if (dist > 0.0) {\\n float angle = atan(distVector.y, distVector.x);\\n float additionalVelocity = alpha * gravity * dist * 0.1;\\n velocity.rg += additionalVelocity * vec2(cos(angle), sin(angle));\\n }\\n\\n fragColor = velocity;\\n}\"","import { Buffer, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport forceFrag from '@/graph/modules/ForceGravity/force-gravity.frag?raw'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport class ForceGravity extends CoreModule {\n private runCommand: Model | undefined\n private vertexCoordBuffer: Buffer | undefined\n private uniformStore: UniformStore<{\n forceGravityUniforms: {\n gravity: number;\n spaceSize: number;\n alpha: number;\n };\n }> | undefined\n\n public initPrograms (): void {\n const { device, points, store } = this\n if (!points || !store.pointsTextureSize) return\n\n this.vertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.uniformStore ||= new UniformStore({\n forceGravityUniforms: {\n uniformTypes: {\n gravity: 'f32',\n spaceSize: 'f32',\n alpha: 'f32',\n },\n },\n })\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.vertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceGravityUniforms: this.uniformStore.getManagedUniformBuffer(device, 'forceGravityUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, points, store } = this\n if (!points) return\n if (!this.runCommand || !this.uniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n this.uniformStore.setUniforms({\n forceGravityUniforms: {\n gravity: this.config.simulationGravity ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n alpha: store.alpha,\n },\n })\n\n // Update texture bindings dynamically\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n // ForceGravity has no framebuffers\n\n // 3. Destroy Textures\n // ForceGravity has no textures\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.uniformStore?.destroy()\n this.uniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.vertexCoordBuffer && !this.vertexCoordBuffer.destroyed) {\n this.vertexCoordBuffer.destroy()\n }\n this.vertexCoordBuffer = undefined\n }\n}\n","export function forceFrag (maxLinks: number): string {\n return `#version 300 es\nprecision highp float;\n\nuniform sampler2D positionsTexture;\nuniform sampler2D linkInfoTexture; // Texture storing first link indices and amount\nuniform sampler2D linkIndicesTexture;\nuniform sampler2D linkPropertiesTexture; // Texture storing link bias and strength\nuniform sampler2D linkRandomDistanceTexture;\n\n#ifdef USE_UNIFORM_BUFFERS\nlayout(std140) uniform forceLinkUniforms {\n float linkSpring;\n float linkDistance;\n vec2 linkDistRandomVariationRange;\n float pointsTextureSize;\n float linksTextureSize;\n float alpha;\n} forceLink;\n\n#define linkSpring forceLink.linkSpring\n#define linkDistance forceLink.linkDistance\n#define linkDistRandomVariationRange forceLink.linkDistRandomVariationRange\n#define pointsTextureSize forceLink.pointsTextureSize\n#define linksTextureSize forceLink.linksTextureSize\n#define alpha forceLink.alpha\n#else\nuniform float linkSpring;\nuniform float linkDistance;\nuniform vec2 linkDistRandomVariationRange;\nuniform float pointsTextureSize;\nuniform float linksTextureSize;\nuniform float alpha;\n#endif\n\nin vec2 textureCoords;\nout vec4 fragColor;\n\nconst float MAX_LINKS = ${maxLinks}.0;\n\nvoid main() {\n vec4 pointPosition = texture(positionsTexture, textureCoords);\n vec4 velocity = vec4(0.0);\n\n vec4 linkInfo = texture(linkInfoTexture, textureCoords);\n float iCount = linkInfo.r;\n float jCount = linkInfo.g;\n float linkAmount = linkInfo.b;\n if (linkAmount > 0.0) {\n for (float i = 0.0; i < MAX_LINKS; i += 1.0) {\n if (i < linkAmount) {\n if (iCount >= linksTextureSize) {\n iCount = 0.0;\n jCount += 1.0;\n }\n vec2 linkTextureIndex = (vec2(iCount, jCount) + 0.5) / linksTextureSize;\n vec4 connectedPointIndex = texture(linkIndicesTexture, linkTextureIndex);\n vec4 biasAndStrength = texture(linkPropertiesTexture, linkTextureIndex);\n vec4 randomMinDistance = texture(linkRandomDistanceTexture, linkTextureIndex);\n float bias = biasAndStrength.r;\n float strength = biasAndStrength.g;\n float randomMinLinkDist = randomMinDistance.r * (linkDistRandomVariationRange.g - linkDistRandomVariationRange.r) + linkDistRandomVariationRange.r;\n randomMinLinkDist *= linkDistance;\n\n iCount += 1.0;\n\n vec4 connectedPointPosition = texture(positionsTexture, (connectedPointIndex.rg + 0.5) / pointsTextureSize);\n float x = connectedPointPosition.x - (pointPosition.x + velocity.x);\n float y = connectedPointPosition.y - (pointPosition.y + velocity.y);\n float l = sqrt(x * x + y * y);\n\n // Apply the link force\n l = max(l, randomMinLinkDist * 0.99);\n l = (l - randomMinLinkDist) / l;\n l *= linkSpring * alpha;\n l *= strength;\n l *= bias;\n x *= l;\n y *= l;\n velocity.x += x;\n velocity.y += y;\n }\n }\n }\n\n fragColor = vec4(velocity.rg, 0.0, 0.0);\n}\n `\n}\n","/**\n * Validates and normalizes array values to fixed-size tuples for shader uniforms.\n */\n\n/**\n * Ensures a value is a vec2 tuple [number, number].\n */\nexport function ensureVec2 (\n arr: number[] | undefined,\n fallback: [number, number]\n): [number, number] {\n if (!arr || arr.length !== 2) return fallback\n return [arr[0], arr[1]] as [number, number]\n}\n\n/**\n * Ensures a value is a vec4 tuple [number, number, number, number].\n */\nexport function ensureVec4 (\n arr: number[] | undefined,\n fallback: [number, number, number, number]\n): [number, number, number, number] {\n if (!arr || arr.length !== 4) return fallback\n return [arr[0], arr[1], arr[2], arr[3]] as [number, number, number, number]\n}\n","import { Buffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport { forceFrag } from '@/graph/modules/ForceLink/force-spring'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport { ensureVec2 } from '@/graph/modules/Shared/uniform-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport enum LinkDirection {\n OUTGOING = 'outgoing',\n INCOMING = 'incoming'\n}\n\nexport class ForceLink extends CoreModule {\n private linkFirstIndicesAndAmount: Float32Array = new Float32Array()\n private indices: Float32Array = new Float32Array()\n private maxPointDegree = 0\n private previousMaxPointDegree: number | undefined\n private previousPointsTextureSize: number | undefined\n private previousLinksTextureSize: number | undefined\n\n private runCommand: Model | undefined\n private vertexCoordBuffer: Buffer | undefined\n private uniformStore: UniformStore<{\n forceLinkUniforms: {\n linkSpring: number;\n linkDistance: number;\n linkDistRandomVariationRange: [number, number];\n pointsTextureSize: number;\n linksTextureSize: number;\n alpha: number;\n };\n }> | undefined\n\n private linkFirstIndicesAndAmountTexture: Texture | undefined\n private indicesTexture: Texture | undefined\n private biasAndStrengthTexture: Texture | undefined\n private randomDistanceTexture: Texture | undefined\n\n public create (direction: LinkDirection): void {\n const { device, store: { pointsTextureSize, linksTextureSize }, data } = this\n if (!pointsTextureSize || !linksTextureSize) return\n\n this.linkFirstIndicesAndAmount = new Float32Array(pointsTextureSize * pointsTextureSize * 4)\n this.indices = new Float32Array(linksTextureSize * linksTextureSize * 4)\n const linkBiasAndStrengthState = new Float32Array(linksTextureSize * linksTextureSize * 4)\n const linkDistanceState = new Float32Array(linksTextureSize * linksTextureSize * 4)\n\n const grouped = direction === LinkDirection.INCOMING ? data.sourceIndexToTargetIndices : data.targetIndexToSourceIndices\n this.maxPointDegree = 0\n let linkIndex = 0\n grouped?.forEach((connectedPointIndices, pointIndex) => {\n if (connectedPointIndices) {\n this.linkFirstIndicesAndAmount[pointIndex * 4 + 0] = linkIndex % linksTextureSize\n this.linkFirstIndicesAndAmount[pointIndex * 4 + 1] = Math.floor(linkIndex / linksTextureSize)\n this.linkFirstIndicesAndAmount[pointIndex * 4 + 2] = connectedPointIndices.length ?? 0\n\n connectedPointIndices.forEach(([connectedPointIndex, initialLinkIndex]) => {\n this.indices[linkIndex * 4 + 0] = connectedPointIndex % pointsTextureSize\n this.indices[linkIndex * 4 + 1] = Math.floor(connectedPointIndex / pointsTextureSize)\n const degree = data.degree?.[connectedPointIndex] ?? 0\n const connectedDegree = data.degree?.[pointIndex] ?? 0\n const degreeSum = degree + connectedDegree\n // Prevent division by zero\n const bias = degreeSum !== 0 ? degree / degreeSum : 0.5\n const minDegree = Math.min(degree, connectedDegree)\n // Prevent division by zero\n let strength = data.linkStrength?.[initialLinkIndex] ?? (1 / Math.max(minDegree, 1))\n strength = Math.sqrt(strength)\n linkBiasAndStrengthState[linkIndex * 4 + 0] = bias\n linkBiasAndStrengthState[linkIndex * 4 + 1] = strength\n linkDistanceState[linkIndex * 4] = this.store.getRandomFloat(0, 1)\n\n linkIndex += 1\n })\n\n this.maxPointDegree = Math.max(this.maxPointDegree, connectedPointIndices.length ?? 0)\n }\n })\n\n // Recreate textures if sizes changed\n const recreatePointTextures =\n !this.linkFirstIndicesAndAmountTexture ||\n this.linkFirstIndicesAndAmountTexture.width !== pointsTextureSize ||\n this.linkFirstIndicesAndAmountTexture.height !== pointsTextureSize\n\n const recreateLinkTextures =\n !this.indicesTexture ||\n this.indicesTexture.width !== linksTextureSize ||\n this.indicesTexture.height !== linksTextureSize\n\n if (recreatePointTextures) {\n if (this.linkFirstIndicesAndAmountTexture && !this.linkFirstIndicesAndAmountTexture.destroyed) {\n this.linkFirstIndicesAndAmountTexture.destroy()\n }\n this.linkFirstIndicesAndAmountTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n }\n this.linkFirstIndicesAndAmountTexture!.copyImageData({\n data: this.linkFirstIndicesAndAmount,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n if (recreateLinkTextures) {\n if (this.indicesTexture && !this.indicesTexture.destroyed) this.indicesTexture.destroy()\n if (this.biasAndStrengthTexture && !this.biasAndStrengthTexture.destroyed) this.biasAndStrengthTexture.destroy()\n if (this.randomDistanceTexture && !this.randomDistanceTexture.destroyed) this.randomDistanceTexture.destroy()\n\n this.indicesTexture = device.createTexture({\n width: linksTextureSize,\n height: linksTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n this.biasAndStrengthTexture = device.createTexture({\n width: linksTextureSize,\n height: linksTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n this.randomDistanceTexture = device.createTexture({\n width: linksTextureSize,\n height: linksTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n }\n\n this.indicesTexture!.copyImageData({\n data: this.indices,\n bytesPerRow: getBytesPerRow('rgba32float', linksTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.biasAndStrengthTexture!.copyImageData({\n data: linkBiasAndStrengthState,\n bytesPerRow: getBytesPerRow('rgba32float', linksTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.randomDistanceTexture!.copyImageData({\n data: linkDistanceState,\n bytesPerRow: getBytesPerRow('rgba32float', linksTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Force shader rebuild if degree changed\n if (this.previousMaxPointDegree !== undefined && this.previousMaxPointDegree !== this.maxPointDegree) {\n this.runCommand?.destroy()\n this.runCommand = undefined\n }\n\n this.previousMaxPointDegree = this.maxPointDegree\n this.previousPointsTextureSize = pointsTextureSize\n this.previousLinksTextureSize = linksTextureSize\n }\n\n public initPrograms (): void {\n const { device, store, points } = this\n if (!points || !store.pointsTextureSize || !store.linksTextureSize) return\n if (!this.linkFirstIndicesAndAmountTexture || !this.indicesTexture || !this.biasAndStrengthTexture || !this.randomDistanceTexture) return\n\n this.vertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.uniformStore ||= new UniformStore({\n forceLinkUniforms: {\n uniformTypes: {\n linkSpring: 'f32',\n linkDistance: 'f32',\n linkDistRandomVariationRange: 'vec2<f32>',\n pointsTextureSize: 'f32',\n linksTextureSize: 'f32',\n alpha: 'f32',\n },\n },\n })\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag(this.maxPointDegree),\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.vertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceLinkUniforms: this.uniformStore.getManagedUniformBuffer(device, 'forceLinkUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, store, points } = this\n if (!points) return\n if (!this.runCommand || !this.uniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!this.linkFirstIndicesAndAmountTexture || !this.indicesTexture || !this.biasAndStrengthTexture || !this.randomDistanceTexture) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n // Skip if sizes changed and create() wasn't called again\n if (\n store.pointsTextureSize !== this.previousPointsTextureSize ||\n store.linksTextureSize !== this.previousLinksTextureSize\n ) {\n return\n }\n\n this.uniformStore.setUniforms({\n forceLinkUniforms: {\n linkSpring: this.config.simulationLinkSpring ?? 0,\n linkDistance: this.config.simulationLinkDistance ?? 0,\n linkDistRandomVariationRange: ensureVec2(this.config.simulationLinkDistRandomVariationRange, [0, 0]),\n pointsTextureSize: store.pointsTextureSize,\n linksTextureSize: store.linksTextureSize,\n alpha: store.alpha,\n },\n })\n\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n linkInfoTexture: this.linkFirstIndicesAndAmountTexture,\n linkIndicesTexture: this.indicesTexture,\n linkPropertiesTexture: this.biasAndStrengthTexture,\n linkRandomDistanceTexture: this.randomDistanceTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n // ForceLink has no framebuffers\n\n // 3. Destroy Textures\n if (this.linkFirstIndicesAndAmountTexture && !this.linkFirstIndicesAndAmountTexture.destroyed) {\n this.linkFirstIndicesAndAmountTexture.destroy()\n }\n this.linkFirstIndicesAndAmountTexture = undefined\n if (this.indicesTexture && !this.indicesTexture.destroyed) {\n this.indicesTexture.destroy()\n }\n this.indicesTexture = undefined\n if (this.biasAndStrengthTexture && !this.biasAndStrengthTexture.destroyed) {\n this.biasAndStrengthTexture.destroy()\n }\n this.biasAndStrengthTexture = undefined\n if (this.randomDistanceTexture && !this.randomDistanceTexture.destroyed) {\n this.randomDistanceTexture.destroy()\n }\n this.randomDistanceTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.uniformStore?.destroy()\n this.uniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.vertexCoordBuffer && !this.vertexCoordBuffer.destroyed) {\n this.vertexCoordBuffer.destroy()\n }\n this.vertexCoordBuffer = undefined\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nin vec4 vColor;\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = vColor;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform calculateLevelsUniforms {\\n float pointsTextureSize;\\n float levelTextureSize;\\n float cellSize;\\n} calculateLevels;\\n\\n#define pointsTextureSize calculateLevels.pointsTextureSize\\n#define levelTextureSize calculateLevels.levelTextureSize\\n#define cellSize calculateLevels.cellSize\\n#else\\nuniform float pointsTextureSize;\\nuniform float levelTextureSize;\\nuniform float cellSize;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nout vec4 vColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, pointIndices / pointsTextureSize);\\n vColor = vec4(pointPosition.rg, 1.0, 0.0);\\n\\n float n = floor(pointPosition.x / cellSize);\\n float m = floor(pointPosition.y / cellSize);\\n \\n vec2 levelPosition = 2.0 * (vec2(n, m) + 0.5) / levelTextureSize - 1.0;\\n\\n gl_Position = vec4(levelPosition, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D levelFbo;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceUniforms {\\n float level;\\n float levels;\\n float levelTextureSize;\\n float alpha;\\n float repulsion;\\n float spaceSize;\\n float theta;\\n} force;\\n\\n#define level force.level\\n#define levels force.levels\\n#define levelTextureSize force.levelTextureSize\\n#define alpha force.alpha\\n#define repulsion force.repulsion\\n#define spaceSize force.spaceSize\\n#define theta force.theta\\n#else\\nuniform float level;\\nuniform float levels;\\nuniform float levelTextureSize;\\nuniform float repulsion;\\nuniform float alpha;\\nuniform float spaceSize;\\nuniform float theta;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nconst float MAX_LEVELS_NUM = 14.0;\\n\\nvec2 calculateAdditionalVelocity (vec2 ij, vec2 pp) {\\n vec2 add = vec2(0.0);\\n vec4 centermass = texture(levelFbo, ij);\\n if (centermass.r > 0.0 && centermass.g > 0.0 && centermass.b > 0.0) {\\n vec2 centermassPosition = vec2(centermass.rg / centermass.b);\\n vec2 distVector = pp - centermassPosition;\\n float l = dot(distVector, distVector);\\n float dist = sqrt(l);\\n if (l > 0.0) {\\n float c = alpha * repulsion * centermass.b;\\n\\n float distanceMin2 = 1.0;\\n if (l < distanceMin2) l = sqrt(distanceMin2 * l);\\n float addV = c / sqrt(l);\\n add = addV * normalize(distVector);\\n }\\n }\\n return add;\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n float x = pointPosition.x;\\n float y = pointPosition.y;\\n\\n float left = 0.0;\\n float top = 0.0;\\n float right = spaceSize;\\n float bottom = spaceSize;\\n\\n float n_left = 0.0;\\n float n_top = 0.0;\\n float n_right = 0.0;\\n float n_bottom = 0.0;\\n\\n float cellSize = 0.0;\\n\\n // Iterate over levels to adjust the boundaries based on the current level\\n for (float i = 0.0; i < MAX_LEVELS_NUM; i += 1.0) {\\n if (i <= level) {\\n left += cellSize * n_left;\\n top += cellSize * n_top;\\n right -= cellSize * n_right;\\n bottom -= cellSize * n_bottom;\\n\\n cellSize = pow(2.0 , levels - i - 1.0);\\n\\n float dist_left = x - left;\\n n_left = max(0.0, floor(dist_left / cellSize - theta));\\n\\n float dist_top = y - top;\\n n_top = max(0.0, floor(dist_top / cellSize - theta));\\n \\n float dist_right = right - x;\\n n_right = max(0.0, floor(dist_right / cellSize - theta));\\n\\n float dist_bottom = bottom - y;\\n n_bottom = max(0.0, floor(dist_bottom / cellSize - theta));\\n\\n }\\n }\\n\\n vec4 velocity = vec4(vec2(0.0), 1.0, 0.0);\\n\\n // Calculate the additional velocity based on neighboring cells\\n for (float i = 0.0; i < 12.0; i += 1.0) {\\n for (float j = 0.0; j < 4.0; j += 1.0) {\\n float n = left + cellSize * j;\\n float m = top + cellSize * n_top + cellSize * i;\\n\\n if (n < (left + n_left * cellSize) && m < bottom) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n\\n n = left + cellSize * i;\\n m = top + cellSize * j;\\n\\n if (n < (right - n_right * cellSize) && m < (top + n_top * cellSize)) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n\\n n = right - n_right * cellSize + cellSize * j;\\n m = top + cellSize * i;\\n\\n if (n < right && m < (bottom - n_bottom * cellSize)) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n\\n n = left + n_left * cellSize + cellSize * i;\\n m = bottom - n_bottom * cellSize + cellSize * j;\\n\\n if (n < right && m < bottom) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n }\\n }\\n\\n fragColor = velocity;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D levelFbo;\\nuniform sampler2D randomValues;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceCenterUniforms {\\n float levelTextureSize;\\n float alpha;\\n float repulsion;\\n} forceCenter;\\n\\n#define levelTextureSize forceCenter.levelTextureSize\\n#define repulsion forceCenter.repulsion\\n#define alpha forceCenter.alpha\\n#else\\nuniform float levelTextureSize;\\nuniform float alpha;\\nuniform float repulsion;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\n// Calculate the additional velocity based on the center of mass\\nvec2 calculateAdditionalVelocity (vec2 ij, vec2 pp) {\\n vec2 add = vec2(0.0);\\n vec4 centermass = texture(levelFbo, ij);\\n if (centermass.r > 0.0 && centermass.g > 0.0 && centermass.b > 0.0) {\\n vec2 centermassPosition = vec2(centermass.rg / centermass.b);\\n vec2 distVector = pp - centermassPosition;\\n float l = dot(distVector, distVector);\\n float dist = sqrt(l);\\n if (l > 0.0) {\\n float angle = atan(distVector.y, distVector.x);\\n float c = alpha * repulsion * centermass.b;\\n\\n float distanceMin2 = 1.0;\\n if (l < distanceMin2) l = sqrt(distanceMin2 * l);\\n float addV = c / sqrt(l);\\n add = addV * vec2(cos(angle), sin(angle));\\n }\\n }\\n return add;\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 random = texture(randomValues, textureCoords);\\n\\n vec4 velocity = vec4(0.0);\\n\\n // Calculate additional velocity based on the point position\\n velocity.xy += calculateAdditionalVelocity(pointPosition.xy / levelTextureSize, pointPosition.xy);\\n // Apply random factor to the velocity\\n velocity.xy += velocity.xy * random.rg;\\n\\n fragColor = velocity;\\n}\"","import { Buffer, Framebuffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport calculateLevelFrag from '@/graph/modules/ForceManyBody/calculate-level.frag?raw'\nimport calculateLevelVert from '@/graph/modules/ForceManyBody/calculate-level.vert?raw'\nimport forceFrag from '@/graph/modules/ForceManyBody/force-level.frag?raw'\nimport forceCenterFrag from '@/graph/modules/ForceManyBody/force-centermass.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\ntype LevelTarget = {\n texture: Texture;\n fbo: Framebuffer;\n}\n\nexport class ForceManyBody extends CoreModule {\n private randomValuesTexture: Texture | undefined\n private pointIndices: Buffer | undefined\n private levels = 0\n private levelTargets = new Map<number, LevelTarget>()\n\n private calculateLevelsCommand: Model | undefined\n private forceCommand: Model | undefined\n private forceFromItsOwnCentermassCommand: Model | undefined\n\n private forceVertexCoordBuffer: Buffer | undefined\n\n private calculateLevelsUniformStore: UniformStore<{\n calculateLevelsUniforms: {\n pointsTextureSize: number;\n levelTextureSize: number;\n cellSize: number;\n };\n }> | undefined\n\n private forceUniformStore: UniformStore<{\n forceUniforms: {\n level: number;\n levels: number;\n levelTextureSize: number;\n alpha: number;\n repulsion: number;\n spaceSize: number;\n theta: number;\n };\n }> | undefined\n\n private forceCenterUniformStore: UniformStore<{\n forceCenterUniforms: {\n levelTextureSize: number;\n alpha: number;\n repulsion: number;\n };\n }> | undefined\n\n private previousPointsTextureSize: number | undefined\n private previousSpaceSize: number | undefined\n\n public create (): void {\n const { device, store } = this\n if (!store.pointsTextureSize) return\n\n this.levels = Math.log2(store.adjustedSpaceSize)\n\n // Allocate quadtree levels\n for (let level = 0; level < this.levels; level += 1) {\n const levelTextureSize = Math.pow(2, level + 1)\n const existingTarget = this.levelTargets.get(level)\n\n if (\n existingTarget &&\n existingTarget.texture.width === levelTextureSize &&\n existingTarget.texture.height === levelTextureSize\n ) {\n // Clear existing texture data to zero\n existingTarget.texture.copyImageData({\n data: new Float32Array(levelTextureSize * levelTextureSize * 4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', levelTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n continue\n }\n\n // Destroy old resources if size changed\n if (existingTarget) {\n if (!existingTarget.fbo.destroyed) existingTarget.fbo.destroy()\n if (!existingTarget.texture.destroyed) existingTarget.texture.destroy()\n }\n\n const texture = device.createTexture({\n width: levelTextureSize,\n height: levelTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n texture.copyImageData({\n data: new Float32Array(levelTextureSize * levelTextureSize * 4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', levelTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n const fbo = device.createFramebuffer({\n width: levelTextureSize,\n height: levelTextureSize,\n colorAttachments: [texture],\n })\n this.levelTargets.set(level, { texture, fbo })\n }\n\n // Drop any stale higher-level buffers if space size shrank\n for (const [level, target] of Array.from(this.levelTargets.entries())) {\n if (level >= this.levels) {\n if (!target.fbo.destroyed) target.fbo.destroy()\n if (!target.texture.destroyed) target.texture.destroy()\n this.levelTargets.delete(level)\n }\n }\n\n // Random jitter texture to prevent sticking\n const totalPixels = store.pointsTextureSize * store.pointsTextureSize\n const randomValuesState = new Float32Array(totalPixels * 4)\n for (let i = 0; i < totalPixels; ++i) {\n randomValuesState[i * 4] = store.getRandomFloat(-1, 1) * 0.00001\n randomValuesState[i * 4 + 1] = store.getRandomFloat(-1, 1) * 0.00001\n }\n\n const recreateRandomValuesTexture =\n !this.randomValuesTexture ||\n this.randomValuesTexture.destroyed ||\n this.randomValuesTexture.width !== store.pointsTextureSize ||\n this.randomValuesTexture.height !== store.pointsTextureSize\n\n if (recreateRandomValuesTexture) {\n if (this.randomValuesTexture && !this.randomValuesTexture.destroyed) {\n this.randomValuesTexture.destroy()\n }\n this.randomValuesTexture = device.createTexture({\n width: store.pointsTextureSize,\n height: store.pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n }\n this.randomValuesTexture!.copyImageData({\n data: randomValuesState,\n bytesPerRow: getBytesPerRow('rgba32float', store.pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Update pointIndices buffer if pointsTextureSize changed\n if (!this.pointIndices || this.previousPointsTextureSize !== store.pointsTextureSize) {\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n this.pointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.calculateLevelsCommand?.setAttributes({\n pointIndices: this.pointIndices,\n })\n }\n\n this.previousPointsTextureSize = store.pointsTextureSize\n this.previousSpaceSize = store.adjustedSpaceSize\n }\n\n public initPrograms (): void {\n const { device, store, data, points } = this\n if (!data.pointsNumber || !points || !store.pointsTextureSize) return\n\n // Calculate levels command (point list)\n this.calculateLevelsUniformStore ||= new UniformStore({\n calculateLevelsUniforms: {\n uniformTypes: {\n pointsTextureSize: 'f32',\n levelTextureSize: 'f32',\n cellSize: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize,\n levelTextureSize: 0,\n cellSize: 0,\n },\n },\n })\n\n this.calculateLevelsCommand ||= new Model(device, {\n fs: calculateLevelFrag,\n vs: calculateLevelVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber,\n attributes: {\n ...this.pointIndices && { pointIndices: this.pointIndices },\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n calculateLevelsUniforms: this.calculateLevelsUniformStore.getManagedUniformBuffer(device, 'calculateLevelsUniforms'),\n // All texture bindings will be set dynamically in drawLevels() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Force command (fullscreen quad)\n this.forceUniformStore ||= new UniformStore({\n forceUniforms: {\n uniformTypes: {\n level: 'f32',\n levels: 'f32',\n levelTextureSize: 'f32',\n alpha: 'f32',\n repulsion: 'f32',\n spaceSize: 'f32',\n theta: 'f32',\n },\n defaultUniforms: {\n level: 0,\n levels: this.levels,\n levelTextureSize: 0,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n theta: this.config.simulationRepulsionTheta ?? 0,\n },\n },\n })\n\n this.forceVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.forceCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.forceVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceUniforms: this.forceUniformStore.getManagedUniformBuffer(device, 'forceUniforms'),\n // All texture bindings will be set dynamically in drawForces() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Force-from-centermass command (fullscreen quad)\n this.forceCenterUniformStore ||= new UniformStore({\n forceCenterUniforms: {\n uniformTypes: {\n levelTextureSize: 'f32',\n alpha: 'f32',\n repulsion: 'f32',\n },\n defaultUniforms: {\n levelTextureSize: 0,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n },\n },\n })\n\n this.forceFromItsOwnCentermassCommand ||= new Model(device, {\n fs: forceCenterFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.forceVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceCenterUniforms: this.forceCenterUniformStore.getManagedUniformBuffer(device, 'forceCenterUniforms'),\n // All texture bindings will be set dynamically in drawForces() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n // Skip if sizes changed and create() wasn't called yet\n if (this.store.pointsTextureSize !== this.previousPointsTextureSize || this.store.adjustedSpaceSize !== this.previousSpaceSize) {\n return\n }\n this.drawLevels()\n this.drawForces()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.calculateLevelsCommand?.destroy()\n this.calculateLevelsCommand = undefined\n this.forceCommand?.destroy()\n this.forceCommand = undefined\n this.forceFromItsOwnCentermassCommand?.destroy()\n this.forceFromItsOwnCentermassCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n for (const target of this.levelTargets.values()) {\n if (target.fbo && !target.fbo.destroyed) {\n target.fbo.destroy()\n }\n }\n\n // 3. Destroy Textures\n if (this.randomValuesTexture && !this.randomValuesTexture.destroyed) {\n this.randomValuesTexture.destroy()\n }\n this.randomValuesTexture = undefined\n\n for (const target of this.levelTargets.values()) {\n if (target.texture && !target.texture.destroyed) {\n target.texture.destroy()\n }\n }\n this.levelTargets.clear()\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.calculateLevelsUniformStore?.destroy()\n this.calculateLevelsUniformStore = undefined\n this.forceUniformStore?.destroy()\n this.forceUniformStore = undefined\n this.forceCenterUniformStore?.destroy()\n this.forceCenterUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n this.pointIndices = undefined\n if (this.forceVertexCoordBuffer && !this.forceVertexCoordBuffer.destroyed) {\n this.forceVertexCoordBuffer.destroy()\n }\n this.forceVertexCoordBuffer = undefined\n }\n\n private drawLevels (): void {\n const { device, store, data, points } = this\n if (!points) return\n if (!this.calculateLevelsCommand || !this.calculateLevelsUniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!data.pointsNumber) return\n // Ensure pointIndices is set (Model might exist but attributes not set yet)\n if (!this.pointIndices) return\n\n for (let level = 0; level < this.levels; level += 1) {\n const target = this.levelTargets.get(level)\n if (!target || target.fbo.destroyed || target.texture.destroyed) continue\n\n const levelTextureSize = Math.pow(2, level + 1)\n const cellSize = (store.adjustedSpaceSize ?? 0) / levelTextureSize\n\n this.calculateLevelsUniformStore.setUniforms({\n calculateLevelsUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n levelTextureSize,\n cellSize,\n },\n })\n\n this.calculateLevelsCommand.setVertexCount(data.pointsNumber)\n // Update texture bindings dynamically\n this.calculateLevelsCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n const levelPass = device.beginRenderPass({\n framebuffer: target.fbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.calculateLevelsCommand.draw(levelPass)\n\n levelPass.end()\n }\n }\n\n private drawForces (): void {\n const { device, store, points } = this\n if (!points) return\n if (!this.forceCommand || !this.forceUniformStore) return\n if (!this.forceFromItsOwnCentermassCommand || !this.forceCenterUniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!this.randomValuesTexture || this.randomValuesTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n const drawPass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n for (let level = 0; level < this.levels; level += 1) {\n const target = this.levelTargets.get(level)\n if (!target || target.texture.destroyed) continue\n const levelTextureSize = Math.pow(2, level + 1)\n\n this.forceUniformStore.setUniforms({\n forceUniforms: {\n level,\n levels: this.levels,\n levelTextureSize,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n theta: this.config.simulationRepulsionTheta ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.forceCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n levelFbo: target.texture,\n })\n\n this.forceCommand.draw(drawPass)\n\n // Only the deepest level uses the centermass fallback\n if (level === this.levels - 1) {\n this.forceCenterUniformStore.setUniforms({\n forceCenterUniforms: {\n levelTextureSize,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.forceFromItsOwnCentermassCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n randomValues: this.randomValuesTexture,\n levelFbo: target.texture,\n })\n this.forceFromItsOwnCentermassCommand.draw(drawPass)\n }\n }\n\n drawPass.end()\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceMouseUniforms {\\n float repulsion;\\n vec2 mousePos;\\n} forceMouse;\\n\\n#define repulsion forceMouse.repulsion\\n#define mousePos forceMouse.mousePos\\n#else\\nuniform float repulsion;\\nuniform vec2 mousePos;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 velocity = vec4(0.0);\\n vec2 mouse = mousePos;\\n // Move particles away from the mouse position using a repulsive force\\n vec2 distVector = mouse - pointPosition.rg;\\n float dist = sqrt(dot(distVector, distVector));\\n dist = max(dist, 10.0);\\n float angle = atan(distVector.y, distVector.x);\\n float addV = 100.0 * repulsion / (dist * dist);\\n velocity.rg -= addV * vec2(cos(angle), sin(angle));\\n\\n fragColor = velocity;\\n}\"","import { Buffer, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport forceFrag from '@/graph/modules/ForceMouse/force-mouse.frag?raw'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\nimport { ensureVec2 } from '@/graph/modules/Shared/uniform-utils'\n\nexport class ForceMouse extends CoreModule {\n private runCommand: Model | undefined\n private vertexCoordBuffer: Buffer | undefined\n private uniformStore: UniformStore<{\n forceMouseUniforms: {\n repulsion: number;\n mousePos: [number, number];\n };\n }> | undefined\n\n public initPrograms (): void {\n const { device, points } = this\n if (!points) return\n\n this.vertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.uniformStore ||= new UniformStore({\n forceMouseUniforms: {\n uniformTypes: {\n repulsion: 'f32',\n mousePos: 'vec2<f32>',\n },\n },\n })\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.vertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceMouseUniforms: this.uniformStore.getManagedUniformBuffer(device, 'forceMouseUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, points, store } = this\n if (!points) return\n if (!this.runCommand || !this.uniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n this.uniformStore.setUniforms({\n forceMouseUniforms: {\n repulsion: this.config.simulationRepulsionFromMouse ?? 0,\n mousePos: ensureVec2(store.mousePosition, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n // ForceMouse has no framebuffers\n\n // 3. Destroy Textures\n // ForceMouse has no textures\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.uniformStore?.destroy()\n this.uniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.vertexCoordBuffer && !this.vertexCoordBuffer.destroyed) {\n this.vertexCoordBuffer.destroy()\n }\n this.vertexCoordBuffer = undefined\n }\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgba;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D clusterTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform calculateCentermassUniforms {\\n float pointsTextureSize;\\n float clustersTextureSize;\\n} calculateCentermass;\\n\\n#define pointsTextureSize calculateCentermass.pointsTextureSize\\n#define clustersTextureSize calculateCentermass.clustersTextureSize\\n#else\\nuniform float pointsTextureSize;\\nuniform float clustersTextureSize;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nout vec4 rgba;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, pointIndices / pointsTextureSize);\\n rgba = vec4(pointPosition.xy, 1.0, 0.0);\\n\\n vec4 pointClusterIndices = texture(clusterTexture, pointIndices / pointsTextureSize);\\n vec2 xy = vec2(0.0);\\n if (pointClusterIndices.x >= 0.0 && pointClusterIndices.y >= 0.0) {\\n xy = 2.0 * (pointClusterIndices.xy + 0.5) / clustersTextureSize - 1.0;\\n }\\n \\n gl_Position = vec4(xy, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n}\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D centermassTexture;\\nuniform sampler2D clusterTexture;\\nuniform sampler2D clusterPositionsTexture;\\nuniform sampler2D clusterForceCoefficient;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform applyForcesUniforms {\\n float alpha;\\n float clustersTextureSize;\\n float clusterCoefficient;\\n} applyForces;\\n\\n#define alpha applyForces.alpha\\n#define clustersTextureSize applyForces.clustersTextureSize\\n#define clusterCoefficient applyForces.clusterCoefficient\\n#else\\nuniform float alpha;\\nuniform float clustersTextureSize;\\nuniform float clusterCoefficient;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 velocity = vec4(0.0);\\n vec4 pointClusterIndices = texture(clusterTexture, textureCoords);\\n // no cluster, so no forces\\n if (pointClusterIndices.x >= 0.0 && pointClusterIndices.y >= 0.0) {\\n // positioning points to custom cluster position or either to the center of mass\\n vec2 clusterPositions = texture(clusterPositionsTexture, pointClusterIndices.xy / clustersTextureSize).xy;\\n if (clusterPositions.x < 0.0 || clusterPositions.y < 0.0) {\\n vec4 centermassValues = texture(centermassTexture, pointClusterIndices.xy / clustersTextureSize);\\n clusterPositions = centermassValues.xy / centermassValues.b;\\n }\\n vec4 clusterCustomCoeff = texture(clusterForceCoefficient, textureCoords);\\n vec2 distVector = clusterPositions.xy - pointPosition.xy;\\n float dist = length(distVector);\\n if (dist > 0.0) {\\n float addV = alpha * dist * clusterCoefficient * clusterCustomCoeff.r;\\n velocity.rg += addV * normalize(distVector);\\n }\\n }\\n\\n fragColor = velocity;\\n}\"","import { Framebuffer, Buffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport calculateCentermassFrag from '@/graph/modules/Clusters/calculate-centermass.frag?raw'\nimport calculateCentermassVert from '@/graph/modules/Clusters/calculate-centermass.vert?raw'\nimport forceFrag from '@/graph/modules/Clusters/force-cluster.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport class Clusters extends CoreModule {\n public centermassFbo: Framebuffer | undefined\n public clusterCount: number | undefined\n\n private calculateCentermassCommand: Model | undefined\n private applyForcesCommand: Model | undefined\n private clusterTexture: Texture | undefined\n private clusterPositionsTexture: Texture | undefined\n private clusterForceCoefficientTexture: Texture | undefined\n private centermassTexture: Texture | undefined\n private pointIndices: Buffer | undefined\n private clustersTextureSize: number | undefined\n\n private applyForcesVertexCoordBuffer: Buffer | undefined\n\n // Track previous sizes to detect changes\n private previousPointsTextureSize: number | undefined\n private previousClustersTextureSize: number | undefined\n private previousClusterCount: number | undefined\n\n // Uniform stores for scalar uniforms\n private calculateCentermassUniformStore: UniformStore<{\n calculateCentermassUniforms: {\n pointsTextureSize: number;\n clustersTextureSize: number;\n };\n }> | undefined\n\n private applyForcesUniformStore: UniformStore<{\n applyForcesUniforms: {\n alpha: number;\n clustersTextureSize: number;\n clusterCoefficient: number;\n };\n }> | undefined\n\n public create (): void {\n const { device, store, data } = this\n const { pointsTextureSize } = store\n if (data.pointsNumber === undefined || (!data.pointClusters && !data.clusterPositions)) return\n\n // Find the highest cluster index in the array and add 1 (since cluster indices start at 0).\n this.clusterCount = (data.pointClusters ?? []).reduce<number>((max, clusterIndex) => {\n if (clusterIndex === undefined || clusterIndex < 0) return max\n return Math.max(max, clusterIndex)\n }, 0) + 1\n\n this.clustersTextureSize = Math.ceil(Math.sqrt(this.clusterCount))\n\n // Check if sizes have changed - if so, we need to recreate textures/framebuffers\n const sizesChanged =\n this.previousPointsTextureSize !== pointsTextureSize ||\n this.previousClustersTextureSize !== this.clustersTextureSize ||\n this.previousClusterCount !== this.clusterCount\n\n const pointsTextureDataSize = pointsTextureSize * pointsTextureSize * 4\n const clustersTextureDataSize = this.clustersTextureSize * this.clustersTextureSize * 4\n\n const clusterState = new Float32Array(pointsTextureDataSize)\n const clusterPositions = new Float32Array(clustersTextureDataSize).fill(-1)\n const clusterForceCoefficient = new Float32Array(pointsTextureDataSize).fill(1)\n if (data.clusterPositions) {\n for (let cluster = 0; cluster < this.clusterCount; ++cluster) {\n clusterPositions[cluster * 4 + 0] = data.clusterPositions[cluster * 2 + 0] ?? -1\n clusterPositions[cluster * 4 + 1] = data.clusterPositions[cluster * 2 + 1] ?? -1\n }\n }\n\n for (let i = 0; i < data.pointsNumber; ++i) {\n const clusterIndex = data.pointClusters?.[i]\n if (clusterIndex === undefined) {\n // no cluster, so no forces\n clusterState[i * 4 + 0] = -1\n clusterState[i * 4 + 1] = -1\n } else {\n clusterState[i * 4 + 0] = clusterIndex % this.clustersTextureSize\n clusterState[i * 4 + 1] = Math.floor(clusterIndex / this.clustersTextureSize)\n }\n\n if (data.clusterStrength) clusterForceCoefficient[i * 4 + 0] = data.clusterStrength[i] ?? 1\n }\n\n // Handle clusterTexture - recreate if size changed, update data if size same\n if (!this.clusterTexture || sizesChanged) {\n // Then destroy texture\n if (this.clusterTexture && !this.clusterTexture.destroyed) {\n this.clusterTexture.destroy()\n }\n // Create new texture\n this.clusterTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.clusterTexture.copyImageData({\n data: clusterState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n // Size hasn't changed, just update the data\n this.clusterTexture.copyImageData({\n data: clusterState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Handle clusterPositionsTexture\n if (!this.clusterPositionsTexture || sizesChanged) {\n // Then destroy texture\n if (this.clusterPositionsTexture && !this.clusterPositionsTexture.destroyed) {\n this.clusterPositionsTexture.destroy()\n }\n // Create new texture\n this.clusterPositionsTexture = device.createTexture({\n width: this.clustersTextureSize,\n height: this.clustersTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.clusterPositionsTexture.copyImageData({\n data: clusterPositions,\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n // Update data\n this.clusterPositionsTexture.copyImageData({\n data: clusterPositions,\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Handle clusterForceCoefficientTexture\n if (!this.clusterForceCoefficientTexture || sizesChanged) {\n // Then destroy texture\n if (this.clusterForceCoefficientTexture && !this.clusterForceCoefficientTexture.destroyed) {\n this.clusterForceCoefficientTexture.destroy()\n }\n // Create new texture\n this.clusterForceCoefficientTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.clusterForceCoefficientTexture.copyImageData({\n data: clusterForceCoefficient,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n // Update data\n this.clusterForceCoefficientTexture.copyImageData({\n data: clusterForceCoefficient,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Handle centermassTexture - only size depends on clustersTextureSize\n if (!this.centermassTexture || this.previousClustersTextureSize !== this.clustersTextureSize) {\n // Destroy framebuffer FIRST\n if (this.centermassFbo && !this.centermassFbo.destroyed) {\n this.centermassFbo.destroy()\n }\n // Then destroy texture\n if (this.centermassTexture && !this.centermassTexture.destroyed) {\n this.centermassTexture.destroy()\n }\n // Create new texture\n this.centermassTexture = device.createTexture({\n width: this.clustersTextureSize,\n height: this.clustersTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.centermassTexture.copyImageData({\n data: new Float32Array(clustersTextureDataSize).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n // Create new framebuffer with explicit dimensions\n this.centermassFbo = device.createFramebuffer({\n width: this.clustersTextureSize,\n height: this.clustersTextureSize,\n colorAttachments: [this.centermassTexture],\n })\n } else {\n // Clear the centermass texture (fill with zeros)\n this.centermassTexture.copyImageData({\n data: new Float32Array(clustersTextureDataSize).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Update pointIndices buffer if pointsTextureSize changed\n if (!this.pointIndices || this.previousPointsTextureSize !== pointsTextureSize) {\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n this.pointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.calculateCentermassCommand?.setAttributes({\n pointIndices: this.pointIndices,\n })\n }\n\n // Update tracked sizes\n this.previousPointsTextureSize = pointsTextureSize\n this.previousClustersTextureSize = this.clustersTextureSize\n this.previousClusterCount = this.clusterCount\n }\n\n public initPrograms (): void {\n const { device, store, data } = this\n // Use same check as create() and run() for consistency\n if (data.pointsNumber === undefined || (!data.pointClusters && !data.clusterPositions)) return\n\n // Create UniformStore for calculateCentermass uniforms\n this.calculateCentermassUniformStore ||= new UniformStore({\n calculateCentermassUniforms: {\n uniformTypes: {\n pointsTextureSize: 'f32',\n clustersTextureSize: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n },\n },\n })\n\n this.calculateCentermassCommand ||= new Model(device, {\n fs: calculateCentermassFrag,\n vs: calculateCentermassVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...this.pointIndices && { pointIndices: this.pointIndices },\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' }, // 2 floats per vertex\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true, // Enable uniform buffers\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n calculateCentermassUniforms: this.calculateCentermassUniformStore.getManagedUniformBuffer(device, 'calculateCentermassUniforms'),\n // All texture bindings will be set dynamically in calculateCentermass() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Create UniformStore for applyForces uniforms\n this.applyForcesUniformStore ||= new UniformStore({\n applyForcesUniforms: {\n uniformTypes: {\n alpha: 'f32',\n clustersTextureSize: 'f32',\n clusterCoefficient: 'f32',\n },\n defaultUniforms: {\n alpha: store.alpha,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n clusterCoefficient: (this.config.simulationCluster ?? 0),\n },\n },\n })\n\n // Create and track vertexCoord buffer\n this.applyForcesVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.applyForcesCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.applyForcesVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' }, // 2 floats per vertex\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true, // Enable uniform buffers\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n applyForcesUniforms: this.applyForcesUniformStore.getManagedUniformBuffer(device, 'applyForcesUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n })\n }\n\n public calculateCentermass (): void {\n const { device, points } = this\n if (!points) return\n\n if (!this.calculateCentermassCommand || !this.calculateCentermassUniformStore) return\n // Ensure pointIndices is set (Model might exist but attributes not set yet)\n if (!this.pointIndices) return\n\n if (!this.centermassFbo || this.centermassFbo.destroyed) return\n if (!this.clusterTexture || this.clusterTexture.destroyed) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n\n // Update vertex count dynamically (using same fallback logic as initialization)\n this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n // Update UniformStore with current values\n this.calculateCentermassUniformStore.setUniforms({\n calculateCentermassUniforms: {\n pointsTextureSize: this.store.pointsTextureSize,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n },\n })\n\n // Update texture bindings dynamically\n this.calculateCentermassCommand.setBindings({\n clusterTexture: this.clusterTexture,\n positionsTexture: points.previousPositionTexture,\n })\n\n // Create a RenderPass for the centermass framebuffer\n const centermassPass = device.beginRenderPass({\n framebuffer: this.centermassFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.calculateCentermassCommand.draw(centermassPass)\n\n centermassPass.end()\n }\n\n public run (): void {\n if (!this.data.pointClusters && !this.data.clusterPositions) return\n\n // Calculate centermass (creates its own RenderPass - different framebuffer)\n this.calculateCentermass()\n\n // Add safety check\n if (!this.applyForcesCommand || !this.applyForcesUniformStore) {\n return\n }\n\n // Add destroyed checks for resources before use\n if (!this.clusterTexture || this.clusterTexture.destroyed) return\n if (!this.centermassTexture || this.centermassTexture.destroyed) return\n if (!this.clusterPositionsTexture || this.clusterPositionsTexture.destroyed) return\n if (!this.clusterForceCoefficientTexture || this.clusterForceCoefficientTexture.destroyed) return\n if (!this.points?.previousPositionTexture || this.points.previousPositionTexture.destroyed) return\n if (!this.points.velocityFbo || this.points.velocityFbo.destroyed) return\n\n // Update UniformStore with current values\n this.applyForcesUniformStore.setUniforms({\n applyForcesUniforms: {\n alpha: this.store.alpha,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n clusterCoefficient: this.config.simulationCluster ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.applyForcesCommand.setBindings({\n clusterTexture: this.clusterTexture,\n centermassTexture: this.centermassTexture,\n clusterPositionsTexture: this.clusterPositionsTexture,\n clusterForceCoefficient: this.clusterForceCoefficientTexture,\n positionsTexture: this.points.previousPositionTexture,\n })\n\n const pass = this.device.beginRenderPass({\n framebuffer: this.points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.applyForcesCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.calculateCentermassCommand?.destroy()\n this.calculateCentermassCommand = undefined\n this.applyForcesCommand?.destroy()\n this.applyForcesCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.centermassFbo && !this.centermassFbo.destroyed) {\n this.centermassFbo.destroy()\n }\n this.centermassFbo = undefined\n\n // 3. Destroy Textures\n if (this.clusterTexture && !this.clusterTexture.destroyed) {\n this.clusterTexture.destroy()\n }\n this.clusterTexture = undefined\n if (this.clusterPositionsTexture && !this.clusterPositionsTexture.destroyed) {\n this.clusterPositionsTexture.destroy()\n }\n this.clusterPositionsTexture = undefined\n if (this.clusterForceCoefficientTexture && !this.clusterForceCoefficientTexture.destroyed) {\n this.clusterForceCoefficientTexture.destroy()\n }\n this.clusterForceCoefficientTexture = undefined\n if (this.centermassTexture && !this.centermassTexture.destroyed) {\n this.centermassTexture.destroy()\n }\n this.centermassTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.calculateCentermassUniformStore?.destroy()\n this.calculateCentermassUniformStore = undefined\n this.applyForcesUniformStore?.destroy()\n this.applyForcesUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n this.pointIndices = undefined\n if (this.applyForcesVertexCoordBuffer && !this.applyForcesVertexCoordBuffer.destroyed) {\n this.applyForcesVertexCoordBuffer.destroy()\n }\n this.applyForcesVertexCoordBuffer = undefined\n }\n}\n","export const benchCSS = `\n #gl-bench {\n position:absolute;\n right:0;\n top:0;\n z-index:1000;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n }\n #gl-bench div {\n position: relative;\n display: block;\n margin: 4px;\n padding: 0 7px 0 10px;\n background: #5f69de;\n border-radius: 15px;\n cursor: pointer;\n opacity: 0.9;\n }\n #gl-bench svg {\n height: 60px;\n margin: 0 -1px;\n }\n #gl-bench text {\n font-size: 12px;\n font-family: Helvetica,Arial,sans-serif;\n font-weight: 700;\n dominant-baseline: middle;\n text-anchor: middle;\n }\n #gl-bench .gl-mem {\n font-size: 9px;\n }\n #gl-bench line {\n stroke-width: 5;\n stroke: #112211;\n stroke-linecap: round;\n }\n #gl-bench polyline {\n fill: none;\n stroke: #112211;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-width: 3.5;\n }\n #gl-bench rect {\n fill: #8288e4;\n }\n #gl-bench .opacity {\n stroke: #8288e4;\n }\n`\n","\nimport { select } from 'd3-selection'\nimport GLBench from 'gl-bench/dist/gl-bench'\nimport { benchCSS } from './css'\n\nexport class FPSMonitor {\n private bench: GLBench | undefined\n\n public constructor (canvas: HTMLCanvasElement) {\n this.destroy()\n const gl = (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) as WebGL2RenderingContext\n this.bench = new GLBench(gl, { css: benchCSS })\n }\n\n public begin (): void {\n this.bench?.begin('frame')\n }\n\n public end (now: number): void {\n this.bench?.end('frame')\n this.bench?.nextFrame(now)\n }\n\n public destroy (): void {\n this.bench = undefined\n select('#gl-bench').remove()\n }\n}\n","import { getRgbaColor, isNumber } from '@/graph/helper'\nimport { GraphConfig } from '@/graph/config'\n\nexport enum PointShape {\n Circle = 0,\n Square = 1,\n Triangle = 2,\n Diamond = 3,\n Pentagon = 4,\n Hexagon = 5,\n Star = 6,\n Cross = 7,\n None = 8\n}\n\nexport class GraphData {\n public inputPointPositions: Float32Array | undefined\n public inputPointColors: Float32Array | undefined\n public inputPointSizes: Float32Array | undefined\n public inputPointShapes: Float32Array | undefined\n public inputImageData: ImageData[] | undefined\n public inputPointImageIndices: Float32Array | undefined\n public inputPointImageSizes: Float32Array | undefined\n public inputLinkColors: Float32Array | undefined\n public inputLinkWidths: Float32Array | undefined\n public inputLinkStrength: Float32Array | undefined\n public inputPointClusters: (number | undefined)[] | undefined\n public inputClusterPositions: (number | undefined)[] | undefined\n public inputClusterStrength: Float32Array | undefined\n public inputPinnedPoints: number[] | undefined\n\n public pointPositions: Float32Array | undefined\n public pointColors: Float32Array | undefined\n public pointSizes: Float32Array | undefined\n public pointShapes: Float32Array | undefined\n public pointImageIndices: Float32Array | undefined\n public pointImageSizes: Float32Array | undefined\n\n public inputLinks: Float32Array | undefined\n public links: Float32Array | undefined\n public linkColors: Float32Array | undefined\n public linkWidths: Float32Array | undefined\n public linkArrowsBoolean: boolean[] | undefined\n public linkArrows: number[] | undefined\n public linkStrength: Float32Array | undefined\n\n public pointClusters: (number | undefined)[] | undefined\n public clusterPositions: (number | undefined)[] | undefined\n public clusterStrength: Float32Array | undefined\n\n /**\n * Each inner array of `sourceIndexToTargetIndices` and `targetIndexToSourceIndices` contains pairs where:\n * - The first value is the target/source index in the point array.\n * - The second value is the link index in the array of links.\n */\n public sourceIndexToTargetIndices: ([number, number][] | undefined)[] | undefined\n public targetIndexToSourceIndices: ([number, number][] | undefined)[] | undefined\n\n public degree: number[] | undefined\n public inDegree: number[] | undefined\n public outDegree: number[] | undefined\n\n private _config: GraphConfig\n\n public constructor (config: GraphConfig) {\n this._config = config\n }\n\n public get pointsNumber (): number | undefined {\n return this.pointPositions && this.pointPositions.length / 2\n }\n\n public get linksNumber (): number | undefined {\n return this.links && this.links.length / 2\n }\n\n public updatePoints (): void {\n this.pointPositions = this.inputPointPositions\n }\n\n /**\n * Updates the point colors based on the input data or default config value.\n */\n public updatePointColor (): void {\n if (this.pointsNumber === undefined) {\n this.pointColors = undefined\n return\n }\n\n // Sets point colors to default values from config if the input is missing or does not match input points number.\n const defaultRgba = getRgbaColor(this._config.pointDefaultColor ?? this._config.pointColor)\n if (this.inputPointColors === undefined || this.inputPointColors.length / 4 !== this.pointsNumber) {\n this.pointColors = new Float32Array(this.pointsNumber * 4)\n for (let i = 0; i < this.pointColors.length / 4; i++) {\n this.pointColors[i * 4] = defaultRgba[0]\n this.pointColors[i * 4 + 1] = defaultRgba[1]\n this.pointColors[i * 4 + 2] = defaultRgba[2]\n this.pointColors[i * 4 + 3] = defaultRgba[3]\n }\n } else {\n this.pointColors = this.inputPointColors\n for (let i = 0; i < this.pointColors.length / 4; i++) {\n if (!isNumber(this.pointColors[i * 4])) this.pointColors[i * 4] = defaultRgba[0]\n if (!isNumber(this.pointColors[i * 4 + 1])) this.pointColors[i * 4 + 1] = defaultRgba[1]\n if (!isNumber(this.pointColors[i * 4 + 2])) this.pointColors[i * 4 + 2] = defaultRgba[2]\n if (!isNumber(this.pointColors[i * 4 + 3])) this.pointColors[i * 4 + 3] = defaultRgba[3]\n }\n }\n }\n\n /**\n * Updates the point sizes based on the input data or default config value.\n */\n public updatePointSize (): void {\n if (this.pointsNumber === undefined) {\n this.pointSizes = undefined\n return\n }\n\n // Sets point sizes to default values from config if the input is missing or does not match input points number.\n const defaultSize = this._config.pointDefaultSize ?? this._config.pointSize\n if (this.inputPointSizes === undefined || this.inputPointSizes.length !== this.pointsNumber) {\n this.pointSizes = new Float32Array(this.pointsNumber).fill(defaultSize)\n } else {\n this.pointSizes = this.inputPointSizes\n for (let i = 0; i < this.pointSizes.length; i++) {\n if (!isNumber(this.pointSizes[i])) {\n this.pointSizes[i] = defaultSize\n }\n }\n }\n }\n\n /**\n * Updates the point shapes based on the input data or default shape.\n * Default behavior: Circle (0).\n * Images are rendered above shapes.\n */\n public updatePointShape (): void {\n if (this.pointsNumber === undefined) {\n this.pointShapes = undefined\n return\n }\n\n // Determine default shape: Circle\n const defaultShape = PointShape.Circle\n\n // Sets point shapes to default values if the input is missing or does not match input points number.\n if (this.inputPointShapes === undefined || this.inputPointShapes.length !== this.pointsNumber) {\n this.pointShapes = new Float32Array(this.pointsNumber).fill(defaultShape)\n } else {\n this.pointShapes = new Float32Array(this.inputPointShapes)\n const pointShapes = this.pointShapes\n for (let i = 0; i < pointShapes.length; i++) {\n const shape = pointShapes[i]\n if (shape == null || !isNumber(shape) || shape < 0 || shape > 8) {\n pointShapes[i] = defaultShape\n }\n }\n }\n }\n\n /**\n * Updates the point image indices based on the input data or default value (-1 for no image).\n */\n public updatePointImageIndices (): void {\n if (this.pointsNumber === undefined) {\n this.pointImageIndices = undefined\n return\n }\n\n // Sets point image indices to -1 if input is missing or doesn't match points count\n if (this.inputPointImageIndices === undefined || this.inputPointImageIndices.length !== this.pointsNumber) {\n this.pointImageIndices = new Float32Array(this.pointsNumber).fill(-1)\n } else {\n const pointImageIndices = new Float32Array(this.inputPointImageIndices)\n for (let i = 0; i < pointImageIndices.length; i++) {\n const rawIndex = pointImageIndices[i]\n const imageIndex = (rawIndex === undefined) ? NaN : rawIndex\n if (!Number.isFinite(imageIndex) || imageIndex < 0) {\n pointImageIndices[i] = -1\n } else {\n pointImageIndices[i] = Math.trunc(imageIndex)\n }\n }\n this.pointImageIndices = pointImageIndices\n }\n }\n\n /**\n * Updates the point image sizes based on the input data or default to point sizes.\n */\n public updatePointImageSizes (): void {\n if (this.pointsNumber === undefined) {\n this.pointImageSizes = undefined\n return\n }\n\n // Sets point image sizes to point sizes if the input is missing or does not match input points number.\n const defaultSize = this._config.pointDefaultSize ?? this._config.pointSize\n if (this.inputPointImageSizes === undefined || this.inputPointImageSizes.length !== this.pointsNumber) {\n this.pointImageSizes = this.pointSizes ? new Float32Array(this.pointSizes) : new Float32Array(this.pointsNumber).fill(defaultSize)\n } else {\n this.pointImageSizes = new Float32Array(this.inputPointImageSizes)\n for (let i = 0; i < this.pointImageSizes.length; i++) {\n if (!isNumber(this.pointImageSizes[i])) {\n this.pointImageSizes[i] = this.pointSizes?.[i] ?? defaultSize\n }\n }\n }\n }\n\n public updateLinks (): void {\n this.links = this.inputLinks\n }\n\n /**\n * Updates the link colors based on the input data or default config value.\n */\n public updateLinkColor (): void {\n if (this.linksNumber === undefined) {\n this.linkColors = undefined\n return\n }\n\n // Sets link colors to default values from config if the input is missing or does not match input links number.\n const defaultRgba = getRgbaColor(this._config.linkDefaultColor ?? this._config.linkColor)\n if (this.inputLinkColors === undefined || this.inputLinkColors.length / 4 !== this.linksNumber) {\n this.linkColors = new Float32Array(this.linksNumber * 4)\n\n for (let i = 0; i < this.linkColors.length / 4; i++) {\n this.linkColors[i * 4] = defaultRgba[0]\n this.linkColors[i * 4 + 1] = defaultRgba[1]\n this.linkColors[i * 4 + 2] = defaultRgba[2]\n this.linkColors[i * 4 + 3] = defaultRgba[3]\n }\n } else {\n this.linkColors = this.inputLinkColors\n for (let i = 0; i < this.linkColors.length / 4; i++) {\n if (!isNumber(this.linkColors[i * 4])) this.linkColors[i * 4] = defaultRgba[0]\n if (!isNumber(this.linkColors[i * 4 + 1])) this.linkColors[i * 4 + 1] = defaultRgba[1]\n if (!isNumber(this.linkColors[i * 4 + 2])) this.linkColors[i * 4 + 2] = defaultRgba[2]\n if (!isNumber(this.linkColors[i * 4 + 3])) this.linkColors[i * 4 + 3] = defaultRgba[3]\n }\n }\n }\n\n /**\n * Updates the link width based on the input data or default config value.\n */\n public updateLinkWidth (): void {\n if (this.linksNumber === undefined) {\n this.linkWidths = undefined\n return\n }\n\n // Sets link widths to default values from config if the input is missing or does not match input links number.\n const defaultWidth = this._config.linkDefaultWidth ?? this._config.linkWidth\n if (this.inputLinkWidths === undefined || this.inputLinkWidths.length !== this.linksNumber) {\n this.linkWidths = new Float32Array(this.linksNumber).fill(defaultWidth)\n } else {\n this.linkWidths = this.inputLinkWidths\n for (let i = 0; i < this.linkWidths.length; i++) {\n if (!isNumber(this.linkWidths[i])) {\n this.linkWidths[i] = defaultWidth\n }\n }\n }\n }\n\n /**\n * Updates the link arrows based on the input data or default config value.\n */\n public updateArrows (): void {\n if (this.linksNumber === undefined) {\n this.linkArrows = undefined\n return\n }\n\n // Sets link arrows to default values from config if the input is missing or does not match input links number.\n const defaultArrows = this._config.linkDefaultArrows ?? this._config.linkArrows\n if (this.linkArrowsBoolean === undefined || this.linkArrowsBoolean.length !== this.linksNumber) {\n this.linkArrows = new Array(this.linksNumber).fill(+defaultArrows)\n } else {\n this.linkArrows = this.linkArrowsBoolean.map(d => +d)\n }\n }\n\n public updateLinkStrength (): void {\n if (this.linksNumber === undefined) {\n this.linkStrength = undefined\n }\n\n if (this.inputLinkStrength === undefined || this.inputLinkStrength.length !== this.linksNumber) {\n this.linkStrength = undefined\n } else {\n this.linkStrength = this.inputLinkStrength\n }\n }\n\n public updateClusters (): void {\n if (this.pointsNumber === undefined) {\n this.pointClusters = undefined\n this.clusterPositions = undefined\n return\n }\n if (this.inputPointClusters === undefined || this.inputPointClusters.length !== this.pointsNumber) {\n this.pointClusters = undefined\n } else {\n this.pointClusters = this.inputPointClusters\n }\n if (this.inputClusterPositions === undefined) {\n this.clusterPositions = undefined\n } else {\n this.clusterPositions = this.inputClusterPositions\n }\n if (this.inputClusterStrength === undefined || this.inputClusterStrength.length !== this.pointsNumber) {\n this.clusterStrength = undefined\n } else {\n this.clusterStrength = this.inputClusterStrength\n }\n }\n\n public update (): void {\n this.updatePoints()\n this.updatePointColor()\n this.updatePointSize()\n this.updatePointShape()\n this.updatePointImageIndices()\n this.updatePointImageSizes()\n\n this.updateLinks()\n this.updateLinkColor()\n this.updateLinkWidth()\n this.updateArrows()\n this.updateLinkStrength()\n\n this.updateClusters()\n\n this._createAdjacencyLists()\n this._calculateDegrees()\n }\n\n public getAdjacentIndices (index: number): number[] | undefined {\n return [...(this.sourceIndexToTargetIndices?.[index]?.map(d => d[0]) || []), ...(this.targetIndexToSourceIndices?.[index]?.map(d => d[0]) || [])]\n }\n\n private _createAdjacencyLists (): void {\n if (this.linksNumber === undefined || this.links === undefined) {\n this.sourceIndexToTargetIndices = undefined\n this.targetIndexToSourceIndices = undefined\n return\n }\n\n this.sourceIndexToTargetIndices = new Array(this.pointsNumber).fill(undefined)\n this.targetIndexToSourceIndices = new Array(this.pointsNumber).fill(undefined)\n for (let i = 0; i < this.linksNumber; i++) {\n const sourceIndex = this.links[i * 2]\n const targetIndex = this.links[i * 2 + 1]\n if (sourceIndex !== undefined && targetIndex !== undefined) {\n if (this.sourceIndexToTargetIndices[sourceIndex] === undefined) this.sourceIndexToTargetIndices[sourceIndex] = []\n this.sourceIndexToTargetIndices[sourceIndex]?.push([targetIndex, i])\n\n if (this.targetIndexToSourceIndices[targetIndex] === undefined) this.targetIndexToSourceIndices[targetIndex] = []\n this.targetIndexToSourceIndices[targetIndex]?.push([sourceIndex, i])\n }\n }\n }\n\n private _calculateDegrees (): void {\n if (this.pointsNumber === undefined) {\n this.degree = undefined\n this.inDegree = undefined\n this.outDegree = undefined\n return\n }\n\n this.degree = new Array(this.pointsNumber).fill(0)\n this.inDegree = new Array(this.pointsNumber).fill(0)\n this.outDegree = new Array(this.pointsNumber).fill(0)\n\n for (let i = 0; i < this.pointsNumber; i++) {\n this.inDegree[i] = this.targetIndexToSourceIndices?.[i]?.length ?? 0\n this.outDegree[i] = this.sourceIndexToTargetIndices?.[i]?.length ?? 0\n this.degree[i] = (this.inDegree[i] ?? 0) + (this.outDegree[i] ?? 0)\n }\n }\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgbaColor;\\nin vec2 pos;\\nin float arrowLength;\\nin float useArrow;\\nin float smoothing;\\nin float arrowWidthFactor;\\nin float linkIndex;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawLineFragmentUniforms {\\n float renderMode;\\n} drawLineFrag;\\n\\n#define renderMode drawLineFrag.renderMode\\n#else\\n// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking\\nuniform float renderMode;\\n#endif\\n\\nout vec4 fragColor;\\n\\nfloat map(float value, float min1, float max1, float min2, float max2) {\\n return min2 + (value - min1) * (max2 - min2) / (max1 - min1);\\n}\\n\\nvoid main() {\\n float opacity = 1.0;\\n vec3 color = rgbaColor.rgb;\\n\\n if (useArrow > 0.5) {\\n float end_arrow = 0.5 + arrowLength / 2.0;\\n float start_arrow = end_arrow - arrowLength;\\n float arrowWidthDelta = arrowWidthFactor / 2.0;\\n float linkOpacity = rgbaColor.a * smoothstep(0.5 - arrowWidthDelta, 0.5 - arrowWidthDelta - smoothing / 2.0, abs(pos.y));\\n float arrowOpacity = 1.0;\\n if (pos.x > start_arrow && pos.x < start_arrow + arrowLength) {\\n float xmapped = map(pos.x, start_arrow, end_arrow, 0.0, 1.0);\\n arrowOpacity = rgbaColor.a * smoothstep(xmapped - smoothing, xmapped, map(abs(pos.y), 0.5, 0.0, 0.0, 1.0));\\n if (linkOpacity != arrowOpacity) {\\n linkOpacity = max(linkOpacity, arrowOpacity);\\n }\\n }\\n opacity = linkOpacity;\\n } else opacity = rgbaColor.a * smoothstep(0.5, 0.5 - smoothing, abs(pos.y));\\n \\n if (renderMode > 0.0) {\\n if (opacity > 0.0) {\\n fragColor = vec4(linkIndex, 0.0, 0.0, 1.0);\\n } else {\\n fragColor = vec4(-1.0, 0.0, 0.0, 0.0);\\n }\\n } else fragColor = vec4(color, opacity);\\n\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 position, pointA, pointB;\\nin vec4 color;\\nin float width;\\nin float arrow;\\nin float linkIndices;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatus;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawLineUniforms {\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float widthScale;\\n float linkArrowsSizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n vec2 linkVisibilityDistanceRange;\\n float linkVisibilityMinTransparency;\\n float linkOpacity;\\n float greyoutOpacity;\\n float curvedWeight;\\n float curvedLinkControlPointDistance;\\n float curvedLinkSegments;\\n float scaleLinksOnZoom;\\n float maxPointSize;\\n float renderMode;\\n float hoveredLinkIndex;\\n vec4 hoveredLinkColor;\\n float hoveredLinkWidthIncrease;\\n} drawLine;\\n\\n#define transformationMatrix drawLine.transformationMatrix\\n#define pointsTextureSize drawLine.pointsTextureSize\\n#define widthScale drawLine.widthScale\\n#define linkArrowsSizeScale drawLine.linkArrowsSizeScale\\n#define spaceSize drawLine.spaceSize\\n#define screenSize drawLine.screenSize\\n#define linkVisibilityDistanceRange drawLine.linkVisibilityDistanceRange\\n#define linkVisibilityMinTransparency drawLine.linkVisibilityMinTransparency\\n#define linkOpacity drawLine.linkOpacity\\n#define greyoutOpacity drawLine.greyoutOpacity\\n#define curvedWeight drawLine.curvedWeight\\n#define curvedLinkControlPointDistance drawLine.curvedLinkControlPointDistance\\n#define curvedLinkSegments drawLine.curvedLinkSegments\\n#define scaleLinksOnZoom drawLine.scaleLinksOnZoom\\n#define maxPointSize drawLine.maxPointSize\\n#define renderMode drawLine.renderMode\\n#define hoveredLinkIndex drawLine.hoveredLinkIndex\\n#define hoveredLinkColor drawLine.hoveredLinkColor\\n#define hoveredLinkWidthIncrease drawLine.hoveredLinkWidthIncrease\\n#else\\nuniform mat3 transformationMatrix;\\nuniform float pointsTextureSize;\\nuniform float widthScale;\\nuniform float linkArrowsSizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform vec2 linkVisibilityDistanceRange;\\nuniform float linkVisibilityMinTransparency;\\nuniform float linkOpacity;\\nuniform float greyoutOpacity;\\nuniform float curvedWeight;\\nuniform float curvedLinkControlPointDistance;\\nuniform float curvedLinkSegments;\\nuniform bool scaleLinksOnZoom;\\nuniform float maxPointSize;\\n// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking\\nuniform float renderMode;\\nuniform float hoveredLinkIndex;\\nuniform vec4 hoveredLinkColor;\\nuniform float hoveredLinkWidthIncrease;\\n#endif\\n\\nout vec4 rgbaColor;\\nout vec2 pos;\\nout float arrowLength;\\nout float useArrow;\\nout float smoothing;\\nout float arrowWidthFactor;\\nout float linkIndex;\\n\\nfloat map(float value, float min1, float max1, float min2, float max2) {\\n return min2 + (value - min1) * (max2 - min2) / (max1 - min1);\\n}\\n\\nvec2 conicParametricCurve(vec2 A, vec2 B, vec2 ControlPoint, float t, float w) {\\n vec2 divident = (1.0 - t) * (1.0 - t) * A + 2.0 * (1.0 - t) * t * w * ControlPoint + t * t * B;\\n float divisor = (1.0 - t) * (1.0 - t) + 2.0 * (1.0 - t) * t * w + t * t;\\n return divident / divisor;\\n}\\n\\nfloat calculateLinkWidth(float width) {\\n float linkWidth;\\n if (scaleLinksOnZoom > 0.0) {\\n // Use original width if links should scale with zoom\\n linkWidth = width;\\n } else {\\n // Adjust width based on zoom level to maintain visual size\\n linkWidth = width / transformationMatrix[0][0];\\n // Apply a non-linear scaling to avoid extreme widths\\n linkWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n // Limit link width based on whether it has an arrow\\n if (useArrow > 0.5) {\\n return min(linkWidth, (maxPointSize * 2.0) / transformationMatrix[0][0]);\\n } else {\\n return min(linkWidth, maxPointSize / transformationMatrix[0][0]);\\n }\\n}\\n\\nfloat calculateArrowWidth(float arrowWidth) {\\n if (scaleLinksOnZoom > 0.0) {\\n return arrowWidth;\\n } else {\\n // Apply the same scaling logic as calculateLinkWidth to maintain proportionality\\n arrowWidth = arrowWidth / transformationMatrix[0][0];\\n // Apply the same non-linear scaling to avoid extreme widths\\n arrowWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n return arrowWidth;\\n }\\n}\\n\\nvoid main() {\\n pos = position;\\n linkIndex = linkIndices;\\n\\n vec2 pointTexturePosA = (pointA + 0.5) / pointsTextureSize;\\n vec2 pointTexturePosB = (pointB + 0.5) / pointsTextureSize;\\n \\n vec4 greyoutStatusA = texture(pointGreyoutStatus, pointTexturePosA);\\n vec4 greyoutStatusB = texture(pointGreyoutStatus, pointTexturePosB);\\n \\n vec4 pointPositionA = texture(positionsTexture, pointTexturePosA);\\n vec4 pointPositionB = texture(positionsTexture, pointTexturePosB);\\n vec2 a = pointPositionA.xy;\\n vec2 b = pointPositionB.xy;\\n \\n // Calculate direction vector and its perpendicular\\n vec2 xBasis = b - a;\\n vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));\\n\\n // Calculate link distance and control point for curved link\\n float linkDist = length(xBasis);\\n float h = curvedLinkControlPointDistance;\\n vec2 controlPoint = (a + b) / 2.0 + yBasis * linkDist * h;\\n\\n // Convert link distance to screen pixels\\n float linkDistPx = linkDist * transformationMatrix[0][0];\\n \\n // Calculate line width using the width scale\\n float linkWidth = width * widthScale;\\n float k = 2.0;\\n // Arrow width is proportionally larger than the line width\\n float arrowWidth = linkWidth * k;\\n arrowWidth *= linkArrowsSizeScale;\\n\\n // Ensure arrow width difference is non-negative to prevent unwanted changes to link width\\n float arrowWidthDifference = max(0.0, arrowWidth - linkWidth);\\n\\n // Calculate arrow width in pixels\\n float arrowWidthPx = calculateArrowWidth(arrowWidth);\\n\\n // Calculate arrow length proportional to its width\\n // 0.866 is approximately sqrt(3)/2 - related to equilateral triangle geometry\\n // Cap the length to avoid overly long arrows on short links\\n arrowLength = min(0.3, (0.866 * arrowWidthPx * 2.0) / linkDist);\\n\\n useArrow = arrow;\\n if (useArrow > 0.5) {\\n linkWidth += arrowWidthDifference;\\n }\\n\\n arrowWidthFactor = arrowWidthDifference / linkWidth;\\n\\n // Calculate final link width in pixels with smoothing\\n float linkWidthPx = calculateLinkWidth(linkWidth);\\n \\n if (renderMode > 0.0) {\\n // Add 5 pixels padding for better hover detection\\n linkWidthPx += 5.0 / transformationMatrix[0][0];\\n } else {\\n // Add pixel increase if this is the hovered link\\n if (hoveredLinkIndex == linkIndex) {\\n linkWidthPx += hoveredLinkWidthIncrease / transformationMatrix[0][0];\\n }\\n }\\n float smoothingPx = 0.5 / transformationMatrix[0][0];\\n smoothing = smoothingPx / linkWidthPx;\\n linkWidthPx += smoothingPx;\\n\\n\\n\\n // Calculate final color with opacity based on link distance\\n vec3 rgbColor = color.rgb;\\n // Adjust opacity based on link distance\\n float opacity = color.a * linkOpacity * max(linkVisibilityMinTransparency, map(linkDistPx, linkVisibilityDistanceRange.g, linkVisibilityDistanceRange.r, 0.0, 1.0));\\n\\n // Apply greyed out opacity if either endpoint is greyed out\\n if (greyoutStatusA.r > 0.0 || greyoutStatusB.r > 0.0) {\\n opacity *= greyoutOpacity;\\n }\\n\\n // Pass final color to fragment shader\\n rgbaColor = vec4(rgbColor, opacity);\\n\\n // Apply hover color if this is the hovered link and hover color is defined\\n if (hoveredLinkIndex == linkIndex && hoveredLinkColor.a > -0.5) {\\n // Keep existing RGB values but multiply opacity with hover color opacity\\n rgbaColor.rgb = hoveredLinkColor.rgb;\\n rgbaColor.a *= hoveredLinkColor.a;\\n }\\n\\n // Calculate position on the curved path\\n float t = position.x;\\n float w = curvedWeight;\\n \\n float tPrev = t - 1.0 / curvedLinkSegments;\\n float tNext = t + 1.0 / curvedLinkSegments;\\n \\n vec2 pointCurr = conicParametricCurve(a, b, controlPoint, t, w);\\n \\n vec2 pointPrev = conicParametricCurve(a, b, controlPoint, max(0.0, tPrev), w);\\n vec2 pointNext = conicParametricCurve(a, b, controlPoint, min(tNext, 1.0), w);\\n \\n vec2 xBasisCurved = pointNext - pointPrev;\\n vec2 yBasisCurved = normalize(vec2(-xBasisCurved.y, xBasisCurved.x));\\n \\n pointCurr += yBasisCurved * linkWidthPx * position.y;\\n \\n // Transform to clip space coordinates\\n vec2 p = 2.0 * pointCurr / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n \\n gl_Position = vec4(final.rg, 0, 1);\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D linkIndexTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform hoveredLineIndexUniforms {\\n vec2 mousePosition;\\n vec2 screenSize;\\n} hoveredLine;\\n\\n#define mousePosition hoveredLine.mousePosition\\n#define screenSize hoveredLine.screenSize\\n#else\\nuniform vec2 mousePosition;\\nuniform vec2 screenSize;\\n#endif\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n // Convert mouse position to texture coordinates\\n vec2 texCoord = mousePosition / screenSize;\\n \\n // Read the link index from the linkIndexFbo texture at mouse position\\n vec4 linkIndexData = texture(linkIndexTexture, texCoord);\\n \\n // Extract the link index (stored in the red channel)\\n float linkIndex = linkIndexData.r;\\n \\n // Check if there's a valid link at this position (alpha > 0)\\n if (linkIndexData.a > 0.0 && linkIndex >= 0.0) {\\n // Output the link index\\n fragColor = vec4(linkIndex, 0.0, 0.0, 1.0);\\n } else {\\n // No link at this position, output -1 to indicate no hover\\n fragColor = vec4(-1.0, 0.0, 0.0, 0.0);\\n }\\n} \"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 vertexCoord;\\n\\nvoid main() {\\n gl_Position = vec4(vertexCoord, 0.0, 1.0);\\n} \"","import { scalePow } from 'd3-scale'\nimport { range } from 'd3-array'\n\nexport const getCurveLineGeometry = (segments: number): number[][] => {\n const scale = scalePow()\n .exponent(2)\n .range([0, 1])\n .domain([-1, 1])\n\n const hodographValues = range(0, segments).map(d => -0.5 + d / segments)\n hodographValues.push(0.5)\n const result = new Array(hodographValues.length * 2)\n hodographValues.forEach((d, i) => {\n result[i * 2] = [scale(d * 2), 0.5]\n result[i * 2 + 1] = [scale(d * 2), -0.5]\n })\n return result\n}\n","import { Framebuffer, Buffer, Texture, UniformStore, RenderPass } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport type { Mat4Array } from '@/graph/modules/Store'\nimport drawLineFrag from '@/graph/modules/Lines/draw-curve-line.frag?raw'\nimport drawLineVert from '@/graph/modules/Lines/draw-curve-line.vert?raw'\nimport hoveredLineIndexFrag from '@/graph/modules/Lines/hovered-line-index.frag?raw'\nimport hoveredLineIndexVert from '@/graph/modules/Lines/hovered-line-index.vert?raw'\nimport { defaultConfigValues } from '@/graph/variables'\nimport { getCurveLineGeometry } from '@/graph/modules/Lines/geometry'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport { ensureVec2, ensureVec4 } from '@/graph/modules/Shared/uniform-utils'\n\nexport class Lines extends CoreModule {\n public linkIndexFbo: Framebuffer | undefined\n public hoveredLineIndexFbo: Framebuffer | undefined\n private drawCurveCommand: Model | undefined\n private hoveredLineIndexCommand: Model | undefined\n private pointABuffer: Buffer | undefined\n private pointBBuffer: Buffer | undefined\n private colorBuffer: Buffer | undefined\n private widthBuffer: Buffer | undefined\n private arrowBuffer: Buffer | undefined\n private curveLineGeometry: number[][] | undefined\n private curveLineBuffer: Buffer | undefined\n private linkIndexBuffer: Buffer | undefined\n private quadBuffer: Buffer | undefined\n private linkIndexTexture: Texture | undefined\n private hoveredLineIndexTexture: Texture | undefined\n\n // Uniform stores for scalar uniforms\n private drawLineUniformStore: UniformStore<{\n drawLineUniforms: {\n transformationMatrix: Mat4Array;\n pointsTextureSize: number;\n widthScale: number;\n linkArrowsSizeScale: number;\n spaceSize: number;\n screenSize: [number, number];\n linkVisibilityDistanceRange: [number, number];\n linkVisibilityMinTransparency: number;\n linkOpacity: number;\n greyoutOpacity: number;\n curvedWeight: number;\n curvedLinkControlPointDistance: number;\n curvedLinkSegments: number;\n scaleLinksOnZoom: number;\n maxPointSize: number;\n renderMode: number;\n hoveredLinkIndex: number;\n hoveredLinkColor: [number, number, number, number];\n hoveredLinkWidthIncrease: number;\n };\n drawLineFragmentUniforms: {\n renderMode: number;\n };\n }> | undefined\n\n private hoveredLineIndexUniformStore: UniformStore<{\n hoveredLineIndexUniforms: {\n mousePosition: [number, number];\n screenSize: [number, number];\n };\n }> | undefined\n\n // Track previous screen size to detect changes\n private previousScreenSize: [number, number] | undefined\n\n public initPrograms (): void {\n const { device, config, store } = this\n\n this.updateLinkIndexFbo()\n\n // Initialize the hovered line index FBO\n this.hoveredLineIndexTexture ||= device.createTexture({\n width: 1,\n height: 1,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n data: new Float32Array(4).fill(0),\n })\n this.hoveredLineIndexFbo ||= device.createFramebuffer({\n width: 1,\n height: 1,\n colorAttachments: [this.hoveredLineIndexTexture],\n })\n\n // Ensure geometry buffer exists (create empty if needed)\n if (!this.curveLineGeometry) {\n this.updateCurveLineGeometry()\n }\n\n // Ensure all attribute buffers exist (create empty if needed) so Model has all attributes\n const linksNumber = this.data.linksNumber ?? 0\n this.pointABuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber * 2),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.pointBBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber * 2),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.colorBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber * 4),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.widthBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.arrowBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.linkIndexBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n\n // Create UniformStore for drawLine uniforms\n this.drawLineUniformStore ||= new UniformStore({\n drawLineUniforms: {\n uniformTypes: {\n transformationMatrix: 'mat4x4<f32>',\n pointsTextureSize: 'f32',\n widthScale: 'f32',\n linkArrowsSizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n linkVisibilityDistanceRange: 'vec2<f32>',\n linkVisibilityMinTransparency: 'f32',\n linkOpacity: 'f32',\n greyoutOpacity: 'f32',\n curvedWeight: 'f32',\n curvedLinkControlPointDistance: 'f32',\n curvedLinkSegments: 'f32',\n scaleLinksOnZoom: 'f32',\n maxPointSize: 'f32',\n renderMode: 'f32',\n hoveredLinkIndex: 'f32',\n hoveredLinkColor: 'vec4<f32>',\n hoveredLinkWidthIncrease: 'f32',\n },\n defaultUniforms: {\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize,\n widthScale: config.linkWidthScale ?? 1,\n linkArrowsSizeScale: config.linkArrowsSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n linkVisibilityDistanceRange: ensureVec2(config.linkVisibilityDistanceRange, [0, 0]),\n linkVisibilityMinTransparency: config.linkVisibilityMinTransparency ?? 0,\n linkOpacity: config.linkOpacity ?? 1,\n greyoutOpacity: config.linkGreyoutOpacity ?? 1,\n curvedWeight: config.curvedLinkWeight ?? 0,\n curvedLinkControlPointDistance: config.curvedLinkControlPointDistance ?? 0,\n curvedLinkSegments: config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,\n scaleLinksOnZoom: (config.scaleLinksOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n renderMode: 0.0,\n hoveredLinkIndex: store.hoveredLinkIndex ?? -1,\n hoveredLinkColor: ensureVec4(store.hoveredLinkColor, [-1, -1, -1, -1]),\n hoveredLinkWidthIncrease: config.hoveredLinkWidthIncrease ?? 0,\n },\n },\n drawLineFragmentUniforms: {\n uniformTypes: {\n renderMode: 'f32',\n },\n defaultUniforms: {\n renderMode: 0.0,\n },\n },\n })\n\n this.drawCurveCommand ||= new Model(device, {\n vs: drawLineVert,\n fs: drawLineFrag,\n topology: 'triangle-strip',\n vertexCount: this.curveLineGeometry?.length ?? 0,\n attributes: {\n ...this.curveLineBuffer && { position: this.curveLineBuffer },\n ...this.pointABuffer && { pointA: this.pointABuffer },\n ...this.pointBBuffer && { pointB: this.pointBBuffer },\n ...this.colorBuffer && { color: this.colorBuffer },\n ...this.widthBuffer && { width: this.widthBuffer },\n ...this.arrowBuffer && { arrow: this.arrowBuffer },\n ...this.linkIndexBuffer && { linkIndices: this.linkIndexBuffer },\n },\n bufferLayout: [\n { name: 'position', format: 'float32x2' },\n { name: 'pointA', format: 'float32x2', stepMode: 'instance' },\n { name: 'pointB', format: 'float32x2', stepMode: 'instance' },\n { name: 'color', format: 'float32x4', stepMode: 'instance' },\n { name: 'width', format: 'float32', stepMode: 'instance' },\n { name: 'arrow', format: 'float32', stepMode: 'instance' },\n { name: 'linkIndices', format: 'float32', stepMode: 'instance' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n drawLineUniforms: this.drawLineUniformStore.getManagedUniformBuffer(device, 'drawLineUniforms'),\n drawLineFragmentUniforms: this.drawLineUniformStore.getManagedUniformBuffer(device, 'drawLineFragmentUniforms'),\n // All texture bindings will be set dynamically in draw() method\n },\n /**\n * Blending behavior for link index rendering (renderMode: 1.0 - hover detection):\n *\n * When rendering link indices to the framebuffer, we use full opacity (1.0).\n * This means:\n * - The source color completely overwrites the destination\n * - No blending occurs - it's like drawing with a permanent marker\n * - This preserves the exact index values we need for picking/selection\n */\n parameters: {\n cullMode: 'back',\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Initialize quad buffer for full-screen rendering\n this.quadBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n\n this.hoveredLineIndexUniformStore ||= new UniformStore({\n hoveredLineIndexUniforms: {\n uniformTypes: {\n mousePosition: 'vec2<f32>',\n screenSize: 'vec2<f32>',\n },\n defaultUniforms: {\n mousePosition: ensureVec2(store.screenMousePosition, [0, 0]),\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n },\n },\n })\n\n this.hoveredLineIndexCommand ||= new Model(device, {\n vs: hoveredLineIndexVert,\n fs: hoveredLineIndexFrag,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.quadBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n hoveredLineIndexUniforms: this.hoveredLineIndexUniformStore.getManagedUniformBuffer(device, 'hoveredLineIndexUniforms'),\n // All texture bindings will be set dynamically in findHoveredLine() method\n },\n })\n }\n\n public draw (renderPass: RenderPass): void {\n const { config, points, store } = this\n if (!points) return\n if (!points.currentPositionTexture || points.currentPositionTexture.destroyed) return\n if (!points.greyoutStatusTexture || points.greyoutStatusTexture.destroyed) return\n if (!this.pointABuffer || !this.pointBBuffer) this.updatePointsBuffer()\n if (!this.colorBuffer) this.updateColor()\n if (!this.widthBuffer) this.updateWidth()\n if (!this.arrowBuffer) this.updateArrow()\n if (!this.curveLineGeometry) this.updateCurveLineGeometry()\n if (!this.drawCurveCommand || !this.drawLineUniformStore) return\n\n // Update uniforms\n this.drawLineUniformStore.setUniforms({\n drawLineUniforms: {\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize,\n widthScale: config.linkWidthScale ?? 1,\n linkArrowsSizeScale: config.linkArrowsSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n linkVisibilityDistanceRange: ensureVec2(config.linkVisibilityDistanceRange, [0, 0]),\n linkVisibilityMinTransparency: config.linkVisibilityMinTransparency ?? 0,\n linkOpacity: config.linkOpacity ?? 1,\n greyoutOpacity: config.linkGreyoutOpacity ?? 1,\n curvedWeight: config.curvedLinkWeight ?? 0,\n curvedLinkControlPointDistance: config.curvedLinkControlPointDistance ?? 0,\n curvedLinkSegments: config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,\n scaleLinksOnZoom: (config.scaleLinksOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n renderMode: 0.0, // Normal rendering\n hoveredLinkIndex: store.hoveredLinkIndex ?? -1,\n hoveredLinkColor: ensureVec4(store.hoveredLinkColor, [-1, -1, -1, -1]),\n hoveredLinkWidthIncrease: config.hoveredLinkWidthIncrease ?? 0,\n },\n drawLineFragmentUniforms: {\n renderMode: 0.0, // Normal rendering\n },\n })\n\n // Update texture bindings dynamically\n this.drawCurveCommand.setBindings({\n positionsTexture: points.currentPositionTexture,\n pointGreyoutStatus: points.greyoutStatusTexture,\n })\n\n // Update instance count\n this.drawCurveCommand.setInstanceCount(this.data.linksNumber ?? 0)\n\n // Render normal links\n this.drawCurveCommand.draw(renderPass)\n }\n\n public updateLinkIndexFbo (): void {\n const { device, store } = this\n\n // Only create and update the link index FBO if link hovering is enabled\n if (!this.store.isLinkHoveringEnabled) return\n\n const screenSize = store.screenSize ?? [0, 0]\n const screenWidth = screenSize[0]\n const screenHeight = screenSize[1]\n\n // Avoid invalid uploads when size is zero\n if (!screenWidth || !screenHeight) return\n\n // Check if screen size changed\n const screenSizeChanged =\n this.previousScreenSize?.[0] !== screenWidth ||\n this.previousScreenSize?.[1] !== screenHeight\n\n if (!this.linkIndexTexture || screenSizeChanged) {\n // Destroy old framebuffer and texture if they exist\n if (this.linkIndexFbo && !this.linkIndexFbo.destroyed) {\n this.linkIndexFbo.destroy()\n }\n if (this.linkIndexTexture && !this.linkIndexTexture.destroyed) {\n this.linkIndexTexture.destroy()\n }\n\n // Create new texture\n this.linkIndexTexture = device.createTexture({\n width: screenWidth,\n height: screenHeight,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.linkIndexTexture.copyImageData({\n data: new Float32Array(screenWidth * screenHeight * 4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', screenWidth),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Create new framebuffer\n this.linkIndexFbo = device.createFramebuffer({\n width: screenWidth,\n height: screenHeight,\n colorAttachments: [this.linkIndexTexture],\n })\n\n this.previousScreenSize = [screenWidth, screenHeight]\n }\n }\n\n public updatePointsBuffer (): void {\n const { device, data, store } = this\n if (data.linksNumber === undefined || data.links === undefined) return\n if (!store.pointsTextureSize) return // Guard against 0/undefined\n\n // Create separate buffers for pointA and pointB\n const pointAData = new Float32Array(data.linksNumber * 2)\n const pointBData = new Float32Array(data.linksNumber * 2)\n\n for (let i = 0; i < data.linksNumber; i++) {\n const fromIndex = data.links[i * 2] as number\n const toIndex = data.links[i * 2 + 1] as number\n const fromX = fromIndex % store.pointsTextureSize\n const fromY = Math.floor(fromIndex / store.pointsTextureSize)\n const toX = toIndex % store.pointsTextureSize\n const toY = Math.floor(toIndex / store.pointsTextureSize)\n\n pointAData[i * 2] = fromX\n pointAData[i * 2 + 1] = fromY\n pointBData[i * 2] = toX\n pointBData[i * 2 + 1] = toY\n }\n\n // Check if buffer needs to be resized (buffers can't be resized, need to recreate)\n const currentSize = (this.pointABuffer?.byteLength ?? 0) / (Float32Array.BYTES_PER_ELEMENT * 2)\n if (!this.pointABuffer || currentSize !== data.linksNumber) {\n if (this.pointABuffer && !this.pointABuffer.destroyed) {\n this.pointABuffer.destroy()\n }\n this.pointABuffer = device.createBuffer({\n data: pointAData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n // Note: Model attributes are set at creation time, so if Model exists and buffer is recreated,\n // the Model will need to be recreated too. For now, we ensure buffers exist before initPrograms.\n } else {\n this.pointABuffer.write(pointAData)\n }\n\n if (!this.pointBBuffer || currentSize !== data.linksNumber) {\n if (this.pointBBuffer && !this.pointBBuffer.destroyed) {\n this.pointBBuffer.destroy()\n }\n this.pointBBuffer = device.createBuffer({\n data: pointBData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.pointBBuffer.write(pointBData)\n }\n\n const linkIndices = new Float32Array(data.linksNumber)\n for (let i = 0; i < data.linksNumber; i++) {\n linkIndices[i] = i\n }\n if (!this.linkIndexBuffer || currentSize !== data.linksNumber) {\n if (this.linkIndexBuffer && !this.linkIndexBuffer.destroyed) {\n this.linkIndexBuffer.destroy()\n }\n this.linkIndexBuffer = device.createBuffer({\n data: linkIndices,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.linkIndexBuffer.write(linkIndices)\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n pointA: this.pointABuffer,\n pointB: this.pointBBuffer,\n linkIndices: this.linkIndexBuffer,\n })\n }\n }\n\n public updateColor (): void {\n const { device, data } = this\n const linksNumber = data.linksNumber ?? 0\n const colorData = data.linkColors ?? new Float32Array(linksNumber * 4).fill(0)\n\n if (!this.colorBuffer) {\n this.colorBuffer = device.createBuffer({\n data: colorData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n // Check if buffer needs to be resized\n const currentSize = (this.colorBuffer.byteLength ?? 0) / (Float32Array.BYTES_PER_ELEMENT * 4)\n if (currentSize !== linksNumber) {\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = device.createBuffer({\n data: colorData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.colorBuffer.write(colorData)\n }\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n color: this.colorBuffer,\n })\n }\n }\n\n public updateWidth (): void {\n const { device, data } = this\n const linksNumber = data.linksNumber ?? 0\n const widthData = data.linkWidths ?? new Float32Array(linksNumber).fill(0)\n\n if (!this.widthBuffer) {\n this.widthBuffer = device.createBuffer({\n data: widthData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n // Check if buffer needs to be resized\n const currentSize = (this.widthBuffer.byteLength ?? 0) / Float32Array.BYTES_PER_ELEMENT\n if (currentSize !== linksNumber) {\n if (this.widthBuffer && !this.widthBuffer.destroyed) {\n this.widthBuffer.destroy()\n }\n this.widthBuffer = device.createBuffer({\n data: widthData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.widthBuffer.write(widthData)\n }\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n width: this.widthBuffer,\n })\n }\n }\n\n public updateArrow (): void {\n const { device, data } = this\n // linkArrows is number[] not Float32Array, so we need to convert it\n // Ensure we have the right size even if linkArrows is undefined\n const linksNumber = data.linksNumber ?? 0\n const arrowData = data.linkArrows\n ? new Float32Array(data.linkArrows)\n : new Float32Array(linksNumber).fill(0)\n\n if (!this.arrowBuffer) {\n this.arrowBuffer = device.createBuffer({\n data: arrowData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n // Check if buffer needs to be resized\n const currentSize = (this.arrowBuffer.byteLength ?? 0) / Float32Array.BYTES_PER_ELEMENT\n if (currentSize !== linksNumber) {\n if (this.arrowBuffer && !this.arrowBuffer.destroyed) {\n this.arrowBuffer.destroy()\n }\n this.arrowBuffer = device.createBuffer({\n data: arrowData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.arrowBuffer.write(arrowData)\n }\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n arrow: this.arrowBuffer,\n })\n }\n }\n\n public updateCurveLineGeometry (): void {\n const { device, config: { curvedLinks, curvedLinkSegments } } = this\n this.curveLineGeometry = getCurveLineGeometry(curvedLinks ? curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1)\n\n // Flatten the 2D array to 1D\n const flatGeometry = new Float32Array(this.curveLineGeometry.length * 2)\n for (let i = 0; i < this.curveLineGeometry.length; i++) {\n flatGeometry[i * 2] = this.curveLineGeometry[i]![0]!\n flatGeometry[i * 2 + 1] = this.curveLineGeometry[i]![1]!\n }\n\n if (!this.curveLineBuffer || this.curveLineBuffer.byteLength !== flatGeometry.byteLength) {\n if (this.curveLineBuffer && !this.curveLineBuffer.destroyed) {\n this.curveLineBuffer.destroy()\n }\n this.curveLineBuffer = device.createBuffer({\n data: flatGeometry,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.curveLineBuffer.write(flatGeometry)\n }\n\n // Update vertex count in model if it exists\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n position: this.curveLineBuffer,\n })\n this.drawCurveCommand.setVertexCount(this.curveLineGeometry.length)\n }\n }\n\n public findHoveredLine (): void {\n const { config, points, store } = this\n if (!points) return\n if (!points.currentPositionTexture || points.currentPositionTexture.destroyed) return\n if (!points.greyoutStatusTexture || points.greyoutStatusTexture.destroyed) return\n if (!this.data.linksNumber || !this.store.isLinkHoveringEnabled) return\n if (!this.linkIndexFbo || !this.drawCurveCommand || !this.drawLineUniformStore) return\n if (!this.linkIndexTexture || this.linkIndexTexture.destroyed) return\n\n // Update uniforms for index rendering\n this.drawLineUniformStore.setUniforms({\n drawLineUniforms: {\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize,\n widthScale: config.linkWidthScale ?? 1,\n linkArrowsSizeScale: config.linkArrowsSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n linkVisibilityDistanceRange: ensureVec2(config.linkVisibilityDistanceRange, [0, 0]),\n linkVisibilityMinTransparency: config.linkVisibilityMinTransparency ?? 0,\n linkOpacity: config.linkOpacity ?? 1,\n greyoutOpacity: config.linkGreyoutOpacity ?? 1,\n curvedWeight: config.curvedLinkWeight ?? 0,\n curvedLinkControlPointDistance: config.curvedLinkControlPointDistance ?? 0,\n curvedLinkSegments: config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,\n scaleLinksOnZoom: (config.scaleLinksOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n renderMode: 1.0, // Index rendering for picking\n hoveredLinkIndex: store.hoveredLinkIndex ?? -1,\n hoveredLinkColor: ensureVec4(store.hoveredLinkColor, [-1, -1, -1, -1]),\n hoveredLinkWidthIncrease: config.hoveredLinkWidthIncrease ?? 0,\n },\n drawLineFragmentUniforms: {\n renderMode: 1.0, // Index rendering for picking\n },\n })\n\n // Update texture bindings dynamically\n this.drawCurveCommand.setBindings({\n positionsTexture: points.currentPositionTexture,\n pointGreyoutStatus: points.greyoutStatusTexture,\n })\n\n // Update instance count\n this.drawCurveCommand.setInstanceCount(this.data.linksNumber ?? 0)\n\n // Render to index buffer for picking/hover detection\n const indexPass = this.device.beginRenderPass({\n framebuffer: this.linkIndexFbo,\n // Clear framebuffer to transparent black (luma.gl default would be opaque black)\n clearColor: [0, 0, 0, 0],\n })\n this.drawCurveCommand.draw(indexPass)\n indexPass.end()\n\n if (this.hoveredLineIndexCommand && this.hoveredLineIndexFbo && this.hoveredLineIndexUniformStore) {\n this.hoveredLineIndexUniformStore.setUniforms({\n hoveredLineIndexUniforms: {\n mousePosition: ensureVec2(store.screenMousePosition, [0, 0]),\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.hoveredLineIndexCommand.setBindings({\n linkIndexTexture: this.linkIndexTexture,\n })\n\n const hoverPass = this.device.beginRenderPass({\n framebuffer: this.hoveredLineIndexFbo,\n })\n this.hoveredLineIndexCommand.draw(hoverPass)\n hoverPass.end()\n }\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.drawCurveCommand?.destroy()\n this.drawCurveCommand = undefined\n this.hoveredLineIndexCommand?.destroy()\n this.hoveredLineIndexCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.linkIndexFbo && !this.linkIndexFbo.destroyed) {\n this.linkIndexFbo.destroy()\n }\n this.linkIndexFbo = undefined\n if (this.hoveredLineIndexFbo && !this.hoveredLineIndexFbo.destroyed) {\n this.hoveredLineIndexFbo.destroy()\n }\n this.hoveredLineIndexFbo = undefined\n\n // 3. Destroy Textures\n if (this.linkIndexTexture && !this.linkIndexTexture.destroyed) {\n this.linkIndexTexture.destroy()\n }\n this.linkIndexTexture = undefined\n if (this.hoveredLineIndexTexture && !this.hoveredLineIndexTexture.destroyed) {\n this.hoveredLineIndexTexture.destroy()\n }\n this.hoveredLineIndexTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.drawLineUniformStore?.destroy()\n this.drawLineUniformStore = undefined\n this.hoveredLineIndexUniformStore?.destroy()\n this.hoveredLineIndexUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointABuffer && !this.pointABuffer.destroyed) {\n this.pointABuffer.destroy()\n }\n this.pointABuffer = undefined\n if (this.pointBBuffer && !this.pointBBuffer.destroyed) {\n this.pointBBuffer.destroy()\n }\n this.pointBBuffer = undefined\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = undefined\n if (this.widthBuffer && !this.widthBuffer.destroyed) {\n this.widthBuffer.destroy()\n }\n this.widthBuffer = undefined\n if (this.arrowBuffer && !this.arrowBuffer.destroyed) {\n this.arrowBuffer.destroy()\n }\n this.arrowBuffer = undefined\n if (this.curveLineBuffer && !this.curveLineBuffer.destroyed) {\n this.curveLineBuffer.destroy()\n }\n this.curveLineBuffer = undefined\n if (this.linkIndexBuffer && !this.linkIndexBuffer.destroyed) {\n this.linkIndexBuffer.destroy()\n }\n this.linkIndexBuffer = undefined\n if (this.quadBuffer && !this.quadBuffer.destroyed) {\n this.quadBuffer.destroy()\n }\n this.quadBuffer = undefined\n }\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D imageAtlasTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawFragmentUniforms {\\n float greyoutOpacity;\\n float pointOpacity;\\n float isDarkenGreyout;\\n vec4 backgroundColor;\\n} drawFragment;\\n\\n#define greyoutOpacity drawFragment.greyoutOpacity\\n#define pointOpacity drawFragment.pointOpacity\\n#define isDarkenGreyout drawFragment.isDarkenGreyout\\n#define backgroundColor drawFragment.backgroundColor\\n#else\\nuniform float greyoutOpacity;\\nuniform float pointOpacity;\\nuniform float isDarkenGreyout;\\nuniform vec4 backgroundColor;\\n#endif\\n\\n\\nin float pointShape;\\nin float isGreyedOut;\\nin vec4 shapeColor;\\nin vec4 imageAtlasUV;\\nin float shapeSize;\\nin float imageSizeVarying;\\nin float overallSize;\\n\\nout vec4 fragColor;\\n\\n// Smoothing controls the smoothness of the point's edge\\nconst float smoothing = 0.9;\\n\\n// Shape constants\\nconst float CIRCLE = 0.0;\\nconst float SQUARE = 1.0;\\nconst float TRIANGLE = 2.0;\\nconst float DIAMOND = 3.0;\\nconst float PENTAGON = 4.0;\\nconst float HEXAGON = 5.0;\\nconst float STAR = 6.0;\\nconst float CROSS = 7.0;\\nconst float NONE = 8.0;\\n\\n// Distance functions for different shapes\\nfloat circleDistance(vec2 p) {\\n return dot(p, p);\\n}\\n\\n// Function to apply greyout logic to image colors\\nvec4 applyGreyoutToImage(vec4 imageColor, float isGreyedOutValue) {\\n vec3 finalColor = imageColor.rgb;\\n float finalAlpha = imageColor.a;\\n \\n if (isGreyedOutValue > 0.0) {\\n float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)\\n \\n if (isDarkenGreyout > 0.0) {\\n finalColor = mix(finalColor, vec3(0.2), blendFactor);\\n } else {\\n finalColor = mix(finalColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n }\\n \\n return vec4(finalColor, finalAlpha);\\n}\\n\\nfloat squareDistance(vec2 p) {\\n vec2 d = abs(p) - vec2(0.8);\\n return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);\\n}\\n\\nfloat triangleDistance(vec2 p) {\\n const float k = sqrt(3.0); // ≈1.732; slope of 60° lines for an equilateral triangle\\n p.x = abs(p.x) - 0.9; // fold the X axis and shift: brings left and right halves together\\n p.y = p.y + 0.55; // move the whole shape up slightly so it is centred vertically\\n\\n // reflect points that fall outside the main triangle back inside, to reuse the same maths\\n if (p.x + k * p.y > 0.0)\\n p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;\\n\\n p.x -= clamp(p.x, -1.0, 0.0); // clip any remainder on the left side\\n\\n // Return signed distance: negative = inside; positive = outside\\n return -length(p) * sign(p.y);\\n}\\n\\nfloat diamondDistance(vec2 p) {\\n // aspect > 1 → taller diamond\\n const float aspect = 1.2;\\n return abs(p.x) + abs(p.y) / aspect - 0.8;\\n}\\n\\nfloat pentagonDistance(vec2 p) {\\n // Regular pentagon signed-distance (Inigo Quilez)\\n const vec3 k = vec3(0.809016994, 0.587785252, 0.726542528);\\n p.x = abs(p.x);\\n\\n // Reflect across the two tilted edges ─ only if point is outside\\n p -= 2.0 * min(dot(vec2(-k.x, k.y), p), 0.0) * vec2(-k.x, k.y);\\n p -= 2.0 * min(dot(vec2( k.x, k.y), p), 0.0) * vec2( k.x, k.y);\\n\\n // Clip against the top horizontal edge (keeps top point sharp)\\n p -= vec2(clamp(p.x, -k.z * k.x, k.z * k.x), k.z);\\n\\n // Return signed distance (negative → inside, positive → outside)\\n return length(p) * sign(p.y);\\n}\\n\\nfloat hexagonDistance(vec2 p) {\\n const vec3 k = vec3(-0.866025404, 0.5, 0.577350269);\\n p = abs(p);\\n p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy;\\n p -= vec2(clamp(p.x, -k.z * 0.8, k.z * 0.8), 0.8);\\n return length(p) * sign(p.y);\\n}\\n\\nfloat starDistance(vec2 p) {\\n // 5-point star signed-distance function (adapted from Inigo Quilez)\\n // r – outer radius, rf – inner/outer radius ratio\\n const float r = 0.9;\\n const float rf = 0.45;\\n\\n // Pre-computed rotation vectors for the star arms (36° increments)\\n const vec2 k1 = vec2(0.809016994, -0.587785252);\\n const vec2 k2 = vec2(-k1.x, k1.y);\\n\\n // Fold the plane into a single arm sector\\n p.x = abs(p.x);\\n p -= 2.0 * max(dot(k1, p), 0.0) * k1;\\n p -= 2.0 * max(dot(k2, p), 0.0) * k2;\\n p.x = abs(p.x);\\n\\n // Translate so the top tip of the star lies on the X-axis\\n p.y -= r;\\n\\n // Vector describing the edge between an outer tip and its adjacent inner point\\n vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0);\\n // Project the point onto that edge and clamp the projection to the segment\\n float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r);\\n\\n // Return signed distance (negative => inside, positive => outside)\\n return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y);\\n}\\n\\nfloat crossDistance(vec2 p) {\\n // Signed distance function for a cross (union of two rectangles)\\n // Adapted from Inigo Quilez (https://iquilezles.org/)\\n // Each arm has half-sizes 0.3 (thickness) and 0.8 (length)\\n p = abs(p);\\n if (p.y > p.x) p = p.yx; // exploit symmetry\\n\\n vec2 q = p - vec2(0.8, 0.3); // subtract half-sizes (length, thickness)\\n\\n // Standard rectangle SDF, then take union of the two arms\\n return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0);\\n}\\n\\nfloat getShapeDistance(vec2 p, float shape) {\\n if (shape == SQUARE) return squareDistance(p);\\n else if (shape == TRIANGLE) return triangleDistance(p);\\n else if (shape == DIAMOND) return diamondDistance(p);\\n else if (shape == PENTAGON) return pentagonDistance(p);\\n else if (shape == HEXAGON) return hexagonDistance(p);\\n else if (shape == STAR) return starDistance(p);\\n else if (shape == CROSS) return crossDistance(p);\\n else return circleDistance(p); // Default to circle\\n}\\n\\nvoid main() {\\n // Discard the fragment if the point is fully transparent and has no image\\n if (shapeColor.a == 0.0 && imageAtlasUV.x == -1.0) {\\n discard;\\n }\\n\\n // Discard the fragment if the point has no shape and no image\\n if (pointShape == NONE && imageAtlasUV.x == -1.0) {\\n discard;\\n }\\n\\n // Calculate coordinates within the point\\n vec2 pointCoord = 2.0 * gl_PointCoord - 1.0;\\n\\n vec4 finalShapeColor = vec4(0.0);\\n vec4 finalImageColor = vec4(0.0);\\n \\n // Handle shape rendering with centering logic\\n if (pointShape != NONE) {\\n // Calculate shape coordinates with centering\\n vec2 shapeCoord = pointCoord;\\n if (overallSize > shapeSize && shapeSize > 0.0) {\\n // Shape is smaller than overall size, center it\\n float scale = shapeSize / overallSize;\\n shapeCoord = pointCoord / scale;\\n }\\n \\n float opacity;\\n if (pointShape == CIRCLE) {\\n // For circles, use the original distance calculation\\n float pointCenterDistance = dot(shapeCoord, shapeCoord);\\n opacity = 1.0 - smoothstep(smoothing, 1.0, pointCenterDistance);\\n } else {\\n // For other shapes, use the shape distance function\\n float shapeDistance = getShapeDistance(shapeCoord, pointShape);\\n opacity = 1.0 - smoothstep(-0.01, 0.01, shapeDistance);\\n }\\n opacity *= shapeColor.a;\\n\\n finalShapeColor = vec4(shapeColor.rgb, opacity);\\n }\\n\\n // Handle image rendering with centering logic\\n if (imageAtlasUV.x != -1.0) {\\n // Calculate image coordinates with centering\\n vec2 imageCoord = pointCoord;\\n if (overallSize > imageSizeVarying && imageSizeVarying > 0.0) {\\n // Image is smaller than overall size, center it\\n float scale = imageSizeVarying / overallSize;\\n imageCoord = pointCoord / scale;\\n \\n // Check if we're outside the valid image area\\n if (abs(imageCoord.x) > 1.0 || abs(imageCoord.y) > 1.0) {\\n // We're outside the image bounds, don't render the image\\n finalImageColor = vec4(0.0);\\n } else {\\n // Sample from texture atlas\\n vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5);\\n vec4 imageColor = texture(imageAtlasTexture, atlasUV);\\n finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut);\\n }\\n } else {\\n // Image is same size or larger than overall size, no scaling needed\\n // Sample from texture atlas\\n vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5);\\n vec4 imageColor = texture(imageAtlasTexture, atlasUV);\\n finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut);\\n }\\n }\\n\\n float finalPointAlpha = max(finalShapeColor.a, finalImageColor.a);\\n if (isGreyedOut > 0.0 && greyoutOpacity != -1.0) {\\n finalPointAlpha *= greyoutOpacity;\\n } else {\\n finalPointAlpha *= pointOpacity;\\n }\\n\\n // Blend image color above point color\\n fragColor = vec4(\\n mix(finalShapeColor.rgb, finalImageColor.rgb, finalImageColor.a),\\n finalPointAlpha\\n );\\n}\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 pointIndices;\\nin float size;\\nin vec4 color;\\nin float shape;\\nin float imageIndex;\\nin float imageSize;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatus;\\nuniform sampler2D imageAtlasCoords;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawVertexUniforms {\\n float ratio;\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n vec4 greyoutColor;\\n vec4 backgroundColor;\\n float scalePointsOnZoom;\\n float maxPointSize;\\n float isDarkenGreyout;\\n float skipSelected;\\n float skipUnselected;\\n float hasImages;\\n float imageCount;\\n float imageAtlasCoordsTextureSize;\\n} drawVertex;\\n\\n#define ratio drawVertex.ratio\\n#define transformationMatrix drawVertex.transformationMatrix\\n#define pointsTextureSize drawVertex.pointsTextureSize\\n#define sizeScale drawVertex.sizeScale\\n#define spaceSize drawVertex.spaceSize\\n#define screenSize drawVertex.screenSize\\n#define greyoutColor drawVertex.greyoutColor\\n#define backgroundColor drawVertex.backgroundColor\\n#define scalePointsOnZoom drawVertex.scalePointsOnZoom\\n#define maxPointSize drawVertex.maxPointSize\\n#define isDarkenGreyout drawVertex.isDarkenGreyout\\n#define skipSelected drawVertex.skipSelected\\n#define skipUnselected drawVertex.skipUnselected\\n#define hasImages drawVertex.hasImages\\n#define imageCount drawVertex.imageCount\\n#define imageAtlasCoordsTextureSize drawVertex.imageAtlasCoordsTextureSize\\n#else\\nuniform float ratio;\\nuniform mat3 transformationMatrix;\\nuniform float pointsTextureSize;\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform vec4 greyoutColor;\\nuniform vec4 backgroundColor;\\nuniform float scalePointsOnZoom;\\nuniform float maxPointSize;\\nuniform float isDarkenGreyout;\\nuniform float skipSelected;\\nuniform float skipUnselected;\\nuniform float hasImages;\\nuniform float imageCount;\\nuniform float imageAtlasCoordsTextureSize;\\n#endif\\n\\nout float pointShape;\\nout float isGreyedOut;\\nout vec4 shapeColor;\\nout vec4 imageAtlasUV;\\nout float shapeSize;\\nout float imageSizeVarying;\\nout float overallSize;\\n\\nfloat calculatePointSize(float size) {\\n float pSize;\\n\\n if (scalePointsOnZoom > 0.0) { \\n pSize = size * ratio * transformationMatrix[0][0];\\n } else {\\n pSize = size * ratio * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n\\n return min(pSize, maxPointSize * ratio);\\n}\\n\\nvoid main() { \\n // Check greyout status for selective rendering\\n vec4 greyoutStatus = texture(pointGreyoutStatus, (pointIndices + 0.5) / pointsTextureSize);\\n isGreyedOut = greyoutStatus.r;\\n float isSelected = (greyoutStatus.r == 0.0) ? 1.0 : 0.0;\\n \\n // Discard point based on rendering mode\\n if (skipSelected > 0.0 && isSelected > 0.0) {\\n gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Move off-screen\\n gl_PointSize = 0.0;\\n return;\\n }\\n if (skipUnselected > 0.0 && isSelected <= 0.0) {\\n gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Move off-screen\\n gl_PointSize = 0.0;\\n return;\\n }\\n \\n // Position\\n vec4 pointPosition = texture(positionsTexture, (pointIndices + 0.5) / pointsTextureSize);\\n vec2 point = pointPosition.rg;\\n\\n // Transform point position to normalized device coordinates\\n // Convert from space coordinates [0, spaceSize] to normalized [-1, 1]\\n vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0;\\n \\n // Apply aspect ratio correction - this is needed to map the square space to the rectangular screen\\n // The transformation matrix handles zoom/pan, but we need this to handle aspect ratio\\n normalizedPosition *= spaceSize / screenSize;\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1);\\n #else\\n vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1);\\n #endif\\n gl_Position = vec4(finalPosition.rg, 0, 1);\\n\\n // Calculate sizes for shape and image\\n float shapeSizeValue = calculatePointSize(size * sizeScale);\\n float imageSizeValue = calculatePointSize(imageSize * sizeScale);\\n \\n // Use the larger of the two sizes for the overall point size\\n float overallSizeValue = max(shapeSizeValue, imageSizeValue);\\n gl_PointSize = overallSizeValue;\\n\\n // Pass size information to fragment shader\\n shapeSize = shapeSizeValue;\\n imageSizeVarying = imageSizeValue;\\n overallSize = overallSizeValue;\\n\\n shapeColor = color;\\n pointShape = shape;\\n\\n // Adjust alpha of selected points\\n if (isGreyedOut > 0.0) {\\n if (greyoutColor[0] != -1.0) {\\n shapeColor = greyoutColor;\\n } else {\\n // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout\\n float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n shapeColor.rgb = mix(shapeColor.rgb, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n shapeColor.rgb = mix(shapeColor.rgb, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #else\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n shapeColor.rgb = mix(shapeColor.rgb, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n shapeColor.rgb = mix(shapeColor.rgb, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #endif\\n }\\n }\\n\\n #ifdef USE_UNIFORM_BUFFERS\\n if (hasImages <= 0.0 || imageIndex < 0.0 || imageIndex >= imageCount) {\\n imageAtlasUV = vec4(-1.0);\\n } else {\\n // Calculate image atlas UV coordinates based on imageIndex\\n float atlasCoordIndex = imageIndex;\\n // Calculate the position in the texture grid\\n float texX = mod(atlasCoordIndex, imageAtlasCoordsTextureSize);\\n float texY = floor(atlasCoordIndex / imageAtlasCoordsTextureSize);\\n // Convert to texture coordinates (0.0 to 1.0)\\n vec2 atlasCoordTexCoord = (vec2(texX, texY) + 0.5) / imageAtlasCoordsTextureSize;\\n vec4 atlasCoords = texture(imageAtlasCoords, atlasCoordTexCoord);\\n imageAtlasUV = atlasCoords;\\n }\\n #else\\n if (hasImages <= 0.0 || imageIndex < 0.0 || imageIndex >= imageCount) {\\n imageAtlasUV = vec4(-1.0);\\n } else {\\n // Calculate image atlas UV coordinates based on imageIndex\\n float atlasCoordIndex = imageIndex;\\n // Calculate the position in the texture grid\\n float texX = mod(atlasCoordIndex, imageAtlasCoordsTextureSize);\\n float texY = floor(atlasCoordIndex / imageAtlasCoordsTextureSize);\\n // Convert to texture coordinates (0.0 to 1.0)\\n vec2 atlasCoordTexCoord = (vec2(texX, texY) + 0.5) / imageAtlasCoordsTextureSize;\\n vec4 atlasCoords = texture(imageAtlasCoords, atlasCoordTexCoord);\\n imageAtlasUV = atlasCoords;\\n }\\n #endif\\n} \"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointSize;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform findPointsOnAreaSelectionUniforms {\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float ratio;\\n mat4 transformationMatrix;\\n vec2 selection0;\\n vec2 selection1;\\n float scalePointsOnZoom;\\n float maxPointSize;\\n} findPointsOnAreaSelection;\\n\\n#define sizeScale findPointsOnAreaSelection.sizeScale\\n#define spaceSize findPointsOnAreaSelection.spaceSize\\n#define screenSize findPointsOnAreaSelection.screenSize\\n#define ratio findPointsOnAreaSelection.ratio\\n#define transformationMatrix findPointsOnAreaSelection.transformationMatrix\\n#define selection0 findPointsOnAreaSelection.selection0\\n#define selection1 findPointsOnAreaSelection.selection1\\n#define scalePointsOnZoom findPointsOnAreaSelection.scalePointsOnZoom\\n#define maxPointSize findPointsOnAreaSelection.maxPointSize\\n#else\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform float ratio;\\nuniform mat3 transformationMatrix;\\nuniform vec2 selection0;\\nuniform vec2 selection1;\\nuniform float scalePointsOnZoom;\\nuniform float maxPointSize;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nfloat pointSizeF(float size) {\\n float pSize;\\n // Extract top-left element from mat4 (or use mat3 conversion)\\n #ifdef USE_UNIFORM_BUFFERS\\n float scale = transformationMatrix[0][0]; // mat4 first element\\n #else\\n float scale = transformationMatrix[0][0]; // mat3 first element\\n #endif\\n if (scalePointsOnZoom > 0.0) { \\n pSize = size * ratio * scale;\\n } else {\\n pSize = size * ratio * min(5.0, max(1.0, scale * 0.01));\\n }\\n return min(pSize, maxPointSize * ratio);\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n // Convert mat4 to mat3 for vec3 multiplication\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n\\n vec4 pSize = texture(pointSize, textureCoords);\\n float size = pSize.r * sizeScale;\\n\\n float left = 2.0 * (selection0.x - 0.5 * pointSizeF(size)) / screenSize.x - 1.0;\\n float right = 2.0 * (selection1.x + 0.5 * pointSizeF(size)) / screenSize.x - 1.0;\\n float top = 2.0 * (selection0.y - 0.5 * pointSizeF(size)) / screenSize.y - 1.0;\\n float bottom = 2.0 * (selection1.y + 0.5 * pointSizeF(size)) / screenSize.y - 1.0;\\n\\n fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g);\\n if (final.x >= left && final.x <= right && final.y >= top && final.y <= bottom) {\\n fragColor.r = 1.0;\\n }\\n}\\n\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D polygonPathTexture; // Texture containing polygon path points\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform findPointsOnPolygonSelectionUniforms {\\n float spaceSize;\\n vec2 screenSize;\\n mat4 transformationMatrix;\\n float polygonPathLength;\\n} findPointsOnPolygonSelection;\\n\\n#define spaceSize findPointsOnPolygonSelection.spaceSize\\n#define screenSize findPointsOnPolygonSelection.screenSize\\n#define transformationMatrix findPointsOnPolygonSelection.transformationMatrix\\n#define polygonPathLength int(findPointsOnPolygonSelection.polygonPathLength)\\n#else\\nuniform int polygonPathLength;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform mat3 transformationMatrix;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\n// Get a point from the polygon path texture at a specific index\\nvec2 getPolygonPoint(sampler2D pathTexture, int index, int pathLength) {\\n if (index >= pathLength) return vec2(0.0);\\n \\n // Calculate texture coordinates for the index\\n int textureSize = int(ceil(sqrt(float(pathLength))));\\n int x = index - (index / textureSize) * textureSize;\\n int y = index / textureSize;\\n \\n vec2 texCoord = (vec2(float(x), float(y)) + 0.5) / float(textureSize);\\n vec4 pathData = texture(pathTexture, texCoord);\\n \\n return pathData.xy;\\n}\\n\\n// Point-in-polygon algorithm using ray casting\\nbool pointInPolygon(vec2 point, sampler2D pathTexture, int pathLength) {\\n bool inside = false;\\n \\n for (int i = 0; i < 2048; i++) {\\n if (i >= pathLength) break;\\n \\n int j = int(mod(float(i + 1), float(pathLength)));\\n \\n vec2 pi = getPolygonPoint(pathTexture, i, pathLength);\\n vec2 pj = getPolygonPoint(pathTexture, j, pathLength);\\n \\n if (((pi.y > point.y) != (pj.y > point.y)) &&\\n (point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x)) {\\n inside = !inside;\\n }\\n }\\n \\n return inside;\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n // Convert mat4 to mat3 for vec3 multiplication\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n\\n // Convert to screen coordinates for polygon check\\n vec2 screenPos = (final.xy + 1.0) * screenSize / 2.0;\\n \\n fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g);\\n \\n // Check if point center is inside the polygon\\n if (pointInPolygon(screenPos, polygonPathTexture, polygonPathLength)) {\\n fragColor.r = 1.0;\\n }\\n} \"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawHighlightedUniforms {\\n float size;\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float scalePointsOnZoom;\\n float pointIndex;\\n float maxPointSize;\\n vec4 color;\\n float universalPointOpacity;\\n float greyoutOpacity;\\n float isDarkenGreyout;\\n vec4 backgroundColor;\\n vec4 greyoutColor;\\n float width;\\n} drawHighlighted;\\n\\n#define width drawHighlighted.width\\n#else\\nuniform float width;\\n#endif\\n\\nin vec2 vertexPosition;\\nin float pointOpacity;\\nin vec3 rgbColor;\\n\\nout vec4 fragColor;\\n\\nconst float smoothing = 1.05;\\n\\nvoid main () {\\n float r = dot(vertexPosition, vertexPosition);\\n float opacity = smoothstep(r, r * smoothing, 1.0);\\n float stroke = smoothstep(width, width * smoothing, r);\\n fragColor = vec4(rgbColor, opacity * stroke * pointOpacity);\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 vertexCoord;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatusTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawHighlightedUniforms {\\n float size;\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float scalePointsOnZoom;\\n float pointIndex;\\n float maxPointSize;\\n vec4 color;\\n float universalPointOpacity;\\n float greyoutOpacity;\\n float isDarkenGreyout;\\n vec4 backgroundColor;\\n vec4 greyoutColor;\\n float width;\\n} drawHighlighted;\\n\\n#define size drawHighlighted.size\\n#define transformationMatrix drawHighlighted.transformationMatrix\\n#define pointsTextureSize drawHighlighted.pointsTextureSize\\n#define sizeScale drawHighlighted.sizeScale\\n#define spaceSize drawHighlighted.spaceSize\\n#define screenSize drawHighlighted.screenSize\\n#define scalePointsOnZoom drawHighlighted.scalePointsOnZoom\\n#define pointIndex drawHighlighted.pointIndex\\n#define maxPointSize drawHighlighted.maxPointSize\\n#define color drawHighlighted.color\\n#define universalPointOpacity drawHighlighted.universalPointOpacity\\n#define greyoutOpacity drawHighlighted.greyoutOpacity\\n#define isDarkenGreyout drawHighlighted.isDarkenGreyout\\n#define backgroundColor drawHighlighted.backgroundColor\\n#define greyoutColor drawHighlighted.greyoutColor\\n#else\\nuniform float size;\\nuniform mat3 transformationMatrix;\\nuniform float pointsTextureSize;\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform float scalePointsOnZoom;\\nuniform float pointIndex;\\nuniform float maxPointSize;\\nuniform vec4 color;\\nuniform float universalPointOpacity;\\nuniform float greyoutOpacity;\\nuniform float isDarkenGreyout;\\nuniform vec4 backgroundColor;\\nuniform vec4 greyoutColor;\\nuniform float width;\\n#endif\\nout vec2 vertexPosition;\\nout float pointOpacity;\\nout vec3 rgbColor;\\n\\nfloat calculatePointSize(float pointSize) {\\n float pSize;\\n\\n if (scalePointsOnZoom > 0.0) { \\n pSize = pointSize * transformationMatrix[0][0];\\n } else {\\n pSize = pointSize * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n\\n return min(pSize, maxPointSize);\\n}\\n\\nconst float relativeRingRadius = 1.3;\\n\\nvoid main () {\\n vertexPosition = vertexCoord;\\n\\n vec2 textureCoordinates = vec2(mod(pointIndex, pointsTextureSize), floor(pointIndex / pointsTextureSize)) + 0.5;\\n vec4 pointPosition = texture(positionsTexture, textureCoordinates / pointsTextureSize);\\n\\n rgbColor = color.rgb;\\n pointOpacity = color.a * universalPointOpacity;\\n vec4 greyoutStatus = texture(pointGreyoutStatusTexture, textureCoordinates / pointsTextureSize);\\n if (greyoutStatus.r > 0.0) {\\n if (greyoutColor[0] != -1.0) {\\n rgbColor = greyoutColor.rgb;\\n pointOpacity = greyoutColor.a;\\n } else {\\n // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout\\n float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n rgbColor = mix(rgbColor, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #else\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n rgbColor = mix(rgbColor, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #endif\\n }\\n\\n if (greyoutOpacity != -1.0) {\\n pointOpacity *= greyoutOpacity;\\n }\\n }\\n\\n // Calculate point radius\\n float pointSize = (calculatePointSize(size * sizeScale) * relativeRingRadius) / transformationMatrix[0][0];\\n float radius = pointSize * 0.5;\\n\\n // Calculate point position in screen space\\n vec2 a = pointPosition.xy;\\n vec2 b = pointPosition.xy + vec2(0.0, radius);\\n vec2 xBasis = b - a;\\n vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));\\n vec2 pointPositionInScreenSpace = a + xBasis * vertexCoord.x + yBasis * radius * vertexCoord.y;\\n\\n // Transform point position to normalized device coordinates\\n vec2 p = 2.0 * pointPositionInScreenSpace / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n \\n gl_Position = vec4(final.rg, 0, 1);\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgba;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n if (rgba.g <= 0.0) {\\n discard;\\n }\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 pointIndices;\\nin float size;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatus;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform findHoveredPointUniforms {\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float ratio;\\n mat4 transformationMatrix;\\n vec2 mousePosition;\\n float scalePointsOnZoom;\\n float maxPointSize;\\n float skipSelected;\\n float skipUnselected;\\n} findHoveredPoint;\\n\\n#define pointsTextureSize findHoveredPoint.pointsTextureSize\\n#define sizeScale findHoveredPoint.sizeScale\\n#define spaceSize findHoveredPoint.spaceSize\\n#define screenSize findHoveredPoint.screenSize\\n#define ratio findHoveredPoint.ratio\\n#define transformationMatrix findHoveredPoint.transformationMatrix\\n#define mousePosition findHoveredPoint.mousePosition\\n#define scalePointsOnZoom findHoveredPoint.scalePointsOnZoom\\n#define maxPointSize findHoveredPoint.maxPointSize\\n#define skipSelected findHoveredPoint.skipSelected\\n#define skipUnselected findHoveredPoint.skipUnselected\\n#else\\nuniform float pointsTextureSize;\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform float ratio;\\nuniform mat3 transformationMatrix;\\nuniform vec2 mousePosition;\\nuniform float scalePointsOnZoom;\\nuniform float maxPointSize;\\nuniform float skipSelected;\\nuniform float skipUnselected;\\n#endif\\n\\nout vec4 rgba;\\n\\nfloat calculatePointSize(float size) {\\n float pSize;\\n\\n if (scalePointsOnZoom > 0.0) { \\n pSize = size * ratio * transformationMatrix[0][0];\\n } else {\\n pSize = size * ratio * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n\\n return min(pSize, maxPointSize * ratio);\\n}\\n\\nfloat euclideanDistance (float x1, float x2, float y1, float y2) {\\n return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\\n}\\n\\nvoid main() {\\n vec4 greyoutStatus = texture(pointGreyoutStatus, (pointIndices + 0.5) / pointsTextureSize);\\n float isSelected = (greyoutStatus.r == 0.0) ? 1.0 : 0.0;\\n\\n if (skipSelected > 0.0 && isSelected > 0.0) {\\n rgba = vec4(0.0);\\n gl_Position = vec4(0.5, 0.5, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n return;\\n }\\n if (skipUnselected > 0.0 && isSelected <= 0.0) {\\n rgba = vec4(0.0);\\n gl_Position = vec4(0.5, 0.5, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n return;\\n }\\n\\n vec4 pointPosition = texture(positionsTexture, (pointIndices + 0.5) / pointsTextureSize);\\n vec2 point = pointPosition.rg;\\n\\n vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0;\\n normalizedPosition *= spaceSize / screenSize;\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1);\\n #else\\n vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1);\\n #endif\\n\\n float pointRadius = 0.5 * calculatePointSize(size * sizeScale);\\n vec2 pointScreenPosition = (finalPosition.xy + 1.0) * screenSize / 2.0;\\n \\n rgba = vec4(0.0);\\n gl_Position = vec4(0.5, 0.5, 0.0, 1.0);\\n \\n if (euclideanDistance(pointScreenPosition.x, mousePosition.x, pointScreenPosition.y, mousePosition.y) < pointRadius / ratio) {\\n float index = pointIndices.g * pointsTextureSize + pointIndices.r;\\n rgba = vec4(index, size, pointPosition.xy);\\n gl_Position = vec4(-0.5, -0.5, 0.0, 1.0);\\n }\\n\\n gl_PointSize = 1.0;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgba;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform fillSampledPointsUniforms {\\n float pointsTextureSize;\\n mat4 transformationMatrix;\\n float spaceSize;\\n vec2 screenSize;\\n} fillSampledPoints;\\n\\n#define pointsTextureSize fillSampledPoints.pointsTextureSize\\n#define transformationMatrix fillSampledPoints.transformationMatrix\\n#define spaceSize fillSampledPoints.spaceSize\\n#define screenSize fillSampledPoints.screenSize\\n#else\\nuniform float pointsTextureSize;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform mat3 transformationMatrix;\\n#endif\\n\\nout vec4 rgba;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, (pointIndices + 0.5) / pointsTextureSize);\\n vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n // Convert mat4 to mat3 for vec3 multiplication\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n\\n vec2 pointScreenPosition = (final.xy + 1.0) * screenSize / 2.0;\\n float index = pointIndices.g * pointsTextureSize + pointIndices.r;\\n rgba = vec4(index, 1.0, pointPosition.xy);\\n float i = (pointScreenPosition.x + 0.5) / screenSize.x;\\n float j = (pointScreenPosition.y + 0.5) / screenSize.y;\\n gl_Position = vec4(2.0 * vec2(i, j) - 1.0, 0.0, 1.0);\\n\\n gl_PointSize = 1.0;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D velocity;\\nuniform sampler2D pinnedStatusTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform updatePositionUniforms {\\n float friction;\\n float spaceSize;\\n} updatePosition;\\n\\n#define friction updatePosition.friction\\n#define spaceSize updatePosition.spaceSize\\n#else\\nuniform float friction;\\nuniform float spaceSize;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 pointVelocity = texture(velocity, textureCoords);\\n\\n // Check if point is pinned\\n // pinnedStatusTexture has the same size and layout as positionsTexture\\n // Each pixel corresponds to a point: red channel > 0.5 means the point is pinned\\n vec4 pinnedStatus = texture(pinnedStatusTexture, textureCoords);\\n \\n // If pinned, don't update position\\n if (pinnedStatus.r > 0.5) {\\n fragColor = pointPosition;\\n return;\\n }\\n\\n // Friction\\n pointVelocity.rg *= friction;\\n\\n pointPosition.rg += pointVelocity.rg;\\n\\n pointPosition.r = clamp(pointPosition.r, 0.0, spaceSize);\\n pointPosition.g = clamp(pointPosition.g, 0.0, spaceSize);\\n \\n fragColor = pointPosition;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D trackedIndices;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform trackPointsUniforms {\\n float pointsTextureSize;\\n} trackPoints;\\n\\n#define pointsTextureSize trackPoints.pointsTextureSize\\n#else\\nuniform float pointsTextureSize;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 trackedPointIndices = texture(trackedIndices, textureCoords);\\n if (trackedPointIndices.r < 0.0) discard;\\n vec4 pointPosition = texture(positionsTexture, (trackedPointIndices.rg + 0.5) / pointsTextureSize);\\n\\n fragColor = vec4(pointPosition.rg, 1.0, 1.0);\\n}\\n\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform dragPointUniforms {\\n vec2 mousePos;\\n float index;\\n} dragPoint;\\n\\n#define mousePos dragPoint.mousePos\\n#define index dragPoint.index\\n#else\\nuniform vec2 mousePos;\\nuniform float index;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n\\n // Check if a point is being dragged\\n if (index >= 0.0 && index == pointPosition.b) {\\n pointPosition.rg = mousePos.rg;\\n }\\n\\n fragColor = pointPosition;\\n}\"","/**\n * Creates a texture atlas from an array of ImageData objects.\n *\n * A texture atlas is a single large texture that contains multiple smaller images.\n * This allows efficient rendering by reducing the number of texture bindings needed.\n *\n * The atlas uses a grid layout where each image gets a square region sized to\n * accommodate the largest image dimension. Images are placed left-to-right, top-to-bottom.\n *\n * @param imageDataArray - Array of ImageData objects to pack into the atlas\n * @param webglMaxTextureSize - WebGL maximum texture size limit (default: 16384)\n * @returns Atlas data object containing:\n * - atlasData: RGBA pixel data as Uint8Array\n * - atlasSize: Total atlas texture size in pixels\n * - atlasCoords: UV coordinates for each image as Float32Array\n * - atlasCoordsSize: Grid size (number of rows/columns)\n * Returns null if creation fails or no valid images provided\n */\nexport function createAtlasDataFromImageData (\n imageDataArray: ImageData[],\n webglMaxTextureSize = 16384\n): {\n atlasData: Uint8Array;\n atlasSize: number;\n atlasCoords: Float32Array;\n atlasCoordsSize: number;\n} | null {\n // Step 1: Validate input - ensure we have images to process\n if (!imageDataArray?.length) {\n return null\n }\n\n // Step 2: Find the maximum dimension across all images\n // The max dimension determines the size of each grid cell in the atlas\n let maxDimension = 0\n for (const imageData of imageDataArray) {\n const dimension = Math.max(imageData.width, imageData.height)\n if (dimension > maxDimension) {\n maxDimension = dimension\n }\n }\n\n // Step 3: Validate that we found valid image dimensions\n if (maxDimension === 0) {\n console.warn('Invalid image dimensions: all images have zero width or height')\n return null\n }\n\n const originalMaxDimension = maxDimension\n\n // Step 4: Calculate optimal atlas grid size\n const atlasCoordsSize = Math.ceil(Math.sqrt(imageDataArray.length))\n let atlasSize = atlasCoordsSize * maxDimension\n\n // Step 5: Apply WebGL size limit scaling if necessary\n let scalingFactor = 1.0\n\n if (atlasSize > webglMaxTextureSize) {\n // Calculate required scale to fit within WebGL limits\n scalingFactor = webglMaxTextureSize / atlasSize\n\n // Apply scaling to both the individual image dimensions and atlas size\n maxDimension = Math.max(1, Math.floor(maxDimension * scalingFactor))\n atlasSize = Math.max(1, Math.floor(atlasSize * scalingFactor))\n\n console.warn(\n '🖼️ Atlas scaling required: Original size ' +\n `${(originalMaxDimension * atlasCoordsSize).toLocaleString()}px exceeds WebGL limit ` +\n `${webglMaxTextureSize.toLocaleString()}px. Scaling down to ${atlasSize.toLocaleString()}px ` +\n `(${Math.round(scalingFactor * 100)}% of original quality)`\n )\n }\n\n // Step 6: Create buffers for atlas data\n const atlasData = new Uint8Array(atlasSize * atlasSize * 4).fill(0)\n const atlasCoords = new Float32Array(atlasCoordsSize * atlasCoordsSize * 4).fill(-1)\n\n // Step 7: Pack each image into the atlas grid\n for (const [index, imageData] of imageDataArray.entries()) {\n const originalWidth = imageData.width\n const originalHeight = imageData.height\n if (originalWidth === 0 || originalHeight === 0) {\n // leave coords at -1 for this index and continue\n continue\n }\n\n // Calculate individual scale for this image based on maxDimension\n // This ensures each image fits optimally within its grid cell\n const individualScale = Math.min(1.0, maxDimension / Math.max(originalWidth, originalHeight))\n\n const scaledWidth = Math.floor(originalWidth * individualScale)\n const scaledHeight = Math.floor(originalHeight * individualScale)\n\n // Calculate grid position (row, column) for this image\n const row = Math.floor(index / atlasCoordsSize)\n const col = index % atlasCoordsSize\n\n // Calculate pixel position in the atlas texture\n const atlasX = col * maxDimension\n const atlasY = row * maxDimension\n\n // Calculate and store UV coordinates for this image\n atlasCoords[index * 4] = atlasX / atlasSize // minU\n atlasCoords[index * 4 + 1] = atlasY / atlasSize // minV\n atlasCoords[index * 4 + 2] = (atlasX + scaledWidth) / atlasSize // maxU\n atlasCoords[index * 4 + 3] = (atlasY + scaledHeight) / atlasSize // maxV\n\n // Copy image pixel data into the atlas texture\n for (let y = 0; y < scaledHeight; y++) {\n for (let x = 0; x < scaledWidth; x++) {\n // Calculate source pixel coordinates (with scaling)\n const srcX = Math.floor(x * (originalWidth / scaledWidth))\n const srcY = Math.floor(y * (originalHeight / scaledHeight))\n\n // Calculate source pixel index in the original image\n const srcIndex = (srcY * originalWidth + srcX) * 4\n\n // Calculate target pixel index in the atlas texture\n const atlasIndex = ((atlasY + y) * atlasSize + (atlasX + x)) * 4\n\n // Copy RGBA values from source to atlas\n atlasData[atlasIndex] = imageData.data[srcIndex] ?? 0 // Red channel\n atlasData[atlasIndex + 1] = imageData.data[srcIndex + 1] ?? 0 // Green channel\n atlasData[atlasIndex + 2] = imageData.data[srcIndex + 2] ?? 0 // Blue channel\n atlasData[atlasIndex + 3] = imageData.data[srcIndex + 3] ?? 255 // Alpha channel\n }\n }\n }\n\n // Return the complete atlas data\n return {\n atlasData,\n atlasSize,\n atlasCoords,\n atlasCoordsSize,\n }\n}\n","import { Framebuffer, Buffer, Texture, UniformStore, RenderPass } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\n// import { scaleLinear } from 'd3-scale'\n// import { extent } from 'd3-array'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport type { Mat4Array } from '@/graph/modules/Store'\nimport { defaultConfigValues } from '@/graph/variables'\nimport drawPointsFrag from '@/graph/modules/Points/draw-points.frag?raw'\nimport drawPointsVert from '@/graph/modules/Points/draw-points.vert?raw'\nimport findPointsOnAreaSelectionFrag from '@/graph/modules/Points/find-points-on-area-selection.frag?raw'\nimport findPointsOnPolygonSelectionFrag from '@/graph/modules/Points/find-points-on-polygon-selection.frag?raw'\nimport drawHighlightedFrag from '@/graph/modules/Points/draw-highlighted.frag?raw'\nimport drawHighlightedVert from '@/graph/modules/Points/draw-highlighted.vert?raw'\nimport findHoveredPointFrag from '@/graph/modules/Points/find-hovered-point.frag?raw'\nimport findHoveredPointVert from '@/graph/modules/Points/find-hovered-point.vert?raw'\nimport fillGridWithSampledPointsFrag from '@/graph/modules/Points/fill-sampled-points.frag?raw'\nimport fillGridWithSampledPointsVert from '@/graph/modules/Points/fill-sampled-points.vert?raw'\nimport updatePositionFrag from '@/graph/modules/Points/update-position.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport trackPositionsFrag from '@/graph/modules/Points/track-positions.frag?raw'\nimport dragPointFrag from '@/graph/modules/Points/drag-point.frag?raw'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\nimport { readPixels } from '@/graph/helper'\nimport { ensureVec2, ensureVec4 } from '@/graph/modules/Shared/uniform-utils'\nimport { createAtlasDataFromImageData } from '@/graph/modules/Points/atlas-utils'\n\nexport class Points extends CoreModule {\n public currentPositionFbo: Framebuffer | undefined\n public previousPositionFbo: Framebuffer | undefined\n public velocityFbo: Framebuffer | undefined\n public selectedFbo: Framebuffer | undefined\n public hoveredFbo: Framebuffer | undefined\n public scaleX: ((x: number) => number) | undefined\n public scaleY: ((y: number) => number) | undefined\n public shouldSkipRescale: boolean | undefined\n public imageAtlasTexture: Texture | undefined\n public imageCount = 0\n // Add texture properties for position data (public for Clusters module access)\n public currentPositionTexture: Texture | undefined\n public previousPositionTexture: Texture | undefined\n public velocityTexture: Texture | undefined\n // Add texture property for greyout status (public for Lines module access)\n public greyoutStatusTexture: Texture | undefined\n private colorBuffer: Buffer | undefined\n private sizeBuffer: Buffer | undefined\n private shapeBuffer: Buffer | undefined\n private imageIndicesBuffer: Buffer | undefined\n private imageSizesBuffer: Buffer | undefined\n private imageAtlasCoordsTexture: Texture | undefined\n private imageAtlasCoordsTextureSize: number | undefined\n private trackedPositionsFbo: Framebuffer | undefined\n private sampledPointsFbo: Framebuffer | undefined\n private trackedPositions: Map<number, [number, number]> | undefined\n private isPositionsUpToDate = false\n private drawCommand: Model | undefined\n private drawHighlightedCommand: Model | undefined\n private updatePositionCommand: Model | undefined\n private dragPointCommand: Model | undefined\n private findPointsOnAreaSelectionCommand: Model | undefined\n private findPointsOnPolygonSelectionCommand: Model | undefined\n private findHoveredPointCommand: Model | undefined\n private fillSampledPointsFboCommand: Model | undefined\n private trackPointsCommand: Model | undefined\n // Vertex buffers for quad rendering (Model doesn't destroy them automatically)\n private updatePositionVertexCoordBuffer: Buffer | undefined\n private dragPointVertexCoordBuffer: Buffer | undefined\n private findPointsOnAreaSelectionVertexCoordBuffer: Buffer | undefined\n private findPointsOnPolygonSelectionVertexCoordBuffer: Buffer | undefined\n private drawHighlightedVertexCoordBuffer: Buffer | undefined\n private trackPointsVertexCoordBuffer: Buffer | undefined\n private trackedIndices: number[] | undefined\n private selectedTexture: Texture | undefined\n private pinnedStatusTexture: Texture | undefined\n private sizeTexture: Texture | undefined\n private trackedIndicesTexture: Texture | undefined\n private polygonPathTexture: Texture | undefined\n private polygonPathLength = 0\n private drawPointIndices: Buffer | undefined\n private hoveredPointIndices: Buffer | undefined\n private sampledPointIndices: Buffer | undefined\n\n // Uniform stores for scalar uniforms\n private updatePositionUniformStore: UniformStore<{\n updatePositionUniforms: {\n friction: number;\n spaceSize: number;\n };\n }> | undefined\n\n private dragPointUniformStore: UniformStore<{\n dragPointUniforms: {\n mousePos: [number, number];\n index: number;\n };\n }> | undefined\n\n private drawUniformStore: UniformStore<{\n drawVertexUniforms: {\n ratio: number;\n sizeScale: number;\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n greyoutColor: [number, number, number, number];\n backgroundColor: [number, number, number, number];\n scalePointsOnZoom: number;\n maxPointSize: number;\n isDarkenGreyout: number;\n skipSelected: number;\n skipUnselected: number;\n hasImages: number;\n imageCount: number;\n imageAtlasCoordsTextureSize: number;\n };\n drawFragmentUniforms: {\n greyoutOpacity: number;\n pointOpacity: number;\n isDarkenGreyout: number;\n backgroundColor: [number, number, number, number];\n };\n }> | undefined\n\n private findPointsOnAreaSelectionUniformStore: UniformStore<{\n findPointsOnAreaSelectionUniforms: {\n spaceSize: number;\n screenSize: [number, number];\n sizeScale: number;\n transformationMatrix: Mat4Array;\n ratio: number;\n selection0: [number, number];\n selection1: [number, number];\n scalePointsOnZoom: number;\n maxPointSize: number;\n };\n }> | undefined\n\n private findPointsOnPolygonSelectionUniformStore: UniformStore<{\n findPointsOnPolygonSelectionUniforms: {\n spaceSize: number;\n screenSize: [number, number];\n transformationMatrix: Mat4Array;\n polygonPathLength: number;\n };\n }> | undefined\n\n private findHoveredPointUniformStore: UniformStore<{\n findHoveredPointUniforms: {\n ratio: number;\n sizeScale: number;\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n scalePointsOnZoom: number;\n mousePosition: [number, number];\n maxPointSize: number;\n skipSelected: number;\n skipUnselected: number;\n };\n }> | undefined\n\n private fillSampledPointsUniformStore: UniformStore<{\n fillSampledPointsUniforms: {\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n };\n }> | undefined\n\n private drawHighlightedUniformStore: UniformStore<{\n drawHighlightedUniforms: {\n color: [number, number, number, number];\n width: number;\n pointIndex: number;\n size: number;\n sizeScale: number;\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n scalePointsOnZoom: number; // f32 in shader, not boolean\n maxPointSize: number;\n universalPointOpacity: number;\n greyoutOpacity: number;\n isDarkenGreyout: number; // f32 in shader, not boolean\n backgroundColor: [number, number, number, number];\n greyoutColor: [number, number, number, number];\n };\n }> | undefined\n\n private trackPointsUniformStore: UniformStore<{\n trackPointsUniforms: {\n pointsTextureSize: number;\n };\n }> | undefined\n\n public updatePositions (): void {\n const { device, store, data, config: { rescalePositions, enableSimulation } } = this\n\n const { pointsTextureSize } = store\n if (!pointsTextureSize || !data.pointPositions || data.pointsNumber === undefined) return\n\n // Create initial state array with exact size needed for RGBA32Float texture\n // Ensure it's a new contiguous buffer (not a view) with the exact size\n const textureDataSize = pointsTextureSize * pointsTextureSize * 4\n const initialState = new Float32Array(textureDataSize)\n\n const expectedBytes = pointsTextureSize * pointsTextureSize * 4 * 4 // width * height * 4 components * 4 bytes\n const actualBytes = initialState.byteLength\n if (actualBytes !== expectedBytes) {\n console.error('Texture data size mismatch:', {\n pointsTextureSize,\n expectedBytes,\n actualBytes,\n textureDataSize,\n dataLength: initialState.length,\n })\n }\n\n let shouldRescale = rescalePositions\n // If rescalePositions isn't specified in config and simulation is disabled, default to true\n if (rescalePositions === undefined && !enableSimulation) shouldRescale = true\n // Skip rescaling if `shouldSkipRescale` flag is set (allowing one-time skip of rescaling)\n // Temporary flag is used to skip rescaling when change point positions or adding new points by function `setPointPositions`\n // This flag overrides any other rescaling settings\n if (this.shouldSkipRescale) shouldRescale = false\n\n if (shouldRescale) {\n this.rescaleInitialNodePositions()\n } else if (!this.shouldSkipRescale) {\n // Only reset scale functions if not temporarily skipping rescale\n this.scaleX = undefined\n this.scaleY = undefined\n }\n\n // Reset temporary flag\n this.shouldSkipRescale = undefined\n\n for (let i = 0; i < data.pointsNumber; ++i) {\n initialState[i * 4 + 0] = data.pointPositions[i * 2 + 0] as number\n initialState[i * 4 + 1] = data.pointPositions[i * 2 + 1] as number\n initialState[i * 4 + 2] = i\n }\n\n // Create currentPositionTexture and framebuffer\n if (!this.currentPositionTexture || this.currentPositionTexture.width !== pointsTextureSize || this.currentPositionTexture.height !== pointsTextureSize) {\n if (this.currentPositionTexture && !this.currentPositionTexture.destroyed) {\n this.currentPositionTexture.destroy()\n }\n if (this.currentPositionFbo && !this.currentPositionFbo.destroyed) {\n this.currentPositionFbo.destroy()\n }\n this.currentPositionTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.currentPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.currentPositionFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.currentPositionTexture],\n })\n } else {\n this.currentPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Create previousPositionTexture and framebuffer\n if (!this.previousPositionTexture ||\n this.previousPositionTexture.width !== pointsTextureSize ||\n this.previousPositionTexture.height !== pointsTextureSize) {\n if (this.previousPositionTexture && !this.previousPositionTexture.destroyed) {\n this.previousPositionTexture.destroy()\n }\n if (this.previousPositionFbo && !this.previousPositionFbo.destroyed) {\n this.previousPositionFbo.destroy()\n }\n this.previousPositionTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.previousPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.previousPositionFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.previousPositionTexture],\n })\n } else {\n this.previousPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n if (this.config.enableSimulation) {\n // Create velocityTexture and framebuffer\n const velocityData = new Float32Array(pointsTextureSize * pointsTextureSize * 4).fill(0)\n if (!this.velocityTexture || this.velocityTexture.width !== pointsTextureSize || this.velocityTexture.height !== pointsTextureSize) {\n if (this.velocityTexture && !this.velocityTexture.destroyed) {\n this.velocityTexture.destroy()\n }\n if (this.velocityFbo && !this.velocityFbo.destroyed) {\n this.velocityFbo.destroy()\n }\n this.velocityTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.velocityTexture.copyImageData({\n data: velocityData,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.velocityFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.velocityTexture],\n })\n } else {\n this.velocityTexture.copyImageData({\n data: velocityData,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n // Create selectedTexture and framebuffer\n if (!this.selectedTexture || this.selectedTexture.width !== pointsTextureSize || this.selectedTexture.height !== pointsTextureSize) {\n if (this.selectedTexture && !this.selectedTexture.destroyed) {\n this.selectedTexture.destroy()\n }\n if (this.selectedFbo && !this.selectedFbo.destroyed) {\n this.selectedFbo.destroy()\n }\n this.selectedTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.selectedTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.selectedFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.selectedTexture],\n })\n } else {\n this.selectedTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Create hoveredFbo (2x2 for hover detection)\n this.hoveredFbo ||= device.createFramebuffer({\n width: 2,\n height: 2,\n colorAttachments: ['rgba32float'],\n })\n\n // Create buffers\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n const requiredByteLength = indexData.byteLength\n\n if (!this.drawPointIndices || this.drawPointIndices.byteLength !== requiredByteLength) {\n if (this.drawPointIndices && !this.drawPointIndices.destroyed) {\n this.drawPointIndices.destroy()\n }\n this.drawPointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.drawPointIndices.write(indexData)\n }\n\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n pointIndices: this.drawPointIndices,\n })\n }\n\n if (!this.hoveredPointIndices || this.hoveredPointIndices.byteLength !== requiredByteLength) {\n if (this.hoveredPointIndices && !this.hoveredPointIndices.destroyed) {\n this.hoveredPointIndices.destroy()\n }\n this.hoveredPointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.hoveredPointIndices.write(indexData)\n }\n\n if (!this.sampledPointIndices || this.sampledPointIndices.byteLength !== requiredByteLength) {\n if (this.sampledPointIndices && !this.sampledPointIndices.destroyed) {\n this.sampledPointIndices.destroy()\n }\n this.sampledPointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.sampledPointIndices.write(indexData)\n }\n if (this.fillSampledPointsFboCommand) {\n this.fillSampledPointsFboCommand.setAttributes({\n pointIndices: this.sampledPointIndices,\n })\n }\n\n this.updateGreyoutStatus()\n this.updatePinnedStatus()\n this.updateSampledPointsGrid()\n\n this.trackPointsByIndices()\n }\n\n public initPrograms (): void {\n const { device, config, store, data } = this\n // Ensure textures are created before Model initialization\n if (!this.imageAtlasCoordsTexture || !this.imageAtlasTexture) {\n this.createAtlas()\n }\n // Ensure buffers exist before Model creation (Model needs attributes at creation time)\n if (!this.colorBuffer) this.updateColor()\n if (!this.sizeBuffer) this.updateSize()\n if (!this.shapeBuffer) this.updateShape()\n if (!this.imageIndicesBuffer) this.updateImageIndices()\n if (!this.imageSizesBuffer) this.updateImageSizes()\n if (!this.greyoutStatusTexture) this.updateGreyoutStatus()\n if (config.enableSimulation) {\n // Create vertex buffer for quad\n this.updatePositionVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for updatePosition uniforms\n this.updatePositionUniformStore ||= new UniformStore({\n updatePositionUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n friction: 'f32',\n spaceSize: 'f32',\n },\n defaultUniforms: {\n friction: config.simulationFriction ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n },\n },\n })\n\n this.updatePositionCommand ||= new Model(device, {\n fs: updatePositionFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.updatePositionVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n updatePositionUniforms: this.updatePositionUniformStore.getManagedUniformBuffer(device, 'updatePositionUniforms'),\n // All texture bindings will be set dynamically in updatePosition() method\n },\n })\n }\n\n // Create vertex buffer for quad\n this.dragPointVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for dragPoint uniforms\n this.dragPointUniformStore ||= new UniformStore({\n dragPointUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n mousePos: 'vec2<f32>',\n index: 'f32',\n },\n defaultUniforms: {\n mousePos: ensureVec2(store.mousePosition, [0, 0]),\n index: store.hoveredPoint?.index ?? -1,\n },\n },\n })\n\n this.dragPointCommand ||= new Model(device, {\n fs: dragPointFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.dragPointVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n dragPointUniforms: this.dragPointUniformStore.getManagedUniformBuffer(device, 'dragPointUniforms'),\n // All texture bindings will be set dynamically in drag() method\n },\n })\n\n // Create UniformStore for draw uniforms\n this.drawUniformStore ||= new UniformStore({\n drawVertexUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n ratio: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n pointsTextureSize: 'f32',\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n greyoutColor: 'vec4<f32>',\n backgroundColor: 'vec4<f32>',\n scalePointsOnZoom: 'f32',\n maxPointSize: 'f32',\n isDarkenGreyout: 'f32',\n skipSelected: 'f32',\n skipUnselected: 'f32',\n hasImages: 'f32',\n imageCount: 'f32',\n imageAtlasCoordsTextureSize: 'f32',\n },\n defaultUniforms: {\n // Order MUST match uniformTypes and shader declaration\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: ((): Mat4Array => {\n const t = store.transform ?? [1, 0, 0, 0, 1, 0, 0, 0, 1]\n return [\n t[0], t[1], t[2], 0,\n t[3], t[4], t[5], 0,\n t[6], t[7], t[8], 0,\n 0, 0, 0, 1,\n ]\n })(),\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0, // Convert boolean to float\n maxPointSize: store.maxPointSize ?? 100,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n skipSelected: 0, // Default to 0 (false)\n skipUnselected: 0, // Default to 0 (false)\n hasImages: (this.imageCount > 0) ? 1 : 0, // Convert boolean to float\n imageCount: this.imageCount,\n imageAtlasCoordsTextureSize: this.imageAtlasCoordsTextureSize ?? 0,\n },\n },\n drawFragmentUniforms: {\n uniformTypes: {\n greyoutOpacity: 'f32',\n pointOpacity: 'f32',\n isDarkenGreyout: 'f32',\n backgroundColor: 'vec4<f32>',\n },\n defaultUniforms: {\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n pointOpacity: config.pointOpacity ?? 1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n },\n },\n })\n\n this.drawCommand ||= new Model(device, {\n fs: drawPointsFrag,\n vs: drawPointsVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...(this.drawPointIndices && { pointIndices: this.drawPointIndices }),\n ...(this.sizeBuffer && { size: this.sizeBuffer }),\n ...(this.colorBuffer && { color: this.colorBuffer }),\n ...(this.shapeBuffer && { shape: this.shapeBuffer }),\n ...(this.imageIndicesBuffer && { imageIndex: this.imageIndicesBuffer }),\n ...(this.imageSizesBuffer && { imageSize: this.imageSizesBuffer }),\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n { name: 'size', format: 'float32' },\n { name: 'color', format: 'float32x4' },\n { name: 'shape', format: 'float32' },\n { name: 'imageIndex', format: 'float32' },\n { name: 'imageSize', format: 'float32' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n drawVertexUniforms: this.drawUniformStore.getManagedUniformBuffer(device, 'drawVertexUniforms'),\n drawFragmentUniforms: this.drawUniformStore.getManagedUniformBuffer(device, 'drawFragmentUniforms'),\n // All texture bindings will be set dynamically in draw() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Create vertex buffer for quad\n this.findPointsOnAreaSelectionVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for findPointsOnAreaSelection uniforms\n this.findPointsOnAreaSelectionUniformStore ||= new UniformStore({\n findPointsOnAreaSelectionUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n ratio: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n selection0: 'vec2<f32>',\n selection1: 'vec2<f32>',\n scalePointsOnZoom: 'f32',\n maxPointSize: 'f32',\n },\n defaultUniforms: {\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: store.transformationMatrix4x4,\n selection0: ensureVec2(store.selectedArea?.[0], [0, 0]),\n selection1: ensureVec2(store.selectedArea?.[1], [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n },\n },\n })\n\n this.findPointsOnAreaSelectionCommand ||= new Model(device, {\n fs: findPointsOnAreaSelectionFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.findPointsOnAreaSelectionVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n findPointsOnAreaSelectionUniforms: this.findPointsOnAreaSelectionUniformStore.getManagedUniformBuffer(device, 'findPointsOnAreaSelectionUniforms'),\n // All texture bindings will be set dynamically in findPointsOnAreaSelection() method\n },\n })\n\n // Create vertex buffer for quad\n this.findPointsOnPolygonSelectionVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for findPointsOnPolygonSelection uniforms\n this.findPointsOnPolygonSelectionUniformStore ||= new UniformStore({\n findPointsOnPolygonSelectionUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n transformationMatrix: 'mat4x4<f32>',\n polygonPathLength: 'f32',\n },\n defaultUniforms: {\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n transformationMatrix: store.transformationMatrix4x4,\n polygonPathLength: this.polygonPathLength,\n },\n },\n })\n\n this.findPointsOnPolygonSelectionCommand ||= new Model(device, {\n fs: findPointsOnPolygonSelectionFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.findPointsOnPolygonSelectionVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n findPointsOnPolygonSelectionUniforms: this.findPointsOnPolygonSelectionUniformStore\n .getManagedUniformBuffer(device, 'findPointsOnPolygonSelectionUniforms'),\n // All texture bindings will be set dynamically in findPointsOnPolygonSelection() method\n },\n })\n\n // Create UniformStore for findHoveredPoint uniforms\n this.findHoveredPointUniformStore ||= new UniformStore({\n findHoveredPointUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n pointsTextureSize: 'f32',\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n ratio: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n mousePosition: 'vec2<f32>',\n scalePointsOnZoom: 'f32',\n maxPointSize: 'f32',\n skipSelected: 'f32',\n skipUnselected: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: store.transformationMatrix4x4,\n mousePosition: ensureVec2(store.screenMousePosition, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n skipSelected: 0,\n skipUnselected: 0,\n },\n },\n })\n\n this.findHoveredPointCommand ||= new Model(device, {\n fs: findHoveredPointFrag,\n vs: findHoveredPointVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...(this.hoveredPointIndices && { pointIndices: this.hoveredPointIndices }),\n ...(this.sizeBuffer && { size: this.sizeBuffer }),\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n { name: 'size', format: 'float32' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n findHoveredPointUniforms: this.findHoveredPointUniformStore.getManagedUniformBuffer(device, 'findHoveredPointUniforms'),\n // All texture bindings will be set dynamically in findHoveredPoint() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n blend: false, // Disable blending - we want to overwrite, not blend\n },\n })\n\n // Create UniformStore for fillSampledPoints uniforms\n this.fillSampledPointsUniformStore ||= new UniformStore({\n fillSampledPointsUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n pointsTextureSize: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n transformationMatrix: store.transformationMatrix4x4,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n },\n },\n })\n\n this.fillSampledPointsFboCommand ||= new Model(device, {\n fs: fillGridWithSampledPointsFrag,\n vs: fillGridWithSampledPointsVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...(this.sampledPointIndices && { pointIndices: this.sampledPointIndices }),\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n fillSampledPointsUniforms: this.fillSampledPointsUniformStore.getManagedUniformBuffer(device, 'fillSampledPointsUniforms'),\n // All texture bindings will be set dynamically in getSampledPointPositionsMap() and getSampledPoints() methods\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n this.drawHighlightedVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.drawHighlightedUniformStore ||= new UniformStore({\n drawHighlightedUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n // Vertex shader uniforms:\n size: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n pointsTextureSize: 'f32',\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n scalePointsOnZoom: 'f32',\n pointIndex: 'f32',\n maxPointSize: 'f32',\n color: 'vec4<f32>',\n universalPointOpacity: 'f32',\n greyoutOpacity: 'f32',\n isDarkenGreyout: 'f32',\n backgroundColor: 'vec4<f32>',\n greyoutColor: 'vec4<f32>',\n // Fragment shader uniforms (width is in same block):\n width: 'f32',\n },\n defaultUniforms: {\n size: 1,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n pointIndex: -1,\n maxPointSize: store.maxPointSize ?? 100,\n color: [0, 0, 0, 1],\n universalPointOpacity: config.pointOpacity ?? 1,\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0,\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n width: 0.85,\n },\n },\n })\n\n this.drawHighlightedCommand ||= new Model(device, {\n fs: drawHighlightedFrag,\n vs: drawHighlightedVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.drawHighlightedVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n drawHighlightedUniforms: this.drawHighlightedUniformStore.getManagedUniformBuffer(device, 'drawHighlightedUniforms'),\n // All texture bindings will be set dynamically in draw() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Create vertex buffer for quad\n this.trackPointsVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for trackPoints uniforms\n this.trackPointsUniformStore ||= new UniformStore({\n trackPointsUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n pointsTextureSize: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n },\n },\n })\n\n this.trackPointsCommand ||= new Model(device, {\n fs: trackPositionsFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.trackPointsVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n trackPointsUniforms: this.trackPointsUniformStore.getManagedUniformBuffer(device, 'trackPointsUniforms'),\n // All texture bindings will be set dynamically in trackPoints() method\n },\n })\n }\n\n public updateColor (): void {\n const { device, store: { pointsTextureSize }, data } = this\n if (!pointsTextureSize) return\n\n const colorData = data.pointColors as Float32Array\n const requiredByteLength = colorData.byteLength\n\n if (!this.colorBuffer || this.colorBuffer.byteLength !== requiredByteLength) {\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = device.createBuffer({\n data: colorData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.colorBuffer.write(colorData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n color: this.colorBuffer,\n })\n }\n }\n\n public updateGreyoutStatus (): void {\n const { device, store: { selectedIndices, pointsTextureSize } } = this\n if (!pointsTextureSize) return\n\n // Greyout status: 0 - false, highlighted or normal point; 1 - true, greyout point\n const initialState = new Float32Array(pointsTextureSize * pointsTextureSize * 4)\n .fill(selectedIndices ? 1 : 0)\n\n if (selectedIndices) {\n for (const selectedIndex of selectedIndices) {\n initialState[selectedIndex * 4] = 0\n }\n }\n\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.width !== pointsTextureSize || this.greyoutStatusTexture.height !== pointsTextureSize) {\n if (this.greyoutStatusTexture && !this.greyoutStatusTexture.destroyed) {\n this.greyoutStatusTexture.destroy()\n }\n this.greyoutStatusTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.greyoutStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.greyoutStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public updatePinnedStatus (): void {\n const { device, store: { pointsTextureSize }, data } = this\n if (!pointsTextureSize) return\n\n // Pinned status: 0 - not pinned, 1 - pinned\n const initialState = new Float32Array(pointsTextureSize * pointsTextureSize * 4).fill(0)\n\n if (data.inputPinnedPoints && data.pointsNumber !== undefined) {\n for (const pinnedIndex of data.inputPinnedPoints) {\n if (pinnedIndex >= 0 && pinnedIndex < data.pointsNumber) {\n initialState[pinnedIndex * 4] = 1\n }\n }\n }\n\n if (!this.pinnedStatusTexture || this.pinnedStatusTexture.width !== pointsTextureSize || this.pinnedStatusTexture.height !== pointsTextureSize) {\n if (this.pinnedStatusTexture && !this.pinnedStatusTexture.destroyed) {\n this.pinnedStatusTexture.destroy()\n }\n this.pinnedStatusTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.pinnedStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.pinnedStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public updateSize (): void {\n const { device, store: { pointsTextureSize }, data } = this\n if (!pointsTextureSize || data.pointsNumber === undefined || data.pointSizes === undefined) return\n\n const sizeData = data.pointSizes\n const requiredByteLength = sizeData.byteLength\n\n if (!this.sizeBuffer || this.sizeBuffer.byteLength !== requiredByteLength) {\n if (this.sizeBuffer && !this.sizeBuffer.destroyed) {\n this.sizeBuffer.destroy()\n }\n this.sizeBuffer = device.createBuffer({\n data: sizeData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.sizeBuffer.write(sizeData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n size: this.sizeBuffer,\n })\n }\n\n const initialState = new Float32Array(pointsTextureSize * pointsTextureSize * 4)\n for (let i = 0; i < data.pointsNumber; i++) {\n initialState[i * 4] = data.pointSizes[i] as number\n }\n\n if (!this.sizeTexture || this.sizeTexture.width !== pointsTextureSize || this.sizeTexture.height !== pointsTextureSize) {\n if (this.sizeTexture && !this.sizeTexture.destroyed) {\n this.sizeTexture.destroy()\n }\n this.sizeTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.sizeTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.sizeTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public updateShape (): void {\n const { device, data } = this\n if (data.pointsNumber === undefined || data.pointShapes === undefined) return\n\n const shapeData = data.pointShapes\n const requiredByteLength = shapeData.byteLength\n\n if (!this.shapeBuffer || this.shapeBuffer.byteLength !== requiredByteLength) {\n if (this.shapeBuffer && !this.shapeBuffer.destroyed) {\n this.shapeBuffer.destroy()\n }\n this.shapeBuffer = device.createBuffer({\n data: shapeData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.shapeBuffer.write(shapeData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n shape: this.shapeBuffer,\n })\n }\n }\n\n public updateImageIndices (): void {\n const { device, data } = this\n if (data.pointsNumber === undefined || data.pointImageIndices === undefined) return\n\n const imageIndicesData = data.pointImageIndices\n const requiredByteLength = imageIndicesData.byteLength\n\n if (!this.imageIndicesBuffer || this.imageIndicesBuffer.byteLength !== requiredByteLength) {\n if (this.imageIndicesBuffer && !this.imageIndicesBuffer.destroyed) {\n this.imageIndicesBuffer.destroy()\n }\n this.imageIndicesBuffer = device.createBuffer({\n data: imageIndicesData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.imageIndicesBuffer.write(imageIndicesData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n imageIndex: this.imageIndicesBuffer,\n })\n }\n }\n\n public updateImageSizes (): void {\n const { device, data } = this\n if (data.pointsNumber === undefined || data.pointImageSizes === undefined) return\n\n const imageSizesData = data.pointImageSizes\n const requiredByteLength = imageSizesData.byteLength\n\n if (!this.imageSizesBuffer || this.imageSizesBuffer.byteLength !== requiredByteLength) {\n if (this.imageSizesBuffer && !this.imageSizesBuffer.destroyed) {\n this.imageSizesBuffer.destroy()\n }\n this.imageSizesBuffer = device.createBuffer({\n data: imageSizesData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.imageSizesBuffer.write(imageSizesData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n imageSize: this.imageSizesBuffer,\n })\n }\n }\n\n public createAtlas (): void {\n const { device, data, store } = this\n\n if (!data.inputImageData?.length) {\n this.imageCount = 0\n this.imageAtlasCoordsTextureSize = 0\n // Create dummy textures so bindings are always available\n this.imageAtlasCoordsTexture ||= device.createTexture({\n data: new Float32Array(4).fill(0),\n width: 1,\n height: 1,\n format: 'rgba32float',\n })\n\n this.imageAtlasTexture ||= device.createTexture({\n data: new Uint8Array(4).fill(0),\n width: 1,\n height: 1,\n format: 'rgba8unorm',\n })\n\n return\n }\n\n const atlasResult = createAtlasDataFromImageData(data.inputImageData, store.webglMaxTextureSize)\n if (!atlasResult) {\n console.warn('Failed to create atlas from image data')\n return\n }\n\n this.imageCount = data.inputImageData.length\n const { atlasData, atlasSize, atlasCoords, atlasCoordsSize } = atlasResult\n this.imageAtlasCoordsTextureSize = atlasCoordsSize\n\n // Recreate atlas texture to avoid row-stride/format issues\n if (this.imageAtlasTexture && !this.imageAtlasTexture.destroyed) {\n this.imageAtlasTexture.destroy()\n }\n this.imageAtlasTexture = device.createTexture({\n width: atlasSize,\n height: atlasSize,\n format: 'rgba8unorm',\n })\n this.imageAtlasTexture.copyImageData({\n data: atlasData,\n bytesPerRow: getBytesPerRow('rgba8unorm', atlasSize),\n rowsPerImage: atlasSize,\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Recreate coords texture\n if (this.imageAtlasCoordsTexture && !this.imageAtlasCoordsTexture.destroyed) {\n this.imageAtlasCoordsTexture.destroy()\n }\n this.imageAtlasCoordsTexture = device.createTexture({\n width: atlasCoordsSize,\n height: atlasCoordsSize,\n format: 'rgba32float',\n })\n this.imageAtlasCoordsTexture.copyImageData({\n data: atlasCoords,\n bytesPerRow: getBytesPerRow('rgba32float', atlasCoordsSize),\n rowsPerImage: atlasCoordsSize,\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n public updateSampledPointsGrid (): void {\n const { store: { screenSize }, config: { pointSamplingDistance }, device } = this\n let dist = pointSamplingDistance ?? Math.min(...screenSize) / 2\n if (dist === 0) dist = defaultConfigValues.pointSamplingDistance\n const w = Math.ceil(screenSize[0] / dist)\n const h = Math.ceil(screenSize[1] / dist)\n\n if (!this.sampledPointsFbo || this.sampledPointsFbo.width !== w || this.sampledPointsFbo.height !== h) {\n if (this.sampledPointsFbo && !this.sampledPointsFbo.destroyed) {\n this.sampledPointsFbo.destroy()\n }\n this.sampledPointsFbo = device.createFramebuffer({\n width: w,\n height: h,\n colorAttachments: ['rgba32float'],\n })\n }\n }\n\n public trackPoints (): void {\n if (!this.trackedIndices?.length || !this.trackPointsCommand || !this.trackPointsUniformStore ||\n !this.trackedPositionsFbo || this.trackedPositionsFbo.destroyed) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.trackedIndicesTexture || this.trackedIndicesTexture.destroyed) return\n\n this.trackPointsUniformStore.setUniforms({\n trackPointsUniforms: {\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.trackPointsCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n trackedIndices: this.trackedIndicesTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.trackedPositionsFbo,\n })\n this.trackPointsCommand.draw(renderPass)\n renderPass.end()\n }\n\n public draw (renderPass: RenderPass): void {\n const { data, config, store } = this\n if (!this.colorBuffer) this.updateColor()\n if (!this.sizeBuffer) this.updateSize()\n if (!this.shapeBuffer) this.updateShape()\n if (!this.imageIndicesBuffer) this.updateImageIndices()\n if (!this.imageSizesBuffer) this.updateImageSizes()\n\n if (!this.drawCommand || !this.drawUniformStore) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n if (!this.imageAtlasTexture || !this.imageAtlasCoordsTexture) {\n this.createAtlas()\n if (!this.imageAtlasTexture || !this.imageAtlasCoordsTexture) return\n }\n if (this.imageAtlasTexture.destroyed || this.imageAtlasCoordsTexture.destroyed) return\n\n // Check if we have points to draw\n if (!data.pointsNumber || data.pointsNumber === 0) {\n return\n }\n\n // Verify canvas is sized (screenSize must be non-zero to avoid division by zero in shader)\n if (!store.screenSize || store.screenSize[0] === 0 || store.screenSize[1] === 0) {\n return\n }\n\n // Update vertex count dynamically\n this.drawCommand.setVertexCount(data.pointsNumber)\n\n // Base uniforms that don't change between layers\n // Convert booleans to floats (1.0 or 0.0) since uniform type is 'f32'\n const baseVertexUniforms = {\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [-1, -1, -1, -1]),\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0, // Convert boolean to float\n maxPointSize: store.maxPointSize ?? 100,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n hasImages: (this.imageCount > 0) ? 1 : 0, // Convert boolean to float\n imageCount: this.imageCount,\n imageAtlasCoordsTextureSize: this.imageAtlasCoordsTextureSize ?? 0,\n }\n\n const baseFragmentUniforms = {\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n pointOpacity: config.pointOpacity ?? 1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n }\n\n // Render in layers: unselected points first (behind), then selected points (in front)\n if (store.selectedIndices && store.selectedIndices.length > 0) {\n // First draw unselected points (they will appear behind)\n this.drawUniformStore.setUniforms({\n drawVertexUniforms: {\n ...baseVertexUniforms,\n skipSelected: 1, // Skip selected points (1.0 for true)\n skipUnselected: 0, // Draw unselected points (0.0 for false)\n },\n drawFragmentUniforms: baseFragmentUniforms,\n })\n\n // Update texture bindings dynamically\n this.drawCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n imageAtlasTexture: this.imageAtlasTexture,\n imageAtlasCoords: this.imageAtlasCoordsTexture,\n })\n\n this.drawCommand.draw(renderPass)\n\n // Then draw selected points (they will appear in front)\n this.drawUniformStore.setUniforms({\n drawVertexUniforms: {\n ...baseVertexUniforms,\n skipSelected: 0, // Draw selected points (0.0 for false)\n skipUnselected: 1, // Skip unselected points (1.0 for true)\n },\n drawFragmentUniforms: baseFragmentUniforms,\n })\n\n // Update texture bindings dynamically\n this.drawCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n imageAtlasTexture: this.imageAtlasTexture,\n imageAtlasCoords: this.imageAtlasCoordsTexture,\n })\n\n this.drawCommand.draw(renderPass)\n } else {\n // If no selection, draw all points\n this.drawUniformStore.setUniforms({\n drawVertexUniforms: {\n ...baseVertexUniforms,\n skipSelected: 0, // Draw all points (0.0 for false)\n skipUnselected: 0, // Draw all points (0.0 for false)\n },\n drawFragmentUniforms: baseFragmentUniforms,\n })\n\n // Update texture bindings dynamically\n this.drawCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n imageAtlasTexture: this.imageAtlasTexture,\n imageAtlasCoords: this.imageAtlasCoordsTexture,\n })\n\n this.drawCommand.draw(renderPass)\n }\n\n // Draw highlighted point rings if enabled\n if (config.renderHoveredPointRing && store.hoveredPoint && this.drawHighlightedCommand && this.drawHighlightedUniformStore) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n const pointSize = data.pointSizes?.[store.hoveredPoint.index] ?? 1\n this.drawHighlightedUniformStore.setUniforms({\n drawHighlightedUniforms: {\n size: pointSize,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n pointIndex: store.hoveredPoint.index,\n maxPointSize: store.maxPointSize ?? 100,\n color: ensureVec4(store.hoveredPointRingColor, [0, 0, 0, 1]),\n universalPointOpacity: config.pointOpacity ?? 1,\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0,\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n width: 0.85,\n },\n })\n // Update texture bindings dynamically\n this.drawHighlightedCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatusTexture: this.greyoutStatusTexture,\n })\n this.drawHighlightedCommand.draw(renderPass)\n }\n\n if (store.focusedPoint && this.drawHighlightedCommand && this.drawHighlightedUniformStore) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n const pointSize = data.pointSizes?.[store.focusedPoint.index] ?? 1\n this.drawHighlightedUniformStore.setUniforms({\n drawHighlightedUniforms: {\n size: pointSize,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n pointIndex: store.focusedPoint.index,\n maxPointSize: store.maxPointSize ?? 100,\n color: ensureVec4(store.focusedPointRingColor, [0, 0, 0, 1]),\n universalPointOpacity: config.pointOpacity ?? 1,\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0,\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n width: 0.85,\n },\n })\n // Update texture bindings dynamically\n this.drawHighlightedCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatusTexture: this.greyoutStatusTexture,\n })\n this.drawHighlightedCommand.draw(renderPass)\n }\n }\n\n public updatePosition (): void {\n if (!this.updatePositionCommand || !this.updatePositionUniformStore || !this.currentPositionFbo || this.currentPositionFbo.destroyed) return\n if (!this.previousPositionTexture || this.previousPositionTexture.destroyed) return\n if (!this.velocityTexture || this.velocityTexture.destroyed) return\n if (!this.pinnedStatusTexture || this.pinnedStatusTexture.destroyed) return\n\n this.updatePositionUniformStore.setUniforms({\n updatePositionUniforms: {\n friction: this.config.simulationFriction ?? 0,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.updatePositionCommand.setBindings({\n positionsTexture: this.previousPositionTexture,\n velocity: this.velocityTexture,\n pinnedStatusTexture: this.pinnedStatusTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.currentPositionFbo,\n })\n this.updatePositionCommand.draw(renderPass)\n renderPass.end()\n\n this.swapFbo()\n // Invalidate tracked positions cache since positions have changed\n this.isPositionsUpToDate = false\n }\n\n public drag (): void {\n if (!this.dragPointCommand || !this.dragPointUniformStore || !this.currentPositionFbo || this.currentPositionFbo.destroyed) return\n if (!this.previousPositionTexture || this.previousPositionTexture.destroyed) return\n\n this.dragPointUniformStore.setUniforms({\n dragPointUniforms: {\n mousePos: ensureVec2(this.store.mousePosition, [0, 0]),\n index: this.store.hoveredPoint?.index ?? -1,\n },\n })\n\n // Update texture bindings dynamically\n this.dragPointCommand.setBindings({\n positionsTexture: this.previousPositionTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.currentPositionFbo,\n })\n this.dragPointCommand.draw(renderPass)\n renderPass.end()\n\n this.swapFbo()\n // Invalidate tracked positions cache since positions have changed\n this.isPositionsUpToDate = false\n }\n\n public findPointsOnAreaSelection (): void {\n if (!this.findPointsOnAreaSelectionCommand || !this.findPointsOnAreaSelectionUniformStore || !this.selectedFbo || this.selectedFbo.destroyed) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.sizeTexture || this.sizeTexture.destroyed) return\n\n this.findPointsOnAreaSelectionUniformStore.setUniforms({\n findPointsOnAreaSelectionUniforms: {\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n sizeScale: this.config.pointSizeScale ?? 1,\n transformationMatrix: this.store.transformationMatrix4x4,\n ratio: this.config.pixelRatio ?? defaultConfigValues.pixelRatio,\n selection0: ensureVec2(this.store.selectedArea?.[0], [0, 0]),\n selection1: ensureVec2(this.store.selectedArea?.[1], [0, 0]),\n scalePointsOnZoom: (this.config.scalePointsOnZoom ?? true) ? 1 : 0, // Convert boolean to number\n maxPointSize: this.store.maxPointSize ?? 100,\n },\n })\n\n // Update texture bindings dynamically\n this.findPointsOnAreaSelectionCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointSize: this.sizeTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.selectedFbo,\n })\n this.findPointsOnAreaSelectionCommand.draw(renderPass)\n renderPass.end()\n }\n\n public findPointsOnPolygonSelection (): void {\n if (!this.findPointsOnPolygonSelectionCommand || !this.findPointsOnPolygonSelectionUniformStore || !this.selectedFbo || this.selectedFbo.destroyed) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.polygonPathTexture || this.polygonPathTexture.destroyed) return\n\n this.findPointsOnPolygonSelectionUniformStore.setUniforms({\n findPointsOnPolygonSelectionUniforms: {\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n transformationMatrix: this.store.transformationMatrix4x4,\n polygonPathLength: this.polygonPathLength,\n },\n })\n\n // Update texture bindings dynamically\n this.findPointsOnPolygonSelectionCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n polygonPathTexture: this.polygonPathTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.selectedFbo,\n })\n this.findPointsOnPolygonSelectionCommand.draw(renderPass)\n renderPass.end()\n }\n\n public updatePolygonPath (polygonPath: [number, number][]): void {\n const { device } = this\n this.polygonPathLength = polygonPath.length\n\n if (polygonPath.length === 0) {\n if (this.polygonPathTexture && !this.polygonPathTexture.destroyed) {\n this.polygonPathTexture.destroy()\n }\n this.polygonPathTexture = undefined\n return\n }\n\n // Calculate texture size (square texture)\n const textureSize = Math.ceil(Math.sqrt(polygonPath.length))\n const textureData = new Float32Array(textureSize * textureSize * 4)\n\n // Fill texture with polygon path points\n for (const [i, point] of polygonPath.entries()) {\n const [x, y] = point\n textureData[i * 4] = x\n textureData[i * 4 + 1] = y\n textureData[i * 4 + 2] = 0 // unused\n textureData[i * 4 + 3] = 0 // unused\n }\n\n if (!this.polygonPathTexture || this.polygonPathTexture.width !== textureSize || this.polygonPathTexture.height !== textureSize) {\n if (this.polygonPathTexture && !this.polygonPathTexture.destroyed) {\n this.polygonPathTexture.destroy()\n }\n this.polygonPathTexture = device.createTexture({\n width: textureSize,\n height: textureSize,\n format: 'rgba32float',\n })\n this.polygonPathTexture.copyImageData({\n data: textureData,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.polygonPathTexture.copyImageData({\n data: textureData,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public findHoveredPoint (): void {\n if (!this.hoveredFbo || this.hoveredFbo.destroyed) return\n\n if (!this.findHoveredPointCommand || !this.findHoveredPointUniformStore) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture) this.updateGreyoutStatus()\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n\n this.findHoveredPointCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.findHoveredPointCommand.setAttributes({\n ...(this.hoveredPointIndices && { pointIndices: this.hoveredPointIndices }),\n ...(this.sizeBuffer && { size: this.sizeBuffer }),\n })\n\n const baseUniforms = {\n ratio: this.config.pixelRatio ?? defaultConfigValues.pixelRatio,\n sizeScale: this.config.pointSizeScale ?? 1,\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n transformationMatrix: this.store.transformationMatrix4x4,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n scalePointsOnZoom: (this.config.scalePointsOnZoom ?? true) ? 1 : 0,\n mousePosition: ensureVec2(this.store.screenMousePosition, [0, 0]),\n maxPointSize: this.store.maxPointSize ?? 100,\n }\n\n const bindings = {\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n }\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.hoveredFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n if (this.store.selectedIndices && this.store.selectedIndices.length > 0) {\n // Same two-pass order as drawing: unselected first, then selected (top-most wins)\n this.findHoveredPointUniformStore.setUniforms({\n findHoveredPointUniforms: {\n ...baseUniforms,\n skipSelected: 1,\n skipUnselected: 0,\n },\n })\n this.findHoveredPointCommand.setBindings(bindings)\n this.findHoveredPointCommand.draw(renderPass)\n\n this.findHoveredPointUniformStore.setUniforms({\n findHoveredPointUniforms: {\n ...baseUniforms,\n skipSelected: 0,\n skipUnselected: 1,\n },\n })\n this.findHoveredPointCommand.setBindings(bindings)\n this.findHoveredPointCommand.draw(renderPass)\n } else {\n this.findHoveredPointUniformStore.setUniforms({\n findHoveredPointUniforms: {\n ...baseUniforms,\n skipSelected: 0,\n skipUnselected: 0,\n },\n })\n this.findHoveredPointCommand.setBindings(bindings)\n this.findHoveredPointCommand.draw(renderPass)\n }\n\n renderPass.end()\n }\n\n public trackPointsByIndices (indices?: number[] | undefined): void {\n const { store: { pointsTextureSize }, device } = this\n this.trackedIndices = indices\n\n // Clear cache when changing tracked indices\n this.trackedPositions = undefined\n this.isPositionsUpToDate = false\n\n if (!indices?.length || !pointsTextureSize) return\n const textureSize = Math.ceil(Math.sqrt(indices.length))\n\n const initialState = new Float32Array(textureSize * textureSize * 4).fill(-1)\n for (const [i, sortedIndex] of indices.entries()) {\n if (sortedIndex !== undefined) {\n initialState[i * 4] = sortedIndex % pointsTextureSize\n initialState[i * 4 + 1] = Math.floor(sortedIndex / pointsTextureSize)\n initialState[i * 4 + 2] = 0\n initialState[i * 4 + 3] = 0\n }\n }\n\n if (!this.trackedIndicesTexture || this.trackedIndicesTexture.width !== textureSize || this.trackedIndicesTexture.height !== textureSize) {\n if (this.trackedIndicesTexture && !this.trackedIndicesTexture.destroyed) {\n this.trackedIndicesTexture.destroy()\n }\n this.trackedIndicesTexture = device.createTexture({\n width: textureSize,\n height: textureSize,\n format: 'rgba32float',\n })\n this.trackedIndicesTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.trackedIndicesTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n if (!this.trackedPositionsFbo || this.trackedPositionsFbo.width !== textureSize || this.trackedPositionsFbo.height !== textureSize) {\n if (this.trackedPositionsFbo && !this.trackedPositionsFbo.destroyed) {\n this.trackedPositionsFbo.destroy()\n }\n this.trackedPositionsFbo = device.createFramebuffer({\n width: textureSize,\n height: textureSize,\n colorAttachments: ['rgba32float'],\n })\n }\n\n this.trackPoints()\n }\n\n /**\n * Get current X and Y coordinates of the tracked points.\n *\n * When the simulation is disabled or stopped, this method returns a cached\n * result to avoid expensive GPU-to-CPU memory transfers (`readPixels`).\n *\n * @returns A ReadonlyMap where keys are point indices and values are [x, y] coordinates.\n */\n public getTrackedPositionsMap (): ReadonlyMap<number, [number, number]> {\n if (!this.trackedIndices) return new Map()\n\n const { config: { enableSimulation }, store: { isSimulationRunning } } = this\n\n // Use cached positions when simulation is inactive and cache is valid\n if ((!enableSimulation || !isSimulationRunning) &&\n this.isPositionsUpToDate &&\n this.trackedPositions) {\n return this.trackedPositions\n }\n\n if (!this.trackedPositionsFbo || this.trackedPositionsFbo.destroyed) return new Map()\n\n const pixels = readPixels(this.device, this.trackedPositionsFbo as Framebuffer)\n\n const tracked = new Map<number, [number, number]>()\n for (let i = 0; i < pixels.length / 4; i += 1) {\n const x = pixels[i * 4]\n const y = pixels[i * 4 + 1]\n const index = this.trackedIndices[i]\n if (x !== undefined && y !== undefined && index !== undefined) {\n tracked.set(index, [x, y])\n }\n }\n\n // If simulation is inactive, cache the result for next time\n if (!enableSimulation || !isSimulationRunning) {\n this.trackedPositions = tracked\n this.isPositionsUpToDate = true\n }\n\n return tracked\n }\n\n public getSampledPointPositionsMap (): Map<number, [number, number]> {\n const positions = new Map<number, [number, number]>()\n if (!this.sampledPointsFbo || this.sampledPointsFbo.destroyed) return positions\n\n // Fill sampled points FBO\n if (this.fillSampledPointsFboCommand && this.fillSampledPointsUniformStore && this.sampledPointsFbo) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return positions\n // Update vertex count dynamically\n this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.fillSampledPointsUniformStore.setUniforms({\n fillSampledPointsUniforms: {\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n transformationMatrix: this.store.transformationMatrix4x4,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.fillSampledPointsFboCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n })\n\n const fillPass = this.device.beginRenderPass({\n framebuffer: this.sampledPointsFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.fillSampledPointsFboCommand.draw(fillPass)\n fillPass.end()\n }\n\n const pixels = readPixels(this.device, this.sampledPointsFbo as Framebuffer)\n for (let i = 0; i < pixels.length / 4; i++) {\n const index = pixels[i * 4]\n const isNotEmpty = !!pixels[i * 4 + 1]\n const x = pixels[i * 4 + 2]\n const y = pixels[i * 4 + 3]\n\n if (isNotEmpty && index !== undefined && x !== undefined && y !== undefined) {\n positions.set(index, [x, y])\n }\n }\n return positions\n }\n\n public getSampledPoints (): { indices: number[]; positions: number[] } {\n const indices: number[] = []\n const positions: number[] = []\n if (!this.sampledPointsFbo || this.sampledPointsFbo.destroyed) return { indices, positions }\n\n // Fill sampled points FBO\n if (this.fillSampledPointsFboCommand && this.fillSampledPointsUniformStore && this.sampledPointsFbo) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return { indices, positions }\n // Update vertex count dynamically\n this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.fillSampledPointsUniformStore.setUniforms({\n fillSampledPointsUniforms: {\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n transformationMatrix: this.store.transformationMatrix4x4,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.fillSampledPointsFboCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n })\n\n const fillPass = this.device.beginRenderPass({\n framebuffer: this.sampledPointsFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.fillSampledPointsFboCommand.draw(fillPass)\n fillPass.end()\n }\n\n const pixels = readPixels(this.device, this.sampledPointsFbo as Framebuffer)\n\n for (let i = 0; i < pixels.length / 4; i++) {\n const index = pixels[i * 4]\n const isNotEmpty = !!pixels[i * 4 + 1]\n const x = pixels[i * 4 + 2]\n const y = pixels[i * 4 + 3]\n\n if (isNotEmpty && index !== undefined && x !== undefined && y !== undefined) {\n indices.push(index)\n positions.push(x, y)\n }\n }\n\n return { indices, positions }\n }\n\n public getTrackedPositionsArray (): number[] {\n const positions: number[] = []\n if (!this.trackedIndices) return positions\n if (!this.trackedPositionsFbo || this.trackedPositionsFbo.destroyed) return positions\n positions.length = this.trackedIndices.length * 2\n const pixels = readPixels(this.device, this.trackedPositionsFbo as Framebuffer)\n for (let i = 0; i < pixels.length / 4; i += 1) {\n const x = pixels[i * 4]\n const y = pixels[i * 4 + 1]\n const index = this.trackedIndices[i]\n if (x !== undefined && y !== undefined && index !== undefined) {\n positions[i * 2] = x\n positions[i * 2 + 1] = y\n }\n }\n return positions\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n * */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.drawCommand?.destroy()\n this.drawCommand = undefined\n this.drawHighlightedCommand?.destroy()\n this.drawHighlightedCommand = undefined\n this.updatePositionCommand?.destroy()\n this.updatePositionCommand = undefined\n this.dragPointCommand?.destroy()\n this.dragPointCommand = undefined\n this.findPointsOnAreaSelectionCommand?.destroy()\n this.findPointsOnAreaSelectionCommand = undefined\n this.findPointsOnPolygonSelectionCommand?.destroy()\n this.findPointsOnPolygonSelectionCommand = undefined\n this.findHoveredPointCommand?.destroy()\n this.findHoveredPointCommand = undefined\n this.fillSampledPointsFboCommand?.destroy()\n this.fillSampledPointsFboCommand = undefined\n this.trackPointsCommand?.destroy()\n this.trackPointsCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.currentPositionFbo && !this.currentPositionFbo.destroyed) {\n this.currentPositionFbo.destroy()\n }\n this.currentPositionFbo = undefined\n if (this.previousPositionFbo && !this.previousPositionFbo.destroyed) {\n this.previousPositionFbo.destroy()\n }\n this.previousPositionFbo = undefined\n if (this.velocityFbo && !this.velocityFbo.destroyed) {\n this.velocityFbo.destroy()\n }\n this.velocityFbo = undefined\n if (this.selectedFbo && !this.selectedFbo.destroyed) {\n this.selectedFbo.destroy()\n }\n this.selectedFbo = undefined\n if (this.hoveredFbo && !this.hoveredFbo.destroyed) {\n this.hoveredFbo.destroy()\n }\n this.hoveredFbo = undefined\n if (this.trackedPositionsFbo && !this.trackedPositionsFbo.destroyed) {\n this.trackedPositionsFbo.destroy()\n }\n this.trackedPositionsFbo = undefined\n if (this.sampledPointsFbo && !this.sampledPointsFbo.destroyed) {\n this.sampledPointsFbo.destroy()\n }\n this.sampledPointsFbo = undefined\n\n // 3. Destroy Textures\n if (this.currentPositionTexture && !this.currentPositionTexture.destroyed) {\n this.currentPositionTexture.destroy()\n }\n this.currentPositionTexture = undefined\n if (this.previousPositionTexture && !this.previousPositionTexture.destroyed) {\n this.previousPositionTexture.destroy()\n }\n this.previousPositionTexture = undefined\n if (this.velocityTexture && !this.velocityTexture.destroyed) {\n this.velocityTexture.destroy()\n }\n this.velocityTexture = undefined\n if (this.selectedTexture && !this.selectedTexture.destroyed) {\n this.selectedTexture.destroy()\n }\n this.selectedTexture = undefined\n if (this.greyoutStatusTexture && !this.greyoutStatusTexture.destroyed) {\n this.greyoutStatusTexture.destroy()\n }\n this.greyoutStatusTexture = undefined\n if (this.sizeTexture && !this.sizeTexture.destroyed) {\n this.sizeTexture.destroy()\n }\n this.sizeTexture = undefined\n if (this.trackedIndicesTexture && !this.trackedIndicesTexture.destroyed) {\n this.trackedIndicesTexture.destroy()\n }\n this.trackedIndicesTexture = undefined\n if (this.polygonPathTexture && !this.polygonPathTexture.destroyed) {\n this.polygonPathTexture.destroy()\n }\n this.polygonPathTexture = undefined\n if (this.imageAtlasTexture && !this.imageAtlasTexture.destroyed) {\n this.imageAtlasTexture.destroy()\n }\n this.imageAtlasTexture = undefined\n if (this.imageAtlasCoordsTexture && !this.imageAtlasCoordsTexture.destroyed) {\n this.imageAtlasCoordsTexture.destroy()\n }\n this.imageAtlasCoordsTexture = undefined\n if (this.pinnedStatusTexture && !this.pinnedStatusTexture.destroyed) {\n this.pinnedStatusTexture.destroy()\n }\n this.pinnedStatusTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.updatePositionUniformStore?.destroy()\n this.updatePositionUniformStore = undefined\n this.dragPointUniformStore?.destroy()\n this.dragPointUniformStore = undefined\n this.drawUniformStore?.destroy()\n this.drawUniformStore = undefined\n this.findPointsOnAreaSelectionUniformStore?.destroy()\n this.findPointsOnAreaSelectionUniformStore = undefined\n this.findPointsOnPolygonSelectionUniformStore?.destroy()\n this.findPointsOnPolygonSelectionUniformStore = undefined\n this.findHoveredPointUniformStore?.destroy()\n this.findHoveredPointUniformStore = undefined\n this.fillSampledPointsUniformStore?.destroy()\n this.fillSampledPointsUniformStore = undefined\n this.drawHighlightedUniformStore?.destroy()\n this.drawHighlightedUniformStore = undefined\n this.trackPointsUniformStore?.destroy()\n this.trackPointsUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = undefined\n if (this.sizeBuffer && !this.sizeBuffer.destroyed) {\n this.sizeBuffer.destroy()\n }\n this.sizeBuffer = undefined\n if (this.shapeBuffer && !this.shapeBuffer.destroyed) {\n this.shapeBuffer.destroy()\n }\n this.shapeBuffer = undefined\n if (this.imageIndicesBuffer && !this.imageIndicesBuffer.destroyed) {\n this.imageIndicesBuffer.destroy()\n }\n this.imageIndicesBuffer = undefined\n if (this.imageSizesBuffer && !this.imageSizesBuffer.destroyed) {\n this.imageSizesBuffer.destroy()\n }\n this.imageSizesBuffer = undefined\n if (this.drawPointIndices && !this.drawPointIndices.destroyed) {\n this.drawPointIndices.destroy()\n }\n this.drawPointIndices = undefined\n if (this.hoveredPointIndices && !this.hoveredPointIndices.destroyed) {\n this.hoveredPointIndices.destroy()\n }\n this.hoveredPointIndices = undefined\n if (this.sampledPointIndices && !this.sampledPointIndices.destroyed) {\n this.sampledPointIndices.destroy()\n }\n this.sampledPointIndices = undefined\n if (this.updatePositionVertexCoordBuffer && !this.updatePositionVertexCoordBuffer.destroyed) {\n this.updatePositionVertexCoordBuffer.destroy()\n }\n this.updatePositionVertexCoordBuffer = undefined\n if (this.dragPointVertexCoordBuffer && !this.dragPointVertexCoordBuffer.destroyed) {\n this.dragPointVertexCoordBuffer.destroy()\n }\n this.dragPointVertexCoordBuffer = undefined\n if (this.findPointsOnAreaSelectionVertexCoordBuffer && !this.findPointsOnAreaSelectionVertexCoordBuffer.destroyed) {\n this.findPointsOnAreaSelectionVertexCoordBuffer.destroy()\n }\n this.findPointsOnAreaSelectionVertexCoordBuffer = undefined\n if (this.findPointsOnPolygonSelectionVertexCoordBuffer && !this.findPointsOnPolygonSelectionVertexCoordBuffer.destroyed) {\n this.findPointsOnPolygonSelectionVertexCoordBuffer.destroy()\n }\n this.findPointsOnPolygonSelectionVertexCoordBuffer = undefined\n if (this.drawHighlightedVertexCoordBuffer && !this.drawHighlightedVertexCoordBuffer.destroyed) {\n this.drawHighlightedVertexCoordBuffer.destroy()\n }\n this.drawHighlightedVertexCoordBuffer = undefined\n if (this.trackPointsVertexCoordBuffer && !this.trackPointsVertexCoordBuffer.destroyed) {\n this.trackPointsVertexCoordBuffer.destroy()\n }\n this.trackPointsVertexCoordBuffer = undefined\n }\n\n private swapFbo (): void {\n // Swap textures and framebuffers\n // Safety check: ensure resources exist and aren't destroyed before swapping\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed ||\n !this.previousPositionTexture || this.previousPositionTexture.destroyed ||\n !this.currentPositionFbo || this.currentPositionFbo.destroyed ||\n !this.previousPositionFbo || this.previousPositionFbo.destroyed) {\n return\n }\n const tempTexture = this.previousPositionTexture\n const tempFbo = this.previousPositionFbo\n this.previousPositionTexture = this.currentPositionTexture\n this.previousPositionFbo = this.currentPositionFbo\n this.currentPositionTexture = tempTexture\n this.currentPositionFbo = tempFbo\n }\n\n private rescaleInitialNodePositions (): void {\n const { config: { spaceSize } } = this\n if (!this.data.pointPositions || !spaceSize) return\n\n const points = this.data.pointPositions\n const pointsNumber = points.length / 2\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (let i = 0; i < points.length; i += 2) {\n const x = points[i] as number\n const y = points[i + 1] as number\n minX = Math.min(minX, x)\n maxX = Math.max(maxX, x)\n minY = Math.min(minY, y)\n maxY = Math.max(maxY, y)\n }\n const w = maxX - minX\n const h = maxY - minY\n const range = Math.max(w, h)\n\n // Do not rescale if the range is greater than the space size (no need to)\n if (range > spaceSize) {\n this.scaleX = undefined\n this.scaleY = undefined\n return\n }\n\n // Density threshold - points per pixel ratio (0.001 = 0.1%)\n const densityThreshold = spaceSize * spaceSize * 0.001\n // Calculate effective space size based on point density\n const effectiveSpaceSize = pointsNumber > densityThreshold\n // For dense datasets: scale up based on point count, minimum 120% of space\n ? spaceSize * Math.max(1.2, Math.sqrt(pointsNumber) / spaceSize)\n // For sparse datasets: use 10% of space to cluster points closer\n : spaceSize * 0.1\n\n // Calculate uniform scale factor to fit data within effective space\n const scaleFactor = effectiveSpaceSize / range\n // Shift to center the scaled data within the full [0, spaceSize] space\n const centerOffset = (spaceSize - effectiveSpaceSize) / 2\n // Pad the shorter axis so both axes are centered within the square bounding box\n const offsetX = ((range - w) / 2) * scaleFactor + centerOffset\n const offsetY = ((range - h) / 2) * scaleFactor + centerOffset\n\n this.scaleX = (x: number): number => (x - minX) * scaleFactor + offsetX\n this.scaleY = (y: number): number => (y - minY) * scaleFactor + offsetY\n\n // Apply scaling to point positions\n for (let i = 0; i < pointsNumber; i++) {\n this.data.pointPositions[i * 2] = this.scaleX(points[i * 2] as number)\n this.data.pointPositions[i * 2 + 1] = this.scaleY(points[i * 2 + 1] as number)\n }\n }\n}\n","import { zoom, ZoomTransform, zoomIdentity, D3ZoomEvent } from 'd3-zoom'\nimport { mat3 } from 'gl-matrix'\nimport { Store } from '@/graph/modules/Store'\nimport { GraphConfigInterface } from '@/graph/config'\nimport { clamp } from '@/graph/helper'\n\nexport class Zoom {\n public readonly store: Store\n public readonly config: GraphConfigInterface\n public eventTransform = zoomIdentity\n public behavior = zoom<HTMLCanvasElement, undefined>()\n .scaleExtent([0.001, Infinity])\n .on('start', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.isRunning = true\n const userDriven = !!e.sourceEvent\n this.config?.onZoomStart?.(e, userDriven)\n })\n .on('zoom', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.eventTransform = e.transform\n const { eventTransform: { x, y, k }, store: { transform, screenSize } } = this\n const w = screenSize[0]\n const h = screenSize[1]\n if (!w || !h) return\n mat3.projection(transform, w, h)\n mat3.translate(transform, transform, [x, y])\n mat3.scale(transform, transform, [k, k])\n mat3.translate(transform, transform, [w / 2, h / 2])\n mat3.scale(transform, transform, [w / 2, h / 2])\n mat3.scale(transform, transform, [1, -1])\n\n const userDriven = !!e.sourceEvent\n this.config?.onZoom?.(e, userDriven)\n })\n .on('end', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.isRunning = false\n\n const userDriven = !!e.sourceEvent\n this.config?.onZoomEnd?.(e, userDriven)\n })\n\n public isRunning = false\n\n public constructor (store: Store, config: GraphConfigInterface) {\n this.store = store\n this.config = config\n }\n\n /**\n * Returns the zoom transform that fits the given point positions into the viewport.\n *\n * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]` (number[] or Float32Array).\n * @param scale Optional scale factor to apply to the transform.\n * @param padding Padding around the viewport as a fraction of the viewport size (e.g. 0.1 = 10%).\n * @returns The zoom transform that fits the positions.\n */\n public getTransform (positions: number[] | Float32Array, scale?: number, padding = 0.1): ZoomTransform {\n if (positions.length === 0) return this.eventTransform\n const { store: { screenSize } } = this\n const width = screenSize[0]\n const height = screenSize[1]\n\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (let i = 0; i < positions.length; i += 2) {\n const x = positions[i] as number\n const y = positions[i + 1] as number\n if (x < minX) minX = x\n if (x > maxX) maxX = x\n if (y < minY) minY = y\n if (y > maxY) maxY = y\n }\n\n const xExtent: [number, number] = [this.store.scaleX(minX), this.store.scaleX(maxX)]\n const yExtent: [number, number] = [this.store.scaleY(minY), this.store.scaleY(maxY)]\n // Adjust extent with one screen pixel if one point coordinate is set\n if (xExtent[0] === xExtent[1]) {\n xExtent[0] -= 0.5\n xExtent[1] += 0.5\n }\n if (yExtent[0] === yExtent[1]) {\n yExtent[0] += 0.5\n yExtent[1] -= 0.5\n }\n\n const xScale = (width * (1 - padding * 2)) / (xExtent[1] - xExtent[0])\n const yScale = (height * (1 - padding * 2)) / (yExtent[0] - yExtent[1])\n const clampedScale = clamp(scale ?? Math.min(xScale, yScale), ...this.behavior.scaleExtent())\n const xCenter = (xExtent[1] + xExtent[0]) / 2\n const yCenter = (yExtent[1] + yExtent[0]) / 2\n const translateX = width / 2 - xCenter * clampedScale\n const translateY = height / 2 - yCenter * clampedScale\n\n const transform = zoomIdentity\n .translate(translateX, translateY)\n .scale(clampedScale)\n\n return transform\n }\n\n public getDistanceToPoint (position: [number, number]): number {\n const { x, y, k } = this.eventTransform\n const point = this.getTransform(position, k)\n const dx = x - point.x\n const dy = y - point.y\n return Math.sqrt(dx * dx + dy * dy)\n }\n\n public getMiddlePointTransform (position: [number, number]): ZoomTransform {\n const { store: { screenSize }, eventTransform: { x, y, k } } = this\n const width = screenSize[0]\n const height = screenSize[1]\n const currX = (width / 2 - x) / k\n const currY = (height / 2 - y) / k\n const pointX = this.store.scaleX(position[0])\n const pointY = this.store.scaleY(position[1])\n const centerX = (currX + pointX) / 2\n const centerY = (currY + pointY) / 2\n\n const scale = 1\n const translateX = width / 2 - centerX * scale\n const translateY = height / 2 - centerY * scale\n\n return zoomIdentity\n .translate(translateX, translateY)\n .scale(scale)\n }\n\n public convertScreenToSpacePosition (screenPosition: [number, number]): [number, number] {\n const { eventTransform: { x, y, k }, store: { screenSize } } = this\n const w = screenSize[0]\n const h = screenSize[1]\n const invertedX = (screenPosition[0] - x) / k\n const invertedY = (screenPosition[1] - y) / k\n const spacePosition = [invertedX, (h - invertedY)] as [number, number]\n spacePosition[0] -= (w - this.store.adjustedSpaceSize) / 2\n spacePosition[1] -= (h - this.store.adjustedSpaceSize) / 2\n return spacePosition\n }\n\n public convertSpaceToScreenPosition (spacePosition: [number, number]): [number, number] {\n const screenPointX = this.eventTransform.applyX(this.store.scaleX(spacePosition[0]))\n const screenPointY = this.eventTransform.applyY(this.store.scaleY(spacePosition[1]))\n return [screenPointX, screenPointY]\n }\n\n public convertSpaceToScreenRadius (spaceRadius: number): number {\n const { config: { scalePointsOnZoom }, store: { maxPointSize }, eventTransform: { k } } = this\n let size = spaceRadius * 2\n if (scalePointsOnZoom) {\n size *= k\n } else {\n size *= Math.min(5.0, Math.max(1.0, k * 0.01))\n }\n return Math.min(size, maxPointSize) / 2\n }\n}\n","import { drag } from 'd3-drag'\nimport { Store } from '@/graph/modules/Store'\nimport { GraphConfigInterface } from '@/graph/config'\n\nexport class Drag {\n public readonly store: Store\n public readonly config: GraphConfigInterface\n public isActive = false\n public behavior = drag<HTMLCanvasElement, undefined>()\n .subject((event) => {\n return this.store.hoveredPoint && !this.store.isSpaceKeyPressed ? { x: event.x, y: event.y } : undefined\n })\n .on('start', (e) => {\n if (this.store.hoveredPoint) {\n this.store.draggingPointIndex = this.store.hoveredPoint.index\n this.isActive = true\n this.config?.onDragStart?.(e)\n }\n })\n .on('drag', (e) => {\n this.config?.onDrag?.(e)\n })\n .on('end', (e) => {\n this.isActive = false\n this.store.draggingPointIndex = undefined\n this.config?.onDragEnd?.(e)\n })\n\n public constructor (store: Store, config: GraphConfigInterface) {\n this.store = store\n this.config = config\n }\n}\n","import { select, Selection } from 'd3-selection'\nimport 'd3-transition'\nimport { easeQuadInOut, easeQuadIn, easeQuadOut } from 'd3-ease'\nimport { D3ZoomEvent } from 'd3-zoom'\nimport { D3DragEvent } from 'd3-drag'\nimport { Device, Framebuffer, luma } from '@luma.gl/core'\nimport { webgl2Adapter } from '@luma.gl/webgl'\n\nimport { GraphConfig, GraphConfigInterface } from '@/graph/config'\nimport { getRgbaColor, getMaxPointSize, readPixels, sanitizeHtml } from '@/graph/helper'\nimport { ForceCenter } from '@/graph/modules/ForceCenter'\nimport { ForceGravity } from '@/graph/modules/ForceGravity'\nimport { ForceLink, LinkDirection } from '@/graph/modules/ForceLink'\nimport { ForceManyBody } from '@/graph/modules/ForceManyBody'\nimport { ForceMouse } from '@/graph/modules/ForceMouse'\nimport { Clusters } from '@/graph/modules/Clusters'\nimport { FPSMonitor } from '@/graph/modules/FPSMonitor'\nimport { GraphData } from '@/graph/modules/GraphData'\nimport { Lines } from '@/graph/modules/Lines'\nimport { Points } from '@/graph/modules/Points'\nimport { Store, ALPHA_MIN, MAX_HOVER_DETECTION_DELAY, MIN_MOUSE_MOVEMENT_THRESHOLD, type Hovered } from '@/graph/modules/Store'\nimport { Zoom } from '@/graph/modules/Zoom'\nimport { Drag } from '@/graph/modules/Drag'\nimport { defaultConfigValues, defaultScaleToZoom, defaultGreyoutPointColor, defaultBackgroundColor } from '@/graph/variables'\n\nexport class Graph {\n public config = new GraphConfig()\n public graph = new GraphData(this.config)\n /** Promise that resolves with the luma device when the graph is ready. Await or `.then()` to run after init. */\n public readonly deviceInitPromise: Promise<Device>\n /** Canvas element, assigned asynchronously during device initialization */\n private canvas!: HTMLCanvasElement\n private attributionDivElement: HTMLElement | undefined\n private canvasD3Selection: Selection<HTMLCanvasElement, undefined, null, undefined> | undefined\n private device: Device | undefined\n /**\n * Tracks whether this Graph instance owns the device and should destroy it on cleanup.\n * Set to `true` when Graph creates its own device, `false` when using an external device.\n * When `false`, the external device lifecycle is managed by the user.\n */\n private shouldDestroyDevice: boolean\n private requestAnimationFrameId = 0\n private isRightClickMouse = false\n\n private store = new Store()\n private points: Points | undefined\n private lines: Lines | undefined\n private forceGravity: ForceGravity | undefined\n private forceCenter: ForceCenter | undefined\n private forceManyBody: ForceManyBody | undefined\n private forceLinkIncoming: ForceLink | undefined\n private forceLinkOutgoing: ForceLink | undefined\n private forceMouse: ForceMouse | undefined\n private clusters: Clusters | undefined\n private zoomInstance = new Zoom(this.store, this.config)\n private dragInstance = new Drag(this.store, this.config)\n\n private fpsMonitor: FPSMonitor | undefined\n\n private currentEvent: D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | MouseEvent | undefined\n /**\n * The value of `_findHoveredItemExecutionCount` is incremented by 1 on each animation frame.\n * When the counter reaches MAX_HOVER_DETECTION_DELAY (default 4), it is reset to 0 and the `findHoveredPoint` or `findHoveredLine` method is executed.\n */\n private _findHoveredItemExecutionCount = 0\n /**\n * If the mouse is not on the Canvas, the `findHoveredPoint` or `findHoveredLine` method will not be executed.\n */\n private _isMouseOnCanvas = false\n /**\n * Last mouse position for detecting significant mouse movement\n */\n private _lastMouseX = 0\n private _lastMouseY = 0\n /**\n * Last checked mouse position for hover detection\n */\n private _lastCheckedMouseX = 0\n private _lastCheckedMouseY = 0\n /**\n * Force hover detection on next frame, bypassing mouse movement check.\n * Set when scene changes but mouse stays still (after simulation or zoom ends).\n */\n private _shouldForceHoverDetection = false\n /**\n * After setting data and render graph at a first time, the fit logic will run\n * */\n private _isFirstRenderAfterInit = true\n private _fitViewOnInitTimeoutID: number | undefined\n\n private isPointPositionsUpdateNeeded = false\n private isPointColorUpdateNeeded = false\n private isPointSizeUpdateNeeded = false\n private isPointShapeUpdateNeeded = false\n private isPointImageIndicesUpdateNeeded = false\n private isLinksUpdateNeeded = false\n private isLinkColorUpdateNeeded = false\n private isLinkWidthUpdateNeeded = false\n private isLinkArrowUpdateNeeded = false\n private isPointClusterUpdateNeeded = false\n private isForceManyBodyUpdateNeeded = false\n private isForceLinkUpdateNeeded = false\n private isForceCenterUpdateNeeded = false\n private isPointImageSizesUpdateNeeded = false\n\n private _isDestroyed = false\n\n public constructor (\n div: HTMLDivElement,\n config?: GraphConfigInterface,\n devicePromise?: Promise<Device>\n ) {\n if (config) this.config.init(config)\n\n if (devicePromise) {\n this.deviceInitPromise = devicePromise\n this.shouldDestroyDevice = false // External device - Graph does not own it\n } else {\n const canvas = document.createElement('canvas')\n this.deviceInitPromise = this.createDevice(canvas)\n this.shouldDestroyDevice = true // Graph created the device and owns it\n }\n\n this.deviceInitPromise.then(device => {\n if (this._isDestroyed) {\n // Only destroy the device if Graph owns it\n if (this.shouldDestroyDevice) {\n device.destroy()\n }\n return device\n }\n this.device = device\n const deviceCanvasContext = this.validateDevice(device)\n\n // If external device was provided, sync its useDevicePixels with config.pixelRatio\n if (devicePromise) {\n deviceCanvasContext.setProps({ useDevicePixels: this.config.pixelRatio })\n }\n\n this.store.div = div\n const deviceCanvas = deviceCanvasContext.canvas as HTMLCanvasElement\n // Ensure canvas is in the div\n if (deviceCanvas.parentNode !== this.store.div) {\n if (deviceCanvas.parentNode) {\n deviceCanvas.parentNode.removeChild(deviceCanvas)\n }\n this.store.div.appendChild(deviceCanvas)\n }\n this.addAttribution()\n deviceCanvas.style.width = '100%'\n deviceCanvas.style.height = '100%'\n this.canvas = deviceCanvas\n\n const w = this.canvas.clientWidth\n const h = this.canvas.clientHeight\n\n this.store.adjustSpaceSize(this.config.spaceSize, this.device.limits.maxTextureDimension2D)\n this.store.setWebGLMaxTextureSize(this.device.limits.maxTextureDimension2D)\n this.store.updateScreenSize(w, h)\n\n this.canvasD3Selection = select<HTMLCanvasElement, undefined>(this.canvas)\n this.canvasD3Selection\n .on('mouseenter.cosmos', (event) => {\n this._isMouseOnCanvas = true\n this._lastMouseX = event.clientX\n this._lastMouseY = event.clientY\n })\n .on('mousemove.cosmos', (event) => {\n this._isMouseOnCanvas = true\n this._lastMouseX = event.clientX\n this._lastMouseY = event.clientY\n })\n .on('mouseleave.cosmos', (event) => {\n this._isMouseOnCanvas = false\n this.currentEvent = event\n\n // Clear point hover state and trigger callback if needed\n if (this.store.hoveredPoint !== undefined && this.config.onPointMouseOut) {\n this.config.onPointMouseOut(event)\n }\n\n // Clear link hover state and trigger callback if needed\n if (this.store.hoveredLinkIndex !== undefined && this.config.onLinkMouseOut) {\n this.config.onLinkMouseOut(event)\n }\n\n // Reset right-click flag\n this.isRightClickMouse = false\n\n // Clear hover states\n this.store.hoveredPoint = undefined\n this.store.hoveredLinkIndex = undefined\n\n // Update cursor style after clearing hover states\n this.updateCanvasCursor()\n })\n select(document)\n .on('keydown.cosmos', (event) => { if (event.code === 'Space') this.store.isSpaceKeyPressed = true })\n .on('keyup.cosmos', (event) => { if (event.code === 'Space') this.store.isSpaceKeyPressed = false })\n this.zoomInstance.behavior\n .on('start.detect', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => { this.currentEvent = e })\n .on('zoom.detect', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n const userDriven = !!e.sourceEvent\n if (userDriven) this.updateMousePosition(e.sourceEvent)\n this.currentEvent = e\n })\n .on('end.detect', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.currentEvent = e\n // Force hover detection on next frame since zoom may have changed what's under the mouse\n this._shouldForceHoverDetection = true\n })\n this.dragInstance.behavior\n .on('start.detect', (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => {\n this.currentEvent = e\n this.updateCanvasCursor()\n })\n .on('drag.detect', (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => {\n if (this.dragInstance.isActive) {\n this.updateMousePosition(e)\n }\n this.currentEvent = e\n })\n .on('end.detect', (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => {\n this.currentEvent = e\n this.updateCanvasCursor()\n })\n this.canvasD3Selection\n .call(this.dragInstance.behavior)\n .call(this.zoomInstance.behavior)\n .on('click', this.onClick.bind(this))\n .on('mousemove', this.onMouseMove.bind(this))\n .on('contextmenu', this.onContextMenu.bind(this))\n if (!this.config.enableZoom || !this.config.enableDrag) this.updateZoomDragBehaviors()\n this.setZoomLevel(this.config.initialZoomLevel ?? 1)\n\n this.store.maxPointSize = getMaxPointSize(device, this.config.pixelRatio)\n\n // Initialize simulation state based on enableSimulation config\n // If simulation is disabled, start with isSimulationRunning = false\n this.store.isSimulationRunning = this.config.enableSimulation\n\n this.points = new Points(device, this.config, this.store, this.graph)\n this.lines = new Lines(device, this.config, this.store, this.graph, this.points)\n if (this.config.enableSimulation) {\n this.forceGravity = new ForceGravity(device, this.config, this.store, this.graph, this.points)\n this.forceCenter = new ForceCenter(device, this.config, this.store, this.graph, this.points)\n this.forceManyBody = new ForceManyBody(device, this.config, this.store, this.graph, this.points)\n this.forceLinkIncoming = new ForceLink(device, this.config, this.store, this.graph, this.points)\n this.forceLinkOutgoing = new ForceLink(device, this.config, this.store, this.graph, this.points)\n this.forceMouse = new ForceMouse(device, this.config, this.store, this.graph, this.points)\n }\n this.clusters = new Clusters(device, this.config, this.store, this.graph, this.points)\n\n this.store.backgroundColor = getRgbaColor(this.config.backgroundColor)\n this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor ?? defaultConfigValues.hoveredPointRingColor)\n this.store.setFocusedPointRingColor(this.config.focusedPointRingColor ?? defaultConfigValues.focusedPointRingColor)\n if (this.config.focusedPointIndex !== undefined) {\n this.store.setFocusedPoint(this.config.focusedPointIndex)\n }\n this.store.setGreyoutPointColor(this.config.pointGreyoutColor ?? defaultGreyoutPointColor)\n this.store.setHoveredLinkColor(this.config.hoveredLinkColor ?? defaultConfigValues.hoveredLinkColor)\n\n this.store.updateLinkHoveringEnabled(this.config)\n\n if (this.config.showFPSMonitor) this.fpsMonitor = new FPSMonitor(this.canvas)\n\n if (this.config.randomSeed !== undefined) this.store.addRandomSeed(this.config.randomSeed)\n\n return device\n })\n .catch(error => {\n console.error('Device initialization failed:', error)\n throw error\n })\n }\n\n /**\n * Returns the current simulation progress\n */\n public get progress (): number {\n if (this._isDestroyed) return 0\n return this.store.simulationProgress\n }\n\n /**\n * A value that gives information about the running simulation status.\n */\n public get isSimulationRunning (): boolean {\n if (this._isDestroyed) return false\n return this.store.isSimulationRunning\n }\n\n /**\n * The maximum point size.\n * This value is the maximum size of the `gl.POINTS` primitive that WebGL can render on the user's hardware.\n */\n public get maxPointSize (): number {\n if (this._isDestroyed) return 0\n return this.store.maxPointSize\n }\n\n /**\n * Set or update Cosmos configuration. The changes will be applied in real time.\n * @param config Cosmos configuration object.\n */\n public setConfig (config: Partial<GraphConfigInterface>): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setConfig(config))) return\n const prevConfig = { ...this.config }\n this.config.init(config)\n if ((prevConfig.pointDefaultColor !== this.config.pointDefaultColor) ||\n (prevConfig.pointColor !== this.config.pointColor)) {\n this.graph.updatePointColor()\n this.points?.updateColor()\n }\n if ((prevConfig.pointDefaultSize !== this.config.pointDefaultSize) ||\n (prevConfig.pointSize !== this.config.pointSize)) {\n this.graph.updatePointSize()\n this.points?.updateSize()\n }\n if ((prevConfig.linkDefaultColor !== this.config.linkDefaultColor) ||\n (prevConfig.linkColor !== this.config.linkColor)) {\n this.graph.updateLinkColor()\n this.lines?.updateColor()\n }\n if ((prevConfig.linkDefaultWidth !== this.config.linkDefaultWidth) ||\n (prevConfig.linkWidth !== this.config.linkWidth)) {\n this.graph.updateLinkWidth()\n this.lines?.updateWidth()\n }\n if ((prevConfig.linkDefaultArrows !== this.config.linkDefaultArrows) ||\n (prevConfig.linkArrows !== this.config.linkArrows)) {\n this.graph.updateArrows()\n this.lines?.updateArrow()\n }\n if (prevConfig.curvedLinkSegments !== this.config.curvedLinkSegments ||\n prevConfig.curvedLinks !== this.config.curvedLinks) {\n this.lines?.updateCurveLineGeometry()\n }\n\n if (prevConfig.backgroundColor !== this.config.backgroundColor) {\n this.store.backgroundColor = getRgbaColor(this.config.backgroundColor ?? defaultBackgroundColor)\n }\n if (prevConfig.hoveredPointRingColor !== this.config.hoveredPointRingColor) {\n this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor ?? defaultConfigValues.hoveredPointRingColor)\n }\n if (prevConfig.focusedPointRingColor !== this.config.focusedPointRingColor) {\n this.store.setFocusedPointRingColor(this.config.focusedPointRingColor ?? defaultConfigValues.focusedPointRingColor)\n }\n if (prevConfig.pointGreyoutColor !== this.config.pointGreyoutColor) {\n this.store.setGreyoutPointColor(this.config.pointGreyoutColor ?? defaultGreyoutPointColor)\n }\n if (prevConfig.hoveredLinkColor !== this.config.hoveredLinkColor) {\n this.store.setHoveredLinkColor(this.config.hoveredLinkColor ?? defaultConfigValues.hoveredLinkColor)\n }\n if (prevConfig.focusedPointIndex !== this.config.focusedPointIndex) {\n this.store.setFocusedPoint(this.config.focusedPointIndex)\n }\n if (prevConfig.pixelRatio !== this.config.pixelRatio) {\n // Update device's canvas context useDevicePixels\n if (this.device?.canvasContext) {\n this.device.canvasContext.setProps({ useDevicePixels: this.config.pixelRatio })\n\n // Recalculate maxPointSize with new pixelRatio\n this.store.maxPointSize = getMaxPointSize(this.device, this.config.pixelRatio)\n }\n }\n if (prevConfig.spaceSize !== this.config.spaceSize) {\n this.store.adjustSpaceSize(this.config.spaceSize, this.device?.limits.maxTextureDimension2D ?? 4096)\n this.resizeCanvas(true)\n this.update(this.store.isSimulationRunning ? this.store.alpha : 0)\n }\n if (prevConfig.showFPSMonitor !== this.config.showFPSMonitor) {\n if (this.config.showFPSMonitor) {\n this.fpsMonitor = new FPSMonitor(this.canvas)\n } else {\n this.fpsMonitor?.destroy()\n this.fpsMonitor = undefined\n }\n }\n if (prevConfig.enableZoom !== this.config.enableZoom || prevConfig.enableDrag !== this.config.enableDrag) {\n this.updateZoomDragBehaviors()\n }\n\n if (prevConfig.onLinkClick !== this.config.onLinkClick ||\n prevConfig.onLinkContextMenu !== this.config.onLinkContextMenu ||\n prevConfig.onLinkMouseOver !== this.config.onLinkMouseOver ||\n prevConfig.onLinkMouseOut !== this.config.onLinkMouseOut) {\n this.store.updateLinkHoveringEnabled(this.config)\n }\n }\n\n /**\n * Sets the positions for the graph points.\n *\n * @param {Float32Array} pointPositions - A Float32Array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn],\n * where `n` is the index of the point.\n * 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.\n * @param {boolean | undefined} dontRescale - For this call only, don't rescale the points.\n * - `true`: Don't rescale.\n * - `false` or `undefined` (default): Use the behavior defined by `config.rescalePositions`.\n */\n public setPointPositions (pointPositions: Float32Array, dontRescale?: boolean | undefined): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setPointPositions(pointPositions, dontRescale))) return\n this.graph.inputPointPositions = pointPositions\n this.points!.shouldSkipRescale = dontRescale\n this.isPointPositionsUpdateNeeded = true\n // Links related texture depends on point positions, so we need to update it\n this.isLinksUpdateNeeded = true\n // Point related textures depend on point positions length, so we need to update them\n this.isPointColorUpdateNeeded = true\n this.isPointSizeUpdateNeeded = true\n this.isPointShapeUpdateNeeded = true\n this.isPointImageIndicesUpdateNeeded = true\n this.isPointImageSizesUpdateNeeded = true\n this.isPointClusterUpdateNeeded = true\n this.isForceManyBodyUpdateNeeded = true\n this.isForceLinkUpdateNeeded = true\n this.isForceCenterUpdateNeeded = true\n }\n\n /**\n * Sets the colors for the graph points.\n *\n * @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],\n * where each color is represented in RGBA format.\n * Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first point to red and the second point to green.\n */\n public setPointColors (pointColors: Float32Array): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setPointColors(pointColors))) return\n this.graph.inputPointColors = pointColors\n this.isPointColorUpdateNeeded = true\n }\n\n /**\n * Gets the current colors of the graph points.\n *\n * @returns {Float32Array} A Float32Array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an],\n * where each color is in RGBA format. Returns an empty Float32Array if no point colors are set.\n */\n public getPointColors (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.pointColors ?? new Float32Array()\n }\n\n /**\n * Sets the sizes for the graph points.\n *\n * @param {Float32Array} pointSizes - A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen],\n * where `n` is the index of the point.\n * 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.\n */\n public setPointSizes (pointSizes: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointSizes(pointSizes))) return\n this.graph.inputPointSizes = pointSizes\n this.isPointSizeUpdateNeeded = true\n }\n\n /**\n * Sets the shapes for the graph points.\n *\n * @param {Float32Array} pointShapes - A Float32Array representing the shapes of points in the format [shape1, shape2, ..., shapen],\n * where `n` is the index of the point and each shape value corresponds to a PointShape enum:\n * 0 = Circle, 1 = Square, 2 = Triangle, 3 = Diamond, 4 = Pentagon, 5 = Hexagon, 6 = Star, 7 = Cross, 8 = None.\n * Example: `new Float32Array([0, 1, 2])` sets the first point to Circle, the second point to Square, and the third point to Triangle.\n * Images are rendered above shapes.\n */\n public setPointShapes (pointShapes: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointShapes(pointShapes))) return\n this.graph.inputPointShapes = pointShapes\n this.isPointShapeUpdateNeeded = true\n }\n\n /**\n * Sets the images for the graph points using ImageData objects.\n * Images are rendered above shapes.\n * To use images, provide image indices via setPointImageIndices().\n *\n * @param {ImageData[]} imageDataArray - Array of ImageData objects to use as point images.\n * Example: `setImageData([imageData1, imageData2, imageData3])`\n */\n public setImageData (imageDataArray: ImageData[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setImageData(imageDataArray))) return\n this.graph.inputImageData = imageDataArray\n this.points?.createAtlas()\n }\n\n /**\n * Sets which image each point should use from the images array.\n * Images are rendered above shapes.\n *\n * @param {Float32Array} imageIndices - A Float32Array representing which image each point uses in the format [index1, index2, ..., indexn],\n * where `n` is the index of the point and each value is an index into the images array provided to `setImageData`.\n * 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.\n */\n public setPointImageIndices (imageIndices: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointImageIndices(imageIndices))) return\n this.graph.inputPointImageIndices = imageIndices\n this.isPointImageIndicesUpdateNeeded = true\n }\n\n /**\n * Sets the sizes for the point images.\n *\n * @param {Float32Array} imageSizes - A Float32Array representing the sizes of point images in the format [size1, size2, ..., sizen],\n * where `n` is the index of the point.\n * 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.\n */\n public setPointImageSizes (imageSizes: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointImageSizes(imageSizes))) return\n this.graph.inputPointImageSizes = imageSizes\n this.isPointImageSizesUpdateNeeded = true\n }\n\n /**\n * Gets the current sizes of the graph points.\n *\n * @returns {Float32Array} A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen],\n * where `n` is the index of the point. Returns an empty Float32Array if no point sizes are set.\n */\n public getPointSizes (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.pointSizes ?? new Float32Array()\n }\n\n /**\n * Sets the links for the graph.\n *\n * @param {Float32Array} links - A Float32Array representing the links between points\n * in the format [source1, target1, source2, target2, ..., sourcen, targetn],\n * where `source` and `target` are the indices of the points being linked.\n * 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.\n */\n public setLinks (links: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinks(links))) return\n this.graph.inputLinks = links\n this.isLinksUpdateNeeded = true\n // Links related texture depends on links length, so we need to update it\n this.isLinkColorUpdateNeeded = true\n this.isLinkWidthUpdateNeeded = true\n this.isLinkArrowUpdateNeeded = true\n this.isForceLinkUpdateNeeded = true\n }\n\n /**\n * Sets the colors for the graph links.\n *\n * @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],\n * where each color is in RGBA format.\n * Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first link to red and the second link to green.\n */\n public setLinkColors (linkColors: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkColors(linkColors))) return\n this.graph.inputLinkColors = linkColors\n this.isLinkColorUpdateNeeded = true\n }\n\n /**\n * Gets the current colors of the graph links.\n *\n * @returns {Float32Array} A Float32Array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an],\n * where each color is in RGBA format. Returns an empty Float32Array if no link colors are set.\n */\n public getLinkColors (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.linkColors ?? new Float32Array()\n }\n\n /**\n * Sets the widths for the graph links.\n *\n * @param {Float32Array} linkWidths - A Float32Array representing the widths of links in the format [width1, width2, ..., widthn],\n * where `n` is the index of the link.\n * 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.\n */\n public setLinkWidths (linkWidths: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkWidths(linkWidths))) return\n this.graph.inputLinkWidths = linkWidths\n this.isLinkWidthUpdateNeeded = true\n }\n\n /**\n * Gets the current widths of the graph links.\n *\n * @returns {Float32Array} A Float32Array representing the widths of links in the format [width1, width2, ..., widthn],\n * where `n` is the index of the link. Returns an empty Float32Array if no link widths are set.\n */\n public getLinkWidths (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.linkWidths ?? new Float32Array()\n }\n\n /**\n * Sets the arrows for the graph links.\n *\n * @param {boolean[]} linkArrows - An array of booleans indicating whether each link should have an arrow,\n * in the format [arrow1, arrow2, ..., arrown], where `n` is the index of the link.\n * Example: `[true, false, true]` sets arrows on the first and third links, but not on the second link.\n */\n public setLinkArrows (linkArrows: boolean[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkArrows(linkArrows))) return\n this.graph.linkArrowsBoolean = linkArrows\n this.isLinkArrowUpdateNeeded = true\n }\n\n /**\n * Sets the strength for the graph links.\n *\n * @param {Float32Array} linkStrength - A Float32Array representing the strength of each link in the format [strength1, strength2, ..., strengthn],\n * where `n` is the index of the link.\n * 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.\n */\n public setLinkStrength (linkStrength: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkStrength(linkStrength))) return\n this.graph.inputLinkStrength = linkStrength\n this.isForceLinkUpdateNeeded = true\n }\n\n /**\n * Sets the point clusters for the graph.\n *\n * @param {(number | undefined)[]} pointClusters - Array of cluster indices for each point in the graph.\n * - Index: Each index corresponds to a point.\n * - Values: Integers starting from 0; `undefined` indicates that a point does not belong to any cluster and will not be affected by cluster forces.\n * @example\n * `[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.\n * Points 4 is unclustered.\n * @note Clusters without specified positions via `setClusterPositions` will be positioned at their centermass by default.\n */\n public setPointClusters (pointClusters: (number | undefined)[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointClusters(pointClusters))) return\n this.graph.inputPointClusters = pointClusters\n this.isPointClusterUpdateNeeded = true\n }\n\n /**\n * Sets the positions of the point clusters for the graph.\n *\n * @param {(number | undefined)[]} clusterPositions - Array of cluster positions.\n * - Every two elements represent the x and y coordinates for a cluster position.\n * - `undefined` means the cluster's position is not defined and will use centermass positioning instead.\n * @example\n * `[10, 20, 30, 40, undefined, undefined]` places the first cluster at (10, 20) and the second at (30, 40);\n * the third cluster will be positioned at its centermass automatically.\n */\n public setClusterPositions (clusterPositions: (number | undefined)[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setClusterPositions(clusterPositions))) return\n this.graph.inputClusterPositions = clusterPositions\n this.isPointClusterUpdateNeeded = true\n }\n\n /**\n * Sets the force strength coefficients for clustering points in the graph.\n *\n * This method allows you to customize the forces acting on individual points during the clustering process.\n * The force coefficients determine the strength of the forces applied to each point.\n *\n * @param {Float32Array} clusterStrength - A Float32Array of force strength coefficients for each point in the format [coeff1, coeff2, ..., coeffn],\n * where `n` is the index of the point.\n * 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.\n */\n public setPointClusterStrength (clusterStrength: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointClusterStrength(clusterStrength))) return\n this.graph.inputClusterStrength = clusterStrength\n this.isPointClusterUpdateNeeded = true\n }\n\n /**\n * Sets which points are pinned (fixed) in position.\n *\n * Pinned points:\n * - Do not move due to physics forces (gravity, repulsion, link forces, etc.)\n * - Still participate in force calculations (other nodes are attracted to/repelled by them)\n * - Can still be dragged by the user if `enableDrag` is true\n *\n * @param {number[] | null} pinnedIndices - Array of point indices to pin. Set to `[]` or `null` to unpin all points.\n * @example\n * // Pin points 0 and 5\n * graph.setPinnedPoints([0, 5])\n *\n * // Unpin all points\n * graph.setPinnedPoints([])\n * graph.setPinnedPoints(null)\n */\n public setPinnedPoints (pinnedIndices: number[] | null): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPinnedPoints(pinnedIndices))) return\n this.graph.inputPinnedPoints = pinnedIndices && pinnedIndices.length > 0 ? pinnedIndices : undefined\n this.points?.updatePinnedStatus()\n }\n\n /**\n * Renders the graph and starts rendering.\n * Does NOT modify simulation state - use start(), stop(), pause(), unpause() to control simulation.\n *\n * @param {number} [simulationAlpha] - Optional alpha value to set.\n * - If 0: Sets alpha to 0, simulation stops after one frame (graph becomes static).\n * - If positive: Sets alpha to that value.\n * - If undefined: Keeps current alpha value.\n */\n public render (simulationAlpha?: number): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.render(simulationAlpha))) return\n this.graph.update()\n const { fitViewOnInit, fitViewDelay, fitViewPadding, fitViewDuration, fitViewByPointsInRect, fitViewByPointIndices, initialZoomLevel } = this.config\n if (!this.graph.pointsNumber && !this.graph.linksNumber) {\n this.stopFrames()\n select(this.canvas).style('cursor', null)\n if (this.device) {\n const clearPass = this.device.beginRenderPass({\n clearColor: this.store.backgroundColor,\n clearDepth: 1,\n clearStencil: 0,\n })\n clearPass.end()\n this.device.submit()\n }\n return\n }\n\n // If `initialZoomLevel` is set, we don't need to fit the view\n if (this._isFirstRenderAfterInit && fitViewOnInit && initialZoomLevel === undefined) {\n this._fitViewOnInitTimeoutID = window.setTimeout(() => {\n if (fitViewByPointIndices) this.fitViewByPointIndices(fitViewByPointIndices, fitViewDuration, fitViewPadding)\n else if (fitViewByPointsInRect) {\n this.setZoomTransformByPointPositions(\n new Float32Array(this.flatten(fitViewByPointsInRect)),\n fitViewDuration,\n undefined,\n fitViewPadding\n )\n } else this.fitView(fitViewDuration, fitViewPadding)\n }, fitViewDelay)\n }\n // Update graph and start frames\n this.update(simulationAlpha)\n this.startFrames()\n\n this._isFirstRenderAfterInit = false\n }\n\n /**\n * Center the view on a point and zoom in, by point index.\n * @param index The index of the point in the array of points.\n * @param duration Duration of the animation transition in milliseconds (`700` by default).\n * @param scale Scale value to zoom in or out (`3` by default).\n * @param canZoomOut Set to `false` to prevent zooming out from the point (`true` by default).\n */\n public zoomToPointByIndex (index: number, duration = 700, scale = defaultScaleToZoom, canZoomOut = true): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.zoomToPointByIndex(index, duration, scale, canZoomOut))) return\n if (!this.device || !this.points || !this.canvasD3Selection) return\n const { store: { screenSize } } = this\n const positionPixels = readPixels(this.device, this.points.currentPositionFbo as Framebuffer)\n if (index === undefined) return\n const posX = positionPixels[index * 4 + 0]\n const posY = positionPixels[index * 4 + 1]\n if (posX === undefined || posY === undefined) return\n const distance = this.zoomInstance.getDistanceToPoint([posX, posY])\n const zoomLevel = canZoomOut ? scale : Math.max(this.getZoomLevel(), scale)\n if (distance < Math.min(screenSize[0], screenSize[1])) {\n this.setZoomTransformByPointPositions(new Float32Array([posX, posY]), duration, zoomLevel)\n } else {\n const transform = this.zoomInstance.getTransform([posX, posY], zoomLevel)\n const middle = this.zoomInstance.getMiddlePointTransform([posX, posY])\n this.canvasD3Selection\n .transition()\n .ease(easeQuadIn)\n .duration(duration / 2)\n .call(this.zoomInstance.behavior.transform, middle)\n .transition()\n .ease(easeQuadOut)\n .duration(duration / 2)\n .call(this.zoomInstance.behavior.transform, transform)\n }\n }\n\n /**\n * Zoom the view in or out to the specified zoom level.\n * @param value Zoom level\n * @param duration Duration of the zoom in/out transition.\n */\n\n public zoom (value: number, duration = 0): void {\n if (this._isDestroyed) return\n this.setZoomLevel(value, duration)\n }\n\n /**\n * Zoom the view in or out to the specified zoom level.\n * @param value Zoom level\n * @param duration Duration of the zoom in/out transition.\n */\n public setZoomLevel (value: number, duration = 0): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setZoomLevel(value, duration))) return\n\n if (!this.canvasD3Selection) return\n\n if (duration === 0) {\n this.canvasD3Selection\n .call(this.zoomInstance.behavior.scaleTo, value)\n } else {\n this.canvasD3Selection\n .transition()\n .duration(duration)\n .call(this.zoomInstance.behavior.scaleTo, value)\n }\n }\n\n /**\n * Get zoom level.\n * @returns Zoom level value of the view.\n */\n public getZoomLevel (): number {\n if (this._isDestroyed) return 0\n return this.zoomInstance.eventTransform.k\n }\n\n /**\n * Get current X and Y coordinates of the points.\n * @returns Array of point positions.\n */\n public getPointPositions (): number[] {\n if (this._isDestroyed || !this.device || !this.points) return []\n if (this.graph.pointsNumber === undefined) return []\n const positions: number[] = []\n const pointPositionsPixels = readPixels(this.device, this.points.currentPositionFbo as Framebuffer)\n positions.length = this.graph.pointsNumber * 2\n for (let i = 0; i < this.graph.pointsNumber; i += 1) {\n const posX = pointPositionsPixels[i * 4 + 0]\n const posY = pointPositionsPixels[i * 4 + 1]\n if (posX !== undefined && posY !== undefined) {\n positions[i * 2] = posX\n positions[i * 2 + 1] = posY\n }\n }\n return positions\n }\n\n /**\n * Get current X and Y coordinates of the clusters.\n * @returns Array of point cluster.\n */\n public getClusterPositions (): number[] {\n if (this._isDestroyed || !this.device || !this.clusters) return []\n if (this.graph.pointClusters === undefined || this.clusters.clusterCount === undefined) return []\n this.clusters.calculateCentermass()\n const positions: number[] = []\n const clusterPositionsPixels = readPixels(this.device, this.clusters.centermassFbo as Framebuffer)\n positions.length = this.clusters.clusterCount * 2\n for (let i = 0; i < positions.length / 2; i += 1) {\n const sumX = clusterPositionsPixels[i * 4 + 0]\n const sumY = clusterPositionsPixels[i * 4 + 1]\n const sumN = clusterPositionsPixels[i * 4 + 2]\n if (sumX !== undefined && sumY !== undefined && sumN !== undefined) {\n positions[i * 2] = sumX / sumN\n positions[i * 2 + 1] = sumY / sumN\n }\n }\n return positions\n }\n\n /**\n * Center and zoom in/out the view to fit all points in the scene.\n * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default).\n * @param padding Padding around the viewport in percentage (`0.1` by default).\n */\n public fitView (duration = 250, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.fitView(duration, padding))) return\n\n this.setZoomTransformByPointPositions(new Float32Array(this.getPointPositions()), duration, undefined, padding)\n }\n\n /**\n * Center and zoom in/out the view to fit points by their indices in the scene.\n * @param indices Point indices to fit in the view.\n * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default).\n * @param padding Padding around the viewport in percentage (`0.1` by default).\n */\n public fitViewByPointIndices (indices: number[], duration = 250, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.fitViewByPointIndices(indices, duration, padding))) return\n const positionsArray = this.getPointPositions()\n const positions = new Float32Array(indices.length * 2)\n for (const [i, index] of indices.entries()) {\n positions[i * 2] = positionsArray[index * 2] as number\n positions[i * 2 + 1] = positionsArray[index * 2 + 1] as number\n }\n this.setZoomTransformByPointPositions(positions, duration, undefined, padding)\n }\n\n /**\n * Center and zoom in/out the view to fit points by their positions in the scene.\n * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]`.\n * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default).\n * @param padding Padding around the viewport in percentage (`0.1` by default).\n */\n public fitViewByPointPositions (positions: number[], duration = 250, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.fitViewByPointPositions(positions, duration, padding))) return\n\n this.setZoomTransformByPointPositions(new Float32Array(positions), duration, undefined, padding)\n }\n\n /**\n * Sets the zoom transform so that the given point positions fit in the viewport, with optional animation.\n *\n * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]`.\n * @param duration Animation duration in milliseconds. Default `250`.\n * @param scale Optional scale factor; if omitted, scale is chosen to fit the positions.\n * @param padding Padding around the viewport as a fraction (e.g. `0.1` = 10%). Default `0.1`.\n */\n public setZoomTransformByPointPositions (positions: Float32Array, duration = 250, scale?: number, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setZoomTransformByPointPositions(positions, duration, scale, padding))) return\n\n this.resizeCanvas()\n const transform = this.zoomInstance.getTransform(positions, scale, padding)\n this.canvasD3Selection\n ?.transition()\n .ease(easeQuadInOut)\n .duration(duration)\n .call(this.zoomInstance.behavior.transform, transform)\n }\n\n /**\n * Get points indices inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas.\n * @returns A Float32Array containing the indices of points inside a rectangular area.\n */\n public getPointsInRect (selection: [[number, number], [number, number]]): Float32Array {\n if (this._isDestroyed || !this.device || !this.points) return new Float32Array()\n const h = this.store.screenSize[1]\n this.store.selectedArea = [[selection[0][0], (h - selection[1][1])], [selection[1][0], (h - selection[0][1])]]\n this.points.findPointsOnAreaSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n\n return pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n }\n\n /**\n * Get points indices inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas.\n * @returns A Float32Array containing the indices of points inside a rectangular area.\n * @deprecated Use `getPointsInRect` instead. This method will be removed in a future version.\n */\n public getPointsInRange (selection: [[number, number], [number, number]]): Float32Array {\n return this.getPointsInRect(selection)\n }\n\n /**\n * Get points indices inside a polygon area.\n * @param polygonPath - Array of points `[[x1, y1], [x2, y2], ..., [xn, yn]]` that defines the polygon.\n * The coordinates should be from 0 to the width/height of the canvas.\n * @returns A Float32Array containing the indices of points inside the polygon area.\n */\n public getPointsInPolygon (polygonPath: [number, number][]): Float32Array {\n if (this._isDestroyed || !this.device || !this.points) return new Float32Array()\n if (polygonPath.length < 3) return new Float32Array() // Need at least 3 points for a polygon\n\n const h = this.store.screenSize[1]\n // Convert coordinates to WebGL coordinate system (flip Y)\n const convertedPath = polygonPath.map(([x, y]) => [x, h - y] as [number, number])\n this.points.updatePolygonPath(convertedPath)\n this.points.findPointsOnPolygonSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n\n return pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n }\n\n /** Select points inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas. */\n public selectPointsInRect (selection: [[number, number], [number, number]] | null): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.selectPointsInRect(selection))) return\n if (!this.device || !this.points) return\n if (selection) {\n const h = this.store.screenSize[1]\n this.store.selectedArea = [[selection[0][0], (h - selection[1][1])], [selection[1][0], (h - selection[0][1])]]\n this.points.findPointsOnAreaSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n this.store.selectedIndices = pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n } else {\n this.store.selectedIndices = null\n }\n this.points.updateGreyoutStatus()\n }\n\n /** Select points inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas.\n * @deprecated Use `selectPointsInRect` instead. This method will be removed in a future version.\n */\n public selectPointsInRange (selection: [[number, number], [number, number]] | null): void {\n return this.selectPointsInRect(selection)\n }\n\n /** Select points inside a polygon area.\n * @param polygonPath - Array of points `[[x1, y1], [x2, y2], ..., [xn, yn]]` that defines the polygon.\n * The coordinates should be from 0 to the width/height of the canvas.\n * Set to null to clear selection. */\n public selectPointsInPolygon (polygonPath: [number, number][] | null): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.selectPointsInPolygon(polygonPath))) return\n if (!this.device || !this.points) return\n if (polygonPath) {\n if (polygonPath.length < 3) {\n console.warn('Polygon path requires at least 3 points to form a polygon.')\n return\n }\n\n const h = this.store.screenSize[1]\n // Convert coordinates to WebGL coordinate system (flip Y)\n const convertedPath = polygonPath.map(([x, y]) => [x, h - y] as [number, number])\n this.points.updatePolygonPath(convertedPath)\n this.points.findPointsOnPolygonSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n this.store.selectedIndices = pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n } else {\n this.store.selectedIndices = null\n }\n this.points.updateGreyoutStatus()\n }\n\n /**\n * Select a point by index. If you want the adjacent points to get selected too, provide `true` as the second argument.\n * @param index The index of the point in the array of points.\n * @param selectAdjacentPoints When set to `true`, selects adjacent points (`false` by default).\n */\n public selectPointByIndex (index: number, selectAdjacentPoints = false): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.selectPointByIndex(index, selectAdjacentPoints))) return\n if (selectAdjacentPoints) {\n const adjacentIndices = this.graph.getAdjacentIndices(index) ?? []\n this.selectPointsByIndices([index, ...adjacentIndices])\n } else this.selectPointsByIndices([index])\n }\n\n /**\n * Select multiples points by their indices.\n * @param indices Array of points indices.\n */\n public selectPointsByIndices (indices?: (number | undefined)[] | null): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.selectPointsByIndices(indices))) return\n if (!this.points) return\n if (!indices) {\n this.store.selectedIndices = null\n } else if (indices.length === 0) {\n this.store.selectedIndices = new Float32Array()\n } else {\n this.store.selectedIndices = new Float32Array(indices.filter(d => d !== undefined))\n }\n\n this.points.updateGreyoutStatus()\n }\n\n /**\n * Unselect all points.\n */\n public unselectPoints (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.unselectPoints())) return\n if (!this.points) return\n this.store.selectedIndices = null\n this.points.updateGreyoutStatus()\n }\n\n /**\n * Get indices of points that are currently selected.\n * @returns Array of selected indices of points.\n */\n public getSelectedIndices (): number[] | null {\n if (this._isDestroyed) return null\n const { selectedIndices } = this.store\n if (!selectedIndices) return null\n return Array.from(selectedIndices)\n }\n\n /**\n * Get indices that are adjacent to a specific point by its index.\n * @param index Index of the point.\n * @returns Array of adjacent indices.\n */\n\n public getAdjacentIndices (index: number): number[] | undefined {\n if (this._isDestroyed) return undefined\n return this.graph.getAdjacentIndices(index)\n }\n\n /**\n * Converts the X and Y point coordinates from the space coordinate system to the screen coordinate system.\n * @param spacePosition Array of x and y coordinates in the space coordinate system.\n * @returns Array of x and y coordinates in the screen coordinate system.\n */\n public spaceToScreenPosition (spacePosition: [number, number]): [number, number] {\n if (this._isDestroyed) return [0, 0]\n return this.zoomInstance.convertSpaceToScreenPosition(spacePosition)\n }\n\n /**\n * Converts the X and Y point coordinates from the screen coordinate system to the space coordinate system.\n * @param screenPosition Array of x and y coordinates in the screen coordinate system.\n * @returns Array of x and y coordinates in the space coordinate system.\n */\n public screenToSpacePosition (screenPosition: [number, number]): [number, number] {\n if (this._isDestroyed) return [0, 0]\n return this.zoomInstance.convertScreenToSpacePosition(screenPosition)\n }\n\n /**\n * Converts the point radius value from the space coordinate system to the screen coordinate system.\n * @param spaceRadius Radius of point in the space coordinate system.\n * @returns Radius of point in the screen coordinate system.\n */\n public spaceToScreenRadius (spaceRadius: number): number {\n if (this._isDestroyed) return 0\n return this.zoomInstance.convertSpaceToScreenRadius(spaceRadius)\n }\n\n /**\n * Get point radius by its index.\n * @param index Index of the point.\n * @returns Radius of the point.\n */\n public getPointRadiusByIndex (index: number): number | undefined {\n if (this._isDestroyed) return undefined\n return this.graph.pointSizes?.[index]\n }\n\n /**\n * Track multiple point positions by their indices on each Cosmos tick.\n * @param indices Array of points indices.\n */\n public trackPointPositionsByIndices (indices: number[]): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.trackPointPositionsByIndices(indices))) return\n if (!this.points) return\n this.points.trackPointsByIndices(indices)\n }\n\n /**\n * Get current X and Y coordinates of the tracked points.\n * Do not mutate the returned map - it may affect future calls.\n * @returns A ReadonlyMap where keys are point indices and values are their corresponding X and Y coordinates in the [number, number] format.\n * @see trackPointPositionsByIndices To set which points should be tracked\n */\n public getTrackedPointPositionsMap (): ReadonlyMap<number, [number, number]> {\n if (this._isDestroyed || !this.points) return new Map()\n return this.points.getTrackedPositionsMap()\n }\n\n /**\n * Get current X and Y coordinates of the tracked points as an array.\n * @returns Array of point positions in the format [x1, y1, x2, y2, ..., xn, yn] for tracked points only.\n * The positions are ordered by the tracking indices (same order as provided to trackPointPositionsByIndices).\n * Returns an empty array if no points are being tracked.\n */\n public getTrackedPointPositionsArray (): number[] {\n if (this._isDestroyed || !this.points) return []\n return this.points.getTrackedPositionsArray()\n }\n\n /**\n * For the points that are currently visible on the screen, get a sample of point indices with their coordinates.\n * The resulting number of points will depend on the `pointSamplingDistance` configuration property,\n * and the sampled points will be evenly distributed.\n * @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.\n */\n public getSampledPointPositionsMap (): Map<number, [number, number]> {\n if (this._isDestroyed || !this.points) return new Map()\n return this.points.getSampledPointPositionsMap()\n }\n\n /**\n * For the points that are currently visible on the screen, get a sample of point indices and positions.\n * The resulting number of points will depend on the `pointSamplingDistance` configuration property,\n * and the sampled points will be evenly distributed.\n * @returns An object containing arrays of point indices and positions.\n */\n public getSampledPoints (): { indices: number[]; positions: number[] } {\n if (this._isDestroyed || !this.points) return { indices: [], positions: [] }\n return this.points.getSampledPoints()\n }\n\n /**\n * Gets the X-axis of rescaling function.\n *\n * This scale is automatically created when position rescaling is enabled.\n */\n public getScaleX (): ((x: number) => number) | undefined {\n if (this._isDestroyed || !this.points) return undefined\n return this.points.scaleX\n }\n\n /**\n * Gets the Y-axis of rescaling function.\n *\n * This scale is automatically created when position rescaling is enabled.\n */\n public getScaleY (): ((y: number) => number) | undefined {\n if (this._isDestroyed || !this.points) return undefined\n return this.points.scaleY\n }\n\n /**\n * Start the simulation.\n * This only controls the simulation state, not rendering.\n * @param alpha Value from 0 to 1. The higher the value, the more initial energy the simulation will get.\n */\n public start (alpha = 1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.start(alpha))) return\n\n if (!this.graph.pointsNumber) return\n\n // Always set simulation as running when start() is called\n this.store.isSimulationRunning = true\n this.store.simulationProgress = 0\n this.store.alpha = alpha\n this.config.onSimulationStart?.()\n\n // Note: Does NOT start frames - that's handled separately\n }\n\n /**\n * Stop the simulation. This stops the simulation and resets its state.\n * Use start() to begin a new simulation cycle.\n */\n public stop (): void {\n if (this._isDestroyed) return\n this.store.isSimulationRunning = false\n this.store.simulationProgress = 0\n this.store.alpha = 0\n this.config.onSimulationEnd?.()\n }\n\n /**\n * Pause the simulation. When paused, the simulation stops running\n * but preserves its current state (progress, alpha).\n * Can be resumed using the unpause method.\n */\n public pause (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.pause())) return\n this.store.isSimulationRunning = false\n this.config.onSimulationPause?.()\n }\n\n /**\n * Unpause the simulation. This method resumes a paused\n * simulation and continues its execution.\n */\n public unpause (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.unpause())) return\n this.store.isSimulationRunning = true\n this.config.onSimulationUnpause?.()\n }\n\n /**\n * Restart/Resume the simulation. This method unpauses a paused\n * simulation and resumes its execution.\n * @deprecated Use `unpause()` instead. This method will be removed in a future version.\n */\n public restart (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.restart())) return\n this.store.isSimulationRunning = true\n this.config.onSimulationRestart?.()\n }\n\n /**\n * Run one step of the simulation manually.\n * Works even when the simulation is paused.\n */\n public step (): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.step())) return\n\n if (!this.config.enableSimulation) return\n if (!this.store.pointsTextureSize) return\n\n // Run one simulation step, forcing execution regardless of isSimulationRunning\n this.runSimulationStep(true)\n }\n\n /**\n * Destroy this Cosmos instance.\n */\n public destroy (): void {\n if (this._isDestroyed) return\n this._isDestroyed = true\n window.clearTimeout(this._fitViewOnInitTimeoutID)\n this.stopFrames()\n\n // Remove all event listeners\n if (this.canvasD3Selection) {\n this.canvasD3Selection\n .on('mouseenter.cosmos', null)\n .on('mousemove.cosmos', null)\n .on('mouseleave.cosmos', null)\n .on('click', null)\n .on('mousemove', null)\n .on('contextmenu', null)\n .on('.drag', null)\n .on('.zoom', null)\n }\n\n select(document)\n .on('keydown.cosmos', null)\n .on('keyup.cosmos', null)\n\n if (this.zoomInstance?.behavior) {\n this.zoomInstance.behavior\n .on('start.detect', null)\n .on('zoom.detect', null)\n .on('end.detect', null)\n }\n\n if (this.dragInstance?.behavior) {\n this.dragInstance.behavior\n .on('start.detect', null)\n .on('drag.detect', null)\n .on('end.detect', null)\n }\n\n this.fpsMonitor?.destroy()\n\n // Destroy all module resources before destroying the device\n this.points?.destroy()\n this.lines?.destroy()\n this.clusters?.destroy()\n this.forceGravity?.destroy()\n this.forceCenter?.destroy()\n this.forceManyBody?.destroy()\n this.forceLinkIncoming?.destroy()\n this.forceLinkOutgoing?.destroy()\n this.forceMouse?.destroy()\n\n if (this.device) {\n // Only clear and destroy the device if Graph owns it\n if (this.shouldDestroyDevice) {\n // Clears the canvas after particle system is destroyed\n const clearPass = this.device.beginRenderPass({\n clearColor: this.store.backgroundColor,\n clearDepth: 1,\n clearStencil: 0,\n })\n clearPass.end()\n this.device.submit()\n this.device.destroy()\n }\n }\n\n // Only remove canvas if Graph owns the device (canvas was created by Graph)\n if (this.shouldDestroyDevice && this.canvas && this.canvas.parentNode) {\n this.canvas.parentNode.removeChild(this.canvas)\n }\n\n if (this.attributionDivElement && this.attributionDivElement.parentNode) {\n this.attributionDivElement.parentNode.removeChild(this.attributionDivElement)\n }\n\n document.getElementById('gl-bench-style')?.remove()\n\n this.canvasD3Selection = undefined\n this.attributionDivElement = undefined\n }\n\n /**\n * Updates and recreates the graph visualization based on pending changes.\n */\n public create (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.create())) return\n if (!this.points) return\n if (!this.lines) return\n if (this.isPointPositionsUpdateNeeded) this.points.updatePositions()\n if (this.isPointColorUpdateNeeded) this.points.updateColor()\n if (this.isPointSizeUpdateNeeded) this.points.updateSize()\n if (this.isPointShapeUpdateNeeded) this.points.updateShape()\n if (this.isPointImageIndicesUpdateNeeded) this.points.updateImageIndices()\n if (this.isPointImageSizesUpdateNeeded) this.points.updateImageSizes()\n\n if (this.isLinksUpdateNeeded) this.lines.updatePointsBuffer()\n if (this.isLinkColorUpdateNeeded) this.lines.updateColor()\n if (this.isLinkWidthUpdateNeeded) this.lines.updateWidth()\n if (this.isLinkArrowUpdateNeeded) this.lines.updateArrow()\n\n if (this.isForceManyBodyUpdateNeeded) this.forceManyBody?.create()\n if (this.isForceLinkUpdateNeeded) {\n this.forceLinkIncoming?.create(LinkDirection.INCOMING)\n this.forceLinkOutgoing?.create(LinkDirection.OUTGOING)\n }\n if (this.isForceCenterUpdateNeeded) this.forceCenter?.create()\n if (this.isPointClusterUpdateNeeded) this.clusters?.create()\n\n this.isPointPositionsUpdateNeeded = false\n this.isPointColorUpdateNeeded = false\n this.isPointSizeUpdateNeeded = false\n this.isPointShapeUpdateNeeded = false\n this.isPointImageIndicesUpdateNeeded = false\n this.isPointImageSizesUpdateNeeded = false\n this.isLinksUpdateNeeded = false\n this.isLinkColorUpdateNeeded = false\n this.isLinkWidthUpdateNeeded = false\n this.isLinkArrowUpdateNeeded = false\n this.isPointClusterUpdateNeeded = false\n this.isForceManyBodyUpdateNeeded = false\n this.isForceLinkUpdateNeeded = false\n this.isForceCenterUpdateNeeded = false\n }\n\n /**\n * Converts an array of tuple positions to a single array containing all coordinates sequentially\n * @param pointPositions An array of tuple positions\n * @returns A flatten array of coordinates\n */\n public flatten (pointPositions: [number, number][]): number[] {\n return pointPositions.flat()\n }\n\n /**\n * Converts a flat array of point positions to a tuple pairs representing coordinates\n * @param pointPositions A flattened array of coordinates\n * @returns An array of tuple positions\n */\n public pair (pointPositions: number[]): [number, number][] {\n const arr = new Array(pointPositions.length / 2) as [number, number][]\n for (let i = 0; i < pointPositions.length / 2; i++) {\n arr[i] = [pointPositions[i * 2] as number, pointPositions[i * 2 + 1] as number]\n }\n\n return arr\n }\n\n /**\n * Ensures device is initialized before executing a method.\n * If device is not ready, queues the method to run after initialization.\n * @param callback - Function to execute once device is ready\n * @returns true if device was not ready and operation was queued, false if device is ready\n */\n private ensureDevice (callback: () => void): boolean {\n if (!this.device) {\n this.deviceInitPromise\n .then(() => {\n if (this._isDestroyed) return\n callback()\n })\n .catch(error => {\n console.error('Device initialization failed', error)\n })\n return true\n }\n return false\n }\n\n /**\n * Validates that a device has the required HTMLCanvasElement canvas context.\n * Cosmos requires an HTMLCanvasElement canvas context and does not support\n * OffscreenCanvas or compute-only devices.\n * @param device - The device to validate\n * @returns The validated canvas context (guaranteed to be non-null and HTMLCanvasElement type)\n * @throws Error if the device does not meet Cosmos requirements\n */\n private validateDevice (device: Device): NonNullable<Device['canvasContext']> {\n const deviceCanvasContext = device.canvasContext\n // Cosmos requires an HTMLCanvasElement canvas context.\n // OffscreenCanvas and compute-only devices are not supported.\n if (deviceCanvasContext === null || deviceCanvasContext.type === 'offscreen-canvas') {\n throw new Error('Device must have an HTMLCanvasElement canvas context. OffscreenCanvas and compute-only devices are not supported.')\n }\n return deviceCanvasContext\n }\n\n /**\n * Internal device creation method\n * Graph class decides what device to create with sensible defaults\n */\n private async createDevice (\n canvas: HTMLCanvasElement\n ): Promise<Device> {\n return await luma.createDevice({\n type: 'webgl',\n adapters: [webgl2Adapter],\n createCanvasContext: {\n canvas, // Provide existing canvas\n useDevicePixels: this.config.pixelRatio, // Use config pixelRatio value\n autoResize: true,\n width: undefined,\n height: undefined,\n },\n })\n }\n\n /**\n * Updates and recreates the graph visualization based on pending changes.\n *\n * @param simulationAlpha - Optional alpha value to set. If not provided, keeps current alpha.\n */\n private update (simulationAlpha = this.store.alpha): void {\n const { graph } = this\n this.store.pointsTextureSize = Math.ceil(Math.sqrt(graph.pointsNumber ?? 0))\n this.store.linksTextureSize = Math.ceil(Math.sqrt((graph.linksNumber ?? 0) * 2))\n this.create()\n this.initPrograms()\n this.store.hoveredPoint = undefined\n this.store.alpha = simulationAlpha\n }\n\n /**\n * Runs one step of the simulation (forces, position updates, alpha decay).\n * This is the core simulation logic that can be called by step() or during rendering.\n *\n * @param forceExecution - Controls whether to run the simulation step when paused.\n * - If true: Always runs the simulation step, even when isSimulationRunning is false.\n * Used by step() to allow manual stepping while the simulation is paused.\n * - If false: Only runs if isSimulationRunning is true. Used during rendering\n * to respect pause/unpause state.\n */\n private runSimulationStep (forceExecution = false): void {\n const { config: { simulationGravity, simulationCenter, enableSimulation }, store: { isSimulationRunning } } = this\n\n if (!enableSimulation) return\n\n // Right-click repulsion (runs regardless of isSimulationRunning)\n if (this.isRightClickMouse && this.config.enableRightClickRepulsion) {\n this.forceMouse?.run()\n this.points?.updatePosition()\n }\n\n // Main simulation forces\n // If forceExecution is true (from step()), always run\n // Otherwise, respect isSimulationRunning and zoom state\n const shouldRunSimulation = forceExecution ||\n (isSimulationRunning && !(this.zoomInstance.isRunning && !this.config.enableSimulationDuringZoom))\n\n if (shouldRunSimulation) {\n if (simulationGravity) {\n this.forceGravity?.run()\n this.points?.updatePosition()\n }\n\n if (simulationCenter) {\n this.forceCenter?.run()\n this.points?.updatePosition()\n }\n\n this.forceManyBody?.run()\n this.points?.updatePosition()\n\n if (this.store.linksTextureSize) {\n this.forceLinkIncoming?.run()\n this.points?.updatePosition()\n this.forceLinkOutgoing?.run()\n this.points?.updatePosition()\n }\n\n if (this.graph.pointClusters || this.graph.clusterPositions) {\n this.clusters?.run()\n this.points?.updatePosition()\n }\n\n // Alpha decay and progress\n this.store.alpha += this.store.addAlpha(this.config.simulationDecay ?? defaultConfigValues.simulation.decay)\n if (this.isRightClickMouse && this.config.enableRightClickRepulsion) {\n this.store.alpha = Math.max(this.store.alpha, 0.1)\n }\n this.store.simulationProgress = Math.sqrt(Math.min(1, ALPHA_MIN / this.store.alpha))\n\n this.config.onSimulationTick?.(\n this.store.alpha,\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position\n )\n }\n\n // Track points (runs regardless of simulation state)\n this.points?.trackPoints()\n }\n\n private initPrograms (): void {\n if (this._isDestroyed || !this.points || !this.lines || !this.clusters) return\n this.points.initPrograms()\n this.lines.initPrograms()\n this.forceGravity?.initPrograms()\n this.forceManyBody?.initPrograms()\n this.forceCenter?.initPrograms()\n this.forceLinkIncoming?.initPrograms()\n this.forceLinkOutgoing?.initPrograms()\n this.forceMouse?.initPrograms()\n this.clusters.initPrograms()\n }\n\n /**\n * The rendering loop - schedules itself to run continuously\n */\n private frame (): void {\n if (this._isDestroyed) return\n\n // Check if simulation should end BEFORE scheduling next frame\n // This prevents one extra frame from running after simulation ends\n const { store: { alpha, isSimulationRunning } } = this\n if (alpha < ALPHA_MIN && isSimulationRunning) {\n this.end()\n }\n\n this.requestAnimationFrameId = window.requestAnimationFrame((now) => {\n this.renderFrame(now)\n\n // Continue the loop (even after simulation ends)\n if (!this._isDestroyed) {\n this.frame()\n }\n })\n }\n\n /**\n * Renders a single frame (the actual rendering logic).\n * This does NOT schedule the next frame.\n */\n private renderFrame (now?: number): void {\n if (this._isDestroyed) return\n if (!this.store.pointsTextureSize) return\n\n this.fpsMonitor?.begin()\n this.resizeCanvas()\n if (!this.dragInstance.isActive) {\n this.findHoveredItem()\n }\n\n // Run simulation step (respects isSimulationRunning)\n // When simulation ends, forces stop but rendering continues\n this.runSimulationStep(false)\n\n // Create a single render pass for drawing (points, lines, etc.)\n // Simulation will use separate render passes later\n if (this.device) {\n const backgroundColor = this.store.backgroundColor ?? [0, 0, 0, 1]\n const drawRenderPass = this.device.beginRenderPass({\n clearColor: backgroundColor,\n clearDepth: 1,\n clearStencil: 0,\n })\n\n const { config: { renderLinks } } = this\n const shouldDrawLinks =\n renderLinks !== false &&\n !!this.store.linksTextureSize &&\n !!this.graph.linksNumber &&\n this.graph.linksNumber > 0\n\n if (shouldDrawLinks) {\n this.lines?.draw(drawRenderPass)\n }\n\n this.points?.draw(drawRenderPass)\n\n if (this.dragInstance.isActive) {\n // To prevent the dragged point from suddenly jumping, run the drag function twice\n this.points?.drag()\n this.points?.drag()\n // Update tracked positions after drag, even when simulation is disabled\n this.points?.trackPoints()\n }\n\n drawRenderPass.end()\n this.device.submit()\n }\n\n this.fpsMonitor?.end(now ?? performance.now())\n\n this.currentEvent = undefined\n }\n\n private stopFrames (): void {\n if (this.requestAnimationFrameId) {\n window.cancelAnimationFrame(this.requestAnimationFrameId)\n this.requestAnimationFrameId = 0 // Reset to 0\n }\n }\n\n /**\n * Starts continuous rendering\n */\n private startFrames (): void {\n if (this._isDestroyed) return\n this.stopFrames() // Stop any existing rendering\n this.frame() // Start the loop\n }\n\n /**\n * Called automatically when simulation completes (alpha < ALPHA_MIN).\n * Rendering continues after this is called (for rendering/interaction).\n */\n private end (): void {\n this.store.isSimulationRunning = false\n this.store.simulationProgress = 1\n this.config.onSimulationEnd?.()\n // Force hover detection on next frame since points may have moved under stationary mouse\n this._shouldForceHoverDetection = true\n }\n\n private onClick (event: MouseEvent): void {\n this.config.onClick?.(\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position,\n event\n )\n\n if (this.store.hoveredPoint) {\n this.config.onPointClick?.(\n this.store.hoveredPoint.index,\n this.store.hoveredPoint.position,\n event\n )\n } else if (this.store.hoveredLinkIndex !== undefined) {\n this.config.onLinkClick?.(\n this.store.hoveredLinkIndex,\n event\n )\n } else {\n this.config.onBackgroundClick?.(\n event\n )\n }\n }\n\n private updateMousePosition (event: MouseEvent | D3DragEvent<HTMLCanvasElement, undefined, Hovered>): void {\n if (!event) return\n const mouseX = (event as MouseEvent).offsetX ?? (event as D3DragEvent<HTMLCanvasElement, undefined, Hovered>).x\n const mouseY = (event as MouseEvent).offsetY ?? (event as D3DragEvent<HTMLCanvasElement, undefined, Hovered>).y\n if (mouseX === undefined || mouseY === undefined) return\n this.store.mousePosition = this.zoomInstance.convertScreenToSpacePosition([mouseX, mouseY])\n this.store.screenMousePosition = [mouseX, (this.store.screenSize[1] - mouseY)]\n }\n\n private onMouseMove (event: MouseEvent): void {\n this.currentEvent = event\n this.updateMousePosition(event)\n this.isRightClickMouse = event.which === 3\n this.config.onMouseMove?.(\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position,\n this.currentEvent\n )\n }\n\n private onContextMenu (event: MouseEvent): void {\n event.preventDefault()\n\n this.config.onContextMenu?.(\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position,\n event\n )\n\n if (this.store.hoveredPoint) {\n this.config.onPointContextMenu?.(\n this.store.hoveredPoint.index,\n this.store.hoveredPoint.position,\n event\n )\n } else if (this.store.hoveredLinkIndex !== undefined) {\n this.config.onLinkContextMenu?.(\n this.store.hoveredLinkIndex,\n event\n )\n } else {\n this.config.onBackgroundContextMenu?.(\n event\n )\n }\n }\n\n private resizeCanvas (forceResize = false): void {\n if (this._isDestroyed) return\n const w = this.canvas.clientWidth\n const h = this.canvas.clientHeight\n const [prevW, prevH] = this.store.screenSize\n\n // Check if CSS size changed (luma.gl's autoResize handles canvas.width/height automatically)\n if (forceResize || prevW !== w || prevH !== h) {\n const { k } = this.zoomInstance.eventTransform\n const centerPosition = this.zoomInstance.convertScreenToSpacePosition([prevW / 2, prevH / 2])\n\n this.store.updateScreenSize(w, h)\n // Note: canvas.width and canvas.height are managed by luma.gl's autoResize\n // We only update our internal state and dependent components\n this.canvasD3Selection\n ?.call(this.zoomInstance.behavior.transform, this.zoomInstance.getTransform(centerPosition, k))\n this.points?.updateSampledPointsGrid()\n // Only update link index FBO if link hovering is enabled\n if (this.store.isLinkHoveringEnabled) {\n this.lines?.updateLinkIndexFbo()\n }\n }\n }\n\n private updateZoomDragBehaviors (): void {\n if (this.config.enableDrag) {\n this.canvasD3Selection?.call(this.dragInstance.behavior)\n } else {\n this.canvasD3Selection\n ?.call(this.dragInstance.behavior)\n .on('.drag', null)\n }\n\n if (this.config.enableZoom) {\n this.canvasD3Selection?.call(this.zoomInstance.behavior)\n } else {\n this.canvasD3Selection\n ?.call(this.zoomInstance.behavior)\n .on('wheel.zoom', null)\n }\n }\n\n private findHoveredItem (): void {\n if (this._isDestroyed || !this._isMouseOnCanvas) return\n if (this._findHoveredItemExecutionCount < MAX_HOVER_DETECTION_DELAY) {\n this._findHoveredItemExecutionCount += 1\n return\n }\n\n // Check if mouse has moved significantly since last hover detection\n const deltaX = Math.abs(this._lastMouseX - this._lastCheckedMouseX)\n const deltaY = Math.abs(this._lastMouseY - this._lastCheckedMouseY)\n const mouseMoved = deltaX > MIN_MOUSE_MOVEMENT_THRESHOLD || deltaY > MIN_MOUSE_MOVEMENT_THRESHOLD\n\n // Skip if mouse hasn't moved AND not forced\n if (!mouseMoved && !this._shouldForceHoverDetection) {\n return\n }\n\n // Update last checked position\n this._lastCheckedMouseX = this._lastMouseX\n this._lastCheckedMouseY = this._lastMouseY\n\n // Reset force flag after use\n this._shouldForceHoverDetection = false\n\n this._findHoveredItemExecutionCount = 0\n this.findHoveredPoint()\n\n if (this.graph.linksNumber && this.store.isLinkHoveringEnabled) {\n this.findHoveredLine()\n } else if (this.store.hoveredLinkIndex !== undefined) {\n // Clear stale hoveredLinkIndex when there are no links\n const wasHovered = this.store.hoveredLinkIndex !== undefined\n this.store.hoveredLinkIndex = undefined\n if (wasHovered && this.config.onLinkMouseOut) {\n this.config.onLinkMouseOut(this.currentEvent)\n }\n }\n\n this.updateCanvasCursor()\n }\n\n private findHoveredPoint (): void {\n if (this._isDestroyed || !this.device || !this.points) return\n this.points.findHoveredPoint()\n let isMouseover = false\n let isMouseout = false\n const pixels = readPixels(this.device, this.points.hoveredFbo as Framebuffer, 0, 0, 2, 2)\n // Shader writes: rgba = vec4(index, size, pointPosition.xy)\n const hoveredIndex = pixels[0] as number\n const pointSize = pixels[1] as number\n const pointX = pixels[2] as number\n const pointY = pixels[3] as number\n\n if (pointSize > 0) {\n if (this.store.hoveredPoint === undefined || this.store.hoveredPoint.index !== hoveredIndex) {\n isMouseover = true\n }\n this.store.hoveredPoint = {\n index: hoveredIndex,\n position: [pointX, pointY],\n }\n } else {\n if (this.store.hoveredPoint) isMouseout = true\n this.store.hoveredPoint = undefined\n }\n\n if (isMouseover && this.store.hoveredPoint) {\n this.config.onPointMouseOver?.(\n this.store.hoveredPoint.index,\n this.store.hoveredPoint.position,\n this.currentEvent,\n this.store.selectedIndices?.includes(this.store.hoveredPoint.index) ?? false\n )\n }\n if (isMouseout) this.config.onPointMouseOut?.(this.currentEvent)\n }\n\n private findHoveredLine (): void {\n if (this._isDestroyed || !this.lines) return\n if (this.store.hoveredPoint) {\n if (this.store.hoveredLinkIndex !== undefined) {\n this.store.hoveredLinkIndex = undefined\n this.config.onLinkMouseOut?.(this.currentEvent)\n }\n return\n }\n this.lines.findHoveredLine()\n let isMouseover = false\n let isMouseout = false\n\n if (!this.device) return\n const pixels = readPixels(this.device, this.lines.hoveredLineIndexFbo!)\n const hoveredLineIndex = pixels[0] as number\n\n if (hoveredLineIndex >= 0) {\n if (this.store.hoveredLinkIndex !== hoveredLineIndex) isMouseover = true\n this.store.hoveredLinkIndex = hoveredLineIndex\n } else {\n if (this.store.hoveredLinkIndex !== undefined) isMouseout = true\n this.store.hoveredLinkIndex = undefined\n }\n\n if (isMouseover && this.store.hoveredLinkIndex !== undefined) {\n this.config.onLinkMouseOver?.(this.store.hoveredLinkIndex)\n }\n if (isMouseout) this.config.onLinkMouseOut?.(this.currentEvent)\n }\n\n private updateCanvasCursor (): void {\n const { hoveredPointCursor, hoveredLinkCursor } = this.config\n if (this.dragInstance.isActive) select(this.canvas).style('cursor', 'grabbing')\n else if (this.store.hoveredPoint) {\n if (!this.config.enableDrag || this.store.isSpaceKeyPressed) select(this.canvas).style('cursor', hoveredPointCursor)\n else select(this.canvas).style('cursor', 'grab')\n } else if (this.store.isLinkHoveringEnabled && this.store.hoveredLinkIndex !== undefined) {\n select(this.canvas).style('cursor', hoveredLinkCursor)\n } else select(this.canvas).style('cursor', null)\n }\n\n private addAttribution (): void {\n if (!this.config.attribution) return\n this.attributionDivElement = document.createElement('div')\n this.attributionDivElement.style.cssText = `\n user-select: none;\n position: absolute;\n bottom: 0;\n right: 0;\n color: var(--cosmosgl-attribution-color);\n margin: 0 0.6rem 0.6rem 0;\n font-size: 0.7rem;\n font-family: inherit;\n `\n // Sanitize the attribution HTML content to prevent XSS attacks\n // Use more permissive settings for attribution since it's controlled by the library user\n this.attributionDivElement.innerHTML = sanitizeHtml(this.config.attribution, {\n ALLOWED_TAGS: ['a', 'b', 'i', 'em', 'strong', 'span', 'div', 'p', 'br', 'img'],\n ALLOWED_ATTR: ['href', 'target', 'class', 'id', 'style', 'src', 'alt', 'title'],\n })\n this.store.div?.appendChild(this.attributionDivElement)\n }\n}\n\nexport type { GraphConfigInterface } from './config'\nexport { PointShape } from './modules/GraphData'\n\nexport * from './helper'\n"],"names":["defaultPointColor","defaultGreyoutPointOpacity","defaultGreyoutPointColor","defaultPointOpacity","defaultPointSize","defaultLinkColor","defaultGreyoutLinkOpacity","defaultLinkOpacity","defaultLinkWidth","defaultBackgroundColor","defaultConfigValues","hoveredPointRingOpacity","focusedPointRingOpacity","defaultScaleToZoom","GLEnum","ALPHA_MIN","MAX_POINT_SIZE","MAX_HOVER_DETECTION_DELAY","MIN_MOUSE_MOVEMENT_THRESHOLD","Store","mat3","scaleLinear","Random","decay","color","brightness","rgbToBrightness","seed","min","max","configSpaceSize","webglMaxTextureSize","minSpaceSize","width","height","adjustedSpaceSize","x","y","convertedRgba","getRgbaColor","config","index","isFunction","a","isArray","isObject","isAClassInstance","isPlainObject","value","rgba","d3Color","rgb","r","g","b","readPixels","device","fbo","sourceX","sourceY","sourceWidth","sourceHeight","getMaxPointSize","pixelRatio","range","GL","clamp","num","isNumber","sanitizeHtml","html","options","DOMPurify","GraphConfig","configParameter","current","next","key","CoreModule","store","data","points","calculateCentermassFrag$1","calculateCentermassVert$1","forceFrag$5","createIndexesForBuffer","textureSize","indexes","i","getBytesPerRow","format","formatInfo","textureFormatDecoder","updateVert","ForceCenter","pointsTextureSize","Texture","indexData","Buffer","_a","UniformStore","Model","calculateCentermassFrag","calculateCentermassVert","forceFrag","centermassPass","pass","_b","_c","_d","forceFrag$4","ForceGravity","maxLinks","ensureVec2","arr","fallback","ensureVec4","LinkDirection","ForceLink","direction","linksTextureSize","linkBiasAndStrengthState","linkDistanceState","grouped","linkIndex","connectedPointIndices","pointIndex","connectedPointIndex","initialLinkIndex","degree","connectedDegree","degreeSum","bias","minDegree","strength","recreatePointTextures","recreateLinkTextures","calculateLevelFrag","calculateLevelVert","forceFrag$2","forceCenterFrag","ForceManyBody","level","levelTextureSize","existingTarget","texture","target","totalPixels","randomValuesState","_e","_f","cellSize","levelPass","drawPass","forceFrag$1","ForceMouse","Clusters","clusterIndex","sizesChanged","pointsTextureDataSize","clustersTextureDataSize","clusterState","clusterPositions","clusterForceCoefficient","cluster","benchCSS","FPSMonitor","canvas","gl","GLBench","now","select","PointShape","GraphData","defaultRgba","defaultSize","defaultShape","pointShapes","shape","pointImageIndices","rawIndex","imageIndex","defaultWidth","defaultArrows","d","sourceIndex","targetIndex","drawLineFrag","drawLineVert","hoveredLineIndexFrag","hoveredLineIndexVert","getCurveLineGeometry","segments","scale","scalePow","hodographValues","result","Lines","linksNumber","renderPass","screenSize","screenWidth","screenHeight","screenSizeChanged","pointAData","pointBData","fromIndex","toIndex","fromX","fromY","toX","toY","currentSize","linkIndices","colorData","widthData","arrowData","curvedLinks","curvedLinkSegments","flatGeometry","indexPass","hoverPass","drawPointsFrag","drawPointsVert","findPointsOnAreaSelectionFrag","findPointsOnPolygonSelectionFrag","drawHighlightedFrag","drawHighlightedVert","findHoveredPointFrag","findHoveredPointVert","fillGridWithSampledPointsFrag","fillGridWithSampledPointsVert","updatePositionFrag","trackPositionsFrag","dragPointFrag","createAtlasDataFromImageData","imageDataArray","maxDimension","imageData","dimension","originalMaxDimension","atlasCoordsSize","atlasSize","scalingFactor","atlasData","atlasCoords","originalWidth","originalHeight","individualScale","scaledWidth","scaledHeight","row","atlasX","atlasY","srcX","srcIndex","atlasIndex","Points","rescalePositions","enableSimulation","textureDataSize","initialState","expectedBytes","actualBytes","shouldRescale","velocityData","requiredByteLength","t","selectedIndices","selectedIndex","pinnedIndex","sizeData","shapeData","imageIndicesData","imageSizesData","atlasResult","pointSamplingDistance","dist","w","h","baseVertexUniforms","baseFragmentUniforms","pointSize","polygonPath","textureData","point","baseUniforms","bindings","indices","sortedIndex","isSimulationRunning","pixels","tracked","positions","fillPass","isNotEmpty","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","tempTexture","tempFbo","spaceSize","pointsNumber","minX","maxX","minY","maxY","densityThreshold","effectiveSpaceSize","scaleFactor","centerOffset","offsetX","offsetY","Zoom","zoomIdentity","zoom","e","userDriven","k","transform","padding","xExtent","yExtent","xScale","yScale","clampedScale","xCenter","yCenter","translateX","translateY","position","dx","dy","currX","currY","pointX","pointY","centerX","centerY","screenPosition","invertedX","invertedY","spacePosition","screenPointX","screenPointY","spaceRadius","scalePointsOnZoom","maxPointSize","size","Drag","drag","event","Graph","div","devicePromise","deviceCanvasContext","deviceCanvas","error","prevConfig","pointPositions","dontRescale","pointColors","pointSizes","imageIndices","imageSizes","links","linkColors","linkWidths","linkArrows","linkStrength","pointClusters","clusterStrength","pinnedIndices","simulationAlpha","fitViewOnInit","fitViewDelay","fitViewPadding","fitViewDuration","fitViewByPointsInRect","fitViewByPointIndices","initialZoomLevel","duration","canZoomOut","positionPixels","posX","posY","distance","zoomLevel","middle","easeQuadIn","easeQuadOut","pointPositionsPixels","clusterPositionsPixels","sumX","sumY","sumN","positionsArray","easeQuadInOut","selection","pixel","convertedPath","selectAdjacentPoints","adjacentIndices","alpha","callback","luma","webgl2Adapter","graph","forceExecution","simulationGravity","simulationCenter","_s","backgroundColor","drawRenderPass","renderLinks","mouseX","mouseY","forceResize","prevW","prevH","centerPosition","deltaX","deltaY","wasHovered","isMouseover","isMouseout","hoveredIndex","hoveredLineIndex","hoveredPointCursor","hoveredLinkCursor"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","x_google_ignoreList":[1]}
1
+ {"version":3,"file":"index.js","sources":["../src/variables.ts","../node_modules/@luma.gl/constants/dist/webgl-constants.js","../src/modules/Store/index.ts","../src/helper.ts","../src/config.ts","../src/modules/core-module.ts","../src/modules/ForceCenter/calculate-centermass.frag?raw","../src/modules/ForceCenter/calculate-centermass.vert?raw","../src/modules/ForceCenter/force-center.frag?raw","../src/modules/Shared/buffer.ts","../src/modules/Shared/texture-utils.ts","../src/modules/Shared/quad.vert?raw","../src/modules/ForceCenter/index.ts","../src/modules/ForceGravity/force-gravity.frag?raw","../src/modules/ForceGravity/index.ts","../src/modules/ForceLink/force-spring.ts","../src/modules/Shared/uniform-utils.ts","../src/modules/ForceLink/index.ts","../src/modules/ForceManyBody/calculate-level.frag?raw","../src/modules/ForceManyBody/calculate-level.vert?raw","../src/modules/ForceManyBody/force-level.frag?raw","../src/modules/ForceManyBody/force-centermass.frag?raw","../src/modules/ForceManyBody/index.ts","../src/modules/ForceMouse/force-mouse.frag?raw","../src/modules/ForceMouse/index.ts","../src/modules/Clusters/calculate-centermass.frag?raw","../src/modules/Clusters/calculate-centermass.vert?raw","../src/modules/Clusters/force-cluster.frag?raw","../src/modules/Clusters/index.ts","../src/modules/FPSMonitor/css.ts","../src/modules/FPSMonitor/index.ts","../src/modules/GraphData/index.ts","../src/modules/Lines/draw-curve-line.frag?raw","../src/modules/Lines/draw-curve-line.vert?raw","../src/modules/Lines/hovered-line-index.frag?raw","../src/modules/Lines/hovered-line-index.vert?raw","../src/modules/Lines/geometry.ts","../src/modules/Lines/index.ts","../src/modules/Points/draw-points.frag?raw","../src/modules/Points/draw-points.vert?raw","../src/modules/Points/find-points-on-area-selection.frag?raw","../src/modules/Points/find-points-on-polygon-selection.frag?raw","../src/modules/Points/draw-highlighted.frag?raw","../src/modules/Points/draw-highlighted.vert?raw","../src/modules/Points/find-hovered-point.frag?raw","../src/modules/Points/find-hovered-point.vert?raw","../src/modules/Points/fill-sampled-points.frag?raw","../src/modules/Points/fill-sampled-points.vert?raw","../src/modules/Points/update-position.frag?raw","../src/modules/Points/track-positions.frag?raw","../src/modules/Points/drag-point.frag?raw","../src/modules/Points/atlas-utils.ts","../src/modules/Points/index.ts","../src/modules/Zoom/index.ts","../src/modules/Drag/index.ts","../src/index.ts"],"sourcesContent":["export const defaultPointColor = '#b3b3b3'\nexport const defaultGreyoutPointOpacity = undefined\nexport const defaultGreyoutPointColor = undefined\nexport const defaultPointOpacity = 1.0\nexport const defaultPointSize = 4\nexport const defaultLinkColor = '#666666'\nexport const defaultGreyoutLinkOpacity = 0.1\nexport const defaultLinkOpacity = 1.0\nexport const defaultLinkWidth = 1\nexport const defaultBackgroundColor = '#222222'\n\nexport const defaultConfigValues = {\n enableSimulation: true,\n spaceSize: 8192,\n pointSizeScale: 1,\n linkWidthScale: 1,\n linkArrowsSizeScale: 1,\n renderLinks: true,\n curvedLinks: false,\n curvedLinkSegments: 19,\n curvedLinkWeight: 0.8,\n curvedLinkControlPointDistance: 0.5,\n linkArrows: false,\n linkVisibilityDistanceRange: [50, 150],\n linkVisibilityMinTransparency: 0.25,\n hoveredPointCursor: 'auto',\n hoveredLinkCursor: 'auto',\n renderHoveredPointRing: false,\n hoveredPointRingColor: 'white',\n hoveredLinkColor: undefined,\n hoveredLinkWidthIncrease: 5,\n focusedPointRingColor: 'white',\n focusedPointIndex: undefined,\n simulation: {\n decay: 5000,\n gravity: 0.25,\n center: 0,\n repulsion: 1.0,\n repulsionTheta: 1.15,\n linkSpring: 1,\n linkDistance: 10,\n linkDistRandomVariationRange: [1, 1.2],\n repulsionFromMouse: 2,\n friction: 0.85,\n cluster: 0.1,\n },\n showFPSMonitor: false,\n pixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio || 2 : 2,\n scalePointsOnZoom: false,\n scaleLinksOnZoom: false,\n enableZoom: true,\n enableSimulationDuringZoom: false,\n enableDrag: false,\n fitViewOnInit: true,\n fitViewDelay: 250,\n fitViewPadding: 0.1,\n fitViewDuration: 250,\n pointSamplingDistance: 150,\n attribution: '',\n rescalePositions: undefined,\n enableRightClickRepulsion: false,\n}\n\nexport const hoveredPointRingOpacity = 0.7\nexport const focusedPointRingOpacity = 0.95\nexport const defaultScaleToZoom = 3\n","// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/* eslint-disable key-spacing, max-len, no-inline-comments, camelcase */\n/**\n * Standard WebGL, WebGL2 and extension constants (OpenGL constants)\n * @note (Most) of these constants are also defined on the WebGLRenderingContext interface.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants\n * @privateRemarks Locally called `GLEnum` instead of `GL`, because `babel-plugin-inline-webl-constants`\n * both depends on and processes this module, but shouldn't replace these declarations.\n */\n// eslint-disable-next-line no-shadow\nvar GLEnum;\n(function (GLEnum) {\n // Clearing buffers\n // Constants passed to clear() to clear buffer masks.\n /** Passed to clear to clear the current depth buffer. */\n GLEnum[GLEnum[\"DEPTH_BUFFER_BIT\"] = 256] = \"DEPTH_BUFFER_BIT\";\n /** Passed to clear to clear the current stencil buffer. */\n GLEnum[GLEnum[\"STENCIL_BUFFER_BIT\"] = 1024] = \"STENCIL_BUFFER_BIT\";\n /** Passed to clear to clear the current color buffer. */\n GLEnum[GLEnum[\"COLOR_BUFFER_BIT\"] = 16384] = \"COLOR_BUFFER_BIT\";\n // Rendering primitives\n // Constants passed to drawElements() or drawArrays() to specify what kind of primitive to render.\n /** Passed to drawElements or drawArrays to draw single points. */\n GLEnum[GLEnum[\"POINTS\"] = 0] = \"POINTS\";\n /** Passed to drawElements or drawArrays to draw lines. Each vertex connects to the one after it. */\n GLEnum[GLEnum[\"LINES\"] = 1] = \"LINES\";\n /** Passed to drawElements or drawArrays to draw lines. Each set of two vertices is treated as a separate line segment. */\n GLEnum[GLEnum[\"LINE_LOOP\"] = 2] = \"LINE_LOOP\";\n /** Passed to drawElements or drawArrays to draw a connected group of line segments from the first vertex to the last. */\n GLEnum[GLEnum[\"LINE_STRIP\"] = 3] = \"LINE_STRIP\";\n /** Passed to drawElements or drawArrays to draw triangles. Each set of three vertices creates a separate triangle. */\n GLEnum[GLEnum[\"TRIANGLES\"] = 4] = \"TRIANGLES\";\n /** Passed to drawElements or drawArrays to draw a connected group of triangles. */\n GLEnum[GLEnum[\"TRIANGLE_STRIP\"] = 5] = \"TRIANGLE_STRIP\";\n /** Passed to drawElements or drawArrays to draw a connected group of triangles. Each vertex connects to the previous and the first vertex in the fan. */\n GLEnum[GLEnum[\"TRIANGLE_FAN\"] = 6] = \"TRIANGLE_FAN\";\n // Blending modes\n // Constants passed to blendFunc() or blendFuncSeparate() to specify the blending mode (for both, RBG and alpha, or separately).\n /** Passed to blendFunc or blendFuncSeparate to turn off a component. */\n GLEnum[GLEnum[\"ZERO\"] = 0] = \"ZERO\";\n /** Passed to blendFunc or blendFuncSeparate to turn on a component. */\n GLEnum[GLEnum[\"ONE\"] = 1] = \"ONE\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the source elements color. */\n GLEnum[GLEnum[\"SRC_COLOR\"] = 768] = \"SRC_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the source elements color. */\n GLEnum[GLEnum[\"ONE_MINUS_SRC_COLOR\"] = 769] = \"ONE_MINUS_SRC_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the source's alpha. */\n GLEnum[GLEnum[\"SRC_ALPHA\"] = 770] = \"SRC_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the source's alpha. */\n GLEnum[GLEnum[\"ONE_MINUS_SRC_ALPHA\"] = 771] = \"ONE_MINUS_SRC_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the destination's alpha. */\n GLEnum[GLEnum[\"DST_ALPHA\"] = 772] = \"DST_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the destination's alpha. */\n GLEnum[GLEnum[\"ONE_MINUS_DST_ALPHA\"] = 773] = \"ONE_MINUS_DST_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the destination's color. */\n GLEnum[GLEnum[\"DST_COLOR\"] = 774] = \"DST_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the destination's color. */\n GLEnum[GLEnum[\"ONE_MINUS_DST_COLOR\"] = 775] = \"ONE_MINUS_DST_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to multiply a component by the minimum of source's alpha or one minus the destination's alpha. */\n GLEnum[GLEnum[\"SRC_ALPHA_SATURATE\"] = 776] = \"SRC_ALPHA_SATURATE\";\n /** Passed to blendFunc or blendFuncSeparate to specify a constant color blend function. */\n GLEnum[GLEnum[\"CONSTANT_COLOR\"] = 32769] = \"CONSTANT_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to specify one minus a constant color blend function. */\n GLEnum[GLEnum[\"ONE_MINUS_CONSTANT_COLOR\"] = 32770] = \"ONE_MINUS_CONSTANT_COLOR\";\n /** Passed to blendFunc or blendFuncSeparate to specify a constant alpha blend function. */\n GLEnum[GLEnum[\"CONSTANT_ALPHA\"] = 32771] = \"CONSTANT_ALPHA\";\n /** Passed to blendFunc or blendFuncSeparate to specify one minus a constant alpha blend function. */\n GLEnum[GLEnum[\"ONE_MINUS_CONSTANT_ALPHA\"] = 32772] = \"ONE_MINUS_CONSTANT_ALPHA\";\n // Blending equations\n // Constants passed to blendEquation() or blendEquationSeparate() to control\n // how the blending is calculated (for both, RBG and alpha, or separately).\n /** Passed to blendEquation or blendEquationSeparate to set an addition blend function. */\n /** Passed to blendEquation or blendEquationSeparate to specify a subtraction blend function (source - destination). */\n /** Passed to blendEquation or blendEquationSeparate to specify a reverse subtraction blend function (destination - source). */\n GLEnum[GLEnum[\"FUNC_ADD\"] = 32774] = \"FUNC_ADD\";\n GLEnum[GLEnum[\"FUNC_SUBTRACT\"] = 32778] = \"FUNC_SUBTRACT\";\n GLEnum[GLEnum[\"FUNC_REVERSE_SUBTRACT\"] = 32779] = \"FUNC_REVERSE_SUBTRACT\";\n // Getting GL parameter information\n // Constants passed to getParameter() to specify what information to return.\n /** Passed to getParameter to get the current RGB blend function. */\n GLEnum[GLEnum[\"BLEND_EQUATION\"] = 32777] = \"BLEND_EQUATION\";\n /** Passed to getParameter to get the current RGB blend function. Same as BLEND_EQUATION */\n GLEnum[GLEnum[\"BLEND_EQUATION_RGB\"] = 32777] = \"BLEND_EQUATION_RGB\";\n /** Passed to getParameter to get the current alpha blend function. Same as BLEND_EQUATION */\n GLEnum[GLEnum[\"BLEND_EQUATION_ALPHA\"] = 34877] = \"BLEND_EQUATION_ALPHA\";\n /** Passed to getParameter to get the current destination RGB blend function. */\n GLEnum[GLEnum[\"BLEND_DST_RGB\"] = 32968] = \"BLEND_DST_RGB\";\n /** Passed to getParameter to get the current destination RGB blend function. */\n GLEnum[GLEnum[\"BLEND_SRC_RGB\"] = 32969] = \"BLEND_SRC_RGB\";\n /** Passed to getParameter to get the current destination alpha blend function. */\n GLEnum[GLEnum[\"BLEND_DST_ALPHA\"] = 32970] = \"BLEND_DST_ALPHA\";\n /** Passed to getParameter to get the current source alpha blend function. */\n GLEnum[GLEnum[\"BLEND_SRC_ALPHA\"] = 32971] = \"BLEND_SRC_ALPHA\";\n /** Passed to getParameter to return a the current blend color. */\n GLEnum[GLEnum[\"BLEND_COLOR\"] = 32773] = \"BLEND_COLOR\";\n /** Passed to getParameter to get the array buffer binding. */\n GLEnum[GLEnum[\"ARRAY_BUFFER_BINDING\"] = 34964] = \"ARRAY_BUFFER_BINDING\";\n /** Passed to getParameter to get the current element array buffer. */\n GLEnum[GLEnum[\"ELEMENT_ARRAY_BUFFER_BINDING\"] = 34965] = \"ELEMENT_ARRAY_BUFFER_BINDING\";\n /** Passed to getParameter to get the current lineWidth (set by the lineWidth method). */\n GLEnum[GLEnum[\"LINE_WIDTH\"] = 2849] = \"LINE_WIDTH\";\n /** Passed to getParameter to get the current size of a point drawn with gl.POINTS */\n GLEnum[GLEnum[\"ALIASED_POINT_SIZE_RANGE\"] = 33901] = \"ALIASED_POINT_SIZE_RANGE\";\n /** Passed to getParameter to get the range of available widths for a line. Returns a length-2 array with the lo value at 0, and hight at 1. */\n GLEnum[GLEnum[\"ALIASED_LINE_WIDTH_RANGE\"] = 33902] = \"ALIASED_LINE_WIDTH_RANGE\";\n /** Passed to getParameter to get the current value of cullFace. Should return FRONT, BACK, or FRONT_AND_BACK */\n GLEnum[GLEnum[\"CULL_FACE_MODE\"] = 2885] = \"CULL_FACE_MODE\";\n /** Passed to getParameter to determine the current value of frontFace. Should return CW or CCW. */\n GLEnum[GLEnum[\"FRONT_FACE\"] = 2886] = \"FRONT_FACE\";\n /** Passed to getParameter to return a length-2 array of floats giving the current depth range. */\n GLEnum[GLEnum[\"DEPTH_RANGE\"] = 2928] = \"DEPTH_RANGE\";\n /** Passed to getParameter to determine if the depth write mask is enabled. */\n GLEnum[GLEnum[\"DEPTH_WRITEMASK\"] = 2930] = \"DEPTH_WRITEMASK\";\n /** Passed to getParameter to determine the current depth clear value. */\n GLEnum[GLEnum[\"DEPTH_CLEAR_VALUE\"] = 2931] = \"DEPTH_CLEAR_VALUE\";\n /** Passed to getParameter to get the current depth function. Returns NEVER, ALWAYS, LESS, EQUAL, LEQUAL, GREATER, GEQUAL, or NOTEQUAL. */\n GLEnum[GLEnum[\"DEPTH_FUNC\"] = 2932] = \"DEPTH_FUNC\";\n /** Passed to getParameter to get the value the stencil will be cleared to. */\n GLEnum[GLEnum[\"STENCIL_CLEAR_VALUE\"] = 2961] = \"STENCIL_CLEAR_VALUE\";\n /** Passed to getParameter to get the current stencil function. Returns NEVER, ALWAYS, LESS, EQUAL, LEQUAL, GREATER, GEQUAL, or NOTEQUAL. */\n GLEnum[GLEnum[\"STENCIL_FUNC\"] = 2962] = \"STENCIL_FUNC\";\n /** Passed to getParameter to get the current stencil fail function. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP. */\n GLEnum[GLEnum[\"STENCIL_FAIL\"] = 2964] = \"STENCIL_FAIL\";\n /** Passed to getParameter to get the current stencil fail function should the depth buffer test fail. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP. */\n GLEnum[GLEnum[\"STENCIL_PASS_DEPTH_FAIL\"] = 2965] = \"STENCIL_PASS_DEPTH_FAIL\";\n /** Passed to getParameter to get the current stencil fail function should the depth buffer test pass. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP. */\n GLEnum[GLEnum[\"STENCIL_PASS_DEPTH_PASS\"] = 2966] = \"STENCIL_PASS_DEPTH_PASS\";\n /** Passed to getParameter to get the reference value used for stencil tests. */\n GLEnum[GLEnum[\"STENCIL_REF\"] = 2967] = \"STENCIL_REF\";\n GLEnum[GLEnum[\"STENCIL_VALUE_MASK\"] = 2963] = \"STENCIL_VALUE_MASK\";\n GLEnum[GLEnum[\"STENCIL_WRITEMASK\"] = 2968] = \"STENCIL_WRITEMASK\";\n GLEnum[GLEnum[\"STENCIL_BACK_FUNC\"] = 34816] = \"STENCIL_BACK_FUNC\";\n GLEnum[GLEnum[\"STENCIL_BACK_FAIL\"] = 34817] = \"STENCIL_BACK_FAIL\";\n GLEnum[GLEnum[\"STENCIL_BACK_PASS_DEPTH_FAIL\"] = 34818] = \"STENCIL_BACK_PASS_DEPTH_FAIL\";\n GLEnum[GLEnum[\"STENCIL_BACK_PASS_DEPTH_PASS\"] = 34819] = \"STENCIL_BACK_PASS_DEPTH_PASS\";\n GLEnum[GLEnum[\"STENCIL_BACK_REF\"] = 36003] = \"STENCIL_BACK_REF\";\n GLEnum[GLEnum[\"STENCIL_BACK_VALUE_MASK\"] = 36004] = \"STENCIL_BACK_VALUE_MASK\";\n GLEnum[GLEnum[\"STENCIL_BACK_WRITEMASK\"] = 36005] = \"STENCIL_BACK_WRITEMASK\";\n /** An Int32Array with four elements for the current viewport dimensions. */\n GLEnum[GLEnum[\"VIEWPORT\"] = 2978] = \"VIEWPORT\";\n /** An Int32Array with four elements for the current scissor box dimensions. */\n GLEnum[GLEnum[\"SCISSOR_BOX\"] = 3088] = \"SCISSOR_BOX\";\n GLEnum[GLEnum[\"COLOR_CLEAR_VALUE\"] = 3106] = \"COLOR_CLEAR_VALUE\";\n GLEnum[GLEnum[\"COLOR_WRITEMASK\"] = 3107] = \"COLOR_WRITEMASK\";\n GLEnum[GLEnum[\"UNPACK_ALIGNMENT\"] = 3317] = \"UNPACK_ALIGNMENT\";\n GLEnum[GLEnum[\"PACK_ALIGNMENT\"] = 3333] = \"PACK_ALIGNMENT\";\n GLEnum[GLEnum[\"MAX_TEXTURE_SIZE\"] = 3379] = \"MAX_TEXTURE_SIZE\";\n GLEnum[GLEnum[\"MAX_VIEWPORT_DIMS\"] = 3386] = \"MAX_VIEWPORT_DIMS\";\n GLEnum[GLEnum[\"SUBPIXEL_BITS\"] = 3408] = \"SUBPIXEL_BITS\";\n GLEnum[GLEnum[\"RED_BITS\"] = 3410] = \"RED_BITS\";\n GLEnum[GLEnum[\"GREEN_BITS\"] = 3411] = \"GREEN_BITS\";\n GLEnum[GLEnum[\"BLUE_BITS\"] = 3412] = \"BLUE_BITS\";\n GLEnum[GLEnum[\"ALPHA_BITS\"] = 3413] = \"ALPHA_BITS\";\n GLEnum[GLEnum[\"DEPTH_BITS\"] = 3414] = \"DEPTH_BITS\";\n GLEnum[GLEnum[\"STENCIL_BITS\"] = 3415] = \"STENCIL_BITS\";\n GLEnum[GLEnum[\"POLYGON_OFFSET_UNITS\"] = 10752] = \"POLYGON_OFFSET_UNITS\";\n GLEnum[GLEnum[\"POLYGON_OFFSET_FACTOR\"] = 32824] = \"POLYGON_OFFSET_FACTOR\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_2D\"] = 32873] = \"TEXTURE_BINDING_2D\";\n GLEnum[GLEnum[\"SAMPLE_BUFFERS\"] = 32936] = \"SAMPLE_BUFFERS\";\n GLEnum[GLEnum[\"SAMPLES\"] = 32937] = \"SAMPLES\";\n GLEnum[GLEnum[\"SAMPLE_COVERAGE_VALUE\"] = 32938] = \"SAMPLE_COVERAGE_VALUE\";\n GLEnum[GLEnum[\"SAMPLE_COVERAGE_INVERT\"] = 32939] = \"SAMPLE_COVERAGE_INVERT\";\n GLEnum[GLEnum[\"COMPRESSED_TEXTURE_FORMATS\"] = 34467] = \"COMPRESSED_TEXTURE_FORMATS\";\n GLEnum[GLEnum[\"VENDOR\"] = 7936] = \"VENDOR\";\n GLEnum[GLEnum[\"RENDERER\"] = 7937] = \"RENDERER\";\n GLEnum[GLEnum[\"VERSION\"] = 7938] = \"VERSION\";\n GLEnum[GLEnum[\"IMPLEMENTATION_COLOR_READ_TYPE\"] = 35738] = \"IMPLEMENTATION_COLOR_READ_TYPE\";\n GLEnum[GLEnum[\"IMPLEMENTATION_COLOR_READ_FORMAT\"] = 35739] = \"IMPLEMENTATION_COLOR_READ_FORMAT\";\n GLEnum[GLEnum[\"BROWSER_DEFAULT_WEBGL\"] = 37444] = \"BROWSER_DEFAULT_WEBGL\";\n // Buffers\n // Constants passed to bufferData(), bufferSubData(), bindBuffer(), or\n // getBufferParameter().\n /** Passed to bufferData as a hint about whether the contents of the buffer are likely to be used often and not change often. */\n GLEnum[GLEnum[\"STATIC_DRAW\"] = 35044] = \"STATIC_DRAW\";\n /** Passed to bufferData as a hint about whether the contents of the buffer are likely to not be used often. */\n GLEnum[GLEnum[\"STREAM_DRAW\"] = 35040] = \"STREAM_DRAW\";\n /** Passed to bufferData as a hint about whether the contents of the buffer are likely to be used often and change often. */\n GLEnum[GLEnum[\"DYNAMIC_DRAW\"] = 35048] = \"DYNAMIC_DRAW\";\n /** Passed to bindBuffer or bufferData to specify the type of buffer being used. */\n GLEnum[GLEnum[\"ARRAY_BUFFER\"] = 34962] = \"ARRAY_BUFFER\";\n /** Passed to bindBuffer or bufferData to specify the type of buffer being used. */\n GLEnum[GLEnum[\"ELEMENT_ARRAY_BUFFER\"] = 34963] = \"ELEMENT_ARRAY_BUFFER\";\n /** Passed to getBufferParameter to get a buffer's size. */\n GLEnum[GLEnum[\"BUFFER_SIZE\"] = 34660] = \"BUFFER_SIZE\";\n /** Passed to getBufferParameter to get the hint for the buffer passed in when it was created. */\n GLEnum[GLEnum[\"BUFFER_USAGE\"] = 34661] = \"BUFFER_USAGE\";\n // Vertex attributes\n // Constants passed to getVertexAttrib().\n /** Passed to getVertexAttrib to read back the current vertex attribute. */\n GLEnum[GLEnum[\"CURRENT_VERTEX_ATTRIB\"] = 34342] = \"CURRENT_VERTEX_ATTRIB\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_ENABLED\"] = 34338] = \"VERTEX_ATTRIB_ARRAY_ENABLED\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_SIZE\"] = 34339] = \"VERTEX_ATTRIB_ARRAY_SIZE\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_STRIDE\"] = 34340] = \"VERTEX_ATTRIB_ARRAY_STRIDE\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_TYPE\"] = 34341] = \"VERTEX_ATTRIB_ARRAY_TYPE\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_NORMALIZED\"] = 34922] = \"VERTEX_ATTRIB_ARRAY_NORMALIZED\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_POINTER\"] = 34373] = \"VERTEX_ATTRIB_ARRAY_POINTER\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\"] = 34975] = \"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\";\n // Culling\n // Constants passed to cullFace().\n /** Passed to enable/disable to turn on/off culling. Can also be used with getParameter to find the current culling method. */\n GLEnum[GLEnum[\"CULL_FACE\"] = 2884] = \"CULL_FACE\";\n /** Passed to cullFace to specify that only front faces should be culled. */\n GLEnum[GLEnum[\"FRONT\"] = 1028] = \"FRONT\";\n /** Passed to cullFace to specify that only back faces should be culled. */\n GLEnum[GLEnum[\"BACK\"] = 1029] = \"BACK\";\n /** Passed to cullFace to specify that front and back faces should be culled. */\n GLEnum[GLEnum[\"FRONT_AND_BACK\"] = 1032] = \"FRONT_AND_BACK\";\n // Enabling and disabling\n // Constants passed to enable() or disable().\n /** Passed to enable/disable to turn on/off blending. Can also be used with getParameter to find the current blending method. */\n GLEnum[GLEnum[\"BLEND\"] = 3042] = \"BLEND\";\n /** Passed to enable/disable to turn on/off the depth test. Can also be used with getParameter to query the depth test. */\n GLEnum[GLEnum[\"DEPTH_TEST\"] = 2929] = \"DEPTH_TEST\";\n /** Passed to enable/disable to turn on/off dithering. Can also be used with getParameter to find the current dithering method. */\n GLEnum[GLEnum[\"DITHER\"] = 3024] = \"DITHER\";\n /** Passed to enable/disable to turn on/off the polygon offset. Useful for rendering hidden-line images, decals, and or solids with highlighted edges. Can also be used with getParameter to query the scissor test. */\n GLEnum[GLEnum[\"POLYGON_OFFSET_FILL\"] = 32823] = \"POLYGON_OFFSET_FILL\";\n /** Passed to enable/disable to turn on/off the alpha to coverage. Used in multi-sampling alpha channels. */\n GLEnum[GLEnum[\"SAMPLE_ALPHA_TO_COVERAGE\"] = 32926] = \"SAMPLE_ALPHA_TO_COVERAGE\";\n /** Passed to enable/disable to turn on/off the sample coverage. Used in multi-sampling. */\n GLEnum[GLEnum[\"SAMPLE_COVERAGE\"] = 32928] = \"SAMPLE_COVERAGE\";\n /** Passed to enable/disable to turn on/off the scissor test. Can also be used with getParameter to query the scissor test. */\n GLEnum[GLEnum[\"SCISSOR_TEST\"] = 3089] = \"SCISSOR_TEST\";\n /** Passed to enable/disable to turn on/off the stencil test. Can also be used with getParameter to query the stencil test. */\n GLEnum[GLEnum[\"STENCIL_TEST\"] = 2960] = \"STENCIL_TEST\";\n // Errors\n // Constants returned from getError().\n /** Returned from getError(). */\n GLEnum[GLEnum[\"NO_ERROR\"] = 0] = \"NO_ERROR\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"INVALID_ENUM\"] = 1280] = \"INVALID_ENUM\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"INVALID_VALUE\"] = 1281] = \"INVALID_VALUE\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"INVALID_OPERATION\"] = 1282] = \"INVALID_OPERATION\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"OUT_OF_MEMORY\"] = 1285] = \"OUT_OF_MEMORY\";\n /** Returned from getError(). */\n GLEnum[GLEnum[\"CONTEXT_LOST_WEBGL\"] = 37442] = \"CONTEXT_LOST_WEBGL\";\n // Front face directions\n // Constants passed to frontFace().\n /** Passed to frontFace to specify the front face of a polygon is drawn in the clockwise direction */\n GLEnum[GLEnum[\"CW\"] = 2304] = \"CW\";\n /** Passed to frontFace to specify the front face of a polygon is drawn in the counter clockwise direction */\n GLEnum[GLEnum[\"CCW\"] = 2305] = \"CCW\";\n // Hints\n // Constants passed to hint()\n /** There is no preference for this behavior. */\n GLEnum[GLEnum[\"DONT_CARE\"] = 4352] = \"DONT_CARE\";\n /** The most efficient behavior should be used. */\n GLEnum[GLEnum[\"FASTEST\"] = 4353] = \"FASTEST\";\n /** The most correct or the highest quality option should be used. */\n GLEnum[GLEnum[\"NICEST\"] = 4354] = \"NICEST\";\n /** Hint for the quality of filtering when generating mipmap images with WebGLRenderingContext.generateMipmap(). */\n GLEnum[GLEnum[\"GENERATE_MIPMAP_HINT\"] = 33170] = \"GENERATE_MIPMAP_HINT\";\n // Data types\n GLEnum[GLEnum[\"BYTE\"] = 5120] = \"BYTE\";\n GLEnum[GLEnum[\"UNSIGNED_BYTE\"] = 5121] = \"UNSIGNED_BYTE\";\n GLEnum[GLEnum[\"SHORT\"] = 5122] = \"SHORT\";\n GLEnum[GLEnum[\"UNSIGNED_SHORT\"] = 5123] = \"UNSIGNED_SHORT\";\n GLEnum[GLEnum[\"INT\"] = 5124] = \"INT\";\n GLEnum[GLEnum[\"UNSIGNED_INT\"] = 5125] = \"UNSIGNED_INT\";\n GLEnum[GLEnum[\"FLOAT\"] = 5126] = \"FLOAT\";\n GLEnum[GLEnum[\"DOUBLE\"] = 5130] = \"DOUBLE\";\n // Pixel formats\n GLEnum[GLEnum[\"DEPTH_COMPONENT\"] = 6402] = \"DEPTH_COMPONENT\";\n GLEnum[GLEnum[\"ALPHA\"] = 6406] = \"ALPHA\";\n GLEnum[GLEnum[\"RGB\"] = 6407] = \"RGB\";\n GLEnum[GLEnum[\"RGBA\"] = 6408] = \"RGBA\";\n GLEnum[GLEnum[\"LUMINANCE\"] = 6409] = \"LUMINANCE\";\n GLEnum[GLEnum[\"LUMINANCE_ALPHA\"] = 6410] = \"LUMINANCE_ALPHA\";\n // Pixel types\n // UNSIGNED_BYTE = 0x1401,\n GLEnum[GLEnum[\"UNSIGNED_SHORT_4_4_4_4\"] = 32819] = \"UNSIGNED_SHORT_4_4_4_4\";\n GLEnum[GLEnum[\"UNSIGNED_SHORT_5_5_5_1\"] = 32820] = \"UNSIGNED_SHORT_5_5_5_1\";\n GLEnum[GLEnum[\"UNSIGNED_SHORT_5_6_5\"] = 33635] = \"UNSIGNED_SHORT_5_6_5\";\n // Shaders\n // Constants passed to createShader() or getShaderParameter()\n /** Passed to createShader to define a fragment shader. */\n GLEnum[GLEnum[\"FRAGMENT_SHADER\"] = 35632] = \"FRAGMENT_SHADER\";\n /** Passed to createShader to define a vertex shader */\n GLEnum[GLEnum[\"VERTEX_SHADER\"] = 35633] = \"VERTEX_SHADER\";\n /** Passed to getShaderParameter to get the status of the compilation. Returns false if the shader was not compiled. You can then query getShaderInfoLog to find the exact error */\n GLEnum[GLEnum[\"COMPILE_STATUS\"] = 35713] = \"COMPILE_STATUS\";\n /** Passed to getShaderParameter to determine if a shader was deleted via deleteShader. Returns true if it was, false otherwise. */\n GLEnum[GLEnum[\"DELETE_STATUS\"] = 35712] = \"DELETE_STATUS\";\n /** Passed to getProgramParameter after calling linkProgram to determine if a program was linked correctly. Returns false if there were errors. Use getProgramInfoLog to find the exact error. */\n GLEnum[GLEnum[\"LINK_STATUS\"] = 35714] = \"LINK_STATUS\";\n /** Passed to getProgramParameter after calling validateProgram to determine if it is valid. Returns false if errors were found. */\n GLEnum[GLEnum[\"VALIDATE_STATUS\"] = 35715] = \"VALIDATE_STATUS\";\n /** Passed to getProgramParameter after calling attachShader to determine if the shader was attached correctly. Returns false if errors occurred. */\n GLEnum[GLEnum[\"ATTACHED_SHADERS\"] = 35717] = \"ATTACHED_SHADERS\";\n /** Passed to getProgramParameter to get the number of attributes active in a program. */\n GLEnum[GLEnum[\"ACTIVE_ATTRIBUTES\"] = 35721] = \"ACTIVE_ATTRIBUTES\";\n /** Passed to getProgramParameter to get the number of uniforms active in a program. */\n GLEnum[GLEnum[\"ACTIVE_UNIFORMS\"] = 35718] = \"ACTIVE_UNIFORMS\";\n /** The maximum number of entries possible in the vertex attribute list. */\n GLEnum[GLEnum[\"MAX_VERTEX_ATTRIBS\"] = 34921] = \"MAX_VERTEX_ATTRIBS\";\n GLEnum[GLEnum[\"MAX_VERTEX_UNIFORM_VECTORS\"] = 36347] = \"MAX_VERTEX_UNIFORM_VECTORS\";\n GLEnum[GLEnum[\"MAX_VARYING_VECTORS\"] = 36348] = \"MAX_VARYING_VECTORS\";\n GLEnum[GLEnum[\"MAX_COMBINED_TEXTURE_IMAGE_UNITS\"] = 35661] = \"MAX_COMBINED_TEXTURE_IMAGE_UNITS\";\n GLEnum[GLEnum[\"MAX_VERTEX_TEXTURE_IMAGE_UNITS\"] = 35660] = \"MAX_VERTEX_TEXTURE_IMAGE_UNITS\";\n /** Implementation dependent number of maximum texture units. At least 8. */\n GLEnum[GLEnum[\"MAX_TEXTURE_IMAGE_UNITS\"] = 34930] = \"MAX_TEXTURE_IMAGE_UNITS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_UNIFORM_VECTORS\"] = 36349] = \"MAX_FRAGMENT_UNIFORM_VECTORS\";\n GLEnum[GLEnum[\"SHADER_TYPE\"] = 35663] = \"SHADER_TYPE\";\n GLEnum[GLEnum[\"SHADING_LANGUAGE_VERSION\"] = 35724] = \"SHADING_LANGUAGE_VERSION\";\n GLEnum[GLEnum[\"CURRENT_PROGRAM\"] = 35725] = \"CURRENT_PROGRAM\";\n // Depth or stencil tests\n // Constants passed to depthFunc() or stencilFunc().\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass, i.e., nothing will be drawn. */\n GLEnum[GLEnum[\"NEVER\"] = 512] = \"NEVER\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value. */\n GLEnum[GLEnum[\"LESS\"] = 513] = \"LESS\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value. */\n GLEnum[GLEnum[\"EQUAL\"] = 514] = \"EQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value. */\n GLEnum[GLEnum[\"LEQUAL\"] = 515] = \"LEQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value. */\n GLEnum[GLEnum[\"GREATER\"] = 516] = \"GREATER\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value. */\n GLEnum[GLEnum[\"NOTEQUAL\"] = 517] = \"NOTEQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value. */\n GLEnum[GLEnum[\"GEQUAL\"] = 518] = \"GEQUAL\";\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass, i.e., pixels will be drawn in the order they are drawn. */\n GLEnum[GLEnum[\"ALWAYS\"] = 519] = \"ALWAYS\";\n // Stencil actions\n // Constants passed to stencilOp().\n GLEnum[GLEnum[\"KEEP\"] = 7680] = \"KEEP\";\n GLEnum[GLEnum[\"REPLACE\"] = 7681] = \"REPLACE\";\n GLEnum[GLEnum[\"INCR\"] = 7682] = \"INCR\";\n GLEnum[GLEnum[\"DECR\"] = 7683] = \"DECR\";\n GLEnum[GLEnum[\"INVERT\"] = 5386] = \"INVERT\";\n GLEnum[GLEnum[\"INCR_WRAP\"] = 34055] = \"INCR_WRAP\";\n GLEnum[GLEnum[\"DECR_WRAP\"] = 34056] = \"DECR_WRAP\";\n // Textures\n // Constants passed to texParameteri(),\n // texParameterf(), bindTexture(), texImage2D(), and others.\n GLEnum[GLEnum[\"NEAREST\"] = 9728] = \"NEAREST\";\n GLEnum[GLEnum[\"LINEAR\"] = 9729] = \"LINEAR\";\n GLEnum[GLEnum[\"NEAREST_MIPMAP_NEAREST\"] = 9984] = \"NEAREST_MIPMAP_NEAREST\";\n GLEnum[GLEnum[\"LINEAR_MIPMAP_NEAREST\"] = 9985] = \"LINEAR_MIPMAP_NEAREST\";\n GLEnum[GLEnum[\"NEAREST_MIPMAP_LINEAR\"] = 9986] = \"NEAREST_MIPMAP_LINEAR\";\n GLEnum[GLEnum[\"LINEAR_MIPMAP_LINEAR\"] = 9987] = \"LINEAR_MIPMAP_LINEAR\";\n /** The texture magnification function is used when the pixel being textured maps to an area less than or equal to one texture element. It sets the texture magnification function to either GL_NEAREST or GL_LINEAR (see below). GL_NEAREST is generally faster than GL_LINEAR, but it can produce textured images with sharper edges because the transition between texture elements is not as smooth. Default: GL_LINEAR. */\n GLEnum[GLEnum[\"TEXTURE_MAG_FILTER\"] = 10240] = \"TEXTURE_MAG_FILTER\";\n /** The texture minifying function is used whenever the pixel being textured maps to an area greater than one texture element. There are six defined minifying functions. Two of them use the nearest one or nearest four texture elements to compute the texture value. The other four use mipmaps. Default: GL_NEAREST_MIPMAP_LINEAR */\n GLEnum[GLEnum[\"TEXTURE_MIN_FILTER\"] = 10241] = \"TEXTURE_MIN_FILTER\";\n /** Sets the wrap parameter for texture coordinate to either GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT. G */\n GLEnum[GLEnum[\"TEXTURE_WRAP_S\"] = 10242] = \"TEXTURE_WRAP_S\";\n /** Sets the wrap parameter for texture coordinate to either GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT. G */\n GLEnum[GLEnum[\"TEXTURE_WRAP_T\"] = 10243] = \"TEXTURE_WRAP_T\";\n GLEnum[GLEnum[\"TEXTURE_2D\"] = 3553] = \"TEXTURE_2D\";\n GLEnum[GLEnum[\"TEXTURE\"] = 5890] = \"TEXTURE\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP\"] = 34067] = \"TEXTURE_CUBE_MAP\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_CUBE_MAP\"] = 34068] = \"TEXTURE_BINDING_CUBE_MAP\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_POSITIVE_X\"] = 34069] = \"TEXTURE_CUBE_MAP_POSITIVE_X\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_NEGATIVE_X\"] = 34070] = \"TEXTURE_CUBE_MAP_NEGATIVE_X\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_POSITIVE_Y\"] = 34071] = \"TEXTURE_CUBE_MAP_POSITIVE_Y\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_NEGATIVE_Y\"] = 34072] = \"TEXTURE_CUBE_MAP_NEGATIVE_Y\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_POSITIVE_Z\"] = 34073] = \"TEXTURE_CUBE_MAP_POSITIVE_Z\";\n GLEnum[GLEnum[\"TEXTURE_CUBE_MAP_NEGATIVE_Z\"] = 34074] = \"TEXTURE_CUBE_MAP_NEGATIVE_Z\";\n GLEnum[GLEnum[\"MAX_CUBE_MAP_TEXTURE_SIZE\"] = 34076] = \"MAX_CUBE_MAP_TEXTURE_SIZE\";\n // TEXTURE0 - 31 0x84C0 - 0x84DF A texture unit.\n GLEnum[GLEnum[\"TEXTURE0\"] = 33984] = \"TEXTURE0\";\n GLEnum[GLEnum[\"ACTIVE_TEXTURE\"] = 34016] = \"ACTIVE_TEXTURE\";\n GLEnum[GLEnum[\"REPEAT\"] = 10497] = \"REPEAT\";\n GLEnum[GLEnum[\"CLAMP_TO_EDGE\"] = 33071] = \"CLAMP_TO_EDGE\";\n GLEnum[GLEnum[\"MIRRORED_REPEAT\"] = 33648] = \"MIRRORED_REPEAT\";\n // Emulation\n GLEnum[GLEnum[\"TEXTURE_WIDTH\"] = 4096] = \"TEXTURE_WIDTH\";\n GLEnum[GLEnum[\"TEXTURE_HEIGHT\"] = 4097] = \"TEXTURE_HEIGHT\";\n // Uniform types\n GLEnum[GLEnum[\"FLOAT_VEC2\"] = 35664] = \"FLOAT_VEC2\";\n GLEnum[GLEnum[\"FLOAT_VEC3\"] = 35665] = \"FLOAT_VEC3\";\n GLEnum[GLEnum[\"FLOAT_VEC4\"] = 35666] = \"FLOAT_VEC4\";\n GLEnum[GLEnum[\"INT_VEC2\"] = 35667] = \"INT_VEC2\";\n GLEnum[GLEnum[\"INT_VEC3\"] = 35668] = \"INT_VEC3\";\n GLEnum[GLEnum[\"INT_VEC4\"] = 35669] = \"INT_VEC4\";\n GLEnum[GLEnum[\"BOOL\"] = 35670] = \"BOOL\";\n GLEnum[GLEnum[\"BOOL_VEC2\"] = 35671] = \"BOOL_VEC2\";\n GLEnum[GLEnum[\"BOOL_VEC3\"] = 35672] = \"BOOL_VEC3\";\n GLEnum[GLEnum[\"BOOL_VEC4\"] = 35673] = \"BOOL_VEC4\";\n GLEnum[GLEnum[\"FLOAT_MAT2\"] = 35674] = \"FLOAT_MAT2\";\n GLEnum[GLEnum[\"FLOAT_MAT3\"] = 35675] = \"FLOAT_MAT3\";\n GLEnum[GLEnum[\"FLOAT_MAT4\"] = 35676] = \"FLOAT_MAT4\";\n GLEnum[GLEnum[\"SAMPLER_2D\"] = 35678] = \"SAMPLER_2D\";\n GLEnum[GLEnum[\"SAMPLER_CUBE\"] = 35680] = \"SAMPLER_CUBE\";\n // Shader precision-specified types\n GLEnum[GLEnum[\"LOW_FLOAT\"] = 36336] = \"LOW_FLOAT\";\n GLEnum[GLEnum[\"MEDIUM_FLOAT\"] = 36337] = \"MEDIUM_FLOAT\";\n GLEnum[GLEnum[\"HIGH_FLOAT\"] = 36338] = \"HIGH_FLOAT\";\n GLEnum[GLEnum[\"LOW_INT\"] = 36339] = \"LOW_INT\";\n GLEnum[GLEnum[\"MEDIUM_INT\"] = 36340] = \"MEDIUM_INT\";\n GLEnum[GLEnum[\"HIGH_INT\"] = 36341] = \"HIGH_INT\";\n // Framebuffers and renderbuffers\n GLEnum[GLEnum[\"FRAMEBUFFER\"] = 36160] = \"FRAMEBUFFER\";\n GLEnum[GLEnum[\"RENDERBUFFER\"] = 36161] = \"RENDERBUFFER\";\n GLEnum[GLEnum[\"RGBA4\"] = 32854] = \"RGBA4\";\n GLEnum[GLEnum[\"RGB5_A1\"] = 32855] = \"RGB5_A1\";\n GLEnum[GLEnum[\"RGB565\"] = 36194] = \"RGB565\";\n GLEnum[GLEnum[\"DEPTH_COMPONENT16\"] = 33189] = \"DEPTH_COMPONENT16\";\n GLEnum[GLEnum[\"STENCIL_INDEX\"] = 6401] = \"STENCIL_INDEX\";\n GLEnum[GLEnum[\"STENCIL_INDEX8\"] = 36168] = \"STENCIL_INDEX8\";\n GLEnum[GLEnum[\"DEPTH_STENCIL\"] = 34041] = \"DEPTH_STENCIL\";\n GLEnum[GLEnum[\"RENDERBUFFER_WIDTH\"] = 36162] = \"RENDERBUFFER_WIDTH\";\n GLEnum[GLEnum[\"RENDERBUFFER_HEIGHT\"] = 36163] = \"RENDERBUFFER_HEIGHT\";\n GLEnum[GLEnum[\"RENDERBUFFER_INTERNAL_FORMAT\"] = 36164] = \"RENDERBUFFER_INTERNAL_FORMAT\";\n GLEnum[GLEnum[\"RENDERBUFFER_RED_SIZE\"] = 36176] = \"RENDERBUFFER_RED_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_GREEN_SIZE\"] = 36177] = \"RENDERBUFFER_GREEN_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_BLUE_SIZE\"] = 36178] = \"RENDERBUFFER_BLUE_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_ALPHA_SIZE\"] = 36179] = \"RENDERBUFFER_ALPHA_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_DEPTH_SIZE\"] = 36180] = \"RENDERBUFFER_DEPTH_SIZE\";\n GLEnum[GLEnum[\"RENDERBUFFER_STENCIL_SIZE\"] = 36181] = \"RENDERBUFFER_STENCIL_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE\"] = 36048] = \"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME\"] = 36049] = \"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL\"] = 36050] = \"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE\"] = 36051] = \"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT0\"] = 36064] = \"COLOR_ATTACHMENT0\";\n GLEnum[GLEnum[\"DEPTH_ATTACHMENT\"] = 36096] = \"DEPTH_ATTACHMENT\";\n GLEnum[GLEnum[\"STENCIL_ATTACHMENT\"] = 36128] = \"STENCIL_ATTACHMENT\";\n GLEnum[GLEnum[\"DEPTH_STENCIL_ATTACHMENT\"] = 33306] = \"DEPTH_STENCIL_ATTACHMENT\";\n GLEnum[GLEnum[\"NONE\"] = 0] = \"NONE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_COMPLETE\"] = 36053] = \"FRAMEBUFFER_COMPLETE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_ATTACHMENT\"] = 36054] = \"FRAMEBUFFER_INCOMPLETE_ATTACHMENT\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\"] = 36055] = \"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_DIMENSIONS\"] = 36057] = \"FRAMEBUFFER_INCOMPLETE_DIMENSIONS\";\n GLEnum[GLEnum[\"FRAMEBUFFER_UNSUPPORTED\"] = 36061] = \"FRAMEBUFFER_UNSUPPORTED\";\n GLEnum[GLEnum[\"FRAMEBUFFER_BINDING\"] = 36006] = \"FRAMEBUFFER_BINDING\";\n GLEnum[GLEnum[\"RENDERBUFFER_BINDING\"] = 36007] = \"RENDERBUFFER_BINDING\";\n GLEnum[GLEnum[\"READ_FRAMEBUFFER\"] = 36008] = \"READ_FRAMEBUFFER\";\n GLEnum[GLEnum[\"DRAW_FRAMEBUFFER\"] = 36009] = \"DRAW_FRAMEBUFFER\";\n GLEnum[GLEnum[\"MAX_RENDERBUFFER_SIZE\"] = 34024] = \"MAX_RENDERBUFFER_SIZE\";\n GLEnum[GLEnum[\"INVALID_FRAMEBUFFER_OPERATION\"] = 1286] = \"INVALID_FRAMEBUFFER_OPERATION\";\n // Pixel storage modes\n // Constants passed to pixelStorei().\n GLEnum[GLEnum[\"UNPACK_FLIP_Y_WEBGL\"] = 37440] = \"UNPACK_FLIP_Y_WEBGL\";\n GLEnum[GLEnum[\"UNPACK_PREMULTIPLY_ALPHA_WEBGL\"] = 37441] = \"UNPACK_PREMULTIPLY_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"UNPACK_COLORSPACE_CONVERSION_WEBGL\"] = 37443] = \"UNPACK_COLORSPACE_CONVERSION_WEBGL\";\n // Additional constants defined WebGL 2\n // These constants are defined on the WebGL2RenderingContext interface.\n // All WebGL 1 constants are also available in a WebGL 2 context.\n // Getting GL parameter information\n // Constants passed to getParameter()\n // to specify what information to return.\n GLEnum[GLEnum[\"READ_BUFFER\"] = 3074] = \"READ_BUFFER\";\n GLEnum[GLEnum[\"UNPACK_ROW_LENGTH\"] = 3314] = \"UNPACK_ROW_LENGTH\";\n GLEnum[GLEnum[\"UNPACK_SKIP_ROWS\"] = 3315] = \"UNPACK_SKIP_ROWS\";\n GLEnum[GLEnum[\"UNPACK_SKIP_PIXELS\"] = 3316] = \"UNPACK_SKIP_PIXELS\";\n GLEnum[GLEnum[\"PACK_ROW_LENGTH\"] = 3330] = \"PACK_ROW_LENGTH\";\n GLEnum[GLEnum[\"PACK_SKIP_ROWS\"] = 3331] = \"PACK_SKIP_ROWS\";\n GLEnum[GLEnum[\"PACK_SKIP_PIXELS\"] = 3332] = \"PACK_SKIP_PIXELS\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_3D\"] = 32874] = \"TEXTURE_BINDING_3D\";\n GLEnum[GLEnum[\"UNPACK_SKIP_IMAGES\"] = 32877] = \"UNPACK_SKIP_IMAGES\";\n GLEnum[GLEnum[\"UNPACK_IMAGE_HEIGHT\"] = 32878] = \"UNPACK_IMAGE_HEIGHT\";\n GLEnum[GLEnum[\"MAX_3D_TEXTURE_SIZE\"] = 32883] = \"MAX_3D_TEXTURE_SIZE\";\n GLEnum[GLEnum[\"MAX_ELEMENTS_VERTICES\"] = 33000] = \"MAX_ELEMENTS_VERTICES\";\n GLEnum[GLEnum[\"MAX_ELEMENTS_INDICES\"] = 33001] = \"MAX_ELEMENTS_INDICES\";\n GLEnum[GLEnum[\"MAX_TEXTURE_LOD_BIAS\"] = 34045] = \"MAX_TEXTURE_LOD_BIAS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_UNIFORM_COMPONENTS\"] = 35657] = \"MAX_FRAGMENT_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_VERTEX_UNIFORM_COMPONENTS\"] = 35658] = \"MAX_VERTEX_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_ARRAY_TEXTURE_LAYERS\"] = 35071] = \"MAX_ARRAY_TEXTURE_LAYERS\";\n GLEnum[GLEnum[\"MIN_PROGRAM_TEXEL_OFFSET\"] = 35076] = \"MIN_PROGRAM_TEXEL_OFFSET\";\n GLEnum[GLEnum[\"MAX_PROGRAM_TEXEL_OFFSET\"] = 35077] = \"MAX_PROGRAM_TEXEL_OFFSET\";\n GLEnum[GLEnum[\"MAX_VARYING_COMPONENTS\"] = 35659] = \"MAX_VARYING_COMPONENTS\";\n GLEnum[GLEnum[\"FRAGMENT_SHADER_DERIVATIVE_HINT\"] = 35723] = \"FRAGMENT_SHADER_DERIVATIVE_HINT\";\n GLEnum[GLEnum[\"RASTERIZER_DISCARD\"] = 35977] = \"RASTERIZER_DISCARD\";\n GLEnum[GLEnum[\"VERTEX_ARRAY_BINDING\"] = 34229] = \"VERTEX_ARRAY_BINDING\";\n GLEnum[GLEnum[\"MAX_VERTEX_OUTPUT_COMPONENTS\"] = 37154] = \"MAX_VERTEX_OUTPUT_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_INPUT_COMPONENTS\"] = 37157] = \"MAX_FRAGMENT_INPUT_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_SERVER_WAIT_TIMEOUT\"] = 37137] = \"MAX_SERVER_WAIT_TIMEOUT\";\n GLEnum[GLEnum[\"MAX_ELEMENT_INDEX\"] = 36203] = \"MAX_ELEMENT_INDEX\";\n // Textures\n // Constants passed to texParameteri(),\n // texParameterf(), bindTexture(), texImage2D(), and others.\n GLEnum[GLEnum[\"RED\"] = 6403] = \"RED\";\n GLEnum[GLEnum[\"RGB8\"] = 32849] = \"RGB8\";\n GLEnum[GLEnum[\"RGBA8\"] = 32856] = \"RGBA8\";\n GLEnum[GLEnum[\"RGB10_A2\"] = 32857] = \"RGB10_A2\";\n GLEnum[GLEnum[\"TEXTURE_3D\"] = 32879] = \"TEXTURE_3D\";\n /** Sets the wrap parameter for texture coordinate to either GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT. G */\n GLEnum[GLEnum[\"TEXTURE_WRAP_R\"] = 32882] = \"TEXTURE_WRAP_R\";\n GLEnum[GLEnum[\"TEXTURE_MIN_LOD\"] = 33082] = \"TEXTURE_MIN_LOD\";\n GLEnum[GLEnum[\"TEXTURE_MAX_LOD\"] = 33083] = \"TEXTURE_MAX_LOD\";\n GLEnum[GLEnum[\"TEXTURE_BASE_LEVEL\"] = 33084] = \"TEXTURE_BASE_LEVEL\";\n GLEnum[GLEnum[\"TEXTURE_MAX_LEVEL\"] = 33085] = \"TEXTURE_MAX_LEVEL\";\n GLEnum[GLEnum[\"TEXTURE_COMPARE_MODE\"] = 34892] = \"TEXTURE_COMPARE_MODE\";\n GLEnum[GLEnum[\"TEXTURE_COMPARE_FUNC\"] = 34893] = \"TEXTURE_COMPARE_FUNC\";\n GLEnum[GLEnum[\"SRGB\"] = 35904] = \"SRGB\";\n GLEnum[GLEnum[\"SRGB8\"] = 35905] = \"SRGB8\";\n GLEnum[GLEnum[\"SRGB8_ALPHA8\"] = 35907] = \"SRGB8_ALPHA8\";\n GLEnum[GLEnum[\"COMPARE_REF_TO_TEXTURE\"] = 34894] = \"COMPARE_REF_TO_TEXTURE\";\n GLEnum[GLEnum[\"RGBA32F\"] = 34836] = \"RGBA32F\";\n GLEnum[GLEnum[\"RGB32F\"] = 34837] = \"RGB32F\";\n GLEnum[GLEnum[\"RGBA16F\"] = 34842] = \"RGBA16F\";\n GLEnum[GLEnum[\"RGB16F\"] = 34843] = \"RGB16F\";\n GLEnum[GLEnum[\"TEXTURE_2D_ARRAY\"] = 35866] = \"TEXTURE_2D_ARRAY\";\n GLEnum[GLEnum[\"TEXTURE_BINDING_2D_ARRAY\"] = 35869] = \"TEXTURE_BINDING_2D_ARRAY\";\n GLEnum[GLEnum[\"R11F_G11F_B10F\"] = 35898] = \"R11F_G11F_B10F\";\n GLEnum[GLEnum[\"RGB9_E5\"] = 35901] = \"RGB9_E5\";\n GLEnum[GLEnum[\"RGBA32UI\"] = 36208] = \"RGBA32UI\";\n GLEnum[GLEnum[\"RGB32UI\"] = 36209] = \"RGB32UI\";\n GLEnum[GLEnum[\"RGBA16UI\"] = 36214] = \"RGBA16UI\";\n GLEnum[GLEnum[\"RGB16UI\"] = 36215] = \"RGB16UI\";\n GLEnum[GLEnum[\"RGBA8UI\"] = 36220] = \"RGBA8UI\";\n GLEnum[GLEnum[\"RGB8UI\"] = 36221] = \"RGB8UI\";\n GLEnum[GLEnum[\"RGBA32I\"] = 36226] = \"RGBA32I\";\n GLEnum[GLEnum[\"RGB32I\"] = 36227] = \"RGB32I\";\n GLEnum[GLEnum[\"RGBA16I\"] = 36232] = \"RGBA16I\";\n GLEnum[GLEnum[\"RGB16I\"] = 36233] = \"RGB16I\";\n GLEnum[GLEnum[\"RGBA8I\"] = 36238] = \"RGBA8I\";\n GLEnum[GLEnum[\"RGB8I\"] = 36239] = \"RGB8I\";\n GLEnum[GLEnum[\"RED_INTEGER\"] = 36244] = \"RED_INTEGER\";\n GLEnum[GLEnum[\"RGB_INTEGER\"] = 36248] = \"RGB_INTEGER\";\n GLEnum[GLEnum[\"RGBA_INTEGER\"] = 36249] = \"RGBA_INTEGER\";\n GLEnum[GLEnum[\"R8\"] = 33321] = \"R8\";\n GLEnum[GLEnum[\"RG8\"] = 33323] = \"RG8\";\n GLEnum[GLEnum[\"R16F\"] = 33325] = \"R16F\";\n GLEnum[GLEnum[\"R32F\"] = 33326] = \"R32F\";\n GLEnum[GLEnum[\"RG16F\"] = 33327] = \"RG16F\";\n GLEnum[GLEnum[\"RG32F\"] = 33328] = \"RG32F\";\n GLEnum[GLEnum[\"R8I\"] = 33329] = \"R8I\";\n GLEnum[GLEnum[\"R8UI\"] = 33330] = \"R8UI\";\n GLEnum[GLEnum[\"R16I\"] = 33331] = \"R16I\";\n GLEnum[GLEnum[\"R16UI\"] = 33332] = \"R16UI\";\n GLEnum[GLEnum[\"R32I\"] = 33333] = \"R32I\";\n GLEnum[GLEnum[\"R32UI\"] = 33334] = \"R32UI\";\n GLEnum[GLEnum[\"RG8I\"] = 33335] = \"RG8I\";\n GLEnum[GLEnum[\"RG8UI\"] = 33336] = \"RG8UI\";\n GLEnum[GLEnum[\"RG16I\"] = 33337] = \"RG16I\";\n GLEnum[GLEnum[\"RG16UI\"] = 33338] = \"RG16UI\";\n GLEnum[GLEnum[\"RG32I\"] = 33339] = \"RG32I\";\n GLEnum[GLEnum[\"RG32UI\"] = 33340] = \"RG32UI\";\n GLEnum[GLEnum[\"R8_SNORM\"] = 36756] = \"R8_SNORM\";\n GLEnum[GLEnum[\"RG8_SNORM\"] = 36757] = \"RG8_SNORM\";\n GLEnum[GLEnum[\"RGB8_SNORM\"] = 36758] = \"RGB8_SNORM\";\n GLEnum[GLEnum[\"RGBA8_SNORM\"] = 36759] = \"RGBA8_SNORM\";\n GLEnum[GLEnum[\"RGB10_A2UI\"] = 36975] = \"RGB10_A2UI\";\n /* covered by extension\n COMPRESSED_R11_EAC = 0x9270,\n COMPRESSED_SIGNED_R11_EAC = 0x9271,\n COMPRESSED_RG11_EAC = 0x9272,\n COMPRESSED_SIGNED_RG11_EAC = 0x9273,\n COMPRESSED_RGB8_ETC2 = 0x9274,\n COMPRESSED_SRGB8_ETC2 = 0x9275,\n COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276,\n COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC = 0x9277,\n COMPRESSED_RGBA8_ETC2_EAC = 0x9278,\n COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279,\n */\n GLEnum[GLEnum[\"TEXTURE_IMMUTABLE_FORMAT\"] = 37167] = \"TEXTURE_IMMUTABLE_FORMAT\";\n GLEnum[GLEnum[\"TEXTURE_IMMUTABLE_LEVELS\"] = 33503] = \"TEXTURE_IMMUTABLE_LEVELS\";\n // Pixel types\n GLEnum[GLEnum[\"UNSIGNED_INT_2_10_10_10_REV\"] = 33640] = \"UNSIGNED_INT_2_10_10_10_REV\";\n GLEnum[GLEnum[\"UNSIGNED_INT_10F_11F_11F_REV\"] = 35899] = \"UNSIGNED_INT_10F_11F_11F_REV\";\n GLEnum[GLEnum[\"UNSIGNED_INT_5_9_9_9_REV\"] = 35902] = \"UNSIGNED_INT_5_9_9_9_REV\";\n GLEnum[GLEnum[\"FLOAT_32_UNSIGNED_INT_24_8_REV\"] = 36269] = \"FLOAT_32_UNSIGNED_INT_24_8_REV\";\n GLEnum[GLEnum[\"UNSIGNED_INT_24_8\"] = 34042] = \"UNSIGNED_INT_24_8\";\n GLEnum[GLEnum[\"HALF_FLOAT\"] = 5131] = \"HALF_FLOAT\";\n GLEnum[GLEnum[\"RG\"] = 33319] = \"RG\";\n GLEnum[GLEnum[\"RG_INTEGER\"] = 33320] = \"RG_INTEGER\";\n GLEnum[GLEnum[\"INT_2_10_10_10_REV\"] = 36255] = \"INT_2_10_10_10_REV\";\n // Queries\n GLEnum[GLEnum[\"CURRENT_QUERY\"] = 34917] = \"CURRENT_QUERY\";\n /** Returns a GLuint containing the query result. */\n GLEnum[GLEnum[\"QUERY_RESULT\"] = 34918] = \"QUERY_RESULT\";\n /** Whether query result is available. */\n GLEnum[GLEnum[\"QUERY_RESULT_AVAILABLE\"] = 34919] = \"QUERY_RESULT_AVAILABLE\";\n /** Occlusion query (if drawing passed depth test) */\n GLEnum[GLEnum[\"ANY_SAMPLES_PASSED\"] = 35887] = \"ANY_SAMPLES_PASSED\";\n /** Occlusion query less accurate/faster version */\n GLEnum[GLEnum[\"ANY_SAMPLES_PASSED_CONSERVATIVE\"] = 36202] = \"ANY_SAMPLES_PASSED_CONSERVATIVE\";\n // Draw buffers\n GLEnum[GLEnum[\"MAX_DRAW_BUFFERS\"] = 34852] = \"MAX_DRAW_BUFFERS\";\n GLEnum[GLEnum[\"DRAW_BUFFER0\"] = 34853] = \"DRAW_BUFFER0\";\n GLEnum[GLEnum[\"DRAW_BUFFER1\"] = 34854] = \"DRAW_BUFFER1\";\n GLEnum[GLEnum[\"DRAW_BUFFER2\"] = 34855] = \"DRAW_BUFFER2\";\n GLEnum[GLEnum[\"DRAW_BUFFER3\"] = 34856] = \"DRAW_BUFFER3\";\n GLEnum[GLEnum[\"DRAW_BUFFER4\"] = 34857] = \"DRAW_BUFFER4\";\n GLEnum[GLEnum[\"DRAW_BUFFER5\"] = 34858] = \"DRAW_BUFFER5\";\n GLEnum[GLEnum[\"DRAW_BUFFER6\"] = 34859] = \"DRAW_BUFFER6\";\n GLEnum[GLEnum[\"DRAW_BUFFER7\"] = 34860] = \"DRAW_BUFFER7\";\n GLEnum[GLEnum[\"DRAW_BUFFER8\"] = 34861] = \"DRAW_BUFFER8\";\n GLEnum[GLEnum[\"DRAW_BUFFER9\"] = 34862] = \"DRAW_BUFFER9\";\n GLEnum[GLEnum[\"DRAW_BUFFER10\"] = 34863] = \"DRAW_BUFFER10\";\n GLEnum[GLEnum[\"DRAW_BUFFER11\"] = 34864] = \"DRAW_BUFFER11\";\n GLEnum[GLEnum[\"DRAW_BUFFER12\"] = 34865] = \"DRAW_BUFFER12\";\n GLEnum[GLEnum[\"DRAW_BUFFER13\"] = 34866] = \"DRAW_BUFFER13\";\n GLEnum[GLEnum[\"DRAW_BUFFER14\"] = 34867] = \"DRAW_BUFFER14\";\n GLEnum[GLEnum[\"DRAW_BUFFER15\"] = 34868] = \"DRAW_BUFFER15\";\n GLEnum[GLEnum[\"MAX_COLOR_ATTACHMENTS\"] = 36063] = \"MAX_COLOR_ATTACHMENTS\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT1\"] = 36065] = \"COLOR_ATTACHMENT1\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT2\"] = 36066] = \"COLOR_ATTACHMENT2\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT3\"] = 36067] = \"COLOR_ATTACHMENT3\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT4\"] = 36068] = \"COLOR_ATTACHMENT4\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT5\"] = 36069] = \"COLOR_ATTACHMENT5\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT6\"] = 36070] = \"COLOR_ATTACHMENT6\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT7\"] = 36071] = \"COLOR_ATTACHMENT7\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT8\"] = 36072] = \"COLOR_ATTACHMENT8\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT9\"] = 36073] = \"COLOR_ATTACHMENT9\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT10\"] = 36074] = \"COLOR_ATTACHMENT10\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT11\"] = 36075] = \"COLOR_ATTACHMENT11\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT12\"] = 36076] = \"COLOR_ATTACHMENT12\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT13\"] = 36077] = \"COLOR_ATTACHMENT13\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT14\"] = 36078] = \"COLOR_ATTACHMENT14\";\n GLEnum[GLEnum[\"COLOR_ATTACHMENT15\"] = 36079] = \"COLOR_ATTACHMENT15\";\n // Samplers\n GLEnum[GLEnum[\"SAMPLER_3D\"] = 35679] = \"SAMPLER_3D\";\n GLEnum[GLEnum[\"SAMPLER_2D_SHADOW\"] = 35682] = \"SAMPLER_2D_SHADOW\";\n GLEnum[GLEnum[\"SAMPLER_2D_ARRAY\"] = 36289] = \"SAMPLER_2D_ARRAY\";\n GLEnum[GLEnum[\"SAMPLER_2D_ARRAY_SHADOW\"] = 36292] = \"SAMPLER_2D_ARRAY_SHADOW\";\n GLEnum[GLEnum[\"SAMPLER_CUBE_SHADOW\"] = 36293] = \"SAMPLER_CUBE_SHADOW\";\n GLEnum[GLEnum[\"INT_SAMPLER_2D\"] = 36298] = \"INT_SAMPLER_2D\";\n GLEnum[GLEnum[\"INT_SAMPLER_3D\"] = 36299] = \"INT_SAMPLER_3D\";\n GLEnum[GLEnum[\"INT_SAMPLER_CUBE\"] = 36300] = \"INT_SAMPLER_CUBE\";\n GLEnum[GLEnum[\"INT_SAMPLER_2D_ARRAY\"] = 36303] = \"INT_SAMPLER_2D_ARRAY\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_2D\"] = 36306] = \"UNSIGNED_INT_SAMPLER_2D\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_3D\"] = 36307] = \"UNSIGNED_INT_SAMPLER_3D\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_CUBE\"] = 36308] = \"UNSIGNED_INT_SAMPLER_CUBE\";\n GLEnum[GLEnum[\"UNSIGNED_INT_SAMPLER_2D_ARRAY\"] = 36311] = \"UNSIGNED_INT_SAMPLER_2D_ARRAY\";\n GLEnum[GLEnum[\"MAX_SAMPLES\"] = 36183] = \"MAX_SAMPLES\";\n GLEnum[GLEnum[\"SAMPLER_BINDING\"] = 35097] = \"SAMPLER_BINDING\";\n // Buffers\n GLEnum[GLEnum[\"PIXEL_PACK_BUFFER\"] = 35051] = \"PIXEL_PACK_BUFFER\";\n GLEnum[GLEnum[\"PIXEL_UNPACK_BUFFER\"] = 35052] = \"PIXEL_UNPACK_BUFFER\";\n GLEnum[GLEnum[\"PIXEL_PACK_BUFFER_BINDING\"] = 35053] = \"PIXEL_PACK_BUFFER_BINDING\";\n GLEnum[GLEnum[\"PIXEL_UNPACK_BUFFER_BINDING\"] = 35055] = \"PIXEL_UNPACK_BUFFER_BINDING\";\n GLEnum[GLEnum[\"COPY_READ_BUFFER\"] = 36662] = \"COPY_READ_BUFFER\";\n GLEnum[GLEnum[\"COPY_WRITE_BUFFER\"] = 36663] = \"COPY_WRITE_BUFFER\";\n GLEnum[GLEnum[\"COPY_READ_BUFFER_BINDING\"] = 36662] = \"COPY_READ_BUFFER_BINDING\";\n GLEnum[GLEnum[\"COPY_WRITE_BUFFER_BINDING\"] = 36663] = \"COPY_WRITE_BUFFER_BINDING\";\n // Data types\n GLEnum[GLEnum[\"FLOAT_MAT2x3\"] = 35685] = \"FLOAT_MAT2x3\";\n GLEnum[GLEnum[\"FLOAT_MAT2x4\"] = 35686] = \"FLOAT_MAT2x4\";\n GLEnum[GLEnum[\"FLOAT_MAT3x2\"] = 35687] = \"FLOAT_MAT3x2\";\n GLEnum[GLEnum[\"FLOAT_MAT3x4\"] = 35688] = \"FLOAT_MAT3x4\";\n GLEnum[GLEnum[\"FLOAT_MAT4x2\"] = 35689] = \"FLOAT_MAT4x2\";\n GLEnum[GLEnum[\"FLOAT_MAT4x3\"] = 35690] = \"FLOAT_MAT4x3\";\n GLEnum[GLEnum[\"UNSIGNED_INT_VEC2\"] = 36294] = \"UNSIGNED_INT_VEC2\";\n GLEnum[GLEnum[\"UNSIGNED_INT_VEC3\"] = 36295] = \"UNSIGNED_INT_VEC3\";\n GLEnum[GLEnum[\"UNSIGNED_INT_VEC4\"] = 36296] = \"UNSIGNED_INT_VEC4\";\n GLEnum[GLEnum[\"UNSIGNED_NORMALIZED\"] = 35863] = \"UNSIGNED_NORMALIZED\";\n GLEnum[GLEnum[\"SIGNED_NORMALIZED\"] = 36764] = \"SIGNED_NORMALIZED\";\n // Vertex attributes\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_INTEGER\"] = 35069] = \"VERTEX_ATTRIB_ARRAY_INTEGER\";\n GLEnum[GLEnum[\"VERTEX_ATTRIB_ARRAY_DIVISOR\"] = 35070] = \"VERTEX_ATTRIB_ARRAY_DIVISOR\";\n // Transform feedback\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_MODE\"] = 35967] = \"TRANSFORM_FEEDBACK_BUFFER_MODE\";\n GLEnum[GLEnum[\"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS\"] = 35968] = \"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_VARYINGS\"] = 35971] = \"TRANSFORM_FEEDBACK_VARYINGS\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_START\"] = 35972] = \"TRANSFORM_FEEDBACK_BUFFER_START\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_SIZE\"] = 35973] = \"TRANSFORM_FEEDBACK_BUFFER_SIZE\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN\"] = 35976] = \"TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN\";\n GLEnum[GLEnum[\"MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS\"] = 35978] = \"MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS\"] = 35979] = \"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS\";\n GLEnum[GLEnum[\"INTERLEAVED_ATTRIBS\"] = 35980] = \"INTERLEAVED_ATTRIBS\";\n GLEnum[GLEnum[\"SEPARATE_ATTRIBS\"] = 35981] = \"SEPARATE_ATTRIBS\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER\"] = 35982] = \"TRANSFORM_FEEDBACK_BUFFER\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BUFFER_BINDING\"] = 35983] = \"TRANSFORM_FEEDBACK_BUFFER_BINDING\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK\"] = 36386] = \"TRANSFORM_FEEDBACK\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_PAUSED\"] = 36387] = \"TRANSFORM_FEEDBACK_PAUSED\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_ACTIVE\"] = 36388] = \"TRANSFORM_FEEDBACK_ACTIVE\";\n GLEnum[GLEnum[\"TRANSFORM_FEEDBACK_BINDING\"] = 36389] = \"TRANSFORM_FEEDBACK_BINDING\";\n // Framebuffers and renderbuffers\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING\"] = 33296] = \"FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE\"] = 33297] = \"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_RED_SIZE\"] = 33298] = \"FRAMEBUFFER_ATTACHMENT_RED_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_GREEN_SIZE\"] = 33299] = \"FRAMEBUFFER_ATTACHMENT_GREEN_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_BLUE_SIZE\"] = 33300] = \"FRAMEBUFFER_ATTACHMENT_BLUE_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE\"] = 33301] = \"FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE\"] = 33302] = \"FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE\"] = 33303] = \"FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE\";\n GLEnum[GLEnum[\"FRAMEBUFFER_DEFAULT\"] = 33304] = \"FRAMEBUFFER_DEFAULT\";\n // DEPTH_STENCIL_ATTACHMENT = 0x821A,\n // DEPTH_STENCIL = 0x84F9,\n GLEnum[GLEnum[\"DEPTH24_STENCIL8\"] = 35056] = \"DEPTH24_STENCIL8\";\n GLEnum[GLEnum[\"DRAW_FRAMEBUFFER_BINDING\"] = 36006] = \"DRAW_FRAMEBUFFER_BINDING\";\n GLEnum[GLEnum[\"READ_FRAMEBUFFER_BINDING\"] = 36010] = \"READ_FRAMEBUFFER_BINDING\";\n GLEnum[GLEnum[\"RENDERBUFFER_SAMPLES\"] = 36011] = \"RENDERBUFFER_SAMPLES\";\n GLEnum[GLEnum[\"FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER\"] = 36052] = \"FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER\";\n GLEnum[GLEnum[\"FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\"] = 36182] = \"FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\";\n // Uniforms\n GLEnum[GLEnum[\"UNIFORM_BUFFER\"] = 35345] = \"UNIFORM_BUFFER\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_BINDING\"] = 35368] = \"UNIFORM_BUFFER_BINDING\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_START\"] = 35369] = \"UNIFORM_BUFFER_START\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_SIZE\"] = 35370] = \"UNIFORM_BUFFER_SIZE\";\n GLEnum[GLEnum[\"MAX_VERTEX_UNIFORM_BLOCKS\"] = 35371] = \"MAX_VERTEX_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"MAX_FRAGMENT_UNIFORM_BLOCKS\"] = 35373] = \"MAX_FRAGMENT_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"MAX_COMBINED_UNIFORM_BLOCKS\"] = 35374] = \"MAX_COMBINED_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"MAX_UNIFORM_BUFFER_BINDINGS\"] = 35375] = \"MAX_UNIFORM_BUFFER_BINDINGS\";\n GLEnum[GLEnum[\"MAX_UNIFORM_BLOCK_SIZE\"] = 35376] = \"MAX_UNIFORM_BLOCK_SIZE\";\n GLEnum[GLEnum[\"MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS\"] = 35377] = \"MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS\"] = 35379] = \"MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS\";\n GLEnum[GLEnum[\"UNIFORM_BUFFER_OFFSET_ALIGNMENT\"] = 35380] = \"UNIFORM_BUFFER_OFFSET_ALIGNMENT\";\n GLEnum[GLEnum[\"ACTIVE_UNIFORM_BLOCKS\"] = 35382] = \"ACTIVE_UNIFORM_BLOCKS\";\n GLEnum[GLEnum[\"UNIFORM_TYPE\"] = 35383] = \"UNIFORM_TYPE\";\n GLEnum[GLEnum[\"UNIFORM_SIZE\"] = 35384] = \"UNIFORM_SIZE\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_INDEX\"] = 35386] = \"UNIFORM_BLOCK_INDEX\";\n GLEnum[GLEnum[\"UNIFORM_OFFSET\"] = 35387] = \"UNIFORM_OFFSET\";\n GLEnum[GLEnum[\"UNIFORM_ARRAY_STRIDE\"] = 35388] = \"UNIFORM_ARRAY_STRIDE\";\n GLEnum[GLEnum[\"UNIFORM_MATRIX_STRIDE\"] = 35389] = \"UNIFORM_MATRIX_STRIDE\";\n GLEnum[GLEnum[\"UNIFORM_IS_ROW_MAJOR\"] = 35390] = \"UNIFORM_IS_ROW_MAJOR\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_BINDING\"] = 35391] = \"UNIFORM_BLOCK_BINDING\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_DATA_SIZE\"] = 35392] = \"UNIFORM_BLOCK_DATA_SIZE\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_ACTIVE_UNIFORMS\"] = 35394] = \"UNIFORM_BLOCK_ACTIVE_UNIFORMS\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES\"] = 35395] = \"UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER\"] = 35396] = \"UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER\";\n GLEnum[GLEnum[\"UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER\"] = 35398] = \"UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER\";\n // Sync objects\n GLEnum[GLEnum[\"OBJECT_TYPE\"] = 37138] = \"OBJECT_TYPE\";\n GLEnum[GLEnum[\"SYNC_CONDITION\"] = 37139] = \"SYNC_CONDITION\";\n GLEnum[GLEnum[\"SYNC_STATUS\"] = 37140] = \"SYNC_STATUS\";\n GLEnum[GLEnum[\"SYNC_FLAGS\"] = 37141] = \"SYNC_FLAGS\";\n GLEnum[GLEnum[\"SYNC_FENCE\"] = 37142] = \"SYNC_FENCE\";\n GLEnum[GLEnum[\"SYNC_GPU_COMMANDS_COMPLETE\"] = 37143] = \"SYNC_GPU_COMMANDS_COMPLETE\";\n GLEnum[GLEnum[\"UNSIGNALED\"] = 37144] = \"UNSIGNALED\";\n GLEnum[GLEnum[\"SIGNALED\"] = 37145] = \"SIGNALED\";\n GLEnum[GLEnum[\"ALREADY_SIGNALED\"] = 37146] = \"ALREADY_SIGNALED\";\n GLEnum[GLEnum[\"TIMEOUT_EXPIRED\"] = 37147] = \"TIMEOUT_EXPIRED\";\n GLEnum[GLEnum[\"CONDITION_SATISFIED\"] = 37148] = \"CONDITION_SATISFIED\";\n GLEnum[GLEnum[\"WAIT_FAILED\"] = 37149] = \"WAIT_FAILED\";\n GLEnum[GLEnum[\"SYNC_FLUSH_COMMANDS_BIT\"] = 1] = \"SYNC_FLUSH_COMMANDS_BIT\";\n // Miscellaneous constants\n GLEnum[GLEnum[\"COLOR\"] = 6144] = \"COLOR\";\n GLEnum[GLEnum[\"DEPTH\"] = 6145] = \"DEPTH\";\n GLEnum[GLEnum[\"STENCIL\"] = 6146] = \"STENCIL\";\n GLEnum[GLEnum[\"MIN\"] = 32775] = \"MIN\";\n GLEnum[GLEnum[\"MAX\"] = 32776] = \"MAX\";\n GLEnum[GLEnum[\"DEPTH_COMPONENT24\"] = 33190] = \"DEPTH_COMPONENT24\";\n GLEnum[GLEnum[\"STREAM_READ\"] = 35041] = \"STREAM_READ\";\n GLEnum[GLEnum[\"STREAM_COPY\"] = 35042] = \"STREAM_COPY\";\n GLEnum[GLEnum[\"STATIC_READ\"] = 35045] = \"STATIC_READ\";\n GLEnum[GLEnum[\"STATIC_COPY\"] = 35046] = \"STATIC_COPY\";\n GLEnum[GLEnum[\"DYNAMIC_READ\"] = 35049] = \"DYNAMIC_READ\";\n GLEnum[GLEnum[\"DYNAMIC_COPY\"] = 35050] = \"DYNAMIC_COPY\";\n GLEnum[GLEnum[\"DEPTH_COMPONENT32F\"] = 36012] = \"DEPTH_COMPONENT32F\";\n GLEnum[GLEnum[\"DEPTH32F_STENCIL8\"] = 36013] = \"DEPTH32F_STENCIL8\";\n GLEnum[GLEnum[\"INVALID_INDEX\"] = 4294967295] = \"INVALID_INDEX\";\n GLEnum[GLEnum[\"TIMEOUT_IGNORED\"] = -1] = \"TIMEOUT_IGNORED\";\n GLEnum[GLEnum[\"MAX_CLIENT_WAIT_TIMEOUT_WEBGL\"] = 37447] = \"MAX_CLIENT_WAIT_TIMEOUT_WEBGL\";\n // Constants defined in WebGL extensions\n // WEBGL_debug_renderer_info\n /** Passed to getParameter to get the vendor string of the graphics driver. */\n GLEnum[GLEnum[\"UNMASKED_VENDOR_WEBGL\"] = 37445] = \"UNMASKED_VENDOR_WEBGL\";\n /** Passed to getParameter to get the renderer string of the graphics driver. */\n GLEnum[GLEnum[\"UNMASKED_RENDERER_WEBGL\"] = 37446] = \"UNMASKED_RENDERER_WEBGL\";\n // EXT_texture_filter_anisotropic\n /** Returns the maximum available anisotropy. */\n GLEnum[GLEnum[\"MAX_TEXTURE_MAX_ANISOTROPY_EXT\"] = 34047] = \"MAX_TEXTURE_MAX_ANISOTROPY_EXT\";\n /** Passed to texParameter to set the desired maximum anisotropy for a texture. */\n GLEnum[GLEnum[\"TEXTURE_MAX_ANISOTROPY_EXT\"] = 34046] = \"TEXTURE_MAX_ANISOTROPY_EXT\";\n // EXT_texture_norm16 - https://khronos.org/registry/webgl/extensions/EXT_texture_norm16/\n GLEnum[GLEnum[\"R16_EXT\"] = 33322] = \"R16_EXT\";\n GLEnum[GLEnum[\"RG16_EXT\"] = 33324] = \"RG16_EXT\";\n GLEnum[GLEnum[\"RGB16_EXT\"] = 32852] = \"RGB16_EXT\";\n GLEnum[GLEnum[\"RGBA16_EXT\"] = 32859] = \"RGBA16_EXT\";\n GLEnum[GLEnum[\"R16_SNORM_EXT\"] = 36760] = \"R16_SNORM_EXT\";\n GLEnum[GLEnum[\"RG16_SNORM_EXT\"] = 36761] = \"RG16_SNORM_EXT\";\n GLEnum[GLEnum[\"RGB16_SNORM_EXT\"] = 36762] = \"RGB16_SNORM_EXT\";\n GLEnum[GLEnum[\"RGBA16_SNORM_EXT\"] = 36763] = \"RGBA16_SNORM_EXT\";\n // WEBGL_compressed_texture_s3tc (BC1, BC2, BC3)\n /** A DXT1-compressed image in an RGB image format. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_S3TC_DXT1_EXT\"] = 33776] = \"COMPRESSED_RGB_S3TC_DXT1_EXT\";\n /** A DXT1-compressed image in an RGB image format with a simple on/off alpha value. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_S3TC_DXT1_EXT\"] = 33777] = \"COMPRESSED_RGBA_S3TC_DXT1_EXT\";\n /** A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_S3TC_DXT3_EXT\"] = 33778] = \"COMPRESSED_RGBA_S3TC_DXT3_EXT\";\n /** A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_S3TC_DXT5_EXT\"] = 33779] = \"COMPRESSED_RGBA_S3TC_DXT5_EXT\";\n // WEBGL_compressed_texture_s3tc_srgb (BC1, BC2, BC3 - SRGB)\n GLEnum[GLEnum[\"COMPRESSED_SRGB_S3TC_DXT1_EXT\"] = 35916] = \"COMPRESSED_SRGB_S3TC_DXT1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT\"] = 35917] = \"COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT\"] = 35918] = \"COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT\"] = 35919] = \"COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT\";\n // WEBGL_compressed_texture_rgtc (BC4, BC5)\n GLEnum[GLEnum[\"COMPRESSED_RED_RGTC1_EXT\"] = 36283] = \"COMPRESSED_RED_RGTC1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_RED_RGTC1_EXT\"] = 36284] = \"COMPRESSED_SIGNED_RED_RGTC1_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_RED_GREEN_RGTC2_EXT\"] = 36285] = \"COMPRESSED_RED_GREEN_RGTC2_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT\"] = 36286] = \"COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT\";\n // WEBGL_compressed_texture_bptc (BC6, BC7)\n GLEnum[GLEnum[\"COMPRESSED_RGBA_BPTC_UNORM_EXT\"] = 36492] = \"COMPRESSED_RGBA_BPTC_UNORM_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT\"] = 36493] = \"COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT\"] = 36494] = \"COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT\";\n GLEnum[GLEnum[\"COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT\"] = 36495] = \"COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT\";\n // WEBGL_compressed_texture_es3\n /** One-channel (red) unsigned format compression. */\n GLEnum[GLEnum[\"COMPRESSED_R11_EAC\"] = 37488] = \"COMPRESSED_R11_EAC\";\n /** One-channel (red) signed format compression. */\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_R11_EAC\"] = 37489] = \"COMPRESSED_SIGNED_R11_EAC\";\n /** Two-channel (red and green) unsigned format compression. */\n GLEnum[GLEnum[\"COMPRESSED_RG11_EAC\"] = 37490] = \"COMPRESSED_RG11_EAC\";\n /** Two-channel (red and green) signed format compression. */\n GLEnum[GLEnum[\"COMPRESSED_SIGNED_RG11_EAC\"] = 37491] = \"COMPRESSED_SIGNED_RG11_EAC\";\n /** Compresses RGB8 data with no alpha channel. */\n GLEnum[GLEnum[\"COMPRESSED_RGB8_ETC2\"] = 37492] = \"COMPRESSED_RGB8_ETC2\";\n /** Compresses RGBA8 data. The RGB part is encoded the same as RGB_ETC2, but the alpha part is encoded separately. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA8_ETC2_EAC\"] = 37493] = \"COMPRESSED_RGBA8_ETC2_EAC\";\n /** Compresses sRGB8 data with no alpha channel. */\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ETC2\"] = 37494] = \"COMPRESSED_SRGB8_ETC2\";\n /** Compresses sRGBA8 data. The sRGB part is encoded the same as SRGB_ETC2, but the alpha part is encoded separately. */\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC\"] = 37495] = \"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC\";\n /** Similar to RGB8_ETC, but with ability to punch through the alpha channel, which means to make it completely opaque or transparent. */\n GLEnum[GLEnum[\"COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2\"] = 37496] = \"COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2\";\n /** Similar to SRGB8_ETC, but with ability to punch through the alpha channel, which means to make it completely opaque or transparent. */\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2\"] = 37497] = \"COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2\";\n // WEBGL_compressed_texture_pvrtc\n /** RGB compression in 4-bit mode. One block for each 4×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_PVRTC_4BPPV1_IMG\"] = 35840] = \"COMPRESSED_RGB_PVRTC_4BPPV1_IMG\";\n /** RGBA compression in 4-bit mode. One block for each 4×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\"] = 35842] = \"COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\";\n /** RGB compression in 2-bit mode. One block for each 8×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_PVRTC_2BPPV1_IMG\"] = 35841] = \"COMPRESSED_RGB_PVRTC_2BPPV1_IMG\";\n /** RGBA compression in 2-bit mode. One block for each 8×4 pixels. */\n GLEnum[GLEnum[\"COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\"] = 35843] = \"COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\";\n // WEBGL_compressed_texture_etc1\n /** Compresses 24-bit RGB data with no alpha channel. */\n GLEnum[GLEnum[\"COMPRESSED_RGB_ETC1_WEBGL\"] = 36196] = \"COMPRESSED_RGB_ETC1_WEBGL\";\n // WEBGL_compressed_texture_atc\n GLEnum[GLEnum[\"COMPRESSED_RGB_ATC_WEBGL\"] = 35986] = \"COMPRESSED_RGB_ATC_WEBGL\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL\"] = 35986] = \"COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL\"] = 34798] = \"COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL\";\n // WEBGL_compressed_texture_astc\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_4x4_KHR\"] = 37808] = \"COMPRESSED_RGBA_ASTC_4x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_5x4_KHR\"] = 37809] = \"COMPRESSED_RGBA_ASTC_5x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_5x5_KHR\"] = 37810] = \"COMPRESSED_RGBA_ASTC_5x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_6x5_KHR\"] = 37811] = \"COMPRESSED_RGBA_ASTC_6x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_6x6_KHR\"] = 37812] = \"COMPRESSED_RGBA_ASTC_6x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_8x5_KHR\"] = 37813] = \"COMPRESSED_RGBA_ASTC_8x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_8x6_KHR\"] = 37814] = \"COMPRESSED_RGBA_ASTC_8x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_8x8_KHR\"] = 37815] = \"COMPRESSED_RGBA_ASTC_8x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x5_KHR\"] = 37816] = \"COMPRESSED_RGBA_ASTC_10x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x6_KHR\"] = 37817] = \"COMPRESSED_RGBA_ASTC_10x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x8_KHR\"] = 37818] = \"COMPRESSED_RGBA_ASTC_10x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_10x10_KHR\"] = 37819] = \"COMPRESSED_RGBA_ASTC_10x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_12x10_KHR\"] = 37820] = \"COMPRESSED_RGBA_ASTC_12x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_RGBA_ASTC_12x12_KHR\"] = 37821] = \"COMPRESSED_RGBA_ASTC_12x12_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR\"] = 37840] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR\"] = 37841] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR\"] = 37842] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR\"] = 37843] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR\"] = 37844] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR\"] = 37845] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR\"] = 37846] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR\"] = 37847] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR\"] = 37848] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR\"] = 37849] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR\"] = 37850] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR\"] = 37851] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR\"] = 37852] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR\";\n GLEnum[GLEnum[\"COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR\"] = 37853] = \"COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR\";\n // EXT_disjoint_timer_query\n /** The number of bits used to hold the query result for the given target. */\n GLEnum[GLEnum[\"QUERY_COUNTER_BITS_EXT\"] = 34916] = \"QUERY_COUNTER_BITS_EXT\";\n /** The currently active query. */\n GLEnum[GLEnum[\"CURRENT_QUERY_EXT\"] = 34917] = \"CURRENT_QUERY_EXT\";\n /** The query result. */\n GLEnum[GLEnum[\"QUERY_RESULT_EXT\"] = 34918] = \"QUERY_RESULT_EXT\";\n /** A Boolean indicating whether or not a query result is available. */\n GLEnum[GLEnum[\"QUERY_RESULT_AVAILABLE_EXT\"] = 34919] = \"QUERY_RESULT_AVAILABLE_EXT\";\n /** Elapsed time (in nanoseconds). */\n GLEnum[GLEnum[\"TIME_ELAPSED_EXT\"] = 35007] = \"TIME_ELAPSED_EXT\";\n /** The current time. */\n GLEnum[GLEnum[\"TIMESTAMP_EXT\"] = 36392] = \"TIMESTAMP_EXT\";\n /** A Boolean indicating whether or not the GPU performed any disjoint operation (lost context) */\n GLEnum[GLEnum[\"GPU_DISJOINT_EXT\"] = 36795] = \"GPU_DISJOINT_EXT\";\n // KHR_parallel_shader_compile https://registry.khronos.org/webgl/extensions/KHR_parallel_shader_compile\n /** a non-blocking poll operation, so that compile/link status availability can be queried without potentially incurring stalls */\n GLEnum[GLEnum[\"COMPLETION_STATUS_KHR\"] = 37297] = \"COMPLETION_STATUS_KHR\";\n // EXT_depth_clamp https://registry.khronos.org/webgl/extensions/EXT_depth_clamp/\n /** Disables depth clipping */\n GLEnum[GLEnum[\"DEPTH_CLAMP_EXT\"] = 34383] = \"DEPTH_CLAMP_EXT\";\n // WEBGL_provoking_vertex https://registry.khronos.org/webgl/extensions/WEBGL_provoking_vertex/\n /** Values of first vertex in primitive are used for flat shading */\n GLEnum[GLEnum[\"FIRST_VERTEX_CONVENTION_WEBGL\"] = 36429] = \"FIRST_VERTEX_CONVENTION_WEBGL\";\n /** Values of first vertex in primitive are used for flat shading */\n GLEnum[GLEnum[\"LAST_VERTEX_CONVENTION_WEBGL\"] = 36430] = \"LAST_VERTEX_CONVENTION_WEBGL\";\n /** Controls which vertex in primitive is used for flat shading */\n GLEnum[GLEnum[\"PROVOKING_VERTEX_WEBL\"] = 36431] = \"PROVOKING_VERTEX_WEBL\";\n // WEBGL_polygon_mode https://registry.khronos.org/webgl/extensions/WEBGL_polygon_mode/\n GLEnum[GLEnum[\"POLYGON_MODE_WEBGL\"] = 2880] = \"POLYGON_MODE_WEBGL\";\n GLEnum[GLEnum[\"POLYGON_OFFSET_LINE_WEBGL\"] = 10754] = \"POLYGON_OFFSET_LINE_WEBGL\";\n GLEnum[GLEnum[\"LINE_WEBGL\"] = 6913] = \"LINE_WEBGL\";\n GLEnum[GLEnum[\"FILL_WEBGL\"] = 6914] = \"FILL_WEBGL\";\n // WEBGL_clip_cull_distance https://registry.khronos.org/webgl/extensions/WEBGL_clip_cull_distance/\n /** Max clip distances */\n GLEnum[GLEnum[\"MAX_CLIP_DISTANCES_WEBGL\"] = 3378] = \"MAX_CLIP_DISTANCES_WEBGL\";\n /** Max cull distances */\n GLEnum[GLEnum[\"MAX_CULL_DISTANCES_WEBGL\"] = 33529] = \"MAX_CULL_DISTANCES_WEBGL\";\n /** Max clip and cull distances */\n GLEnum[GLEnum[\"MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL\"] = 33530] = \"MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL\";\n /** Enable gl_ClipDistance[0] and gl_CullDistance[0] */\n GLEnum[GLEnum[\"CLIP_DISTANCE0_WEBGL\"] = 12288] = \"CLIP_DISTANCE0_WEBGL\";\n /** Enable gl_ClipDistance[1] and gl_CullDistance[1] */\n GLEnum[GLEnum[\"CLIP_DISTANCE1_WEBGL\"] = 12289] = \"CLIP_DISTANCE1_WEBGL\";\n /** Enable gl_ClipDistance[2] and gl_CullDistance[2] */\n GLEnum[GLEnum[\"CLIP_DISTANCE2_WEBGL\"] = 12290] = \"CLIP_DISTANCE2_WEBGL\";\n /** Enable gl_ClipDistance[3] and gl_CullDistance[3] */\n GLEnum[GLEnum[\"CLIP_DISTANCE3_WEBGL\"] = 12291] = \"CLIP_DISTANCE3_WEBGL\";\n /** Enable gl_ClipDistance[4] and gl_CullDistance[4] */\n GLEnum[GLEnum[\"CLIP_DISTANCE4_WEBGL\"] = 12292] = \"CLIP_DISTANCE4_WEBGL\";\n /** Enable gl_ClipDistance[5] and gl_CullDistance[5] */\n GLEnum[GLEnum[\"CLIP_DISTANCE5_WEBGL\"] = 12293] = \"CLIP_DISTANCE5_WEBGL\";\n /** Enable gl_ClipDistance[6] and gl_CullDistance[6] */\n GLEnum[GLEnum[\"CLIP_DISTANCE6_WEBGL\"] = 12294] = \"CLIP_DISTANCE6_WEBGL\";\n /** Enable gl_ClipDistance[7] and gl_CullDistance[7] */\n GLEnum[GLEnum[\"CLIP_DISTANCE7_WEBGL\"] = 12295] = \"CLIP_DISTANCE7_WEBGL\";\n /** EXT_polygon_offset_clamp https://registry.khronos.org/webgl/extensions/EXT_polygon_offset_clamp/ */\n GLEnum[GLEnum[\"POLYGON_OFFSET_CLAMP_EXT\"] = 36379] = \"POLYGON_OFFSET_CLAMP_EXT\";\n /** EXT_clip_control https://registry.khronos.org/webgl/extensions/EXT_clip_control/ */\n GLEnum[GLEnum[\"LOWER_LEFT_EXT\"] = 36001] = \"LOWER_LEFT_EXT\";\n GLEnum[GLEnum[\"UPPER_LEFT_EXT\"] = 36002] = \"UPPER_LEFT_EXT\";\n GLEnum[GLEnum[\"NEGATIVE_ONE_TO_ONE_EXT\"] = 37726] = \"NEGATIVE_ONE_TO_ONE_EXT\";\n GLEnum[GLEnum[\"ZERO_TO_ONE_EXT\"] = 37727] = \"ZERO_TO_ONE_EXT\";\n GLEnum[GLEnum[\"CLIP_ORIGIN_EXT\"] = 37724] = \"CLIP_ORIGIN_EXT\";\n GLEnum[GLEnum[\"CLIP_DEPTH_MODE_EXT\"] = 37725] = \"CLIP_DEPTH_MODE_EXT\";\n /** WEBGL_blend_func_extended https://registry.khronos.org/webgl/extensions/WEBGL_blend_func_extended/ */\n GLEnum[GLEnum[\"SRC1_COLOR_WEBGL\"] = 35065] = \"SRC1_COLOR_WEBGL\";\n GLEnum[GLEnum[\"SRC1_ALPHA_WEBGL\"] = 34185] = \"SRC1_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"ONE_MINUS_SRC1_COLOR_WEBGL\"] = 35066] = \"ONE_MINUS_SRC1_COLOR_WEBGL\";\n GLEnum[GLEnum[\"ONE_MINUS_SRC1_ALPHA_WEBGL\"] = 35067] = \"ONE_MINUS_SRC1_ALPHA_WEBGL\";\n GLEnum[GLEnum[\"MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL\"] = 35068] = \"MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL\";\n /** EXT_texture_mirror_clamp_to_edge https://registry.khronos.org/webgl/extensions/EXT_texture_mirror_clamp_to_edge/ */\n GLEnum[GLEnum[\"MIRROR_CLAMP_TO_EDGE_EXT\"] = 34627] = \"MIRROR_CLAMP_TO_EDGE_EXT\";\n})(GLEnum || (GLEnum = {}));\nexport { GLEnum as GL };\n//# sourceMappingURL=webgl-constants.js.map","import { scaleLinear } from 'd3-scale'\nimport { mat3 } from 'gl-matrix'\nimport { Random } from 'random'\nimport { getRgbaColor, rgbToBrightness } from '@/graph/helper'\nimport { hoveredPointRingOpacity, focusedPointRingOpacity, defaultConfigValues } from '@/graph/variables'\nimport type { GraphConfigInterface } from '@/graph/config'\n\nexport const ALPHA_MIN = 0.001\nexport const MAX_POINT_SIZE = 64\n\n/**\n * Maximum number of executions to delay before performing hover detection.\n * This threshold prevents excessive hover detection calls for performance optimization.\n * The `findHoveredItem` method will skip actual detection until this count is reached.\n */\nexport const MAX_HOVER_DETECTION_DELAY = 4\n\n/**\n * Minimum mouse movement threshold (in pixels) to trigger hover detection.\n * If the mouse moves less than this distance, hover detection will be skipped to save performance.\n */\nexport const MIN_MOUSE_MOVEMENT_THRESHOLD = 2\n\nexport type Hovered = { index: number; position: [ number, number ] }\ntype Focused = { index: number }\n\n/**\n * Type alias for a 4x4 matrix stored as a 16-element array in column-major order.\n * Used for std140 uniform buffer layout compatibility.\n */\nexport type Mat4Array = [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]\n\nexport class Store {\n public pointsTextureSize = 0\n public linksTextureSize = 0\n public alpha = 1\n public transform = mat3.create()\n public screenSize: [number, number] = [0, 0]\n public mousePosition = [0, 0]\n public screenMousePosition = [0, 0]\n public selectedArea = [[0, 0], [0, 0]]\n public isSimulationRunning = false\n public simulationProgress = 0\n public selectedIndices: Float32Array | null = null\n public maxPointSize = MAX_POINT_SIZE\n public hoveredPoint: Hovered | undefined = undefined\n public focusedPoint: Focused | undefined = undefined\n public draggingPointIndex: number | undefined = undefined\n public hoveredLinkIndex: number | undefined = undefined\n public adjustedSpaceSize = defaultConfigValues.spaceSize\n public isSpaceKeyPressed = false\n public div: HTMLDivElement | undefined\n public webglMaxTextureSize = 16384 // Default fallback value\n\n public hoveredPointRingColor = [1, 1, 1, hoveredPointRingOpacity]\n public focusedPointRingColor = [1, 1, 1, focusedPointRingOpacity]\n public hoveredLinkColor = [-1, -1, -1, -1]\n // -1 means that the color is not set\n public greyoutPointColor = [-1, -1, -1, -1]\n // If backgroundColor is dark, isDarkenGreyout is true\n public isDarkenGreyout = false\n // Whether link hovering is enabled based on configured event handlers\n public isLinkHoveringEnabled = false\n private alphaTarget = 0\n private scalePointX = scaleLinear()\n private scalePointY = scaleLinear()\n private random = new Random()\n private _backgroundColor: [number, number, number, number] = [0, 0, 0, 0]\n\n public get backgroundColor (): [number, number, number, number] {\n return this._backgroundColor\n }\n\n /**\n * Gets the transformation matrix as a 4x4 matrix for std140 uniform buffer layout.\n *\n * This method converts the internal 3x3 transformation matrix (mat3) to a 4x4 matrix format\n * required by WebGPU uniform buffers using the std140 layout standard.\n *\n * ## Matrix Storage Format\n *\n * Matrices are stored in **column-major order** (GLSL convention). The internal `transform`\n * array is a 9-element array representing a 3x3 matrix:\n *\n * ```\n * [m00, m10, m20, m01, m11, m21, m02, m12, m22]\n * ```\n *\n * Which represents the matrix:\n * ```\n * [m00 m01 m02]\n * [m10 m11 m12]\n * [m20 m21 m22]\n * ```\n *\n * ## Why This Conversion Is Needed\n *\n * The internal `transform` property stores a 3x3 matrix (9 elements) which is sufficient for\n * 2D transformations (translation, rotation, scaling in x/y plane). However, when passing\n * transformation matrices to GPU shaders via uniform buffers, we must comply with the std140\n * layout standard.\n *\n * ### std140 Layout Requirements\n *\n * The std140 layout standard (used in both OpenGL and WebGPU) defines strict alignment rules:\n *\n * 1. **Matrix Alignment**: In std140, matrices are stored as arrays of column vectors\n * - `mat3` requires each column to be aligned to 16 bytes (vec4 alignment)\n * - This means `mat3` occupies 3 columns × 16 bytes = 48 bytes total\n * - `mat4` occupies 4 columns × 16 bytes = 64 bytes total\n *\n * 2. **Alignment Issues with mat3**:\n * - The 48-byte size of `mat3` creates awkward alignment and padding requirements\n * - Different GPU drivers may handle `mat3` padding inconsistently\n * - This can lead to data misalignment and incorrect transformations\n *\n * 3. **Why mat4 is Preferred**:\n * - `mat4` has clean 64-byte alignment (power of 2)\n * - Consistent behavior across all GPU drivers and platforms\n * - The shader can easily extract the 3x3 portion: `mat3 transformMat3 = mat3(transformationMatrix)`\n * - The 4th column is set to `[0, 0, 0, 1]` (homogeneous coordinate) which doesn't affect 2D transforms\n *\n * ### Conversion Process\n *\n * The 3x3 matrix is converted to 4x4 by:\n * - Placing the 3x3 values in the top-left corner (preserving column-major order)\n * - Setting the 4th column to `[0, 0, 0, 1]` (homogeneous coordinate)\n * - The 4th row is implicitly `[0, 0, 0, 1]` due to column-major storage\n *\n * This creates a valid 4x4 transformation matrix that:\n * - Maintains the same 2D transformation behavior\n * - Satisfies std140 alignment requirements\n * - Works consistently across all GPU platforms\n *\n * ### Usage in Shaders\n *\n * Shaders using uniform buffers receive this as `mat4` and extract the 3x3 portion:\n * ```glsl\n * layout(std140) uniform uniforms {\n * mat4 transformationMatrix;\n * } uniforms;\n *\n * mat3 transformMat3 = mat3(uniforms.transformationMatrix);\n * vec3 final = transformMat3 * vec3(position, 1);\n * ```\n *\n * @returns A 16-element array representing a 4x4 matrix in column-major order,\n * suitable for std140 uniform buffer layout. The matrix preserves the\n * 2D transformation from the original 3x3 matrix.\n *\n * @example\n * ```typescript\n * const matrix = store.transformationMatrix4x4;\n * uniformStore.setUniforms({\n * uniforms: {\n * transformationMatrix: matrix // Expects mat4x4<f32> in shader\n * }\n * });\n * ```\n */\n public get transformationMatrix4x4 (): Mat4Array {\n const t = this.transform\n\n // Validate transform array length\n if (t.length !== 9) {\n throw new Error(`Transform must be a 9-element array (3x3 matrix), got ${t.length} elements`)\n }\n\n // Convert 3x3 to 4x4 matrix in column-major order\n return [\n t[0], t[1], t[2], 0, // Column 0\n t[3], t[4], t[5], 0, // Column 1\n t[6], t[7], t[8], 0, // Column 2\n 0, 0, 0, 1, // Column 3 (homogeneous)\n ]\n }\n\n public set backgroundColor (color: [number, number, number, number]) {\n this._backgroundColor = color\n const brightness = rgbToBrightness(color[0], color[1], color[2])\n document.documentElement.style.setProperty('--cosmosgl-attribution-color', brightness > 0.65 ? 'black' : 'white')\n document.documentElement.style.setProperty('--cosmosgl-error-message-color', brightness > 0.65 ? 'black' : 'white')\n if (this.div) this.div.style.backgroundColor = `rgba(${color[0] * 255}, ${color[1] * 255}, ${color[2] * 255}, ${color[3]})`\n\n this.isDarkenGreyout = brightness < 0.65\n }\n\n public addRandomSeed (seed: number | string): void {\n this.random = this.random.clone(seed)\n }\n\n public getRandomFloat (min: number, max: number): number {\n return this.random.float(min, max)\n }\n\n /**\n * If the config parameter `spaceSize` exceeds the limits of WebGL,\n * it reduces the space size without changing the config parameter.\n * Ensures `spaceSize` is always a positive number >= 2 (required for Math.log2).\n */\n public adjustSpaceSize (configSpaceSize: number, webglMaxTextureSize: number): void {\n if (configSpaceSize <= 0 || !isFinite(configSpaceSize)) {\n console.error(`Invalid spaceSize value: ${configSpaceSize}. Using default value of ${defaultConfigValues.spaceSize}`)\n configSpaceSize = defaultConfigValues.spaceSize\n }\n // Enforce minimum value of 2 (since we use Math.log2, minimum should be 2^1 = 2)\n const minSpaceSize = 2\n if (configSpaceSize < minSpaceSize) {\n console.warn(`spaceSize (${configSpaceSize}) is too small. Using minimum value of ${minSpaceSize}`)\n configSpaceSize = minSpaceSize\n }\n\n // Validate webglMaxTextureSize (values below minSpaceSize are invalid; clamp would exceed limit)\n if (!Number.isFinite(webglMaxTextureSize) || webglMaxTextureSize <= 0 || webglMaxTextureSize < minSpaceSize) {\n console.warn(`Invalid webglMaxTextureSize: ${webglMaxTextureSize}. Using configSpaceSize without WebGL limit adjustment.`)\n this.adjustedSpaceSize = configSpaceSize\n return\n }\n\n // Handle WebGL limits - ensure result is still >= minSpaceSize\n if (configSpaceSize >= webglMaxTextureSize) {\n this.adjustedSpaceSize = Math.max(webglMaxTextureSize / 2, minSpaceSize)\n console.warn(`The \\`spaceSize\\` has been reduced to ${this.adjustedSpaceSize} due to WebGL limits`)\n } else this.adjustedSpaceSize = configSpaceSize\n }\n\n /**\n * Sets the WebGL texture size limit for use in atlas creation and other texture operations.\n */\n public setWebGLMaxTextureSize (webglMaxTextureSize: number): void {\n this.webglMaxTextureSize = webglMaxTextureSize\n }\n\n public updateScreenSize (width: number, height: number): void {\n const { adjustedSpaceSize } = this\n this.screenSize = [width, height]\n this.scalePointX\n .domain([0, adjustedSpaceSize])\n .range([(width - adjustedSpaceSize) / 2, (width + adjustedSpaceSize) / 2])\n this.scalePointY\n .domain([adjustedSpaceSize, 0])\n .range([(height - adjustedSpaceSize) / 2, (height + adjustedSpaceSize) / 2])\n }\n\n public scaleX (x: number): number {\n return this.scalePointX(x)\n }\n\n public scaleY (y: number): number {\n return this.scalePointY(y)\n }\n\n public setHoveredPointRingColor (color: string | [number, number, number, number]): void {\n const convertedRgba = getRgbaColor(color)\n this.hoveredPointRingColor[0] = convertedRgba[0]\n this.hoveredPointRingColor[1] = convertedRgba[1]\n this.hoveredPointRingColor[2] = convertedRgba[2]\n }\n\n public setFocusedPointRingColor (color: string | [number, number, number, number]): void {\n const convertedRgba = getRgbaColor(color)\n this.focusedPointRingColor[0] = convertedRgba[0]\n this.focusedPointRingColor[1] = convertedRgba[1]\n this.focusedPointRingColor[2] = convertedRgba[2]\n }\n\n public setGreyoutPointColor (color: string | [number, number, number, number] | undefined): void {\n if (color === undefined) {\n this.greyoutPointColor = [-1, -1, -1, -1]\n return\n }\n const convertedRgba = getRgbaColor(color)\n this.greyoutPointColor[0] = convertedRgba[0]\n this.greyoutPointColor[1] = convertedRgba[1]\n this.greyoutPointColor[2] = convertedRgba[2]\n this.greyoutPointColor[3] = convertedRgba[3]\n }\n\n public updateLinkHoveringEnabled (config: Pick<GraphConfigInterface, 'onLinkClick' | 'onLinkContextMenu' | 'onLinkMouseOver' | 'onLinkMouseOut'>): void {\n this.isLinkHoveringEnabled = !!(config.onLinkClick || config.onLinkContextMenu || config.onLinkMouseOver || config.onLinkMouseOut)\n if (!this.isLinkHoveringEnabled) {\n this.hoveredLinkIndex = undefined\n }\n }\n\n public setHoveredLinkColor (color?: string | [number, number, number, number]): void {\n if (color === undefined) {\n this.hoveredLinkColor = [-1, -1, -1, -1]\n return\n }\n const convertedRgba = getRgbaColor(color)\n this.hoveredLinkColor[0] = convertedRgba[0]\n this.hoveredLinkColor[1] = convertedRgba[1]\n this.hoveredLinkColor[2] = convertedRgba[2]\n this.hoveredLinkColor[3] = convertedRgba[3]\n }\n\n public setFocusedPoint (index?: number): void {\n if (index !== undefined) {\n this.focusedPoint = { index }\n } else this.focusedPoint = undefined\n }\n\n public addAlpha (decay: number): number {\n return (this.alphaTarget - this.alpha) * this.alphaDecay(decay)\n }\n\n private alphaDecay = (decay: number): number => 1 - Math.pow(ALPHA_MIN, 1 / decay)\n}\n","import { color as d3Color } from 'd3-color'\nimport { Device, Framebuffer } from '@luma.gl/core'\nimport { WebGLDevice } from '@luma.gl/webgl'\nimport { GL } from '@luma.gl/constants'\nimport DOMPurify from 'dompurify'\n\nimport { MAX_POINT_SIZE } from '@/graph/modules/Store'\n\nexport const isFunction = <T>(a: T): boolean => typeof a === 'function'\nexport const isArray = <T>(a: unknown | T[]): a is T[] => Array.isArray(a)\nexport const isObject = <T>(a: T): boolean => (a instanceof Object)\nexport const isAClassInstance = <T>(a: T): boolean => {\n if (a instanceof Object) {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (a as T & Object).constructor.name !== 'Function' && (a as T & Object).constructor.name !== 'Object'\n } else return false\n}\nexport const isPlainObject = <T>(a: T): boolean => isObject(a) && !isArray(a) && !isFunction(a) && !isAClassInstance(a)\n\nexport function getRgbaColor (value: string | [number, number, number, number]): [number, number, number, number] {\n let rgba: [number, number, number, number]\n if (isArray(value)) {\n rgba = value\n } else {\n const color = d3Color(value)\n const rgb = color?.rgb()\n rgba = [rgb?.r || 0, rgb?.g || 0, rgb?.b || 0, color?.opacity ?? 1]\n }\n\n return [\n rgba[0] / 255,\n rgba[1] / 255,\n rgba[2] / 255,\n rgba[3],\n ]\n}\n\nexport function rgbToBrightness (r: number, g: number, b: number): number {\n return 0.2126 * r + 0.7152 * g + 0.0722 * b\n}\n\n/**\n * TODO: Migrate from deprecated `readPixelsToArrayWebGL` to CommandEncoder API\n *\n * `readPixelsToArrayWebGL` is deprecated in luma.gl v9. The recommended modern approach is:\n *\n * 1. Create a buffer to hold the pixel data:\n * const buffer = device.createBuffer({\n * byteLength: width * height * 4 * 4, // RGBA, 4 bytes per float\n * usage: Buffer.COPY_DST | Buffer.MAP_READ\n * });\n *\n * 2. Copy texture/framebuffer to buffer using command encoder:\n * const commandEncoder = device.createCommandEncoder();\n * commandEncoder.copyTextureToBuffer({\n * sourceTexture: fbo, // Can be Texture or Framebuffer\n * width: sourceWidth ?? fbo.width,\n * height: sourceHeight ?? fbo.height,\n * origin: [sourceX, sourceY],\n * destinationBuffer: buffer\n * });\n * const commandBuffer = commandEncoder.finish();\n * device.submit(commandBuffer);\n *\n * 3. Read the data from the buffer (async):\n * const pixelData = await buffer.readAsync(); // Returns ArrayBuffer\n * return new Float32Array(pixelData);\n *\n * Note: The modern approach is asynchronous, so this function signature would need to change\n * to return Promise<Float32Array> or we'd need to handle async at all call sites (18 locations).\n *\n * Migration impact:\n * - This function is used in 18 places across the codebase\n * - All call sites would need to be updated to handle async\n * - Consider batching the migration to avoid inconsistencies\n *\n * Current status: Deprecated but still functional. Keeping for now until full migration can be planned.\n *\n * @note Cosmos currently supports WebGL only; support for other device types will be added later.\n */\nexport function readPixels (device: Device, fbo: Framebuffer, sourceX = 0, sourceY = 0, sourceWidth?: number, sourceHeight?: number): Float32Array {\n // Let luma.gl auto-allocate based on texture format\n // It will use Float32Array for rgba32float textures\n return device.readPixelsToArrayWebGL(fbo, {\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n }) as Float32Array\n}\n\n/**\n * Returns the maximum point size supported by the device, scaled by pixel ratio.\n * For WebGL devices, reads the limit from the context; for other device types, uses MAX_POINT_SIZE from Store.\n * @param device - The luma.gl device\n * @param pixelRatio - Device pixel ratio to scale the result\n * @returns Maximum point size (device limit / pixelRatio)\n */\nexport function getMaxPointSize (device: Device, pixelRatio: number): number {\n switch (device.info.type) {\n case 'webgl': {\n const range = (device as WebGLDevice).gl.getParameter(GL.ALIASED_POINT_SIZE_RANGE) as [number, number]\n return (range?.[1] ?? MAX_POINT_SIZE) / pixelRatio\n }\n case 'webgpu':\n // Will be implemented when WebGPU support is added\n return MAX_POINT_SIZE / pixelRatio\n default:\n return MAX_POINT_SIZE / pixelRatio\n }\n}\n\nexport function clamp (num: number, min: number, max: number): number {\n return Math.min(Math.max(num, min), max)\n}\n\nexport function isNumber (value: number | undefined | null | typeof NaN): boolean {\n return value !== undefined && value !== null && !Number.isNaN(value)\n}\n\n/**\n * Sanitizes HTML content to prevent XSS attacks using DOMPurify\n *\n * This function is used internally to sanitize HTML content before setting innerHTML,\n * such as in attribution text. It uses a safe default configuration that allows\n * only common safe HTML elements and attributes.\n *\n * @param html The HTML string to sanitize\n * @param options Optional DOMPurify configuration options to override defaults\n * @returns Sanitized HTML string safe for innerHTML usage\n */\nexport function sanitizeHtml (html: string, options?: DOMPurify.Config): string {\n return DOMPurify.sanitize(html, {\n // Default configuration: allow common safe HTML elements and attributes\n ALLOWED_TAGS: ['a', 'b', 'i', 'em', 'strong', 'span', 'div', 'p', 'br'],\n ALLOWED_ATTR: ['href', 'target', 'class', 'id', 'style'],\n ALLOW_DATA_ATTR: false,\n ...options,\n })\n}\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { D3ZoomEvent } from 'd3-zoom'\nimport { D3DragEvent } from 'd3-drag'\nimport {\n defaultPointColor,\n defaultGreyoutPointOpacity,\n defaultGreyoutPointColor,\n defaultPointOpacity,\n defaultPointSize,\n defaultLinkColor,\n defaultGreyoutLinkOpacity,\n defaultLinkOpacity,\n defaultLinkWidth,\n defaultBackgroundColor,\n defaultConfigValues,\n} from '@/graph/variables'\nimport { isPlainObject } from '@/graph/helper'\nimport { type Hovered } from '@/graph/modules/Store'\n\nexport interface GraphConfigInterface {\n /**\n * If set to `false`, the simulation will not run.\n * This property will be applied only on component initialization and it\n * can't be changed using the `setConfig` method.\n * Default value: `true`\n */\n enableSimulation?: boolean;\n /**\n * Canvas background color.\n * Can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values.\n * Default value: '#222222'\n */\n backgroundColor?: string | [number, number, number, number];\n /**\n * Simulation space size (max 8192).\n * Default value: `8192`\n */\n spaceSize?: number;\n\n /**\n * The default color to use for points when no point colors are provided,\n * or if the color value in the array is `undefined` or `null`.\n * This can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n * Default value: '#b3b3b3'\n */\n pointDefaultColor?: string | [number, number, number, number];\n\n /** @deprecated Use `pointDefaultColor` instead */\n pointColor?: string | [number, number, number, number];\n\n /**\n * The color to use for points when they are greyed out (when selection is active).\n * This can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n *\n * If not provided, the color will be the same as the point's original color,\n * but darkened or lightened depending on the background color.\n *\n * If `pointGreyoutOpacity` is also defined, it will override the alpha/opacity component\n * of this color.\n *\n * Default value: `undefined`\n */\n pointGreyoutColor?: string | [number, number, number, number];\n\n /**\n * Opacity value for points when they are greyed out (when selection is active).\n * Values range from 0 (completely transparent) to 1 (fully opaque).\n *\n * If defined, this value will override the alpha/opacity component of `pointGreyoutColor`.\n *\n * Default value: `undefined`\n */\n pointGreyoutOpacity?: number;\n\n /**\n * The default size value to use for points when no point sizes are provided or\n * if the size value in the array is `undefined` or `null`.\n * Default value: `4`\n */\n pointDefaultSize?: number;\n\n /** @deprecated Use `pointDefaultSize` instead */\n pointSize?: number;\n\n /**\n * Universal opacity value applied to all points.\n * This value multiplies with individual point alpha values (if set via setPointColors).\n * Useful for dynamically controlling opacity of all points without updating individual RGBA arrays.\n * Default value: `1.0`\n */\n pointOpacity?: number;\n\n /**\n * Scale factor for the point size.\n * Default value: `1`\n */\n pointSizeScale?: number;\n\n /**\n * Cursor style to use when hovering over a point\n * Default value: `auto`\n */\n hoveredPointCursor?: string;\n\n /**\n * Cursor style to use when hovering over a link\n * Default value: `auto`\n */\n hoveredLinkCursor?: string;\n\n /**\n * Turns ring rendering around a point on hover on / off\n * Default value: `false`\n */\n renderHoveredPointRing?: boolean;\n\n /**\n * Hovered point ring color hex value.\n * Can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values.\n * Default value: `white`\n */\n hoveredPointRingColor?: string | [number, number, number, number];\n\n /**\n * Focused point ring color hex value.\n * Can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values.\n * Default value: `white`\n */\n focusedPointRingColor?: string | [number, number, number, number];\n\n /**\n * Set focus on a point by index. A ring will be highlighted around the focused point.\n * When set to `undefined`, no point is focused.\n * Default value: `undefined`\n */\n focusedPointIndex?: number;\n\n /**\n * Turns link rendering on / off.\n * Default value: `true`\n */\n renderLinks?: boolean;\n\n /**\n * The default color to use for links when no link colors are provided,\n * or if the color value in the array is `undefined` or `null`.\n * This can be either a hex color string (e.g., '#666666') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n * Default value: '#666666'\n */\n linkDefaultColor?: string | [number, number, number, number];\n\n /** @deprecated Use `linkDefaultColor` instead */\n linkColor?: string | [number, number, number, number];\n\n /**\n * Universal opacity value applied to all links.\n * This value multiplies with individual link alpha values (if set via setLinkColors).\n * Useful for dynamically controlling opacity of all links without updating individual RGBA arrays.\n * Default value: `1.0`\n */\n linkOpacity?: number;\n\n /**\n * Greyed out link opacity value when the selection is active.\n * Default value: `0.1`\n */\n linkGreyoutOpacity?: number;\n /**\n * The default width value to use for links when no link widths are provided or if the width value in the array is `undefined` or `null`.\n * Default value: `1`\n */\n linkDefaultWidth?: number;\n\n /** @deprecated Use `linkDefaultWidth` instead */\n linkWidth?: number;\n /**\n * The color to use for links when they are hovered.\n * This can be either a hex color string (e.g., '#ff3333') or an array of RGBA values\n * in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255.\n * Default value: `undefined`\n */\n hoveredLinkColor?: string | [number, number, number, number];\n /**\n * Number of pixels to add to the link width when hovered.\n * The hovered width is calculated as: originalWidth + hoveredLinkWidthIncrease\n * Default value: `5`\n */\n hoveredLinkWidthIncrease?: number;\n /**\n * Scale factor for the link width.\n * Default value: `1`\n */\n linkWidthScale?: number;\n /**\n * Increase or decrease the size of the links when zooming in or out.\n * Default value: `false`\n */\n scaleLinksOnZoom?: boolean;\n /**\n * If set to true, links are rendered as curved lines.\n * Otherwise as straight lines.\n * Default value: `false`\n */\n curvedLinks?: boolean;\n /**\n * Number of segments in a curved line.\n * Default value: `19`.\n */\n curvedLinkSegments?: number;\n /**\n * Weight affects the shape of the curve.\n * Default value: `0.8`.\n */\n curvedLinkWeight?: number;\n /**\n * Defines the position of the control point of the curve on the normal from the centre of the line.\n * If set to 1 then the control point is at a distance equal to the length of the line.\n * Default value: `0.5`\n */\n curvedLinkControlPointDistance?: number;\n /**\n * The default link arrow value that controls whether or not to display link arrows.\n * Default value: `false`\n */\n linkDefaultArrows?: boolean;\n\n /** @deprecated Use `linkDefaultArrows` instead */\n linkArrows?: boolean;\n /**\n * Scale factor for the link arrows size.\n * Default value: `1`\n */\n linkArrowsSizeScale?: number;\n /**\n * The range defines the minimum and maximum link visibility distance in pixels.\n * The link will be fully opaque when its length is less than the first number in the array,\n * and will have `linkVisibilityMinTransparency` transparency when its length is greater than\n * the second number in the array.\n * This distance is defined in screen space coordinates and will change as you zoom in and out\n * (e.g. links become longer when you zoom in, and shorter when you zoom out).\n * Default value: `[50, 150]`\n */\n linkVisibilityDistanceRange?: number[];\n /**\n * The transparency value that the link will have when its length reaches\n * the maximum link distance value from `linkVisibilityDistanceRange`.\n * Default value: `0.25`\n */\n linkVisibilityMinTransparency?: number;\n\n /**\n * Decay coefficient. Use smaller values if you want the simulation to \"cool down\" slower.\n * Default value: `5000`\n */\n simulationDecay?: number;\n /**\n * Gravity force coefficient.\n * Default value: `0.25`\n */\n simulationGravity?: number;\n /**\n * Centering to center mass force coefficient.\n * Default value: `0`\n */\n simulationCenter?: number;\n /**\n * Repulsion force coefficient.\n * Default value: `1.0`\n */\n simulationRepulsion?: number;\n /**\n * Decreases / increases the detalization of the Many-Body force calculations.\n * Default value: `1.15`\n */\n simulationRepulsionTheta?: number;\n /**\n * Link spring force coefficient.\n * Default value: `1`\n */\n simulationLinkSpring?: number;\n /**\n * Minimum link distance.\n * Default value: `10`\n */\n simulationLinkDistance?: number;\n /**\n * Range of random link distance values.\n * Default value: `[1, 1.2]`\n */\n simulationLinkDistRandomVariationRange?: number[];\n /**\n * Repulsion coefficient from mouse position.\n * The repulsion force is activated by pressing the right mouse button.\n * Default value: `2`\n */\n simulationRepulsionFromMouse?: number;\n /**\n * Enable or disable the repulsion force from mouse when right-clicking.\n * When set to `true`, holding the right mouse button will activate the mouse repulsion force.\n * When set to `false`, right-clicking will not trigger any repulsion force.\n * Default value: `false`\n */\n enableRightClickRepulsion?: boolean;\n /**\n * Friction coefficient.\n * Values range from 0 (high friction, stops quickly) to 1 (no friction, keeps moving).\n * Default value: `0.85`\n */\n simulationFriction?: number;\n /**\n * Cluster coefficient.\n * Default value: `0.1`\n */\n simulationCluster?: number;\n\n /**\n * Callback function that will be called when the simulation starts.\n * Default value: `undefined`\n */\n onSimulationStart?: () => void;\n /**\n * Callback function that will be called on every simulation tick.\n * The value of the first argument `alpha` will decrease over time as the simulation \"cools down\".\n * If there's a point under the mouse pointer, its index will be passed as the second argument\n * and position as the third argument:\n * `(alpha: number, hoveredIndex: number | undefined, pointPosition: [number, number] | undefined) => void`.\n * Default value: `undefined`\n */\n onSimulationTick?: (\n alpha: number, hoveredIndex?: number, pointPosition?: [number, number]\n ) => void;\n /**\n * Callback function that will be called when the simulation stops.\n * Default value: `undefined`\n */\n onSimulationEnd?: () => void;\n /**\n * Callback function that will be called when the simulation gets paused.\n * Default value: `undefined`\n */\n onSimulationPause?: () => void;\n /**\n * Callback function that will be called when the simulation is restarted.\n * @deprecated Use `onSimulationUnpause` instead. This callback will be removed in a future version.\n * Default value: `undefined`\n */\n onSimulationRestart?: () => void;\n /**\n * Callback function that will be called when the simulation is unpaused.\n * Default value: `undefined`\n */\n onSimulationUnpause?: () => void;\n\n /**\n * Callback function that will be called on every canvas click.\n * If clicked on a point, its index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onClick?: (\n index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a point is clicked.\n * The point index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number, pointPosition: [number, number], event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onPointClick?: (\n index: number,\n pointPosition: [number, number],\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a link is clicked.\n * The link index will be passed as the first argument and the corresponding mouse event as the second argument:\n * `(linkIndex: number, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onLinkClick?: (\n linkIndex: number,\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when the background (empty space) is clicked.\n * The mouse event will be passed as the first argument:\n * `(event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onBackgroundClick?: (\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on the canvas.\n * If triggered on a point, its index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onContextMenu?: (\n index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on a point.\n * The point index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number, pointPosition: [number, number], event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onPointContextMenu?: (\n index: number,\n pointPosition: [number, number],\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on a link.\n * The link index will be passed as the first argument and the corresponding mouse event as the second argument:\n * `(linkIndex: number, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onLinkContextMenu?: (\n linkIndex: number,\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a context menu trigger (typically right click) happens on the background (empty space).\n * The mouse event will be passed as the first argument:\n * `(event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onBackgroundContextMenu?: (\n event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when mouse movement happens.\n * If the mouse moves over a point, its index will be passed as the first argument,\n * position as the second argument and the corresponding mouse event as the third argument:\n * `(index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent) => void`.\n * Default value: `undefined`\n */\n onMouseMove?: (\n index: number | undefined, pointPosition: [number, number] | undefined, event: MouseEvent\n ) => void;\n\n /**\n * Callback function that will be called when a point appears under the mouse\n * as a result of a mouse event, zooming and panning, or movement of points.\n * The point index will be passed as the first argument, position as the second argument,\n * the corresponding mouse event or D3's zoom event as the third argument, and whether\n * the hovered point is selected as the fourth argument:\n * `(index: number, pointPosition: [number, number], event: MouseEvent | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | D3ZoomEvent<HTMLCanvasElement, undefined> | undefined, isSelected: boolean) => void`.\n * Default value: `undefined`\n */\n onPointMouseOver?: (\n index: number,\n pointPosition: [number, number],\n event: MouseEvent | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | D3ZoomEvent<HTMLCanvasElement, undefined> | undefined,\n isSelected: boolean\n ) => void;\n\n /**\n * Callback function that will be called when a point is no longer underneath\n * the mouse pointer because of a mouse event, zoom/pan event, or movement of points.\n * The corresponding mouse event or D3's zoom event will be passed as the first argument:\n * `(event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void`.\n * Default value: `undefined`\n */\n onPointMouseOut?: (event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void;\n\n /**\n * Callback function that will be called when the mouse moves over a link.\n * The link index will be passed as the first argument:\n * `(linkIndex: number) => void`.\n * Default value: `undefined`\n */\n onLinkMouseOver?: (linkIndex: number) => void;\n\n /**\n * Callback function that will be called when the mouse moves out of a link.\n * The event will be passed as the first argument:\n * `(event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void`.\n * Default value: `undefined`\n */\n onLinkMouseOut?: (event: MouseEvent | D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | undefined) => void;\n\n /**\n * Callback function that will be called when zooming or panning starts.\n * First argument is a D3 Zoom Event and second indicates whether\n * the event has been initiated by a user interaction (e.g. a mouse event):\n * `(event: D3ZoomEvent, userDriven: boolean) => void`.\n * Default value: `undefined`\n */\n onZoomStart?: (e: D3ZoomEvent<HTMLCanvasElement, undefined>, userDriven: boolean) => void;\n\n /**\n * Callback function that will be called continuously during zooming or panning.\n * First argument is a D3 Zoom Event and second indicates whether\n * the event has been initiated by a user interaction (e.g. a mouse event):\n * `(event: D3ZoomEvent, userDriven: boolean) => void`.\n * Default value: `undefined`\n */\n onZoom?: (e: D3ZoomEvent<HTMLCanvasElement, undefined>, userDriven: boolean) => void;\n\n /**\n * Callback function that will be called when zooming or panning ends.\n * First argument is a D3 Zoom Event and second indicates whether\n * the event has been initiated by a user interaction (e.g. a mouse event):\n * `(event: D3ZoomEvent, userDriven: boolean) => void`.\n * Default value: `undefined`\n */\n onZoomEnd?: (e: D3ZoomEvent<HTMLCanvasElement, undefined>, userDriven: boolean) => void;\n\n /**\n * Callback function that will be called when dragging starts.\n * First argument is a D3 Drag Event:\n * `(event: D3DragEvent) => void`.\n * Default value: `undefined`\n */\n onDragStart?: (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => void;\n\n /**\n * Callback function that will be called continuously during dragging.\n * First argument is a D3 Drag Event:\n * `(event: D3DragEvent) => void`.\n * Default value: `undefined`\n */\n onDrag?: (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => void;\n\n /**\n * Callback function that will be called when dragging ends.\n * First argument is a D3 Drag Event:\n * `(event: D3DragEvent) => void`.\n * Default value: `undefined`\n */\n onDragEnd?: (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => void;\n\n /**\n * Show WebGL performance monitor.\n * Default value: `false`\n */\n showFPSMonitor?: boolean;\n /**\n * Pixel ratio for the canvas. Higher values use more GPU memory but provide better quality on high-DPI displays.\n * Default value: `window.devicePixelRatio || 2`\n */\n pixelRatio?: number;\n /**\n * Increase or decrease the size of the points when zooming in or out.\n * Default value: `false`\n */\n scalePointsOnZoom?: boolean;\n /**\n * Initial zoom level. Can be set once during graph initialization.\n * If set, `fitViewOnInit` value will be ignored.\n * Default value: `undefined`\n */\n initialZoomLevel?: number;\n /**\n * Enables or disables zooming in and out.\n * Default: `true`\n */\n enableZoom?: boolean;\n /**\n * Controls whether the simulation remains active during zoom operations.\n * When set to `true`, the simulation continues running while zooming.\n * When set to `false`, the simulation pauses during zoom operations.\n * Default value: `false`\n */\n enableSimulationDuringZoom?: boolean;\n /**\n * Enables or disables dragging of points in the graph.\n * Default value: `false`\n */\n enableDrag?: boolean;\n /**\n * Whether to center and zoom the view to fit all points in the scene on initialization or not.\n * Ignored if `initialZoomLevel` is set.\n * Default: `true`\n */\n fitViewOnInit?: boolean;\n /**\n * Delay in milliseconds before fitting the view when `fitViewOnInit` is enabled.\n * Useful if you want the layout to stabilize a bit before fitting.\n * Default: `250`\n */\n fitViewDelay?: number;\n /**\n * Padding to apply when fitting the view to show all points.\n * This value is added to the calculated bounding box to provide some extra space around the points.\n * This is used when the `fitViewOnInit` option is enabled.\n * Default: `0.1`\n */\n fitViewPadding?: number;\n /**\n * Duration in milliseconds for fitting the view to show all points when fitViewOnInit is enabled.\n * Default: `250`\n */\n fitViewDuration?: number;\n /**\n * When `fitViewOnInit` is set to `true`, fits the view to show the points within a rectangle\n * defined by its two corner coordinates `[[left, bottom], [right, top]]` in the scene space.\n * Default: `undefined`\n */\n fitViewByPointsInRect?: [[number, number], [number, number]] | [number, number][];\n /**\n * When `fitViewOnInit` is set to `true`, fits the view to show only the specified points by their indices.\n * Takes precedence over `fitViewByPointsInRect` when both are provided.\n * Default: `undefined`\n */\n fitViewByPointIndices?: number[];\n /**\n * Providing a `randomSeed` value allows you to control\n * the randomness of the layout across different simulation runs.\n * It is useful when you want the graph to always look the same on same datasets.\n * This property will be applied only on component initialization and it\n * can't be changed using the `setConfig` method.\n * Default value: undefined\n */\n randomSeed?: number | string;\n /**\n * Point sampling distance in pixels between neighboring points when calling the `getSampledPointPositionsMap` method.\n * This parameter determines how many points will be included in the sample.\n * Default value: `150`\n */\n pointSamplingDistance?: number;\n /**\n * Controls automatic position adjustment of points in the visible space.\n *\n * When `undefined` (default):\n * - If simulation is disabled (`enableSimulation: false`), points will be automatically\n * repositioned to fit within the visible space\n * - If simulation is enabled, points will not be rescaled\n *\n * When explicitly set:\n * - `true`: Forces points positions to be rescaled\n * - `false`: Forces points positions to not be rescaled\n */\n rescalePositions?: boolean | undefined;\n /**\n * Controls the text shown in the bottom right corner.\n * - When a non-empty string is provided: Displays the string as HTML\n * - When empty string or not provided: No text is displayed\n */\n attribution?: string;\n}\n\nexport class GraphConfig implements GraphConfigInterface {\n public enableSimulation = defaultConfigValues.enableSimulation\n public backgroundColor = defaultBackgroundColor\n public spaceSize = defaultConfigValues.spaceSize\n public pointColor = defaultPointColor\n // TODO: When pointColor is removed, change this to:\n // public pointDefaultColor = defaultPointColor\n // Currently undefined to allow fallback to deprecated pointColor via nullish coalescing\n // in GraphData.updatePointColor() (see: this._config.pointDefaultColor ?? this._config.pointColor)\n public pointDefaultColor = undefined\n public pointGreyoutOpacity = defaultGreyoutPointOpacity\n public pointGreyoutColor = defaultGreyoutPointColor\n public pointSize = defaultPointSize\n // TODO: When pointSize is removed, change this to:\n // public pointDefaultSize = defaultPointSize\n // Currently undefined to allow fallback to deprecated pointSize via nullish coalescing\n // in GraphData.updatePointSize() (see: this._config.pointDefaultSize ?? this._config.pointSize)\n public pointDefaultSize = undefined\n public pointOpacity = defaultPointOpacity\n public pointSizeScale = defaultConfigValues.pointSizeScale\n public hoveredPointCursor = defaultConfigValues.hoveredPointCursor\n public hoveredLinkCursor = defaultConfigValues.hoveredLinkCursor\n public renderHoveredPointRing = defaultConfigValues.renderHoveredPointRing\n public hoveredPointRingColor = defaultConfigValues.hoveredPointRingColor\n public focusedPointRingColor = defaultConfigValues.focusedPointRingColor\n public focusedPointIndex = defaultConfigValues.focusedPointIndex\n public linkColor = defaultLinkColor\n // TODO: When linkColor is removed, change this to:\n // public linkDefaultColor = defaultLinkColor\n // Currently undefined to allow fallback to deprecated linkColor via nullish coalescing\n // in GraphData.updateLinkColor() (see: this._config.linkDefaultColor ?? this._config.linkColor)\n public linkDefaultColor = undefined\n public linkOpacity = defaultLinkOpacity\n public linkGreyoutOpacity = defaultGreyoutLinkOpacity\n public linkWidth = defaultLinkWidth\n // TODO: When linkWidth is removed, change this to:\n // public linkDefaultWidth = defaultLinkWidth\n // Currently undefined to allow fallback to deprecated linkWidth via nullish coalescing\n // in GraphData.updateLinkWidth() (see: this._config.linkDefaultWidth ?? this._config.linkWidth)\n public linkDefaultWidth = undefined\n public linkWidthScale = defaultConfigValues.linkWidthScale\n public hoveredLinkColor = defaultConfigValues.hoveredLinkColor\n public hoveredLinkWidthIncrease = defaultConfigValues.hoveredLinkWidthIncrease\n public renderLinks = defaultConfigValues.renderLinks\n public curvedLinks = defaultConfigValues.curvedLinks\n public curvedLinkSegments = defaultConfigValues.curvedLinkSegments\n public curvedLinkWeight = defaultConfigValues.curvedLinkWeight\n public curvedLinkControlPointDistance = defaultConfigValues.curvedLinkControlPointDistance\n public linkArrows = defaultConfigValues.linkArrows\n // TODO: When linkArrows is removed, change this to:\n // public linkDefaultArrows = defaultConfigValues.linkArrows\n // Currently undefined to allow fallback to deprecated linkArrows via nullish coalescing\n // in GraphData.updateArrows() (see: this._config.linkDefaultArrows ?? this._config.linkArrows)\n public linkDefaultArrows = undefined\n public linkArrowsSizeScale = defaultConfigValues.linkArrowsSizeScale\n public scaleLinksOnZoom = defaultConfigValues.scaleLinksOnZoom\n public linkVisibilityDistanceRange = defaultConfigValues.linkVisibilityDistanceRange\n public linkVisibilityMinTransparency = defaultConfigValues.linkVisibilityMinTransparency\n\n public simulationDecay = defaultConfigValues.simulation.decay\n public simulationGravity = defaultConfigValues.simulation.gravity\n public simulationCenter = defaultConfigValues.simulation.center\n public simulationRepulsion = defaultConfigValues.simulation.repulsion\n public simulationRepulsionTheta = defaultConfigValues.simulation.repulsionTheta\n public simulationLinkSpring = defaultConfigValues.simulation.linkSpring\n public simulationLinkDistance = defaultConfigValues.simulation.linkDistance\n public simulationLinkDistRandomVariationRange = defaultConfigValues.simulation.linkDistRandomVariationRange\n public simulationRepulsionFromMouse = defaultConfigValues.simulation.repulsionFromMouse\n public enableRightClickRepulsion = defaultConfigValues.enableRightClickRepulsion\n public simulationFriction = defaultConfigValues.simulation.friction\n public simulationCluster = defaultConfigValues.simulation.cluster\n\n public onSimulationStart: GraphConfigInterface['onSimulationStart'] = undefined\n public onSimulationTick: GraphConfigInterface['onSimulationTick'] = undefined\n public onSimulationEnd: GraphConfigInterface['onSimulationEnd'] = undefined\n public onSimulationPause: GraphConfigInterface['onSimulationPause'] = undefined\n public onSimulationRestart: GraphConfigInterface['onSimulationRestart'] = undefined\n public onSimulationUnpause: GraphConfigInterface['onSimulationUnpause'] = undefined\n\n public onClick: GraphConfigInterface['onClick'] = undefined\n public onPointClick: GraphConfigInterface['onPointClick'] = undefined\n public onLinkClick: GraphConfigInterface['onLinkClick'] = undefined\n public onBackgroundClick: GraphConfigInterface['onBackgroundClick'] = undefined\n public onContextMenu: GraphConfigInterface['onContextMenu'] = undefined\n public onPointContextMenu: GraphConfigInterface['onPointContextMenu'] = undefined\n public onLinkContextMenu: GraphConfigInterface['onLinkContextMenu'] = undefined\n public onBackgroundContextMenu: GraphConfigInterface['onBackgroundContextMenu'] = undefined\n public onMouseMove: GraphConfigInterface['onMouseMove'] = undefined\n public onPointMouseOver: GraphConfigInterface['onPointMouseOver'] = undefined\n public onPointMouseOut: GraphConfigInterface['onPointMouseOut'] = undefined\n public onLinkMouseOver: GraphConfigInterface['onLinkMouseOver'] = undefined\n public onLinkMouseOut: GraphConfigInterface['onLinkMouseOut'] = undefined\n public onZoomStart: GraphConfigInterface['onZoomStart'] = undefined\n public onZoom: GraphConfigInterface['onZoom'] = undefined\n public onZoomEnd: GraphConfigInterface['onZoomEnd'] = undefined\n public onDragStart: GraphConfigInterface['onDragStart'] = undefined\n public onDrag: GraphConfigInterface['onDrag'] = undefined\n public onDragEnd: GraphConfigInterface['onDragEnd'] = undefined\n\n public showFPSMonitor = defaultConfigValues.showFPSMonitor\n\n public pixelRatio = defaultConfigValues.pixelRatio\n\n public scalePointsOnZoom = defaultConfigValues.scalePointsOnZoom\n public initialZoomLevel = undefined\n public enableZoom = defaultConfigValues.enableZoom\n public enableSimulationDuringZoom = defaultConfigValues.enableSimulationDuringZoom\n public enableDrag = defaultConfigValues.enableDrag\n public fitViewOnInit = defaultConfigValues.fitViewOnInit\n public fitViewDelay = defaultConfigValues.fitViewDelay\n public fitViewPadding = defaultConfigValues.fitViewPadding\n public fitViewDuration = defaultConfigValues.fitViewDuration\n public fitViewByPointsInRect = undefined\n public fitViewByPointIndices = undefined\n\n public randomSeed = undefined\n public pointSamplingDistance = defaultConfigValues.pointSamplingDistance\n public attribution = defaultConfigValues.attribution\n public rescalePositions = defaultConfigValues.rescalePositions\n\n public init (config: GraphConfigInterface): void {\n (Object.keys(config) as (keyof GraphConfigInterface)[])\n .forEach(configParameter => {\n this.deepMergeConfig(this.getConfig(), config, configParameter)\n })\n }\n\n public deepMergeConfig <T> (current: T, next: T, key: keyof T): void {\n if (isPlainObject(current[key]) && isPlainObject(next[key])) {\n // eslint-disable-next-line @typescript-eslint/ban-types\n (Object.keys(next[key] as Object) as (keyof T[keyof T])[])\n .forEach(configParameter => {\n this.deepMergeConfig(current[key], next[key], configParameter)\n })\n } else current[key] = next[key]\n }\n\n private getConfig (): GraphConfigInterface {\n return this\n }\n}\n","import { Device } from '@luma.gl/core'\nimport { GraphConfigInterface } from '@/graph/config'\nimport { GraphData } from '@/graph/modules/GraphData'\nimport { Points } from '@/graph/modules/Points'\nimport { Store } from '@/graph/modules/Store'\n\nexport class CoreModule {\n public readonly device: Device\n public readonly config: GraphConfigInterface\n public readonly store: Store\n public readonly data: GraphData\n public readonly points: Points | undefined\n public _debugRandomNumber = Math.floor(Math.random() * 1000)\n\n public constructor (\n device: Device,\n config: GraphConfigInterface,\n store: Store,\n data: GraphData,\n points?: Points\n ) {\n this.device = device\n this.config = config\n this.store = store\n this.data = data\n if (points) this.points = points\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nin vec4 rgba;\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform calculateCentermassUniforms {\\n float pointsTextureSize;\\n} calculateCentermass;\\n\\n#define pointsTextureSize calculateCentermass.pointsTextureSize\\n#else\\nuniform float pointsTextureSize;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nout vec4 rgba;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, pointIndices / pointsTextureSize);\\n rgba = vec4(pointPosition.xy, 1.0, 0.0);\\n\\n gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n}\\n\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D centermassTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceCenterUniforms {\\n float centerForce;\\n float alpha;\\n} forceCenter;\\n\\n#define centerForce forceCenter.centerForce\\n#define alpha forceCenter.alpha\\n#else\\nuniform float centerForce;\\nuniform float alpha;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 velocity = vec4(0.0);\\n vec4 centermassValues = texture(centermassTexture, vec2(0.0));\\n vec2 centermassPosition = centermassValues.xy / centermassValues.b;\\n vec2 distVector = centermassPosition - pointPosition.xy;\\n float dist = sqrt(dot(distVector, distVector));\\n if (dist > 0.0) {\\n float angle = atan(distVector.y, distVector.x);\\n float addV = alpha * centerForce * dist * 0.01;\\n velocity.rg += addV * vec2(cos(angle), sin(angle));\\n }\\n\\n fragColor = velocity;\\n}\"","export function createIndexesForBuffer (textureSize: number): Float32Array {\n const indexes = new Float32Array(textureSize * textureSize * 2)\n for (let y = 0; y < textureSize; y++) {\n for (let x = 0; x < textureSize; x++) {\n const i = y * textureSize * 2 + x * 2\n indexes[i + 0] = x\n indexes[i + 1] = y\n }\n }\n return indexes\n}\n","import type { TextureFormat } from '@luma.gl/core'\nimport { textureFormatDecoder } from '@luma.gl/core'\n\n/**\n * Calculates bytesPerRow for texture uploads.\n * @param format - Texture format\n * @param width - Texture width in pixels\n * @returns bytesPerRow in bytes\n */\nexport function getBytesPerRow (format: TextureFormat, width: number): number {\n const formatInfo = textureFormatDecoder.getInfo(format)\n return width * (formatInfo.bytesPerPixel ?? 0)\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 vertexCoord; // Vertex coordinates in normalized device coordinates\\nout vec2 textureCoords; // Texture coordinates to pass to the fragment shader\\n\\nvoid main() {\\n // Convert vertex coordinates from [-1, 1] range to [0, 1] range for texture sampling\\n textureCoords = (vertexCoord + 1.0) / 2.0;\\n gl_Position = vec4(vertexCoord, 0, 1);\\n}\\n\"","import { Buffer, Framebuffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport calculateCentermassFrag from '@/graph/modules/ForceCenter/calculate-centermass.frag?raw'\nimport calculateCentermassVert from '@/graph/modules/ForceCenter/calculate-centermass.vert?raw'\nimport forceFrag from '@/graph/modules/ForceCenter/force-center.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport class ForceCenter extends CoreModule {\n private centermassTexture: Texture | undefined\n private centermassFbo: Framebuffer | undefined\n private pointIndices: Buffer | undefined\n\n private calculateCentermassCommand: Model | undefined\n private runCommand: Model | undefined\n\n private forceVertexCoordBuffer: Buffer | undefined\n\n private calculateUniformStore: UniformStore<{\n calculateCentermassUniforms: {\n pointsTextureSize: number;\n };\n }> | undefined\n\n private forceUniformStore: UniformStore<{\n forceCenterUniforms: {\n centerForce: number;\n alpha: number;\n };\n }> | undefined\n\n private previousPointsTextureSize: number | undefined\n\n public create (): void {\n const { device, store } = this\n const { pointsTextureSize } = store\n if (!pointsTextureSize) return\n\n this.centermassTexture ||= device.createTexture({\n width: 1,\n height: 1,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.centermassTexture.copyImageData({\n data: new Float32Array(4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', 1),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n this.centermassFbo ||= device.createFramebuffer({\n width: 1,\n height: 1,\n colorAttachments: [this.centermassTexture],\n })\n\n // Update pointIndices buffer if pointsTextureSize changed\n if (!this.pointIndices || this.previousPointsTextureSize !== store.pointsTextureSize) {\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n this.pointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.calculateCentermassCommand?.setAttributes({\n pointIndices: this.pointIndices,\n })\n }\n\n this.previousPointsTextureSize = pointsTextureSize\n }\n\n public initPrograms (): void {\n const { device, store, points } = this\n if (!points || !store.pointsTextureSize) return\n if (!this.centermassFbo || this.centermassFbo.destroyed || !this.centermassTexture || this.centermassTexture.destroyed) return\n\n this.forceVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.calculateUniformStore ||= new UniformStore({\n calculateCentermassUniforms: {\n uniformTypes: {\n pointsTextureSize: 'f32',\n },\n },\n })\n\n this.forceUniformStore ||= new UniformStore({\n forceCenterUniforms: {\n uniformTypes: {\n centerForce: 'f32',\n alpha: 'f32',\n },\n },\n })\n\n this.calculateCentermassCommand ||= new Model(device, {\n fs: calculateCentermassFrag,\n vs: calculateCentermassVert,\n topology: 'point-list',\n attributes: {\n ...this.pointIndices && { pointIndices: this.pointIndices },\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n calculateCentermassUniforms: this.calculateUniformStore.getManagedUniformBuffer(device, 'calculateCentermassUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.forceVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceCenterUniforms: this.forceUniformStore.getManagedUniformBuffer(device, 'forceCenterUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, store, points } = this\n if (!points) return\n if (!this.calculateCentermassCommand || !this.calculateUniformStore || !this.runCommand || !this.forceUniformStore) return\n if (!this.centermassFbo || !this.centermassTexture) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n // Skip if sizes changed and create() wasn't called yet\n if (store.pointsTextureSize !== this.previousPointsTextureSize) return\n\n // Ensure pointIndices is set (Model might exist but attributes not set yet)\n if (!this.pointIndices) return\n\n // Clear centermass framebuffer and accumulate point positions\n const centermassPass = device.beginRenderPass({\n framebuffer: this.centermassFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.calculateUniformStore.setUniforms({\n calculateCentermassUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n },\n })\n // Update texture bindings dynamically\n this.calculateCentermassCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n this.calculateCentermassCommand.draw(centermassPass)\n centermassPass.end()\n\n // Apply center force into velocity\n this.forceUniformStore.setUniforms({\n forceCenterUniforms: {\n centerForce: this.config.simulationCenter ?? 0,\n alpha: store.alpha,\n },\n })\n // Update texture bindings dynamically\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n centermassTexture: this.centermassTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.calculateCentermassCommand?.destroy()\n this.calculateCentermassCommand = undefined\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.centermassFbo && !this.centermassFbo.destroyed) {\n this.centermassFbo.destroy()\n }\n this.centermassFbo = undefined\n\n // 3. Destroy Textures\n if (this.centermassTexture && !this.centermassTexture.destroyed) {\n this.centermassTexture.destroy()\n }\n this.centermassTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.calculateUniformStore?.destroy()\n this.calculateUniformStore = undefined\n this.forceUniformStore?.destroy()\n this.forceUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n this.pointIndices = undefined\n if (this.forceVertexCoordBuffer && !this.forceVertexCoordBuffer.destroyed) {\n this.forceVertexCoordBuffer.destroy()\n }\n this.forceVertexCoordBuffer = undefined\n\n this.previousPointsTextureSize = undefined\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceGravityUniforms {\\n float gravity;\\n float spaceSize;\\n float alpha;\\n} forceGravity;\\n\\n#define gravity forceGravity.gravity\\n#define spaceSize forceGravity.spaceSize\\n#define alpha forceGravity.alpha\\n#else\\nuniform float gravity;\\nuniform float spaceSize;\\nuniform float alpha;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n\\n vec4 velocity = vec4(0.0);\\n\\n vec2 centerPosition = vec2(spaceSize * 0.5);\\n vec2 distVector = centerPosition - pointPosition.rg;\\n float dist = sqrt(dot(distVector, distVector));\\n if (dist > 0.0) {\\n float angle = atan(distVector.y, distVector.x);\\n float additionalVelocity = alpha * gravity * dist * 0.1;\\n velocity.rg += additionalVelocity * vec2(cos(angle), sin(angle));\\n }\\n\\n fragColor = velocity;\\n}\"","import { Buffer, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport forceFrag from '@/graph/modules/ForceGravity/force-gravity.frag?raw'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport class ForceGravity extends CoreModule {\n private runCommand: Model | undefined\n private vertexCoordBuffer: Buffer | undefined\n private uniformStore: UniformStore<{\n forceGravityUniforms: {\n gravity: number;\n spaceSize: number;\n alpha: number;\n };\n }> | undefined\n\n public initPrograms (): void {\n const { device, points, store } = this\n if (!points || !store.pointsTextureSize) return\n\n this.vertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.uniformStore ||= new UniformStore({\n forceGravityUniforms: {\n uniformTypes: {\n gravity: 'f32',\n spaceSize: 'f32',\n alpha: 'f32',\n },\n },\n })\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.vertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceGravityUniforms: this.uniformStore.getManagedUniformBuffer(device, 'forceGravityUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, points, store } = this\n if (!points) return\n if (!this.runCommand || !this.uniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n this.uniformStore.setUniforms({\n forceGravityUniforms: {\n gravity: this.config.simulationGravity ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n alpha: store.alpha,\n },\n })\n\n // Update texture bindings dynamically\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n // ForceGravity has no framebuffers\n\n // 3. Destroy Textures\n // ForceGravity has no textures\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.uniformStore?.destroy()\n this.uniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.vertexCoordBuffer && !this.vertexCoordBuffer.destroyed) {\n this.vertexCoordBuffer.destroy()\n }\n this.vertexCoordBuffer = undefined\n }\n}\n","export function forceFrag (maxLinks: number): string {\n return `#version 300 es\nprecision highp float;\n\nuniform sampler2D positionsTexture;\nuniform sampler2D linkInfoTexture; // Texture storing first link indices and amount\nuniform sampler2D linkIndicesTexture;\nuniform sampler2D linkPropertiesTexture; // Texture storing link bias and strength\nuniform sampler2D linkRandomDistanceTexture;\n\n#ifdef USE_UNIFORM_BUFFERS\nlayout(std140) uniform forceLinkUniforms {\n float linkSpring;\n float linkDistance;\n vec2 linkDistRandomVariationRange;\n float pointsTextureSize;\n float linksTextureSize;\n float alpha;\n} forceLink;\n\n#define linkSpring forceLink.linkSpring\n#define linkDistance forceLink.linkDistance\n#define linkDistRandomVariationRange forceLink.linkDistRandomVariationRange\n#define pointsTextureSize forceLink.pointsTextureSize\n#define linksTextureSize forceLink.linksTextureSize\n#define alpha forceLink.alpha\n#else\nuniform float linkSpring;\nuniform float linkDistance;\nuniform vec2 linkDistRandomVariationRange;\nuniform float pointsTextureSize;\nuniform float linksTextureSize;\nuniform float alpha;\n#endif\n\nin vec2 textureCoords;\nout vec4 fragColor;\n\nconst float MAX_LINKS = ${maxLinks}.0;\n\nvoid main() {\n vec4 pointPosition = texture(positionsTexture, textureCoords);\n vec4 velocity = vec4(0.0);\n\n vec4 linkInfo = texture(linkInfoTexture, textureCoords);\n float iCount = linkInfo.r;\n float jCount = linkInfo.g;\n float linkAmount = linkInfo.b;\n if (linkAmount > 0.0) {\n for (float i = 0.0; i < MAX_LINKS; i += 1.0) {\n if (i < linkAmount) {\n if (iCount >= linksTextureSize) {\n iCount = 0.0;\n jCount += 1.0;\n }\n vec2 linkTextureIndex = (vec2(iCount, jCount) + 0.5) / linksTextureSize;\n vec4 connectedPointIndex = texture(linkIndicesTexture, linkTextureIndex);\n vec4 biasAndStrength = texture(linkPropertiesTexture, linkTextureIndex);\n vec4 randomMinDistance = texture(linkRandomDistanceTexture, linkTextureIndex);\n float bias = biasAndStrength.r;\n float strength = biasAndStrength.g;\n float randomMinLinkDist = randomMinDistance.r * (linkDistRandomVariationRange.g - linkDistRandomVariationRange.r) + linkDistRandomVariationRange.r;\n randomMinLinkDist *= linkDistance;\n\n iCount += 1.0;\n\n vec4 connectedPointPosition = texture(positionsTexture, (connectedPointIndex.rg + 0.5) / pointsTextureSize);\n float x = connectedPointPosition.x - (pointPosition.x + velocity.x);\n float y = connectedPointPosition.y - (pointPosition.y + velocity.y);\n float l = sqrt(x * x + y * y);\n\n // Apply the link force\n l = max(l, randomMinLinkDist * 0.99);\n l = (l - randomMinLinkDist) / l;\n l *= linkSpring * alpha;\n l *= strength;\n l *= bias;\n x *= l;\n y *= l;\n velocity.x += x;\n velocity.y += y;\n }\n }\n }\n\n fragColor = vec4(velocity.rg, 0.0, 0.0);\n}\n `\n}\n","/**\n * Validates and normalizes array values to fixed-size tuples for shader uniforms.\n */\n\n/**\n * Ensures a value is a vec2 tuple [number, number].\n */\nexport function ensureVec2 (\n arr: number[] | undefined,\n fallback: [number, number]\n): [number, number] {\n if (!arr || arr.length !== 2) return fallback\n return [arr[0], arr[1]] as [number, number]\n}\n\n/**\n * Ensures a value is a vec4 tuple [number, number, number, number].\n */\nexport function ensureVec4 (\n arr: number[] | undefined,\n fallback: [number, number, number, number]\n): [number, number, number, number] {\n if (!arr || arr.length !== 4) return fallback\n return [arr[0], arr[1], arr[2], arr[3]] as [number, number, number, number]\n}\n","import { Buffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport { forceFrag } from '@/graph/modules/ForceLink/force-spring'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport { ensureVec2 } from '@/graph/modules/Shared/uniform-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport enum LinkDirection {\n OUTGOING = 'outgoing',\n INCOMING = 'incoming'\n}\n\nexport class ForceLink extends CoreModule {\n private linkFirstIndicesAndAmount: Float32Array = new Float32Array()\n private indices: Float32Array = new Float32Array()\n private maxPointDegree = 0\n private previousMaxPointDegree: number | undefined\n private previousPointsTextureSize: number | undefined\n private previousLinksTextureSize: number | undefined\n\n private runCommand: Model | undefined\n private vertexCoordBuffer: Buffer | undefined\n private uniformStore: UniformStore<{\n forceLinkUniforms: {\n linkSpring: number;\n linkDistance: number;\n linkDistRandomVariationRange: [number, number];\n pointsTextureSize: number;\n linksTextureSize: number;\n alpha: number;\n };\n }> | undefined\n\n private linkFirstIndicesAndAmountTexture: Texture | undefined\n private indicesTexture: Texture | undefined\n private biasAndStrengthTexture: Texture | undefined\n private randomDistanceTexture: Texture | undefined\n\n public create (direction: LinkDirection): void {\n const { device, store: { pointsTextureSize, linksTextureSize }, data } = this\n if (!pointsTextureSize || !linksTextureSize) return\n\n this.linkFirstIndicesAndAmount = new Float32Array(pointsTextureSize * pointsTextureSize * 4)\n this.indices = new Float32Array(linksTextureSize * linksTextureSize * 4)\n const linkBiasAndStrengthState = new Float32Array(linksTextureSize * linksTextureSize * 4)\n const linkDistanceState = new Float32Array(linksTextureSize * linksTextureSize * 4)\n\n const grouped = direction === LinkDirection.INCOMING ? data.sourceIndexToTargetIndices : data.targetIndexToSourceIndices\n this.maxPointDegree = 0\n let linkIndex = 0\n grouped?.forEach((connectedPointIndices, pointIndex) => {\n if (connectedPointIndices) {\n this.linkFirstIndicesAndAmount[pointIndex * 4 + 0] = linkIndex % linksTextureSize\n this.linkFirstIndicesAndAmount[pointIndex * 4 + 1] = Math.floor(linkIndex / linksTextureSize)\n this.linkFirstIndicesAndAmount[pointIndex * 4 + 2] = connectedPointIndices.length ?? 0\n\n connectedPointIndices.forEach(([connectedPointIndex, initialLinkIndex]) => {\n this.indices[linkIndex * 4 + 0] = connectedPointIndex % pointsTextureSize\n this.indices[linkIndex * 4 + 1] = Math.floor(connectedPointIndex / pointsTextureSize)\n const degree = data.degree?.[connectedPointIndex] ?? 0\n const connectedDegree = data.degree?.[pointIndex] ?? 0\n const degreeSum = degree + connectedDegree\n // Prevent division by zero\n const bias = degreeSum !== 0 ? degree / degreeSum : 0.5\n const minDegree = Math.min(degree, connectedDegree)\n // Prevent division by zero\n let strength = data.linkStrength?.[initialLinkIndex] ?? (1 / Math.max(minDegree, 1))\n strength = Math.sqrt(strength)\n linkBiasAndStrengthState[linkIndex * 4 + 0] = bias\n linkBiasAndStrengthState[linkIndex * 4 + 1] = strength\n linkDistanceState[linkIndex * 4] = this.store.getRandomFloat(0, 1)\n\n linkIndex += 1\n })\n\n this.maxPointDegree = Math.max(this.maxPointDegree, connectedPointIndices.length ?? 0)\n }\n })\n\n // Recreate textures if sizes changed\n const recreatePointTextures =\n !this.linkFirstIndicesAndAmountTexture ||\n this.linkFirstIndicesAndAmountTexture.width !== pointsTextureSize ||\n this.linkFirstIndicesAndAmountTexture.height !== pointsTextureSize\n\n const recreateLinkTextures =\n !this.indicesTexture ||\n this.indicesTexture.width !== linksTextureSize ||\n this.indicesTexture.height !== linksTextureSize\n\n if (recreatePointTextures) {\n if (this.linkFirstIndicesAndAmountTexture && !this.linkFirstIndicesAndAmountTexture.destroyed) {\n this.linkFirstIndicesAndAmountTexture.destroy()\n }\n this.linkFirstIndicesAndAmountTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n }\n this.linkFirstIndicesAndAmountTexture!.copyImageData({\n data: this.linkFirstIndicesAndAmount,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n if (recreateLinkTextures) {\n if (this.indicesTexture && !this.indicesTexture.destroyed) this.indicesTexture.destroy()\n if (this.biasAndStrengthTexture && !this.biasAndStrengthTexture.destroyed) this.biasAndStrengthTexture.destroy()\n if (this.randomDistanceTexture && !this.randomDistanceTexture.destroyed) this.randomDistanceTexture.destroy()\n\n this.indicesTexture = device.createTexture({\n width: linksTextureSize,\n height: linksTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n this.biasAndStrengthTexture = device.createTexture({\n width: linksTextureSize,\n height: linksTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n this.randomDistanceTexture = device.createTexture({\n width: linksTextureSize,\n height: linksTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n }\n\n this.indicesTexture!.copyImageData({\n data: this.indices,\n bytesPerRow: getBytesPerRow('rgba32float', linksTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.biasAndStrengthTexture!.copyImageData({\n data: linkBiasAndStrengthState,\n bytesPerRow: getBytesPerRow('rgba32float', linksTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.randomDistanceTexture!.copyImageData({\n data: linkDistanceState,\n bytesPerRow: getBytesPerRow('rgba32float', linksTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Force shader rebuild if degree changed\n if (this.previousMaxPointDegree !== undefined && this.previousMaxPointDegree !== this.maxPointDegree) {\n this.runCommand?.destroy()\n this.runCommand = undefined\n }\n\n this.previousMaxPointDegree = this.maxPointDegree\n this.previousPointsTextureSize = pointsTextureSize\n this.previousLinksTextureSize = linksTextureSize\n }\n\n public initPrograms (): void {\n const { device, store, points } = this\n if (!points || !store.pointsTextureSize || !store.linksTextureSize) return\n if (!this.linkFirstIndicesAndAmountTexture || !this.indicesTexture || !this.biasAndStrengthTexture || !this.randomDistanceTexture) return\n\n this.vertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.uniformStore ||= new UniformStore({\n forceLinkUniforms: {\n uniformTypes: {\n linkSpring: 'f32',\n linkDistance: 'f32',\n linkDistRandomVariationRange: 'vec2<f32>',\n pointsTextureSize: 'f32',\n linksTextureSize: 'f32',\n alpha: 'f32',\n },\n },\n })\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag(this.maxPointDegree),\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.vertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceLinkUniforms: this.uniformStore.getManagedUniformBuffer(device, 'forceLinkUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, store, points } = this\n if (!points) return\n if (!this.runCommand || !this.uniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!this.linkFirstIndicesAndAmountTexture || !this.indicesTexture || !this.biasAndStrengthTexture || !this.randomDistanceTexture) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n // Skip if sizes changed and create() wasn't called again\n if (\n store.pointsTextureSize !== this.previousPointsTextureSize ||\n store.linksTextureSize !== this.previousLinksTextureSize\n ) {\n return\n }\n\n this.uniformStore.setUniforms({\n forceLinkUniforms: {\n linkSpring: this.config.simulationLinkSpring ?? 0,\n linkDistance: this.config.simulationLinkDistance ?? 0,\n linkDistRandomVariationRange: ensureVec2(this.config.simulationLinkDistRandomVariationRange, [0, 0]),\n pointsTextureSize: store.pointsTextureSize,\n linksTextureSize: store.linksTextureSize,\n alpha: store.alpha,\n },\n })\n\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n linkInfoTexture: this.linkFirstIndicesAndAmountTexture,\n linkIndicesTexture: this.indicesTexture,\n linkPropertiesTexture: this.biasAndStrengthTexture,\n linkRandomDistanceTexture: this.randomDistanceTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n // ForceLink has no framebuffers\n\n // 3. Destroy Textures\n if (this.linkFirstIndicesAndAmountTexture && !this.linkFirstIndicesAndAmountTexture.destroyed) {\n this.linkFirstIndicesAndAmountTexture.destroy()\n }\n this.linkFirstIndicesAndAmountTexture = undefined\n if (this.indicesTexture && !this.indicesTexture.destroyed) {\n this.indicesTexture.destroy()\n }\n this.indicesTexture = undefined\n if (this.biasAndStrengthTexture && !this.biasAndStrengthTexture.destroyed) {\n this.biasAndStrengthTexture.destroy()\n }\n this.biasAndStrengthTexture = undefined\n if (this.randomDistanceTexture && !this.randomDistanceTexture.destroyed) {\n this.randomDistanceTexture.destroy()\n }\n this.randomDistanceTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.uniformStore?.destroy()\n this.uniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.vertexCoordBuffer && !this.vertexCoordBuffer.destroyed) {\n this.vertexCoordBuffer.destroy()\n }\n this.vertexCoordBuffer = undefined\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nin vec4 vColor;\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = vColor;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform calculateLevelsUniforms {\\n float pointsTextureSize;\\n float levelTextureSize;\\n float cellSize;\\n} calculateLevels;\\n\\n#define pointsTextureSize calculateLevels.pointsTextureSize\\n#define levelTextureSize calculateLevels.levelTextureSize\\n#define cellSize calculateLevels.cellSize\\n#else\\nuniform float pointsTextureSize;\\nuniform float levelTextureSize;\\nuniform float cellSize;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nout vec4 vColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, pointIndices / pointsTextureSize);\\n vColor = vec4(pointPosition.rg, 1.0, 0.0);\\n\\n float n = floor(pointPosition.x / cellSize);\\n float m = floor(pointPosition.y / cellSize);\\n \\n vec2 levelPosition = 2.0 * (vec2(n, m) + 0.5) / levelTextureSize - 1.0;\\n\\n gl_Position = vec4(levelPosition, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D levelFbo;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceUniforms {\\n float level;\\n float levels;\\n float levelTextureSize;\\n float alpha;\\n float repulsion;\\n float spaceSize;\\n float theta;\\n} force;\\n\\n#define level force.level\\n#define levels force.levels\\n#define levelTextureSize force.levelTextureSize\\n#define alpha force.alpha\\n#define repulsion force.repulsion\\n#define spaceSize force.spaceSize\\n#define theta force.theta\\n#else\\nuniform float level;\\nuniform float levels;\\nuniform float levelTextureSize;\\nuniform float repulsion;\\nuniform float alpha;\\nuniform float spaceSize;\\nuniform float theta;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nconst float MAX_LEVELS_NUM = 14.0;\\n\\nvec2 calculateAdditionalVelocity (vec2 ij, vec2 pp) {\\n vec2 add = vec2(0.0);\\n vec4 centermass = texture(levelFbo, ij);\\n if (centermass.r > 0.0 && centermass.g > 0.0 && centermass.b > 0.0) {\\n vec2 centermassPosition = vec2(centermass.rg / centermass.b);\\n vec2 distVector = pp - centermassPosition;\\n float l = dot(distVector, distVector);\\n float dist = sqrt(l);\\n if (l > 0.0) {\\n float c = alpha * repulsion * centermass.b;\\n\\n float distanceMin2 = 1.0;\\n if (l < distanceMin2) l = sqrt(distanceMin2 * l);\\n float addV = c / sqrt(l);\\n add = addV * normalize(distVector);\\n }\\n }\\n return add;\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n float x = pointPosition.x;\\n float y = pointPosition.y;\\n\\n float left = 0.0;\\n float top = 0.0;\\n float right = spaceSize;\\n float bottom = spaceSize;\\n\\n float n_left = 0.0;\\n float n_top = 0.0;\\n float n_right = 0.0;\\n float n_bottom = 0.0;\\n\\n float cellSize = 0.0;\\n\\n // Iterate over levels to adjust the boundaries based on the current level\\n for (float i = 0.0; i < MAX_LEVELS_NUM; i += 1.0) {\\n if (i <= level) {\\n left += cellSize * n_left;\\n top += cellSize * n_top;\\n right -= cellSize * n_right;\\n bottom -= cellSize * n_bottom;\\n\\n cellSize = pow(2.0 , levels - i - 1.0);\\n\\n float dist_left = x - left;\\n n_left = max(0.0, floor(dist_left / cellSize - theta));\\n\\n float dist_top = y - top;\\n n_top = max(0.0, floor(dist_top / cellSize - theta));\\n \\n float dist_right = right - x;\\n n_right = max(0.0, floor(dist_right / cellSize - theta));\\n\\n float dist_bottom = bottom - y;\\n n_bottom = max(0.0, floor(dist_bottom / cellSize - theta));\\n\\n }\\n }\\n\\n vec4 velocity = vec4(vec2(0.0), 1.0, 0.0);\\n\\n // Calculate the additional velocity based on neighboring cells\\n for (float i = 0.0; i < 12.0; i += 1.0) {\\n for (float j = 0.0; j < 4.0; j += 1.0) {\\n float n = left + cellSize * j;\\n float m = top + cellSize * n_top + cellSize * i;\\n\\n if (n < (left + n_left * cellSize) && m < bottom) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n\\n n = left + cellSize * i;\\n m = top + cellSize * j;\\n\\n if (n < (right - n_right * cellSize) && m < (top + n_top * cellSize)) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n\\n n = right - n_right * cellSize + cellSize * j;\\n m = top + cellSize * i;\\n\\n if (n < right && m < (bottom - n_bottom * cellSize)) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n\\n n = left + n_left * cellSize + cellSize * i;\\n m = bottom - n_bottom * cellSize + cellSize * j;\\n\\n if (n < right && m < bottom) {\\n velocity.xy += calculateAdditionalVelocity(vec2(n / cellSize, m / cellSize) / levelTextureSize, pointPosition.xy);\\n }\\n }\\n }\\n\\n fragColor = velocity;\\n}\"","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D levelFbo;\\nuniform sampler2D randomValues;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceCenterUniforms {\\n float levelTextureSize;\\n float alpha;\\n float repulsion;\\n} forceCenter;\\n\\n#define levelTextureSize forceCenter.levelTextureSize\\n#define repulsion forceCenter.repulsion\\n#define alpha forceCenter.alpha\\n#else\\nuniform float levelTextureSize;\\nuniform float alpha;\\nuniform float repulsion;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\n// Calculate the additional velocity based on the center of mass\\nvec2 calculateAdditionalVelocity (vec2 ij, vec2 pp) {\\n vec2 add = vec2(0.0);\\n vec4 centermass = texture(levelFbo, ij);\\n if (centermass.r > 0.0 && centermass.g > 0.0 && centermass.b > 0.0) {\\n vec2 centermassPosition = vec2(centermass.rg / centermass.b);\\n vec2 distVector = pp - centermassPosition;\\n float l = dot(distVector, distVector);\\n float dist = sqrt(l);\\n if (l > 0.0) {\\n float angle = atan(distVector.y, distVector.x);\\n float c = alpha * repulsion * centermass.b;\\n\\n float distanceMin2 = 1.0;\\n if (l < distanceMin2) l = sqrt(distanceMin2 * l);\\n float addV = c / sqrt(l);\\n add = addV * vec2(cos(angle), sin(angle));\\n }\\n }\\n return add;\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 random = texture(randomValues, textureCoords);\\n\\n vec4 velocity = vec4(0.0);\\n\\n // Calculate additional velocity based on the point position\\n velocity.xy += calculateAdditionalVelocity(pointPosition.xy / levelTextureSize, pointPosition.xy);\\n // Apply random factor to the velocity\\n velocity.xy += velocity.xy * random.rg;\\n\\n fragColor = velocity;\\n}\"","import { Buffer, Framebuffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport calculateLevelFrag from '@/graph/modules/ForceManyBody/calculate-level.frag?raw'\nimport calculateLevelVert from '@/graph/modules/ForceManyBody/calculate-level.vert?raw'\nimport forceFrag from '@/graph/modules/ForceManyBody/force-level.frag?raw'\nimport forceCenterFrag from '@/graph/modules/ForceManyBody/force-centermass.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\ntype LevelTarget = {\n texture: Texture;\n fbo: Framebuffer;\n}\n\nexport class ForceManyBody extends CoreModule {\n private randomValuesTexture: Texture | undefined\n private pointIndices: Buffer | undefined\n private levels = 0\n private levelTargets = new Map<number, LevelTarget>()\n\n private calculateLevelsCommand: Model | undefined\n private forceCommand: Model | undefined\n private forceFromItsOwnCentermassCommand: Model | undefined\n\n private forceVertexCoordBuffer: Buffer | undefined\n\n private calculateLevelsUniformStore: UniformStore<{\n calculateLevelsUniforms: {\n pointsTextureSize: number;\n levelTextureSize: number;\n cellSize: number;\n };\n }> | undefined\n\n private forceUniformStore: UniformStore<{\n forceUniforms: {\n level: number;\n levels: number;\n levelTextureSize: number;\n alpha: number;\n repulsion: number;\n spaceSize: number;\n theta: number;\n };\n }> | undefined\n\n private forceCenterUniformStore: UniformStore<{\n forceCenterUniforms: {\n levelTextureSize: number;\n alpha: number;\n repulsion: number;\n };\n }> | undefined\n\n private previousPointsTextureSize: number | undefined\n private previousSpaceSize: number | undefined\n\n public create (): void {\n const { device, store } = this\n if (!store.pointsTextureSize) return\n\n this.levels = Math.log2(store.adjustedSpaceSize)\n\n // Allocate quadtree levels\n for (let level = 0; level < this.levels; level += 1) {\n const levelTextureSize = Math.pow(2, level + 1)\n const existingTarget = this.levelTargets.get(level)\n\n if (\n existingTarget &&\n existingTarget.texture.width === levelTextureSize &&\n existingTarget.texture.height === levelTextureSize\n ) {\n // Clear existing texture data to zero\n existingTarget.texture.copyImageData({\n data: new Float32Array(levelTextureSize * levelTextureSize * 4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', levelTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n continue\n }\n\n // Destroy old resources if size changed\n if (existingTarget) {\n if (!existingTarget.fbo.destroyed) existingTarget.fbo.destroy()\n if (!existingTarget.texture.destroyed) existingTarget.texture.destroy()\n }\n\n const texture = device.createTexture({\n width: levelTextureSize,\n height: levelTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n texture.copyImageData({\n data: new Float32Array(levelTextureSize * levelTextureSize * 4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', levelTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n const fbo = device.createFramebuffer({\n width: levelTextureSize,\n height: levelTextureSize,\n colorAttachments: [texture],\n })\n this.levelTargets.set(level, { texture, fbo })\n }\n\n // Drop any stale higher-level buffers if space size shrank\n for (const [level, target] of Array.from(this.levelTargets.entries())) {\n if (level >= this.levels) {\n if (!target.fbo.destroyed) target.fbo.destroy()\n if (!target.texture.destroyed) target.texture.destroy()\n this.levelTargets.delete(level)\n }\n }\n\n // Random jitter texture to prevent sticking\n const totalPixels = store.pointsTextureSize * store.pointsTextureSize\n const randomValuesState = new Float32Array(totalPixels * 4)\n for (let i = 0; i < totalPixels; ++i) {\n randomValuesState[i * 4] = store.getRandomFloat(-1, 1) * 0.00001\n randomValuesState[i * 4 + 1] = store.getRandomFloat(-1, 1) * 0.00001\n }\n\n const recreateRandomValuesTexture =\n !this.randomValuesTexture ||\n this.randomValuesTexture.destroyed ||\n this.randomValuesTexture.width !== store.pointsTextureSize ||\n this.randomValuesTexture.height !== store.pointsTextureSize\n\n if (recreateRandomValuesTexture) {\n if (this.randomValuesTexture && !this.randomValuesTexture.destroyed) {\n this.randomValuesTexture.destroy()\n }\n this.randomValuesTexture = device.createTexture({\n width: store.pointsTextureSize,\n height: store.pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.COPY_DST,\n })\n }\n this.randomValuesTexture!.copyImageData({\n data: randomValuesState,\n bytesPerRow: getBytesPerRow('rgba32float', store.pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Update pointIndices buffer if pointsTextureSize changed\n if (!this.pointIndices || this.previousPointsTextureSize !== store.pointsTextureSize) {\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n this.pointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.calculateLevelsCommand?.setAttributes({\n pointIndices: this.pointIndices,\n })\n }\n\n this.previousPointsTextureSize = store.pointsTextureSize\n this.previousSpaceSize = store.adjustedSpaceSize\n }\n\n public initPrograms (): void {\n const { device, store, data, points } = this\n if (!data.pointsNumber || !points || !store.pointsTextureSize) return\n\n // Calculate levels command (point list)\n this.calculateLevelsUniformStore ||= new UniformStore({\n calculateLevelsUniforms: {\n uniformTypes: {\n pointsTextureSize: 'f32',\n levelTextureSize: 'f32',\n cellSize: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize,\n levelTextureSize: 0,\n cellSize: 0,\n },\n },\n })\n\n this.calculateLevelsCommand ||= new Model(device, {\n fs: calculateLevelFrag,\n vs: calculateLevelVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber,\n attributes: {\n ...this.pointIndices && { pointIndices: this.pointIndices },\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n calculateLevelsUniforms: this.calculateLevelsUniformStore.getManagedUniformBuffer(device, 'calculateLevelsUniforms'),\n // All texture bindings will be set dynamically in drawLevels() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Force command (fullscreen quad)\n this.forceUniformStore ||= new UniformStore({\n forceUniforms: {\n uniformTypes: {\n level: 'f32',\n levels: 'f32',\n levelTextureSize: 'f32',\n alpha: 'f32',\n repulsion: 'f32',\n spaceSize: 'f32',\n theta: 'f32',\n },\n defaultUniforms: {\n level: 0,\n levels: this.levels,\n levelTextureSize: 0,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n theta: this.config.simulationRepulsionTheta ?? 0,\n },\n },\n })\n\n this.forceVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.forceCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.forceVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceUniforms: this.forceUniformStore.getManagedUniformBuffer(device, 'forceUniforms'),\n // All texture bindings will be set dynamically in drawForces() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Force-from-centermass command (fullscreen quad)\n this.forceCenterUniformStore ||= new UniformStore({\n forceCenterUniforms: {\n uniformTypes: {\n levelTextureSize: 'f32',\n alpha: 'f32',\n repulsion: 'f32',\n },\n defaultUniforms: {\n levelTextureSize: 0,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n },\n },\n })\n\n this.forceFromItsOwnCentermassCommand ||= new Model(device, {\n fs: forceCenterFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.forceVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceCenterUniforms: this.forceCenterUniformStore.getManagedUniformBuffer(device, 'forceCenterUniforms'),\n // All texture bindings will be set dynamically in drawForces() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n // Skip if sizes changed and create() wasn't called yet\n if (this.store.pointsTextureSize !== this.previousPointsTextureSize || this.store.adjustedSpaceSize !== this.previousSpaceSize) {\n return\n }\n this.drawLevels()\n this.drawForces()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.calculateLevelsCommand?.destroy()\n this.calculateLevelsCommand = undefined\n this.forceCommand?.destroy()\n this.forceCommand = undefined\n this.forceFromItsOwnCentermassCommand?.destroy()\n this.forceFromItsOwnCentermassCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n for (const target of this.levelTargets.values()) {\n if (target.fbo && !target.fbo.destroyed) {\n target.fbo.destroy()\n }\n }\n\n // 3. Destroy Textures\n if (this.randomValuesTexture && !this.randomValuesTexture.destroyed) {\n this.randomValuesTexture.destroy()\n }\n this.randomValuesTexture = undefined\n\n for (const target of this.levelTargets.values()) {\n if (target.texture && !target.texture.destroyed) {\n target.texture.destroy()\n }\n }\n this.levelTargets.clear()\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.calculateLevelsUniformStore?.destroy()\n this.calculateLevelsUniformStore = undefined\n this.forceUniformStore?.destroy()\n this.forceUniformStore = undefined\n this.forceCenterUniformStore?.destroy()\n this.forceCenterUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n this.pointIndices = undefined\n if (this.forceVertexCoordBuffer && !this.forceVertexCoordBuffer.destroyed) {\n this.forceVertexCoordBuffer.destroy()\n }\n this.forceVertexCoordBuffer = undefined\n }\n\n private drawLevels (): void {\n const { device, store, data, points } = this\n if (!points) return\n if (!this.calculateLevelsCommand || !this.calculateLevelsUniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!data.pointsNumber) return\n // Ensure pointIndices is set (Model might exist but attributes not set yet)\n if (!this.pointIndices) return\n\n for (let level = 0; level < this.levels; level += 1) {\n const target = this.levelTargets.get(level)\n if (!target || target.fbo.destroyed || target.texture.destroyed) continue\n\n const levelTextureSize = Math.pow(2, level + 1)\n const cellSize = (store.adjustedSpaceSize ?? 0) / levelTextureSize\n\n this.calculateLevelsUniformStore.setUniforms({\n calculateLevelsUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n levelTextureSize,\n cellSize,\n },\n })\n\n this.calculateLevelsCommand.setVertexCount(data.pointsNumber)\n // Update texture bindings dynamically\n this.calculateLevelsCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n const levelPass = device.beginRenderPass({\n framebuffer: target.fbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.calculateLevelsCommand.draw(levelPass)\n\n levelPass.end()\n }\n }\n\n private drawForces (): void {\n const { device, store, points } = this\n if (!points) return\n if (!this.forceCommand || !this.forceUniformStore) return\n if (!this.forceFromItsOwnCentermassCommand || !this.forceCenterUniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!this.randomValuesTexture || this.randomValuesTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n const drawPass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n for (let level = 0; level < this.levels; level += 1) {\n const target = this.levelTargets.get(level)\n if (!target || target.texture.destroyed) continue\n const levelTextureSize = Math.pow(2, level + 1)\n\n this.forceUniformStore.setUniforms({\n forceUniforms: {\n level,\n levels: this.levels,\n levelTextureSize,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n theta: this.config.simulationRepulsionTheta ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.forceCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n levelFbo: target.texture,\n })\n\n this.forceCommand.draw(drawPass)\n\n // Only the deepest level uses the centermass fallback\n if (level === this.levels - 1) {\n this.forceCenterUniformStore.setUniforms({\n forceCenterUniforms: {\n levelTextureSize,\n alpha: store.alpha,\n repulsion: this.config.simulationRepulsion ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.forceFromItsOwnCentermassCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n randomValues: this.randomValuesTexture,\n levelFbo: target.texture,\n })\n this.forceFromItsOwnCentermassCommand.draw(drawPass)\n }\n }\n\n drawPass.end()\n }\n}\n","export default \"#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform forceMouseUniforms {\\n float repulsion;\\n vec2 mousePos;\\n} forceMouse;\\n\\n#define repulsion forceMouse.repulsion\\n#define mousePos forceMouse.mousePos\\n#else\\nuniform float repulsion;\\nuniform vec2 mousePos;\\n#endif\\n\\nin vec2 textureCoords;\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 velocity = vec4(0.0);\\n vec2 mouse = mousePos;\\n // Move particles away from the mouse position using a repulsive force\\n vec2 distVector = mouse - pointPosition.rg;\\n float dist = sqrt(dot(distVector, distVector));\\n dist = max(dist, 10.0);\\n float angle = atan(distVector.y, distVector.x);\\n float addV = 100.0 * repulsion / (dist * dist);\\n velocity.rg -= addV * vec2(cos(angle), sin(angle));\\n\\n fragColor = velocity;\\n}\"","import { Buffer, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport forceFrag from '@/graph/modules/ForceMouse/force-mouse.frag?raw'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\nimport { ensureVec2 } from '@/graph/modules/Shared/uniform-utils'\n\nexport class ForceMouse extends CoreModule {\n private runCommand: Model | undefined\n private vertexCoordBuffer: Buffer | undefined\n private uniformStore: UniformStore<{\n forceMouseUniforms: {\n repulsion: number;\n mousePos: [number, number];\n };\n }> | undefined\n\n public initPrograms (): void {\n const { device, points } = this\n if (!points) return\n\n this.vertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.uniformStore ||= new UniformStore({\n forceMouseUniforms: {\n uniformTypes: {\n repulsion: 'f32',\n mousePos: 'vec2<f32>',\n },\n },\n })\n\n this.runCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.vertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n forceMouseUniforms: this.uniformStore.getManagedUniformBuffer(device, 'forceMouseUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n }\n\n public run (): void {\n const { device, points, store } = this\n if (!points) return\n if (!this.runCommand || !this.uniformStore) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n if (!points.velocityFbo || points.velocityFbo.destroyed) return\n\n this.uniformStore.setUniforms({\n forceMouseUniforms: {\n repulsion: this.config.simulationRepulsionFromMouse ?? 0,\n mousePos: ensureVec2(store.mousePosition, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.runCommand.setBindings({\n positionsTexture: points.previousPositionTexture,\n })\n\n const pass = device.beginRenderPass({\n framebuffer: points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.runCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.runCommand?.destroy()\n this.runCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n // ForceMouse has no framebuffers\n\n // 3. Destroy Textures\n // ForceMouse has no textures\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.uniformStore?.destroy()\n this.uniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.vertexCoordBuffer && !this.vertexCoordBuffer.destroyed) {\n this.vertexCoordBuffer.destroy()\n }\n this.vertexCoordBuffer = undefined\n }\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgba;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D clusterTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform calculateCentermassUniforms {\\n float pointsTextureSize;\\n float clustersTextureSize;\\n} calculateCentermass;\\n\\n#define pointsTextureSize calculateCentermass.pointsTextureSize\\n#define clustersTextureSize calculateCentermass.clustersTextureSize\\n#else\\nuniform float pointsTextureSize;\\nuniform float clustersTextureSize;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nout vec4 rgba;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, pointIndices / pointsTextureSize);\\n rgba = vec4(pointPosition.xy, 1.0, 0.0);\\n\\n vec4 pointClusterIndices = texture(clusterTexture, pointIndices / pointsTextureSize);\\n vec2 xy = vec2(0.0);\\n if (pointClusterIndices.x >= 0.0 && pointClusterIndices.y >= 0.0) {\\n xy = 2.0 * (pointClusterIndices.xy + 0.5) / clustersTextureSize - 1.0;\\n }\\n \\n gl_Position = vec4(xy, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n}\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D centermassTexture;\\nuniform sampler2D clusterTexture;\\nuniform sampler2D clusterPositionsTexture;\\nuniform sampler2D clusterForceCoefficient;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform applyForcesUniforms {\\n float alpha;\\n float clustersTextureSize;\\n float clusterCoefficient;\\n} applyForces;\\n\\n#define alpha applyForces.alpha\\n#define clustersTextureSize applyForces.clustersTextureSize\\n#define clusterCoefficient applyForces.clusterCoefficient\\n#else\\nuniform float alpha;\\nuniform float clustersTextureSize;\\nuniform float clusterCoefficient;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 velocity = vec4(0.0);\\n vec4 pointClusterIndices = texture(clusterTexture, textureCoords);\\n // no cluster, so no forces\\n if (pointClusterIndices.x >= 0.0 && pointClusterIndices.y >= 0.0) {\\n // positioning points to custom cluster position or either to the center of mass\\n vec2 clusterPositions = texture(clusterPositionsTexture, pointClusterIndices.xy / clustersTextureSize).xy;\\n if (clusterPositions.x < 0.0 || clusterPositions.y < 0.0) {\\n vec4 centermassValues = texture(centermassTexture, pointClusterIndices.xy / clustersTextureSize);\\n clusterPositions = centermassValues.xy / centermassValues.b;\\n }\\n vec4 clusterCustomCoeff = texture(clusterForceCoefficient, textureCoords);\\n vec2 distVector = clusterPositions.xy - pointPosition.xy;\\n float dist = length(distVector);\\n if (dist > 0.0) {\\n float addV = alpha * dist * clusterCoefficient * clusterCustomCoeff.r;\\n velocity.rg += addV * normalize(distVector);\\n }\\n }\\n\\n fragColor = velocity;\\n}\"","import { Framebuffer, Buffer, Texture, UniformStore } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport calculateCentermassFrag from '@/graph/modules/Clusters/calculate-centermass.frag?raw'\nimport calculateCentermassVert from '@/graph/modules/Clusters/calculate-centermass.vert?raw'\nimport forceFrag from '@/graph/modules/Clusters/force-cluster.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\n\nexport class Clusters extends CoreModule {\n public centermassFbo: Framebuffer | undefined\n public clusterCount: number | undefined\n\n private calculateCentermassCommand: Model | undefined\n private applyForcesCommand: Model | undefined\n private clusterTexture: Texture | undefined\n private clusterPositionsTexture: Texture | undefined\n private clusterForceCoefficientTexture: Texture | undefined\n private centermassTexture: Texture | undefined\n private pointIndices: Buffer | undefined\n private clustersTextureSize: number | undefined\n\n private applyForcesVertexCoordBuffer: Buffer | undefined\n\n // Track previous sizes to detect changes\n private previousPointsTextureSize: number | undefined\n private previousClustersTextureSize: number | undefined\n private previousClusterCount: number | undefined\n\n // Uniform stores for scalar uniforms\n private calculateCentermassUniformStore: UniformStore<{\n calculateCentermassUniforms: {\n pointsTextureSize: number;\n clustersTextureSize: number;\n };\n }> | undefined\n\n private applyForcesUniformStore: UniformStore<{\n applyForcesUniforms: {\n alpha: number;\n clustersTextureSize: number;\n clusterCoefficient: number;\n };\n }> | undefined\n\n public create (): void {\n const { device, store, data } = this\n const { pointsTextureSize } = store\n if (data.pointsNumber === undefined || (!data.pointClusters && !data.clusterPositions)) return\n\n // Find the highest cluster index in the array and add 1 (since cluster indices start at 0).\n this.clusterCount = (data.pointClusters ?? []).reduce<number>((max, clusterIndex) => {\n if (clusterIndex === undefined || clusterIndex < 0) return max\n return Math.max(max, clusterIndex)\n }, 0) + 1\n\n this.clustersTextureSize = Math.ceil(Math.sqrt(this.clusterCount))\n\n // Check if sizes have changed - if so, we need to recreate textures/framebuffers\n const sizesChanged =\n this.previousPointsTextureSize !== pointsTextureSize ||\n this.previousClustersTextureSize !== this.clustersTextureSize ||\n this.previousClusterCount !== this.clusterCount\n\n const pointsTextureDataSize = pointsTextureSize * pointsTextureSize * 4\n const clustersTextureDataSize = this.clustersTextureSize * this.clustersTextureSize * 4\n\n const clusterState = new Float32Array(pointsTextureDataSize)\n const clusterPositions = new Float32Array(clustersTextureDataSize).fill(-1)\n const clusterForceCoefficient = new Float32Array(pointsTextureDataSize).fill(1)\n if (data.clusterPositions) {\n for (let cluster = 0; cluster < this.clusterCount; ++cluster) {\n clusterPositions[cluster * 4 + 0] = data.clusterPositions[cluster * 2 + 0] ?? -1\n clusterPositions[cluster * 4 + 1] = data.clusterPositions[cluster * 2 + 1] ?? -1\n }\n }\n\n for (let i = 0; i < data.pointsNumber; ++i) {\n const clusterIndex = data.pointClusters?.[i]\n if (clusterIndex === undefined) {\n // no cluster, so no forces\n clusterState[i * 4 + 0] = -1\n clusterState[i * 4 + 1] = -1\n } else {\n clusterState[i * 4 + 0] = clusterIndex % this.clustersTextureSize\n clusterState[i * 4 + 1] = Math.floor(clusterIndex / this.clustersTextureSize)\n }\n\n if (data.clusterStrength) clusterForceCoefficient[i * 4 + 0] = data.clusterStrength[i] ?? 1\n }\n\n // Handle clusterTexture - recreate if size changed, update data if size same\n if (!this.clusterTexture || sizesChanged) {\n // Then destroy texture\n if (this.clusterTexture && !this.clusterTexture.destroyed) {\n this.clusterTexture.destroy()\n }\n // Create new texture\n this.clusterTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.clusterTexture.copyImageData({\n data: clusterState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n // Size hasn't changed, just update the data\n this.clusterTexture.copyImageData({\n data: clusterState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Handle clusterPositionsTexture\n if (!this.clusterPositionsTexture || sizesChanged) {\n // Then destroy texture\n if (this.clusterPositionsTexture && !this.clusterPositionsTexture.destroyed) {\n this.clusterPositionsTexture.destroy()\n }\n // Create new texture\n this.clusterPositionsTexture = device.createTexture({\n width: this.clustersTextureSize,\n height: this.clustersTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.clusterPositionsTexture.copyImageData({\n data: clusterPositions,\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n // Update data\n this.clusterPositionsTexture.copyImageData({\n data: clusterPositions,\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Handle clusterForceCoefficientTexture\n if (!this.clusterForceCoefficientTexture || sizesChanged) {\n // Then destroy texture\n if (this.clusterForceCoefficientTexture && !this.clusterForceCoefficientTexture.destroyed) {\n this.clusterForceCoefficientTexture.destroy()\n }\n // Create new texture\n this.clusterForceCoefficientTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.clusterForceCoefficientTexture.copyImageData({\n data: clusterForceCoefficient,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n // Update data\n this.clusterForceCoefficientTexture.copyImageData({\n data: clusterForceCoefficient,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Handle centermassTexture - only size depends on clustersTextureSize\n if (!this.centermassTexture || this.previousClustersTextureSize !== this.clustersTextureSize) {\n // Destroy framebuffer FIRST\n if (this.centermassFbo && !this.centermassFbo.destroyed) {\n this.centermassFbo.destroy()\n }\n // Then destroy texture\n if (this.centermassTexture && !this.centermassTexture.destroyed) {\n this.centermassTexture.destroy()\n }\n // Create new texture\n this.centermassTexture = device.createTexture({\n width: this.clustersTextureSize,\n height: this.clustersTextureSize,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.centermassTexture.copyImageData({\n data: new Float32Array(clustersTextureDataSize).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n // Create new framebuffer with explicit dimensions\n this.centermassFbo = device.createFramebuffer({\n width: this.clustersTextureSize,\n height: this.clustersTextureSize,\n colorAttachments: [this.centermassTexture],\n })\n } else {\n // Clear the centermass texture (fill with zeros)\n this.centermassTexture.copyImageData({\n data: new Float32Array(clustersTextureDataSize).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', this.clustersTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Update pointIndices buffer if pointsTextureSize changed\n if (!this.pointIndices || this.previousPointsTextureSize !== pointsTextureSize) {\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n this.pointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.calculateCentermassCommand?.setAttributes({\n pointIndices: this.pointIndices,\n })\n }\n\n // Update tracked sizes\n this.previousPointsTextureSize = pointsTextureSize\n this.previousClustersTextureSize = this.clustersTextureSize\n this.previousClusterCount = this.clusterCount\n }\n\n public initPrograms (): void {\n const { device, store, data } = this\n // Use same check as create() and run() for consistency\n if (data.pointsNumber === undefined || (!data.pointClusters && !data.clusterPositions)) return\n\n // Create UniformStore for calculateCentermass uniforms\n this.calculateCentermassUniformStore ||= new UniformStore({\n calculateCentermassUniforms: {\n uniformTypes: {\n pointsTextureSize: 'f32',\n clustersTextureSize: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n },\n },\n })\n\n this.calculateCentermassCommand ||= new Model(device, {\n fs: calculateCentermassFrag,\n vs: calculateCentermassVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...this.pointIndices && { pointIndices: this.pointIndices },\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' }, // 2 floats per vertex\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true, // Enable uniform buffers\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n calculateCentermassUniforms: this.calculateCentermassUniformStore.getManagedUniformBuffer(device, 'calculateCentermassUniforms'),\n // All texture bindings will be set dynamically in calculateCentermass() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'one',\n blendColorDstFactor: 'one',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Create UniformStore for applyForces uniforms\n this.applyForcesUniformStore ||= new UniformStore({\n applyForcesUniforms: {\n uniformTypes: {\n alpha: 'f32',\n clustersTextureSize: 'f32',\n clusterCoefficient: 'f32',\n },\n defaultUniforms: {\n alpha: store.alpha,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n clusterCoefficient: (this.config.simulationCluster ?? 0),\n },\n },\n })\n\n // Create and track vertexCoord buffer\n this.applyForcesVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.applyForcesCommand ||= new Model(device, {\n fs: forceFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.applyForcesVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' }, // 2 floats per vertex\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true, // Enable uniform buffers\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n applyForcesUniforms: this.applyForcesUniformStore.getManagedUniformBuffer(device, 'applyForcesUniforms'),\n // All texture bindings will be set dynamically in run() method\n },\n })\n }\n\n public calculateCentermass (): void {\n const { device, points } = this\n if (!points) return\n\n if (!this.calculateCentermassCommand || !this.calculateCentermassUniformStore) return\n // Ensure pointIndices is set (Model might exist but attributes not set yet)\n if (!this.pointIndices) return\n\n if (!this.centermassFbo || this.centermassFbo.destroyed) return\n if (!this.clusterTexture || this.clusterTexture.destroyed) return\n if (!points.previousPositionTexture || points.previousPositionTexture.destroyed) return\n\n // Update vertex count dynamically (using same fallback logic as initialization)\n this.calculateCentermassCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n // Update UniformStore with current values\n this.calculateCentermassUniformStore.setUniforms({\n calculateCentermassUniforms: {\n pointsTextureSize: this.store.pointsTextureSize,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n },\n })\n\n // Update texture bindings dynamically\n this.calculateCentermassCommand.setBindings({\n clusterTexture: this.clusterTexture,\n positionsTexture: points.previousPositionTexture,\n })\n\n // Create a RenderPass for the centermass framebuffer\n const centermassPass = device.beginRenderPass({\n framebuffer: this.centermassFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.calculateCentermassCommand.draw(centermassPass)\n\n centermassPass.end()\n }\n\n public run (): void {\n if (!this.data.pointClusters && !this.data.clusterPositions) return\n\n // Calculate centermass (creates its own RenderPass - different framebuffer)\n this.calculateCentermass()\n\n // Add safety check\n if (!this.applyForcesCommand || !this.applyForcesUniformStore) {\n return\n }\n\n // Add destroyed checks for resources before use\n if (!this.clusterTexture || this.clusterTexture.destroyed) return\n if (!this.centermassTexture || this.centermassTexture.destroyed) return\n if (!this.clusterPositionsTexture || this.clusterPositionsTexture.destroyed) return\n if (!this.clusterForceCoefficientTexture || this.clusterForceCoefficientTexture.destroyed) return\n if (!this.points?.previousPositionTexture || this.points.previousPositionTexture.destroyed) return\n if (!this.points.velocityFbo || this.points.velocityFbo.destroyed) return\n\n // Update UniformStore with current values\n this.applyForcesUniformStore.setUniforms({\n applyForcesUniforms: {\n alpha: this.store.alpha,\n clustersTextureSize: (this.clustersTextureSize ?? 0),\n clusterCoefficient: this.config.simulationCluster ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.applyForcesCommand.setBindings({\n clusterTexture: this.clusterTexture,\n centermassTexture: this.centermassTexture,\n clusterPositionsTexture: this.clusterPositionsTexture,\n clusterForceCoefficient: this.clusterForceCoefficientTexture,\n positionsTexture: this.points.previousPositionTexture,\n })\n\n const pass = this.device.beginRenderPass({\n framebuffer: this.points.velocityFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n this.applyForcesCommand.draw(pass)\n pass.end()\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.calculateCentermassCommand?.destroy()\n this.calculateCentermassCommand = undefined\n this.applyForcesCommand?.destroy()\n this.applyForcesCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.centermassFbo && !this.centermassFbo.destroyed) {\n this.centermassFbo.destroy()\n }\n this.centermassFbo = undefined\n\n // 3. Destroy Textures\n if (this.clusterTexture && !this.clusterTexture.destroyed) {\n this.clusterTexture.destroy()\n }\n this.clusterTexture = undefined\n if (this.clusterPositionsTexture && !this.clusterPositionsTexture.destroyed) {\n this.clusterPositionsTexture.destroy()\n }\n this.clusterPositionsTexture = undefined\n if (this.clusterForceCoefficientTexture && !this.clusterForceCoefficientTexture.destroyed) {\n this.clusterForceCoefficientTexture.destroy()\n }\n this.clusterForceCoefficientTexture = undefined\n if (this.centermassTexture && !this.centermassTexture.destroyed) {\n this.centermassTexture.destroy()\n }\n this.centermassTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.calculateCentermassUniformStore?.destroy()\n this.calculateCentermassUniformStore = undefined\n this.applyForcesUniformStore?.destroy()\n this.applyForcesUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointIndices && !this.pointIndices.destroyed) {\n this.pointIndices.destroy()\n }\n this.pointIndices = undefined\n if (this.applyForcesVertexCoordBuffer && !this.applyForcesVertexCoordBuffer.destroyed) {\n this.applyForcesVertexCoordBuffer.destroy()\n }\n this.applyForcesVertexCoordBuffer = undefined\n }\n}\n","export const benchCSS = `\n #gl-bench {\n position:absolute;\n right:0;\n top:0;\n z-index:1000;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n }\n #gl-bench div {\n position: relative;\n display: block;\n margin: 4px;\n padding: 0 7px 0 10px;\n background: #5f69de;\n border-radius: 15px;\n cursor: pointer;\n opacity: 0.9;\n }\n #gl-bench svg {\n height: 60px;\n margin: 0 -1px;\n }\n #gl-bench text {\n font-size: 12px;\n font-family: Helvetica,Arial,sans-serif;\n font-weight: 700;\n dominant-baseline: middle;\n text-anchor: middle;\n }\n #gl-bench .gl-mem {\n font-size: 9px;\n }\n #gl-bench line {\n stroke-width: 5;\n stroke: #112211;\n stroke-linecap: round;\n }\n #gl-bench polyline {\n fill: none;\n stroke: #112211;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-width: 3.5;\n }\n #gl-bench rect {\n fill: #8288e4;\n }\n #gl-bench .opacity {\n stroke: #8288e4;\n }\n`\n","\nimport { select } from 'd3-selection'\nimport GLBench from 'gl-bench'\nimport { benchCSS } from './css'\n\nexport class FPSMonitor {\n private bench: GLBench | undefined\n\n public constructor (canvas: HTMLCanvasElement) {\n this.destroy()\n const gl = (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) as WebGL2RenderingContext\n this.bench = new GLBench(gl, { css: benchCSS })\n }\n\n public begin (): void {\n this.bench?.begin('frame')\n }\n\n public end (now: number): void {\n this.bench?.end('frame')\n this.bench?.nextFrame(now)\n }\n\n public destroy (): void {\n this.bench = undefined\n select('#gl-bench').remove()\n }\n}\n","import { getRgbaColor, isNumber } from '@/graph/helper'\nimport { GraphConfig } from '@/graph/config'\n\nexport enum PointShape {\n Circle = 0,\n Square = 1,\n Triangle = 2,\n Diamond = 3,\n Pentagon = 4,\n Hexagon = 5,\n Star = 6,\n Cross = 7,\n None = 8\n}\n\nexport class GraphData {\n public inputPointPositions: Float32Array | undefined\n public inputPointColors: Float32Array | undefined\n public inputPointSizes: Float32Array | undefined\n public inputPointShapes: Float32Array | undefined\n public inputImageData: ImageData[] | undefined\n public inputPointImageIndices: Float32Array | undefined\n public inputPointImageSizes: Float32Array | undefined\n public inputLinkColors: Float32Array | undefined\n public inputLinkWidths: Float32Array | undefined\n public inputLinkStrength: Float32Array | undefined\n public inputPointClusters: (number | undefined)[] | undefined\n public inputClusterPositions: (number | undefined)[] | undefined\n public inputClusterStrength: Float32Array | undefined\n public inputPinnedPoints: number[] | undefined\n\n public pointPositions: Float32Array | undefined\n public pointColors: Float32Array | undefined\n public pointSizes: Float32Array | undefined\n public pointShapes: Float32Array | undefined\n public pointImageIndices: Float32Array | undefined\n public pointImageSizes: Float32Array | undefined\n\n public inputLinks: Float32Array | undefined\n public links: Float32Array | undefined\n public linkColors: Float32Array | undefined\n public linkWidths: Float32Array | undefined\n public linkArrowsBoolean: boolean[] | undefined\n public linkArrows: number[] | undefined\n public linkStrength: Float32Array | undefined\n\n public pointClusters: (number | undefined)[] | undefined\n public clusterPositions: (number | undefined)[] | undefined\n public clusterStrength: Float32Array | undefined\n\n /**\n * Each inner array of `sourceIndexToTargetIndices` and `targetIndexToSourceIndices` contains pairs where:\n * - The first value is the target/source index in the point array.\n * - The second value is the link index in the array of links.\n */\n public sourceIndexToTargetIndices: ([number, number][] | undefined)[] | undefined\n public targetIndexToSourceIndices: ([number, number][] | undefined)[] | undefined\n\n public degree: number[] | undefined\n public inDegree: number[] | undefined\n public outDegree: number[] | undefined\n\n private _config: GraphConfig\n\n public constructor (config: GraphConfig) {\n this._config = config\n }\n\n public get pointsNumber (): number | undefined {\n return this.pointPositions && this.pointPositions.length / 2\n }\n\n public get linksNumber (): number | undefined {\n return this.links && this.links.length / 2\n }\n\n public updatePoints (): void {\n this.pointPositions = this.inputPointPositions\n }\n\n /**\n * Updates the point colors based on the input data or default config value.\n */\n public updatePointColor (): void {\n if (this.pointsNumber === undefined) {\n this.pointColors = undefined\n return\n }\n\n // Sets point colors to default values from config if the input is missing or does not match input points number.\n const defaultRgba = getRgbaColor(this._config.pointDefaultColor ?? this._config.pointColor)\n if (this.inputPointColors === undefined || this.inputPointColors.length / 4 !== this.pointsNumber) {\n this.pointColors = new Float32Array(this.pointsNumber * 4)\n for (let i = 0; i < this.pointColors.length / 4; i++) {\n this.pointColors[i * 4] = defaultRgba[0]\n this.pointColors[i * 4 + 1] = defaultRgba[1]\n this.pointColors[i * 4 + 2] = defaultRgba[2]\n this.pointColors[i * 4 + 3] = defaultRgba[3]\n }\n } else {\n this.pointColors = this.inputPointColors\n for (let i = 0; i < this.pointColors.length / 4; i++) {\n if (!isNumber(this.pointColors[i * 4])) this.pointColors[i * 4] = defaultRgba[0]\n if (!isNumber(this.pointColors[i * 4 + 1])) this.pointColors[i * 4 + 1] = defaultRgba[1]\n if (!isNumber(this.pointColors[i * 4 + 2])) this.pointColors[i * 4 + 2] = defaultRgba[2]\n if (!isNumber(this.pointColors[i * 4 + 3])) this.pointColors[i * 4 + 3] = defaultRgba[3]\n }\n }\n }\n\n /**\n * Updates the point sizes based on the input data or default config value.\n */\n public updatePointSize (): void {\n if (this.pointsNumber === undefined) {\n this.pointSizes = undefined\n return\n }\n\n // Sets point sizes to default values from config if the input is missing or does not match input points number.\n const defaultSize = this._config.pointDefaultSize ?? this._config.pointSize\n if (this.inputPointSizes === undefined || this.inputPointSizes.length !== this.pointsNumber) {\n this.pointSizes = new Float32Array(this.pointsNumber).fill(defaultSize)\n } else {\n this.pointSizes = this.inputPointSizes\n for (let i = 0; i < this.pointSizes.length; i++) {\n if (!isNumber(this.pointSizes[i])) {\n this.pointSizes[i] = defaultSize\n }\n }\n }\n }\n\n /**\n * Updates the point shapes based on the input data or default shape.\n * Default behavior: Circle (0).\n * Images are rendered above shapes.\n */\n public updatePointShape (): void {\n if (this.pointsNumber === undefined) {\n this.pointShapes = undefined\n return\n }\n\n // Determine default shape: Circle\n const defaultShape = PointShape.Circle\n\n // Sets point shapes to default values if the input is missing or does not match input points number.\n if (this.inputPointShapes === undefined || this.inputPointShapes.length !== this.pointsNumber) {\n this.pointShapes = new Float32Array(this.pointsNumber).fill(defaultShape)\n } else {\n this.pointShapes = new Float32Array(this.inputPointShapes)\n const pointShapes = this.pointShapes\n for (let i = 0; i < pointShapes.length; i++) {\n const shape = pointShapes[i]\n if (shape == null || !isNumber(shape) || shape < 0 || shape > 8) {\n pointShapes[i] = defaultShape\n }\n }\n }\n }\n\n /**\n * Updates the point image indices based on the input data or default value (-1 for no image).\n */\n public updatePointImageIndices (): void {\n if (this.pointsNumber === undefined) {\n this.pointImageIndices = undefined\n return\n }\n\n // Sets point image indices to -1 if input is missing or doesn't match points count\n if (this.inputPointImageIndices === undefined || this.inputPointImageIndices.length !== this.pointsNumber) {\n this.pointImageIndices = new Float32Array(this.pointsNumber).fill(-1)\n } else {\n const pointImageIndices = new Float32Array(this.inputPointImageIndices)\n for (let i = 0; i < pointImageIndices.length; i++) {\n const rawIndex = pointImageIndices[i]\n const imageIndex = (rawIndex === undefined) ? NaN : rawIndex\n if (!Number.isFinite(imageIndex) || imageIndex < 0) {\n pointImageIndices[i] = -1\n } else {\n pointImageIndices[i] = Math.trunc(imageIndex)\n }\n }\n this.pointImageIndices = pointImageIndices\n }\n }\n\n /**\n * Updates the point image sizes based on the input data or default to point sizes.\n */\n public updatePointImageSizes (): void {\n if (this.pointsNumber === undefined) {\n this.pointImageSizes = undefined\n return\n }\n\n // Sets point image sizes to point sizes if the input is missing or does not match input points number.\n const defaultSize = this._config.pointDefaultSize ?? this._config.pointSize\n if (this.inputPointImageSizes === undefined || this.inputPointImageSizes.length !== this.pointsNumber) {\n this.pointImageSizes = this.pointSizes ? new Float32Array(this.pointSizes) : new Float32Array(this.pointsNumber).fill(defaultSize)\n } else {\n this.pointImageSizes = new Float32Array(this.inputPointImageSizes)\n for (let i = 0; i < this.pointImageSizes.length; i++) {\n if (!isNumber(this.pointImageSizes[i])) {\n this.pointImageSizes[i] = this.pointSizes?.[i] ?? defaultSize\n }\n }\n }\n }\n\n public updateLinks (): void {\n this.links = this.inputLinks\n }\n\n /**\n * Updates the link colors based on the input data or default config value.\n */\n public updateLinkColor (): void {\n if (this.linksNumber === undefined) {\n this.linkColors = undefined\n return\n }\n\n // Sets link colors to default values from config if the input is missing or does not match input links number.\n const defaultRgba = getRgbaColor(this._config.linkDefaultColor ?? this._config.linkColor)\n if (this.inputLinkColors === undefined || this.inputLinkColors.length / 4 !== this.linksNumber) {\n this.linkColors = new Float32Array(this.linksNumber * 4)\n\n for (let i = 0; i < this.linkColors.length / 4; i++) {\n this.linkColors[i * 4] = defaultRgba[0]\n this.linkColors[i * 4 + 1] = defaultRgba[1]\n this.linkColors[i * 4 + 2] = defaultRgba[2]\n this.linkColors[i * 4 + 3] = defaultRgba[3]\n }\n } else {\n this.linkColors = this.inputLinkColors\n for (let i = 0; i < this.linkColors.length / 4; i++) {\n if (!isNumber(this.linkColors[i * 4])) this.linkColors[i * 4] = defaultRgba[0]\n if (!isNumber(this.linkColors[i * 4 + 1])) this.linkColors[i * 4 + 1] = defaultRgba[1]\n if (!isNumber(this.linkColors[i * 4 + 2])) this.linkColors[i * 4 + 2] = defaultRgba[2]\n if (!isNumber(this.linkColors[i * 4 + 3])) this.linkColors[i * 4 + 3] = defaultRgba[3]\n }\n }\n }\n\n /**\n * Updates the link width based on the input data or default config value.\n */\n public updateLinkWidth (): void {\n if (this.linksNumber === undefined) {\n this.linkWidths = undefined\n return\n }\n\n // Sets link widths to default values from config if the input is missing or does not match input links number.\n const defaultWidth = this._config.linkDefaultWidth ?? this._config.linkWidth\n if (this.inputLinkWidths === undefined || this.inputLinkWidths.length !== this.linksNumber) {\n this.linkWidths = new Float32Array(this.linksNumber).fill(defaultWidth)\n } else {\n this.linkWidths = this.inputLinkWidths\n for (let i = 0; i < this.linkWidths.length; i++) {\n if (!isNumber(this.linkWidths[i])) {\n this.linkWidths[i] = defaultWidth\n }\n }\n }\n }\n\n /**\n * Updates the link arrows based on the input data or default config value.\n */\n public updateArrows (): void {\n if (this.linksNumber === undefined) {\n this.linkArrows = undefined\n return\n }\n\n // Sets link arrows to default values from config if the input is missing or does not match input links number.\n const defaultArrows = this._config.linkDefaultArrows ?? this._config.linkArrows\n if (this.linkArrowsBoolean === undefined || this.linkArrowsBoolean.length !== this.linksNumber) {\n this.linkArrows = new Array(this.linksNumber).fill(+defaultArrows)\n } else {\n this.linkArrows = this.linkArrowsBoolean.map(d => +d)\n }\n }\n\n public updateLinkStrength (): void {\n if (this.linksNumber === undefined) {\n this.linkStrength = undefined\n }\n\n if (this.inputLinkStrength === undefined || this.inputLinkStrength.length !== this.linksNumber) {\n this.linkStrength = undefined\n } else {\n this.linkStrength = this.inputLinkStrength\n }\n }\n\n public updateClusters (): void {\n if (this.pointsNumber === undefined) {\n this.pointClusters = undefined\n this.clusterPositions = undefined\n return\n }\n if (this.inputPointClusters === undefined || this.inputPointClusters.length !== this.pointsNumber) {\n this.pointClusters = undefined\n } else {\n this.pointClusters = this.inputPointClusters\n }\n if (this.inputClusterPositions === undefined) {\n this.clusterPositions = undefined\n } else {\n this.clusterPositions = this.inputClusterPositions\n }\n if (this.inputClusterStrength === undefined || this.inputClusterStrength.length !== this.pointsNumber) {\n this.clusterStrength = undefined\n } else {\n this.clusterStrength = this.inputClusterStrength\n }\n }\n\n public update (): void {\n this.updatePoints()\n this.updatePointColor()\n this.updatePointSize()\n this.updatePointShape()\n this.updatePointImageIndices()\n this.updatePointImageSizes()\n\n this.updateLinks()\n this.updateLinkColor()\n this.updateLinkWidth()\n this.updateArrows()\n this.updateLinkStrength()\n\n this.updateClusters()\n\n this._createAdjacencyLists()\n this._calculateDegrees()\n }\n\n public getAdjacentIndices (index: number): number[] | undefined {\n return [...(this.sourceIndexToTargetIndices?.[index]?.map(d => d[0]) || []), ...(this.targetIndexToSourceIndices?.[index]?.map(d => d[0]) || [])]\n }\n\n private _createAdjacencyLists (): void {\n if (this.linksNumber === undefined || this.links === undefined) {\n this.sourceIndexToTargetIndices = undefined\n this.targetIndexToSourceIndices = undefined\n return\n }\n\n this.sourceIndexToTargetIndices = new Array(this.pointsNumber).fill(undefined)\n this.targetIndexToSourceIndices = new Array(this.pointsNumber).fill(undefined)\n for (let i = 0; i < this.linksNumber; i++) {\n const sourceIndex = this.links[i * 2]\n const targetIndex = this.links[i * 2 + 1]\n if (sourceIndex !== undefined && targetIndex !== undefined) {\n if (this.sourceIndexToTargetIndices[sourceIndex] === undefined) this.sourceIndexToTargetIndices[sourceIndex] = []\n this.sourceIndexToTargetIndices[sourceIndex]?.push([targetIndex, i])\n\n if (this.targetIndexToSourceIndices[targetIndex] === undefined) this.targetIndexToSourceIndices[targetIndex] = []\n this.targetIndexToSourceIndices[targetIndex]?.push([sourceIndex, i])\n }\n }\n }\n\n private _calculateDegrees (): void {\n if (this.pointsNumber === undefined) {\n this.degree = undefined\n this.inDegree = undefined\n this.outDegree = undefined\n return\n }\n\n this.degree = new Array(this.pointsNumber).fill(0)\n this.inDegree = new Array(this.pointsNumber).fill(0)\n this.outDegree = new Array(this.pointsNumber).fill(0)\n\n for (let i = 0; i < this.pointsNumber; i++) {\n this.inDegree[i] = this.targetIndexToSourceIndices?.[i]?.length ?? 0\n this.outDegree[i] = this.sourceIndexToTargetIndices?.[i]?.length ?? 0\n this.degree[i] = (this.inDegree[i] ?? 0) + (this.outDegree[i] ?? 0)\n }\n }\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgbaColor;\\nin vec2 pos;\\nin float arrowLength;\\nin float useArrow;\\nin float smoothing;\\nin float arrowWidthFactor;\\nin float linkIndex;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawLineFragmentUniforms {\\n float renderMode;\\n} drawLineFrag;\\n\\n#define renderMode drawLineFrag.renderMode\\n#else\\n// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking\\nuniform float renderMode;\\n#endif\\n\\nout vec4 fragColor;\\n\\nfloat map(float value, float min1, float max1, float min2, float max2) {\\n return min2 + (value - min1) * (max2 - min2) / (max1 - min1);\\n}\\n\\nvoid main() {\\n float opacity = 1.0;\\n vec3 color = rgbaColor.rgb;\\n\\n if (useArrow > 0.5) {\\n float end_arrow = 0.5 + arrowLength / 2.0;\\n float start_arrow = end_arrow - arrowLength;\\n float arrowWidthDelta = arrowWidthFactor / 2.0;\\n float linkOpacity = rgbaColor.a * smoothstep(0.5 - arrowWidthDelta, 0.5 - arrowWidthDelta - smoothing / 2.0, abs(pos.y));\\n float arrowOpacity = 1.0;\\n if (pos.x > start_arrow && pos.x < start_arrow + arrowLength) {\\n float xmapped = map(pos.x, start_arrow, end_arrow, 0.0, 1.0);\\n arrowOpacity = rgbaColor.a * smoothstep(xmapped - smoothing, xmapped, map(abs(pos.y), 0.5, 0.0, 0.0, 1.0));\\n if (linkOpacity != arrowOpacity) {\\n linkOpacity = max(linkOpacity, arrowOpacity);\\n }\\n }\\n opacity = linkOpacity;\\n } else opacity = rgbaColor.a * smoothstep(0.5, 0.5 - smoothing, abs(pos.y));\\n \\n if (renderMode > 0.0) {\\n if (opacity > 0.0) {\\n fragColor = vec4(linkIndex, 0.0, 0.0, 1.0);\\n } else {\\n fragColor = vec4(-1.0, 0.0, 0.0, 0.0);\\n }\\n } else fragColor = vec4(color, opacity);\\n\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 position, pointA, pointB;\\nin vec4 color;\\nin float width;\\nin float arrow;\\nin float linkIndices;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatus;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawLineUniforms {\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float widthScale;\\n float linkArrowsSizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n vec2 linkVisibilityDistanceRange;\\n float linkVisibilityMinTransparency;\\n float linkOpacity;\\n float greyoutOpacity;\\n float curvedWeight;\\n float curvedLinkControlPointDistance;\\n float curvedLinkSegments;\\n float scaleLinksOnZoom;\\n float maxPointSize;\\n float renderMode;\\n float hoveredLinkIndex;\\n vec4 hoveredLinkColor;\\n float hoveredLinkWidthIncrease;\\n} drawLine;\\n\\n#define transformationMatrix drawLine.transformationMatrix\\n#define pointsTextureSize drawLine.pointsTextureSize\\n#define widthScale drawLine.widthScale\\n#define linkArrowsSizeScale drawLine.linkArrowsSizeScale\\n#define spaceSize drawLine.spaceSize\\n#define screenSize drawLine.screenSize\\n#define linkVisibilityDistanceRange drawLine.linkVisibilityDistanceRange\\n#define linkVisibilityMinTransparency drawLine.linkVisibilityMinTransparency\\n#define linkOpacity drawLine.linkOpacity\\n#define greyoutOpacity drawLine.greyoutOpacity\\n#define curvedWeight drawLine.curvedWeight\\n#define curvedLinkControlPointDistance drawLine.curvedLinkControlPointDistance\\n#define curvedLinkSegments drawLine.curvedLinkSegments\\n#define scaleLinksOnZoom drawLine.scaleLinksOnZoom\\n#define maxPointSize drawLine.maxPointSize\\n#define renderMode drawLine.renderMode\\n#define hoveredLinkIndex drawLine.hoveredLinkIndex\\n#define hoveredLinkColor drawLine.hoveredLinkColor\\n#define hoveredLinkWidthIncrease drawLine.hoveredLinkWidthIncrease\\n#else\\nuniform mat3 transformationMatrix;\\nuniform float pointsTextureSize;\\nuniform float widthScale;\\nuniform float linkArrowsSizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform vec2 linkVisibilityDistanceRange;\\nuniform float linkVisibilityMinTransparency;\\nuniform float linkOpacity;\\nuniform float greyoutOpacity;\\nuniform float curvedWeight;\\nuniform float curvedLinkControlPointDistance;\\nuniform float curvedLinkSegments;\\nuniform bool scaleLinksOnZoom;\\nuniform float maxPointSize;\\n// renderMode: 0.0 = normal rendering, 1.0 = index buffer rendering for picking\\nuniform float renderMode;\\nuniform float hoveredLinkIndex;\\nuniform vec4 hoveredLinkColor;\\nuniform float hoveredLinkWidthIncrease;\\n#endif\\n\\nout vec4 rgbaColor;\\nout vec2 pos;\\nout float arrowLength;\\nout float useArrow;\\nout float smoothing;\\nout float arrowWidthFactor;\\nout float linkIndex;\\n\\nfloat map(float value, float min1, float max1, float min2, float max2) {\\n return min2 + (value - min1) * (max2 - min2) / (max1 - min1);\\n}\\n\\nvec2 conicParametricCurve(vec2 A, vec2 B, vec2 ControlPoint, float t, float w) {\\n vec2 divident = (1.0 - t) * (1.0 - t) * A + 2.0 * (1.0 - t) * t * w * ControlPoint + t * t * B;\\n float divisor = (1.0 - t) * (1.0 - t) + 2.0 * (1.0 - t) * t * w + t * t;\\n return divident / divisor;\\n}\\n\\nfloat calculateLinkWidth(float width) {\\n float linkWidth;\\n if (scaleLinksOnZoom > 0.0) {\\n // Use original width if links should scale with zoom\\n linkWidth = width;\\n } else {\\n // Adjust width based on zoom level to maintain visual size\\n linkWidth = width / transformationMatrix[0][0];\\n // Apply a non-linear scaling to avoid extreme widths\\n linkWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n // Limit link width based on whether it has an arrow\\n if (useArrow > 0.5) {\\n return min(linkWidth, (maxPointSize * 2.0) / transformationMatrix[0][0]);\\n } else {\\n return min(linkWidth, maxPointSize / transformationMatrix[0][0]);\\n }\\n}\\n\\nfloat calculateArrowWidth(float arrowWidth) {\\n if (scaleLinksOnZoom > 0.0) {\\n return arrowWidth;\\n } else {\\n // Apply the same scaling logic as calculateLinkWidth to maintain proportionality\\n arrowWidth = arrowWidth / transformationMatrix[0][0];\\n // Apply the same non-linear scaling to avoid extreme widths\\n arrowWidth *= min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n return arrowWidth;\\n }\\n}\\n\\nvoid main() {\\n pos = position;\\n linkIndex = linkIndices;\\n\\n vec2 pointTexturePosA = (pointA + 0.5) / pointsTextureSize;\\n vec2 pointTexturePosB = (pointB + 0.5) / pointsTextureSize;\\n \\n vec4 greyoutStatusA = texture(pointGreyoutStatus, pointTexturePosA);\\n vec4 greyoutStatusB = texture(pointGreyoutStatus, pointTexturePosB);\\n \\n vec4 pointPositionA = texture(positionsTexture, pointTexturePosA);\\n vec4 pointPositionB = texture(positionsTexture, pointTexturePosB);\\n vec2 a = pointPositionA.xy;\\n vec2 b = pointPositionB.xy;\\n \\n // Calculate direction vector and its perpendicular\\n vec2 xBasis = b - a;\\n vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));\\n\\n // Calculate link distance and control point for curved link\\n float linkDist = length(xBasis);\\n float h = curvedLinkControlPointDistance;\\n vec2 controlPoint = (a + b) / 2.0 + yBasis * linkDist * h;\\n\\n // Convert link distance to screen pixels\\n float linkDistPx = linkDist * transformationMatrix[0][0];\\n \\n // Calculate line width using the width scale\\n float linkWidth = width * widthScale;\\n float k = 2.0;\\n // Arrow width is proportionally larger than the line width\\n float arrowWidth = linkWidth * k;\\n arrowWidth *= linkArrowsSizeScale;\\n\\n // Ensure arrow width difference is non-negative to prevent unwanted changes to link width\\n float arrowWidthDifference = max(0.0, arrowWidth - linkWidth);\\n\\n // Calculate arrow width in pixels\\n float arrowWidthPx = calculateArrowWidth(arrowWidth);\\n\\n // Calculate arrow length proportional to its width\\n // 0.866 is approximately sqrt(3)/2 - related to equilateral triangle geometry\\n // Cap the length to avoid overly long arrows on short links\\n arrowLength = min(0.3, (0.866 * arrowWidthPx * 2.0) / linkDist);\\n\\n useArrow = arrow;\\n if (useArrow > 0.5) {\\n linkWidth += arrowWidthDifference;\\n }\\n\\n arrowWidthFactor = arrowWidthDifference / linkWidth;\\n\\n // Calculate final link width in pixels with smoothing\\n float linkWidthPx = calculateLinkWidth(linkWidth);\\n \\n if (renderMode > 0.0) {\\n // Add 5 pixels padding for better hover detection\\n linkWidthPx += 5.0 / transformationMatrix[0][0];\\n } else {\\n // Add pixel increase if this is the hovered link\\n if (hoveredLinkIndex == linkIndex) {\\n linkWidthPx += hoveredLinkWidthIncrease / transformationMatrix[0][0];\\n }\\n }\\n float smoothingPx = 0.5 / transformationMatrix[0][0];\\n smoothing = smoothingPx / linkWidthPx;\\n linkWidthPx += smoothingPx;\\n\\n\\n\\n // Calculate final color with opacity based on link distance\\n vec3 rgbColor = color.rgb;\\n // Adjust opacity based on link distance\\n float opacity = color.a * linkOpacity * max(linkVisibilityMinTransparency, map(linkDistPx, linkVisibilityDistanceRange.g, linkVisibilityDistanceRange.r, 0.0, 1.0));\\n\\n // Apply greyed out opacity if either endpoint is greyed out\\n if (greyoutStatusA.r > 0.0 || greyoutStatusB.r > 0.0) {\\n opacity *= greyoutOpacity;\\n }\\n\\n // Pass final color to fragment shader\\n rgbaColor = vec4(rgbColor, opacity);\\n\\n // Apply hover color if this is the hovered link and hover color is defined\\n if (hoveredLinkIndex == linkIndex && hoveredLinkColor.a > -0.5) {\\n // Keep existing RGB values but multiply opacity with hover color opacity\\n rgbaColor.rgb = hoveredLinkColor.rgb;\\n rgbaColor.a *= hoveredLinkColor.a;\\n }\\n\\n // Calculate position on the curved path\\n float t = position.x;\\n float w = curvedWeight;\\n \\n float tPrev = t - 1.0 / curvedLinkSegments;\\n float tNext = t + 1.0 / curvedLinkSegments;\\n \\n vec2 pointCurr = conicParametricCurve(a, b, controlPoint, t, w);\\n \\n vec2 pointPrev = conicParametricCurve(a, b, controlPoint, max(0.0, tPrev), w);\\n vec2 pointNext = conicParametricCurve(a, b, controlPoint, min(tNext, 1.0), w);\\n \\n vec2 xBasisCurved = pointNext - pointPrev;\\n vec2 yBasisCurved = normalize(vec2(-xBasisCurved.y, xBasisCurved.x));\\n \\n pointCurr += yBasisCurved * linkWidthPx * position.y;\\n \\n // Transform to clip space coordinates\\n vec2 p = 2.0 * pointCurr / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n \\n gl_Position = vec4(final.rg, 0, 1);\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D linkIndexTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform hoveredLineIndexUniforms {\\n vec2 mousePosition;\\n vec2 screenSize;\\n} hoveredLine;\\n\\n#define mousePosition hoveredLine.mousePosition\\n#define screenSize hoveredLine.screenSize\\n#else\\nuniform vec2 mousePosition;\\nuniform vec2 screenSize;\\n#endif\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n // Convert mouse position to texture coordinates\\n vec2 texCoord = mousePosition / screenSize;\\n \\n // Read the link index from the linkIndexFbo texture at mouse position\\n vec4 linkIndexData = texture(linkIndexTexture, texCoord);\\n \\n // Extract the link index (stored in the red channel)\\n float linkIndex = linkIndexData.r;\\n \\n // Check if there's a valid link at this position (alpha > 0)\\n if (linkIndexData.a > 0.0 && linkIndex >= 0.0) {\\n // Output the link index\\n fragColor = vec4(linkIndex, 0.0, 0.0, 1.0);\\n } else {\\n // No link at this position, output -1 to indicate no hover\\n fragColor = vec4(-1.0, 0.0, 0.0, 0.0);\\n }\\n} \"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 vertexCoord;\\n\\nvoid main() {\\n gl_Position = vec4(vertexCoord, 0.0, 1.0);\\n} \"","import { scalePow } from 'd3-scale'\nimport { range } from 'd3-array'\n\nexport const getCurveLineGeometry = (segments: number): number[][] => {\n const scale = scalePow()\n .exponent(2)\n .range([0, 1])\n .domain([-1, 1])\n\n const hodographValues = range(0, segments).map(d => -0.5 + d / segments)\n hodographValues.push(0.5)\n const result = new Array(hodographValues.length * 2)\n hodographValues.forEach((d, i) => {\n result[i * 2] = [scale(d * 2), 0.5]\n result[i * 2 + 1] = [scale(d * 2), -0.5]\n })\n return result\n}\n","import { Framebuffer, Buffer, Texture, UniformStore, RenderPass } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport type { Mat4Array } from '@/graph/modules/Store'\nimport drawLineFrag from '@/graph/modules/Lines/draw-curve-line.frag?raw'\nimport drawLineVert from '@/graph/modules/Lines/draw-curve-line.vert?raw'\nimport hoveredLineIndexFrag from '@/graph/modules/Lines/hovered-line-index.frag?raw'\nimport hoveredLineIndexVert from '@/graph/modules/Lines/hovered-line-index.vert?raw'\nimport { defaultConfigValues } from '@/graph/variables'\nimport { getCurveLineGeometry } from '@/graph/modules/Lines/geometry'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport { ensureVec2, ensureVec4 } from '@/graph/modules/Shared/uniform-utils'\n\nexport class Lines extends CoreModule {\n public linkIndexFbo: Framebuffer | undefined\n public hoveredLineIndexFbo: Framebuffer | undefined\n private drawCurveCommand: Model | undefined\n private hoveredLineIndexCommand: Model | undefined\n private pointABuffer: Buffer | undefined\n private pointBBuffer: Buffer | undefined\n private colorBuffer: Buffer | undefined\n private widthBuffer: Buffer | undefined\n private arrowBuffer: Buffer | undefined\n private curveLineGeometry: number[][] | undefined\n private curveLineBuffer: Buffer | undefined\n private linkIndexBuffer: Buffer | undefined\n private quadBuffer: Buffer | undefined\n private linkIndexTexture: Texture | undefined\n private hoveredLineIndexTexture: Texture | undefined\n\n // Uniform stores for scalar uniforms\n private drawLineUniformStore: UniformStore<{\n drawLineUniforms: {\n transformationMatrix: Mat4Array;\n pointsTextureSize: number;\n widthScale: number;\n linkArrowsSizeScale: number;\n spaceSize: number;\n screenSize: [number, number];\n linkVisibilityDistanceRange: [number, number];\n linkVisibilityMinTransparency: number;\n linkOpacity: number;\n greyoutOpacity: number;\n curvedWeight: number;\n curvedLinkControlPointDistance: number;\n curvedLinkSegments: number;\n scaleLinksOnZoom: number;\n maxPointSize: number;\n renderMode: number;\n hoveredLinkIndex: number;\n hoveredLinkColor: [number, number, number, number];\n hoveredLinkWidthIncrease: number;\n };\n drawLineFragmentUniforms: {\n renderMode: number;\n };\n }> | undefined\n\n private hoveredLineIndexUniformStore: UniformStore<{\n hoveredLineIndexUniforms: {\n mousePosition: [number, number];\n screenSize: [number, number];\n };\n }> | undefined\n\n // Track previous screen size to detect changes\n private previousScreenSize: [number, number] | undefined\n\n public initPrograms (): void {\n const { device, config, store } = this\n\n this.updateLinkIndexFbo()\n\n // Initialize the hovered line index FBO\n this.hoveredLineIndexTexture ||= device.createTexture({\n width: 1,\n height: 1,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n data: new Float32Array(4).fill(0),\n })\n this.hoveredLineIndexFbo ||= device.createFramebuffer({\n width: 1,\n height: 1,\n colorAttachments: [this.hoveredLineIndexTexture],\n })\n\n // Ensure geometry buffer exists (create empty if needed)\n if (!this.curveLineGeometry) {\n this.updateCurveLineGeometry()\n }\n\n // Ensure all attribute buffers exist (create empty if needed) so Model has all attributes\n const linksNumber = this.data.linksNumber ?? 0\n this.pointABuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber * 2),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.pointBBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber * 2),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.colorBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber * 4),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.widthBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.arrowBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n this.linkIndexBuffer ||= device.createBuffer({\n data: new Float32Array(linksNumber),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n\n // Create UniformStore for drawLine uniforms\n this.drawLineUniformStore ||= new UniformStore({\n drawLineUniforms: {\n uniformTypes: {\n transformationMatrix: 'mat4x4<f32>',\n pointsTextureSize: 'f32',\n widthScale: 'f32',\n linkArrowsSizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n linkVisibilityDistanceRange: 'vec2<f32>',\n linkVisibilityMinTransparency: 'f32',\n linkOpacity: 'f32',\n greyoutOpacity: 'f32',\n curvedWeight: 'f32',\n curvedLinkControlPointDistance: 'f32',\n curvedLinkSegments: 'f32',\n scaleLinksOnZoom: 'f32',\n maxPointSize: 'f32',\n renderMode: 'f32',\n hoveredLinkIndex: 'f32',\n hoveredLinkColor: 'vec4<f32>',\n hoveredLinkWidthIncrease: 'f32',\n },\n defaultUniforms: {\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize,\n widthScale: config.linkWidthScale ?? 1,\n linkArrowsSizeScale: config.linkArrowsSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n linkVisibilityDistanceRange: ensureVec2(config.linkVisibilityDistanceRange, [0, 0]),\n linkVisibilityMinTransparency: config.linkVisibilityMinTransparency ?? 0,\n linkOpacity: config.linkOpacity ?? 1,\n greyoutOpacity: config.linkGreyoutOpacity ?? 1,\n curvedWeight: config.curvedLinkWeight ?? 0,\n curvedLinkControlPointDistance: config.curvedLinkControlPointDistance ?? 0,\n curvedLinkSegments: config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,\n scaleLinksOnZoom: (config.scaleLinksOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n renderMode: 0.0,\n hoveredLinkIndex: store.hoveredLinkIndex ?? -1,\n hoveredLinkColor: ensureVec4(store.hoveredLinkColor, [-1, -1, -1, -1]),\n hoveredLinkWidthIncrease: config.hoveredLinkWidthIncrease ?? 0,\n },\n },\n drawLineFragmentUniforms: {\n uniformTypes: {\n renderMode: 'f32',\n },\n defaultUniforms: {\n renderMode: 0.0,\n },\n },\n })\n\n this.drawCurveCommand ||= new Model(device, {\n vs: drawLineVert,\n fs: drawLineFrag,\n topology: 'triangle-strip',\n vertexCount: this.curveLineGeometry?.length ?? 0,\n attributes: {\n ...this.curveLineBuffer && { position: this.curveLineBuffer },\n ...this.pointABuffer && { pointA: this.pointABuffer },\n ...this.pointBBuffer && { pointB: this.pointBBuffer },\n ...this.colorBuffer && { color: this.colorBuffer },\n ...this.widthBuffer && { width: this.widthBuffer },\n ...this.arrowBuffer && { arrow: this.arrowBuffer },\n ...this.linkIndexBuffer && { linkIndices: this.linkIndexBuffer },\n },\n bufferLayout: [\n { name: 'position', format: 'float32x2' },\n { name: 'pointA', format: 'float32x2', stepMode: 'instance' },\n { name: 'pointB', format: 'float32x2', stepMode: 'instance' },\n { name: 'color', format: 'float32x4', stepMode: 'instance' },\n { name: 'width', format: 'float32', stepMode: 'instance' },\n { name: 'arrow', format: 'float32', stepMode: 'instance' },\n { name: 'linkIndices', format: 'float32', stepMode: 'instance' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n drawLineUniforms: this.drawLineUniformStore.getManagedUniformBuffer(device, 'drawLineUniforms'),\n drawLineFragmentUniforms: this.drawLineUniformStore.getManagedUniformBuffer(device, 'drawLineFragmentUniforms'),\n // All texture bindings will be set dynamically in draw() method\n },\n /**\n * Blending behavior for link index rendering (renderMode: 1.0 - hover detection):\n *\n * When rendering link indices to the framebuffer, we use full opacity (1.0).\n * This means:\n * - The source color completely overwrites the destination\n * - No blending occurs - it's like drawing with a permanent marker\n * - This preserves the exact index values we need for picking/selection\n */\n parameters: {\n cullMode: 'back',\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Initialize quad buffer for full-screen rendering\n this.quadBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n\n this.hoveredLineIndexUniformStore ||= new UniformStore({\n hoveredLineIndexUniforms: {\n uniformTypes: {\n mousePosition: 'vec2<f32>',\n screenSize: 'vec2<f32>',\n },\n defaultUniforms: {\n mousePosition: ensureVec2(store.screenMousePosition, [0, 0]),\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n },\n },\n })\n\n this.hoveredLineIndexCommand ||= new Model(device, {\n vs: hoveredLineIndexVert,\n fs: hoveredLineIndexFrag,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.quadBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n hoveredLineIndexUniforms: this.hoveredLineIndexUniformStore.getManagedUniformBuffer(device, 'hoveredLineIndexUniforms'),\n // All texture bindings will be set dynamically in findHoveredLine() method\n },\n })\n }\n\n public draw (renderPass: RenderPass): void {\n const { config, points, store } = this\n if (!points) return\n if (!points.currentPositionTexture || points.currentPositionTexture.destroyed) return\n if (!points.greyoutStatusTexture || points.greyoutStatusTexture.destroyed) return\n if (!this.pointABuffer || !this.pointBBuffer) this.updatePointsBuffer()\n if (!this.colorBuffer) this.updateColor()\n if (!this.widthBuffer) this.updateWidth()\n if (!this.arrowBuffer) this.updateArrow()\n if (!this.curveLineGeometry) this.updateCurveLineGeometry()\n if (!this.drawCurveCommand || !this.drawLineUniformStore) return\n\n // Update uniforms\n this.drawLineUniformStore.setUniforms({\n drawLineUniforms: {\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize,\n widthScale: config.linkWidthScale ?? 1,\n linkArrowsSizeScale: config.linkArrowsSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n linkVisibilityDistanceRange: ensureVec2(config.linkVisibilityDistanceRange, [0, 0]),\n linkVisibilityMinTransparency: config.linkVisibilityMinTransparency ?? 0,\n linkOpacity: config.linkOpacity ?? 1,\n greyoutOpacity: config.linkGreyoutOpacity ?? 1,\n curvedWeight: config.curvedLinkWeight ?? 0,\n curvedLinkControlPointDistance: config.curvedLinkControlPointDistance ?? 0,\n curvedLinkSegments: config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,\n scaleLinksOnZoom: (config.scaleLinksOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n renderMode: 0.0, // Normal rendering\n hoveredLinkIndex: store.hoveredLinkIndex ?? -1,\n hoveredLinkColor: ensureVec4(store.hoveredLinkColor, [-1, -1, -1, -1]),\n hoveredLinkWidthIncrease: config.hoveredLinkWidthIncrease ?? 0,\n },\n drawLineFragmentUniforms: {\n renderMode: 0.0, // Normal rendering\n },\n })\n\n // Update texture bindings dynamically\n this.drawCurveCommand.setBindings({\n positionsTexture: points.currentPositionTexture,\n pointGreyoutStatus: points.greyoutStatusTexture,\n })\n\n // Update instance count\n this.drawCurveCommand.setInstanceCount(this.data.linksNumber ?? 0)\n\n // Render normal links\n this.drawCurveCommand.draw(renderPass)\n }\n\n public updateLinkIndexFbo (): void {\n const { device, store } = this\n\n // Only create and update the link index FBO if link hovering is enabled\n if (!this.store.isLinkHoveringEnabled) return\n\n const screenSize = store.screenSize ?? [0, 0]\n const screenWidth = screenSize[0]\n const screenHeight = screenSize[1]\n\n // Avoid invalid uploads when size is zero\n if (!screenWidth || !screenHeight) return\n\n // Check if screen size changed\n const screenSizeChanged =\n this.previousScreenSize?.[0] !== screenWidth ||\n this.previousScreenSize?.[1] !== screenHeight\n\n if (!this.linkIndexTexture || screenSizeChanged) {\n // Destroy old framebuffer and texture if they exist\n if (this.linkIndexFbo && !this.linkIndexFbo.destroyed) {\n this.linkIndexFbo.destroy()\n }\n if (this.linkIndexTexture && !this.linkIndexTexture.destroyed) {\n this.linkIndexTexture.destroy()\n }\n\n // Create new texture\n this.linkIndexTexture = device.createTexture({\n width: screenWidth,\n height: screenHeight,\n format: 'rgba32float',\n usage: Texture.SAMPLE | Texture.RENDER | Texture.COPY_DST,\n })\n this.linkIndexTexture.copyImageData({\n data: new Float32Array(screenWidth * screenHeight * 4).fill(0),\n bytesPerRow: getBytesPerRow('rgba32float', screenWidth),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Create new framebuffer\n this.linkIndexFbo = device.createFramebuffer({\n width: screenWidth,\n height: screenHeight,\n colorAttachments: [this.linkIndexTexture],\n })\n\n this.previousScreenSize = [screenWidth, screenHeight]\n }\n }\n\n public updatePointsBuffer (): void {\n const { device, data, store } = this\n if (data.linksNumber === undefined || data.links === undefined) return\n if (!store.pointsTextureSize) return // Guard against 0/undefined\n\n // Create separate buffers for pointA and pointB\n const pointAData = new Float32Array(data.linksNumber * 2)\n const pointBData = new Float32Array(data.linksNumber * 2)\n\n for (let i = 0; i < data.linksNumber; i++) {\n const fromIndex = data.links[i * 2] as number\n const toIndex = data.links[i * 2 + 1] as number\n const fromX = fromIndex % store.pointsTextureSize\n const fromY = Math.floor(fromIndex / store.pointsTextureSize)\n const toX = toIndex % store.pointsTextureSize\n const toY = Math.floor(toIndex / store.pointsTextureSize)\n\n pointAData[i * 2] = fromX\n pointAData[i * 2 + 1] = fromY\n pointBData[i * 2] = toX\n pointBData[i * 2 + 1] = toY\n }\n\n // Check if buffer needs to be resized (buffers can't be resized, need to recreate)\n const currentSize = (this.pointABuffer?.byteLength ?? 0) / (Float32Array.BYTES_PER_ELEMENT * 2)\n if (!this.pointABuffer || currentSize !== data.linksNumber) {\n if (this.pointABuffer && !this.pointABuffer.destroyed) {\n this.pointABuffer.destroy()\n }\n this.pointABuffer = device.createBuffer({\n data: pointAData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n // Note: Model attributes are set at creation time, so if Model exists and buffer is recreated,\n // the Model will need to be recreated too. For now, we ensure buffers exist before initPrograms.\n } else {\n this.pointABuffer.write(pointAData)\n }\n\n if (!this.pointBBuffer || currentSize !== data.linksNumber) {\n if (this.pointBBuffer && !this.pointBBuffer.destroyed) {\n this.pointBBuffer.destroy()\n }\n this.pointBBuffer = device.createBuffer({\n data: pointBData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.pointBBuffer.write(pointBData)\n }\n\n const linkIndices = new Float32Array(data.linksNumber)\n for (let i = 0; i < data.linksNumber; i++) {\n linkIndices[i] = i\n }\n if (!this.linkIndexBuffer || currentSize !== data.linksNumber) {\n if (this.linkIndexBuffer && !this.linkIndexBuffer.destroyed) {\n this.linkIndexBuffer.destroy()\n }\n this.linkIndexBuffer = device.createBuffer({\n data: linkIndices,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.linkIndexBuffer.write(linkIndices)\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n pointA: this.pointABuffer,\n pointB: this.pointBBuffer,\n linkIndices: this.linkIndexBuffer,\n })\n }\n }\n\n public updateColor (): void {\n const { device, data } = this\n const linksNumber = data.linksNumber ?? 0\n const colorData = data.linkColors ?? new Float32Array(linksNumber * 4).fill(0)\n\n if (!this.colorBuffer) {\n this.colorBuffer = device.createBuffer({\n data: colorData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n // Check if buffer needs to be resized\n const currentSize = (this.colorBuffer.byteLength ?? 0) / (Float32Array.BYTES_PER_ELEMENT * 4)\n if (currentSize !== linksNumber) {\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = device.createBuffer({\n data: colorData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.colorBuffer.write(colorData)\n }\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n color: this.colorBuffer,\n })\n }\n }\n\n public updateWidth (): void {\n const { device, data } = this\n const linksNumber = data.linksNumber ?? 0\n const widthData = data.linkWidths ?? new Float32Array(linksNumber).fill(0)\n\n if (!this.widthBuffer) {\n this.widthBuffer = device.createBuffer({\n data: widthData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n // Check if buffer needs to be resized\n const currentSize = (this.widthBuffer.byteLength ?? 0) / Float32Array.BYTES_PER_ELEMENT\n if (currentSize !== linksNumber) {\n if (this.widthBuffer && !this.widthBuffer.destroyed) {\n this.widthBuffer.destroy()\n }\n this.widthBuffer = device.createBuffer({\n data: widthData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.widthBuffer.write(widthData)\n }\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n width: this.widthBuffer,\n })\n }\n }\n\n public updateArrow (): void {\n const { device, data } = this\n // linkArrows is number[] not Float32Array, so we need to convert it\n // Ensure we have the right size even if linkArrows is undefined\n const linksNumber = data.linksNumber ?? 0\n const arrowData = data.linkArrows\n ? new Float32Array(data.linkArrows)\n : new Float32Array(linksNumber).fill(0)\n\n if (!this.arrowBuffer) {\n this.arrowBuffer = device.createBuffer({\n data: arrowData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n // Check if buffer needs to be resized\n const currentSize = (this.arrowBuffer.byteLength ?? 0) / Float32Array.BYTES_PER_ELEMENT\n if (currentSize !== linksNumber) {\n if (this.arrowBuffer && !this.arrowBuffer.destroyed) {\n this.arrowBuffer.destroy()\n }\n this.arrowBuffer = device.createBuffer({\n data: arrowData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.arrowBuffer.write(arrowData)\n }\n }\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n arrow: this.arrowBuffer,\n })\n }\n }\n\n public updateCurveLineGeometry (): void {\n const { device, config: { curvedLinks, curvedLinkSegments } } = this\n this.curveLineGeometry = getCurveLineGeometry(curvedLinks ? curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1)\n\n // Flatten the 2D array to 1D\n const flatGeometry = new Float32Array(this.curveLineGeometry.length * 2)\n for (let i = 0; i < this.curveLineGeometry.length; i++) {\n flatGeometry[i * 2] = this.curveLineGeometry[i]![0]!\n flatGeometry[i * 2 + 1] = this.curveLineGeometry[i]![1]!\n }\n\n if (!this.curveLineBuffer || this.curveLineBuffer.byteLength !== flatGeometry.byteLength) {\n if (this.curveLineBuffer && !this.curveLineBuffer.destroyed) {\n this.curveLineBuffer.destroy()\n }\n this.curveLineBuffer = device.createBuffer({\n data: flatGeometry,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.curveLineBuffer.write(flatGeometry)\n }\n\n // Update vertex count in model if it exists\n if (this.drawCurveCommand) {\n this.drawCurveCommand.setAttributes({\n position: this.curveLineBuffer,\n })\n this.drawCurveCommand.setVertexCount(this.curveLineGeometry.length)\n }\n }\n\n public findHoveredLine (): void {\n const { config, points, store } = this\n if (!points) return\n if (!points.currentPositionTexture || points.currentPositionTexture.destroyed) return\n if (!points.greyoutStatusTexture || points.greyoutStatusTexture.destroyed) return\n if (!this.data.linksNumber || !this.store.isLinkHoveringEnabled) return\n if (!this.linkIndexFbo || !this.drawCurveCommand || !this.drawLineUniformStore) return\n if (!this.linkIndexTexture || this.linkIndexTexture.destroyed) return\n\n // Update uniforms for index rendering\n this.drawLineUniformStore.setUniforms({\n drawLineUniforms: {\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize,\n widthScale: config.linkWidthScale ?? 1,\n linkArrowsSizeScale: config.linkArrowsSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n linkVisibilityDistanceRange: ensureVec2(config.linkVisibilityDistanceRange, [0, 0]),\n linkVisibilityMinTransparency: config.linkVisibilityMinTransparency ?? 0,\n linkOpacity: config.linkOpacity ?? 1,\n greyoutOpacity: config.linkGreyoutOpacity ?? 1,\n curvedWeight: config.curvedLinkWeight ?? 0,\n curvedLinkControlPointDistance: config.curvedLinkControlPointDistance ?? 0,\n curvedLinkSegments: config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,\n scaleLinksOnZoom: (config.scaleLinksOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n renderMode: 1.0, // Index rendering for picking\n hoveredLinkIndex: store.hoveredLinkIndex ?? -1,\n hoveredLinkColor: ensureVec4(store.hoveredLinkColor, [-1, -1, -1, -1]),\n hoveredLinkWidthIncrease: config.hoveredLinkWidthIncrease ?? 0,\n },\n drawLineFragmentUniforms: {\n renderMode: 1.0, // Index rendering for picking\n },\n })\n\n // Update texture bindings dynamically\n this.drawCurveCommand.setBindings({\n positionsTexture: points.currentPositionTexture,\n pointGreyoutStatus: points.greyoutStatusTexture,\n })\n\n // Update instance count\n this.drawCurveCommand.setInstanceCount(this.data.linksNumber ?? 0)\n\n // Render to index buffer for picking/hover detection\n const indexPass = this.device.beginRenderPass({\n framebuffer: this.linkIndexFbo,\n // Clear framebuffer to transparent black (luma.gl default would be opaque black)\n clearColor: [0, 0, 0, 0],\n })\n this.drawCurveCommand.draw(indexPass)\n indexPass.end()\n\n if (this.hoveredLineIndexCommand && this.hoveredLineIndexFbo && this.hoveredLineIndexUniformStore) {\n this.hoveredLineIndexUniformStore.setUniforms({\n hoveredLineIndexUniforms: {\n mousePosition: ensureVec2(store.screenMousePosition, [0, 0]),\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.hoveredLineIndexCommand.setBindings({\n linkIndexTexture: this.linkIndexTexture,\n })\n\n const hoverPass = this.device.beginRenderPass({\n framebuffer: this.hoveredLineIndexFbo,\n })\n this.hoveredLineIndexCommand.draw(hoverPass)\n hoverPass.end()\n }\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.drawCurveCommand?.destroy()\n this.drawCurveCommand = undefined\n this.hoveredLineIndexCommand?.destroy()\n this.hoveredLineIndexCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.linkIndexFbo && !this.linkIndexFbo.destroyed) {\n this.linkIndexFbo.destroy()\n }\n this.linkIndexFbo = undefined\n if (this.hoveredLineIndexFbo && !this.hoveredLineIndexFbo.destroyed) {\n this.hoveredLineIndexFbo.destroy()\n }\n this.hoveredLineIndexFbo = undefined\n\n // 3. Destroy Textures\n if (this.linkIndexTexture && !this.linkIndexTexture.destroyed) {\n this.linkIndexTexture.destroy()\n }\n this.linkIndexTexture = undefined\n if (this.hoveredLineIndexTexture && !this.hoveredLineIndexTexture.destroyed) {\n this.hoveredLineIndexTexture.destroy()\n }\n this.hoveredLineIndexTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.drawLineUniformStore?.destroy()\n this.drawLineUniformStore = undefined\n this.hoveredLineIndexUniformStore?.destroy()\n this.hoveredLineIndexUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.pointABuffer && !this.pointABuffer.destroyed) {\n this.pointABuffer.destroy()\n }\n this.pointABuffer = undefined\n if (this.pointBBuffer && !this.pointBBuffer.destroyed) {\n this.pointBBuffer.destroy()\n }\n this.pointBBuffer = undefined\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = undefined\n if (this.widthBuffer && !this.widthBuffer.destroyed) {\n this.widthBuffer.destroy()\n }\n this.widthBuffer = undefined\n if (this.arrowBuffer && !this.arrowBuffer.destroyed) {\n this.arrowBuffer.destroy()\n }\n this.arrowBuffer = undefined\n if (this.curveLineBuffer && !this.curveLineBuffer.destroyed) {\n this.curveLineBuffer.destroy()\n }\n this.curveLineBuffer = undefined\n if (this.linkIndexBuffer && !this.linkIndexBuffer.destroyed) {\n this.linkIndexBuffer.destroy()\n }\n this.linkIndexBuffer = undefined\n if (this.quadBuffer && !this.quadBuffer.destroyed) {\n this.quadBuffer.destroy()\n }\n this.quadBuffer = undefined\n }\n}\n","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D imageAtlasTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawFragmentUniforms {\\n float greyoutOpacity;\\n float pointOpacity;\\n float isDarkenGreyout;\\n vec4 backgroundColor;\\n} drawFragment;\\n\\n#define greyoutOpacity drawFragment.greyoutOpacity\\n#define pointOpacity drawFragment.pointOpacity\\n#define isDarkenGreyout drawFragment.isDarkenGreyout\\n#define backgroundColor drawFragment.backgroundColor\\n#else\\nuniform float greyoutOpacity;\\nuniform float pointOpacity;\\nuniform float isDarkenGreyout;\\nuniform vec4 backgroundColor;\\n#endif\\n\\n\\nin float pointShape;\\nin float isGreyedOut;\\nin vec4 shapeColor;\\nin vec4 imageAtlasUV;\\nin float shapeSize;\\nin float imageSizeVarying;\\nin float overallSize;\\n\\nout vec4 fragColor;\\n\\n// Smoothing controls the smoothness of the point's edge\\nconst float smoothing = 0.9;\\n\\n// Shape constants\\nconst float CIRCLE = 0.0;\\nconst float SQUARE = 1.0;\\nconst float TRIANGLE = 2.0;\\nconst float DIAMOND = 3.0;\\nconst float PENTAGON = 4.0;\\nconst float HEXAGON = 5.0;\\nconst float STAR = 6.0;\\nconst float CROSS = 7.0;\\nconst float NONE = 8.0;\\n\\n// Distance functions for different shapes\\nfloat circleDistance(vec2 p) {\\n return dot(p, p);\\n}\\n\\n// Function to apply greyout logic to image colors\\nvec4 applyGreyoutToImage(vec4 imageColor, float isGreyedOutValue) {\\n vec3 finalColor = imageColor.rgb;\\n float finalAlpha = imageColor.a;\\n \\n if (isGreyedOutValue > 0.0) {\\n float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)\\n \\n if (isDarkenGreyout > 0.0) {\\n finalColor = mix(finalColor, vec3(0.2), blendFactor);\\n } else {\\n finalColor = mix(finalColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n }\\n \\n return vec4(finalColor, finalAlpha);\\n}\\n\\nfloat squareDistance(vec2 p) {\\n vec2 d = abs(p) - vec2(0.8);\\n return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);\\n}\\n\\nfloat triangleDistance(vec2 p) {\\n const float k = sqrt(3.0); // ≈1.732; slope of 60° lines for an equilateral triangle\\n p.x = abs(p.x) - 0.9; // fold the X axis and shift: brings left and right halves together\\n p.y = p.y + 0.55; // move the whole shape up slightly so it is centred vertically\\n\\n // reflect points that fall outside the main triangle back inside, to reuse the same maths\\n if (p.x + k * p.y > 0.0)\\n p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;\\n\\n p.x -= clamp(p.x, -1.0, 0.0); // clip any remainder on the left side\\n\\n // Return signed distance: negative = inside; positive = outside\\n return -length(p) * sign(p.y);\\n}\\n\\nfloat diamondDistance(vec2 p) {\\n // aspect > 1 → taller diamond\\n const float aspect = 1.2;\\n return abs(p.x) + abs(p.y) / aspect - 0.8;\\n}\\n\\nfloat pentagonDistance(vec2 p) {\\n // Regular pentagon signed-distance (Inigo Quilez)\\n const vec3 k = vec3(0.809016994, 0.587785252, 0.726542528);\\n p.x = abs(p.x);\\n\\n // Reflect across the two tilted edges ─ only if point is outside\\n p -= 2.0 * min(dot(vec2(-k.x, k.y), p), 0.0) * vec2(-k.x, k.y);\\n p -= 2.0 * min(dot(vec2( k.x, k.y), p), 0.0) * vec2( k.x, k.y);\\n\\n // Clip against the top horizontal edge (keeps top point sharp)\\n p -= vec2(clamp(p.x, -k.z * k.x, k.z * k.x), k.z);\\n\\n // Return signed distance (negative → inside, positive → outside)\\n return length(p) * sign(p.y);\\n}\\n\\nfloat hexagonDistance(vec2 p) {\\n const vec3 k = vec3(-0.866025404, 0.5, 0.577350269);\\n p = abs(p);\\n p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy;\\n p -= vec2(clamp(p.x, -k.z * 0.8, k.z * 0.8), 0.8);\\n return length(p) * sign(p.y);\\n}\\n\\nfloat starDistance(vec2 p) {\\n // 5-point star signed-distance function (adapted from Inigo Quilez)\\n // r – outer radius, rf – inner/outer radius ratio\\n const float r = 0.9;\\n const float rf = 0.45;\\n\\n // Pre-computed rotation vectors for the star arms (36° increments)\\n const vec2 k1 = vec2(0.809016994, -0.587785252);\\n const vec2 k2 = vec2(-k1.x, k1.y);\\n\\n // Fold the plane into a single arm sector\\n p.x = abs(p.x);\\n p -= 2.0 * max(dot(k1, p), 0.0) * k1;\\n p -= 2.0 * max(dot(k2, p), 0.0) * k2;\\n p.x = abs(p.x);\\n\\n // Translate so the top tip of the star lies on the X-axis\\n p.y -= r;\\n\\n // Vector describing the edge between an outer tip and its adjacent inner point\\n vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0);\\n // Project the point onto that edge and clamp the projection to the segment\\n float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r);\\n\\n // Return signed distance (negative => inside, positive => outside)\\n return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y);\\n}\\n\\nfloat crossDistance(vec2 p) {\\n // Signed distance function for a cross (union of two rectangles)\\n // Adapted from Inigo Quilez (https://iquilezles.org/)\\n // Each arm has half-sizes 0.3 (thickness) and 0.8 (length)\\n p = abs(p);\\n if (p.y > p.x) p = p.yx; // exploit symmetry\\n\\n vec2 q = p - vec2(0.8, 0.3); // subtract half-sizes (length, thickness)\\n\\n // Standard rectangle SDF, then take union of the two arms\\n return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0);\\n}\\n\\nfloat getShapeDistance(vec2 p, float shape) {\\n if (shape == SQUARE) return squareDistance(p);\\n else if (shape == TRIANGLE) return triangleDistance(p);\\n else if (shape == DIAMOND) return diamondDistance(p);\\n else if (shape == PENTAGON) return pentagonDistance(p);\\n else if (shape == HEXAGON) return hexagonDistance(p);\\n else if (shape == STAR) return starDistance(p);\\n else if (shape == CROSS) return crossDistance(p);\\n else return circleDistance(p); // Default to circle\\n}\\n\\nvoid main() {\\n // Discard the fragment if the point is fully transparent and has no image\\n if (shapeColor.a == 0.0 && imageAtlasUV.x == -1.0) {\\n discard;\\n }\\n\\n // Discard the fragment if the point has no shape and no image\\n if (pointShape == NONE && imageAtlasUV.x == -1.0) {\\n discard;\\n }\\n\\n // Calculate coordinates within the point\\n vec2 pointCoord = 2.0 * gl_PointCoord - 1.0;\\n\\n vec4 finalShapeColor = vec4(0.0);\\n vec4 finalImageColor = vec4(0.0);\\n \\n // Handle shape rendering with centering logic\\n if (pointShape != NONE) {\\n // Calculate shape coordinates with centering\\n vec2 shapeCoord = pointCoord;\\n if (overallSize > shapeSize && shapeSize > 0.0) {\\n // Shape is smaller than overall size, center it\\n float scale = shapeSize / overallSize;\\n shapeCoord = pointCoord / scale;\\n }\\n \\n float opacity;\\n if (pointShape == CIRCLE) {\\n // For circles, use the original distance calculation\\n float pointCenterDistance = dot(shapeCoord, shapeCoord);\\n opacity = 1.0 - smoothstep(smoothing, 1.0, pointCenterDistance);\\n } else {\\n // For other shapes, use the shape distance function\\n float shapeDistance = getShapeDistance(shapeCoord, pointShape);\\n opacity = 1.0 - smoothstep(-0.01, 0.01, shapeDistance);\\n }\\n opacity *= shapeColor.a;\\n\\n finalShapeColor = vec4(shapeColor.rgb, opacity);\\n }\\n\\n // Handle image rendering with centering logic\\n if (imageAtlasUV.x != -1.0) {\\n // Calculate image coordinates with centering\\n vec2 imageCoord = pointCoord;\\n if (overallSize > imageSizeVarying && imageSizeVarying > 0.0) {\\n // Image is smaller than overall size, center it\\n float scale = imageSizeVarying / overallSize;\\n imageCoord = pointCoord / scale;\\n \\n // Check if we're outside the valid image area\\n if (abs(imageCoord.x) > 1.0 || abs(imageCoord.y) > 1.0) {\\n // We're outside the image bounds, don't render the image\\n finalImageColor = vec4(0.0);\\n } else {\\n // Sample from texture atlas\\n vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5);\\n vec4 imageColor = texture(imageAtlasTexture, atlasUV);\\n finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut);\\n }\\n } else {\\n // Image is same size or larger than overall size, no scaling needed\\n // Sample from texture atlas\\n vec2 atlasUV = mix(imageAtlasUV.xy, imageAtlasUV.zw, (imageCoord + 1.0) * 0.5);\\n vec4 imageColor = texture(imageAtlasTexture, atlasUV);\\n finalImageColor = applyGreyoutToImage(imageColor, isGreyedOut);\\n }\\n }\\n\\n float finalPointAlpha = max(finalShapeColor.a, finalImageColor.a);\\n if (isGreyedOut > 0.0 && greyoutOpacity != -1.0) {\\n finalPointAlpha *= greyoutOpacity;\\n } else {\\n finalPointAlpha *= pointOpacity;\\n }\\n\\n // Blend image color above point color\\n fragColor = vec4(\\n mix(finalShapeColor.rgb, finalImageColor.rgb, finalImageColor.a),\\n finalPointAlpha\\n );\\n}\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 pointIndices;\\nin float size;\\nin vec4 color;\\nin float shape;\\nin float imageIndex;\\nin float imageSize;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatus;\\nuniform sampler2D imageAtlasCoords;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawVertexUniforms {\\n float ratio;\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n vec4 greyoutColor;\\n vec4 backgroundColor;\\n float scalePointsOnZoom;\\n float maxPointSize;\\n float isDarkenGreyout;\\n float skipSelected;\\n float skipUnselected;\\n float hasImages;\\n float imageCount;\\n float imageAtlasCoordsTextureSize;\\n} drawVertex;\\n\\n#define ratio drawVertex.ratio\\n#define transformationMatrix drawVertex.transformationMatrix\\n#define pointsTextureSize drawVertex.pointsTextureSize\\n#define sizeScale drawVertex.sizeScale\\n#define spaceSize drawVertex.spaceSize\\n#define screenSize drawVertex.screenSize\\n#define greyoutColor drawVertex.greyoutColor\\n#define backgroundColor drawVertex.backgroundColor\\n#define scalePointsOnZoom drawVertex.scalePointsOnZoom\\n#define maxPointSize drawVertex.maxPointSize\\n#define isDarkenGreyout drawVertex.isDarkenGreyout\\n#define skipSelected drawVertex.skipSelected\\n#define skipUnselected drawVertex.skipUnselected\\n#define hasImages drawVertex.hasImages\\n#define imageCount drawVertex.imageCount\\n#define imageAtlasCoordsTextureSize drawVertex.imageAtlasCoordsTextureSize\\n#else\\nuniform float ratio;\\nuniform mat3 transformationMatrix;\\nuniform float pointsTextureSize;\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform vec4 greyoutColor;\\nuniform vec4 backgroundColor;\\nuniform float scalePointsOnZoom;\\nuniform float maxPointSize;\\nuniform float isDarkenGreyout;\\nuniform float skipSelected;\\nuniform float skipUnselected;\\nuniform float hasImages;\\nuniform float imageCount;\\nuniform float imageAtlasCoordsTextureSize;\\n#endif\\n\\nout float pointShape;\\nout float isGreyedOut;\\nout vec4 shapeColor;\\nout vec4 imageAtlasUV;\\nout float shapeSize;\\nout float imageSizeVarying;\\nout float overallSize;\\n\\nfloat calculatePointSize(float size) {\\n float pSize;\\n\\n if (scalePointsOnZoom > 0.0) { \\n pSize = size * ratio * transformationMatrix[0][0];\\n } else {\\n pSize = size * ratio * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n\\n return min(pSize, maxPointSize * ratio);\\n}\\n\\nvoid main() { \\n // Check greyout status for selective rendering\\n vec4 greyoutStatus = texture(pointGreyoutStatus, (pointIndices + 0.5) / pointsTextureSize);\\n isGreyedOut = greyoutStatus.r;\\n float isSelected = (greyoutStatus.r == 0.0) ? 1.0 : 0.0;\\n \\n // Discard point based on rendering mode\\n if (skipSelected > 0.0 && isSelected > 0.0) {\\n gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Move off-screen\\n gl_PointSize = 0.0;\\n return;\\n }\\n if (skipUnselected > 0.0 && isSelected <= 0.0) {\\n gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Move off-screen\\n gl_PointSize = 0.0;\\n return;\\n }\\n \\n // Position\\n vec4 pointPosition = texture(positionsTexture, (pointIndices + 0.5) / pointsTextureSize);\\n vec2 point = pointPosition.rg;\\n\\n // Transform point position to normalized device coordinates\\n // Convert from space coordinates [0, spaceSize] to normalized [-1, 1]\\n vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0;\\n \\n // Apply aspect ratio correction - this is needed to map the square space to the rectangular screen\\n // The transformation matrix handles zoom/pan, but we need this to handle aspect ratio\\n normalizedPosition *= spaceSize / screenSize;\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1);\\n #else\\n vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1);\\n #endif\\n gl_Position = vec4(finalPosition.rg, 0, 1);\\n\\n // Calculate sizes for shape and image\\n float shapeSizeValue = calculatePointSize(size * sizeScale);\\n float imageSizeValue = calculatePointSize(imageSize * sizeScale);\\n \\n // Use the larger of the two sizes for the overall point size\\n float overallSizeValue = max(shapeSizeValue, imageSizeValue);\\n gl_PointSize = overallSizeValue;\\n\\n // Pass size information to fragment shader\\n shapeSize = shapeSizeValue;\\n imageSizeVarying = imageSizeValue;\\n overallSize = overallSizeValue;\\n\\n shapeColor = color;\\n pointShape = shape;\\n\\n // Adjust alpha of selected points\\n if (isGreyedOut > 0.0) {\\n if (greyoutColor[0] != -1.0) {\\n shapeColor = greyoutColor;\\n } else {\\n // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout\\n float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n shapeColor.rgb = mix(shapeColor.rgb, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n shapeColor.rgb = mix(shapeColor.rgb, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #else\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n shapeColor.rgb = mix(shapeColor.rgb, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n shapeColor.rgb = mix(shapeColor.rgb, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #endif\\n }\\n }\\n\\n #ifdef USE_UNIFORM_BUFFERS\\n if (hasImages <= 0.0 || imageIndex < 0.0 || imageIndex >= imageCount) {\\n imageAtlasUV = vec4(-1.0);\\n } else {\\n // Calculate image atlas UV coordinates based on imageIndex\\n float atlasCoordIndex = imageIndex;\\n // Calculate the position in the texture grid\\n float texX = mod(atlasCoordIndex, imageAtlasCoordsTextureSize);\\n float texY = floor(atlasCoordIndex / imageAtlasCoordsTextureSize);\\n // Convert to texture coordinates (0.0 to 1.0)\\n vec2 atlasCoordTexCoord = (vec2(texX, texY) + 0.5) / imageAtlasCoordsTextureSize;\\n vec4 atlasCoords = texture(imageAtlasCoords, atlasCoordTexCoord);\\n imageAtlasUV = atlasCoords;\\n }\\n #else\\n if (hasImages <= 0.0 || imageIndex < 0.0 || imageIndex >= imageCount) {\\n imageAtlasUV = vec4(-1.0);\\n } else {\\n // Calculate image atlas UV coordinates based on imageIndex\\n float atlasCoordIndex = imageIndex;\\n // Calculate the position in the texture grid\\n float texX = mod(atlasCoordIndex, imageAtlasCoordsTextureSize);\\n float texY = floor(atlasCoordIndex / imageAtlasCoordsTextureSize);\\n // Convert to texture coordinates (0.0 to 1.0)\\n vec2 atlasCoordTexCoord = (vec2(texX, texY) + 0.5) / imageAtlasCoordsTextureSize;\\n vec4 atlasCoords = texture(imageAtlasCoords, atlasCoordTexCoord);\\n imageAtlasUV = atlasCoords;\\n }\\n #endif\\n} \"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointSize;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform findPointsOnAreaSelectionUniforms {\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float ratio;\\n mat4 transformationMatrix;\\n vec2 selection0;\\n vec2 selection1;\\n float scalePointsOnZoom;\\n float maxPointSize;\\n} findPointsOnAreaSelection;\\n\\n#define sizeScale findPointsOnAreaSelection.sizeScale\\n#define spaceSize findPointsOnAreaSelection.spaceSize\\n#define screenSize findPointsOnAreaSelection.screenSize\\n#define ratio findPointsOnAreaSelection.ratio\\n#define transformationMatrix findPointsOnAreaSelection.transformationMatrix\\n#define selection0 findPointsOnAreaSelection.selection0\\n#define selection1 findPointsOnAreaSelection.selection1\\n#define scalePointsOnZoom findPointsOnAreaSelection.scalePointsOnZoom\\n#define maxPointSize findPointsOnAreaSelection.maxPointSize\\n#else\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform float ratio;\\nuniform mat3 transformationMatrix;\\nuniform vec2 selection0;\\nuniform vec2 selection1;\\nuniform float scalePointsOnZoom;\\nuniform float maxPointSize;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nfloat pointSizeF(float size) {\\n float pSize;\\n // Extract top-left element from mat4 (or use mat3 conversion)\\n #ifdef USE_UNIFORM_BUFFERS\\n float scale = transformationMatrix[0][0]; // mat4 first element\\n #else\\n float scale = transformationMatrix[0][0]; // mat3 first element\\n #endif\\n if (scalePointsOnZoom > 0.0) { \\n pSize = size * ratio * scale;\\n } else {\\n pSize = size * ratio * min(5.0, max(1.0, scale * 0.01));\\n }\\n return min(pSize, maxPointSize * ratio);\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n // Convert mat4 to mat3 for vec3 multiplication\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n\\n vec4 pSize = texture(pointSize, textureCoords);\\n float size = pSize.r * sizeScale;\\n\\n float left = 2.0 * (selection0.x - 0.5 * pointSizeF(size)) / screenSize.x - 1.0;\\n float right = 2.0 * (selection1.x + 0.5 * pointSizeF(size)) / screenSize.x - 1.0;\\n float top = 2.0 * (selection0.y - 0.5 * pointSizeF(size)) / screenSize.y - 1.0;\\n float bottom = 2.0 * (selection1.y + 0.5 * pointSizeF(size)) / screenSize.y - 1.0;\\n\\n fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g);\\n if (final.x >= left && final.x <= right && final.y >= top && final.y <= bottom) {\\n fragColor.r = 1.0;\\n }\\n}\\n\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D polygonPathTexture; // Texture containing polygon path points\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform findPointsOnPolygonSelectionUniforms {\\n float spaceSize;\\n vec2 screenSize;\\n mat4 transformationMatrix;\\n float polygonPathLength;\\n} findPointsOnPolygonSelection;\\n\\n#define spaceSize findPointsOnPolygonSelection.spaceSize\\n#define screenSize findPointsOnPolygonSelection.screenSize\\n#define transformationMatrix findPointsOnPolygonSelection.transformationMatrix\\n#define polygonPathLength int(findPointsOnPolygonSelection.polygonPathLength)\\n#else\\nuniform int polygonPathLength;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform mat3 transformationMatrix;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\n// Get a point from the polygon path texture at a specific index\\nvec2 getPolygonPoint(sampler2D pathTexture, int index, int pathLength) {\\n if (index >= pathLength) return vec2(0.0);\\n \\n // Calculate texture coordinates for the index\\n int textureSize = int(ceil(sqrt(float(pathLength))));\\n int x = index - (index / textureSize) * textureSize;\\n int y = index / textureSize;\\n \\n vec2 texCoord = (vec2(float(x), float(y)) + 0.5) / float(textureSize);\\n vec4 pathData = texture(pathTexture, texCoord);\\n \\n return pathData.xy;\\n}\\n\\n// Point-in-polygon algorithm using ray casting\\nbool pointInPolygon(vec2 point, sampler2D pathTexture, int pathLength) {\\n bool inside = false;\\n \\n for (int i = 0; i < 2048; i++) {\\n if (i >= pathLength) break;\\n \\n int j = int(mod(float(i + 1), float(pathLength)));\\n \\n vec2 pi = getPolygonPoint(pathTexture, i, pathLength);\\n vec2 pj = getPolygonPoint(pathTexture, j, pathLength);\\n \\n if (((pi.y > point.y) != (pj.y > point.y)) &&\\n (point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x)) {\\n inside = !inside;\\n }\\n }\\n \\n return inside;\\n}\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n // Convert mat4 to mat3 for vec3 multiplication\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n\\n // Convert to screen coordinates for polygon check\\n vec2 screenPos = (final.xy + 1.0) * screenSize / 2.0;\\n \\n fragColor = vec4(0.0, 0.0, pointPosition.r, pointPosition.g);\\n \\n // Check if point center is inside the polygon\\n if (pointInPolygon(screenPos, polygonPathTexture, polygonPathLength)) {\\n fragColor.r = 1.0;\\n }\\n} \"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawHighlightedUniforms {\\n float size;\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float scalePointsOnZoom;\\n float pointIndex;\\n float maxPointSize;\\n vec4 color;\\n float universalPointOpacity;\\n float greyoutOpacity;\\n float isDarkenGreyout;\\n vec4 backgroundColor;\\n vec4 greyoutColor;\\n float width;\\n} drawHighlighted;\\n\\n#define width drawHighlighted.width\\n#else\\nuniform float width;\\n#endif\\n\\nin vec2 vertexPosition;\\nin float pointOpacity;\\nin vec3 rgbColor;\\n\\nout vec4 fragColor;\\n\\nconst float smoothing = 1.05;\\n\\nvoid main () {\\n float r = dot(vertexPosition, vertexPosition);\\n float opacity = smoothstep(r, r * smoothing, 1.0);\\n float stroke = smoothstep(width, width * smoothing, r);\\n fragColor = vec4(rgbColor, opacity * stroke * pointOpacity);\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 vertexCoord;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatusTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform drawHighlightedUniforms {\\n float size;\\n mat4 transformationMatrix;\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float scalePointsOnZoom;\\n float pointIndex;\\n float maxPointSize;\\n vec4 color;\\n float universalPointOpacity;\\n float greyoutOpacity;\\n float isDarkenGreyout;\\n vec4 backgroundColor;\\n vec4 greyoutColor;\\n float width;\\n} drawHighlighted;\\n\\n#define size drawHighlighted.size\\n#define transformationMatrix drawHighlighted.transformationMatrix\\n#define pointsTextureSize drawHighlighted.pointsTextureSize\\n#define sizeScale drawHighlighted.sizeScale\\n#define spaceSize drawHighlighted.spaceSize\\n#define screenSize drawHighlighted.screenSize\\n#define scalePointsOnZoom drawHighlighted.scalePointsOnZoom\\n#define pointIndex drawHighlighted.pointIndex\\n#define maxPointSize drawHighlighted.maxPointSize\\n#define color drawHighlighted.color\\n#define universalPointOpacity drawHighlighted.universalPointOpacity\\n#define greyoutOpacity drawHighlighted.greyoutOpacity\\n#define isDarkenGreyout drawHighlighted.isDarkenGreyout\\n#define backgroundColor drawHighlighted.backgroundColor\\n#define greyoutColor drawHighlighted.greyoutColor\\n#else\\nuniform float size;\\nuniform mat3 transformationMatrix;\\nuniform float pointsTextureSize;\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform float scalePointsOnZoom;\\nuniform float pointIndex;\\nuniform float maxPointSize;\\nuniform vec4 color;\\nuniform float universalPointOpacity;\\nuniform float greyoutOpacity;\\nuniform float isDarkenGreyout;\\nuniform vec4 backgroundColor;\\nuniform vec4 greyoutColor;\\nuniform float width;\\n#endif\\nout vec2 vertexPosition;\\nout float pointOpacity;\\nout vec3 rgbColor;\\n\\nfloat calculatePointSize(float pointSize) {\\n float pSize;\\n\\n if (scalePointsOnZoom > 0.0) { \\n pSize = pointSize * transformationMatrix[0][0];\\n } else {\\n pSize = pointSize * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n\\n return min(pSize, maxPointSize);\\n}\\n\\nconst float relativeRingRadius = 1.3;\\n\\nvoid main () {\\n vertexPosition = vertexCoord;\\n\\n vec2 textureCoordinates = vec2(mod(pointIndex, pointsTextureSize), floor(pointIndex / pointsTextureSize)) + 0.5;\\n vec4 pointPosition = texture(positionsTexture, textureCoordinates / pointsTextureSize);\\n\\n rgbColor = color.rgb;\\n pointOpacity = color.a * universalPointOpacity;\\n vec4 greyoutStatus = texture(pointGreyoutStatusTexture, textureCoordinates / pointsTextureSize);\\n if (greyoutStatus.r > 0.0) {\\n if (greyoutColor[0] != -1.0) {\\n rgbColor = greyoutColor.rgb;\\n pointOpacity = greyoutColor.a;\\n } else {\\n // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout\\n float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n rgbColor = mix(rgbColor, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #else\\n if (isDarkenGreyout > 0.0) {\\n // Darken the color\\n rgbColor = mix(rgbColor, vec3(0.2), blendFactor);\\n } else {\\n // Lighten the color\\n rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);\\n }\\n #endif\\n }\\n\\n if (greyoutOpacity != -1.0) {\\n pointOpacity *= greyoutOpacity;\\n }\\n }\\n\\n // Calculate point radius\\n float pointSize = (calculatePointSize(size * sizeScale) * relativeRingRadius) / transformationMatrix[0][0];\\n float radius = pointSize * 0.5;\\n\\n // Calculate point position in screen space\\n vec2 a = pointPosition.xy;\\n vec2 b = pointPosition.xy + vec2(0.0, radius);\\n vec2 xBasis = b - a;\\n vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));\\n vec2 pointPositionInScreenSpace = a + xBasis * vertexCoord.x + yBasis * radius * vertexCoord.y;\\n\\n // Transform point position to normalized device coordinates\\n vec2 p = 2.0 * pointPositionInScreenSpace / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n \\n gl_Position = vec4(final.rg, 0, 1);\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgba;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n if (rgba.g <= 0.0) {\\n discard;\\n }\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 pointIndices;\\nin float size;\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D pointGreyoutStatus;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform findHoveredPointUniforms {\\n float pointsTextureSize;\\n float sizeScale;\\n float spaceSize;\\n vec2 screenSize;\\n float ratio;\\n mat4 transformationMatrix;\\n vec2 mousePosition;\\n float scalePointsOnZoom;\\n float maxPointSize;\\n float skipSelected;\\n float skipUnselected;\\n} findHoveredPoint;\\n\\n#define pointsTextureSize findHoveredPoint.pointsTextureSize\\n#define sizeScale findHoveredPoint.sizeScale\\n#define spaceSize findHoveredPoint.spaceSize\\n#define screenSize findHoveredPoint.screenSize\\n#define ratio findHoveredPoint.ratio\\n#define transformationMatrix findHoveredPoint.transformationMatrix\\n#define mousePosition findHoveredPoint.mousePosition\\n#define scalePointsOnZoom findHoveredPoint.scalePointsOnZoom\\n#define maxPointSize findHoveredPoint.maxPointSize\\n#define skipSelected findHoveredPoint.skipSelected\\n#define skipUnselected findHoveredPoint.skipUnselected\\n#else\\nuniform float pointsTextureSize;\\nuniform float sizeScale;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform float ratio;\\nuniform mat3 transformationMatrix;\\nuniform vec2 mousePosition;\\nuniform float scalePointsOnZoom;\\nuniform float maxPointSize;\\nuniform float skipSelected;\\nuniform float skipUnselected;\\n#endif\\n\\nout vec4 rgba;\\n\\nfloat calculatePointSize(float size) {\\n float pSize;\\n\\n if (scalePointsOnZoom > 0.0) { \\n pSize = size * ratio * transformationMatrix[0][0];\\n } else {\\n pSize = size * ratio * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));\\n }\\n\\n return min(pSize, maxPointSize * ratio);\\n}\\n\\nfloat euclideanDistance (float x1, float x2, float y1, float y2) {\\n return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\\n}\\n\\nvoid main() {\\n vec4 greyoutStatus = texture(pointGreyoutStatus, (pointIndices + 0.5) / pointsTextureSize);\\n float isSelected = (greyoutStatus.r == 0.0) ? 1.0 : 0.0;\\n\\n if (skipSelected > 0.0 && isSelected > 0.0) {\\n rgba = vec4(0.0);\\n gl_Position = vec4(0.5, 0.5, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n return;\\n }\\n if (skipUnselected > 0.0 && isSelected <= 0.0) {\\n rgba = vec4(0.0);\\n gl_Position = vec4(0.5, 0.5, 0.0, 1.0);\\n gl_PointSize = 1.0;\\n return;\\n }\\n\\n vec4 pointPosition = texture(positionsTexture, (pointIndices + 0.5) / pointsTextureSize);\\n vec2 point = pointPosition.rg;\\n\\n vec2 normalizedPosition = 2.0 * point / spaceSize - 1.0;\\n normalizedPosition *= spaceSize / screenSize;\\n \\n #ifdef USE_UNIFORM_BUFFERS\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 finalPosition = transformMat3 * vec3(normalizedPosition, 1);\\n #else\\n vec3 finalPosition = transformationMatrix * vec3(normalizedPosition, 1);\\n #endif\\n\\n float pointRadius = 0.5 * calculatePointSize(size * sizeScale);\\n vec2 pointScreenPosition = (finalPosition.xy + 1.0) * screenSize / 2.0;\\n \\n rgba = vec4(0.0);\\n gl_Position = vec4(0.5, 0.5, 0.0, 1.0);\\n \\n if (euclideanDistance(pointScreenPosition.x, mousePosition.x, pointScreenPosition.y, mousePosition.y) < pointRadius / ratio) {\\n float index = pointIndices.g * pointsTextureSize + pointIndices.r;\\n rgba = vec4(index, size, pointPosition.xy);\\n gl_Position = vec4(-0.5, -0.5, 0.0, 1.0);\\n }\\n\\n gl_PointSize = 1.0;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec4 rgba;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n fragColor = rgba;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nin vec2 pointIndices;\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform fillSampledPointsUniforms {\\n float pointsTextureSize;\\n mat4 transformationMatrix;\\n float spaceSize;\\n vec2 screenSize;\\n} fillSampledPoints;\\n\\n#define pointsTextureSize fillSampledPoints.pointsTextureSize\\n#define transformationMatrix fillSampledPoints.transformationMatrix\\n#define spaceSize fillSampledPoints.spaceSize\\n#define screenSize fillSampledPoints.screenSize\\n#else\\nuniform float pointsTextureSize;\\nuniform float spaceSize;\\nuniform vec2 screenSize;\\nuniform mat3 transformationMatrix;\\n#endif\\n\\nout vec4 rgba;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, (pointIndices + 0.5) / pointsTextureSize);\\n vec2 p = 2.0 * pointPosition.rg / spaceSize - 1.0;\\n p *= spaceSize / screenSize;\\n #ifdef USE_UNIFORM_BUFFERS\\n // Convert mat4 to mat3 for vec3 multiplication\\n mat3 transformMat3 = mat3(transformationMatrix);\\n vec3 final = transformMat3 * vec3(p, 1);\\n #else\\n vec3 final = transformationMatrix * vec3(p, 1);\\n #endif\\n\\n vec2 pointScreenPosition = (final.xy + 1.0) * screenSize / 2.0;\\n float index = pointIndices.g * pointsTextureSize + pointIndices.r;\\n rgba = vec4(index, 1.0, pointPosition.xy);\\n float i = (pointScreenPosition.x + 0.5) / screenSize.x;\\n float j = (pointScreenPosition.y + 0.5) / screenSize.y;\\n gl_Position = vec4(2.0 * vec2(i, j) - 1.0, 0.0, 1.0);\\n\\n gl_PointSize = 1.0;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D velocity;\\nuniform sampler2D pinnedStatusTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform updatePositionUniforms {\\n float friction;\\n float spaceSize;\\n} updatePosition;\\n\\n#define friction updatePosition.friction\\n#define spaceSize updatePosition.spaceSize\\n#else\\nuniform float friction;\\nuniform float spaceSize;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n vec4 pointVelocity = texture(velocity, textureCoords);\\n\\n // Check if point is pinned\\n // pinnedStatusTexture has the same size and layout as positionsTexture\\n // Each pixel corresponds to a point: red channel > 0.5 means the point is pinned\\n vec4 pinnedStatus = texture(pinnedStatusTexture, textureCoords);\\n \\n // If pinned, don't update position\\n if (pinnedStatus.r > 0.5) {\\n fragColor = pointPosition;\\n return;\\n }\\n\\n // Friction\\n pointVelocity.rg *= friction;\\n\\n pointPosition.rg += pointVelocity.rg;\\n\\n pointPosition.r = clamp(pointPosition.r, 0.0, spaceSize);\\n pointPosition.g = clamp(pointPosition.g, 0.0, spaceSize);\\n \\n fragColor = pointPosition;\\n}\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\nuniform sampler2D trackedIndices;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform trackPointsUniforms {\\n float pointsTextureSize;\\n} trackPoints;\\n\\n#define pointsTextureSize trackPoints.pointsTextureSize\\n#else\\nuniform float pointsTextureSize;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 trackedPointIndices = texture(trackedIndices, textureCoords);\\n if (trackedPointIndices.r < 0.0) discard;\\n vec4 pointPosition = texture(positionsTexture, (trackedPointIndices.rg + 0.5) / pointsTextureSize);\\n\\n fragColor = vec4(pointPosition.rg, 1.0, 1.0);\\n}\\n\\n\"","export default \"#version 300 es\\n#ifdef GL_ES\\nprecision highp float;\\n#endif\\n\\nuniform sampler2D positionsTexture;\\n\\n#ifdef USE_UNIFORM_BUFFERS\\nlayout(std140) uniform dragPointUniforms {\\n vec2 mousePos;\\n float index;\\n} dragPoint;\\n\\n#define mousePos dragPoint.mousePos\\n#define index dragPoint.index\\n#else\\nuniform vec2 mousePos;\\nuniform float index;\\n#endif\\n\\nin vec2 textureCoords;\\n\\nout vec4 fragColor;\\n\\nvoid main() {\\n vec4 pointPosition = texture(positionsTexture, textureCoords);\\n\\n // Check if a point is being dragged\\n if (index >= 0.0 && index == pointPosition.b) {\\n pointPosition.rg = mousePos.rg;\\n }\\n\\n fragColor = pointPosition;\\n}\"","/**\n * Creates a texture atlas from an array of ImageData objects.\n *\n * A texture atlas is a single large texture that contains multiple smaller images.\n * This allows efficient rendering by reducing the number of texture bindings needed.\n *\n * The atlas uses a grid layout where each image gets a square region sized to\n * accommodate the largest image dimension. Images are placed left-to-right, top-to-bottom.\n *\n * @param imageDataArray - Array of ImageData objects to pack into the atlas\n * @param webglMaxTextureSize - WebGL maximum texture size limit (default: 16384)\n * @returns Atlas data object containing:\n * - atlasData: RGBA pixel data as Uint8Array\n * - atlasSize: Total atlas texture size in pixels\n * - atlasCoords: UV coordinates for each image as Float32Array\n * - atlasCoordsSize: Grid size (number of rows/columns)\n * Returns null if creation fails or no valid images provided\n */\nexport function createAtlasDataFromImageData (\n imageDataArray: ImageData[],\n webglMaxTextureSize = 16384\n): {\n atlasData: Uint8Array;\n atlasSize: number;\n atlasCoords: Float32Array;\n atlasCoordsSize: number;\n} | null {\n // Step 1: Validate input - ensure we have images to process\n if (!imageDataArray?.length) {\n return null\n }\n\n // Step 2: Find the maximum dimension across all images\n // The max dimension determines the size of each grid cell in the atlas\n let maxDimension = 0\n for (const imageData of imageDataArray) {\n const dimension = Math.max(imageData.width, imageData.height)\n if (dimension > maxDimension) {\n maxDimension = dimension\n }\n }\n\n // Step 3: Validate that we found valid image dimensions\n if (maxDimension === 0) {\n console.warn('Invalid image dimensions: all images have zero width or height')\n return null\n }\n\n const originalMaxDimension = maxDimension\n\n // Step 4: Calculate optimal atlas grid size\n const atlasCoordsSize = Math.ceil(Math.sqrt(imageDataArray.length))\n let atlasSize = atlasCoordsSize * maxDimension\n\n // Step 5: Apply WebGL size limit scaling if necessary\n let scalingFactor = 1.0\n\n if (atlasSize > webglMaxTextureSize) {\n // Calculate required scale to fit within WebGL limits\n scalingFactor = webglMaxTextureSize / atlasSize\n\n // Apply scaling to both the individual image dimensions and atlas size\n maxDimension = Math.max(1, Math.floor(maxDimension * scalingFactor))\n atlasSize = Math.max(1, Math.floor(atlasSize * scalingFactor))\n\n console.warn(\n '🖼️ Atlas scaling required: Original size ' +\n `${(originalMaxDimension * atlasCoordsSize).toLocaleString()}px exceeds WebGL limit ` +\n `${webglMaxTextureSize.toLocaleString()}px. Scaling down to ${atlasSize.toLocaleString()}px ` +\n `(${Math.round(scalingFactor * 100)}% of original quality)`\n )\n }\n\n // Step 6: Create buffers for atlas data\n const atlasData = new Uint8Array(atlasSize * atlasSize * 4).fill(0)\n const atlasCoords = new Float32Array(atlasCoordsSize * atlasCoordsSize * 4).fill(-1)\n\n // Step 7: Pack each image into the atlas grid\n for (const [index, imageData] of imageDataArray.entries()) {\n const originalWidth = imageData.width\n const originalHeight = imageData.height\n if (originalWidth === 0 || originalHeight === 0) {\n // leave coords at -1 for this index and continue\n continue\n }\n\n // Calculate individual scale for this image based on maxDimension\n // This ensures each image fits optimally within its grid cell\n const individualScale = Math.min(1.0, maxDimension / Math.max(originalWidth, originalHeight))\n\n const scaledWidth = Math.floor(originalWidth * individualScale)\n const scaledHeight = Math.floor(originalHeight * individualScale)\n\n // Calculate grid position (row, column) for this image\n const row = Math.floor(index / atlasCoordsSize)\n const col = index % atlasCoordsSize\n\n // Calculate pixel position in the atlas texture\n const atlasX = col * maxDimension\n const atlasY = row * maxDimension\n\n // Calculate and store UV coordinates for this image\n atlasCoords[index * 4] = atlasX / atlasSize // minU\n atlasCoords[index * 4 + 1] = atlasY / atlasSize // minV\n atlasCoords[index * 4 + 2] = (atlasX + scaledWidth) / atlasSize // maxU\n atlasCoords[index * 4 + 3] = (atlasY + scaledHeight) / atlasSize // maxV\n\n // Copy image pixel data into the atlas texture\n for (let y = 0; y < scaledHeight; y++) {\n for (let x = 0; x < scaledWidth; x++) {\n // Calculate source pixel coordinates (with scaling)\n const srcX = Math.floor(x * (originalWidth / scaledWidth))\n const srcY = Math.floor(y * (originalHeight / scaledHeight))\n\n // Calculate source pixel index in the original image\n const srcIndex = (srcY * originalWidth + srcX) * 4\n\n // Calculate target pixel index in the atlas texture\n const atlasIndex = ((atlasY + y) * atlasSize + (atlasX + x)) * 4\n\n // Copy RGBA values from source to atlas\n atlasData[atlasIndex] = imageData.data[srcIndex] ?? 0 // Red channel\n atlasData[atlasIndex + 1] = imageData.data[srcIndex + 1] ?? 0 // Green channel\n atlasData[atlasIndex + 2] = imageData.data[srcIndex + 2] ?? 0 // Blue channel\n atlasData[atlasIndex + 3] = imageData.data[srcIndex + 3] ?? 255 // Alpha channel\n }\n }\n }\n\n // Return the complete atlas data\n return {\n atlasData,\n atlasSize,\n atlasCoords,\n atlasCoordsSize,\n }\n}\n","import { Framebuffer, Buffer, Texture, UniformStore, RenderPass } from '@luma.gl/core'\nimport { Model } from '@luma.gl/engine'\n// import { scaleLinear } from 'd3-scale'\n// import { extent } from 'd3-array'\nimport { CoreModule } from '@/graph/modules/core-module'\nimport type { Mat4Array } from '@/graph/modules/Store'\nimport { defaultConfigValues } from '@/graph/variables'\nimport drawPointsFrag from '@/graph/modules/Points/draw-points.frag?raw'\nimport drawPointsVert from '@/graph/modules/Points/draw-points.vert?raw'\nimport findPointsOnAreaSelectionFrag from '@/graph/modules/Points/find-points-on-area-selection.frag?raw'\nimport findPointsOnPolygonSelectionFrag from '@/graph/modules/Points/find-points-on-polygon-selection.frag?raw'\nimport drawHighlightedFrag from '@/graph/modules/Points/draw-highlighted.frag?raw'\nimport drawHighlightedVert from '@/graph/modules/Points/draw-highlighted.vert?raw'\nimport findHoveredPointFrag from '@/graph/modules/Points/find-hovered-point.frag?raw'\nimport findHoveredPointVert from '@/graph/modules/Points/find-hovered-point.vert?raw'\nimport fillGridWithSampledPointsFrag from '@/graph/modules/Points/fill-sampled-points.frag?raw'\nimport fillGridWithSampledPointsVert from '@/graph/modules/Points/fill-sampled-points.vert?raw'\nimport updatePositionFrag from '@/graph/modules/Points/update-position.frag?raw'\nimport { createIndexesForBuffer } from '@/graph/modules/Shared/buffer'\nimport { getBytesPerRow } from '@/graph/modules/Shared/texture-utils'\nimport trackPositionsFrag from '@/graph/modules/Points/track-positions.frag?raw'\nimport dragPointFrag from '@/graph/modules/Points/drag-point.frag?raw'\nimport updateVert from '@/graph/modules/Shared/quad.vert?raw'\nimport { readPixels } from '@/graph/helper'\nimport { ensureVec2, ensureVec4 } from '@/graph/modules/Shared/uniform-utils'\nimport { createAtlasDataFromImageData } from '@/graph/modules/Points/atlas-utils'\n\nexport class Points extends CoreModule {\n public currentPositionFbo: Framebuffer | undefined\n public previousPositionFbo: Framebuffer | undefined\n public velocityFbo: Framebuffer | undefined\n public selectedFbo: Framebuffer | undefined\n public hoveredFbo: Framebuffer | undefined\n public scaleX: ((x: number) => number) | undefined\n public scaleY: ((y: number) => number) | undefined\n public shouldSkipRescale: boolean | undefined\n public imageAtlasTexture: Texture | undefined\n public imageCount = 0\n // Add texture properties for position data (public for Clusters module access)\n public currentPositionTexture: Texture | undefined\n public previousPositionTexture: Texture | undefined\n public velocityTexture: Texture | undefined\n // Add texture property for greyout status (public for Lines module access)\n public greyoutStatusTexture: Texture | undefined\n private colorBuffer: Buffer | undefined\n private sizeBuffer: Buffer | undefined\n private shapeBuffer: Buffer | undefined\n private imageIndicesBuffer: Buffer | undefined\n private imageSizesBuffer: Buffer | undefined\n private imageAtlasCoordsTexture: Texture | undefined\n private imageAtlasCoordsTextureSize: number | undefined\n private trackedPositionsFbo: Framebuffer | undefined\n private sampledPointsFbo: Framebuffer | undefined\n private trackedPositions: Map<number, [number, number]> | undefined\n private isPositionsUpToDate = false\n private drawCommand: Model | undefined\n private drawHighlightedCommand: Model | undefined\n private updatePositionCommand: Model | undefined\n private dragPointCommand: Model | undefined\n private findPointsOnAreaSelectionCommand: Model | undefined\n private findPointsOnPolygonSelectionCommand: Model | undefined\n private findHoveredPointCommand: Model | undefined\n private fillSampledPointsFboCommand: Model | undefined\n private trackPointsCommand: Model | undefined\n // Vertex buffers for quad rendering (Model doesn't destroy them automatically)\n private updatePositionVertexCoordBuffer: Buffer | undefined\n private dragPointVertexCoordBuffer: Buffer | undefined\n private findPointsOnAreaSelectionVertexCoordBuffer: Buffer | undefined\n private findPointsOnPolygonSelectionVertexCoordBuffer: Buffer | undefined\n private drawHighlightedVertexCoordBuffer: Buffer | undefined\n private trackPointsVertexCoordBuffer: Buffer | undefined\n private trackedIndices: number[] | undefined\n private selectedTexture: Texture | undefined\n private pinnedStatusTexture: Texture | undefined\n private sizeTexture: Texture | undefined\n private trackedIndicesTexture: Texture | undefined\n private polygonPathTexture: Texture | undefined\n private polygonPathLength = 0\n private drawPointIndices: Buffer | undefined\n private hoveredPointIndices: Buffer | undefined\n private sampledPointIndices: Buffer | undefined\n\n // Uniform stores for scalar uniforms\n private updatePositionUniformStore: UniformStore<{\n updatePositionUniforms: {\n friction: number;\n spaceSize: number;\n };\n }> | undefined\n\n private dragPointUniformStore: UniformStore<{\n dragPointUniforms: {\n mousePos: [number, number];\n index: number;\n };\n }> | undefined\n\n private drawUniformStore: UniformStore<{\n drawVertexUniforms: {\n ratio: number;\n sizeScale: number;\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n greyoutColor: [number, number, number, number];\n backgroundColor: [number, number, number, number];\n scalePointsOnZoom: number;\n maxPointSize: number;\n isDarkenGreyout: number;\n skipSelected: number;\n skipUnselected: number;\n hasImages: number;\n imageCount: number;\n imageAtlasCoordsTextureSize: number;\n };\n drawFragmentUniforms: {\n greyoutOpacity: number;\n pointOpacity: number;\n isDarkenGreyout: number;\n backgroundColor: [number, number, number, number];\n };\n }> | undefined\n\n private findPointsOnAreaSelectionUniformStore: UniformStore<{\n findPointsOnAreaSelectionUniforms: {\n spaceSize: number;\n screenSize: [number, number];\n sizeScale: number;\n transformationMatrix: Mat4Array;\n ratio: number;\n selection0: [number, number];\n selection1: [number, number];\n scalePointsOnZoom: number;\n maxPointSize: number;\n };\n }> | undefined\n\n private findPointsOnPolygonSelectionUniformStore: UniformStore<{\n findPointsOnPolygonSelectionUniforms: {\n spaceSize: number;\n screenSize: [number, number];\n transformationMatrix: Mat4Array;\n polygonPathLength: number;\n };\n }> | undefined\n\n private findHoveredPointUniformStore: UniformStore<{\n findHoveredPointUniforms: {\n ratio: number;\n sizeScale: number;\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n scalePointsOnZoom: number;\n mousePosition: [number, number];\n maxPointSize: number;\n skipSelected: number;\n skipUnselected: number;\n };\n }> | undefined\n\n private fillSampledPointsUniformStore: UniformStore<{\n fillSampledPointsUniforms: {\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n };\n }> | undefined\n\n private drawHighlightedUniformStore: UniformStore<{\n drawHighlightedUniforms: {\n color: [number, number, number, number];\n width: number;\n pointIndex: number;\n size: number;\n sizeScale: number;\n pointsTextureSize: number;\n transformationMatrix: Mat4Array;\n spaceSize: number;\n screenSize: [number, number];\n scalePointsOnZoom: number; // f32 in shader, not boolean\n maxPointSize: number;\n universalPointOpacity: number;\n greyoutOpacity: number;\n isDarkenGreyout: number; // f32 in shader, not boolean\n backgroundColor: [number, number, number, number];\n greyoutColor: [number, number, number, number];\n };\n }> | undefined\n\n private trackPointsUniformStore: UniformStore<{\n trackPointsUniforms: {\n pointsTextureSize: number;\n };\n }> | undefined\n\n public updatePositions (): void {\n const { device, store, data, config: { rescalePositions, enableSimulation } } = this\n\n const { pointsTextureSize } = store\n if (!pointsTextureSize || !data.pointPositions || data.pointsNumber === undefined) return\n\n // Create initial state array with exact size needed for RGBA32Float texture\n // Ensure it's a new contiguous buffer (not a view) with the exact size\n const textureDataSize = pointsTextureSize * pointsTextureSize * 4\n const initialState = new Float32Array(textureDataSize)\n\n const expectedBytes = pointsTextureSize * pointsTextureSize * 4 * 4 // width * height * 4 components * 4 bytes\n const actualBytes = initialState.byteLength\n if (actualBytes !== expectedBytes) {\n console.error('Texture data size mismatch:', {\n pointsTextureSize,\n expectedBytes,\n actualBytes,\n textureDataSize,\n dataLength: initialState.length,\n })\n }\n\n let shouldRescale = rescalePositions\n // If rescalePositions isn't specified in config and simulation is disabled, default to true\n if (rescalePositions === undefined && !enableSimulation) shouldRescale = true\n // Skip rescaling if `shouldSkipRescale` flag is set (allowing one-time skip of rescaling)\n // Temporary flag is used to skip rescaling when change point positions or adding new points by function `setPointPositions`\n // This flag overrides any other rescaling settings\n if (this.shouldSkipRescale) shouldRescale = false\n\n if (shouldRescale) {\n this.rescaleInitialNodePositions()\n } else if (!this.shouldSkipRescale) {\n // Only reset scale functions if not temporarily skipping rescale\n this.scaleX = undefined\n this.scaleY = undefined\n }\n\n // Reset temporary flag\n this.shouldSkipRescale = undefined\n\n for (let i = 0; i < data.pointsNumber; ++i) {\n initialState[i * 4 + 0] = data.pointPositions[i * 2 + 0] as number\n initialState[i * 4 + 1] = data.pointPositions[i * 2 + 1] as number\n initialState[i * 4 + 2] = i\n }\n\n // Create currentPositionTexture and framebuffer\n if (!this.currentPositionTexture || this.currentPositionTexture.width !== pointsTextureSize || this.currentPositionTexture.height !== pointsTextureSize) {\n if (this.currentPositionTexture && !this.currentPositionTexture.destroyed) {\n this.currentPositionTexture.destroy()\n }\n if (this.currentPositionFbo && !this.currentPositionFbo.destroyed) {\n this.currentPositionFbo.destroy()\n }\n this.currentPositionTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.currentPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.currentPositionFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.currentPositionTexture],\n })\n } else {\n this.currentPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Create previousPositionTexture and framebuffer\n if (!this.previousPositionTexture ||\n this.previousPositionTexture.width !== pointsTextureSize ||\n this.previousPositionTexture.height !== pointsTextureSize) {\n if (this.previousPositionTexture && !this.previousPositionTexture.destroyed) {\n this.previousPositionTexture.destroy()\n }\n if (this.previousPositionFbo && !this.previousPositionFbo.destroyed) {\n this.previousPositionFbo.destroy()\n }\n this.previousPositionTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.previousPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.previousPositionFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.previousPositionTexture],\n })\n } else {\n this.previousPositionTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n if (this.config.enableSimulation) {\n // Create velocityTexture and framebuffer\n const velocityData = new Float32Array(pointsTextureSize * pointsTextureSize * 4).fill(0)\n if (!this.velocityTexture || this.velocityTexture.width !== pointsTextureSize || this.velocityTexture.height !== pointsTextureSize) {\n if (this.velocityTexture && !this.velocityTexture.destroyed) {\n this.velocityTexture.destroy()\n }\n if (this.velocityFbo && !this.velocityFbo.destroyed) {\n this.velocityFbo.destroy()\n }\n this.velocityTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.velocityTexture.copyImageData({\n data: velocityData,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.velocityFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.velocityTexture],\n })\n } else {\n this.velocityTexture.copyImageData({\n data: velocityData,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n // Create selectedTexture and framebuffer\n if (!this.selectedTexture || this.selectedTexture.width !== pointsTextureSize || this.selectedTexture.height !== pointsTextureSize) {\n if (this.selectedTexture && !this.selectedTexture.destroyed) {\n this.selectedTexture.destroy()\n }\n if (this.selectedFbo && !this.selectedFbo.destroyed) {\n this.selectedFbo.destroy()\n }\n this.selectedTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.selectedTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n this.selectedFbo = device.createFramebuffer({\n width: pointsTextureSize,\n height: pointsTextureSize,\n colorAttachments: [this.selectedTexture],\n })\n } else {\n this.selectedTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n // Create hoveredFbo (2x2 for hover detection)\n this.hoveredFbo ||= device.createFramebuffer({\n width: 2,\n height: 2,\n colorAttachments: ['rgba32float'],\n })\n\n // Create buffers\n const indexData = createIndexesForBuffer(store.pointsTextureSize)\n const requiredByteLength = indexData.byteLength\n\n if (!this.drawPointIndices || this.drawPointIndices.byteLength !== requiredByteLength) {\n if (this.drawPointIndices && !this.drawPointIndices.destroyed) {\n this.drawPointIndices.destroy()\n }\n this.drawPointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.drawPointIndices.write(indexData)\n }\n\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n pointIndices: this.drawPointIndices,\n })\n }\n\n if (!this.hoveredPointIndices || this.hoveredPointIndices.byteLength !== requiredByteLength) {\n if (this.hoveredPointIndices && !this.hoveredPointIndices.destroyed) {\n this.hoveredPointIndices.destroy()\n }\n this.hoveredPointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.hoveredPointIndices.write(indexData)\n }\n\n if (!this.sampledPointIndices || this.sampledPointIndices.byteLength !== requiredByteLength) {\n if (this.sampledPointIndices && !this.sampledPointIndices.destroyed) {\n this.sampledPointIndices.destroy()\n }\n this.sampledPointIndices = device.createBuffer({\n data: indexData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.sampledPointIndices.write(indexData)\n }\n if (this.fillSampledPointsFboCommand) {\n this.fillSampledPointsFboCommand.setAttributes({\n pointIndices: this.sampledPointIndices,\n })\n }\n\n this.updateGreyoutStatus()\n this.updatePinnedStatus()\n this.updateSampledPointsGrid()\n\n this.trackPointsByIndices()\n }\n\n public initPrograms (): void {\n const { device, config, store, data } = this\n // Ensure textures are created before Model initialization\n if (!this.imageAtlasCoordsTexture || !this.imageAtlasTexture) {\n this.createAtlas()\n }\n // Ensure buffers exist before Model creation (Model needs attributes at creation time)\n if (!this.colorBuffer) this.updateColor()\n if (!this.sizeBuffer) this.updateSize()\n if (!this.shapeBuffer) this.updateShape()\n if (!this.imageIndicesBuffer) this.updateImageIndices()\n if (!this.imageSizesBuffer) this.updateImageSizes()\n if (!this.greyoutStatusTexture) this.updateGreyoutStatus()\n if (config.enableSimulation) {\n // Create vertex buffer for quad\n this.updatePositionVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for updatePosition uniforms\n this.updatePositionUniformStore ||= new UniformStore({\n updatePositionUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n friction: 'f32',\n spaceSize: 'f32',\n },\n defaultUniforms: {\n friction: config.simulationFriction ?? 0,\n spaceSize: store.adjustedSpaceSize ?? 0,\n },\n },\n })\n\n this.updatePositionCommand ||= new Model(device, {\n fs: updatePositionFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.updatePositionVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n updatePositionUniforms: this.updatePositionUniformStore.getManagedUniformBuffer(device, 'updatePositionUniforms'),\n // All texture bindings will be set dynamically in updatePosition() method\n },\n })\n }\n\n // Create vertex buffer for quad\n this.dragPointVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for dragPoint uniforms\n this.dragPointUniformStore ||= new UniformStore({\n dragPointUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n mousePos: 'vec2<f32>',\n index: 'f32',\n },\n defaultUniforms: {\n mousePos: ensureVec2(store.mousePosition, [0, 0]),\n index: store.hoveredPoint?.index ?? -1,\n },\n },\n })\n\n this.dragPointCommand ||= new Model(device, {\n fs: dragPointFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.dragPointVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n dragPointUniforms: this.dragPointUniformStore.getManagedUniformBuffer(device, 'dragPointUniforms'),\n // All texture bindings will be set dynamically in drag() method\n },\n })\n\n // Create UniformStore for draw uniforms\n this.drawUniformStore ||= new UniformStore({\n drawVertexUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n ratio: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n pointsTextureSize: 'f32',\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n greyoutColor: 'vec4<f32>',\n backgroundColor: 'vec4<f32>',\n scalePointsOnZoom: 'f32',\n maxPointSize: 'f32',\n isDarkenGreyout: 'f32',\n skipSelected: 'f32',\n skipUnselected: 'f32',\n hasImages: 'f32',\n imageCount: 'f32',\n imageAtlasCoordsTextureSize: 'f32',\n },\n defaultUniforms: {\n // Order MUST match uniformTypes and shader declaration\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: ((): Mat4Array => {\n const t = store.transform ?? [1, 0, 0, 0, 1, 0, 0, 0, 1]\n return [\n t[0], t[1], t[2], 0,\n t[3], t[4], t[5], 0,\n t[6], t[7], t[8], 0,\n 0, 0, 0, 1,\n ]\n })(),\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0, // Convert boolean to float\n maxPointSize: store.maxPointSize ?? 100,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n skipSelected: 0, // Default to 0 (false)\n skipUnselected: 0, // Default to 0 (false)\n hasImages: (this.imageCount > 0) ? 1 : 0, // Convert boolean to float\n imageCount: this.imageCount,\n imageAtlasCoordsTextureSize: this.imageAtlasCoordsTextureSize ?? 0,\n },\n },\n drawFragmentUniforms: {\n uniformTypes: {\n greyoutOpacity: 'f32',\n pointOpacity: 'f32',\n isDarkenGreyout: 'f32',\n backgroundColor: 'vec4<f32>',\n },\n defaultUniforms: {\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n pointOpacity: config.pointOpacity ?? 1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n },\n },\n })\n\n this.drawCommand ||= new Model(device, {\n fs: drawPointsFrag,\n vs: drawPointsVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...(this.drawPointIndices && { pointIndices: this.drawPointIndices }),\n ...(this.sizeBuffer && { size: this.sizeBuffer }),\n ...(this.colorBuffer && { color: this.colorBuffer }),\n ...(this.shapeBuffer && { shape: this.shapeBuffer }),\n ...(this.imageIndicesBuffer && { imageIndex: this.imageIndicesBuffer }),\n ...(this.imageSizesBuffer && { imageSize: this.imageSizesBuffer }),\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n { name: 'size', format: 'float32' },\n { name: 'color', format: 'float32x4' },\n { name: 'shape', format: 'float32' },\n { name: 'imageIndex', format: 'float32' },\n { name: 'imageSize', format: 'float32' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n drawVertexUniforms: this.drawUniformStore.getManagedUniformBuffer(device, 'drawVertexUniforms'),\n drawFragmentUniforms: this.drawUniformStore.getManagedUniformBuffer(device, 'drawFragmentUniforms'),\n // All texture bindings will be set dynamically in draw() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Create vertex buffer for quad\n this.findPointsOnAreaSelectionVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for findPointsOnAreaSelection uniforms\n this.findPointsOnAreaSelectionUniformStore ||= new UniformStore({\n findPointsOnAreaSelectionUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n ratio: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n selection0: 'vec2<f32>',\n selection1: 'vec2<f32>',\n scalePointsOnZoom: 'f32',\n maxPointSize: 'f32',\n },\n defaultUniforms: {\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: store.transformationMatrix4x4,\n selection0: ensureVec2(store.selectedArea?.[0], [0, 0]),\n selection1: ensureVec2(store.selectedArea?.[1], [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n },\n },\n })\n\n this.findPointsOnAreaSelectionCommand ||= new Model(device, {\n fs: findPointsOnAreaSelectionFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.findPointsOnAreaSelectionVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n findPointsOnAreaSelectionUniforms: this.findPointsOnAreaSelectionUniformStore.getManagedUniformBuffer(device, 'findPointsOnAreaSelectionUniforms'),\n // All texture bindings will be set dynamically in findPointsOnAreaSelection() method\n },\n })\n\n // Create vertex buffer for quad\n this.findPointsOnPolygonSelectionVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for findPointsOnPolygonSelection uniforms\n this.findPointsOnPolygonSelectionUniformStore ||= new UniformStore({\n findPointsOnPolygonSelectionUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n transformationMatrix: 'mat4x4<f32>',\n polygonPathLength: 'f32',\n },\n defaultUniforms: {\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n transformationMatrix: store.transformationMatrix4x4,\n polygonPathLength: this.polygonPathLength,\n },\n },\n })\n\n this.findPointsOnPolygonSelectionCommand ||= new Model(device, {\n fs: findPointsOnPolygonSelectionFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.findPointsOnPolygonSelectionVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n findPointsOnPolygonSelectionUniforms: this.findPointsOnPolygonSelectionUniformStore\n .getManagedUniformBuffer(device, 'findPointsOnPolygonSelectionUniforms'),\n // All texture bindings will be set dynamically in findPointsOnPolygonSelection() method\n },\n })\n\n // Create UniformStore for findHoveredPoint uniforms\n this.findHoveredPointUniformStore ||= new UniformStore({\n findHoveredPointUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n pointsTextureSize: 'f32',\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n ratio: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n mousePosition: 'vec2<f32>',\n scalePointsOnZoom: 'f32',\n maxPointSize: 'f32',\n skipSelected: 'f32',\n skipUnselected: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: store.transformationMatrix4x4,\n mousePosition: ensureVec2(store.screenMousePosition, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n maxPointSize: store.maxPointSize ?? 100,\n skipSelected: 0,\n skipUnselected: 0,\n },\n },\n })\n\n this.findHoveredPointCommand ||= new Model(device, {\n fs: findHoveredPointFrag,\n vs: findHoveredPointVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...(this.hoveredPointIndices && { pointIndices: this.hoveredPointIndices }),\n ...(this.sizeBuffer && { size: this.sizeBuffer }),\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n { name: 'size', format: 'float32' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n findHoveredPointUniforms: this.findHoveredPointUniformStore.getManagedUniformBuffer(device, 'findHoveredPointUniforms'),\n // All texture bindings will be set dynamically in findHoveredPoint() method\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n blend: false, // Disable blending - we want to overwrite, not blend\n },\n })\n\n // Create UniformStore for fillSampledPoints uniforms\n this.fillSampledPointsUniformStore ||= new UniformStore({\n fillSampledPointsUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n pointsTextureSize: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n transformationMatrix: store.transformationMatrix4x4,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n },\n },\n })\n\n this.fillSampledPointsFboCommand ||= new Model(device, {\n fs: fillGridWithSampledPointsFrag,\n vs: fillGridWithSampledPointsVert,\n topology: 'point-list',\n vertexCount: data.pointsNumber ?? 0,\n attributes: {\n ...(this.sampledPointIndices && { pointIndices: this.sampledPointIndices }),\n },\n bufferLayout: [\n { name: 'pointIndices', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n fillSampledPointsUniforms: this.fillSampledPointsUniformStore.getManagedUniformBuffer(device, 'fillSampledPointsUniforms'),\n // All texture bindings will be set dynamically in getSampledPointPositionsMap() and getSampledPoints() methods\n },\n parameters: {\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n this.drawHighlightedVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n this.drawHighlightedUniformStore ||= new UniformStore({\n drawHighlightedUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n // Vertex shader uniforms:\n size: 'f32',\n transformationMatrix: 'mat4x4<f32>',\n pointsTextureSize: 'f32',\n sizeScale: 'f32',\n spaceSize: 'f32',\n screenSize: 'vec2<f32>',\n scalePointsOnZoom: 'f32',\n pointIndex: 'f32',\n maxPointSize: 'f32',\n color: 'vec4<f32>',\n universalPointOpacity: 'f32',\n greyoutOpacity: 'f32',\n isDarkenGreyout: 'f32',\n backgroundColor: 'vec4<f32>',\n greyoutColor: 'vec4<f32>',\n // Fragment shader uniforms (width is in same block):\n width: 'f32',\n },\n defaultUniforms: {\n size: 1,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n pointIndex: -1,\n maxPointSize: store.maxPointSize ?? 100,\n color: [0, 0, 0, 1],\n universalPointOpacity: config.pointOpacity ?? 1,\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0,\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n width: 0.85,\n },\n },\n })\n\n this.drawHighlightedCommand ||= new Model(device, {\n fs: drawHighlightedFrag,\n vs: drawHighlightedVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.drawHighlightedVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n drawHighlightedUniforms: this.drawHighlightedUniformStore.getManagedUniformBuffer(device, 'drawHighlightedUniforms'),\n // All texture bindings will be set dynamically in draw() method\n },\n parameters: {\n blend: true,\n blendColorOperation: 'add',\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaOperation: 'add',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n depthWriteEnabled: false,\n depthCompare: 'always',\n },\n })\n\n // Create vertex buffer for quad\n this.trackPointsVertexCoordBuffer ||= device.createBuffer({\n data: new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n })\n\n // Create UniformStore for trackPoints uniforms\n this.trackPointsUniformStore ||= new UniformStore({\n trackPointsUniforms: {\n uniformTypes: {\n // Order MUST match shader declaration order (std140 layout)\n pointsTextureSize: 'f32',\n },\n defaultUniforms: {\n pointsTextureSize: store.pointsTextureSize ?? 0,\n },\n },\n })\n\n this.trackPointsCommand ||= new Model(device, {\n fs: trackPositionsFrag,\n vs: updateVert,\n topology: 'triangle-strip',\n vertexCount: 4,\n attributes: {\n vertexCoord: this.trackPointsVertexCoordBuffer,\n },\n bufferLayout: [\n { name: 'vertexCoord', format: 'float32x2' },\n ],\n defines: {\n USE_UNIFORM_BUFFERS: true,\n },\n bindings: {\n // Create uniform buffer binding\n // Update it later by calling uniformStore.setUniforms()\n trackPointsUniforms: this.trackPointsUniformStore.getManagedUniformBuffer(device, 'trackPointsUniforms'),\n // All texture bindings will be set dynamically in trackPoints() method\n },\n })\n }\n\n public updateColor (): void {\n const { device, store: { pointsTextureSize }, data } = this\n if (!pointsTextureSize) return\n\n const colorData = data.pointColors as Float32Array\n const requiredByteLength = colorData.byteLength\n\n if (!this.colorBuffer || this.colorBuffer.byteLength !== requiredByteLength) {\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = device.createBuffer({\n data: colorData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.colorBuffer.write(colorData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n color: this.colorBuffer,\n })\n }\n }\n\n public updateGreyoutStatus (): void {\n const { device, store: { selectedIndices, pointsTextureSize } } = this\n if (!pointsTextureSize) return\n\n // Greyout status: 0 - false, highlighted or normal point; 1 - true, greyout point\n const initialState = new Float32Array(pointsTextureSize * pointsTextureSize * 4)\n .fill(selectedIndices ? 1 : 0)\n\n if (selectedIndices) {\n for (const selectedIndex of selectedIndices) {\n initialState[selectedIndex * 4] = 0\n }\n }\n\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.width !== pointsTextureSize || this.greyoutStatusTexture.height !== pointsTextureSize) {\n if (this.greyoutStatusTexture && !this.greyoutStatusTexture.destroyed) {\n this.greyoutStatusTexture.destroy()\n }\n this.greyoutStatusTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.greyoutStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.greyoutStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public updatePinnedStatus (): void {\n const { device, store: { pointsTextureSize }, data } = this\n if (!pointsTextureSize) return\n\n // Pinned status: 0 - not pinned, 1 - pinned\n const initialState = new Float32Array(pointsTextureSize * pointsTextureSize * 4).fill(0)\n\n if (data.inputPinnedPoints && data.pointsNumber !== undefined) {\n for (const pinnedIndex of data.inputPinnedPoints) {\n if (pinnedIndex >= 0 && pinnedIndex < data.pointsNumber) {\n initialState[pinnedIndex * 4] = 1\n }\n }\n }\n\n if (!this.pinnedStatusTexture || this.pinnedStatusTexture.width !== pointsTextureSize || this.pinnedStatusTexture.height !== pointsTextureSize) {\n if (this.pinnedStatusTexture && !this.pinnedStatusTexture.destroyed) {\n this.pinnedStatusTexture.destroy()\n }\n this.pinnedStatusTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.pinnedStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.pinnedStatusTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public updateSize (): void {\n const { device, store: { pointsTextureSize }, data } = this\n if (!pointsTextureSize || data.pointsNumber === undefined || data.pointSizes === undefined) return\n\n const sizeData = data.pointSizes\n const requiredByteLength = sizeData.byteLength\n\n if (!this.sizeBuffer || this.sizeBuffer.byteLength !== requiredByteLength) {\n if (this.sizeBuffer && !this.sizeBuffer.destroyed) {\n this.sizeBuffer.destroy()\n }\n this.sizeBuffer = device.createBuffer({\n data: sizeData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.sizeBuffer.write(sizeData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n size: this.sizeBuffer,\n })\n }\n\n const initialState = new Float32Array(pointsTextureSize * pointsTextureSize * 4)\n for (let i = 0; i < data.pointsNumber; i++) {\n initialState[i * 4] = data.pointSizes[i] as number\n }\n\n if (!this.sizeTexture || this.sizeTexture.width !== pointsTextureSize || this.sizeTexture.height !== pointsTextureSize) {\n if (this.sizeTexture && !this.sizeTexture.destroyed) {\n this.sizeTexture.destroy()\n }\n this.sizeTexture = device.createTexture({\n width: pointsTextureSize,\n height: pointsTextureSize,\n format: 'rgba32float',\n })\n this.sizeTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.sizeTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', pointsTextureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public updateShape (): void {\n const { device, data } = this\n if (data.pointsNumber === undefined || data.pointShapes === undefined) return\n\n const shapeData = data.pointShapes\n const requiredByteLength = shapeData.byteLength\n\n if (!this.shapeBuffer || this.shapeBuffer.byteLength !== requiredByteLength) {\n if (this.shapeBuffer && !this.shapeBuffer.destroyed) {\n this.shapeBuffer.destroy()\n }\n this.shapeBuffer = device.createBuffer({\n data: shapeData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.shapeBuffer.write(shapeData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n shape: this.shapeBuffer,\n })\n }\n }\n\n public updateImageIndices (): void {\n const { device, data } = this\n if (data.pointsNumber === undefined || data.pointImageIndices === undefined) return\n\n const imageIndicesData = data.pointImageIndices\n const requiredByteLength = imageIndicesData.byteLength\n\n if (!this.imageIndicesBuffer || this.imageIndicesBuffer.byteLength !== requiredByteLength) {\n if (this.imageIndicesBuffer && !this.imageIndicesBuffer.destroyed) {\n this.imageIndicesBuffer.destroy()\n }\n this.imageIndicesBuffer = device.createBuffer({\n data: imageIndicesData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.imageIndicesBuffer.write(imageIndicesData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n imageIndex: this.imageIndicesBuffer,\n })\n }\n }\n\n public updateImageSizes (): void {\n const { device, data } = this\n if (data.pointsNumber === undefined || data.pointImageSizes === undefined) return\n\n const imageSizesData = data.pointImageSizes\n const requiredByteLength = imageSizesData.byteLength\n\n if (!this.imageSizesBuffer || this.imageSizesBuffer.byteLength !== requiredByteLength) {\n if (this.imageSizesBuffer && !this.imageSizesBuffer.destroyed) {\n this.imageSizesBuffer.destroy()\n }\n this.imageSizesBuffer = device.createBuffer({\n data: imageSizesData,\n usage: Buffer.VERTEX | Buffer.COPY_DST,\n })\n } else {\n this.imageSizesBuffer.write(imageSizesData)\n }\n if (this.drawCommand) {\n this.drawCommand.setAttributes({\n imageSize: this.imageSizesBuffer,\n })\n }\n }\n\n public createAtlas (): void {\n const { device, data, store } = this\n\n if (!data.inputImageData?.length) {\n this.imageCount = 0\n this.imageAtlasCoordsTextureSize = 0\n // Create dummy textures so bindings are always available\n this.imageAtlasCoordsTexture ||= device.createTexture({\n data: new Float32Array(4).fill(0),\n width: 1,\n height: 1,\n format: 'rgba32float',\n })\n\n this.imageAtlasTexture ||= device.createTexture({\n data: new Uint8Array(4).fill(0),\n width: 1,\n height: 1,\n format: 'rgba8unorm',\n })\n\n return\n }\n\n const atlasResult = createAtlasDataFromImageData(data.inputImageData, store.webglMaxTextureSize)\n if (!atlasResult) {\n console.warn('Failed to create atlas from image data')\n return\n }\n\n this.imageCount = data.inputImageData.length\n const { atlasData, atlasSize, atlasCoords, atlasCoordsSize } = atlasResult\n this.imageAtlasCoordsTextureSize = atlasCoordsSize\n\n // Recreate atlas texture to avoid row-stride/format issues\n if (this.imageAtlasTexture && !this.imageAtlasTexture.destroyed) {\n this.imageAtlasTexture.destroy()\n }\n this.imageAtlasTexture = device.createTexture({\n width: atlasSize,\n height: atlasSize,\n format: 'rgba8unorm',\n })\n this.imageAtlasTexture.copyImageData({\n data: atlasData,\n bytesPerRow: getBytesPerRow('rgba8unorm', atlasSize),\n rowsPerImage: atlasSize,\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n\n // Recreate coords texture\n if (this.imageAtlasCoordsTexture && !this.imageAtlasCoordsTexture.destroyed) {\n this.imageAtlasCoordsTexture.destroy()\n }\n this.imageAtlasCoordsTexture = device.createTexture({\n width: atlasCoordsSize,\n height: atlasCoordsSize,\n format: 'rgba32float',\n })\n this.imageAtlasCoordsTexture.copyImageData({\n data: atlasCoords,\n bytesPerRow: getBytesPerRow('rgba32float', atlasCoordsSize),\n rowsPerImage: atlasCoordsSize,\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n public updateSampledPointsGrid (): void {\n const { store: { screenSize }, config: { pointSamplingDistance }, device } = this\n let dist = pointSamplingDistance ?? Math.min(...screenSize) / 2\n if (dist === 0) dist = defaultConfigValues.pointSamplingDistance\n const w = Math.ceil(screenSize[0] / dist)\n const h = Math.ceil(screenSize[1] / dist)\n\n if (!this.sampledPointsFbo || this.sampledPointsFbo.width !== w || this.sampledPointsFbo.height !== h) {\n if (this.sampledPointsFbo && !this.sampledPointsFbo.destroyed) {\n this.sampledPointsFbo.destroy()\n }\n this.sampledPointsFbo = device.createFramebuffer({\n width: w,\n height: h,\n colorAttachments: ['rgba32float'],\n })\n }\n }\n\n public trackPoints (): void {\n if (!this.trackedIndices?.length || !this.trackPointsCommand || !this.trackPointsUniformStore ||\n !this.trackedPositionsFbo || this.trackedPositionsFbo.destroyed) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.trackedIndicesTexture || this.trackedIndicesTexture.destroyed) return\n\n this.trackPointsUniformStore.setUniforms({\n trackPointsUniforms: {\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.trackPointsCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n trackedIndices: this.trackedIndicesTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.trackedPositionsFbo,\n })\n this.trackPointsCommand.draw(renderPass)\n renderPass.end()\n }\n\n public draw (renderPass: RenderPass): void {\n const { data, config, store } = this\n if (!this.colorBuffer) this.updateColor()\n if (!this.sizeBuffer) this.updateSize()\n if (!this.shapeBuffer) this.updateShape()\n if (!this.imageIndicesBuffer) this.updateImageIndices()\n if (!this.imageSizesBuffer) this.updateImageSizes()\n\n if (!this.drawCommand || !this.drawUniformStore) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n if (!this.imageAtlasTexture || !this.imageAtlasCoordsTexture) {\n this.createAtlas()\n if (!this.imageAtlasTexture || !this.imageAtlasCoordsTexture) return\n }\n if (this.imageAtlasTexture.destroyed || this.imageAtlasCoordsTexture.destroyed) return\n\n // Check if we have points to draw\n if (!data.pointsNumber || data.pointsNumber === 0) {\n return\n }\n\n // Verify canvas is sized (screenSize must be non-zero to avoid division by zero in shader)\n if (!store.screenSize || store.screenSize[0] === 0 || store.screenSize[1] === 0) {\n return\n }\n\n // Update vertex count dynamically\n this.drawCommand.setVertexCount(data.pointsNumber)\n\n // Base uniforms that don't change between layers\n // Convert booleans to floats (1.0 or 0.0) since uniform type is 'f32'\n const baseVertexUniforms = {\n ratio: config.pixelRatio ?? defaultConfigValues.pixelRatio,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [-1, -1, -1, -1]),\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0, // Convert boolean to float\n maxPointSize: store.maxPointSize ?? 100,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n hasImages: (this.imageCount > 0) ? 1 : 0, // Convert boolean to float\n imageCount: this.imageCount,\n imageAtlasCoordsTextureSize: this.imageAtlasCoordsTextureSize ?? 0,\n }\n\n const baseFragmentUniforms = {\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n pointOpacity: config.pointOpacity ?? 1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0, // Convert boolean to float\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n }\n\n // Render in layers: unselected points first (behind), then selected points (in front)\n if (store.selectedIndices && store.selectedIndices.length > 0) {\n // First draw unselected points (they will appear behind)\n this.drawUniformStore.setUniforms({\n drawVertexUniforms: {\n ...baseVertexUniforms,\n skipSelected: 1, // Skip selected points (1.0 for true)\n skipUnselected: 0, // Draw unselected points (0.0 for false)\n },\n drawFragmentUniforms: baseFragmentUniforms,\n })\n\n // Update texture bindings dynamically\n this.drawCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n imageAtlasTexture: this.imageAtlasTexture,\n imageAtlasCoords: this.imageAtlasCoordsTexture,\n })\n\n this.drawCommand.draw(renderPass)\n\n // Then draw selected points (they will appear in front)\n this.drawUniformStore.setUniforms({\n drawVertexUniforms: {\n ...baseVertexUniforms,\n skipSelected: 0, // Draw selected points (0.0 for false)\n skipUnselected: 1, // Skip unselected points (1.0 for true)\n },\n drawFragmentUniforms: baseFragmentUniforms,\n })\n\n // Update texture bindings dynamically\n this.drawCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n imageAtlasTexture: this.imageAtlasTexture,\n imageAtlasCoords: this.imageAtlasCoordsTexture,\n })\n\n this.drawCommand.draw(renderPass)\n } else {\n // If no selection, draw all points\n this.drawUniformStore.setUniforms({\n drawVertexUniforms: {\n ...baseVertexUniforms,\n skipSelected: 0, // Draw all points (0.0 for false)\n skipUnselected: 0, // Draw all points (0.0 for false)\n },\n drawFragmentUniforms: baseFragmentUniforms,\n })\n\n // Update texture bindings dynamically\n this.drawCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n imageAtlasTexture: this.imageAtlasTexture,\n imageAtlasCoords: this.imageAtlasCoordsTexture,\n })\n\n this.drawCommand.draw(renderPass)\n }\n\n // Draw highlighted point rings if enabled\n if (config.renderHoveredPointRing && store.hoveredPoint && this.drawHighlightedCommand && this.drawHighlightedUniformStore) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n const pointSize = data.pointSizes?.[store.hoveredPoint.index] ?? 1\n this.drawHighlightedUniformStore.setUniforms({\n drawHighlightedUniforms: {\n size: pointSize,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n pointIndex: store.hoveredPoint.index,\n maxPointSize: store.maxPointSize ?? 100,\n color: ensureVec4(store.hoveredPointRingColor, [0, 0, 0, 1]),\n universalPointOpacity: config.pointOpacity ?? 1,\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0,\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n width: 0.85,\n },\n })\n // Update texture bindings dynamically\n this.drawHighlightedCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatusTexture: this.greyoutStatusTexture,\n })\n this.drawHighlightedCommand.draw(renderPass)\n }\n\n if (store.focusedPoint && this.drawHighlightedCommand && this.drawHighlightedUniformStore) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n const pointSize = data.pointSizes?.[store.focusedPoint.index] ?? 1\n this.drawHighlightedUniformStore.setUniforms({\n drawHighlightedUniforms: {\n size: pointSize,\n transformationMatrix: store.transformationMatrix4x4,\n pointsTextureSize: store.pointsTextureSize ?? 0,\n sizeScale: config.pointSizeScale ?? 1,\n spaceSize: store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(store.screenSize, [0, 0]),\n scalePointsOnZoom: (config.scalePointsOnZoom ?? true) ? 1 : 0,\n pointIndex: store.focusedPoint.index,\n maxPointSize: store.maxPointSize ?? 100,\n color: ensureVec4(store.focusedPointRingColor, [0, 0, 0, 1]),\n universalPointOpacity: config.pointOpacity ?? 1,\n greyoutOpacity: config.pointGreyoutOpacity ?? -1,\n isDarkenGreyout: (store.isDarkenGreyout ?? false) ? 1 : 0,\n backgroundColor: ensureVec4(store.backgroundColor, [0, 0, 0, 1]),\n greyoutColor: ensureVec4(store.greyoutPointColor, [0, 0, 0, 1]),\n width: 0.85,\n },\n })\n // Update texture bindings dynamically\n this.drawHighlightedCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatusTexture: this.greyoutStatusTexture,\n })\n this.drawHighlightedCommand.draw(renderPass)\n }\n }\n\n public updatePosition (): void {\n if (!this.updatePositionCommand || !this.updatePositionUniformStore || !this.currentPositionFbo || this.currentPositionFbo.destroyed) return\n if (!this.previousPositionTexture || this.previousPositionTexture.destroyed) return\n if (!this.velocityTexture || this.velocityTexture.destroyed) return\n if (!this.pinnedStatusTexture || this.pinnedStatusTexture.destroyed) return\n\n this.updatePositionUniformStore.setUniforms({\n updatePositionUniforms: {\n friction: this.config.simulationFriction ?? 0,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n },\n })\n\n // Update texture bindings dynamically\n this.updatePositionCommand.setBindings({\n positionsTexture: this.previousPositionTexture,\n velocity: this.velocityTexture,\n pinnedStatusTexture: this.pinnedStatusTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.currentPositionFbo,\n })\n this.updatePositionCommand.draw(renderPass)\n renderPass.end()\n\n this.swapFbo()\n // Invalidate tracked positions cache since positions have changed\n this.isPositionsUpToDate = false\n }\n\n public drag (): void {\n if (!this.dragPointCommand || !this.dragPointUniformStore || !this.currentPositionFbo || this.currentPositionFbo.destroyed) return\n if (!this.previousPositionTexture || this.previousPositionTexture.destroyed) return\n\n this.dragPointUniformStore.setUniforms({\n dragPointUniforms: {\n mousePos: ensureVec2(this.store.mousePosition, [0, 0]),\n index: this.store.hoveredPoint?.index ?? -1,\n },\n })\n\n // Update texture bindings dynamically\n this.dragPointCommand.setBindings({\n positionsTexture: this.previousPositionTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.currentPositionFbo,\n })\n this.dragPointCommand.draw(renderPass)\n renderPass.end()\n\n this.swapFbo()\n // Invalidate tracked positions cache since positions have changed\n this.isPositionsUpToDate = false\n }\n\n public findPointsOnAreaSelection (): void {\n if (!this.findPointsOnAreaSelectionCommand || !this.findPointsOnAreaSelectionUniformStore || !this.selectedFbo || this.selectedFbo.destroyed) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.sizeTexture || this.sizeTexture.destroyed) return\n\n this.findPointsOnAreaSelectionUniformStore.setUniforms({\n findPointsOnAreaSelectionUniforms: {\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n sizeScale: this.config.pointSizeScale ?? 1,\n transformationMatrix: this.store.transformationMatrix4x4,\n ratio: this.config.pixelRatio ?? defaultConfigValues.pixelRatio,\n selection0: ensureVec2(this.store.selectedArea?.[0], [0, 0]),\n selection1: ensureVec2(this.store.selectedArea?.[1], [0, 0]),\n scalePointsOnZoom: (this.config.scalePointsOnZoom ?? true) ? 1 : 0, // Convert boolean to number\n maxPointSize: this.store.maxPointSize ?? 100,\n },\n })\n\n // Update texture bindings dynamically\n this.findPointsOnAreaSelectionCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n pointSize: this.sizeTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.selectedFbo,\n })\n this.findPointsOnAreaSelectionCommand.draw(renderPass)\n renderPass.end()\n }\n\n public findPointsOnPolygonSelection (): void {\n if (!this.findPointsOnPolygonSelectionCommand || !this.findPointsOnPolygonSelectionUniformStore || !this.selectedFbo || this.selectedFbo.destroyed) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.polygonPathTexture || this.polygonPathTexture.destroyed) return\n\n this.findPointsOnPolygonSelectionUniformStore.setUniforms({\n findPointsOnPolygonSelectionUniforms: {\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n transformationMatrix: this.store.transformationMatrix4x4,\n polygonPathLength: this.polygonPathLength,\n },\n })\n\n // Update texture bindings dynamically\n this.findPointsOnPolygonSelectionCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n polygonPathTexture: this.polygonPathTexture,\n })\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.selectedFbo,\n })\n this.findPointsOnPolygonSelectionCommand.draw(renderPass)\n renderPass.end()\n }\n\n public updatePolygonPath (polygonPath: [number, number][]): void {\n const { device } = this\n this.polygonPathLength = polygonPath.length\n\n if (polygonPath.length === 0) {\n if (this.polygonPathTexture && !this.polygonPathTexture.destroyed) {\n this.polygonPathTexture.destroy()\n }\n this.polygonPathTexture = undefined\n return\n }\n\n // Calculate texture size (square texture)\n const textureSize = Math.ceil(Math.sqrt(polygonPath.length))\n const textureData = new Float32Array(textureSize * textureSize * 4)\n\n // Fill texture with polygon path points\n for (const [i, point] of polygonPath.entries()) {\n const [x, y] = point\n textureData[i * 4] = x\n textureData[i * 4 + 1] = y\n textureData[i * 4 + 2] = 0 // unused\n textureData[i * 4 + 3] = 0 // unused\n }\n\n if (!this.polygonPathTexture || this.polygonPathTexture.width !== textureSize || this.polygonPathTexture.height !== textureSize) {\n if (this.polygonPathTexture && !this.polygonPathTexture.destroyed) {\n this.polygonPathTexture.destroy()\n }\n this.polygonPathTexture = device.createTexture({\n width: textureSize,\n height: textureSize,\n format: 'rgba32float',\n })\n this.polygonPathTexture.copyImageData({\n data: textureData,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.polygonPathTexture.copyImageData({\n data: textureData,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n }\n\n public findHoveredPoint (): void {\n if (!this.hoveredFbo || this.hoveredFbo.destroyed) return\n\n if (!this.findHoveredPointCommand || !this.findHoveredPointUniformStore) return\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return\n if (!this.greyoutStatusTexture) this.updateGreyoutStatus()\n if (!this.greyoutStatusTexture || this.greyoutStatusTexture.destroyed) return\n\n this.findHoveredPointCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.findHoveredPointCommand.setAttributes({\n ...(this.hoveredPointIndices && { pointIndices: this.hoveredPointIndices }),\n ...(this.sizeBuffer && { size: this.sizeBuffer }),\n })\n\n const baseUniforms = {\n ratio: this.config.pixelRatio ?? defaultConfigValues.pixelRatio,\n sizeScale: this.config.pointSizeScale ?? 1,\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n transformationMatrix: this.store.transformationMatrix4x4,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n scalePointsOnZoom: (this.config.scalePointsOnZoom ?? true) ? 1 : 0,\n mousePosition: ensureVec2(this.store.screenMousePosition, [0, 0]),\n maxPointSize: this.store.maxPointSize ?? 100,\n }\n\n const bindings = {\n positionsTexture: this.currentPositionTexture,\n pointGreyoutStatus: this.greyoutStatusTexture,\n }\n\n const renderPass = this.device.beginRenderPass({\n framebuffer: this.hoveredFbo,\n clearColor: [0, 0, 0, 0],\n })\n\n if (this.store.selectedIndices && this.store.selectedIndices.length > 0) {\n // Same two-pass order as drawing: unselected first, then selected (top-most wins)\n this.findHoveredPointUniformStore.setUniforms({\n findHoveredPointUniforms: {\n ...baseUniforms,\n skipSelected: 1,\n skipUnselected: 0,\n },\n })\n this.findHoveredPointCommand.setBindings(bindings)\n this.findHoveredPointCommand.draw(renderPass)\n\n this.findHoveredPointUniformStore.setUniforms({\n findHoveredPointUniforms: {\n ...baseUniforms,\n skipSelected: 0,\n skipUnselected: 1,\n },\n })\n this.findHoveredPointCommand.setBindings(bindings)\n this.findHoveredPointCommand.draw(renderPass)\n } else {\n this.findHoveredPointUniformStore.setUniforms({\n findHoveredPointUniforms: {\n ...baseUniforms,\n skipSelected: 0,\n skipUnselected: 0,\n },\n })\n this.findHoveredPointCommand.setBindings(bindings)\n this.findHoveredPointCommand.draw(renderPass)\n }\n\n renderPass.end()\n }\n\n public trackPointsByIndices (indices?: number[] | undefined): void {\n const { store: { pointsTextureSize }, device } = this\n this.trackedIndices = indices\n\n // Clear cache when changing tracked indices\n this.trackedPositions = undefined\n this.isPositionsUpToDate = false\n\n if (!indices?.length || !pointsTextureSize) return\n const textureSize = Math.ceil(Math.sqrt(indices.length))\n\n const initialState = new Float32Array(textureSize * textureSize * 4).fill(-1)\n for (const [i, sortedIndex] of indices.entries()) {\n if (sortedIndex !== undefined) {\n initialState[i * 4] = sortedIndex % pointsTextureSize\n initialState[i * 4 + 1] = Math.floor(sortedIndex / pointsTextureSize)\n initialState[i * 4 + 2] = 0\n initialState[i * 4 + 3] = 0\n }\n }\n\n if (!this.trackedIndicesTexture || this.trackedIndicesTexture.width !== textureSize || this.trackedIndicesTexture.height !== textureSize) {\n if (this.trackedIndicesTexture && !this.trackedIndicesTexture.destroyed) {\n this.trackedIndicesTexture.destroy()\n }\n this.trackedIndicesTexture = device.createTexture({\n width: textureSize,\n height: textureSize,\n format: 'rgba32float',\n })\n this.trackedIndicesTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n } else {\n this.trackedIndicesTexture.copyImageData({\n data: initialState,\n bytesPerRow: getBytesPerRow('rgba32float', textureSize),\n mipLevel: 0,\n x: 0,\n y: 0,\n })\n }\n\n if (!this.trackedPositionsFbo || this.trackedPositionsFbo.width !== textureSize || this.trackedPositionsFbo.height !== textureSize) {\n if (this.trackedPositionsFbo && !this.trackedPositionsFbo.destroyed) {\n this.trackedPositionsFbo.destroy()\n }\n this.trackedPositionsFbo = device.createFramebuffer({\n width: textureSize,\n height: textureSize,\n colorAttachments: ['rgba32float'],\n })\n }\n\n this.trackPoints()\n }\n\n /**\n * Get current X and Y coordinates of the tracked points.\n *\n * When the simulation is disabled or stopped, this method returns a cached\n * result to avoid expensive GPU-to-CPU memory transfers (`readPixels`).\n *\n * @returns A ReadonlyMap where keys are point indices and values are [x, y] coordinates.\n */\n public getTrackedPositionsMap (): ReadonlyMap<number, [number, number]> {\n if (!this.trackedIndices) return new Map()\n\n const { config: { enableSimulation }, store: { isSimulationRunning } } = this\n\n // Use cached positions when simulation is inactive and cache is valid\n if ((!enableSimulation || !isSimulationRunning) &&\n this.isPositionsUpToDate &&\n this.trackedPositions) {\n return this.trackedPositions\n }\n\n if (!this.trackedPositionsFbo || this.trackedPositionsFbo.destroyed) return new Map()\n\n const pixels = readPixels(this.device, this.trackedPositionsFbo as Framebuffer)\n\n const tracked = new Map<number, [number, number]>()\n for (let i = 0; i < pixels.length / 4; i += 1) {\n const x = pixels[i * 4]\n const y = pixels[i * 4 + 1]\n const index = this.trackedIndices[i]\n if (x !== undefined && y !== undefined && index !== undefined) {\n tracked.set(index, [x, y])\n }\n }\n\n // If simulation is inactive, cache the result for next time\n if (!enableSimulation || !isSimulationRunning) {\n this.trackedPositions = tracked\n this.isPositionsUpToDate = true\n }\n\n return tracked\n }\n\n public getSampledPointPositionsMap (): Map<number, [number, number]> {\n const positions = new Map<number, [number, number]>()\n if (!this.sampledPointsFbo || this.sampledPointsFbo.destroyed) return positions\n\n // Fill sampled points FBO\n if (this.fillSampledPointsFboCommand && this.fillSampledPointsUniformStore && this.sampledPointsFbo) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return positions\n // Update vertex count dynamically\n this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.fillSampledPointsUniformStore.setUniforms({\n fillSampledPointsUniforms: {\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n transformationMatrix: this.store.transformationMatrix4x4,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.fillSampledPointsFboCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n })\n\n const fillPass = this.device.beginRenderPass({\n framebuffer: this.sampledPointsFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.fillSampledPointsFboCommand.draw(fillPass)\n fillPass.end()\n }\n\n const pixels = readPixels(this.device, this.sampledPointsFbo as Framebuffer)\n for (let i = 0; i < pixels.length / 4; i++) {\n const index = pixels[i * 4]\n const isNotEmpty = !!pixels[i * 4 + 1]\n const x = pixels[i * 4 + 2]\n const y = pixels[i * 4 + 3]\n\n if (isNotEmpty && index !== undefined && x !== undefined && y !== undefined) {\n positions.set(index, [x, y])\n }\n }\n return positions\n }\n\n public getSampledPoints (): { indices: number[]; positions: number[] } {\n const indices: number[] = []\n const positions: number[] = []\n if (!this.sampledPointsFbo || this.sampledPointsFbo.destroyed) return { indices, positions }\n\n // Fill sampled points FBO\n if (this.fillSampledPointsFboCommand && this.fillSampledPointsUniformStore && this.sampledPointsFbo) {\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed) return { indices, positions }\n // Update vertex count dynamically\n this.fillSampledPointsFboCommand.setVertexCount(this.data.pointsNumber ?? 0)\n\n this.fillSampledPointsUniformStore.setUniforms({\n fillSampledPointsUniforms: {\n pointsTextureSize: this.store.pointsTextureSize ?? 0,\n transformationMatrix: this.store.transformationMatrix4x4,\n spaceSize: this.store.adjustedSpaceSize ?? 0,\n screenSize: ensureVec2(this.store.screenSize, [0, 0]),\n },\n })\n\n // Update texture bindings dynamically\n this.fillSampledPointsFboCommand.setBindings({\n positionsTexture: this.currentPositionTexture,\n })\n\n const fillPass = this.device.beginRenderPass({\n framebuffer: this.sampledPointsFbo,\n clearColor: [0, 0, 0, 0],\n })\n this.fillSampledPointsFboCommand.draw(fillPass)\n fillPass.end()\n }\n\n const pixels = readPixels(this.device, this.sampledPointsFbo as Framebuffer)\n\n for (let i = 0; i < pixels.length / 4; i++) {\n const index = pixels[i * 4]\n const isNotEmpty = !!pixels[i * 4 + 1]\n const x = pixels[i * 4 + 2]\n const y = pixels[i * 4 + 3]\n\n if (isNotEmpty && index !== undefined && x !== undefined && y !== undefined) {\n indices.push(index)\n positions.push(x, y)\n }\n }\n\n return { indices, positions }\n }\n\n public getTrackedPositionsArray (): number[] {\n const positions: number[] = []\n if (!this.trackedIndices) return positions\n if (!this.trackedPositionsFbo || this.trackedPositionsFbo.destroyed) return positions\n positions.length = this.trackedIndices.length * 2\n const pixels = readPixels(this.device, this.trackedPositionsFbo as Framebuffer)\n for (let i = 0; i < pixels.length / 4; i += 1) {\n const x = pixels[i * 4]\n const y = pixels[i * 4 + 1]\n const index = this.trackedIndices[i]\n if (x !== undefined && y !== undefined && index !== undefined) {\n positions[i * 2] = x\n positions[i * 2 + 1] = y\n }\n }\n return positions\n }\n\n /**\n * Destruction order matters\n * Models -> Framebuffers -> Textures -> UniformStores -> Buffers\n * */\n public destroy (): void {\n // 1. Destroy Models FIRST (they destroy _gpuGeometry if exists, and _uniformStore)\n this.drawCommand?.destroy()\n this.drawCommand = undefined\n this.drawHighlightedCommand?.destroy()\n this.drawHighlightedCommand = undefined\n this.updatePositionCommand?.destroy()\n this.updatePositionCommand = undefined\n this.dragPointCommand?.destroy()\n this.dragPointCommand = undefined\n this.findPointsOnAreaSelectionCommand?.destroy()\n this.findPointsOnAreaSelectionCommand = undefined\n this.findPointsOnPolygonSelectionCommand?.destroy()\n this.findPointsOnPolygonSelectionCommand = undefined\n this.findHoveredPointCommand?.destroy()\n this.findHoveredPointCommand = undefined\n this.fillSampledPointsFboCommand?.destroy()\n this.fillSampledPointsFboCommand = undefined\n this.trackPointsCommand?.destroy()\n this.trackPointsCommand = undefined\n\n // 2. Destroy Framebuffers (before textures they reference)\n if (this.currentPositionFbo && !this.currentPositionFbo.destroyed) {\n this.currentPositionFbo.destroy()\n }\n this.currentPositionFbo = undefined\n if (this.previousPositionFbo && !this.previousPositionFbo.destroyed) {\n this.previousPositionFbo.destroy()\n }\n this.previousPositionFbo = undefined\n if (this.velocityFbo && !this.velocityFbo.destroyed) {\n this.velocityFbo.destroy()\n }\n this.velocityFbo = undefined\n if (this.selectedFbo && !this.selectedFbo.destroyed) {\n this.selectedFbo.destroy()\n }\n this.selectedFbo = undefined\n if (this.hoveredFbo && !this.hoveredFbo.destroyed) {\n this.hoveredFbo.destroy()\n }\n this.hoveredFbo = undefined\n if (this.trackedPositionsFbo && !this.trackedPositionsFbo.destroyed) {\n this.trackedPositionsFbo.destroy()\n }\n this.trackedPositionsFbo = undefined\n if (this.sampledPointsFbo && !this.sampledPointsFbo.destroyed) {\n this.sampledPointsFbo.destroy()\n }\n this.sampledPointsFbo = undefined\n\n // 3. Destroy Textures\n if (this.currentPositionTexture && !this.currentPositionTexture.destroyed) {\n this.currentPositionTexture.destroy()\n }\n this.currentPositionTexture = undefined\n if (this.previousPositionTexture && !this.previousPositionTexture.destroyed) {\n this.previousPositionTexture.destroy()\n }\n this.previousPositionTexture = undefined\n if (this.velocityTexture && !this.velocityTexture.destroyed) {\n this.velocityTexture.destroy()\n }\n this.velocityTexture = undefined\n if (this.selectedTexture && !this.selectedTexture.destroyed) {\n this.selectedTexture.destroy()\n }\n this.selectedTexture = undefined\n if (this.greyoutStatusTexture && !this.greyoutStatusTexture.destroyed) {\n this.greyoutStatusTexture.destroy()\n }\n this.greyoutStatusTexture = undefined\n if (this.sizeTexture && !this.sizeTexture.destroyed) {\n this.sizeTexture.destroy()\n }\n this.sizeTexture = undefined\n if (this.trackedIndicesTexture && !this.trackedIndicesTexture.destroyed) {\n this.trackedIndicesTexture.destroy()\n }\n this.trackedIndicesTexture = undefined\n if (this.polygonPathTexture && !this.polygonPathTexture.destroyed) {\n this.polygonPathTexture.destroy()\n }\n this.polygonPathTexture = undefined\n if (this.imageAtlasTexture && !this.imageAtlasTexture.destroyed) {\n this.imageAtlasTexture.destroy()\n }\n this.imageAtlasTexture = undefined\n if (this.imageAtlasCoordsTexture && !this.imageAtlasCoordsTexture.destroyed) {\n this.imageAtlasCoordsTexture.destroy()\n }\n this.imageAtlasCoordsTexture = undefined\n if (this.pinnedStatusTexture && !this.pinnedStatusTexture.destroyed) {\n this.pinnedStatusTexture.destroy()\n }\n this.pinnedStatusTexture = undefined\n\n // 4. Destroy UniformStores (Models already destroyed their managed uniform buffers)\n this.updatePositionUniformStore?.destroy()\n this.updatePositionUniformStore = undefined\n this.dragPointUniformStore?.destroy()\n this.dragPointUniformStore = undefined\n this.drawUniformStore?.destroy()\n this.drawUniformStore = undefined\n this.findPointsOnAreaSelectionUniformStore?.destroy()\n this.findPointsOnAreaSelectionUniformStore = undefined\n this.findPointsOnPolygonSelectionUniformStore?.destroy()\n this.findPointsOnPolygonSelectionUniformStore = undefined\n this.findHoveredPointUniformStore?.destroy()\n this.findHoveredPointUniformStore = undefined\n this.fillSampledPointsUniformStore?.destroy()\n this.fillSampledPointsUniformStore = undefined\n this.drawHighlightedUniformStore?.destroy()\n this.drawHighlightedUniformStore = undefined\n this.trackPointsUniformStore?.destroy()\n this.trackPointsUniformStore = undefined\n\n // 5. Destroy Buffers (passed via attributes - NOT owned by Models, must destroy manually)\n if (this.colorBuffer && !this.colorBuffer.destroyed) {\n this.colorBuffer.destroy()\n }\n this.colorBuffer = undefined\n if (this.sizeBuffer && !this.sizeBuffer.destroyed) {\n this.sizeBuffer.destroy()\n }\n this.sizeBuffer = undefined\n if (this.shapeBuffer && !this.shapeBuffer.destroyed) {\n this.shapeBuffer.destroy()\n }\n this.shapeBuffer = undefined\n if (this.imageIndicesBuffer && !this.imageIndicesBuffer.destroyed) {\n this.imageIndicesBuffer.destroy()\n }\n this.imageIndicesBuffer = undefined\n if (this.imageSizesBuffer && !this.imageSizesBuffer.destroyed) {\n this.imageSizesBuffer.destroy()\n }\n this.imageSizesBuffer = undefined\n if (this.drawPointIndices && !this.drawPointIndices.destroyed) {\n this.drawPointIndices.destroy()\n }\n this.drawPointIndices = undefined\n if (this.hoveredPointIndices && !this.hoveredPointIndices.destroyed) {\n this.hoveredPointIndices.destroy()\n }\n this.hoveredPointIndices = undefined\n if (this.sampledPointIndices && !this.sampledPointIndices.destroyed) {\n this.sampledPointIndices.destroy()\n }\n this.sampledPointIndices = undefined\n if (this.updatePositionVertexCoordBuffer && !this.updatePositionVertexCoordBuffer.destroyed) {\n this.updatePositionVertexCoordBuffer.destroy()\n }\n this.updatePositionVertexCoordBuffer = undefined\n if (this.dragPointVertexCoordBuffer && !this.dragPointVertexCoordBuffer.destroyed) {\n this.dragPointVertexCoordBuffer.destroy()\n }\n this.dragPointVertexCoordBuffer = undefined\n if (this.findPointsOnAreaSelectionVertexCoordBuffer && !this.findPointsOnAreaSelectionVertexCoordBuffer.destroyed) {\n this.findPointsOnAreaSelectionVertexCoordBuffer.destroy()\n }\n this.findPointsOnAreaSelectionVertexCoordBuffer = undefined\n if (this.findPointsOnPolygonSelectionVertexCoordBuffer && !this.findPointsOnPolygonSelectionVertexCoordBuffer.destroyed) {\n this.findPointsOnPolygonSelectionVertexCoordBuffer.destroy()\n }\n this.findPointsOnPolygonSelectionVertexCoordBuffer = undefined\n if (this.drawHighlightedVertexCoordBuffer && !this.drawHighlightedVertexCoordBuffer.destroyed) {\n this.drawHighlightedVertexCoordBuffer.destroy()\n }\n this.drawHighlightedVertexCoordBuffer = undefined\n if (this.trackPointsVertexCoordBuffer && !this.trackPointsVertexCoordBuffer.destroyed) {\n this.trackPointsVertexCoordBuffer.destroy()\n }\n this.trackPointsVertexCoordBuffer = undefined\n }\n\n private swapFbo (): void {\n // Swap textures and framebuffers\n // Safety check: ensure resources exist and aren't destroyed before swapping\n if (!this.currentPositionTexture || this.currentPositionTexture.destroyed ||\n !this.previousPositionTexture || this.previousPositionTexture.destroyed ||\n !this.currentPositionFbo || this.currentPositionFbo.destroyed ||\n !this.previousPositionFbo || this.previousPositionFbo.destroyed) {\n return\n }\n const tempTexture = this.previousPositionTexture\n const tempFbo = this.previousPositionFbo\n this.previousPositionTexture = this.currentPositionTexture\n this.previousPositionFbo = this.currentPositionFbo\n this.currentPositionTexture = tempTexture\n this.currentPositionFbo = tempFbo\n }\n\n private rescaleInitialNodePositions (): void {\n const { config: { spaceSize } } = this\n if (!this.data.pointPositions || !spaceSize) return\n\n const points = this.data.pointPositions\n const pointsNumber = points.length / 2\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (let i = 0; i < points.length; i += 2) {\n const x = points[i] as number\n const y = points[i + 1] as number\n minX = Math.min(minX, x)\n maxX = Math.max(maxX, x)\n minY = Math.min(minY, y)\n maxY = Math.max(maxY, y)\n }\n const w = maxX - minX\n const h = maxY - minY\n const range = Math.max(w, h)\n\n // Do not rescale if the range is greater than the space size (no need to)\n if (range > spaceSize) {\n this.scaleX = undefined\n this.scaleY = undefined\n return\n }\n\n // Density threshold - points per pixel ratio (0.001 = 0.1%)\n const densityThreshold = spaceSize * spaceSize * 0.001\n // Calculate effective space size based on point density\n const effectiveSpaceSize = pointsNumber > densityThreshold\n // For dense datasets: scale up based on point count, minimum 120% of space\n ? spaceSize * Math.max(1.2, Math.sqrt(pointsNumber) / spaceSize)\n // For sparse datasets: use 10% of space to cluster points closer\n : spaceSize * 0.1\n\n // Calculate uniform scale factor to fit data within effective space\n const scaleFactor = effectiveSpaceSize / range\n // Shift to center the scaled data within the full [0, spaceSize] space\n const centerOffset = (spaceSize - effectiveSpaceSize) / 2\n // Pad the shorter axis so both axes are centered within the square bounding box\n const offsetX = ((range - w) / 2) * scaleFactor + centerOffset\n const offsetY = ((range - h) / 2) * scaleFactor + centerOffset\n\n this.scaleX = (x: number): number => (x - minX) * scaleFactor + offsetX\n this.scaleY = (y: number): number => (y - minY) * scaleFactor + offsetY\n\n // Apply scaling to point positions\n for (let i = 0; i < pointsNumber; i++) {\n this.data.pointPositions[i * 2] = this.scaleX(points[i * 2] as number)\n this.data.pointPositions[i * 2 + 1] = this.scaleY(points[i * 2 + 1] as number)\n }\n }\n}\n","import { zoom, ZoomTransform, zoomIdentity, D3ZoomEvent } from 'd3-zoom'\nimport { mat3 } from 'gl-matrix'\nimport { Store } from '@/graph/modules/Store'\nimport { GraphConfigInterface } from '@/graph/config'\nimport { clamp } from '@/graph/helper'\n\nexport class Zoom {\n public readonly store: Store\n public readonly config: GraphConfigInterface\n public eventTransform = zoomIdentity\n public behavior = zoom<HTMLCanvasElement, undefined>()\n .scaleExtent([0.001, Infinity])\n .on('start', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.isRunning = true\n const userDriven = !!e.sourceEvent\n this.config?.onZoomStart?.(e, userDriven)\n })\n .on('zoom', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.eventTransform = e.transform\n const { eventTransform: { x, y, k }, store: { transform, screenSize } } = this\n const w = screenSize[0]\n const h = screenSize[1]\n if (!w || !h) return\n mat3.projection(transform, w, h)\n mat3.translate(transform, transform, [x, y])\n mat3.scale(transform, transform, [k, k])\n mat3.translate(transform, transform, [w / 2, h / 2])\n mat3.scale(transform, transform, [w / 2, h / 2])\n mat3.scale(transform, transform, [1, -1])\n\n const userDriven = !!e.sourceEvent\n this.config?.onZoom?.(e, userDriven)\n })\n .on('end', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.isRunning = false\n\n const userDriven = !!e.sourceEvent\n this.config?.onZoomEnd?.(e, userDriven)\n })\n\n public isRunning = false\n\n public constructor (store: Store, config: GraphConfigInterface) {\n this.store = store\n this.config = config\n }\n\n /**\n * Returns the zoom transform that fits the given point positions into the viewport.\n *\n * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]` (number[] or Float32Array).\n * @param scale Optional scale factor to apply to the transform.\n * @param padding Padding around the viewport as a fraction of the viewport size (e.g. 0.1 = 10%).\n * @returns The zoom transform that fits the positions.\n */\n public getTransform (positions: number[] | Float32Array, scale?: number, padding = 0.1): ZoomTransform {\n if (positions.length === 0) return this.eventTransform\n const { store: { screenSize } } = this\n const width = screenSize[0]\n const height = screenSize[1]\n\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (let i = 0; i < positions.length; i += 2) {\n const x = positions[i] as number\n const y = positions[i + 1] as number\n if (x < minX) minX = x\n if (x > maxX) maxX = x\n if (y < minY) minY = y\n if (y > maxY) maxY = y\n }\n\n const xExtent: [number, number] = [this.store.scaleX(minX), this.store.scaleX(maxX)]\n const yExtent: [number, number] = [this.store.scaleY(minY), this.store.scaleY(maxY)]\n // Adjust extent with one screen pixel if one point coordinate is set\n if (xExtent[0] === xExtent[1]) {\n xExtent[0] -= 0.5\n xExtent[1] += 0.5\n }\n if (yExtent[0] === yExtent[1]) {\n yExtent[0] += 0.5\n yExtent[1] -= 0.5\n }\n\n const xScale = (width * (1 - padding * 2)) / (xExtent[1] - xExtent[0])\n const yScale = (height * (1 - padding * 2)) / (yExtent[0] - yExtent[1])\n const clampedScale = clamp(scale ?? Math.min(xScale, yScale), ...this.behavior.scaleExtent())\n const xCenter = (xExtent[1] + xExtent[0]) / 2\n const yCenter = (yExtent[1] + yExtent[0]) / 2\n const translateX = width / 2 - xCenter * clampedScale\n const translateY = height / 2 - yCenter * clampedScale\n\n const transform = zoomIdentity\n .translate(translateX, translateY)\n .scale(clampedScale)\n\n return transform\n }\n\n public getDistanceToPoint (position: [number, number]): number {\n const { x, y, k } = this.eventTransform\n const point = this.getTransform(position, k)\n const dx = x - point.x\n const dy = y - point.y\n return Math.sqrt(dx * dx + dy * dy)\n }\n\n public getMiddlePointTransform (position: [number, number]): ZoomTransform {\n const { store: { screenSize }, eventTransform: { x, y, k } } = this\n const width = screenSize[0]\n const height = screenSize[1]\n const currX = (width / 2 - x) / k\n const currY = (height / 2 - y) / k\n const pointX = this.store.scaleX(position[0])\n const pointY = this.store.scaleY(position[1])\n const centerX = (currX + pointX) / 2\n const centerY = (currY + pointY) / 2\n\n const scale = 1\n const translateX = width / 2 - centerX * scale\n const translateY = height / 2 - centerY * scale\n\n return zoomIdentity\n .translate(translateX, translateY)\n .scale(scale)\n }\n\n public convertScreenToSpacePosition (screenPosition: [number, number]): [number, number] {\n const { eventTransform: { x, y, k }, store: { screenSize } } = this\n const w = screenSize[0]\n const h = screenSize[1]\n const invertedX = (screenPosition[0] - x) / k\n const invertedY = (screenPosition[1] - y) / k\n const spacePosition = [invertedX, (h - invertedY)] as [number, number]\n spacePosition[0] -= (w - this.store.adjustedSpaceSize) / 2\n spacePosition[1] -= (h - this.store.adjustedSpaceSize) / 2\n return spacePosition\n }\n\n public convertSpaceToScreenPosition (spacePosition: [number, number]): [number, number] {\n const screenPointX = this.eventTransform.applyX(this.store.scaleX(spacePosition[0]))\n const screenPointY = this.eventTransform.applyY(this.store.scaleY(spacePosition[1]))\n return [screenPointX, screenPointY]\n }\n\n public convertSpaceToScreenRadius (spaceRadius: number): number {\n const { config: { scalePointsOnZoom }, store: { maxPointSize }, eventTransform: { k } } = this\n let size = spaceRadius * 2\n if (scalePointsOnZoom) {\n size *= k\n } else {\n size *= Math.min(5.0, Math.max(1.0, k * 0.01))\n }\n return Math.min(size, maxPointSize) / 2\n }\n}\n","import { drag } from 'd3-drag'\nimport { Store } from '@/graph/modules/Store'\nimport { GraphConfigInterface } from '@/graph/config'\n\nexport class Drag {\n public readonly store: Store\n public readonly config: GraphConfigInterface\n public isActive = false\n public behavior = drag<HTMLCanvasElement, undefined>()\n .subject((event) => {\n return this.store.hoveredPoint && !this.store.isSpaceKeyPressed ? { x: event.x, y: event.y } : undefined\n })\n .on('start', (e) => {\n if (this.store.hoveredPoint) {\n this.store.draggingPointIndex = this.store.hoveredPoint.index\n this.isActive = true\n this.config?.onDragStart?.(e)\n }\n })\n .on('drag', (e) => {\n this.config?.onDrag?.(e)\n })\n .on('end', (e) => {\n this.isActive = false\n this.store.draggingPointIndex = undefined\n this.config?.onDragEnd?.(e)\n })\n\n public constructor (store: Store, config: GraphConfigInterface) {\n this.store = store\n this.config = config\n }\n}\n","import { select, Selection } from 'd3-selection'\nimport 'd3-transition'\nimport { easeQuadInOut, easeQuadIn, easeQuadOut } from 'd3-ease'\nimport { D3ZoomEvent } from 'd3-zoom'\nimport { D3DragEvent } from 'd3-drag'\nimport { Device, Framebuffer, luma } from '@luma.gl/core'\nimport { webgl2Adapter } from '@luma.gl/webgl'\n\nimport { GraphConfig, GraphConfigInterface } from '@/graph/config'\nimport { getRgbaColor, getMaxPointSize, readPixels, sanitizeHtml } from '@/graph/helper'\nimport { ForceCenter } from '@/graph/modules/ForceCenter'\nimport { ForceGravity } from '@/graph/modules/ForceGravity'\nimport { ForceLink, LinkDirection } from '@/graph/modules/ForceLink'\nimport { ForceManyBody } from '@/graph/modules/ForceManyBody'\nimport { ForceMouse } from '@/graph/modules/ForceMouse'\nimport { Clusters } from '@/graph/modules/Clusters'\nimport { FPSMonitor } from '@/graph/modules/FPSMonitor'\nimport { GraphData } from '@/graph/modules/GraphData'\nimport { Lines } from '@/graph/modules/Lines'\nimport { Points } from '@/graph/modules/Points'\nimport { Store, ALPHA_MIN, MAX_HOVER_DETECTION_DELAY, MIN_MOUSE_MOVEMENT_THRESHOLD, type Hovered } from '@/graph/modules/Store'\nimport { Zoom } from '@/graph/modules/Zoom'\nimport { Drag } from '@/graph/modules/Drag'\nimport { defaultConfigValues, defaultScaleToZoom, defaultGreyoutPointColor, defaultBackgroundColor } from '@/graph/variables'\n\nexport class Graph {\n public config = new GraphConfig()\n public graph = new GraphData(this.config)\n /** Promise that resolves when the graph is fully initialized and ready to use */\n public readonly ready: Promise<void>\n /** Whether the graph has completed initialization */\n public isReady = false\n private readonly deviceInitPromise: Promise<Device>\n /** Canvas element, assigned asynchronously during device initialization */\n private canvas!: HTMLCanvasElement\n private attributionDivElement: HTMLElement | undefined\n private canvasD3Selection: Selection<HTMLCanvasElement, undefined, null, undefined> | undefined\n private device: Device | undefined\n /**\n * Tracks whether this Graph instance owns the device and should destroy it on cleanup.\n * Set to `true` when Graph creates its own device, `false` when using an external device.\n * When `false`, the external device lifecycle is managed by the user.\n */\n private shouldDestroyDevice: boolean\n private requestAnimationFrameId = 0\n private isRightClickMouse = false\n\n private store = new Store()\n private points: Points | undefined\n private lines: Lines | undefined\n private forceGravity: ForceGravity | undefined\n private forceCenter: ForceCenter | undefined\n private forceManyBody: ForceManyBody | undefined\n private forceLinkIncoming: ForceLink | undefined\n private forceLinkOutgoing: ForceLink | undefined\n private forceMouse: ForceMouse | undefined\n private clusters: Clusters | undefined\n private zoomInstance = new Zoom(this.store, this.config)\n private dragInstance = new Drag(this.store, this.config)\n\n private fpsMonitor: FPSMonitor | undefined\n\n private currentEvent: D3ZoomEvent<HTMLCanvasElement, undefined> | D3DragEvent<HTMLCanvasElement, undefined, Hovered> | MouseEvent | undefined\n /**\n * The value of `_findHoveredItemExecutionCount` is incremented by 1 on each animation frame.\n * When the counter reaches MAX_HOVER_DETECTION_DELAY (default 4), it is reset to 0 and the `findHoveredPoint` or `findHoveredLine` method is executed.\n */\n private _findHoveredItemExecutionCount = 0\n /**\n * If the mouse is not on the Canvas, the `findHoveredPoint` or `findHoveredLine` method will not be executed.\n */\n private _isMouseOnCanvas = false\n /**\n * Last mouse position for detecting significant mouse movement\n */\n private _lastMouseX = 0\n private _lastMouseY = 0\n /**\n * Last checked mouse position for hover detection\n */\n private _lastCheckedMouseX = 0\n private _lastCheckedMouseY = 0\n /**\n * Force hover detection on next frame, bypassing mouse movement check.\n * Set when scene changes but mouse stays still (after simulation or zoom ends).\n */\n private _shouldForceHoverDetection = false\n /**\n * After setting data and render graph at a first time, the fit logic will run\n * */\n private _isFirstRenderAfterInit = true\n private _fitViewOnInitTimeoutID: number | undefined\n\n private isPointPositionsUpdateNeeded = false\n private isPointColorUpdateNeeded = false\n private isPointSizeUpdateNeeded = false\n private isPointShapeUpdateNeeded = false\n private isPointImageIndicesUpdateNeeded = false\n private isLinksUpdateNeeded = false\n private isLinkColorUpdateNeeded = false\n private isLinkWidthUpdateNeeded = false\n private isLinkArrowUpdateNeeded = false\n private isPointClusterUpdateNeeded = false\n private isForceManyBodyUpdateNeeded = false\n private isForceLinkUpdateNeeded = false\n private isForceCenterUpdateNeeded = false\n private isPointImageSizesUpdateNeeded = false\n\n private _isDestroyed = false\n\n public constructor (\n div: HTMLDivElement,\n config?: GraphConfigInterface,\n devicePromise?: Promise<Device>\n ) {\n if (config) this.config.init(config)\n\n if (devicePromise) {\n this.deviceInitPromise = devicePromise\n this.shouldDestroyDevice = false // External device - Graph does not own it\n } else {\n const canvas = document.createElement('canvas')\n this.deviceInitPromise = this.createDevice(canvas)\n this.shouldDestroyDevice = true // Graph created the device and owns it\n }\n\n this.deviceInitPromise.then(device => {\n if (this._isDestroyed) {\n // Only destroy the device if Graph owns it\n if (this.shouldDestroyDevice) {\n device.destroy()\n }\n return device\n }\n this.device = device\n this.isReady = true\n const deviceCanvasContext = this.validateDevice(device)\n\n // If external device was provided, sync its useDevicePixels with config.pixelRatio\n if (devicePromise) {\n deviceCanvasContext.setProps({ useDevicePixels: this.config.pixelRatio })\n }\n\n this.store.div = div\n const deviceCanvas = deviceCanvasContext.canvas as HTMLCanvasElement\n // Ensure canvas is in the div\n if (deviceCanvas.parentNode !== this.store.div) {\n if (deviceCanvas.parentNode) {\n deviceCanvas.parentNode.removeChild(deviceCanvas)\n }\n this.store.div.appendChild(deviceCanvas)\n }\n this.addAttribution()\n deviceCanvas.style.width = '100%'\n deviceCanvas.style.height = '100%'\n this.canvas = deviceCanvas\n\n const w = this.canvas.clientWidth\n const h = this.canvas.clientHeight\n\n this.store.adjustSpaceSize(this.config.spaceSize, this.device.limits.maxTextureDimension2D)\n this.store.setWebGLMaxTextureSize(this.device.limits.maxTextureDimension2D)\n this.store.updateScreenSize(w, h)\n\n this.canvasD3Selection = select<HTMLCanvasElement, undefined>(this.canvas)\n this.canvasD3Selection\n .on('mouseenter.cosmos', (event) => {\n this._isMouseOnCanvas = true\n this._lastMouseX = event.clientX\n this._lastMouseY = event.clientY\n })\n .on('mousemove.cosmos', (event) => {\n this._isMouseOnCanvas = true\n this._lastMouseX = event.clientX\n this._lastMouseY = event.clientY\n })\n .on('mouseleave.cosmos', (event) => {\n this._isMouseOnCanvas = false\n this.currentEvent = event\n\n // Clear point hover state and trigger callback if needed\n if (this.store.hoveredPoint !== undefined && this.config.onPointMouseOut) {\n this.config.onPointMouseOut(event)\n }\n\n // Clear link hover state and trigger callback if needed\n if (this.store.hoveredLinkIndex !== undefined && this.config.onLinkMouseOut) {\n this.config.onLinkMouseOut(event)\n }\n\n // Reset right-click flag\n this.isRightClickMouse = false\n\n // Clear hover states\n this.store.hoveredPoint = undefined\n this.store.hoveredLinkIndex = undefined\n\n // Update cursor style after clearing hover states\n this.updateCanvasCursor()\n })\n select(document)\n .on('keydown.cosmos', (event) => { if (event.code === 'Space') this.store.isSpaceKeyPressed = true })\n .on('keyup.cosmos', (event) => { if (event.code === 'Space') this.store.isSpaceKeyPressed = false })\n this.zoomInstance.behavior\n .on('start.detect', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => { this.currentEvent = e })\n .on('zoom.detect', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n const userDriven = !!e.sourceEvent\n if (userDriven) this.updateMousePosition(e.sourceEvent)\n this.currentEvent = e\n })\n .on('end.detect', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {\n this.currentEvent = e\n // Force hover detection on next frame since zoom may have changed what's under the mouse\n this._shouldForceHoverDetection = true\n })\n this.dragInstance.behavior\n .on('start.detect', (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => {\n this.currentEvent = e\n this.updateCanvasCursor()\n })\n .on('drag.detect', (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => {\n if (this.dragInstance.isActive) {\n this.updateMousePosition(e)\n }\n this.currentEvent = e\n })\n .on('end.detect', (e: D3DragEvent<HTMLCanvasElement, undefined, Hovered>) => {\n this.currentEvent = e\n this.updateCanvasCursor()\n })\n this.canvasD3Selection\n .call(this.dragInstance.behavior)\n .call(this.zoomInstance.behavior)\n .on('click', this.onClick.bind(this))\n .on('mousemove', this.onMouseMove.bind(this))\n .on('contextmenu', this.onContextMenu.bind(this))\n if (!this.config.enableZoom || !this.config.enableDrag) this.updateZoomDragBehaviors()\n this.setZoomLevel(this.config.initialZoomLevel ?? 1)\n\n this.store.maxPointSize = getMaxPointSize(device, this.config.pixelRatio)\n\n // Initialize simulation state based on enableSimulation config\n // If simulation is disabled, start with isSimulationRunning = false\n this.store.isSimulationRunning = this.config.enableSimulation\n\n this.points = new Points(device, this.config, this.store, this.graph)\n this.lines = new Lines(device, this.config, this.store, this.graph, this.points)\n if (this.config.enableSimulation) {\n this.forceGravity = new ForceGravity(device, this.config, this.store, this.graph, this.points)\n this.forceCenter = new ForceCenter(device, this.config, this.store, this.graph, this.points)\n this.forceManyBody = new ForceManyBody(device, this.config, this.store, this.graph, this.points)\n this.forceLinkIncoming = new ForceLink(device, this.config, this.store, this.graph, this.points)\n this.forceLinkOutgoing = new ForceLink(device, this.config, this.store, this.graph, this.points)\n this.forceMouse = new ForceMouse(device, this.config, this.store, this.graph, this.points)\n }\n this.clusters = new Clusters(device, this.config, this.store, this.graph, this.points)\n\n this.store.backgroundColor = getRgbaColor(this.config.backgroundColor)\n this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor ?? defaultConfigValues.hoveredPointRingColor)\n this.store.setFocusedPointRingColor(this.config.focusedPointRingColor ?? defaultConfigValues.focusedPointRingColor)\n if (this.config.focusedPointIndex !== undefined) {\n this.store.setFocusedPoint(this.config.focusedPointIndex)\n }\n this.store.setGreyoutPointColor(this.config.pointGreyoutColor ?? defaultGreyoutPointColor)\n this.store.setHoveredLinkColor(this.config.hoveredLinkColor ?? defaultConfigValues.hoveredLinkColor)\n\n this.store.updateLinkHoveringEnabled(this.config)\n\n if (this.config.showFPSMonitor) this.fpsMonitor = new FPSMonitor(this.canvas)\n\n if (this.config.randomSeed !== undefined) this.store.addRandomSeed(this.config.randomSeed)\n\n return device\n })\n .catch(error => {\n this.device = undefined\n this.isReady = false\n console.error('Device initialization failed:', error)\n throw error\n })\n\n this.ready = this.deviceInitPromise.then(() => undefined)\n }\n\n /**\n * Returns the current simulation progress\n */\n public get progress (): number {\n if (this._isDestroyed) return 0\n return this.store.simulationProgress\n }\n\n /**\n * A value that gives information about the running simulation status.\n */\n public get isSimulationRunning (): boolean {\n if (this._isDestroyed) return false\n return this.store.isSimulationRunning\n }\n\n /**\n * The maximum point size.\n * This value is the maximum size of the `gl.POINTS` primitive that WebGL can render on the user's hardware.\n */\n public get maxPointSize (): number {\n if (this._isDestroyed) return 0\n return this.store.maxPointSize\n }\n\n /**\n * Set or update Cosmos configuration. The changes will be applied in real time.\n * @param config Cosmos configuration object.\n */\n public setConfig (config: Partial<GraphConfigInterface>): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setConfig(config))) return\n const prevConfig = { ...this.config }\n this.config.init(config)\n if ((prevConfig.pointDefaultColor !== this.config.pointDefaultColor) ||\n (prevConfig.pointColor !== this.config.pointColor)) {\n this.graph.updatePointColor()\n this.points?.updateColor()\n }\n if ((prevConfig.pointDefaultSize !== this.config.pointDefaultSize) ||\n (prevConfig.pointSize !== this.config.pointSize)) {\n this.graph.updatePointSize()\n this.points?.updateSize()\n }\n if ((prevConfig.linkDefaultColor !== this.config.linkDefaultColor) ||\n (prevConfig.linkColor !== this.config.linkColor)) {\n this.graph.updateLinkColor()\n this.lines?.updateColor()\n }\n if ((prevConfig.linkDefaultWidth !== this.config.linkDefaultWidth) ||\n (prevConfig.linkWidth !== this.config.linkWidth)) {\n this.graph.updateLinkWidth()\n this.lines?.updateWidth()\n }\n if ((prevConfig.linkDefaultArrows !== this.config.linkDefaultArrows) ||\n (prevConfig.linkArrows !== this.config.linkArrows)) {\n this.graph.updateArrows()\n this.lines?.updateArrow()\n }\n if (prevConfig.curvedLinkSegments !== this.config.curvedLinkSegments ||\n prevConfig.curvedLinks !== this.config.curvedLinks) {\n this.lines?.updateCurveLineGeometry()\n }\n\n if (prevConfig.backgroundColor !== this.config.backgroundColor) {\n this.store.backgroundColor = getRgbaColor(this.config.backgroundColor ?? defaultBackgroundColor)\n }\n if (prevConfig.hoveredPointRingColor !== this.config.hoveredPointRingColor) {\n this.store.setHoveredPointRingColor(this.config.hoveredPointRingColor ?? defaultConfigValues.hoveredPointRingColor)\n }\n if (prevConfig.focusedPointRingColor !== this.config.focusedPointRingColor) {\n this.store.setFocusedPointRingColor(this.config.focusedPointRingColor ?? defaultConfigValues.focusedPointRingColor)\n }\n if (prevConfig.pointGreyoutColor !== this.config.pointGreyoutColor) {\n this.store.setGreyoutPointColor(this.config.pointGreyoutColor ?? defaultGreyoutPointColor)\n }\n if (prevConfig.hoveredLinkColor !== this.config.hoveredLinkColor) {\n this.store.setHoveredLinkColor(this.config.hoveredLinkColor ?? defaultConfigValues.hoveredLinkColor)\n }\n if (prevConfig.focusedPointIndex !== this.config.focusedPointIndex) {\n this.store.setFocusedPoint(this.config.focusedPointIndex)\n }\n if (prevConfig.pixelRatio !== this.config.pixelRatio) {\n // Update device's canvas context useDevicePixels\n if (this.device?.canvasContext) {\n this.device.canvasContext.setProps({ useDevicePixels: this.config.pixelRatio })\n\n // Recalculate maxPointSize with new pixelRatio\n this.store.maxPointSize = getMaxPointSize(this.device, this.config.pixelRatio)\n }\n }\n if (prevConfig.spaceSize !== this.config.spaceSize) {\n this.store.adjustSpaceSize(this.config.spaceSize, this.device?.limits.maxTextureDimension2D ?? 4096)\n this.resizeCanvas(true)\n this.update(this.store.isSimulationRunning ? this.store.alpha : 0)\n }\n if (prevConfig.showFPSMonitor !== this.config.showFPSMonitor) {\n if (this.config.showFPSMonitor) {\n this.fpsMonitor = new FPSMonitor(this.canvas)\n } else {\n this.fpsMonitor?.destroy()\n this.fpsMonitor = undefined\n }\n }\n if (prevConfig.enableZoom !== this.config.enableZoom || prevConfig.enableDrag !== this.config.enableDrag) {\n this.updateZoomDragBehaviors()\n }\n\n if (prevConfig.onLinkClick !== this.config.onLinkClick ||\n prevConfig.onLinkContextMenu !== this.config.onLinkContextMenu ||\n prevConfig.onLinkMouseOver !== this.config.onLinkMouseOver ||\n prevConfig.onLinkMouseOut !== this.config.onLinkMouseOut) {\n this.store.updateLinkHoveringEnabled(this.config)\n }\n }\n\n /**\n * Sets the positions for the graph points.\n *\n * @param {Float32Array} pointPositions - A Float32Array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn],\n * where `n` is the index of the point.\n * 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.\n * @param {boolean | undefined} dontRescale - For this call only, don't rescale the points.\n * - `true`: Don't rescale.\n * - `false` or `undefined` (default): Use the behavior defined by `config.rescalePositions`.\n */\n public setPointPositions (pointPositions: Float32Array, dontRescale?: boolean | undefined): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setPointPositions(pointPositions, dontRescale))) return\n this.graph.inputPointPositions = pointPositions\n this.points!.shouldSkipRescale = dontRescale\n this.isPointPositionsUpdateNeeded = true\n // Links related texture depends on point positions, so we need to update it\n this.isLinksUpdateNeeded = true\n // Point related textures depend on point positions length, so we need to update them\n this.isPointColorUpdateNeeded = true\n this.isPointSizeUpdateNeeded = true\n this.isPointShapeUpdateNeeded = true\n this.isPointImageIndicesUpdateNeeded = true\n this.isPointImageSizesUpdateNeeded = true\n this.isPointClusterUpdateNeeded = true\n this.isForceManyBodyUpdateNeeded = true\n this.isForceLinkUpdateNeeded = true\n this.isForceCenterUpdateNeeded = true\n }\n\n /**\n * Sets the colors for the graph points.\n *\n * @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],\n * where each color is represented in RGBA format.\n * Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first point to red and the second point to green.\n */\n public setPointColors (pointColors: Float32Array): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setPointColors(pointColors))) return\n this.graph.inputPointColors = pointColors\n this.isPointColorUpdateNeeded = true\n }\n\n /**\n * Gets the current colors of the graph points.\n *\n * @returns {Float32Array} A Float32Array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an],\n * where each color is in RGBA format. Returns an empty Float32Array if no point colors are set.\n */\n public getPointColors (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.pointColors ?? new Float32Array()\n }\n\n /**\n * Sets the sizes for the graph points.\n *\n * @param {Float32Array} pointSizes - A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen],\n * where `n` is the index of the point.\n * 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.\n */\n public setPointSizes (pointSizes: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointSizes(pointSizes))) return\n this.graph.inputPointSizes = pointSizes\n this.isPointSizeUpdateNeeded = true\n }\n\n /**\n * Sets the shapes for the graph points.\n *\n * @param {Float32Array} pointShapes - A Float32Array representing the shapes of points in the format [shape1, shape2, ..., shapen],\n * where `n` is the index of the point and each shape value corresponds to a PointShape enum:\n * 0 = Circle, 1 = Square, 2 = Triangle, 3 = Diamond, 4 = Pentagon, 5 = Hexagon, 6 = Star, 7 = Cross, 8 = None.\n * Example: `new Float32Array([0, 1, 2])` sets the first point to Circle, the second point to Square, and the third point to Triangle.\n * Images are rendered above shapes.\n */\n public setPointShapes (pointShapes: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointShapes(pointShapes))) return\n this.graph.inputPointShapes = pointShapes\n this.isPointShapeUpdateNeeded = true\n }\n\n /**\n * Sets the images for the graph points using ImageData objects.\n * Images are rendered above shapes.\n * To use images, provide image indices via setPointImageIndices().\n *\n * @param {ImageData[]} imageDataArray - Array of ImageData objects to use as point images.\n * Example: `setImageData([imageData1, imageData2, imageData3])`\n */\n public setImageData (imageDataArray: ImageData[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setImageData(imageDataArray))) return\n this.graph.inputImageData = imageDataArray\n this.points?.createAtlas()\n }\n\n /**\n * Sets which image each point should use from the images array.\n * Images are rendered above shapes.\n *\n * @param {Float32Array} imageIndices - A Float32Array representing which image each point uses in the format [index1, index2, ..., indexn],\n * where `n` is the index of the point and each value is an index into the images array provided to `setImageData`.\n * 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.\n */\n public setPointImageIndices (imageIndices: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointImageIndices(imageIndices))) return\n this.graph.inputPointImageIndices = imageIndices\n this.isPointImageIndicesUpdateNeeded = true\n }\n\n /**\n * Sets the sizes for the point images.\n *\n * @param {Float32Array} imageSizes - A Float32Array representing the sizes of point images in the format [size1, size2, ..., sizen],\n * where `n` is the index of the point.\n * 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.\n */\n public setPointImageSizes (imageSizes: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointImageSizes(imageSizes))) return\n this.graph.inputPointImageSizes = imageSizes\n this.isPointImageSizesUpdateNeeded = true\n }\n\n /**\n * Gets the current sizes of the graph points.\n *\n * @returns {Float32Array} A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen],\n * where `n` is the index of the point. Returns an empty Float32Array if no point sizes are set.\n */\n public getPointSizes (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.pointSizes ?? new Float32Array()\n }\n\n /**\n * Sets the links for the graph.\n *\n * @param {Float32Array} links - A Float32Array representing the links between points\n * in the format [source1, target1, source2, target2, ..., sourcen, targetn],\n * where `source` and `target` are the indices of the points being linked.\n * 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.\n */\n public setLinks (links: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinks(links))) return\n this.graph.inputLinks = links\n this.isLinksUpdateNeeded = true\n // Links related texture depends on links length, so we need to update it\n this.isLinkColorUpdateNeeded = true\n this.isLinkWidthUpdateNeeded = true\n this.isLinkArrowUpdateNeeded = true\n this.isForceLinkUpdateNeeded = true\n }\n\n /**\n * Sets the colors for the graph links.\n *\n * @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],\n * where each color is in RGBA format.\n * Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first link to red and the second link to green.\n */\n public setLinkColors (linkColors: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkColors(linkColors))) return\n this.graph.inputLinkColors = linkColors\n this.isLinkColorUpdateNeeded = true\n }\n\n /**\n * Gets the current colors of the graph links.\n *\n * @returns {Float32Array} A Float32Array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an],\n * where each color is in RGBA format. Returns an empty Float32Array if no link colors are set.\n */\n public getLinkColors (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.linkColors ?? new Float32Array()\n }\n\n /**\n * Sets the widths for the graph links.\n *\n * @param {Float32Array} linkWidths - A Float32Array representing the widths of links in the format [width1, width2, ..., widthn],\n * where `n` is the index of the link.\n * 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.\n */\n public setLinkWidths (linkWidths: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkWidths(linkWidths))) return\n this.graph.inputLinkWidths = linkWidths\n this.isLinkWidthUpdateNeeded = true\n }\n\n /**\n * Gets the current widths of the graph links.\n *\n * @returns {Float32Array} A Float32Array representing the widths of links in the format [width1, width2, ..., widthn],\n * where `n` is the index of the link. Returns an empty Float32Array if no link widths are set.\n */\n public getLinkWidths (): Float32Array {\n if (this._isDestroyed) return new Float32Array()\n return this.graph.linkWidths ?? new Float32Array()\n }\n\n /**\n * Sets the arrows for the graph links.\n *\n * @param {boolean[]} linkArrows - An array of booleans indicating whether each link should have an arrow,\n * in the format [arrow1, arrow2, ..., arrown], where `n` is the index of the link.\n * Example: `[true, false, true]` sets arrows on the first and third links, but not on the second link.\n */\n public setLinkArrows (linkArrows: boolean[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkArrows(linkArrows))) return\n this.graph.linkArrowsBoolean = linkArrows\n this.isLinkArrowUpdateNeeded = true\n }\n\n /**\n * Sets the strength for the graph links.\n *\n * @param {Float32Array} linkStrength - A Float32Array representing the strength of each link in the format [strength1, strength2, ..., strengthn],\n * where `n` is the index of the link.\n * 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.\n */\n public setLinkStrength (linkStrength: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setLinkStrength(linkStrength))) return\n this.graph.inputLinkStrength = linkStrength\n this.isForceLinkUpdateNeeded = true\n }\n\n /**\n * Sets the point clusters for the graph.\n *\n * @param {(number | undefined)[]} pointClusters - Array of cluster indices for each point in the graph.\n * - Index: Each index corresponds to a point.\n * - Values: Integers starting from 0; `undefined` indicates that a point does not belong to any cluster and will not be affected by cluster forces.\n * @example\n * `[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.\n * Points 4 is unclustered.\n * @note Clusters without specified positions via `setClusterPositions` will be positioned at their centermass by default.\n */\n public setPointClusters (pointClusters: (number | undefined)[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointClusters(pointClusters))) return\n this.graph.inputPointClusters = pointClusters\n this.isPointClusterUpdateNeeded = true\n }\n\n /**\n * Sets the positions of the point clusters for the graph.\n *\n * @param {(number | undefined)[]} clusterPositions - Array of cluster positions.\n * - Every two elements represent the x and y coordinates for a cluster position.\n * - `undefined` means the cluster's position is not defined and will use centermass positioning instead.\n * @example\n * `[10, 20, 30, 40, undefined, undefined]` places the first cluster at (10, 20) and the second at (30, 40);\n * the third cluster will be positioned at its centermass automatically.\n */\n public setClusterPositions (clusterPositions: (number | undefined)[]): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setClusterPositions(clusterPositions))) return\n this.graph.inputClusterPositions = clusterPositions\n this.isPointClusterUpdateNeeded = true\n }\n\n /**\n * Sets the force strength coefficients for clustering points in the graph.\n *\n * This method allows you to customize the forces acting on individual points during the clustering process.\n * The force coefficients determine the strength of the forces applied to each point.\n *\n * @param {Float32Array} clusterStrength - A Float32Array of force strength coefficients for each point in the format [coeff1, coeff2, ..., coeffn],\n * where `n` is the index of the point.\n * 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.\n */\n public setPointClusterStrength (clusterStrength: Float32Array): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPointClusterStrength(clusterStrength))) return\n this.graph.inputClusterStrength = clusterStrength\n this.isPointClusterUpdateNeeded = true\n }\n\n /**\n * Sets which points are pinned (fixed) in position.\n *\n * Pinned points:\n * - Do not move due to physics forces (gravity, repulsion, link forces, etc.)\n * - Still participate in force calculations (other nodes are attracted to/repelled by them)\n * - Can still be dragged by the user if `enableDrag` is true\n *\n * @param {number[] | null} pinnedIndices - Array of point indices to pin. Set to `[]` or `null` to unpin all points.\n * @example\n * // Pin points 0 and 5\n * graph.setPinnedPoints([0, 5])\n *\n * // Unpin all points\n * graph.setPinnedPoints([])\n * graph.setPinnedPoints(null)\n */\n public setPinnedPoints (pinnedIndices: number[] | null): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.setPinnedPoints(pinnedIndices))) return\n this.graph.inputPinnedPoints = pinnedIndices && pinnedIndices.length > 0 ? pinnedIndices : undefined\n this.points?.updatePinnedStatus()\n }\n\n /**\n * Renders the graph and starts rendering.\n * Does NOT modify simulation state - use start(), stop(), pause(), unpause() to control simulation.\n *\n * @param {number} [simulationAlpha] - Optional alpha value to set.\n * - If 0: Sets alpha to 0, simulation stops after one frame (graph becomes static).\n * - If positive: Sets alpha to that value.\n * - If undefined: Keeps current alpha value.\n */\n public render (simulationAlpha?: number): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.render(simulationAlpha))) return\n this.graph.update()\n const { fitViewOnInit, fitViewDelay, fitViewPadding, fitViewDuration, fitViewByPointsInRect, fitViewByPointIndices, initialZoomLevel } = this.config\n if (!this.graph.pointsNumber && !this.graph.linksNumber) {\n this.stopFrames()\n select(this.canvas).style('cursor', null)\n if (this.device) {\n const clearPass = this.device.beginRenderPass({\n clearColor: this.store.backgroundColor,\n clearDepth: 1,\n clearStencil: 0,\n })\n clearPass.end()\n this.device.submit()\n }\n return\n }\n\n // If `initialZoomLevel` is set, we don't need to fit the view\n if (this._isFirstRenderAfterInit && fitViewOnInit && initialZoomLevel === undefined) {\n this._fitViewOnInitTimeoutID = window.setTimeout(() => {\n if (fitViewByPointIndices) this.fitViewByPointIndices(fitViewByPointIndices, fitViewDuration, fitViewPadding)\n else if (fitViewByPointsInRect) {\n this.setZoomTransformByPointPositions(\n new Float32Array(this.flatten(fitViewByPointsInRect)),\n fitViewDuration,\n undefined,\n fitViewPadding\n )\n } else this.fitView(fitViewDuration, fitViewPadding)\n }, fitViewDelay)\n }\n // Update graph and start frames\n this.update(simulationAlpha)\n this.startFrames()\n\n this._isFirstRenderAfterInit = false\n }\n\n /**\n * Center the view on a point and zoom in, by point index.\n * @param index The index of the point in the array of points.\n * @param duration Duration of the animation transition in milliseconds (`700` by default).\n * @param scale Scale value to zoom in or out (`3` by default).\n * @param canZoomOut Set to `false` to prevent zooming out from the point (`true` by default).\n */\n public zoomToPointByIndex (index: number, duration = 700, scale = defaultScaleToZoom, canZoomOut = true): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.zoomToPointByIndex(index, duration, scale, canZoomOut))) return\n if (!this.device || !this.points || !this.canvasD3Selection) return\n const { store: { screenSize } } = this\n const positionPixels = readPixels(this.device, this.points.currentPositionFbo as Framebuffer)\n if (index === undefined) return\n const posX = positionPixels[index * 4 + 0]\n const posY = positionPixels[index * 4 + 1]\n if (posX === undefined || posY === undefined) return\n const distance = this.zoomInstance.getDistanceToPoint([posX, posY])\n const zoomLevel = canZoomOut ? scale : Math.max(this.getZoomLevel(), scale)\n if (distance < Math.min(screenSize[0], screenSize[1])) {\n this.setZoomTransformByPointPositions(new Float32Array([posX, posY]), duration, zoomLevel)\n } else {\n const transform = this.zoomInstance.getTransform([posX, posY], zoomLevel)\n const middle = this.zoomInstance.getMiddlePointTransform([posX, posY])\n this.canvasD3Selection\n .transition()\n .ease(easeQuadIn)\n .duration(duration / 2)\n .call(this.zoomInstance.behavior.transform, middle)\n .transition()\n .ease(easeQuadOut)\n .duration(duration / 2)\n .call(this.zoomInstance.behavior.transform, transform)\n }\n }\n\n /**\n * Zoom the view in or out to the specified zoom level.\n * @param value Zoom level\n * @param duration Duration of the zoom in/out transition.\n */\n\n public zoom (value: number, duration = 0): void {\n if (this._isDestroyed) return\n this.setZoomLevel(value, duration)\n }\n\n /**\n * Zoom the view in or out to the specified zoom level.\n * @param value Zoom level\n * @param duration Duration of the zoom in/out transition.\n */\n public setZoomLevel (value: number, duration = 0): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setZoomLevel(value, duration))) return\n\n if (!this.canvasD3Selection) return\n\n if (duration === 0) {\n this.canvasD3Selection\n .call(this.zoomInstance.behavior.scaleTo, value)\n } else {\n this.canvasD3Selection\n .transition()\n .duration(duration)\n .call(this.zoomInstance.behavior.scaleTo, value)\n }\n }\n\n /**\n * Get zoom level.\n * @returns Zoom level value of the view.\n */\n public getZoomLevel (): number {\n if (this._isDestroyed) return 0\n return this.zoomInstance.eventTransform.k\n }\n\n /**\n * Get current X and Y coordinates of the points.\n * @returns Array of point positions.\n */\n public getPointPositions (): number[] {\n if (this._isDestroyed || !this.device || !this.points) return []\n if (this.graph.pointsNumber === undefined) return []\n const positions: number[] = []\n const pointPositionsPixels = readPixels(this.device, this.points.currentPositionFbo as Framebuffer)\n positions.length = this.graph.pointsNumber * 2\n for (let i = 0; i < this.graph.pointsNumber; i += 1) {\n const posX = pointPositionsPixels[i * 4 + 0]\n const posY = pointPositionsPixels[i * 4 + 1]\n if (posX !== undefined && posY !== undefined) {\n positions[i * 2] = posX\n positions[i * 2 + 1] = posY\n }\n }\n return positions\n }\n\n /**\n * Get current X and Y coordinates of the clusters.\n * @returns Array of point cluster.\n */\n public getClusterPositions (): number[] {\n if (this._isDestroyed || !this.device || !this.clusters) return []\n if (this.graph.pointClusters === undefined || this.clusters.clusterCount === undefined) return []\n this.clusters.calculateCentermass()\n const positions: number[] = []\n const clusterPositionsPixels = readPixels(this.device, this.clusters.centermassFbo as Framebuffer)\n positions.length = this.clusters.clusterCount * 2\n for (let i = 0; i < positions.length / 2; i += 1) {\n const sumX = clusterPositionsPixels[i * 4 + 0]\n const sumY = clusterPositionsPixels[i * 4 + 1]\n const sumN = clusterPositionsPixels[i * 4 + 2]\n if (sumX !== undefined && sumY !== undefined && sumN !== undefined) {\n positions[i * 2] = sumX / sumN\n positions[i * 2 + 1] = sumY / sumN\n }\n }\n return positions\n }\n\n /**\n * Center and zoom in/out the view to fit all points in the scene.\n * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default).\n * @param padding Padding around the viewport in percentage (`0.1` by default).\n */\n public fitView (duration = 250, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.fitView(duration, padding))) return\n\n this.setZoomTransformByPointPositions(new Float32Array(this.getPointPositions()), duration, undefined, padding)\n }\n\n /**\n * Center and zoom in/out the view to fit points by their indices in the scene.\n * @param indices Point indices to fit in the view.\n * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default).\n * @param padding Padding around the viewport in percentage (`0.1` by default).\n */\n public fitViewByPointIndices (indices: number[], duration = 250, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.fitViewByPointIndices(indices, duration, padding))) return\n const positionsArray = this.getPointPositions()\n const positions = new Float32Array(indices.length * 2)\n for (const [i, index] of indices.entries()) {\n positions[i * 2] = positionsArray[index * 2] as number\n positions[i * 2 + 1] = positionsArray[index * 2 + 1] as number\n }\n this.setZoomTransformByPointPositions(positions, duration, undefined, padding)\n }\n\n /**\n * Center and zoom in/out the view to fit points by their positions in the scene.\n * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]`.\n * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default).\n * @param padding Padding around the viewport in percentage (`0.1` by default).\n */\n public fitViewByPointPositions (positions: number[], duration = 250, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.fitViewByPointPositions(positions, duration, padding))) return\n\n this.setZoomTransformByPointPositions(new Float32Array(positions), duration, undefined, padding)\n }\n\n /**\n * Sets the zoom transform so that the given point positions fit in the viewport, with optional animation.\n *\n * @param positions Flat array of point coordinates as `[x0, y0, x1, y1, ...]`.\n * @param duration Animation duration in milliseconds. Default `250`.\n * @param scale Optional scale factor; if omitted, scale is chosen to fit the positions.\n * @param padding Padding around the viewport as a fraction (e.g. `0.1` = 10%). Default `0.1`.\n */\n public setZoomTransformByPointPositions (positions: Float32Array, duration = 250, scale?: number, padding = 0.1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.setZoomTransformByPointPositions(positions, duration, scale, padding))) return\n\n this.resizeCanvas()\n const transform = this.zoomInstance.getTransform(positions, scale, padding)\n this.canvasD3Selection\n ?.transition()\n .ease(easeQuadInOut)\n .duration(duration)\n .call(this.zoomInstance.behavior.transform, transform)\n }\n\n /**\n * Get points indices inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas.\n * @returns A Float32Array containing the indices of points inside a rectangular area.\n */\n public getPointsInRect (selection: [[number, number], [number, number]]): Float32Array {\n if (this._isDestroyed || !this.device || !this.points) return new Float32Array()\n const h = this.store.screenSize[1]\n this.store.selectedArea = [[selection[0][0], (h - selection[1][1])], [selection[1][0], (h - selection[0][1])]]\n this.points.findPointsOnAreaSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n\n return pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n }\n\n /**\n * Get points indices inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas.\n * @returns A Float32Array containing the indices of points inside a rectangular area.\n * @deprecated Use `getPointsInRect` instead. This method will be removed in a future version.\n */\n public getPointsInRange (selection: [[number, number], [number, number]]): Float32Array {\n return this.getPointsInRect(selection)\n }\n\n /**\n * Get points indices inside a polygon area.\n * @param polygonPath - Array of points `[[x1, y1], [x2, y2], ..., [xn, yn]]` that defines the polygon.\n * The coordinates should be from 0 to the width/height of the canvas.\n * @returns A Float32Array containing the indices of points inside the polygon area.\n */\n public getPointsInPolygon (polygonPath: [number, number][]): Float32Array {\n if (this._isDestroyed || !this.device || !this.points) return new Float32Array()\n if (polygonPath.length < 3) return new Float32Array() // Need at least 3 points for a polygon\n\n const h = this.store.screenSize[1]\n // Convert coordinates to WebGL coordinate system (flip Y)\n const convertedPath = polygonPath.map(([x, y]) => [x, h - y] as [number, number])\n this.points.updatePolygonPath(convertedPath)\n this.points.findPointsOnPolygonSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n\n return pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n }\n\n /** Select points inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas. */\n public selectPointsInRect (selection: [[number, number], [number, number]] | null): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.selectPointsInRect(selection))) return\n if (!this.device || !this.points) return\n if (selection) {\n const h = this.store.screenSize[1]\n this.store.selectedArea = [[selection[0][0], (h - selection[1][1])], [selection[1][0], (h - selection[0][1])]]\n this.points.findPointsOnAreaSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n this.store.selectedIndices = pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n } else {\n this.store.selectedIndices = null\n }\n this.points.updateGreyoutStatus()\n }\n\n /** Select points inside a rectangular area.\n * @param selection - Array of two corner points `[[left, top], [right, bottom]]`.\n * The `left` and `right` coordinates should be from 0 to the width of the canvas.\n * The `top` and `bottom` coordinates should be from 0 to the height of the canvas.\n * @deprecated Use `selectPointsInRect` instead. This method will be removed in a future version.\n */\n public selectPointsInRange (selection: [[number, number], [number, number]] | null): void {\n return this.selectPointsInRect(selection)\n }\n\n /** Select points inside a polygon area.\n * @param polygonPath - Array of points `[[x1, y1], [x2, y2], ..., [xn, yn]]` that defines the polygon.\n * The coordinates should be from 0 to the width/height of the canvas.\n * Set to null to clear selection. */\n public selectPointsInPolygon (polygonPath: [number, number][] | null): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.selectPointsInPolygon(polygonPath))) return\n if (!this.device || !this.points) return\n if (polygonPath) {\n if (polygonPath.length < 3) {\n console.warn('Polygon path requires at least 3 points to form a polygon.')\n return\n }\n\n const h = this.store.screenSize[1]\n // Convert coordinates to WebGL coordinate system (flip Y)\n const convertedPath = polygonPath.map(([x, y]) => [x, h - y] as [number, number])\n this.points.updatePolygonPath(convertedPath)\n this.points.findPointsOnPolygonSelection()\n const pixels = readPixels(this.device, this.points.selectedFbo as Framebuffer)\n this.store.selectedIndices = pixels\n .map((pixel, i) => {\n if (i % 4 === 0 && pixel !== 0) return i / 4\n else return -1\n })\n .filter(d => d !== -1)\n } else {\n this.store.selectedIndices = null\n }\n this.points.updateGreyoutStatus()\n }\n\n /**\n * Select a point by index. If you want the adjacent points to get selected too, provide `true` as the second argument.\n * @param index The index of the point in the array of points.\n * @param selectAdjacentPoints When set to `true`, selects adjacent points (`false` by default).\n */\n public selectPointByIndex (index: number, selectAdjacentPoints = false): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.selectPointByIndex(index, selectAdjacentPoints))) return\n if (selectAdjacentPoints) {\n const adjacentIndices = this.graph.getAdjacentIndices(index) ?? []\n this.selectPointsByIndices([index, ...adjacentIndices])\n } else this.selectPointsByIndices([index])\n }\n\n /**\n * Select multiples points by their indices.\n * @param indices Array of points indices.\n */\n public selectPointsByIndices (indices?: (number | undefined)[] | null): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.selectPointsByIndices(indices))) return\n if (!this.points) return\n if (!indices) {\n this.store.selectedIndices = null\n } else if (indices.length === 0) {\n this.store.selectedIndices = new Float32Array()\n } else {\n this.store.selectedIndices = new Float32Array(indices.filter(d => d !== undefined))\n }\n\n this.points.updateGreyoutStatus()\n }\n\n /**\n * Unselect all points.\n */\n public unselectPoints (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.unselectPoints())) return\n if (!this.points) return\n this.store.selectedIndices = null\n this.points.updateGreyoutStatus()\n }\n\n /**\n * Get indices of points that are currently selected.\n * @returns Array of selected indices of points.\n */\n public getSelectedIndices (): number[] | null {\n if (this._isDestroyed) return null\n const { selectedIndices } = this.store\n if (!selectedIndices) return null\n return Array.from(selectedIndices)\n }\n\n /**\n * Get indices that are adjacent to a specific point by its index.\n * @param index Index of the point.\n * @returns Array of adjacent indices.\n */\n\n public getAdjacentIndices (index: number): number[] | undefined {\n if (this._isDestroyed) return undefined\n return this.graph.getAdjacentIndices(index)\n }\n\n /**\n * Converts the X and Y point coordinates from the space coordinate system to the screen coordinate system.\n * @param spacePosition Array of x and y coordinates in the space coordinate system.\n * @returns Array of x and y coordinates in the screen coordinate system.\n */\n public spaceToScreenPosition (spacePosition: [number, number]): [number, number] {\n if (this._isDestroyed) return [0, 0]\n return this.zoomInstance.convertSpaceToScreenPosition(spacePosition)\n }\n\n /**\n * Converts the X and Y point coordinates from the screen coordinate system to the space coordinate system.\n * @param screenPosition Array of x and y coordinates in the screen coordinate system.\n * @returns Array of x and y coordinates in the space coordinate system.\n */\n public screenToSpacePosition (screenPosition: [number, number]): [number, number] {\n if (this._isDestroyed) return [0, 0]\n return this.zoomInstance.convertScreenToSpacePosition(screenPosition)\n }\n\n /**\n * Converts the point radius value from the space coordinate system to the screen coordinate system.\n * @param spaceRadius Radius of point in the space coordinate system.\n * @returns Radius of point in the screen coordinate system.\n */\n public spaceToScreenRadius (spaceRadius: number): number {\n if (this._isDestroyed) return 0\n return this.zoomInstance.convertSpaceToScreenRadius(spaceRadius)\n }\n\n /**\n * Get point radius by its index.\n * @param index Index of the point.\n * @returns Radius of the point.\n */\n public getPointRadiusByIndex (index: number): number | undefined {\n if (this._isDestroyed) return undefined\n return this.graph.pointSizes?.[index]\n }\n\n /**\n * Track multiple point positions by their indices on each Cosmos tick.\n * @param indices Array of points indices.\n */\n public trackPointPositionsByIndices (indices: number[]): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.trackPointPositionsByIndices(indices))) return\n if (!this.points) return\n this.points.trackPointsByIndices(indices)\n }\n\n /**\n * Get current X and Y coordinates of the tracked points.\n * Do not mutate the returned map - it may affect future calls.\n * @returns A ReadonlyMap where keys are point indices and values are their corresponding X and Y coordinates in the [number, number] format.\n * @see trackPointPositionsByIndices To set which points should be tracked\n */\n public getTrackedPointPositionsMap (): ReadonlyMap<number, [number, number]> {\n if (this._isDestroyed || !this.points) return new Map()\n return this.points.getTrackedPositionsMap()\n }\n\n /**\n * Get current X and Y coordinates of the tracked points as an array.\n * @returns Array of point positions in the format [x1, y1, x2, y2, ..., xn, yn] for tracked points only.\n * The positions are ordered by the tracking indices (same order as provided to trackPointPositionsByIndices).\n * Returns an empty array if no points are being tracked.\n */\n public getTrackedPointPositionsArray (): number[] {\n if (this._isDestroyed || !this.points) return []\n return this.points.getTrackedPositionsArray()\n }\n\n /**\n * For the points that are currently visible on the screen, get a sample of point indices with their coordinates.\n * The resulting number of points will depend on the `pointSamplingDistance` configuration property,\n * and the sampled points will be evenly distributed.\n * @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.\n */\n public getSampledPointPositionsMap (): Map<number, [number, number]> {\n if (this._isDestroyed || !this.points) return new Map()\n return this.points.getSampledPointPositionsMap()\n }\n\n /**\n * For the points that are currently visible on the screen, get a sample of point indices and positions.\n * The resulting number of points will depend on the `pointSamplingDistance` configuration property,\n * and the sampled points will be evenly distributed.\n * @returns An object containing arrays of point indices and positions.\n */\n public getSampledPoints (): { indices: number[]; positions: number[] } {\n if (this._isDestroyed || !this.points) return { indices: [], positions: [] }\n return this.points.getSampledPoints()\n }\n\n /**\n * Gets the X-axis of rescaling function.\n *\n * This scale is automatically created when position rescaling is enabled.\n */\n public getScaleX (): ((x: number) => number) | undefined {\n if (this._isDestroyed || !this.points) return undefined\n return this.points.scaleX\n }\n\n /**\n * Gets the Y-axis of rescaling function.\n *\n * This scale is automatically created when position rescaling is enabled.\n */\n public getScaleY (): ((y: number) => number) | undefined {\n if (this._isDestroyed || !this.points) return undefined\n return this.points.scaleY\n }\n\n /**\n * Start the simulation.\n * This only controls the simulation state, not rendering.\n * @param alpha Value from 0 to 1. The higher the value, the more initial energy the simulation will get.\n */\n public start (alpha = 1): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.start(alpha))) return\n\n if (!this.graph.pointsNumber) return\n\n // Always set simulation as running when start() is called\n this.store.isSimulationRunning = true\n this.store.simulationProgress = 0\n this.store.alpha = alpha\n this.config.onSimulationStart?.()\n\n // Note: Does NOT start frames - that's handled separately\n }\n\n /**\n * Stop the simulation. This stops the simulation and resets its state.\n * Use start() to begin a new simulation cycle.\n */\n public stop (): void {\n if (this._isDestroyed) return\n this.store.isSimulationRunning = false\n this.store.simulationProgress = 0\n this.store.alpha = 0\n this.config.onSimulationEnd?.()\n }\n\n /**\n * Pause the simulation. When paused, the simulation stops running\n * but preserves its current state (progress, alpha).\n * Can be resumed using the unpause method.\n */\n public pause (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.pause())) return\n this.store.isSimulationRunning = false\n this.config.onSimulationPause?.()\n }\n\n /**\n * Unpause the simulation. This method resumes a paused\n * simulation and continues its execution.\n */\n public unpause (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.unpause())) return\n this.store.isSimulationRunning = true\n this.config.onSimulationUnpause?.()\n }\n\n /**\n * Restart/Resume the simulation. This method unpauses a paused\n * simulation and resumes its execution.\n * @deprecated Use `unpause()` instead. This method will be removed in a future version.\n */\n public restart (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.restart())) return\n this.store.isSimulationRunning = true\n this.config.onSimulationRestart?.()\n }\n\n /**\n * Run one step of the simulation manually.\n * Works even when the simulation is paused.\n */\n public step (): void {\n if (this._isDestroyed) return\n\n if (this.ensureDevice(() => this.step())) return\n\n if (!this.config.enableSimulation) return\n if (!this.store.pointsTextureSize) return\n\n // Run one simulation step, forcing execution regardless of isSimulationRunning\n this.runSimulationStep(true)\n }\n\n /**\n * Destroy this Cosmos instance.\n */\n public destroy (): void {\n if (this._isDestroyed) return\n this._isDestroyed = true\n this.isReady = false\n window.clearTimeout(this._fitViewOnInitTimeoutID)\n this.stopFrames()\n\n // Remove all event listeners\n if (this.canvasD3Selection) {\n this.canvasD3Selection\n .on('mouseenter.cosmos', null)\n .on('mousemove.cosmos', null)\n .on('mouseleave.cosmos', null)\n .on('click', null)\n .on('mousemove', null)\n .on('contextmenu', null)\n .on('.drag', null)\n .on('.zoom', null)\n }\n\n select(document)\n .on('keydown.cosmos', null)\n .on('keyup.cosmos', null)\n\n if (this.zoomInstance?.behavior) {\n this.zoomInstance.behavior\n .on('start.detect', null)\n .on('zoom.detect', null)\n .on('end.detect', null)\n }\n\n if (this.dragInstance?.behavior) {\n this.dragInstance.behavior\n .on('start.detect', null)\n .on('drag.detect', null)\n .on('end.detect', null)\n }\n\n this.fpsMonitor?.destroy()\n\n // Destroy all module resources before destroying the device\n this.points?.destroy()\n this.lines?.destroy()\n this.clusters?.destroy()\n this.forceGravity?.destroy()\n this.forceCenter?.destroy()\n this.forceManyBody?.destroy()\n this.forceLinkIncoming?.destroy()\n this.forceLinkOutgoing?.destroy()\n this.forceMouse?.destroy()\n\n if (this.device) {\n // Only clear and destroy the device if Graph owns it\n if (this.shouldDestroyDevice) {\n // Clears the canvas after particle system is destroyed\n const clearPass = this.device.beginRenderPass({\n clearColor: this.store.backgroundColor,\n clearDepth: 1,\n clearStencil: 0,\n })\n clearPass.end()\n this.device.submit()\n this.device.destroy()\n }\n }\n\n // Only remove canvas if Graph owns the device (canvas was created by Graph)\n if (this.shouldDestroyDevice && this.canvas && this.canvas.parentNode) {\n this.canvas.parentNode.removeChild(this.canvas)\n }\n\n if (this.attributionDivElement && this.attributionDivElement.parentNode) {\n this.attributionDivElement.parentNode.removeChild(this.attributionDivElement)\n }\n\n document.getElementById('gl-bench-style')?.remove()\n\n this.canvasD3Selection = undefined\n this.attributionDivElement = undefined\n }\n\n /**\n * Updates and recreates the graph visualization based on pending changes.\n */\n public create (): void {\n if (this._isDestroyed) return\n if (this.ensureDevice(() => this.create())) return\n if (!this.points) return\n if (!this.lines) return\n if (this.isPointPositionsUpdateNeeded) this.points.updatePositions()\n if (this.isPointColorUpdateNeeded) this.points.updateColor()\n if (this.isPointSizeUpdateNeeded) this.points.updateSize()\n if (this.isPointShapeUpdateNeeded) this.points.updateShape()\n if (this.isPointImageIndicesUpdateNeeded) this.points.updateImageIndices()\n if (this.isPointImageSizesUpdateNeeded) this.points.updateImageSizes()\n\n if (this.isLinksUpdateNeeded) this.lines.updatePointsBuffer()\n if (this.isLinkColorUpdateNeeded) this.lines.updateColor()\n if (this.isLinkWidthUpdateNeeded) this.lines.updateWidth()\n if (this.isLinkArrowUpdateNeeded) this.lines.updateArrow()\n\n if (this.isForceManyBodyUpdateNeeded) this.forceManyBody?.create()\n if (this.isForceLinkUpdateNeeded) {\n this.forceLinkIncoming?.create(LinkDirection.INCOMING)\n this.forceLinkOutgoing?.create(LinkDirection.OUTGOING)\n }\n if (this.isForceCenterUpdateNeeded) this.forceCenter?.create()\n if (this.isPointClusterUpdateNeeded) this.clusters?.create()\n\n this.isPointPositionsUpdateNeeded = false\n this.isPointColorUpdateNeeded = false\n this.isPointSizeUpdateNeeded = false\n this.isPointShapeUpdateNeeded = false\n this.isPointImageIndicesUpdateNeeded = false\n this.isPointImageSizesUpdateNeeded = false\n this.isLinksUpdateNeeded = false\n this.isLinkColorUpdateNeeded = false\n this.isLinkWidthUpdateNeeded = false\n this.isLinkArrowUpdateNeeded = false\n this.isPointClusterUpdateNeeded = false\n this.isForceManyBodyUpdateNeeded = false\n this.isForceLinkUpdateNeeded = false\n this.isForceCenterUpdateNeeded = false\n }\n\n /**\n * Converts an array of tuple positions to a single array containing all coordinates sequentially\n * @param pointPositions An array of tuple positions\n * @returns A flatten array of coordinates\n */\n public flatten (pointPositions: [number, number][]): number[] {\n return pointPositions.flat()\n }\n\n /**\n * Converts a flat array of point positions to a tuple pairs representing coordinates\n * @param pointPositions A flattened array of coordinates\n * @returns An array of tuple positions\n */\n public pair (pointPositions: number[]): [number, number][] {\n const arr = new Array(pointPositions.length / 2) as [number, number][]\n for (let i = 0; i < pointPositions.length / 2; i++) {\n arr[i] = [pointPositions[i * 2] as number, pointPositions[i * 2 + 1] as number]\n }\n\n return arr\n }\n\n /**\n * Ensures device is initialized before executing a method.\n * If device is not ready, queues the method to run after initialization.\n * @param callback - Function to execute once device is ready\n * @returns true if device was not ready and operation was queued, false if device is ready\n */\n private ensureDevice (callback: () => void): boolean {\n if (!this.isReady) {\n this.ready\n .then(() => {\n if (this._isDestroyed) return\n callback()\n })\n .catch(error => {\n console.error('Device initialization failed', error)\n })\n return true\n }\n return false\n }\n\n /**\n * Validates that a device has the required HTMLCanvasElement canvas context.\n * Cosmos requires an HTMLCanvasElement canvas context and does not support\n * OffscreenCanvas or compute-only devices.\n * @param device - The device to validate\n * @returns The validated canvas context (guaranteed to be non-null and HTMLCanvasElement type)\n * @throws Error if the device does not meet Cosmos requirements\n */\n private validateDevice (device: Device): NonNullable<Device['canvasContext']> {\n const deviceCanvasContext = device.canvasContext\n // Cosmos requires an HTMLCanvasElement canvas context.\n // OffscreenCanvas and compute-only devices are not supported.\n if (deviceCanvasContext === null || deviceCanvasContext.type === 'offscreen-canvas') {\n throw new Error('Device must have an HTMLCanvasElement canvas context. OffscreenCanvas and compute-only devices are not supported.')\n }\n return deviceCanvasContext\n }\n\n /**\n * Internal device creation method\n * Graph class decides what device to create with sensible defaults\n */\n private async createDevice (\n canvas: HTMLCanvasElement\n ): Promise<Device> {\n return await luma.createDevice({\n type: 'webgl',\n adapters: [webgl2Adapter],\n createCanvasContext: {\n canvas, // Provide existing canvas\n useDevicePixels: this.config.pixelRatio, // Use config pixelRatio value\n autoResize: true,\n width: undefined,\n height: undefined,\n },\n })\n }\n\n /**\n * Updates and recreates the graph visualization based on pending changes.\n *\n * @param simulationAlpha - Optional alpha value to set. If not provided, keeps current alpha.\n */\n private update (simulationAlpha = this.store.alpha): void {\n const { graph } = this\n this.store.pointsTextureSize = Math.ceil(Math.sqrt(graph.pointsNumber ?? 0))\n this.store.linksTextureSize = Math.ceil(Math.sqrt((graph.linksNumber ?? 0) * 2))\n this.create()\n this.initPrograms()\n this.store.hoveredPoint = undefined\n this.store.alpha = simulationAlpha\n }\n\n /**\n * Runs one step of the simulation (forces, position updates, alpha decay).\n * This is the core simulation logic that can be called by step() or during rendering.\n *\n * @param forceExecution - Controls whether to run the simulation step when paused.\n * - If true: Always runs the simulation step, even when isSimulationRunning is false.\n * Used by step() to allow manual stepping while the simulation is paused.\n * - If false: Only runs if isSimulationRunning is true. Used during rendering\n * to respect pause/unpause state.\n */\n private runSimulationStep (forceExecution = false): void {\n const { config: { simulationGravity, simulationCenter, enableSimulation }, store: { isSimulationRunning } } = this\n\n if (!enableSimulation) return\n\n // Right-click repulsion (runs regardless of isSimulationRunning)\n if (this.isRightClickMouse && this.config.enableRightClickRepulsion) {\n this.forceMouse?.run()\n this.points?.updatePosition()\n }\n\n // Main simulation forces\n // If forceExecution is true (from step()), always run\n // Otherwise, respect isSimulationRunning and zoom state\n const shouldRunSimulation = forceExecution ||\n (isSimulationRunning && !(this.zoomInstance.isRunning && !this.config.enableSimulationDuringZoom))\n\n if (shouldRunSimulation) {\n if (simulationGravity) {\n this.forceGravity?.run()\n this.points?.updatePosition()\n }\n\n if (simulationCenter) {\n this.forceCenter?.run()\n this.points?.updatePosition()\n }\n\n this.forceManyBody?.run()\n this.points?.updatePosition()\n\n if (this.store.linksTextureSize) {\n this.forceLinkIncoming?.run()\n this.points?.updatePosition()\n this.forceLinkOutgoing?.run()\n this.points?.updatePosition()\n }\n\n if (this.graph.pointClusters || this.graph.clusterPositions) {\n this.clusters?.run()\n this.points?.updatePosition()\n }\n\n // Alpha decay and progress\n this.store.alpha += this.store.addAlpha(this.config.simulationDecay ?? defaultConfigValues.simulation.decay)\n if (this.isRightClickMouse && this.config.enableRightClickRepulsion) {\n this.store.alpha = Math.max(this.store.alpha, 0.1)\n }\n this.store.simulationProgress = Math.sqrt(Math.min(1, ALPHA_MIN / this.store.alpha))\n\n this.config.onSimulationTick?.(\n this.store.alpha,\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position\n )\n }\n\n // Track points (runs regardless of simulation state)\n this.points?.trackPoints()\n }\n\n private initPrograms (): void {\n if (this._isDestroyed || !this.points || !this.lines || !this.clusters) return\n this.points.initPrograms()\n this.lines.initPrograms()\n this.forceGravity?.initPrograms()\n this.forceManyBody?.initPrograms()\n this.forceCenter?.initPrograms()\n this.forceLinkIncoming?.initPrograms()\n this.forceLinkOutgoing?.initPrograms()\n this.forceMouse?.initPrograms()\n this.clusters.initPrograms()\n }\n\n /**\n * The rendering loop - schedules itself to run continuously\n */\n private frame (): void {\n if (this._isDestroyed) return\n\n // Check if simulation should end BEFORE scheduling next frame\n // This prevents one extra frame from running after simulation ends\n const { store: { alpha, isSimulationRunning } } = this\n if (alpha < ALPHA_MIN && isSimulationRunning) {\n this.end()\n }\n\n this.requestAnimationFrameId = window.requestAnimationFrame((now) => {\n this.renderFrame(now)\n\n // Continue the loop (even after simulation ends)\n if (!this._isDestroyed) {\n this.frame()\n }\n })\n }\n\n /**\n * Renders a single frame (the actual rendering logic).\n * This does NOT schedule the next frame.\n */\n private renderFrame (now?: number): void {\n if (this._isDestroyed) return\n if (!this.store.pointsTextureSize) return\n\n this.fpsMonitor?.begin()\n this.resizeCanvas()\n if (!this.dragInstance.isActive) {\n this.findHoveredItem()\n }\n\n // Run simulation step (respects isSimulationRunning)\n // When simulation ends, forces stop but rendering continues\n this.runSimulationStep(false)\n\n // Create a single render pass for drawing (points, lines, etc.)\n // Simulation will use separate render passes later\n if (this.device) {\n const backgroundColor = this.store.backgroundColor ?? [0, 0, 0, 1]\n const drawRenderPass = this.device.beginRenderPass({\n clearColor: backgroundColor,\n clearDepth: 1,\n clearStencil: 0,\n })\n\n const { config: { renderLinks } } = this\n const shouldDrawLinks =\n renderLinks !== false &&\n !!this.store.linksTextureSize &&\n !!this.graph.linksNumber &&\n this.graph.linksNumber > 0\n\n if (shouldDrawLinks) {\n this.lines?.draw(drawRenderPass)\n }\n\n this.points?.draw(drawRenderPass)\n\n if (this.dragInstance.isActive) {\n // To prevent the dragged point from suddenly jumping, run the drag function twice\n this.points?.drag()\n this.points?.drag()\n // Update tracked positions after drag, even when simulation is disabled\n this.points?.trackPoints()\n }\n\n drawRenderPass.end()\n this.device.submit()\n }\n\n this.fpsMonitor?.end(now ?? performance.now())\n\n this.currentEvent = undefined\n }\n\n private stopFrames (): void {\n if (this.requestAnimationFrameId) {\n window.cancelAnimationFrame(this.requestAnimationFrameId)\n this.requestAnimationFrameId = 0 // Reset to 0\n }\n }\n\n /**\n * Starts continuous rendering\n */\n private startFrames (): void {\n if (this._isDestroyed) return\n this.stopFrames() // Stop any existing rendering\n this.frame() // Start the loop\n }\n\n /**\n * Called automatically when simulation completes (alpha < ALPHA_MIN).\n * Rendering continues after this is called (for rendering/interaction).\n */\n private end (): void {\n this.store.isSimulationRunning = false\n this.store.simulationProgress = 1\n this.config.onSimulationEnd?.()\n // Force hover detection on next frame since points may have moved under stationary mouse\n this._shouldForceHoverDetection = true\n }\n\n private onClick (event: MouseEvent): void {\n this.config.onClick?.(\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position,\n event\n )\n\n if (this.store.hoveredPoint) {\n this.config.onPointClick?.(\n this.store.hoveredPoint.index,\n this.store.hoveredPoint.position,\n event\n )\n } else if (this.store.hoveredLinkIndex !== undefined) {\n this.config.onLinkClick?.(\n this.store.hoveredLinkIndex,\n event\n )\n } else {\n this.config.onBackgroundClick?.(\n event\n )\n }\n }\n\n private updateMousePosition (event: MouseEvent | D3DragEvent<HTMLCanvasElement, undefined, Hovered>): void {\n if (!event) return\n const mouseX = (event as MouseEvent).offsetX ?? (event as D3DragEvent<HTMLCanvasElement, undefined, Hovered>).x\n const mouseY = (event as MouseEvent).offsetY ?? (event as D3DragEvent<HTMLCanvasElement, undefined, Hovered>).y\n if (mouseX === undefined || mouseY === undefined) return\n this.store.mousePosition = this.zoomInstance.convertScreenToSpacePosition([mouseX, mouseY])\n this.store.screenMousePosition = [mouseX, (this.store.screenSize[1] - mouseY)]\n }\n\n private onMouseMove (event: MouseEvent): void {\n this.currentEvent = event\n this.updateMousePosition(event)\n this.isRightClickMouse = event.which === 3\n this.config.onMouseMove?.(\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position,\n this.currentEvent\n )\n }\n\n private onContextMenu (event: MouseEvent): void {\n event.preventDefault()\n\n this.config.onContextMenu?.(\n this.store.hoveredPoint?.index,\n this.store.hoveredPoint?.position,\n event\n )\n\n if (this.store.hoveredPoint) {\n this.config.onPointContextMenu?.(\n this.store.hoveredPoint.index,\n this.store.hoveredPoint.position,\n event\n )\n } else if (this.store.hoveredLinkIndex !== undefined) {\n this.config.onLinkContextMenu?.(\n this.store.hoveredLinkIndex,\n event\n )\n } else {\n this.config.onBackgroundContextMenu?.(\n event\n )\n }\n }\n\n private resizeCanvas (forceResize = false): void {\n if (this._isDestroyed) return\n const w = this.canvas.clientWidth\n const h = this.canvas.clientHeight\n const [prevW, prevH] = this.store.screenSize\n\n // Check if CSS size changed (luma.gl's autoResize handles canvas.width/height automatically)\n if (forceResize || prevW !== w || prevH !== h) {\n const { k } = this.zoomInstance.eventTransform\n const centerPosition = this.zoomInstance.convertScreenToSpacePosition([prevW / 2, prevH / 2])\n\n this.store.updateScreenSize(w, h)\n // Note: canvas.width and canvas.height are managed by luma.gl's autoResize\n // We only update our internal state and dependent components\n this.canvasD3Selection\n ?.call(this.zoomInstance.behavior.transform, this.zoomInstance.getTransform(centerPosition, k))\n this.points?.updateSampledPointsGrid()\n // Only update link index FBO if link hovering is enabled\n if (this.store.isLinkHoveringEnabled) {\n this.lines?.updateLinkIndexFbo()\n }\n }\n }\n\n private updateZoomDragBehaviors (): void {\n if (this.config.enableDrag) {\n this.canvasD3Selection?.call(this.dragInstance.behavior)\n } else {\n this.canvasD3Selection\n ?.call(this.dragInstance.behavior)\n .on('.drag', null)\n }\n\n if (this.config.enableZoom) {\n this.canvasD3Selection?.call(this.zoomInstance.behavior)\n } else {\n this.canvasD3Selection\n ?.call(this.zoomInstance.behavior)\n .on('wheel.zoom', null)\n }\n }\n\n private findHoveredItem (): void {\n if (this._isDestroyed || !this._isMouseOnCanvas) return\n if (this._findHoveredItemExecutionCount < MAX_HOVER_DETECTION_DELAY) {\n this._findHoveredItemExecutionCount += 1\n return\n }\n\n // Check if mouse has moved significantly since last hover detection\n const deltaX = Math.abs(this._lastMouseX - this._lastCheckedMouseX)\n const deltaY = Math.abs(this._lastMouseY - this._lastCheckedMouseY)\n const mouseMoved = deltaX > MIN_MOUSE_MOVEMENT_THRESHOLD || deltaY > MIN_MOUSE_MOVEMENT_THRESHOLD\n\n // Skip if mouse hasn't moved AND not forced\n if (!mouseMoved && !this._shouldForceHoverDetection) {\n return\n }\n\n // Update last checked position\n this._lastCheckedMouseX = this._lastMouseX\n this._lastCheckedMouseY = this._lastMouseY\n\n // Reset force flag after use\n this._shouldForceHoverDetection = false\n\n this._findHoveredItemExecutionCount = 0\n this.findHoveredPoint()\n\n if (this.graph.linksNumber && this.store.isLinkHoveringEnabled) {\n this.findHoveredLine()\n } else if (this.store.hoveredLinkIndex !== undefined) {\n // Clear stale hoveredLinkIndex when there are no links\n const wasHovered = this.store.hoveredLinkIndex !== undefined\n this.store.hoveredLinkIndex = undefined\n if (wasHovered && this.config.onLinkMouseOut) {\n this.config.onLinkMouseOut(this.currentEvent)\n }\n }\n\n this.updateCanvasCursor()\n }\n\n private findHoveredPoint (): void {\n if (this._isDestroyed || !this.device || !this.points) return\n this.points.findHoveredPoint()\n let isMouseover = false\n let isMouseout = false\n const pixels = readPixels(this.device, this.points.hoveredFbo as Framebuffer, 0, 0, 2, 2)\n // Shader writes: rgba = vec4(index, size, pointPosition.xy)\n const hoveredIndex = pixels[0] as number\n const pointSize = pixels[1] as number\n const pointX = pixels[2] as number\n const pointY = pixels[3] as number\n\n if (pointSize > 0) {\n if (this.store.hoveredPoint === undefined || this.store.hoveredPoint.index !== hoveredIndex) {\n isMouseover = true\n }\n this.store.hoveredPoint = {\n index: hoveredIndex,\n position: [pointX, pointY],\n }\n } else {\n if (this.store.hoveredPoint) isMouseout = true\n this.store.hoveredPoint = undefined\n }\n\n if (isMouseover && this.store.hoveredPoint) {\n this.config.onPointMouseOver?.(\n this.store.hoveredPoint.index,\n this.store.hoveredPoint.position,\n this.currentEvent,\n this.store.selectedIndices?.includes(this.store.hoveredPoint.index) ?? false\n )\n }\n if (isMouseout) this.config.onPointMouseOut?.(this.currentEvent)\n }\n\n private findHoveredLine (): void {\n if (this._isDestroyed || !this.lines) return\n if (this.store.hoveredPoint) {\n if (this.store.hoveredLinkIndex !== undefined) {\n this.store.hoveredLinkIndex = undefined\n this.config.onLinkMouseOut?.(this.currentEvent)\n }\n return\n }\n this.lines.findHoveredLine()\n let isMouseover = false\n let isMouseout = false\n\n if (!this.device) return\n const pixels = readPixels(this.device, this.lines.hoveredLineIndexFbo!)\n const hoveredLineIndex = pixels[0] as number\n\n if (hoveredLineIndex >= 0) {\n if (this.store.hoveredLinkIndex !== hoveredLineIndex) isMouseover = true\n this.store.hoveredLinkIndex = hoveredLineIndex\n } else {\n if (this.store.hoveredLinkIndex !== undefined) isMouseout = true\n this.store.hoveredLinkIndex = undefined\n }\n\n if (isMouseover && this.store.hoveredLinkIndex !== undefined) {\n this.config.onLinkMouseOver?.(this.store.hoveredLinkIndex)\n }\n if (isMouseout) this.config.onLinkMouseOut?.(this.currentEvent)\n }\n\n private updateCanvasCursor (): void {\n const { hoveredPointCursor, hoveredLinkCursor } = this.config\n if (this.dragInstance.isActive) select(this.canvas).style('cursor', 'grabbing')\n else if (this.store.hoveredPoint) {\n if (!this.config.enableDrag || this.store.isSpaceKeyPressed) select(this.canvas).style('cursor', hoveredPointCursor)\n else select(this.canvas).style('cursor', 'grab')\n } else if (this.store.isLinkHoveringEnabled && this.store.hoveredLinkIndex !== undefined) {\n select(this.canvas).style('cursor', hoveredLinkCursor)\n } else select(this.canvas).style('cursor', null)\n }\n\n private addAttribution (): void {\n if (!this.config.attribution) return\n this.attributionDivElement = document.createElement('div')\n this.attributionDivElement.style.cssText = `\n user-select: none;\n position: absolute;\n bottom: 0;\n right: 0;\n color: var(--cosmosgl-attribution-color);\n margin: 0 0.6rem 0.6rem 0;\n font-size: 0.7rem;\n font-family: inherit;\n `\n // Sanitize the attribution HTML content to prevent XSS attacks\n // Use more permissive settings for attribution since it's controlled by the library user\n this.attributionDivElement.innerHTML = sanitizeHtml(this.config.attribution, {\n ALLOWED_TAGS: ['a', 'b', 'i', 'em', 'strong', 'span', 'div', 'p', 'br', 'img'],\n ALLOWED_ATTR: ['href', 'target', 'class', 'id', 'style', 'src', 'alt', 'title'],\n })\n this.store.div?.appendChild(this.attributionDivElement)\n }\n}\n\nexport type { GraphConfigInterface } from './config'\nexport { PointShape } from './modules/GraphData'\n\nexport * from './helper'\n"],"names":["defaultPointColor","defaultGreyoutPointOpacity","defaultGreyoutPointColor","defaultPointOpacity","defaultPointSize","defaultLinkColor","defaultGreyoutLinkOpacity","defaultLinkOpacity","defaultLinkWidth","defaultBackgroundColor","defaultConfigValues","hoveredPointRingOpacity","focusedPointRingOpacity","defaultScaleToZoom","GLEnum","ALPHA_MIN","MAX_POINT_SIZE","MAX_HOVER_DETECTION_DELAY","MIN_MOUSE_MOVEMENT_THRESHOLD","Store","mat3","scaleLinear","Random","decay","color","brightness","rgbToBrightness","seed","min","max","configSpaceSize","webglMaxTextureSize","minSpaceSize","width","height","adjustedSpaceSize","x","y","convertedRgba","getRgbaColor","config","index","isFunction","a","isArray","isObject","isAClassInstance","isPlainObject","value","rgba","d3Color","rgb","r","g","b","readPixels","device","fbo","sourceX","sourceY","sourceWidth","sourceHeight","getMaxPointSize","pixelRatio","range","GL","clamp","num","isNumber","sanitizeHtml","html","options","DOMPurify","GraphConfig","configParameter","current","next","key","CoreModule","store","data","points","calculateCentermassFrag$1","calculateCentermassVert$1","forceFrag$5","createIndexesForBuffer","textureSize","indexes","i","getBytesPerRow","format","formatInfo","textureFormatDecoder","updateVert","ForceCenter","pointsTextureSize","Texture","indexData","Buffer","_a","UniformStore","Model","calculateCentermassFrag","calculateCentermassVert","forceFrag","centermassPass","pass","_b","_c","_d","forceFrag$4","ForceGravity","maxLinks","ensureVec2","arr","fallback","ensureVec4","LinkDirection","ForceLink","direction","linksTextureSize","linkBiasAndStrengthState","linkDistanceState","grouped","linkIndex","connectedPointIndices","pointIndex","connectedPointIndex","initialLinkIndex","degree","connectedDegree","degreeSum","bias","minDegree","strength","recreatePointTextures","recreateLinkTextures","calculateLevelFrag","calculateLevelVert","forceFrag$2","forceCenterFrag","ForceManyBody","level","levelTextureSize","existingTarget","texture","target","totalPixels","randomValuesState","_e","_f","cellSize","levelPass","drawPass","forceFrag$1","ForceMouse","Clusters","clusterIndex","sizesChanged","pointsTextureDataSize","clustersTextureDataSize","clusterState","clusterPositions","clusterForceCoefficient","cluster","benchCSS","FPSMonitor","canvas","gl","GLBench","now","select","PointShape","GraphData","defaultRgba","defaultSize","defaultShape","pointShapes","shape","pointImageIndices","rawIndex","imageIndex","defaultWidth","defaultArrows","d","sourceIndex","targetIndex","drawLineFrag","drawLineVert","hoveredLineIndexFrag","hoveredLineIndexVert","getCurveLineGeometry","segments","scale","scalePow","hodographValues","result","Lines","linksNumber","renderPass","screenSize","screenWidth","screenHeight","screenSizeChanged","pointAData","pointBData","fromIndex","toIndex","fromX","fromY","toX","toY","currentSize","linkIndices","colorData","widthData","arrowData","curvedLinks","curvedLinkSegments","flatGeometry","indexPass","hoverPass","drawPointsFrag","drawPointsVert","findPointsOnAreaSelectionFrag","findPointsOnPolygonSelectionFrag","drawHighlightedFrag","drawHighlightedVert","findHoveredPointFrag","findHoveredPointVert","fillGridWithSampledPointsFrag","fillGridWithSampledPointsVert","updatePositionFrag","trackPositionsFrag","dragPointFrag","createAtlasDataFromImageData","imageDataArray","maxDimension","imageData","dimension","originalMaxDimension","atlasCoordsSize","atlasSize","scalingFactor","atlasData","atlasCoords","originalWidth","originalHeight","individualScale","scaledWidth","scaledHeight","row","atlasX","atlasY","srcX","srcIndex","atlasIndex","Points","rescalePositions","enableSimulation","textureDataSize","initialState","expectedBytes","actualBytes","shouldRescale","velocityData","requiredByteLength","t","selectedIndices","selectedIndex","pinnedIndex","sizeData","shapeData","imageIndicesData","imageSizesData","atlasResult","pointSamplingDistance","dist","w","h","baseVertexUniforms","baseFragmentUniforms","pointSize","polygonPath","textureData","point","baseUniforms","bindings","indices","sortedIndex","isSimulationRunning","pixels","tracked","positions","fillPass","isNotEmpty","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","tempTexture","tempFbo","spaceSize","pointsNumber","minX","maxX","minY","maxY","densityThreshold","effectiveSpaceSize","scaleFactor","centerOffset","offsetX","offsetY","Zoom","zoomIdentity","zoom","e","userDriven","k","transform","padding","xExtent","yExtent","xScale","yScale","clampedScale","xCenter","yCenter","translateX","translateY","position","dx","dy","currX","currY","pointX","pointY","centerX","centerY","screenPosition","invertedX","invertedY","spacePosition","screenPointX","screenPointY","spaceRadius","scalePointsOnZoom","maxPointSize","size","Drag","drag","event","Graph","div","devicePromise","deviceCanvasContext","deviceCanvas","error","prevConfig","pointPositions","dontRescale","pointColors","pointSizes","imageIndices","imageSizes","links","linkColors","linkWidths","linkArrows","linkStrength","pointClusters","clusterStrength","pinnedIndices","simulationAlpha","fitViewOnInit","fitViewDelay","fitViewPadding","fitViewDuration","fitViewByPointsInRect","fitViewByPointIndices","initialZoomLevel","duration","canZoomOut","positionPixels","posX","posY","distance","zoomLevel","middle","easeQuadIn","easeQuadOut","pointPositionsPixels","clusterPositionsPixels","sumX","sumY","sumN","positionsArray","easeQuadInOut","selection","pixel","convertedPath","selectAdjacentPoints","adjacentIndices","alpha","callback","luma","webgl2Adapter","graph","forceExecution","simulationGravity","simulationCenter","_s","backgroundColor","drawRenderPass","renderLinks","mouseX","mouseY","forceResize","prevW","prevH","centerPosition","deltaX","deltaY","wasHovered","isMouseover","isMouseout","hoveredIndex","hoveredLineIndex","hoveredPointCursor","hoveredLinkCursor"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KCAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ICAAC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","x_google_ignoreList":[1]}