brep-io-kernel 1.0.0-ci.9

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 (271) hide show
  1. package/LICENSE.md +32 -0
  2. package/README.md +154 -0
  3. package/dist-kernel/brep-kernel.js +74699 -0
  4. package/package.json +58 -0
  5. package/src/BREP/AssemblyComponent.js +42 -0
  6. package/src/BREP/BREP.js +43 -0
  7. package/src/BREP/BetterSolid.js +805 -0
  8. package/src/BREP/Edge.js +103 -0
  9. package/src/BREP/Extrude.js +403 -0
  10. package/src/BREP/Face.js +187 -0
  11. package/src/BREP/MeshRepairer.js +634 -0
  12. package/src/BREP/OffsetShellSolid.js +614 -0
  13. package/src/BREP/PointCloudWrap.js +302 -0
  14. package/src/BREP/Revolve.js +345 -0
  15. package/src/BREP/SolidMethods/authoring.js +112 -0
  16. package/src/BREP/SolidMethods/booleanOps.js +230 -0
  17. package/src/BREP/SolidMethods/chamfer.js +122 -0
  18. package/src/BREP/SolidMethods/edgeResolution.js +25 -0
  19. package/src/BREP/SolidMethods/fillet.js +792 -0
  20. package/src/BREP/SolidMethods/index.js +72 -0
  21. package/src/BREP/SolidMethods/io.js +105 -0
  22. package/src/BREP/SolidMethods/lifecycle.js +103 -0
  23. package/src/BREP/SolidMethods/manifoldOps.js +375 -0
  24. package/src/BREP/SolidMethods/meshCleanup.js +2512 -0
  25. package/src/BREP/SolidMethods/meshQueries.js +264 -0
  26. package/src/BREP/SolidMethods/metadata.js +106 -0
  27. package/src/BREP/SolidMethods/metrics.js +51 -0
  28. package/src/BREP/SolidMethods/transforms.js +361 -0
  29. package/src/BREP/SolidMethods/visualize.js +508 -0
  30. package/src/BREP/SolidShared.js +26 -0
  31. package/src/BREP/Sweep.js +1596 -0
  32. package/src/BREP/Tube.js +857 -0
  33. package/src/BREP/Vertex.js +43 -0
  34. package/src/BREP/applyBooleanOperation.js +704 -0
  35. package/src/BREP/boundsUtils.js +48 -0
  36. package/src/BREP/chamfer.js +551 -0
  37. package/src/BREP/edgePolylineUtils.js +85 -0
  38. package/src/BREP/fillets/common.js +388 -0
  39. package/src/BREP/fillets/fillet.js +1422 -0
  40. package/src/BREP/fillets/filletGeometry.js +15 -0
  41. package/src/BREP/fillets/inset.js +389 -0
  42. package/src/BREP/fillets/offsetHelper.js +143 -0
  43. package/src/BREP/fillets/outset.js +88 -0
  44. package/src/BREP/helix.js +193 -0
  45. package/src/BREP/meshToBrep.js +234 -0
  46. package/src/BREP/primitives.js +279 -0
  47. package/src/BREP/setupManifold.js +71 -0
  48. package/src/BREP/threadGeometry.js +1120 -0
  49. package/src/BREP/triangleUtils.js +8 -0
  50. package/src/BREP/triangulate.js +608 -0
  51. package/src/FeatureRegistry.js +183 -0
  52. package/src/PartHistory.js +1132 -0
  53. package/src/UI/AccordionWidget.js +292 -0
  54. package/src/UI/CADmaterials.js +850 -0
  55. package/src/UI/EnvMonacoEditor.js +522 -0
  56. package/src/UI/FloatingWindow.js +396 -0
  57. package/src/UI/HistoryWidget.js +457 -0
  58. package/src/UI/MainToolbar.js +131 -0
  59. package/src/UI/ModelLibraryView.js +194 -0
  60. package/src/UI/OrthoCameraIdle.js +206 -0
  61. package/src/UI/PluginsWidget.js +280 -0
  62. package/src/UI/SceneListing.js +606 -0
  63. package/src/UI/SelectionFilter.js +629 -0
  64. package/src/UI/ViewCube.js +389 -0
  65. package/src/UI/assembly/AssemblyConstraintCollectionWidget.js +329 -0
  66. package/src/UI/assembly/AssemblyConstraintControlsWidget.js +282 -0
  67. package/src/UI/assembly/AssemblyConstraintsWidget.css +292 -0
  68. package/src/UI/assembly/AssemblyConstraintsWidget.js +1373 -0
  69. package/src/UI/assembly/constraintFaceUtils.js +115 -0
  70. package/src/UI/assembly/constraintHighlightUtils.js +70 -0
  71. package/src/UI/assembly/constraintLabelUtils.js +31 -0
  72. package/src/UI/assembly/constraintPointUtils.js +64 -0
  73. package/src/UI/assembly/constraintSelectionUtils.js +185 -0
  74. package/src/UI/assembly/constraintStatusUtils.js +142 -0
  75. package/src/UI/componentSelectorModal.js +240 -0
  76. package/src/UI/controls/CombinedTransformControls.js +386 -0
  77. package/src/UI/dialogs.js +351 -0
  78. package/src/UI/expressionsManager.js +100 -0
  79. package/src/UI/featureDialogWidgets/booleanField.js +25 -0
  80. package/src/UI/featureDialogWidgets/booleanOperationField.js +97 -0
  81. package/src/UI/featureDialogWidgets/buttonField.js +45 -0
  82. package/src/UI/featureDialogWidgets/componentSelectorField.js +102 -0
  83. package/src/UI/featureDialogWidgets/defaultField.js +23 -0
  84. package/src/UI/featureDialogWidgets/fileField.js +66 -0
  85. package/src/UI/featureDialogWidgets/index.js +34 -0
  86. package/src/UI/featureDialogWidgets/numberField.js +165 -0
  87. package/src/UI/featureDialogWidgets/optionsField.js +33 -0
  88. package/src/UI/featureDialogWidgets/referenceSelectionField.js +208 -0
  89. package/src/UI/featureDialogWidgets/stringField.js +24 -0
  90. package/src/UI/featureDialogWidgets/textareaField.js +28 -0
  91. package/src/UI/featureDialogWidgets/threadDesignationField.js +160 -0
  92. package/src/UI/featureDialogWidgets/transformField.js +252 -0
  93. package/src/UI/featureDialogWidgets/utils.js +43 -0
  94. package/src/UI/featureDialogWidgets/vec3Field.js +133 -0
  95. package/src/UI/featureDialogs.js +1414 -0
  96. package/src/UI/fileManagerWidget.js +615 -0
  97. package/src/UI/history/HistoryCollectionWidget.js +1294 -0
  98. package/src/UI/history/historyCollectionWidget.css.js +257 -0
  99. package/src/UI/history/historyDisplayInfo.js +133 -0
  100. package/src/UI/mobile.js +28 -0
  101. package/src/UI/objectDump.js +442 -0
  102. package/src/UI/pmi/AnnotationCollectionWidget.js +120 -0
  103. package/src/UI/pmi/AnnotationHistory.js +353 -0
  104. package/src/UI/pmi/AnnotationRegistry.js +90 -0
  105. package/src/UI/pmi/BaseAnnotation.js +269 -0
  106. package/src/UI/pmi/LabelOverlay.css +102 -0
  107. package/src/UI/pmi/LabelOverlay.js +191 -0
  108. package/src/UI/pmi/PMIMode.js +1550 -0
  109. package/src/UI/pmi/PMIViewsWidget.js +1098 -0
  110. package/src/UI/pmi/annUtils.js +729 -0
  111. package/src/UI/pmi/dimensions/AngleDimensionAnnotation.js +647 -0
  112. package/src/UI/pmi/dimensions/ExplodeBodyAnnotation.js +507 -0
  113. package/src/UI/pmi/dimensions/HoleCalloutAnnotation.js +462 -0
  114. package/src/UI/pmi/dimensions/LeaderAnnotation.js +403 -0
  115. package/src/UI/pmi/dimensions/LinearDimensionAnnotation.js +532 -0
  116. package/src/UI/pmi/dimensions/NoteAnnotation.js +110 -0
  117. package/src/UI/pmi/dimensions/RadialDimensionAnnotation.js +659 -0
  118. package/src/UI/pmi/pmiStyle.js +44 -0
  119. package/src/UI/sketcher/SketchMode3D.js +4095 -0
  120. package/src/UI/sketcher/dimensions.js +674 -0
  121. package/src/UI/sketcher/glyphs.js +236 -0
  122. package/src/UI/sketcher/highlights.js +60 -0
  123. package/src/UI/toolbarButtons/aboutButton.js +5 -0
  124. package/src/UI/toolbarButtons/exportButton.js +609 -0
  125. package/src/UI/toolbarButtons/flatPatternButton.js +307 -0
  126. package/src/UI/toolbarButtons/importButton.js +160 -0
  127. package/src/UI/toolbarButtons/inspectorToggleButton.js +12 -0
  128. package/src/UI/toolbarButtons/metadataButton.js +1063 -0
  129. package/src/UI/toolbarButtons/orientToFaceButton.js +114 -0
  130. package/src/UI/toolbarButtons/registerDefaultButtons.js +46 -0
  131. package/src/UI/toolbarButtons/saveButton.js +99 -0
  132. package/src/UI/toolbarButtons/scriptRunnerButton.js +302 -0
  133. package/src/UI/toolbarButtons/testsButton.js +26 -0
  134. package/src/UI/toolbarButtons/undoRedoButtons.js +25 -0
  135. package/src/UI/toolbarButtons/wireframeToggleButton.js +5 -0
  136. package/src/UI/toolbarButtons/zoomToFitButton.js +5 -0
  137. package/src/UI/triangleDebuggerWindow.js +945 -0
  138. package/src/UI/viewer.js +4228 -0
  139. package/src/assemblyConstraints/AssemblyConstraintHistory.js +1576 -0
  140. package/src/assemblyConstraints/AssemblyConstraintRegistry.js +120 -0
  141. package/src/assemblyConstraints/BaseAssemblyConstraint.js +66 -0
  142. package/src/assemblyConstraints/constraintExpressionUtils.js +35 -0
  143. package/src/assemblyConstraints/constraintUtils/parallelAlignment.js +676 -0
  144. package/src/assemblyConstraints/constraints/AngleConstraint.js +485 -0
  145. package/src/assemblyConstraints/constraints/CoincidentConstraint.js +194 -0
  146. package/src/assemblyConstraints/constraints/DistanceConstraint.js +616 -0
  147. package/src/assemblyConstraints/constraints/FixedConstraint.js +78 -0
  148. package/src/assemblyConstraints/constraints/ParallelConstraint.js +252 -0
  149. package/src/assemblyConstraints/constraints/TouchAlignConstraint.js +961 -0
  150. package/src/core/entities/HistoryCollectionBase.js +72 -0
  151. package/src/core/entities/ListEntityBase.js +109 -0
  152. package/src/core/entities/schemaProcesser.js +121 -0
  153. package/src/exporters/sheetMetalFlatPattern.js +659 -0
  154. package/src/exporters/sheetMetalUnfold.js +862 -0
  155. package/src/exporters/step.js +1135 -0
  156. package/src/exporters/threeMF.js +575 -0
  157. package/src/features/assemblyComponent/AssemblyComponentFeature.js +780 -0
  158. package/src/features/boolean/BooleanFeature.js +94 -0
  159. package/src/features/chamfer/ChamferFeature.js +116 -0
  160. package/src/features/datium/DatiumFeature.js +80 -0
  161. package/src/features/edgeFeatureUtils.js +41 -0
  162. package/src/features/extrude/ExtrudeFeature.js +143 -0
  163. package/src/features/fillet/FilletFeature.js +197 -0
  164. package/src/features/helix/HelixFeature.js +405 -0
  165. package/src/features/hole/HoleFeature.js +1050 -0
  166. package/src/features/hole/screwClearance.js +86 -0
  167. package/src/features/hole/threadDesignationCatalog.js +149 -0
  168. package/src/features/imageHeightSolid/ImageHeightmapSolidFeature.js +463 -0
  169. package/src/features/imageToFace/ImageToFaceFeature.js +727 -0
  170. package/src/features/imageToFace/imageEditor.js +1270 -0
  171. package/src/features/imageToFace/traceUtils.js +971 -0
  172. package/src/features/import3dModel/Import3dModelFeature.js +151 -0
  173. package/src/features/loft/LoftFeature.js +605 -0
  174. package/src/features/mirror/MirrorFeature.js +151 -0
  175. package/src/features/offsetFace/OffsetFaceFeature.js +370 -0
  176. package/src/features/offsetShell/OffsetShellFeature.js +89 -0
  177. package/src/features/overlapCleanup/OverlapCleanupFeature.js +85 -0
  178. package/src/features/pattern/PatternFeature.js +275 -0
  179. package/src/features/patternLinear/PatternLinearFeature.js +120 -0
  180. package/src/features/patternRadial/PatternRadialFeature.js +186 -0
  181. package/src/features/plane/PlaneFeature.js +154 -0
  182. package/src/features/primitiveCone/primitiveConeFeature.js +99 -0
  183. package/src/features/primitiveCube/primitiveCubeFeature.js +70 -0
  184. package/src/features/primitiveCylinder/primitiveCylinderFeature.js +91 -0
  185. package/src/features/primitivePyramid/primitivePyramidFeature.js +72 -0
  186. package/src/features/primitiveSphere/primitiveSphereFeature.js +62 -0
  187. package/src/features/primitiveTorus/primitiveTorusFeature.js +109 -0
  188. package/src/features/remesh/RemeshFeature.js +97 -0
  189. package/src/features/revolve/RevolveFeature.js +111 -0
  190. package/src/features/selectionUtils.js +118 -0
  191. package/src/features/sheetMetal/SheetMetalContourFlangeFeature.js +1656 -0
  192. package/src/features/sheetMetal/SheetMetalCutoutFeature.js +1056 -0
  193. package/src/features/sheetMetal/SheetMetalFlangeFeature.js +1568 -0
  194. package/src/features/sheetMetal/SheetMetalHemFeature.js +43 -0
  195. package/src/features/sheetMetal/SheetMetalObject.js +141 -0
  196. package/src/features/sheetMetal/SheetMetalTabFeature.js +176 -0
  197. package/src/features/sheetMetal/UNFOLD_NEUTRAL_REQUIREMENTS.md +153 -0
  198. package/src/features/sheetMetal/contour-flange-rebuild-spec.md +261 -0
  199. package/src/features/sheetMetal/profileUtils.js +25 -0
  200. package/src/features/sheetMetal/sheetMetalCleanup.js +9 -0
  201. package/src/features/sheetMetal/sheetMetalFaceTypes.js +146 -0
  202. package/src/features/sheetMetal/sheetMetalMetadata.js +165 -0
  203. package/src/features/sheetMetal/sheetMetalPipeline.js +169 -0
  204. package/src/features/sheetMetal/sheetMetalProfileUtils.js +216 -0
  205. package/src/features/sheetMetal/sheetMetalTabUtils.js +29 -0
  206. package/src/features/sheetMetal/sheetMetalTree.js +210 -0
  207. package/src/features/sketch/SketchFeature.js +955 -0
  208. package/src/features/sketch/sketchSolver2D/ConstraintEngine.js +800 -0
  209. package/src/features/sketch/sketchSolver2D/constraintDefinitions.js +704 -0
  210. package/src/features/sketch/sketchSolver2D/mathHelpersMod.js +307 -0
  211. package/src/features/spline/SplineEditorSession.js +988 -0
  212. package/src/features/spline/SplineFeature.js +1388 -0
  213. package/src/features/spline/splineUtils.js +218 -0
  214. package/src/features/sweep/SweepFeature.js +110 -0
  215. package/src/features/transform/TransformFeature.js +152 -0
  216. package/src/features/tube/TubeFeature.js +635 -0
  217. package/src/fs.proxy.js +625 -0
  218. package/src/idbStorage.js +254 -0
  219. package/src/index.js +12 -0
  220. package/src/main.js +15 -0
  221. package/src/metadataManager.js +64 -0
  222. package/src/path.proxy.js +277 -0
  223. package/src/plugins/ghLoader.worker.js +151 -0
  224. package/src/plugins/pluginManager.js +286 -0
  225. package/src/pmi/PMIViewsManager.js +134 -0
  226. package/src/services/componentLibrary.js +198 -0
  227. package/src/tests/ConsoleCapture.js +189 -0
  228. package/src/tests/S7-diagnostics-2025-12-23T18-37-23-570Z.json +630 -0
  229. package/src/tests/browserTests.js +597 -0
  230. package/src/tests/debugBoolean.js +225 -0
  231. package/src/tests/partFiles/badBoolean.json +957 -0
  232. package/src/tests/partFiles/extrudeTest.json +88 -0
  233. package/src/tests/partFiles/filletFail.json +58 -0
  234. package/src/tests/partFiles/import_TEst.part.part.json +646 -0
  235. package/src/tests/partFiles/sheetMetalHem.BREP.json +734 -0
  236. package/src/tests/test_boolean_subtract.js +27 -0
  237. package/src/tests/test_chamfer.js +17 -0
  238. package/src/tests/test_extrudeFace.js +24 -0
  239. package/src/tests/test_fillet.js +17 -0
  240. package/src/tests/test_fillet_nonClosed.js +45 -0
  241. package/src/tests/test_filletsMoreDifficult.js +46 -0
  242. package/src/tests/test_history_features_basic.js +149 -0
  243. package/src/tests/test_hole.js +282 -0
  244. package/src/tests/test_mirror.js +16 -0
  245. package/src/tests/test_offsetShellGrouping.js +85 -0
  246. package/src/tests/test_plane.js +4 -0
  247. package/src/tests/test_primitiveCone.js +11 -0
  248. package/src/tests/test_primitiveCube.js +7 -0
  249. package/src/tests/test_primitiveCylinder.js +8 -0
  250. package/src/tests/test_primitivePyramid.js +9 -0
  251. package/src/tests/test_primitiveSphere.js +17 -0
  252. package/src/tests/test_primitiveTorus.js +21 -0
  253. package/src/tests/test_pushFace.js +126 -0
  254. package/src/tests/test_sheetMetalContourFlange.js +125 -0
  255. package/src/tests/test_sheetMetal_features.js +80 -0
  256. package/src/tests/test_sketch_openLoop.js +45 -0
  257. package/src/tests/test_solidMetrics.js +58 -0
  258. package/src/tests/test_stlLoader.js +1889 -0
  259. package/src/tests/test_sweepFace.js +55 -0
  260. package/src/tests/test_tube.js +45 -0
  261. package/src/tests/test_tube_closedLoop.js +67 -0
  262. package/src/tests/tests.js +493 -0
  263. package/src/tools/assemblyConstraintDialogCapturePage.js +56 -0
  264. package/src/tools/dialogCapturePageFactory.js +227 -0
  265. package/src/tools/featureDialogCapturePage.js +47 -0
  266. package/src/tools/pmiAnnotationDialogCapturePage.js +60 -0
  267. package/src/utils/axisHelpers.js +99 -0
  268. package/src/utils/deepClone.js +69 -0
  269. package/src/utils/geometryTolerance.js +37 -0
  270. package/src/utils/normalizeTypeString.js +8 -0
  271. package/src/utils/xformMath.js +51 -0
@@ -0,0 +1,292 @@
1
+ // AccordionWidget.rewritten.js
2
+ // ES6, framework-free, dark mode, no animations.
3
+ // All public methods are async and resolve AFTER the DOM has painted.
4
+
5
+ export class AccordionSection {
6
+ /**
7
+ * Represents a single accordion section.
8
+ * Properties:
9
+ * - title {string}
10
+ * - callbackOpen {Function|null}
11
+ * - callbackClose {Function|null}
12
+ * - uiElement {HTMLElement} // content container for this section
13
+ */
14
+ constructor({ title, titleElement, contentElement }) {
15
+ this.title = title;
16
+ this.callbackOpen = null;
17
+ this.callbackClose = null;
18
+ this.uiElement = contentElement || document.createElement("div");
19
+
20
+ // Click toggles collapsed state and fires callbacks (not awaited to preserve original behavior)
21
+ titleElement.addEventListener("click", () => {
22
+ const wasCollapsed = this.uiElement.classList.contains("collapsed");
23
+ this.uiElement.classList.toggle("collapsed");
24
+
25
+ if (wasCollapsed) {
26
+ if (typeof this.callbackOpen === "function") this.callbackOpen(this);
27
+ } else {
28
+ if (typeof this.callbackClose === "function") this.callbackClose(this);
29
+ }
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Collapse this section and resolve after paint.
35
+ */
36
+ async collapse() {
37
+ this.uiElement.classList.add("collapsed");
38
+ if (typeof this.callbackClose === "function") this.callbackClose(this);
39
+ await _flushAfterPaint();
40
+ return true;
41
+ }
42
+
43
+ /**
44
+ * Expand this section and resolve after paint.
45
+ */
46
+ async expand() {
47
+ this.uiElement.classList.remove("collapsed");
48
+ if (typeof this.callbackOpen === "function") this.callbackOpen(this);
49
+ await _flushAfterPaint();
50
+ return true;
51
+ }
52
+ }
53
+
54
+ export class AccordionWidget {
55
+ constructor() {
56
+ this.uiElement = document.createElement("div");
57
+ this._ensureStyles();
58
+ this.uiElement.classList.add("accordion");
59
+ }
60
+
61
+ _ensureStyles() {
62
+ if (document.getElementById("accordion-widget-styles")) return;
63
+ const style = document.createElement("style");
64
+ style.id = "accordion-widget-styles";
65
+ style.textContent = `
66
+ .accordion {
67
+ border: 1px solid #1f2937;
68
+ border-radius: 8px;
69
+ overflow: scfroll;
70
+ background: #0b0f13; /* dark */
71
+ color: #e5e7eb; /* light text */
72
+ }
73
+ .accordion-title {
74
+ padding: 8px 10px;
75
+ cursor: pointer;
76
+ border-bottom: 1px solid #1f2937;
77
+ font-weight: 700;
78
+ user-select: none;
79
+ background: #111827;
80
+ user-select: none;
81
+ }
82
+ .accordion-title:hover {
83
+ background: #203955ff;
84
+ }
85
+ .accordion-content {
86
+ padding: 0px;
87
+ background: #0b0f13;
88
+ }
89
+ .accordion-content.collapsed {
90
+ display: none;
91
+ }
92
+ `;
93
+ document.head.appendChild(style);
94
+ }
95
+
96
+ /**
97
+ * Add a new section, expand it, and return the AccordionSection.
98
+ * @param {string} title
99
+ * @returns {Promise<AccordionSection>}
100
+ */
101
+ async addSection(title) {
102
+ // Title element
103
+ const titleElement = document.createElement("div");
104
+ titleElement.classList.add("accordion-title");
105
+ titleElement.textContent = title;
106
+ titleElement.name = `accordion-title-${title}`;
107
+ this.uiElement.appendChild(titleElement);
108
+
109
+ // Content element
110
+ const contentElement = document.createElement("div");
111
+ contentElement.classList.add("accordion-content");
112
+ contentElement.name = `accordion-content-${title}`;
113
+ contentElement.id = `accordion-content-${title}`;
114
+ this.uiElement.appendChild(contentElement);
115
+
116
+ const section = new AccordionSection({
117
+ title,
118
+ titleElement,
119
+ contentElement,
120
+ });
121
+
122
+ // Ensure the new nodes are in the DOM
123
+ await _flushAfterPaint();
124
+
125
+ // Expand the new section (matches original behavior)
126
+ await this.expandSection(title);
127
+
128
+ return section;
129
+ }
130
+
131
+ /**
132
+ * Remove a section by title (returns true if removed).
133
+ * @param {string} title
134
+ */
135
+ async removeSection(title) {
136
+ const titleEl = this.uiElement.querySelector(
137
+ `.accordion-title[name="accordion-title-${title}"]`
138
+ );
139
+ const contentEl = this.uiElement.querySelector(
140
+ `.accordion-content[name="accordion-content-${title}"]`
141
+ );
142
+
143
+ let changed = false;
144
+ if (titleEl) {
145
+ this.uiElement.removeChild(titleEl);
146
+ changed = true;
147
+ }
148
+ if (contentEl) {
149
+ this.uiElement.removeChild(contentEl);
150
+ changed = true;
151
+ }
152
+
153
+ if (changed) {
154
+ await _flushAfterPaint();
155
+ return true;
156
+ }
157
+ return false;
158
+ }
159
+
160
+ /**
161
+ * Clear all sections.
162
+ */
163
+ async clear() {
164
+ this.uiElement.innerHTML = "";
165
+ await _flushAfterPaint();
166
+ return true;
167
+ }
168
+
169
+ /**
170
+ * Collapse all sections (does not invoke per-section callbacks, preserving original behavior).
171
+ */
172
+ async collapseAll() {
173
+ const els = this.uiElement.querySelectorAll(".accordion-content");
174
+ els.forEach((el) => el.classList.add("collapsed"));
175
+ await _flushAfterPaint();
176
+ return true;
177
+ }
178
+
179
+ /**
180
+ * Expand all sections (does not invoke per-section callbacks, preserving original behavior).
181
+ */
182
+ async expandAll() {
183
+ const els = this.uiElement.querySelectorAll(".accordion-content");
184
+ await els.forEach(async(el) => await el.classList.remove("collapsed"));
185
+ await _flushAfterPaint();
186
+ return true;
187
+ }
188
+
189
+ /**
190
+ * Expand a specific section by title. Returns true if found & expanded.
191
+ * @param {string} title
192
+ */
193
+ async expandSection(title) {
194
+ const contentEl = document.getElementById(`accordion-content-${title}`);
195
+ if (!contentEl) return false;
196
+ await contentEl.classList.remove("collapsed");
197
+ await _flushAfterPaint();
198
+ return true;
199
+ }
200
+
201
+ /**
202
+ * Hide a section (title + content) by title.
203
+ * @param {string} title
204
+ * @returns {boolean} true if found
205
+ */
206
+ hideSection(title) {
207
+ const titleEl = this._findTitleEl(title);
208
+ const contentEl = this._findContentEl(title, titleEl);
209
+ let changed = false;
210
+ if (titleEl) {
211
+ titleEl.style.display = 'none';
212
+ titleEl.hidden = true;
213
+ titleEl.setAttribute('aria-hidden', 'true');
214
+ changed = true;
215
+ }
216
+ if (contentEl) {
217
+ contentEl.style.display = 'none';
218
+ contentEl.hidden = true;
219
+ contentEl.setAttribute('aria-hidden', 'true');
220
+ contentEl.classList.add('collapsed');
221
+ changed = true;
222
+ }
223
+ return changed;
224
+ }
225
+
226
+ /**
227
+ * Show a section (title + content) by title.
228
+ * @param {string} title
229
+ * @returns {boolean} true if found
230
+ */
231
+ showSection(title) {
232
+ const titleEl = this._findTitleEl(title);
233
+ const contentEl = this._findContentEl(title, titleEl);
234
+ let changed = false;
235
+ if (titleEl) {
236
+ titleEl.style.display = '';
237
+ titleEl.hidden = false;
238
+ titleEl.setAttribute('aria-hidden', 'false');
239
+ changed = true;
240
+ }
241
+ if (contentEl) {
242
+ contentEl.style.display = '';
243
+ contentEl.hidden = false;
244
+ contentEl.setAttribute('aria-hidden', 'false');
245
+ contentEl.classList.remove('collapsed');
246
+ changed = true;
247
+ }
248
+ return changed;
249
+ }
250
+
251
+ _findTitleEl(title) {
252
+ const direct = this.uiElement.querySelector(`.accordion-title[name="accordion-title-${title}"]`);
253
+ if (direct) return direct;
254
+ const titles = Array.from(this.uiElement.querySelectorAll('.accordion-title'));
255
+ const norm = String(title || '').trim().toUpperCase();
256
+ return titles.find((el) => {
257
+ const text = (el.textContent || '').trim().toUpperCase();
258
+ return text === norm || text.startsWith(norm) || norm.startsWith(text);
259
+ }) || null;
260
+ }
261
+
262
+ _findContentEl(title, titleEl = null) {
263
+ const direct = this.uiElement.querySelector(`.accordion-content[name="accordion-content-${title}"]`);
264
+ if (direct) return direct;
265
+ if (titleEl && titleEl.nextElementSibling && titleEl.nextElementSibling.classList.contains('accordion-content')) {
266
+ return titleEl.nextElementSibling;
267
+ }
268
+ // Fallback: find content by id match start
269
+ const contents = Array.from(this.uiElement.querySelectorAll('.accordion-content'));
270
+ const norm = String(title || '').trim().toUpperCase();
271
+ return contents.find((el) => {
272
+ const id = (el.id || '').trim().toUpperCase();
273
+ const name = (el.getAttribute('name') || '').trim().toUpperCase();
274
+ return id.includes(norm) || name.includes(norm);
275
+ }) || null;
276
+ }
277
+ }
278
+
279
+ /* -------------------------------------------------------
280
+ Internal: resolve AFTER the browser has had a chance to
281
+ apply style changes and paint. Two rAFs are used because:
282
+ - rAF #1: runs before layout/paint of the next frame
283
+ - rAF #2: ensures the paint has occurred
284
+ -------------------------------------------------------- */
285
+ function _nextFrame() {
286
+ return new Promise((resolve) => requestAnimationFrame(() => resolve()));
287
+ }
288
+
289
+ async function _flushAfterPaint() {
290
+ await _nextFrame();
291
+ await _nextFrame();
292
+ }