comfy-3d-viewers 0.1.2__tar.gz

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.
Files changed (51) hide show
  1. comfy_3d_viewers-0.1.2/.github/workflows/publish.yml +67 -0
  2. comfy_3d_viewers-0.1.2/.gitignore +20 -0
  3. comfy_3d_viewers-0.1.2/PKG-INFO +66 -0
  4. comfy_3d_viewers-0.1.2/README.md +45 -0
  5. comfy_3d_viewers-0.1.2/build_vtk_bundle/package.json +21 -0
  6. comfy_3d_viewers-0.1.2/build_vtk_bundle/vtk_gltf_bundle.js +144 -0
  7. comfy_3d_viewers-0.1.2/build_vtk_bundle/webpack.config.js +81 -0
  8. comfy_3d_viewers-0.1.2/comfy_3d_viewers/__init__.py +67 -0
  9. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer.html +218 -0
  10. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_dual.html +1409 -0
  11. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_dual_slider.html +923 -0
  12. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_dual_textured.html +1357 -0
  13. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_gaussian.html +862 -0
  14. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_multi.html +741 -0
  15. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_pbr.html +374 -0
  16. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_uv.html +733 -0
  17. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_vtk.html +665 -0
  18. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/html/viewer_vtk_textured.html +407 -0
  19. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/gsplat-bundle.js +2482 -0
  20. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/analysisPanel.js +280 -0
  21. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/extensionFolder.js +19 -0
  22. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/formatting.js +232 -0
  23. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/index.js +11 -0
  24. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/postMessage.js +173 -0
  25. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/screenshot.js +71 -0
  26. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/utils/uiComponents.js +133 -0
  27. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/core/ActorManager.js +276 -0
  28. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/core/BaseViewer.js +623 -0
  29. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/core/CameraController.js +271 -0
  30. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/features/AxisIndicator.js +242 -0
  31. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/features/FieldVisualization.js +352 -0
  32. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/features/ScreenshotCapture.js +97 -0
  33. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/features/TextureManager.js +213 -0
  34. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/index.js +199 -0
  35. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/loaders/GLTFLoader.js +299 -0
  36. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/loaders/LoaderFactory.js +205 -0
  37. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/loaders/OBJLoader.js +63 -0
  38. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/loaders/STLLoader.js +60 -0
  39. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/loaders/VTPLoader.js +116 -0
  40. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/ui/ControlsBar.js +398 -0
  41. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/ui/SettingsPanel.js +383 -0
  42. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/ui/styles.css +366 -0
  43. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/utils/BoundsUtils.js +94 -0
  44. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/utils/ColorUtils.js +59 -0
  45. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/utils/MessageHandler.js +100 -0
  46. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/viewers/DualViewer.js +551 -0
  47. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/viewers/StandardViewer.js +241 -0
  48. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer/viewers/TexturedViewer.js +161 -0
  49. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/viewer-bundle.js +2 -0
  50. comfy_3d_viewers-0.1.2/comfy_3d_viewers/web/js/vtk-gltf.js +2 -0
  51. comfy_3d_viewers-0.1.2/pyproject.toml +40 -0
@@ -0,0 +1,67 @@
1
+ name: Bump Version & Publish
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ bump-and-publish:
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ permissions:
14
+ contents: write
15
+ id-token: write
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ token: ${{ secrets.GITHUB_TOKEN }}
20
+
21
+ - name: Setup Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.11"
25
+
26
+ - name: Get current version
27
+ id: get_version
28
+ run: |
29
+ current=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
30
+ echo "current=$current" >> $GITHUB_OUTPUT
31
+
32
+ - name: Bump patch version
33
+ id: bump_version
34
+ run: |
35
+ current="${{ steps.get_version.outputs.current }}"
36
+ IFS='.' read -r major minor patch <<< "$current"
37
+ new_patch=$((patch + 1))
38
+ new_version="${major}.${minor}.${new_patch}"
39
+ sed -i "s/^version = \".*\"/version = \"${new_version}\"/" pyproject.toml
40
+ echo "new_version=$new_version" >> $GITHUB_OUTPUT
41
+ echo "Bumped version: $current -> $new_version"
42
+
43
+ - name: Commit version bump
44
+ run: |
45
+ git config user.name "github-actions[bot]"
46
+ git config user.email "github-actions[bot]@users.noreply.github.com"
47
+ git add pyproject.toml
48
+ git commit -m "Bump version to ${{ steps.bump_version.outputs.new_version }} [skip ci]"
49
+ git tag "v${{ steps.bump_version.outputs.new_version }}"
50
+ git push origin main --tags
51
+
52
+ - name: Install build tools
53
+ run: pip install build
54
+
55
+ - name: Build package
56
+ run: python -m build
57
+
58
+ - name: Create GitHub Release
59
+ uses: softprops/action-gh-release@v1
60
+ with:
61
+ tag_name: v${{ steps.bump_version.outputs.new_version }}
62
+ name: v${{ steps.bump_version.outputs.new_version }}
63
+ generate_release_notes: true
64
+ files: dist/*
65
+
66
+ - name: Publish to PyPI
67
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,20 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .eggs/
9
+
10
+ # Node modules (for build_vtk_bundle)
11
+ node_modules/
12
+ package-lock.json
13
+
14
+ # IDE
15
+ .idea/
16
+ .vscode/
17
+ *.swp
18
+
19
+ # OS
20
+ .DS_Store
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.4
2
+ Name: comfy-3d-viewers
3
+ Version: 0.1.2
4
+ Summary: Reusable 3D viewer infrastructure for ComfyUI nodes
5
+ Project-URL: Homepage, https://github.com/PozzettiAndrea/comfy-3d-viewers
6
+ Project-URL: Repository, https://github.com/PozzettiAndrea/comfy-3d-viewers
7
+ Author: ComfyUI-GeometryPack Contributors
8
+ License-Expression: GPL-3.0-or-later
9
+ Keywords: 3d,comfyui,gaussian-splatting,mesh-visualization,viewer,vtk
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
18
+ Classifier: Topic :: Scientific/Engineering :: Visualization
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+
22
+ # comfy-3d-viewers
23
+
24
+ Reusable 3D viewer infrastructure for ComfyUI nodes.
25
+
26
+ Provides VTK.js and Gaussian splatting viewers, shared utilities, and HTML templates for 3D mesh visualization in ComfyUI.
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install -e .
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ This package is used by ComfyUI-GeometryPack. The `prestartup_script.py` copies the viewer files to the extension's web directory at runtime.
37
+
38
+ ```python
39
+ from comfy_3d_viewers import get_js_dir, get_html_dir, get_utils_dir
40
+
41
+ # Get paths to viewer files
42
+ js_dir = get_js_dir() # JS bundles and viewer source
43
+ html_dir = get_html_dir() # HTML viewer templates
44
+ utils_dir = get_utils_dir() # Shared JS utilities
45
+ ```
46
+
47
+ ## Contents
48
+
49
+ - **JS Bundles**: VTK.js, Gaussian splatting, modular viewer bundle
50
+ - **Viewer Modules**: Modular viewer architecture (core, loaders, viewers, ui, features, utils)
51
+ - **Shared Utilities**: Extension folder detection, screenshot handling, UI components, formatting, analysis panels, postMessage helpers
52
+ - **HTML Templates**: Viewer pages for VTK, textured, dual, gaussian, UV, etc.
53
+
54
+ ## Building
55
+
56
+ To rebuild the VTK.js bundle:
57
+
58
+ ```bash
59
+ cd build_vtk_bundle
60
+ npm install
61
+ npm run build
62
+ ```
63
+
64
+ ## License
65
+
66
+ GPL-3.0-or-later
@@ -0,0 +1,45 @@
1
+ # comfy-3d-viewers
2
+
3
+ Reusable 3D viewer infrastructure for ComfyUI nodes.
4
+
5
+ Provides VTK.js and Gaussian splatting viewers, shared utilities, and HTML templates for 3D mesh visualization in ComfyUI.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install -e .
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ This package is used by ComfyUI-GeometryPack. The `prestartup_script.py` copies the viewer files to the extension's web directory at runtime.
16
+
17
+ ```python
18
+ from comfy_3d_viewers import get_js_dir, get_html_dir, get_utils_dir
19
+
20
+ # Get paths to viewer files
21
+ js_dir = get_js_dir() # JS bundles and viewer source
22
+ html_dir = get_html_dir() # HTML viewer templates
23
+ utils_dir = get_utils_dir() # Shared JS utilities
24
+ ```
25
+
26
+ ## Contents
27
+
28
+ - **JS Bundles**: VTK.js, Gaussian splatting, modular viewer bundle
29
+ - **Viewer Modules**: Modular viewer architecture (core, loaders, viewers, ui, features, utils)
30
+ - **Shared Utilities**: Extension folder detection, screenshot handling, UI components, formatting, analysis panels, postMessage helpers
31
+ - **HTML Templates**: Viewer pages for VTK, textured, dual, gaussian, UV, etc.
32
+
33
+ ## Building
34
+
35
+ To rebuild the VTK.js bundle:
36
+
37
+ ```bash
38
+ cd build_vtk_bundle
39
+ npm install
40
+ npm run build
41
+ ```
42
+
43
+ ## License
44
+
45
+ GPL-3.0-or-later
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "vtk-bundle-builder",
3
+ "version": "1.0.0",
4
+ "description": "Build custom VTK.js UMD bundle with GLTFImporter",
5
+ "private": true,
6
+ "scripts": {
7
+ "build": "webpack --config webpack.config.js"
8
+ },
9
+ "dependencies": {
10
+ "@kitware/vtk.js": "^34.0.0"
11
+ },
12
+ "devDependencies": {
13
+ "@babel/core": "^7.28.5",
14
+ "@babel/preset-env": "^7.28.5",
15
+ "babel-loader": "^10.0.0",
16
+ "css-loader": "^7.1.2",
17
+ "style-loader": "^4.0.0",
18
+ "webpack": "^5.0.0",
19
+ "webpack-cli": "^5.0.0"
20
+ }
21
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * VTK.js Bundle with GLTFImporter support
3
+ * This file bundles all required VTK.js modules into a single UMD file
4
+ */
5
+
6
+ // Core rendering
7
+ import '@kitware/vtk.js/Rendering/Profiles/Geometry';
8
+
9
+ // Rendering
10
+ import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
11
+ import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';
12
+ import vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';
13
+ import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
14
+ import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
15
+ import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
16
+ import vtkTexture from '@kitware/vtk.js/Rendering/Core/Texture';
17
+ import vtkProperty from '@kitware/vtk.js/Rendering/Core/Property';
18
+ import vtkAnnotatedCubeActor from '@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor';
19
+ import vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';
20
+
21
+ // OpenGL implementations
22
+ import vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';
23
+
24
+ // Interaction
25
+ import vtkInteractorStyleTrackballCamera from '@kitware/vtk.js/Interaction/Style/InteractorStyleTrackballCamera';
26
+ import vtkOrientationMarkerWidget from '@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget';
27
+
28
+ // IO - Geometry readers
29
+ import vtkSTLReader from '@kitware/vtk.js/IO/Geometry/STLReader';
30
+ import vtkPLYReader from '@kitware/vtk.js/IO/Geometry/PLYReader';
31
+
32
+ // IO - Misc readers
33
+ import vtkOBJReader from '@kitware/vtk.js/IO/Misc/OBJReader';
34
+
35
+ // IO - XML readers
36
+ import vtkXMLPolyDataReader from '@kitware/vtk.js/IO/XML/XMLPolyDataReader';
37
+
38
+ // IO - GLTF (the key addition!)
39
+ import vtkGLTFImporter from '@kitware/vtk.js/IO/Geometry/GLTFImporter';
40
+ const gltfAvailable = true;
41
+ console.log('[VTK Bundle] GLTFImporter included in bundle');
42
+
43
+ // Filters - Core
44
+ import vtkPolyDataNormals from '@kitware/vtk.js/Filters/Core/PolyDataNormals';
45
+ import vtkCutter from '@kitware/vtk.js/Filters/Core/Cutter';
46
+
47
+ // Filters - General
48
+ import vtkWindowedSincPolyDataFilter from '@kitware/vtk.js/Filters/General/WindowedSincPolyDataFilter';
49
+ import vtkOutlineFilter from '@kitware/vtk.js/Filters/General/OutlineFilter';
50
+
51
+ // Sources
52
+ import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource';
53
+ import vtkSphereSource from '@kitware/vtk.js/Filters/Sources/SphereSource';
54
+ import vtkCubeSource from '@kitware/vtk.js/Filters/Sources/CubeSource';
55
+
56
+ // Common - DataModel
57
+ import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';
58
+
59
+ // Color maps
60
+ import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
61
+ import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';
62
+
63
+ // Export everything as a global vtk object (UMD style)
64
+ const vtk = {
65
+ Rendering: {
66
+ Core: {
67
+ vtkActor,
68
+ vtkMapper,
69
+ vtkTexture,
70
+ vtkProperty,
71
+ vtkAnnotatedCubeActor,
72
+ vtkCamera,
73
+ vtkRenderWindow,
74
+ vtkRenderWindowInteractor,
75
+ vtkRenderer,
76
+ vtkColorTransferFunction,
77
+ },
78
+ Misc: {
79
+ vtkFullScreenRenderWindow,
80
+ },
81
+ OpenGL: {
82
+ vtkRenderWindow: vtkOpenGLRenderWindow,
83
+ },
84
+ },
85
+ Interaction: {
86
+ Style: {
87
+ vtkInteractorStyleTrackballCamera,
88
+ },
89
+ Widgets: {
90
+ vtkOrientationMarkerWidget,
91
+ },
92
+ },
93
+ IO: {
94
+ Geometry: {
95
+ vtkSTLReader,
96
+ vtkPLYReader,
97
+ vtkGLTFImporter, // Will be null if not available
98
+ },
99
+ Misc: {
100
+ vtkOBJReader,
101
+ },
102
+ XML: {
103
+ vtkXMLPolyDataReader,
104
+ },
105
+ },
106
+ Filters: {
107
+ Core: {
108
+ vtkPolyDataNormals,
109
+ vtkCutter,
110
+ },
111
+ General: {
112
+ vtkWindowedSincPolyDataFilter,
113
+ vtkOutlineFilter,
114
+ },
115
+ Sources: {
116
+ vtkConeSource,
117
+ vtkSphereSource,
118
+ vtkCubeSource,
119
+ },
120
+ },
121
+ Common: {
122
+ DataModel: {
123
+ vtkPlane,
124
+ },
125
+ },
126
+ // Metadata
127
+ _gltfAvailable: gltfAvailable,
128
+ };
129
+
130
+ // Add vtkColorMaps as a property of vtkColorTransferFunction
131
+ vtkColorTransferFunction.vtkColorMaps = vtkColorMaps;
132
+
133
+ // Export for UMD
134
+ if (typeof module !== 'undefined' && module.exports) {
135
+ module.exports = vtk;
136
+ }
137
+ if (typeof window !== 'undefined') {
138
+ window.vtk = vtk;
139
+ }
140
+ if (typeof global !== 'undefined') {
141
+ global.vtk = vtk;
142
+ }
143
+
144
+ export default vtk;
@@ -0,0 +1,81 @@
1
+ const path = require('path');
2
+
3
+ // Output to comfy_3d_viewers/web/js directory (package structure)
4
+ const OUTPUT_DIR = path.resolve(__dirname, '../comfy_3d_viewers/web/js');
5
+
6
+ module.exports = [
7
+ // VTK.js bundle with GLTF support
8
+ {
9
+ entry: './vtk_gltf_bundle.js',
10
+ output: {
11
+ filename: 'vtk-gltf.js',
12
+ path: OUTPUT_DIR,
13
+ library: {
14
+ name: 'vtk',
15
+ type: 'umd',
16
+ export: 'default',
17
+ },
18
+ globalObject: 'globalThis',
19
+ },
20
+ mode: 'production',
21
+ resolve: {
22
+ extensions: ['.js'],
23
+ },
24
+ module: {
25
+ rules: [
26
+ {
27
+ test: /\.js$/,
28
+ exclude: /node_modules/,
29
+ use: {
30
+ loader: 'babel-loader',
31
+ options: {
32
+ presets: ['@babel/preset-env'],
33
+ },
34
+ },
35
+ },
36
+ ],
37
+ },
38
+ // Optimize for size
39
+ optimization: {
40
+ minimize: true,
41
+ },
42
+ },
43
+ // Modular viewer bundle
44
+ {
45
+ entry: path.resolve(__dirname, '../comfy_3d_viewers/web/js/viewer/index.js'),
46
+ output: {
47
+ filename: 'viewer-bundle.js',
48
+ path: OUTPUT_DIR,
49
+ library: {
50
+ name: 'GeomPackViewer',
51
+ type: 'umd',
52
+ },
53
+ globalObject: 'globalThis',
54
+ },
55
+ mode: 'production',
56
+ resolve: {
57
+ extensions: ['.js'],
58
+ },
59
+ module: {
60
+ rules: [
61
+ {
62
+ test: /\.js$/,
63
+ exclude: /node_modules/,
64
+ use: {
65
+ loader: 'babel-loader',
66
+ options: {
67
+ presets: ['@babel/preset-env'],
68
+ },
69
+ },
70
+ },
71
+ {
72
+ test: /\.css$/,
73
+ use: ['style-loader', 'css-loader'],
74
+ },
75
+ ],
76
+ },
77
+ optimization: {
78
+ minimize: true,
79
+ },
80
+ },
81
+ ];
@@ -0,0 +1,67 @@
1
+ # SPDX-License-Identifier: GPL-3.0-or-later
2
+ # Copyright (C) 2025 comfy-3d-viewers Contributors
3
+
4
+ """
5
+ comfy-3d-viewers: Reusable 3D viewer infrastructure for ComfyUI nodes.
6
+
7
+ Provides VTK.js and Gaussian splatting viewers, shared utilities,
8
+ and HTML templates for 3D mesh visualization in ComfyUI.
9
+ """
10
+
11
+ import os
12
+
13
+ __version__ = "0.1.0"
14
+
15
+
16
+ def get_package_dir() -> str:
17
+ """Return the root directory of the comfy_3d_viewers package."""
18
+ return os.path.dirname(os.path.abspath(__file__))
19
+
20
+
21
+ def get_web_dir() -> str:
22
+ """Return path to the web directory containing JS and HTML files."""
23
+ return os.path.join(get_package_dir(), "web")
24
+
25
+
26
+ def get_js_dir() -> str:
27
+ """Return path to the JS directory containing viewer bundles."""
28
+ return os.path.join(get_web_dir(), "js")
29
+
30
+
31
+ def get_html_dir() -> str:
32
+ """Return path to the HTML viewer templates directory."""
33
+ return os.path.join(get_web_dir(), "html")
34
+
35
+
36
+ def get_utils_dir() -> str:
37
+ """Return path to the shared JS utilities directory."""
38
+ return os.path.join(get_js_dir(), "utils")
39
+
40
+
41
+ def get_viewer_dir() -> str:
42
+ """Return path to the modular viewer source directory."""
43
+ return os.path.join(get_js_dir(), "viewer")
44
+
45
+
46
+ def list_html_templates() -> list[str]:
47
+ """List all available HTML viewer templates."""
48
+ html_dir = get_html_dir()
49
+ if not os.path.exists(html_dir):
50
+ return []
51
+ return [f for f in os.listdir(html_dir) if f.endswith('.html')]
52
+
53
+
54
+ def list_js_bundles() -> list[str]:
55
+ """List all available JS bundle files."""
56
+ js_dir = get_js_dir()
57
+ if not os.path.exists(js_dir):
58
+ return []
59
+ return [f for f in os.listdir(js_dir) if f.endswith('.js') and not os.path.isdir(os.path.join(js_dir, f))]
60
+
61
+
62
+ def list_utils() -> list[str]:
63
+ """List all available utility modules."""
64
+ utils_dir = get_utils_dir()
65
+ if not os.path.exists(utils_dir):
66
+ return []
67
+ return [f for f in os.listdir(utils_dir) if f.endswith('.js')]