@e-llm-studio/citation 0.0.251-beta.1 → 0.0.252

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 (213) hide show
  1. package/dist/cjs/features/CognitiveCompare/CitationAnchor.js +1 -1
  2. package/dist/cjs/features/CognitiveCompare/CitationAnchor.js.map +1 -1
  3. package/dist/cjs/features/CognitiveCompare/CitationRenderer.js +1 -1
  4. package/dist/cjs/features/CognitiveCompare/CitationRenderer.js.map +1 -1
  5. package/dist/cjs/features/CognitiveCompare/CitationRendererInner.js +2 -0
  6. package/dist/cjs/features/CognitiveCompare/CitationRendererInner.js.map +1 -0
  7. package/dist/cjs/features/CognitiveCompare/CognitiveCompare.js +1 -1
  8. package/dist/cjs/features/CognitiveCompare/CognitiveCompare.js.map +1 -1
  9. package/dist/cjs/features/CognitiveCompare/CognitiveCompareConstants.js +1 -1
  10. package/dist/cjs/features/CognitiveCompare/CognitiveCompareConstants.js.map +1 -1
  11. package/dist/cjs/features/CognitiveCompare/CognitiveComparehelpers.js +1 -1
  12. package/dist/cjs/features/CognitiveCompare/CognitiveComparehelpers.js.map +1 -1
  13. package/dist/cjs/features/CognitiveCompare/CognitivePopup.js +1 -1
  14. package/dist/cjs/features/CognitiveCompare/CognitivePopup.js.map +1 -1
  15. package/dist/cjs/features/CognitiveCompare/CompareContext.js +1 -1
  16. package/dist/cjs/features/CognitiveCompare/CompareContext.js.map +1 -1
  17. package/dist/cjs/features/CognitiveCompare/GptWebCitationPanel.js +2 -0
  18. package/dist/cjs/features/CognitiveCompare/GptWebCitationPanel.js.map +1 -0
  19. package/dist/cjs/features/CognitiveCompare/Guidelines/components/GuidelinePanel.js +1 -1
  20. package/dist/cjs/features/CognitiveCompare/Guidelines/components/GuidelinePanel.js.map +1 -1
  21. package/dist/cjs/features/CognitiveCompare/Guidelines/components/WebGptPanel.js +1 -1
  22. package/dist/cjs/features/CognitiveCompare/Guidelines/components/WebGptPanel.js.map +1 -1
  23. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/guidelineTargets.js +2 -0
  24. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/guidelineTargets.js.map +1 -0
  25. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/hasGptCitationObjects.js +2 -0
  26. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/hasGptCitationObjects.js.map +1 -0
  27. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/processGuidelinesMarkdown.js +1 -1
  28. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/processGuidelinesMarkdown.js.map +1 -1
  29. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/resolveGuidelineSelection.js +2 -0
  30. package/dist/cjs/features/CognitiveCompare/Guidelines/utils/resolveGuidelineSelection.js.map +1 -0
  31. package/dist/cjs/features/CognitiveCompare/components/GuidelineSkeletonLoader.js +2 -0
  32. package/dist/cjs/features/CognitiveCompare/components/GuidelineSkeletonLoader.js.map +1 -0
  33. package/dist/cjs/features/CognitiveCompare/components/LHSSectionRow.js +1 -1
  34. package/dist/cjs/features/CognitiveCompare/components/LHSSectionRow.js.map +1 -1
  35. package/dist/cjs/features/CognitiveCompare/components/RHSSectionRow.js +1 -1
  36. package/dist/cjs/features/CognitiveCompare/components/RHSSectionRow.js.map +1 -1
  37. package/dist/cjs/features/CognitiveCompare/components/SectionAccordion.js +1 -1
  38. package/dist/cjs/features/CognitiveCompare/components/SectionAccordion.js.map +1 -1
  39. package/dist/cjs/features/CognitiveCompare/components/SubSectionAccordion.js +1 -1
  40. package/dist/cjs/features/CognitiveCompare/components/SubSectionAccordion.js.map +1 -1
  41. package/dist/cjs/features/CognitiveCompare/components/SvgConnectors.js +1 -1
  42. package/dist/cjs/features/CognitiveCompare/components/SvgConnectors.js.map +1 -1
  43. package/dist/cjs/features/CognitiveCompare/hooks/memoizedMarkdown.js +1 -1
  44. package/dist/cjs/features/CognitiveCompare/hooks/memoizedMarkdown.js.map +1 -1
  45. package/dist/cjs/features/CognitiveCompare/hooks/useCompareData.js +1 -1
  46. package/dist/cjs/features/CognitiveCompare/hooks/useCompareData.js.map +1 -1
  47. package/dist/cjs/features/CognitiveCompare/hooks/useLinesCalculator.js +1 -1
  48. package/dist/cjs/features/CognitiveCompare/hooks/useLinesCalculator.js.map +1 -1
  49. package/dist/cjs/features/CognitiveCompare/hooks/useOnDemandCitationCache.js +2 -0
  50. package/dist/cjs/features/CognitiveCompare/hooks/useOnDemandCitationCache.js.map +1 -0
  51. package/dist/cjs/features/CognitiveCompare/hooks/useSideBySide.js +1 -1
  52. package/dist/cjs/features/CognitiveCompare/hooks/useSideBySide.js.map +1 -1
  53. package/dist/cjs/features/CognitiveCompare/onDemandCitations/cacheKey.js +2 -0
  54. package/dist/cjs/features/CognitiveCompare/onDemandCitations/cacheKey.js.map +1 -0
  55. package/dist/cjs/features/CognitiveCompare/onDemandCitations/contextBuilder.js +2 -0
  56. package/dist/cjs/features/CognitiveCompare/onDemandCitations/contextBuilder.js.map +1 -0
  57. package/dist/cjs/features/CognitiveCompare/onDemandCitations/href.js +2 -0
  58. package/dist/cjs/features/CognitiveCompare/onDemandCitations/href.js.map +1 -0
  59. package/dist/cjs/features/CognitiveCompare/onDemandCitations/payload.js +2 -0
  60. package/dist/cjs/features/CognitiveCompare/onDemandCitations/payload.js.map +1 -0
  61. package/dist/cjs/features/CognitiveCompare/onDemandCitations/response.js +2 -0
  62. package/dist/cjs/features/CognitiveCompare/onDemandCitations/response.js.map +1 -0
  63. package/dist/cjs/features/CognitiveCompare/utils/normalizeCompactedGfmTables.js +2 -0
  64. package/dist/cjs/features/CognitiveCompare/utils/normalizeCompactedGfmTables.js.map +1 -0
  65. package/dist/cjs/features/CognitiveCompare/utils/normalizeInlineMarkdown.js +2 -0
  66. package/dist/cjs/features/CognitiveCompare/utils/normalizeInlineMarkdown.js.map +1 -0
  67. package/dist/cjs/features/CognitiveCompare/utils/normalizeRedlineMarkdown.js +2 -0
  68. package/dist/cjs/features/CognitiveCompare/utils/normalizeRedlineMarkdown.js.map +1 -0
  69. package/dist/cjs/features/SegmentReviewComponents/BoundaryCard.js +1 -1
  70. package/dist/cjs/features/SegmentReviewComponents/BoundaryCard.js.map +1 -1
  71. package/dist/cjs/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js +1 -1
  72. package/dist/cjs/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js.map +1 -1
  73. package/dist/features/CognitiveCompare/CitationAnchor.js +1 -1
  74. package/dist/features/CognitiveCompare/CitationAnchor.js.map +1 -1
  75. package/dist/features/CognitiveCompare/CitationRenderer.js +1 -1
  76. package/dist/features/CognitiveCompare/CitationRenderer.js.map +1 -1
  77. package/dist/features/CognitiveCompare/CitationRendererInner.js +2 -0
  78. package/dist/features/CognitiveCompare/CitationRendererInner.js.map +1 -0
  79. package/dist/features/CognitiveCompare/CognitiveCompare.js +1 -1
  80. package/dist/features/CognitiveCompare/CognitiveCompare.js.map +1 -1
  81. package/dist/features/CognitiveCompare/CognitiveCompareConstants.js +1 -1
  82. package/dist/features/CognitiveCompare/CognitiveCompareConstants.js.map +1 -1
  83. package/dist/features/CognitiveCompare/CognitiveComparehelpers.js +1 -1
  84. package/dist/features/CognitiveCompare/CognitiveComparehelpers.js.map +1 -1
  85. package/dist/features/CognitiveCompare/CognitivePopup.js +1 -1
  86. package/dist/features/CognitiveCompare/CognitivePopup.js.map +1 -1
  87. package/dist/features/CognitiveCompare/CompareContext.js +1 -1
  88. package/dist/features/CognitiveCompare/CompareContext.js.map +1 -1
  89. package/dist/features/CognitiveCompare/GptWebCitationPanel.js +2 -0
  90. package/dist/features/CognitiveCompare/GptWebCitationPanel.js.map +1 -0
  91. package/dist/features/CognitiveCompare/Guidelines/components/GuidelinePanel.js +1 -1
  92. package/dist/features/CognitiveCompare/Guidelines/components/GuidelinePanel.js.map +1 -1
  93. package/dist/features/CognitiveCompare/Guidelines/components/WebGptPanel.js +1 -1
  94. package/dist/features/CognitiveCompare/Guidelines/components/WebGptPanel.js.map +1 -1
  95. package/dist/features/CognitiveCompare/Guidelines/utils/guidelineTargets.js +2 -0
  96. package/dist/features/CognitiveCompare/Guidelines/utils/guidelineTargets.js.map +1 -0
  97. package/dist/features/CognitiveCompare/Guidelines/utils/hasGptCitationObjects.js +2 -0
  98. package/dist/features/CognitiveCompare/Guidelines/utils/hasGptCitationObjects.js.map +1 -0
  99. package/dist/features/CognitiveCompare/Guidelines/utils/processGuidelinesMarkdown.js +1 -1
  100. package/dist/features/CognitiveCompare/Guidelines/utils/processGuidelinesMarkdown.js.map +1 -1
  101. package/dist/features/CognitiveCompare/Guidelines/utils/resolveGuidelineSelection.js +2 -0
  102. package/dist/features/CognitiveCompare/Guidelines/utils/resolveGuidelineSelection.js.map +1 -0
  103. package/dist/features/CognitiveCompare/components/GuidelineSkeletonLoader.js +2 -0
  104. package/dist/features/CognitiveCompare/components/GuidelineSkeletonLoader.js.map +1 -0
  105. package/dist/features/CognitiveCompare/components/LHSSectionRow.js +1 -1
  106. package/dist/features/CognitiveCompare/components/LHSSectionRow.js.map +1 -1
  107. package/dist/features/CognitiveCompare/components/RHSSectionRow.js +1 -1
  108. package/dist/features/CognitiveCompare/components/RHSSectionRow.js.map +1 -1
  109. package/dist/features/CognitiveCompare/components/SectionAccordion.js +1 -1
  110. package/dist/features/CognitiveCompare/components/SectionAccordion.js.map +1 -1
  111. package/dist/features/CognitiveCompare/components/SubSectionAccordion.js +1 -1
  112. package/dist/features/CognitiveCompare/components/SubSectionAccordion.js.map +1 -1
  113. package/dist/features/CognitiveCompare/components/SvgConnectors.js +1 -1
  114. package/dist/features/CognitiveCompare/components/SvgConnectors.js.map +1 -1
  115. package/dist/features/CognitiveCompare/hooks/memoizedMarkdown.js +1 -1
  116. package/dist/features/CognitiveCompare/hooks/memoizedMarkdown.js.map +1 -1
  117. package/dist/features/CognitiveCompare/hooks/useCompareData.js +1 -1
  118. package/dist/features/CognitiveCompare/hooks/useCompareData.js.map +1 -1
  119. package/dist/features/CognitiveCompare/hooks/useLinesCalculator.js +1 -1
  120. package/dist/features/CognitiveCompare/hooks/useLinesCalculator.js.map +1 -1
  121. package/dist/features/CognitiveCompare/hooks/useOnDemandCitationCache.js +2 -0
  122. package/dist/features/CognitiveCompare/hooks/useOnDemandCitationCache.js.map +1 -0
  123. package/dist/features/CognitiveCompare/hooks/useSideBySide.js +1 -1
  124. package/dist/features/CognitiveCompare/hooks/useSideBySide.js.map +1 -1
  125. package/dist/features/CognitiveCompare/onDemandCitations/cacheKey.js +2 -0
  126. package/dist/features/CognitiveCompare/onDemandCitations/cacheKey.js.map +1 -0
  127. package/dist/features/CognitiveCompare/onDemandCitations/contextBuilder.js +2 -0
  128. package/dist/features/CognitiveCompare/onDemandCitations/contextBuilder.js.map +1 -0
  129. package/dist/features/CognitiveCompare/onDemandCitations/href.js +2 -0
  130. package/dist/features/CognitiveCompare/onDemandCitations/href.js.map +1 -0
  131. package/dist/features/CognitiveCompare/onDemandCitations/payload.js +2 -0
  132. package/dist/features/CognitiveCompare/onDemandCitations/payload.js.map +1 -0
  133. package/dist/features/CognitiveCompare/onDemandCitations/response.js +2 -0
  134. package/dist/features/CognitiveCompare/onDemandCitations/response.js.map +1 -0
  135. package/dist/features/CognitiveCompare/utils/normalizeCompactedGfmTables.js +2 -0
  136. package/dist/features/CognitiveCompare/utils/normalizeCompactedGfmTables.js.map +1 -0
  137. package/dist/features/CognitiveCompare/utils/normalizeInlineMarkdown.js +2 -0
  138. package/dist/features/CognitiveCompare/utils/normalizeInlineMarkdown.js.map +1 -0
  139. package/dist/features/CognitiveCompare/utils/normalizeRedlineMarkdown.js +2 -0
  140. package/dist/features/CognitiveCompare/utils/normalizeRedlineMarkdown.js.map +1 -0
  141. package/dist/features/SegmentReviewComponents/BoundaryCard.js +1 -1
  142. package/dist/features/SegmentReviewComponents/BoundaryCard.js.map +1 -1
  143. package/dist/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js +1 -1
  144. package/dist/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js.map +1 -1
  145. package/dist/types/features/CognitiveCompare/CitationAnchor.d.ts +2 -0
  146. package/dist/types/features/CognitiveCompare/CitationAnchor.d.ts.map +1 -1
  147. package/dist/types/features/CognitiveCompare/CitationRenderer.d.ts +8 -1
  148. package/dist/types/features/CognitiveCompare/CitationRenderer.d.ts.map +1 -1
  149. package/dist/types/features/CognitiveCompare/CitationRendererInner.d.ts +13 -0
  150. package/dist/types/features/CognitiveCompare/CitationRendererInner.d.ts.map +1 -0
  151. package/dist/types/features/CognitiveCompare/CognitiveCompare.d.ts +1 -1
  152. package/dist/types/features/CognitiveCompare/CognitiveCompare.d.ts.map +1 -1
  153. package/dist/types/features/CognitiveCompare/CognitiveCompareConstants.d.ts +1 -1
  154. package/dist/types/features/CognitiveCompare/CognitiveCompareConstants.d.ts.map +1 -1
  155. package/dist/types/features/CognitiveCompare/CognitiveCompareTypes.d.ts +14 -1
  156. package/dist/types/features/CognitiveCompare/CognitiveCompareTypes.d.ts.map +1 -1
  157. package/dist/types/features/CognitiveCompare/CognitiveComparehelpers.d.ts +12 -0
  158. package/dist/types/features/CognitiveCompare/CognitiveComparehelpers.d.ts.map +1 -1
  159. package/dist/types/features/CognitiveCompare/CognitivePopup.d.ts.map +1 -1
  160. package/dist/types/features/CognitiveCompare/CompareContext.d.ts +10 -1
  161. package/dist/types/features/CognitiveCompare/CompareContext.d.ts.map +1 -1
  162. package/dist/types/features/CognitiveCompare/GptWebCitationPanel.d.ts +7 -0
  163. package/dist/types/features/CognitiveCompare/GptWebCitationPanel.d.ts.map +1 -0
  164. package/dist/types/features/CognitiveCompare/Guidelines/components/GuidelinePanel.d.ts.map +1 -1
  165. package/dist/types/features/CognitiveCompare/Guidelines/components/WebGptPanel.d.ts.map +1 -1
  166. package/dist/types/features/CognitiveCompare/Guidelines/utils/guidelineTargets.d.ts +3 -0
  167. package/dist/types/features/CognitiveCompare/Guidelines/utils/guidelineTargets.d.ts.map +1 -0
  168. package/dist/types/features/CognitiveCompare/Guidelines/utils/hasGptCitationObjects.d.ts +3 -0
  169. package/dist/types/features/CognitiveCompare/Guidelines/utils/hasGptCitationObjects.d.ts.map +1 -0
  170. package/dist/types/features/CognitiveCompare/Guidelines/utils/processGuidelinesMarkdown.d.ts +14 -1
  171. package/dist/types/features/CognitiveCompare/Guidelines/utils/processGuidelinesMarkdown.d.ts.map +1 -1
  172. package/dist/types/features/CognitiveCompare/Guidelines/utils/resolveGuidelineSelection.d.ts +19 -0
  173. package/dist/types/features/CognitiveCompare/Guidelines/utils/resolveGuidelineSelection.d.ts.map +1 -0
  174. package/dist/types/features/CognitiveCompare/components/GuidelineSkeletonLoader.d.ts +8 -0
  175. package/dist/types/features/CognitiveCompare/components/GuidelineSkeletonLoader.d.ts.map +1 -0
  176. package/dist/types/features/CognitiveCompare/components/LHSSectionRow.d.ts.map +1 -1
  177. package/dist/types/features/CognitiveCompare/components/RHSSectionRow.d.ts.map +1 -1
  178. package/dist/types/features/CognitiveCompare/components/SectionAccordion.d.ts.map +1 -1
  179. package/dist/types/features/CognitiveCompare/components/SubSectionAccordion.d.ts.map +1 -1
  180. package/dist/types/features/CognitiveCompare/components/SvgConnectors.d.ts +3 -2
  181. package/dist/types/features/CognitiveCompare/components/SvgConnectors.d.ts.map +1 -1
  182. package/dist/types/features/CognitiveCompare/hooks/memoizedMarkdown.d.ts +2 -1
  183. package/dist/types/features/CognitiveCompare/hooks/memoizedMarkdown.d.ts.map +1 -1
  184. package/dist/types/features/CognitiveCompare/hooks/useCompareData.d.ts +1 -1
  185. package/dist/types/features/CognitiveCompare/hooks/useCompareData.d.ts.map +1 -1
  186. package/dist/types/features/CognitiveCompare/hooks/useLinesCalculator.d.ts.map +1 -1
  187. package/dist/types/features/CognitiveCompare/hooks/useOnDemandCitationCache.d.ts +10 -0
  188. package/dist/types/features/CognitiveCompare/hooks/useOnDemandCitationCache.d.ts.map +1 -0
  189. package/dist/types/features/CognitiveCompare/hooks/useSideBySide.d.ts.map +1 -1
  190. package/dist/types/features/CognitiveCompare/onDemandCitations/cacheKey.d.ts +3 -0
  191. package/dist/types/features/CognitiveCompare/onDemandCitations/cacheKey.d.ts.map +1 -0
  192. package/dist/types/features/CognitiveCompare/onDemandCitations/contextBuilder.d.ts +16 -0
  193. package/dist/types/features/CognitiveCompare/onDemandCitations/contextBuilder.d.ts.map +1 -0
  194. package/dist/types/features/CognitiveCompare/onDemandCitations/href.d.ts +6 -0
  195. package/dist/types/features/CognitiveCompare/onDemandCitations/href.d.ts.map +1 -0
  196. package/dist/types/features/CognitiveCompare/onDemandCitations/index.d.ts +7 -0
  197. package/dist/types/features/CognitiveCompare/onDemandCitations/index.d.ts.map +1 -0
  198. package/dist/types/features/CognitiveCompare/onDemandCitations/payload.d.ts +4 -0
  199. package/dist/types/features/CognitiveCompare/onDemandCitations/payload.d.ts.map +1 -0
  200. package/dist/types/features/CognitiveCompare/onDemandCitations/response.d.ts +3 -0
  201. package/dist/types/features/CognitiveCompare/onDemandCitations/response.d.ts.map +1 -0
  202. package/dist/types/features/CognitiveCompare/onDemandCitations/types.d.ts +134 -0
  203. package/dist/types/features/CognitiveCompare/onDemandCitations/types.d.ts.map +1 -0
  204. package/dist/types/features/CognitiveCompare/utils/normalizeCompactedGfmTables.d.ts +7 -0
  205. package/dist/types/features/CognitiveCompare/utils/normalizeCompactedGfmTables.d.ts.map +1 -0
  206. package/dist/types/features/CognitiveCompare/utils/normalizeInlineMarkdown.d.ts +6 -0
  207. package/dist/types/features/CognitiveCompare/utils/normalizeInlineMarkdown.d.ts.map +1 -0
  208. package/dist/types/features/CognitiveCompare/utils/normalizeRedlineMarkdown.d.ts +6 -0
  209. package/dist/types/features/CognitiveCompare/utils/normalizeRedlineMarkdown.d.ts.map +1 -0
  210. package/dist/types/features/SegmentReviewComponents/BoundaryCard.d.ts.map +1 -1
  211. package/dist/types/features/SegmentReviewComponents/SegmentReviewPdfWrapper.d.ts +3 -1
  212. package/dist/types/features/SegmentReviewComponents/SegmentReviewPdfWrapper.d.ts.map +1 -1
  213. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import{useState as t,useRef as e,useCallback as n,useEffect as r}from"react";import{DEVIATION_BADGE_SEPARATOR as i}from"../CognitiveComparehelpers.js";const c=({containerRef:c,leftContainerRef:l,rightContainerRef:o,svgContainerRef:u,pathRefs:s,leftHeaderRef:h,rightHeaderRef:g,proposedSections:d,existingSections:a,visibleFields:f,leftRefs:p,rightRefs:b,sectionLeftRefs:y,sectionRightRefs:$,subSectionLeftRefs:x,subSectionRightRefs:m,lhsBadgeRefs:R,rhsBadgeRefs:C,sectionRowRefs:A,expandedSections:B,expandedSubSections:S,connectedSections:M,isSideBySide:v,activeSideBySideSection:I,maintainRelativeOrder:T,isGuidelineMode:L,cognitiveMap:F,getSectionCompareStyle:H,getSubSectionCompareStyle:w,getDeviationStyleByKey:k,isArrowVisible:E,isAnimatingRef:N,isSideBySideRef:Y,sideBySideCacheRef:D,sideBySideLineRef:j,activeSideBySideSectionRef:O,activeSideBySideRightSectionRef:z,connectedLines:P,setConnectedLines:Q,cachedConnectedPositions:X,calculateLinesRef:q,resizeTimerRef:G,scrollLock:K,scrollSyncLocked:V,handleResizeRef:J,activeProposed:U,existingRule:W,analysisData:Z,pendingScrollTargetRef:_,pendingScrollCallbackRef:tt,resolvedComparisonConfig:et,getFieldData:nt})=>{const[rt,it]=t([]),[ct,lt]=t(null),[ot,ut]=t([]),st=P??ot,ht=Q??ut,[gt,dt]=t({width:0,height:0}),at=e(!1),ft=e(!1),pt=e(!1),bt=e(null),yt=e([]),$t=X??yt,xt=(t,e,n,r,i,c,l)=>{if(Math.abs(r-e)<=1)return c&&l?`M ${t},${e} L ${n},${r}`:c&&!l?`M ${t},${e} L ${i},${e}`:!c&&l?`M ${i},${e} L ${n},${r}`:`M ${i},${e} L ${i},${r}`;const o=Math.min(15,Math.abs(i-t),Math.abs(r-e)/2),u=Math.min(15,Math.abs(n-i),Math.abs(r-e)/2),s=r>e?o:-o,h=r>e?u:-u,g=n>i?u:-u;return c&&l?`M ${t},${e} L ${i-o},${e} Q ${i},${e} ${i},${e+s} L ${i},${r-h} Q ${i},${r} ${i+g},${r} L ${n},${r}`:c&&!l?`M ${t},${e} L ${i-o},${e} Q ${i},${e} ${i},${e+s} L ${i},${r}`:!c&&l?`M ${i},${e} L ${i},${r-h} Q ${i},${r} ${i+g},${r} L ${n},${r}`:`M ${i},${e} L ${i},${r}`},mt=n(()=>{if(!at.current&&!N.current){at.current=!0;try{if(!c.current)return;const t=t=>{const e=t.split("-"),n=e[0];if(!B[n]&&!1===T)return!1;if(T&&!B[`left-${n}`]&&!B[`right-${n}`]&&!B[n])return!1;let r=n;for(let t=1;t<e.length-1;t++)if(r+=`-${e[t]}`,!S[r])return!1;return!0},e=c.current.getBoundingClientRect();dt({width:e.width,height:e.height});const n=[];if(f.forEach(({key:t})=>{const e=p.current[t]?.current,n=b.current[t]?.current;e&&n&&(e.style.height="auto",n.style.height="auto",e.style.minHeight="0px",n.style.minHeight="0px")}),!N.current){for(let t=0;t<Math.max(d.length,a.length);t++){const e=y.current[t]?.current,n=$.current[t]?.current;e&&(e.style.height="auto",e.style.minHeight="0px"),n&&(n.style.height="auto",n.style.minHeight="0px")}T||Object.keys(x.current).forEach(e=>{if(!t(e))return;const n=x.current[e]?.current,r=m.current[e]?.current;n&&r&&(n.style.height="auto",r.style.height="auto",n.style.minHeight="0px",r.style.minHeight="0px")})}const r={};f.forEach(({key:t})=>{const e=p.current[t]?.current,n=b.current[t]?.current;if(e&&n){const i=e.getBoundingClientRect(),c=n.getBoundingClientRect();r[t]=Math.max(i.height,c.height)}});const u={left:{},right:{}},s={};if(!N.current)if(T){if(v&&null!==I)if("number"==typeof I){const t=I,e=d[t],n=y.current[t]?.current;n&&e&&(e.refIndexes||[]).forEach(e=>{const r=a.findIndex(t=>t.selfIndex===e),i=$.current[r]?.current;if(i&&(B[`left-${t}`]||B[`right-${r}`])){const e=Math.max(n.getBoundingClientRect().height,i.getBoundingClientRect().height);u.left[t]=Math.max(u.left[t]||0,e),u.right[r]=Math.max(u.right[r]||0,e)}})}else{const t=I.split(i)[2];if(t){const e=x.current[t]?.current,n=m.current[t]?.current;if(e&&n){const r=Math.max(e.getBoundingClientRect().height,n.getBoundingClientRect().height);s[t]=Math.max(s[t]||0,r)}}}}else{Object.keys(x.current).forEach(e=>{if(!t(e))return;const n=x.current[e]?.current,r=m.current[e]?.current;if(n&&r&&null!==n.offsetParent&&null!==r.offsetParent){const t=n.getBoundingClientRect(),i=r.getBoundingClientRect(),c=Math.max(t.height,i.height);s[e]=c,n.style.minHeight=`${c}px`,r.style.minHeight=`${c}px`}});for(let t=0;t<Math.min(d.length,a.length);t++){const e=y.current[t]?.current,n=$.current[t]?.current;if(e&&n){const r=Math.max(e.getBoundingClientRect().height,n.getBoundingClientRect().height);u.left[t]=r,u.right[t]=r}}}if(f.forEach(({key:t})=>{const e=p.current[t]?.current,n=b.current[t]?.current;if(e&&n){const i=r[t];e.style.minHeight=`${i}px`,n.style.minHeight=`${i}px`}}),N.current||(Object.entries(u.left).forEach(([t,e])=>{const n=y.current[Number(t)]?.current;n&&(n.style.minHeight=`${e}px`)}),Object.entries(u.right).forEach(([t,e])=>{const n=$.current[Number(t)]?.current;n&&(n.style.minHeight=`${e}px`)}),T||Object.keys(s).forEach(t=>{const e=x.current[t]?.current,n=m.current[t]?.current;if(e&&n&&s[t]){const r=s[t];e.style.minHeight=`${r}px`,n.style.minHeight=`${r}px`}})),!L){const t=(t,e)=>{if(!T)return a[e]?[e]:[];const n=(t.refIndexes||[]).map(t=>a.findIndex(e=>e.selfIndex===t)).filter(t=>-1!==t);return!n.length&&a[e]?[e]:Array.from(new Set(n))};d.forEach((r,i)=>{const c=r.continuationSourceRowId?d.findIndex(t=>t.comparisonRowId===r.continuationSourceRowId):-1,u=c>=0?c:i,s=y.current[u]?.current;if(!s)return;t(r,i).forEach(t=>{const r=$.current[t]?.current;if(!r)return;const h=s.getBoundingClientRect(),g=r.getBoundingClientRect(),f=h.right-e.left,p=g.left-e.left;let b=h.top+18-e.top,y=g.top+18-e.top;if(T&&v&&I===i){const t=l.current?.getBoundingClientRect().top??0,n=o.current?.getBoundingClientRect().top??0,r=t+(l.current?.clientHeight??1/0),i=n+(o.current?.clientHeight??1/0),c=(t,e,n)=>Math.max(e,Math.min(n,t));b=c(h.top+18,t,r)-e.top,y=c(g.top+18,n,i)-e.top}const x=H(u);x&&n.push({id:`line-${u}-${t}`,x1:f,y1:b,x2:p,y2:y,style:x,sectionIdx:u,targetRightIdx:t,isSubSection:!1,isMappingContinuation:c>=0,hasCognitive:!!(d[u]?.cognitiveData||a[t]?.cognitiveData||d[u]?.nodeId&&F[d[u].nodeId])})})})}if(!L&&v&&"string"==typeof I&&I.includes(i)){const[t,r,c,u]=I.split(i),s=`${t}${i}${r}`,h=R.current[s]?.current,g=C.current[s]?.current;if(h&&g){const i=h.getBoundingClientRect(),u=g.getBoundingClientRect(),d=i.right-e.left,a=u.left-e.left;let f=i.top+i.height/2-e.top,p=u.top+u.height/2-e.top;if(T){const t=l.current?.getBoundingClientRect().top??0,n=o.current?.getBoundingClientRect().top??0,r=t+(l.current?.clientHeight??1/0),c=n+(o.current?.clientHeight??1/0),s=(t,e,n)=>Math.max(e,Math.min(n,t));f=s(i.top+i.height/2,t,r)-e.top,p=s(u.top+u.height/2,n,c)-e.top}const b=k(t,r)??w(c);b&&n.push({id:`line-subsec-${s}`,x1:d,y1:f,x2:a,y2:p,style:b,sectionIdx:Number(c.split("-")[0]),isSubSection:!0,subSectionKeyPath:I})}}if(it(n),h.current&&g.current){const t=h.current.getBoundingClientRect(),n=g.current.getBoundingClientRect(),r=(t.top+t.height/2-e.top+n.top+n.height/2-e.top)/2;lt({x1:t.right-e.left,x2:n.left-e.left,y:r})}else lt(null);if(M.size>0){const t=[],n=l.current,r=o.current;if(n&&r){const c=[],l=n.getBoundingClientRect().top,o=r.getBoundingClientRect().top,u=l+n.clientHeight,s=o+r.clientHeight,h=n.scrollTop,g=r.scrollTop,f=e.top,p=(t,e,n)=>Math.max(e,Math.min(n,t));M.forEach(n=>{if(L){let r=null,d=null,a=null;if("string"==typeof n&&n.includes(i)){const[t,e,c]=n.split(i),l=`${t}${i}${e}`;r=R.current[l]?.current,a=k(t,e)??w(c),d=Number(c?.split("-")[0]||0)}else d=Number(n),r=R.current[d]?.current,a=H(d);if(!r)return;const b=document.querySelectorAll('[id^="guideline-target-"]');b.forEach((d,y)=>{const $=r.getBoundingClientRect(),x=d.getBoundingClientRect(),m=$.right-e.left,R=x.left-e.left-0,C=m+75,A=$.top+$.height/2,B=x.top+x.height/2,S=A-l+h,M=B-o+g,v=`conn-guide-${n}-${y}`;let I="";if("string"==typeof n&&n.includes(i)){I=(n.split(i)[2]||"").split("-").map(t=>Number(t)+1).join(".")}else I=String(Number(n)+1);const T=String.fromCharCode(97+y),L=1===b.length?null:`${I}(${T})`;c.push({lhsScrollY:S,rhsScrollY:M,x1:m,x2:R,containerTop:f,leftIdx:n,rhsArrayIdx:y,styleColor:a?.badgeBorder||"#6366F1",styleBg:a?.badgeBg||"#FFFFFF",styleText:a?.badgeText||"#A16207",styleId:v,centerX:C});const F=p(A,l,u),H=p(B,o,s),w=F-f,k=H-f,E=xt(m,w,R,k,C,A>=l-4&&A<=u+4,B>=o-4&&B<=s+4);t.push({id:v,pathD:E,style:a,leftIdx:n,rhsArrayIdx:y,x1:m,x2:R,y1:w,y2:k,centerX:C,matchLabel:L,isGuideline:!0})})}else if("string"==typeof n&&n.includes(i)){const[r,d,a,b]=n.split(i),y=`${r}${i}${d}`,$=R.current[y]?.current,x=C.current[y]?.current;if(!$||!x)return;const m=$.getBoundingClientRect(),A=x.getBoundingClientRect(),B=k(r,d)??w(a),S=m.right-e.left,M=A.left-e.left-0,v=S+75,I=m.top+m.height/2,T=A.top+A.height/2,L=I-l+h,F=T-o+g,H=`conn-subsec-${y}`,E=((a||"").split("-").map(t=>Number(t)+1).join("."),null);c.push({lhsScrollY:L,rhsScrollY:F,x1:S,x2:M,containerTop:f,leftIdx:n,rhsArrayIdx:n,styleColor:B?.badgeBorder||"#6366F1",styleBg:B?.badgeBg||"#FFFFFF",styleText:B?.badgeText||"#A16207",styleId:H,centerX:v});const N=p(I,l,u),Y=p(T,o,s),D=N-f,j=Y-f,O=xt(S,D,M,j,v,I>=l-4&&I<=u+4,T>=o-4&&T<=s+4);t.push({id:H,pathD:O,style:B,leftIdx:n,rhsArrayIdx:n,x1:S,x2:M,y1:D,y2:j,matchLabel:E})}else if(T){const r=n,i=d[r];if(!i?.refIndexes?.length)return;i.refIndexes.forEach((d,b)=>{const y=a.findIndex(t=>t.selfIndex===d);if(-1===y)return;const $=R.current[r]?.current,x=C.current[y]?.current;if(!$||!x)return;const m=$.getBoundingClientRect(),A=x.getBoundingClientRect(),B=H(r),S=m.right-e.left,M=A.left-e.left-0,v=S+75,I=m.top+m.height/2,T=A.top+A.height/2,L=I-l+h,F=T-o+g,w=`conn-${r}-${y}`,k=String(Number(n)+1),E=String.fromCharCode(97+b),N=1===i.refIndexes.length?null:`${k}(${E})`;c.push({lhsScrollY:L,rhsScrollY:F,x1:S,x2:M,containerTop:f,leftIdx:r,rhsArrayIdx:y,styleColor:B?.badgeBorder||"#6366F1",styleBg:B?.badgeBg||"#FFFFFF",styleText:B?.badgeText||"#A16207",styleId:w,centerX:v});const Y=p(I,l,u),D=p(T,o,s),j=Y-f,O=D-f,z=xt(S,j,M,O,v,I>=l-4&&I<=u+4,T>=o-4&&T<=s+4);t.push({id:w,pathD:z,style:B,leftIdx:r,rhsArrayIdx:y,x1:S,x2:M,y1:j,y2:O,matchLabel:N})})}else{const r=n,i=r,d=R.current[r]?.current,a=C.current[i]?.current;if(!d||!a)return;const b=d.getBoundingClientRect(),y=a.getBoundingClientRect(),$=H(r),x=b.right-e.left,m=y.left-e.left-0,A=x+75,B=b.top+b.height/2,S=y.top+y.height/2,M=B-l+h,v=S-o+g,I=`conn-${r}-${i}`,T=(String(Number(n)+1),null);c.push({lhsScrollY:M,rhsScrollY:v,x1:x,x2:m,containerTop:f,leftIdx:r,rhsArrayIdx:i,styleColor:$?.badgeBorder||"#6366F1",styleBg:$?.badgeBg||"#FFFFFF",styleText:$?.badgeText||"#A16207",styleId:I,centerX:A});const L=p(B,l,u),F=p(S,o,s),w=L-f,k=F-f,E=xt(x,w,m,k,A,B>=l-4&&B<=u+4,S>=o-4&&S<=s+4);t.push({id:I,pathD:E,style:$,leftIdx:r,rhsArrayIdx:i,x1:x,x2:m,y1:w,y2:k,matchLabel:T})}}),$t.current=c}ht(t),setTimeout(()=>Rt(),10)}else ht([]),$t.current=[],setTimeout(()=>Rt(),10)}catch(t){console.error("Line render safe fail: ",t)}finally{at.current=!1}}},[f,d,a,F,et,nt,H,k,T,v,I,M,B,S,L]),Rt=n(()=>{const t=$t.current;if(!t.length)return s.current["guideline-up-stroke"]?.setAttribute("visibility","hidden"),s.current["guideline-up-badge"]?.setAttribute("visibility","hidden"),s.current["guideline-down-stroke"]?.setAttribute("visibility","hidden"),void s.current["guideline-down-badge"]?.setAttribute("visibility","hidden");if(N.current)return;const e=l.current?.scrollTop??0,n=o.current?.scrollTop??0,r=l.current?.clientHeight??1/0,i=o.current?.clientHeight??1/0,u=l.current?.getBoundingClientRect().top??0,h=o.current?.getBoundingClientRect().top??0,g=u+r,d=h+i,a=c.current?.getBoundingClientRect(),f=a?.top??0,p=a?.height??1/0,b=(t,e,n)=>Math.max(e,Math.min(n,t));let y=0,$=0,x=0,m=0,R="#6366F1",C="#A16207",A=!1,B=0;if(t.forEach(t=>{const r=t.lhsScrollY-e+u,i=t.rhsScrollY-n+h,c=s.current[t.styleId+"-stroke"],l=s.current[t.styleId+"-bg"],o=s.current[t.styleId+"-btn"],a=s.current[t.styleId+"-number"];if(!c&&!l)return;const p=b(r,u,g),S=b(i,h,d),M=p-f,v=S-f,I=r>=u-4&&r<=g+4,T=i>=h-4&&i<=d+4;let L=!0;A=!0;const F=t.centerX||t.x1+75;0===x&&(x=t.x1,m=M,B=F,R=t.styleColor,t.styleBg,C=t.styleText||"#A16207"),i<h-4?(y++,L=!1):i>d+4&&($++,L=!1);const H=xt(t.x1,M,t.x2,v,B,I,T);c&&(L&&H?(c.setAttribute("visibility","visible"),c.setAttribute("d",H)):c.setAttribute("visibility","hidden")),l&&(L&&H?(l.setAttribute("visibility","visible"),l.setAttribute("d",H)):l.setAttribute("visibility","hidden")),o&&(I&&L?(o.setAttribute("visibility","visible"),o.setAttribute("y",String(M-12))):o.setAttribute("visibility","hidden")),a&&(I&&L?(a.setAttribute("visibility","visible"),a.setAttribute("transform",`translate(${t.x2-42}, ${v})`)):a.setAttribute("visibility","hidden"))}),A&&B>0){const t=s.current["guideline-up-stroke"],e=s.current["guideline-up-badge"],n=s.current["guideline-up-arrow"],r=s.current["guideline-up-text"],i=s.current["guideline-up-badge-rect"];if(y>0){const c=Math.max(15,h-f+15),l=Math.min(15,Math.abs(B-x),Math.max(0,m-c)),o=`M ${x},${m} L ${B-l},${m} Q ${B},${m} ${B},${m-l} L ${B},${c}`;t?.setAttribute("visibility","visible"),t?.setAttribute("d",o),t?.setAttribute("stroke",R),e?.setAttribute("visibility","visible"),e?.setAttribute("transform",`translate(${B}, ${c})`),n&&n.setAttribute("fill",R),r&&(r.textContent=`+${y}`,r.setAttribute("fill",C)),i&&i.setAttribute("stroke",R)}else t?.setAttribute("visibility","hidden"),e?.setAttribute("visibility","hidden");const c=s.current["guideline-down-stroke"],l=s.current["guideline-down-badge"],o=s.current["guideline-down-arrow"],u=s.current["guideline-down-text"],g=s.current["guideline-down-badge-rect"];if($>0){const t=Math.min(p-15,d-f-15),e=Math.min(15,Math.abs(B-x),Math.max(0,t-m)),n=`M ${x},${m} L ${B-e},${m} Q ${B},${m} ${B},${m+e} L ${B},${t}`;c?.setAttribute("visibility","visible"),c?.setAttribute("d",n),c?.setAttribute("stroke",R),l?.setAttribute("visibility","visible"),l?.setAttribute("transform",`translate(${B}, ${t})`),o&&o.setAttribute("fill",R),u&&(u.textContent=`+${$}`,u.setAttribute("fill",C)),g&&g.setAttribute("stroke",R)}else c?.setAttribute("visibility","hidden"),l?.setAttribute("visibility","hidden")}},[]),Ct=n(()=>{$t.current.length>0&&!N.current||(null!==bt.current&&clearTimeout(bt.current),bt.current=setTimeout(()=>{q.current(),bt.current=null},50))},[]),At=n(t=>{if(null!==_.current&&tt.current&&Math.abs(t.currentTarget.scrollTop-_.current)<=2){const t=tt.current;_.current=null,tt.current=null,t()}if(!pt.current&&!K.current){if(T&&V&&(Y.current||M.size>0)){const e=t.currentTarget,n=l.current,r=o.current,c=e===n?r:e===r?n:null;if(e&&c){const t=()=>{const t=O.current,e=z.current;if(null===t)return{leftAnchor:null,rightAnchor:null};if("string"==typeof t&&t.includes(i)){const e=t.split(i),n=`${e[0]}${i}${e[1]}`;return{leftAnchor:R.current[n]?.current||x.current[e[2]]?.current||y.current[Number(e[2])]?.current||null,rightAnchor:C.current[n]?.current||m.current[e[3]]?.current||$.current[Number(e[3])]?.current||null}}const n=Number(t),r=null!==e?Number(e):n;return{leftAnchor:R.current[n]?.current||A.current[n]?.current||y.current[n]?.current||null,rightAnchor:C.current[r]?.current||$.current[r]?.current||null}},{leftAnchor:r,rightAnchor:l}=t(),o=e===n?r:l,u=e===n?l:r;let s=null;if(o&&u){const t=o.getBoundingClientRect(),e=u.getBoundingClientRect(),n=c.getBoundingClientRect(),r=t.top+t.height/2;s=e.top-n.top+c.scrollTop+e.height/2-(r-n.top)}else{const t=Math.max(0,e.scrollHeight-e.clientHeight),n=Math.max(0,c.scrollHeight-c.clientHeight);s=t>0?e.scrollTop/t*n:e.scrollTop}const h=Math.max(0,c.scrollHeight-c.clientHeight);s=Math.max(0,Math.min(s,h)),Math.abs(c.scrollTop-s)>1&&(pt.current=!0,c.scrollTop=s,requestAnimationFrame(()=>{pt.current=!1}))}}T||Ct(),ft.current||(ft.current=!0,requestAnimationFrame(()=>{if(Y.current){const t=l.current,e=o.current;if(t&&e&&j.current){if(!D.current){const e=O.current;let n;if("string"==typeof e&&e.includes(i)){const t=e.split(i),r=`${t[0]}${i}${t[1]}`;n=R.current[r]?.current}else n=R.current[e]?.current;if(n){const e=n.getBoundingClientRect();D.current={badgeScreenY:e.top+e.height/2,initialScrollTop:t.scrollTop,leftTop:t.getBoundingClientRect().top,leftBottom:t.getBoundingClientRect().top+t.clientHeight,cTop:c.current?.getBoundingClientRect().top??0}}}if(D.current){const e=D.current,n=t.scrollTop-e.initialScrollTop,r=e.badgeScreenY-n,i=(((t,e,n)=>Math.max(e,Math.min(n,t)))(r,e.leftTop,e.leftBottom)-e.cTop).toString(),c=r>=e.leftTop-4&&r<=e.leftBottom+4;j.current.setAttribute("y1",i),j.current.setAttribute("y2",i),j.current.setAttribute("visibility",c?"visible":"hidden")}}}Rt(),ft.current=!1}))}},[Rt,T,V,M,Ct]);return r(()=>{q.current=mt},[mt]),r(()=>{const t=setTimeout(Ct,250),e=()=>J.current();return window.addEventListener("resize",e),()=>{clearTimeout(t),null!==bt.current&&clearTimeout(bt.current),null!==G.current&&clearTimeout(G.current),window.removeEventListener("resize",e)}},[U,W,Z,f,B,S,d,a,et,Ct,v,I,E,M]),{lines:rt,setLines:it,overallConnector:ct,setOverallConnector:lt,connectedLines:st,setConnectedLines:ht,svgDimensions:gt,cachedConnectedPositions:$t,calculateLines:mt,calculateLinesRef:q,calculateLinesDebounced:Ct,handleColumnScroll:At}};export{c as useLinesCalculator};
1
+ import{useState as t,useRef as e,useCallback as n,useEffect as r}from"react";import{DEVIATION_BADGE_SEPARATOR as i}from"../CognitiveComparehelpers.js";import{getVisibleGuidelineTargets as c}from"../Guidelines/utils/guidelineTargets.js";const l=({containerRef:l,leftContainerRef:o,rightContainerRef:u,svgContainerRef:s,pathRefs:h,leftHeaderRef:g,rightHeaderRef:d,proposedSections:a,existingSections:f,visibleFields:p,leftRefs:b,rightRefs:$,sectionLeftRefs:y,sectionRightRefs:x,subSectionLeftRefs:m,subSectionRightRefs:R,lhsBadgeRefs:C,rhsBadgeRefs:B,sectionRowRefs:A,expandedSections:S,expandedSubSections:M,connectedSections:v,isSideBySide:T,activeSideBySideSection:I,maintainRelativeOrder:L,isGuidelineMode:F,cognitiveMap:H,getSectionCompareStyle:w,getSubSectionCompareStyle:k,getDeviationStyleByKey:E,isArrowVisible:N,isAnimatingRef:Y,isSideBySideRef:D,sideBySideCacheRef:j,sideBySideLineRef:O,activeSideBySideSectionRef:z,activeSideBySideRightSectionRef:P,connectedLines:Q,setConnectedLines:X,cachedConnectedPositions:G,calculateLinesRef:q,resizeTimerRef:K,scrollLock:V,scrollSyncLocked:J,handleResizeRef:U,activeProposed:W,existingRule:Z,analysisData:_,pendingScrollTargetRef:tt,pendingScrollCallbackRef:et,resolvedComparisonConfig:nt,getFieldData:rt})=>{const[it,ct]=t([]),[lt,ot]=t(null),[ut,st]=t([]),ht=Q??ut,gt=X??st,[dt,at]=t({width:0,height:0}),ft=e(!1),pt=e(!1),bt=e(!1),$t=e(null),yt=e([]),xt=G??yt,mt=(t,e,n,r,i,c,l)=>{if(Math.abs(r-e)<=1)return c&&l?`M ${t},${e} L ${n},${r}`:c&&!l?`M ${t},${e} L ${i},${e}`:!c&&l?`M ${i},${e} L ${n},${r}`:`M ${i},${e} L ${i},${r}`;const o=Math.min(15,Math.abs(i-t),Math.abs(r-e)/2),u=Math.min(15,Math.abs(n-i),Math.abs(r-e)/2),s=r>e?o:-o,h=r>e?u:-u,g=n>i?u:-u;return c&&l?`M ${t},${e} L ${i-o},${e} Q ${i},${e} ${i},${e+s} L ${i},${r-h} Q ${i},${r} ${i+g},${r} L ${n},${r}`:c&&!l?`M ${t},${e} L ${i-o},${e} Q ${i},${e} ${i},${e+s} L ${i},${r}`:!c&&l?`M ${i},${e} L ${i},${r-h} Q ${i},${r} ${i+g},${r} L ${n},${r}`:`M ${i},${e} L ${i},${r}`},Rt=n(()=>{if(!ft.current&&!Y.current){ft.current=!0;try{if(!l.current)return;const t=t=>{const e=t.split("-"),n=e[0];if(!S[n]&&!1===L)return!1;if(L&&!S[`left-${n}`]&&!S[`right-${n}`]&&!S[n])return!1;let r=n;for(let t=1;t<e.length-1;t++)if(r+=`-${e[t]}`,!M[r])return!1;return!0},e=l.current.getBoundingClientRect();at({width:e.width,height:e.height});const n=[];if(p.forEach(({key:t})=>{const e=b.current[t]?.current,n=$.current[t]?.current;e&&n&&(e.style.height="auto",n.style.height="auto",e.style.minHeight="0px",n.style.minHeight="0px")}),!Y.current){for(let t=0;t<Math.max(a.length,f.length);t++){const e=y.current[t]?.current,n=x.current[t]?.current;e&&(e.style.height="auto",e.style.minHeight="0px"),n&&(n.style.height="auto",n.style.minHeight="0px")}L||Object.keys(m.current).forEach(e=>{if(!t(e))return;const n=m.current[e]?.current,r=R.current[e]?.current;n&&r&&(n.style.height="auto",r.style.height="auto",n.style.minHeight="0px",r.style.minHeight="0px")})}const r={};p.forEach(({key:t})=>{const e=b.current[t]?.current,n=$.current[t]?.current;if(e&&n){const i=e.getBoundingClientRect(),c=n.getBoundingClientRect();r[t]=Math.max(i.height,c.height)}});const s={left:{},right:{}},h={};if(!Y.current)if(L){if(T&&null!==I)if("number"==typeof I){const t=I,e=a[t],n=y.current[t]?.current;n&&e&&(e.refIndexes||[]).forEach(e=>{const r=f.findIndex(t=>t.selfIndex===e),i=x.current[r]?.current;if(i&&(S[`left-${t}`]||S[`right-${r}`])){const e=Math.max(n.getBoundingClientRect().height,i.getBoundingClientRect().height);s.left[t]=Math.max(s.left[t]||0,e),s.right[r]=Math.max(s.right[r]||0,e)}})}else{const t=I.split(i)[2];if(t){const e=m.current[t]?.current,n=R.current[t]?.current;if(e&&n){const r=Math.max(e.getBoundingClientRect().height,n.getBoundingClientRect().height);h[t]=Math.max(h[t]||0,r)}}}}else{Object.keys(m.current).forEach(e=>{if(!t(e))return;const n=m.current[e]?.current,r=R.current[e]?.current;if(n&&r&&null!==n.offsetParent&&null!==r.offsetParent){const t=n.getBoundingClientRect(),i=r.getBoundingClientRect(),c=Math.max(t.height,i.height);h[e]=c,n.style.minHeight=`${c}px`,r.style.minHeight=`${c}px`}});for(let t=0;t<Math.min(a.length,f.length);t++){const e=y.current[t]?.current,n=x.current[t]?.current;if(e&&n){const r=Math.max(e.getBoundingClientRect().height,n.getBoundingClientRect().height);s.left[t]=r,s.right[t]=r}}}if(p.forEach(({key:t})=>{const e=b.current[t]?.current,n=$.current[t]?.current;if(e&&n){const i=r[t];e.style.minHeight=`${i}px`,n.style.minHeight=`${i}px`}}),Y.current||(Object.entries(s.left).forEach(([t,e])=>{const n=y.current[Number(t)]?.current;n&&(n.style.minHeight=`${e}px`)}),Object.entries(s.right).forEach(([t,e])=>{const n=x.current[Number(t)]?.current;n&&(n.style.minHeight=`${e}px`)}),L||Object.keys(h).forEach(t=>{const e=m.current[t]?.current,n=R.current[t]?.current;if(e&&n&&h[t]){const r=h[t];e.style.minHeight=`${r}px`,n.style.minHeight=`${r}px`}})),!F){const t=(t,e)=>{if(!L)return f[e]?[e]:[];const n=(t.refIndexes||[]).map(t=>f.findIndex(e=>e.selfIndex===t)).filter(t=>-1!==t);return!n.length&&f[e]?[e]:Array.from(new Set(n))};a.forEach((r,i)=>{const c=r.continuationSourceRowId?a.findIndex(t=>t.comparisonRowId===r.continuationSourceRowId):-1,l=c>=0?c:i,s=y.current[l]?.current;if(!s)return;t(r,i).forEach(t=>{const r=x.current[t]?.current;if(!r)return;const h=s.getBoundingClientRect(),g=r.getBoundingClientRect(),d=h.right-e.left,p=g.left-e.left;let b=h.top+18-e.top,$=g.top+18-e.top;if(L&&T&&I===i){const t=o.current?.getBoundingClientRect().top??0,n=u.current?.getBoundingClientRect().top??0,r=t+(o.current?.clientHeight??1/0),i=n+(u.current?.clientHeight??1/0),c=(t,e,n)=>Math.max(e,Math.min(n,t));b=c(h.top+18,t,r)-e.top,$=c(g.top+18,n,i)-e.top}const y=w(l);y&&n.push({id:`line-${l}-${t}`,x1:d,y1:b,x2:p,y2:$,style:y,sectionIdx:l,targetRightIdx:t,isSubSection:!1,isMappingContinuation:c>=0,hasCognitive:!!(a[l]?.cognitiveData||f[t]?.cognitiveData||a[l]?.nodeId&&H[a[l].nodeId])})})})}if(!F&&T&&"string"==typeof I&&I.includes(i)){const[t,r,c,l]=I.split(i),s=`${t}${i}${r}`,h=C.current[s]?.current,g=B.current[s]?.current;if(h&&g){const i=h.getBoundingClientRect(),l=g.getBoundingClientRect(),d=i.right-e.left,a=l.left-e.left;let f=i.top+i.height/2-e.top,p=l.top+l.height/2-e.top;if(L){const t=o.current?.getBoundingClientRect().top??0,n=u.current?.getBoundingClientRect().top??0,r=t+(o.current?.clientHeight??1/0),c=n+(u.current?.clientHeight??1/0),s=(t,e,n)=>Math.max(e,Math.min(n,t));f=s(i.top+i.height/2,t,r)-e.top,p=s(l.top+l.height/2,n,c)-e.top}const b=E(t,r)??k(c);b&&n.push({id:`line-subsec-${s}`,x1:d,y1:f,x2:a,y2:p,style:b,sectionIdx:Number(c.split("-")[0]),isSubSection:!0,subSectionKeyPath:I})}}if(ct(n),g.current&&d.current){const t=g.current.getBoundingClientRect(),n=d.current.getBoundingClientRect(),r=(t.top+t.height/2-e.top+n.top+n.height/2-e.top)/2;ot({x1:t.right-e.left,x2:n.left-e.left,y:r})}else ot(null);if(v.size>0){const t=[],n=o.current,r=u.current;if(n&&r){const l=[],o=n.getBoundingClientRect().top,u=r.getBoundingClientRect().top,s=o+n.clientHeight,h=u+r.clientHeight,g=n.scrollTop,d=r.scrollTop,p=e.top,b=(t,e,n)=>Math.max(e,Math.min(n,t));v.forEach(n=>{if(F){let a=null,f=null,$=null;if("string"==typeof n&&n.includes(i)){const[t,e,r]=n.split(i),c=`${t}${i}${e}`;a=C.current[c]?.current,$=E(t,e)??k(r),f=Number(r?.split("-")[0]||0)}else f=Number(n),a=C.current[f]?.current,$=w(f);if(!a)return;const y=c(r);y.forEach((r,c)=>{const f=a.getBoundingClientRect(),x=r.getBoundingClientRect(),m=f.right-e.left,R=x.left-e.left-0,C=m+75,B=f.top+f.height/2,A=x.top+x.height/2,S=B-o+g,M=A-u+d,v=`conn-guide-${n}-${c}`;let T="";if("string"==typeof n&&n.includes(i)){T=(n.split(i)[2]||"").split("-").map(t=>Number(t)+1).join(".")}else T=String(Number(n)+1);const I=String.fromCharCode(97+c),L=1===y.length?null:`${T}(${I})`;l.push({lhsScrollY:S,rhsScrollY:M,x1:m,x2:R,containerTop:p,leftIdx:n,rhsArrayIdx:c,styleColor:$?.badgeBorder||"#6366F1",styleBg:$?.badgeBg||"#FFFFFF",styleText:$?.badgeText||"#A16207",styleId:v,centerX:C});const F=b(B,o,s),H=b(A,u,h),w=F-p,k=H-p,E=mt(m,w,R,k,C,B>=o-4&&B<=s+4,A>=u-4&&A<=h+4);t.push({id:v,pathD:E,style:$,leftIdx:n,rhsArrayIdx:c,x1:m,x2:R,y1:w,y2:k,centerX:C,matchLabel:L,isGuideline:!0})})}else if("string"==typeof n&&n.includes(i)){const[r,c,a,f]=n.split(i),$=`${r}${i}${c}`,y=C.current[$]?.current,x=B.current[$]?.current;if(!y||!x)return;const m=y.getBoundingClientRect(),R=x.getBoundingClientRect(),A=E(r,c)??k(a),S=m.right-e.left,M=R.left-e.left-0,v=S+75,T=m.top+m.height/2,I=R.top+R.height/2,L=T-o+g,F=I-u+d,H=`conn-subsec-${$}`,w=((a||"").split("-").map(t=>Number(t)+1).join("."),null);l.push({lhsScrollY:L,rhsScrollY:F,x1:S,x2:M,containerTop:p,leftIdx:n,rhsArrayIdx:n,styleColor:A?.badgeBorder||"#6366F1",styleBg:A?.badgeBg||"#FFFFFF",styleText:A?.badgeText||"#A16207",styleId:H,centerX:v});const N=b(T,o,s),Y=b(I,u,h),D=N-p,j=Y-p,O=mt(S,D,M,j,v,T>=o-4&&T<=s+4,I>=u-4&&I<=h+4);t.push({id:H,pathD:O,style:A,leftIdx:n,rhsArrayIdx:n,x1:S,x2:M,y1:D,y2:j,matchLabel:w})}else if(L){const r=n,i=a[r];if(!i?.refIndexes?.length)return;i.refIndexes.forEach((c,a)=>{const $=f.findIndex(t=>t.selfIndex===c);if(-1===$)return;const y=C.current[r]?.current,x=B.current[$]?.current;if(!y||!x)return;const m=y.getBoundingClientRect(),R=x.getBoundingClientRect(),A=w(r),S=m.right-e.left,M=R.left-e.left-0,v=S+75,T=m.top+m.height/2,I=R.top+R.height/2,L=T-o+g,F=I-u+d,H=`conn-${r}-${$}`,k=String(Number(n)+1),E=String.fromCharCode(97+a),N=1===i.refIndexes.length?null:`${k}(${E})`;l.push({lhsScrollY:L,rhsScrollY:F,x1:S,x2:M,containerTop:p,leftIdx:r,rhsArrayIdx:$,styleColor:A?.badgeBorder||"#6366F1",styleBg:A?.badgeBg||"#FFFFFF",styleText:A?.badgeText||"#A16207",styleId:H,centerX:v});const Y=b(T,o,s),D=b(I,u,h),j=Y-p,O=D-p,z=mt(S,j,M,O,v,T>=o-4&&T<=s+4,I>=u-4&&I<=h+4);t.push({id:H,pathD:z,style:A,leftIdx:r,rhsArrayIdx:$,x1:S,x2:M,y1:j,y2:O,matchLabel:N})})}else{const r=n,i=r,c=C.current[r]?.current,a=B.current[i]?.current;if(!c||!a)return;const f=c.getBoundingClientRect(),$=a.getBoundingClientRect(),y=w(r),x=f.right-e.left,m=$.left-e.left-0,R=x+75,A=f.top+f.height/2,S=$.top+$.height/2,M=A-o+g,v=S-u+d,T=`conn-${r}-${i}`,I=(String(Number(n)+1),null);l.push({lhsScrollY:M,rhsScrollY:v,x1:x,x2:m,containerTop:p,leftIdx:r,rhsArrayIdx:i,styleColor:y?.badgeBorder||"#6366F1",styleBg:y?.badgeBg||"#FFFFFF",styleText:y?.badgeText||"#A16207",styleId:T,centerX:R});const L=b(A,o,s),F=b(S,u,h),H=L-p,k=F-p,E=mt(x,H,m,k,R,A>=o-4&&A<=s+4,S>=u-4&&S<=h+4);t.push({id:T,pathD:E,style:y,leftIdx:r,rhsArrayIdx:i,x1:x,x2:m,y1:H,y2:k,matchLabel:I})}}),xt.current=l}gt(t),setTimeout(()=>Ct(),10)}else gt([]),xt.current=[],setTimeout(()=>Ct(),10)}catch(t){console.error("Line render safe fail: ",t)}finally{ft.current=!1}}},[p,a,f,H,nt,rt,w,E,L,T,I,v,S,M,F]),Ct=n(()=>{const t=xt.current;if(!t.length)return h.current["guideline-up-stroke"]?.setAttribute("visibility","hidden"),h.current["guideline-up-badge"]?.setAttribute("visibility","hidden"),h.current["guideline-down-stroke"]?.setAttribute("visibility","hidden"),void h.current["guideline-down-badge"]?.setAttribute("visibility","hidden");if(Y.current)return;const e=o.current?.scrollTop??0,n=u.current?.scrollTop??0,r=o.current?.clientHeight??1/0,i=u.current?.clientHeight??1/0,c=o.current?.getBoundingClientRect().top??0,s=u.current?.getBoundingClientRect().top??0,g=c+r,d=s+i,a=l.current?.getBoundingClientRect(),f=a?.top??0,p=a?.height??1/0,b=(t,e,n)=>Math.max(e,Math.min(n,t));let $=0,y=0,x=0,m=0,R="#6366F1",C="#A16207",B=!1,A=0;if(t.forEach(t=>{const r=t.lhsScrollY-e+c,i=t.rhsScrollY-n+s,l=h.current[t.styleId+"-stroke"],o=h.current[t.styleId+"-bg"],u=h.current[t.styleId+"-btn"],a=h.current[t.styleId+"-number"];if(!l&&!o)return;const p=b(r,c,g),S=b(i,s,d),M=p-f,v=S-f,T=r>=c-4&&r<=g+4,I=i>=s-4&&i<=d+4;let L=!0;B=!0;const F=t.centerX||t.x1+75;0===x&&(x=t.x1,m=M,A=F,R=t.styleColor,t.styleBg,C=t.styleText||"#A16207"),i<s-4?($++,L=!1):i>d+4&&(y++,L=!1);const H=mt(t.x1,M,t.x2,v,A,T,I);l&&(L&&H?(l.setAttribute("visibility","visible"),l.setAttribute("d",H)):l.setAttribute("visibility","hidden")),o&&(L&&H?(o.setAttribute("visibility","visible"),o.setAttribute("d",H)):o.setAttribute("visibility","hidden")),u&&(T&&L?(u.setAttribute("visibility","visible"),u.setAttribute("y",String(M-12))):u.setAttribute("visibility","hidden")),a&&(T&&L?(a.setAttribute("visibility","visible"),a.setAttribute("transform",`translate(${t.x2-42}, ${v})`)):a.setAttribute("visibility","hidden"))}),B&&A>0){const t=h.current["guideline-up-stroke"],e=h.current["guideline-up-badge"],n=h.current["guideline-up-arrow"],r=h.current["guideline-up-text"],i=h.current["guideline-up-badge-rect"];if($>0){const c=Math.max(15,s-f+15),l=Math.min(15,Math.abs(A-x),Math.max(0,m-c)),o=`M ${x},${m} L ${A-l},${m} Q ${A},${m} ${A},${m-l} L ${A},${c}`;t?.setAttribute("visibility","visible"),t?.setAttribute("d",o),t?.setAttribute("stroke",R),e?.setAttribute("visibility","visible"),e?.setAttribute("transform",`translate(${A}, ${c})`),n&&n.setAttribute("fill",R),r&&(r.textContent=`+${$}`,r.setAttribute("fill",C)),i&&i.setAttribute("stroke",R)}else t?.setAttribute("visibility","hidden"),e?.setAttribute("visibility","hidden");const c=h.current["guideline-down-stroke"],l=h.current["guideline-down-badge"],o=h.current["guideline-down-arrow"],u=h.current["guideline-down-text"],g=h.current["guideline-down-badge-rect"];if(y>0){const t=Math.min(p-15,d-f-15),e=Math.min(15,Math.abs(A-x),Math.max(0,t-m)),n=`M ${x},${m} L ${A-e},${m} Q ${A},${m} ${A},${m+e} L ${A},${t}`;c?.setAttribute("visibility","visible"),c?.setAttribute("d",n),c?.setAttribute("stroke",R),l?.setAttribute("visibility","visible"),l?.setAttribute("transform",`translate(${A}, ${t})`),o&&o.setAttribute("fill",R),u&&(u.textContent=`+${y}`,u.setAttribute("fill",C)),g&&g.setAttribute("stroke",R)}else c?.setAttribute("visibility","hidden"),l?.setAttribute("visibility","hidden")}},[]),Bt=n(()=>{xt.current.length>0&&!Y.current||(null!==$t.current&&clearTimeout($t.current),$t.current=setTimeout(()=>{q.current(),$t.current=null},50))},[]),At=n(t=>{if(null!==tt.current&&et.current&&Math.abs(t.currentTarget.scrollTop-tt.current)<=2){const t=et.current;tt.current=null,et.current=null,t()}if(!bt.current&&!V.current){if(L&&J&&(D.current||v.size>0)){const e=t.currentTarget,n=o.current,r=u.current,c=e===n?r:e===r?n:null;if(e&&c){const t=()=>{const t=z.current,e=P.current;if(null===t)return{leftAnchor:null,rightAnchor:null};if("string"==typeof t&&t.includes(i)){const e=t.split(i),n=`${e[0]}${i}${e[1]}`;return{leftAnchor:C.current[n]?.current||m.current[e[2]]?.current||y.current[Number(e[2])]?.current||null,rightAnchor:B.current[n]?.current||R.current[e[3]]?.current||x.current[Number(e[3])]?.current||null}}const n=Number(t),r=null!==e?Number(e):n;return{leftAnchor:C.current[n]?.current||A.current[n]?.current||y.current[n]?.current||null,rightAnchor:B.current[r]?.current||x.current[r]?.current||null}},{leftAnchor:r,rightAnchor:l}=t(),o=e===n?r:l,u=e===n?l:r;let s=null;if(o&&u){const t=o.getBoundingClientRect(),e=u.getBoundingClientRect(),n=c.getBoundingClientRect(),r=t.top+t.height/2;s=e.top-n.top+c.scrollTop+e.height/2-(r-n.top)}else{const t=Math.max(0,e.scrollHeight-e.clientHeight),n=Math.max(0,c.scrollHeight-c.clientHeight);s=t>0?e.scrollTop/t*n:e.scrollTop}const h=Math.max(0,c.scrollHeight-c.clientHeight);s=Math.max(0,Math.min(s,h)),Math.abs(c.scrollTop-s)>1&&(bt.current=!0,c.scrollTop=s,requestAnimationFrame(()=>{bt.current=!1}))}}L||Bt(),pt.current||(pt.current=!0,requestAnimationFrame(()=>{if(D.current){const t=o.current,e=u.current;if(t&&e&&O.current){if(!j.current){const e=z.current;let n;if("string"==typeof e&&e.includes(i)){const t=e.split(i),r=`${t[0]}${i}${t[1]}`;n=C.current[r]?.current}else n=C.current[e]?.current;if(n){const e=n.getBoundingClientRect();j.current={badgeScreenY:e.top+e.height/2,initialScrollTop:t.scrollTop,leftTop:t.getBoundingClientRect().top,leftBottom:t.getBoundingClientRect().top+t.clientHeight,cTop:l.current?.getBoundingClientRect().top??0}}}if(j.current){const e=j.current,n=t.scrollTop-e.initialScrollTop,r=e.badgeScreenY-n,i=(((t,e,n)=>Math.max(e,Math.min(n,t)))(r,e.leftTop,e.leftBottom)-e.cTop).toString(),c=r>=e.leftTop-4&&r<=e.leftBottom+4;O.current.setAttribute("y1",i),O.current.setAttribute("y2",i),O.current.setAttribute("visibility",c?"visible":"hidden")}}}Ct(),pt.current=!1}))}},[Ct,L,J,v,Bt]);return r(()=>{q.current=Rt},[Rt]),r(()=>{const t=setTimeout(Bt,250),e=()=>U.current();return window.addEventListener("resize",e),()=>{clearTimeout(t),null!==$t.current&&clearTimeout($t.current),null!==K.current&&clearTimeout(K.current),window.removeEventListener("resize",e)}},[W,Z,_,p,S,M,a,f,nt,Bt,T,I,N,v]),{lines:it,setLines:ct,overallConnector:lt,setOverallConnector:ot,connectedLines:ht,setConnectedLines:gt,svgDimensions:dt,cachedConnectedPositions:xt,calculateLines:Rt,calculateLinesRef:q,calculateLinesDebounced:Bt,handleColumnScroll:At}};export{l as useLinesCalculator};
2
2
  //# sourceMappingURL=useLinesCalculator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLinesCalculator.js","sources":["../../../../src/features/CognitiveCompare/hooks/useLinesCalculator.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { CachedBadgePosition, SectionBlock } from \"../CognitiveCompareTypes\";\nimport { DEVIATION_BADGE_SEPARATOR, getBentArrowPath, hasValue } from \"../CognitiveComparehelpers\";\nimport { maxHeight } from \"@mui/system\";\n\nexport const useLinesCalculator = ({\n containerRef,\n leftContainerRef,\n rightContainerRef,\n svgContainerRef,\n pathRefs,\n leftHeaderRef, rightHeaderRef,\n proposedSections, existingSections,\n visibleFields,\n leftRefs, rightRefs,\n sectionLeftRefs, sectionRightRefs,\n subSectionLeftRefs, subSectionRightRefs,\n lhsBadgeRefs, rhsBadgeRefs,\n sectionRowRefs,\n expandedSections, expandedSubSections,\n connectedSections,\n isSideBySide, activeSideBySideSection,\n maintainRelativeOrder,\n isGuidelineMode, // ── NEW PROP ──\n cognitiveMap,\n getSectionCompareStyle, getSubSectionCompareStyle, getDeviationStyleByKey,\n isArrowVisible,\n\n isAnimatingRef,\n isSideBySideRef,\n sideBySideCacheRef,\n sideBySideLineRef,\n activeSideBySideSectionRef,\n activeSideBySideRightSectionRef,\n connectedLines: providedConnectedLines,\n setConnectedLines: providedSetConnectedLines,\n cachedConnectedPositions: providedCachedConnectedPositions,\n calculateLinesRef,\n resizeTimerRef,\n scrollLock,\n scrollSyncLocked,\n\n handleResizeRef,\n activeProposed, existingRule, analysisData,\n pendingScrollTargetRef, pendingScrollCallbackRef,\n\n resolvedComparisonConfig,\n getFieldData\n}: any) => {\n // States and Refs\n const [lines, setLines] = useState<Record<string, any>[]>([]);\n const [overallConnector, setOverallConnector] = useState<{ x1: number; x2: number; y: number; } | null>(null);\n const [internalConnectedLines, internalSetConnectedLines] = useState<Record<string, any>[]>([]);\n const connectedLines = providedConnectedLines ?? internalConnectedLines;\n const setConnectedLines = providedSetConnectedLines ?? internalSetConnectedLines;\n const [svgDimensions, setSvgDimensions] = useState<{ width: number; height: number }>({ width: 0, height: 0 });\n\n const isCalculatingLines = useRef(false);\n const scrollTicking = useRef(false);\n const scrollSyncing = useRef(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const internalCachedConnectedPositions = useRef<CachedBadgePosition[]>([]);\n const cachedConnectedPositions =\n providedCachedConnectedPositions ?? internalCachedConnectedPositions;\n\n\n \n // Helpers\n // ── UNIFIED ROUNDED PATH GENERATOR (Guarantees shared trunk for ALL modes) ──\n const getRoundedStaggeredPath = (x1: number, y1: number, x2: number, y2: number, cX: number, visL: boolean, visR: boolean) => {\n if (Math.abs(y2 - y1) <= 1) {\n if (visL && visR) return `M ${x1},${y1} L ${x2},${y2}`;\n if (visL && !visR) return `M ${x1},${y1} L ${cX},${y1}`;\n if (!visL && visR) return `M ${cX},${y1} L ${x2},${y2}`;\n return `M ${cX},${y1} L ${cX},${y2}`;\n }\n const r1 = Math.min(15, Math.abs(cX - x1), Math.abs(y2 - y1) / 2);\n const r2 = Math.min(15, Math.abs(x2 - cX), Math.abs(y2 - y1) / 2);\n const dy1 = y2 > y1 ? r1 : -r1;\n const dy2 = y2 > y1 ? r2 : -r2;\n const dx2 = x2 > cX ? r2 : -r2; // Safe horizontal direction\n \n if (visL && visR) {\n return `M ${x1},${y1} L ${cX - r1},${y1} Q ${cX},${y1} ${cX},${y1 + dy1} L ${cX},${y2 - dy2} Q ${cX},${y2} ${cX + dx2},${y2} L ${x2},${y2}`;\n } else if (visL && !visR) {\n return `M ${x1},${y1} L ${cX - r1},${y1} Q ${cX},${y1} ${cX},${y1 + dy1} L ${cX},${y2}`;\n } else if (!visL && visR) {\n return `M ${cX},${y1} L ${cX},${y2 - dy2} Q ${cX},${y2} ${cX + dx2},${y2} L ${x2},${y2}`;\n } else {\n return `M ${cX},${y1} L ${cX},${y2}`;\n }\n };\n\n // Helper to check if a subsection is actually visible in the expanded section\n const isSubSectionVisible = (keyPath: string) => {\n const pathParts = keyPath.split('-');\n const rootIdx = pathParts[0];\n\n // Edge case\n // Early return if root parent is not expanded\n // Only happens in side by side view for deeply nested children\n if (!expandedSections[rootIdx] && maintainRelativeOrder === false) return;\n\n if (maintainRelativeOrder) {\n if (!expandedSections[`left-${rootIdx}`] && !expandedSections[`right-${rootIdx}`] && !expandedSections[rootIdx]) return false;\n }\n\n // Check to confirm if all the ancestors of the node are expanded otherwise early return\n let ancestorPath = rootIdx;\n for (let i = 1; i < pathParts.length - 1; i++) {\n ancestorPath += `-${pathParts[i]}`;\n if (!expandedSections[ancestorPath]) return false;\n }\n\n return true;\n };\n\n // Callbacks\n const calculateLines = useCallback(() => {\n if (isCalculatingLines.current) return;\n if (isAnimatingRef.current) return;\n isCalculatingLines.current = true;\n try {\n if (!containerRef.current) return;\n\n // Helper to check if a subsection is actually visible in the expanded accordion tree\n const isSubSectionVisible = (keyPath: string) => {\n const pathParts = keyPath.split('-');\n const rootIdx = pathParts[0];\n\n // 1. Root Parent must be expanded\n if (!expandedSections[rootIdx] && maintainRelativeOrder === false) return false;\n if (maintainRelativeOrder) {\n if (!expandedSections[`left-${rootIdx}`] && !expandedSections[`right-${rootIdx}`] && !expandedSections[rootIdx]) return false;\n }\n\n // 2. All intermediate ancestor subsections must be expanded\n let ancestorPath = rootIdx;\n for (let i = 1; i < pathParts.length - 1; i++) {\n ancestorPath += `-${pathParts[i]}`;\n if (!expandedSubSections[ancestorPath]) {\n return false;\n }\n }\n return true;\n };\n\n // 3. Keep the SVG setup and field heights logic intact\n const containerRect = containerRef.current.getBoundingClientRect();\n setSvgDimensions({\n width: containerRect.width,\n height: containerRect.height,\n });\n\n const newLines: Record<string, any>[] = [];\n\n // RESET STYLES (WRITE ONLY)\n visibleFields.forEach(({ key }: {key: any}) => {\n const l = leftRefs.current[key]?.current;\n const r = rightRefs.current[key]?.current;\n\n if (l && r) {\n l.style.height = \"auto\";\n r.style.height = \"auto\";\n l.style.minHeight = \"0px\";\n r.style.minHeight = \"0px\";\n }\n });\n\n if (!isAnimatingRef.current) {\n for (let idx = 0; idx < Math.max(proposedSections.length, existingSections.length); idx++) {\n const l = sectionLeftRefs.current[idx]?.current;\n const r = sectionRightRefs.current[idx]?.current;\n\n if (l) {\n l.style.height = \"auto\";\n l.style.minHeight = \"0px\";\n }\n if (r) {\n r.style.height = \"auto\";\n r.style.minHeight = \"0px\";\n }\n }\n \n if (!maintainRelativeOrder) {\n // Subsections reset\n Object.keys(subSectionLeftRefs.current).forEach(keyPath => {\n if (!isSubSectionVisible(keyPath)) return;\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r) {\n l.style.height = \"auto\";\n r.style.height = \"auto\";\n l.style.minHeight = \"0px\";\n r.style.minHeight = \"0px\";\n }\n });\n }\n }\n\n // READ HEIGHTS (READ ONLY)\n const fieldHeights: Record<string, number> = {};\n\n visibleFields.forEach(({ key } : {key: any}) => {\n const l = leftRefs.current[key]?.current;\n const r = rightRefs.current[key]?.current;\n\n if (l && r) {\n const lRect = l.getBoundingClientRect();\n const rRect = r.getBoundingClientRect();\n fieldHeights[key] = Math.max(lRect.height, rRect.height);\n }\n });\n\n const syncHeights = { left: {} as Record<number, number>, right: {} as Record<number, number> };\n const subSectionHeights: Record<string, number> = {};\n\n if (!isAnimatingRef.current) {\n if (!maintainRelativeOrder) {\n // ── FIX: Measure and apply subsection heights FIRST so their new heights push the parent containers ──\n Object.keys(subSectionLeftRefs.current).forEach(keyPath => {\n if (!isSubSectionVisible(keyPath)) return;\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r && l.offsetParent !== null && r.offsetParent !== null) {\n const lRect = l.getBoundingClientRect();\n const rRect = r.getBoundingClientRect();\n const maxH = Math.max(lRect.height, rRect.height);\n subSectionHeights[keyPath] = maxH;\n \n // Apply immediately so the browser recalculates layout for the parent block below\n l.style.minHeight = `${maxH}px`;\n r.style.minHeight = `${maxH}px`;\n }\n });\n\n // ── NOW measure main sections (which will naturally wrap the aligned subsections) ──\n for (let idx = 0; idx < Math.min(proposedSections.length, existingSections.length); idx++) {\n const l = sectionLeftRefs.current[idx]?.current;\n const r = sectionRightRefs.current[idx]?.current;\n\n if (l && r) {\n const maxH = Math.max(l.getBoundingClientRect().height, r.getBoundingClientRect().height);\n syncHeights.left[idx] = maxH;\n syncHeights.right[idx] = maxH;\n }\n }\n\n } else if (isSideBySide && activeSideBySideSection !== null) {\n if (typeof activeSideBySideSection === \"number\") {\n const leftIdx = activeSideBySideSection;\n const leftSec = proposedSections[leftIdx] as any;\n const l = sectionLeftRefs.current[leftIdx]?.current;\n\n if (l && leftSec) {\n (leftSec.refIndexes || []).forEach((rhsSelfIdx: number) => {\n const rhsArrayIdx = existingSections.findIndex((s: any) => s.selfIndex === rhsSelfIdx);\n const r = sectionRightRefs.current[rhsArrayIdx]?.current;\n if (!r) return;\n\n if (expandedSections[`left-${leftIdx}`] || expandedSections[`right-${rhsArrayIdx}`]) {\n const maxH = Math.max(l.getBoundingClientRect().height, r.getBoundingClientRect().height);\n syncHeights.left[leftIdx] = Math.max(syncHeights.left[leftIdx] || 0, maxH);\n syncHeights.right[rhsArrayIdx] = Math.max(syncHeights.right[rhsArrayIdx] || 0, maxH);\n }\n });\n }\n } else {\n const keyPath = activeSideBySideSection.split(DEVIATION_BADGE_SEPARATOR)[2]; \n if (keyPath) {\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r) {\n const maxH = Math.max(l.getBoundingClientRect().height, r.getBoundingClientRect().height);\n subSectionHeights[keyPath] = Math.max(subSectionHeights[keyPath] || 0, maxH);\n }\n }\n }\n }\n }\n\n visibleFields.forEach(({ key } : {key : any}) => {\n const l = leftRefs.current[key]?.current;\n const r = rightRefs.current[key]?.current;\n\n if (l && r) {\n const maxH = fieldHeights[key];\n l.style.minHeight = `${maxH}px`;\n r.style.minHeight = `${maxH}px`;\n }\n });\n\n if (!isAnimatingRef.current) {\n Object.entries(syncHeights.left).forEach(([idx, maxH]) => {\n const l = sectionLeftRefs.current[Number(idx)]?.current;\n if (l) l.style.minHeight = `${maxH}px`;\n });\n \n Object.entries(syncHeights.right).forEach(([idx, maxH]) => {\n const r = sectionRightRefs.current[Number(idx)]?.current;\n if (r) r.style.minHeight = `${maxH}px`;\n });\n\n if (!maintainRelativeOrder) {\n Object.keys(subSectionHeights).forEach(keyPath => {\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r && subSectionHeights[keyPath]) {\n const maxH = subSectionHeights[keyPath];\n l.style.minHeight = `${maxH}px`;\n r.style.minHeight = `${maxH}px`;\n }\n });\n }\n }\n\n // SECTION CONNECTORS\n // ── SKIP SECTION LINES IF IN GUIDELINE MODE ──\n if (!isGuidelineMode) {\n const getMappedRightIndexes = (leftSec: any, leftIdx: number) => {\n // Standard/Side-by-Side data is already materialized as explicit\n // mapping rows, so its counterpart is always at the same row index.\n // Looking up by display_index is ambiguous when a target section is\n // intentionally repeated for more than one mapping edge.\n if (!maintainRelativeOrder) {\n return existingSections[leftIdx] ? [leftIdx] : [];\n }\n\n const mapped = (leftSec.refIndexes || [])\n .map((rhsSelfIdx: number) =>\n existingSections.findIndex((s: any) => s.selfIndex === rhsSelfIdx),\n )\n .filter((idx: number) => idx !== -1);\n\n // Backward-compatible fallback for old one-to-one/index-based data\n if (!mapped.length && existingSections[leftIdx]) {\n return [leftIdx];\n }\n\n return Array.from(new Set(mapped));\n };\n\n proposedSections.forEach((leftSec: any, leftIdx: number) => {\n const continuationSourceIdx = leftSec.continuationSourceRowId\n ? proposedSections.findIndex(\n (section: any) =>\n section.comparisonRowId === leftSec.continuationSourceRowId,\n )\n : -1;\n const resolvedLeftIdx =\n continuationSourceIdx >= 0 ? continuationSourceIdx : leftIdx;\n const lWrap = sectionLeftRefs.current[resolvedLeftIdx]?.current;\n if (!lWrap) return;\n\n const rightIndexes = getMappedRightIndexes(leftSec, leftIdx);\n\n rightIndexes.forEach((rhsArrayIdx: any) => {\n const rWrap = sectionRightRefs.current[rhsArrayIdx]?.current;\n if (!rWrap) return;\n\n const leftRect = lWrap.getBoundingClientRect();\n const rightRect = rWrap.getBoundingClientRect();\n\n const x1 = leftRect.right - containerRect.left;\n const x2 = rightRect.left - containerRect.left;\n\n let y1 = leftRect.top + 18 - containerRect.top;\n let y2 = rightRect.top + 18 - containerRect.top;\n\n if (maintainRelativeOrder && isSideBySide && activeSideBySideSection === leftIdx) {\n const leftTop = leftContainerRef.current?.getBoundingClientRect().top ?? 0;\n const rightTop = rightContainerRef.current?.getBoundingClientRect().top ?? 0;\n const leftBottom = leftTop + (leftContainerRef.current?.clientHeight ?? Infinity);\n const rightBottom = rightTop + (rightContainerRef.current?.clientHeight ?? Infinity);\n\n const clamp = (v: number, min: number, max: number) =>\n Math.max(min, Math.min(max, v));\n\n y1 = clamp(leftRect.top + 18, leftTop, leftBottom) - containerRect.top;\n y2 = clamp(rightRect.top + 18, rightTop, rightBottom) - containerRect.top;\n }\n\n const style = getSectionCompareStyle(resolvedLeftIdx);\n\n if (style) {\n newLines.push({\n id: `line-${resolvedLeftIdx}-${rhsArrayIdx}`,\n x1,\n y1,\n x2,\n y2,\n style,\n sectionIdx: resolvedLeftIdx,\n targetRightIdx: rhsArrayIdx,\n isSubSection: false,\n isMappingContinuation: continuationSourceIdx >= 0,\n hasCognitive: !!(\n proposedSections[resolvedLeftIdx]?.cognitiveData ||\n existingSections[rhsArrayIdx]?.cognitiveData ||\n proposedSections[resolvedLeftIdx]?.nodeId &&\n cognitiveMap[proposedSections[resolvedLeftIdx].nodeId as string]\n ),\n });\n }\n });\n });\n }\n\n if (!isGuidelineMode && isSideBySide && typeof activeSideBySideSection === 'string' && activeSideBySideSection.includes(DEVIATION_BADGE_SEPARATOR)) {\n const [nodeId, devKey, leftKeyPath, rightKeyPath] = activeSideBySideSection.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${nodeId}${DEVIATION_BADGE_SEPARATOR}${devKey}`;\n\n const lBadgeEl = lhsBadgeRefs.current[refId]?.current;\n const rBadgeEl = rhsBadgeRefs.current[refId]?.current;\n\n if (lBadgeEl && rBadgeEl) {\n const lRect = lBadgeEl.getBoundingClientRect();\n const rRect = rBadgeEl.getBoundingClientRect();\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left;\n \n let y1 = lRect.top + lRect.height / 2 - containerRect.top;\n let y2 = rRect.top + rRect.height / 2 - containerRect.top;\n\n if (maintainRelativeOrder) {\n const leftTop = leftContainerRef.current?.getBoundingClientRect().top ?? 0;\n const rightTop = rightContainerRef.current?.getBoundingClientRect().top ?? 0;\n const leftBottom = leftTop + (leftContainerRef.current?.clientHeight ?? Infinity);\n const rightBottom = rightTop + (rightContainerRef.current?.clientHeight ?? Infinity);\n const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));\n\n y1 = clamp(lRect.top + lRect.height / 2, leftTop, leftBottom) - containerRect.top;\n y2 = clamp(rRect.top + rRect.height / 2, rightTop, rightBottom) - containerRect.top;\n }\n \n const style =\n getDeviationStyleByKey(nodeId, devKey) ??\n getSubSectionCompareStyle(leftKeyPath);\n if (style) {\n newLines.push({\n id: `line-subsec-${refId}`,\n x1, y1, x2, y2,\n style,\n sectionIdx: Number(leftKeyPath.split('-')[0]),\n isSubSection: true,\n subSectionKeyPath: activeSideBySideSection,\n });\n }\n }\n }\n\n setLines(newLines);\n\n if (leftHeaderRef.current && rightHeaderRef.current) {\n const leftHeaderRect = leftHeaderRef.current.getBoundingClientRect();\n const rightHeaderRect = rightHeaderRef.current.getBoundingClientRect();\n const overallY =\n (leftHeaderRect.top +\n leftHeaderRect.height / 2 -\n containerRect.top +\n rightHeaderRect.top +\n rightHeaderRect.height / 2 -\n containerRect.top) /\n 2;\n setOverallConnector({\n x1: leftHeaderRect.right - containerRect.left,\n x2: rightHeaderRect.left - containerRect.left,\n y: overallY,\n });\n } else {\n setOverallConnector(null);\n }\n\n if (connectedSections.size > 0) {\n const newConnectedLines: Record<string, any>[] = [];\n const leftContainer = leftContainerRef.current;\n const rightContainer = rightContainerRef.current;\n\n if (leftContainer && rightContainer) {\n const newCache: CachedBadgePosition[] = [];\n \n const leftTop = leftContainer.getBoundingClientRect().top;\n const rightTop = rightContainer.getBoundingClientRect().top;\n const leftBottom = leftTop + leftContainer.clientHeight;\n const rightBottom = rightTop + rightContainer.clientHeight;\n\n const leftScrollTop = leftContainer.scrollTop;\n const rightScrollTop = rightContainer.scrollTop;\n const cTop = containerRect.top;\n\n const clamp = (v: number, min: number, max: number) =>\n Math.max(min, Math.min(max, v));\n\n connectedSections.forEach((connectedIdx:any) => {\n // ── GUIDELINE MODE LOGIC ──\n if (isGuidelineMode) {\n let lBadge: HTMLElement | null = null;\n let leftIdxNum: number | null = null;\n let style: any = null;\n\n if (typeof connectedIdx === 'string' && connectedIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const [nodeId, devKey, leftKeyPath] = connectedIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${nodeId}${DEVIATION_BADGE_SEPARATOR}${devKey}`;\n lBadge = lhsBadgeRefs.current[refId]?.current;\n style = getDeviationStyleByKey(nodeId, devKey) ?? getSubSectionCompareStyle(leftKeyPath);\n leftIdxNum = Number(leftKeyPath?.split('-')[0] || 0);\n } else {\n leftIdxNum = Number(connectedIdx);\n lBadge = lhsBadgeRefs.current[leftIdxNum]?.current;\n style = getSectionCompareStyle(leftIdxNum);\n }\n\n if (!lBadge) return;\n\n const targetMarks = document.querySelectorAll('[id^=\"guideline-target-\"]');\n \n targetMarks.forEach((rBadge, index) => {\n const lRect = lBadge!.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n \n // ── UNIVERSAL SPINE JUNCTION PUSHED TO X1+75 TO CLEAR LOCK ICON ──\n const centerX = x1 + 75;\n\n const rawLhsY = lRect.top + lRect.height / 2;\n // Target the middle of the highlighted text vertically\n const rawRhsY = rRect.top + rRect.height / 2;\n\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n \n const styleId = `conn-guide-${connectedIdx}-${index}`;\n \n // ── BULLETPROOF MATH LABEL GENERATION ──\n let baseLabel = \"\";\n if (typeof connectedIdx === 'string' && connectedIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const parts = connectedIdx.split(DEVIATION_BADGE_SEPARATOR);\n const leftKeyPath = parts[2] || \"\";\n baseLabel = leftKeyPath.split('-').map(n => Number(n) + 1).join('.');\n } else {\n baseLabel = String(Number(connectedIdx) + 1);\n }\n const letter = String.fromCharCode(97 + index); // a, b, c...\n const matchLabel = targetMarks.length === 1 ? null : `${baseLabel}(${letter})`;\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx: connectedIdx, rhsArrayIdx: index, \n styleColor: style?.badgeBorder || \"#6366F1\", \n styleBg: style?.badgeBg || \"#FFFFFF\",\n styleText: style?.badgeText || \"#A16207\",\n styleId, centerX,\n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({ \n id: styleId, pathD, style, leftIdx: connectedIdx, rhsArrayIdx: index, \n x1, x2, y1, y2, centerX, matchLabel, isGuideline: true \n });\n });\n } else {\n // ── UNIFIED CONTRACT TO CONTRACT LOGIC ──\n if (typeof connectedIdx === 'string' && connectedIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const [nodeId, devKey, leftKeyPath, rightKeyPath] = connectedIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${nodeId}${DEVIATION_BADGE_SEPARATOR}${devKey}`;\n\n const lBadge = lhsBadgeRefs.current[refId]?.current;\n const rBadge = rhsBadgeRefs.current[refId]?.current;\n if (!lBadge || !rBadge) return;\n\n const lRect = lBadge.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n const style = getDeviationStyleByKey(nodeId, devKey) ?? getSubSectionCompareStyle(leftKeyPath);\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n const centerX = x1 + 75; // ── UNIVERSAL SPINE JUNCTION ──\n\n const rawLhsY = lRect.top + lRect.height / 2;\n const rawRhsY = rRect.top + rRect.height / 2;\n\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n const styleId = `conn-subsec-${refId}`;\n \n const leftKeyP = leftKeyPath || \"\";\n const baseLabel = leftKeyP.split('-').map(n => Number(n) + 1).join('.');\n const matchLabel = null; // 1-to-1 connection, no badge needed\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx: connectedIdx, rhsArrayIdx: connectedIdx,\n styleColor: style?.badgeBorder || \"#6366F1\", styleBg: style?.badgeBg || \"#FFFFFF\", styleText: style?.badgeText || \"#A16207\",\n styleId, centerX, \n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({ id: styleId, pathD, style, leftIdx: connectedIdx, rhsArrayIdx: connectedIdx, x1, x2, y1, y2, matchLabel });\n } else {\n if (!maintainRelativeOrder) {\n const leftIdx = connectedIdx;\n const rhsArrayIdx = leftIdx as number;\n const lBadge = lhsBadgeRefs.current[leftIdx]?.current;\n const rBadge = rhsBadgeRefs.current[rhsArrayIdx]?.current;\n if (!lBadge || !rBadge) return;\n\n const lRect = lBadge.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n const style = getSectionCompareStyle(leftIdx as number);\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n const centerX = x1 + 75; // ── UNIVERSAL SPINE JUNCTION ──\n\n const rawLhsY = lRect.top + lRect.height / 2;\n const rawRhsY = rRect.top + rRect.height / 2;\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n const styleId = `conn-${leftIdx}-${rhsArrayIdx}`;\n \n const baseLabel = String(Number(connectedIdx) + 1);\n const matchLabel = null; // 1-to-1 connection, no badge needed\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx, rhsArrayIdx, \n styleColor: style?.badgeBorder || \"#6366F1\", styleBg: style?.badgeBg || \"#FFFFFF\", styleText: style?.badgeText || \"#A16207\",\n styleId, centerX,\n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({ id: styleId, pathD, style, leftIdx, rhsArrayIdx, x1, x2, y1, y2, matchLabel });\n } else {\n const leftIdx = connectedIdx as number;\n const leftSec = proposedSections[leftIdx] as any;\n if (!leftSec?.refIndexes?.length) return;\n\n leftSec.refIndexes.forEach((rhsSelfIdx: number, index: number) => {\n const rhsArrayIdx = existingSections.findIndex((s: any) => s.selfIndex === rhsSelfIdx);\n if (rhsArrayIdx === -1) return;\n\n const lBadge = lhsBadgeRefs.current[leftIdx]?.current;\n const rBadge = rhsBadgeRefs.current[rhsArrayIdx]?.current;\n if (!lBadge || !rBadge) return;\n\n const lRect = lBadge.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n const style = getSectionCompareStyle(leftIdx);\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n \n const centerX = x1 + 75; // ── UNIVERSAL SPINE JUNCTION ──\n\n const rawLhsY = lRect.top + lRect.height / 2;\n const rawRhsY = rRect.top + rRect.height / 2;\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n const styleId = `conn-${leftIdx}-${rhsArrayIdx}`;\n \n const baseLabel = String(Number(connectedIdx) + 1);\n const letter = String.fromCharCode(97 + index); \n const matchLabel = leftSec.refIndexes.length === 1 ? null : `${baseLabel}(${letter})`;\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx, rhsArrayIdx,\n styleColor: style?.badgeBorder || \"#6366F1\", styleBg: style?.badgeBg || \"#FFFFFF\", styleText: style?.badgeText || \"#A16207\",\n styleId, centerX,\n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({\n id: styleId, pathD, style, leftIdx, rhsArrayIdx, x1, x2, y1, y2, matchLabel,\n });\n });\n }\n }\n }\n });\n cachedConnectedPositions.current = newCache;\n }\n setConnectedLines(newConnectedLines);\n\n setTimeout(() => updateConnectedLinesOnScroll(), 10);\n } else {\n setConnectedLines([]);\n cachedConnectedPositions.current = [];\n setTimeout(() => updateConnectedLinesOnScroll(), 10);\n }\n } catch (e) {\n console.error(\"Line render safe fail: \", e);\n } finally {\n isCalculatingLines.current = false;\n }\n }, [\n visibleFields,\n proposedSections,\n existingSections,\n cognitiveMap,\n resolvedComparisonConfig,\n getFieldData,\n getSectionCompareStyle,\n getDeviationStyleByKey,\n maintainRelativeOrder,\n isSideBySide, \n activeSideBySideSection, \n connectedSections,\n expandedSections,\n expandedSubSections,\n isGuidelineMode, \n ]);\n\n const updateConnectedLinesOnScroll = useCallback(() => {\n const cache = cachedConnectedPositions.current;\n \n if (!cache.length) {\n pathRefs.current[\"guideline-up-stroke\"]?.setAttribute(\"visibility\", \"hidden\");\n pathRefs.current[\"guideline-up-badge\"]?.setAttribute(\"visibility\", \"hidden\");\n pathRefs.current[\"guideline-down-stroke\"]?.setAttribute(\"visibility\", \"hidden\");\n pathRefs.current[\"guideline-down-badge\"]?.setAttribute(\"visibility\", \"hidden\");\n return;\n }\n\n if (isAnimatingRef.current) return;\n \n const leftScroll = leftContainerRef.current?.scrollTop ?? 0;\n const rightScroll = rightContainerRef.current?.scrollTop ?? 0;\n \n const leftHeight = leftContainerRef.current?.clientHeight ?? Infinity;\n const rightHeight = rightContainerRef.current?.clientHeight ?? Infinity;\n \n const leftTop = leftContainerRef.current?.getBoundingClientRect().top ?? 0;\n const rightTop = rightContainerRef.current?.getBoundingClientRect().top ?? 0;\n \n const leftBottom = leftTop + leftHeight;\n const rightBottom = rightTop + rightHeight;\n \n const containerRect = containerRef.current?.getBoundingClientRect();\n const containerTop = containerRect?.top ?? 0;\n const containerHeight = containerRect?.height ?? Infinity;\n \n const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));\n \n let topCount = 0;\n let bottomCount = 0;\n let sharedX1 = 0, sharedY1 = 0;\n let sharedColor = \"#6366F1\", sharedBg = \"#FFFFFF\", sharedTextCol = \"#A16207\";\n let hasActiveConnections = false;\n let universalSpineX = 0; \n\n cache.forEach((entry: any) => {\n const lhsViewportY = (entry.lhsScrollY - leftScroll) + leftTop;\n const rhsViewportY = (entry.rhsScrollY - rightScroll) + rightTop;\n \n const strokeEl = pathRefs.current[entry.styleId + \"-stroke\"];\n const bgEl = pathRefs.current[entry.styleId + \"-bg\"];\n const btnEl = pathRefs.current[entry.styleId + \"-btn\"];\n const numberBadgeEl = pathRefs.current[entry.styleId + \"-number\"];\n \n if (!strokeEl && !bgEl) return;\n \n const visibleLhsY = clamp(lhsViewportY, leftTop, leftBottom);\n const visibleRhsY = clamp(rhsViewportY, rightTop, rightBottom);\n \n const y1 = visibleLhsY - containerTop;\n const y2 = visibleRhsY - containerTop;\n \n const lhsVisible = lhsViewportY >= leftTop - 4 && lhsViewportY <= leftBottom + 4;\n const rhsVisible = rhsViewportY >= rightTop - 4 && rhsViewportY <= rightBottom + 4;\n \n let showLine = true;\n hasActiveConnections = true;\n\n // Enforce absolute strict universal spine\n const centerX = entry.centerX || (entry.x1 + 75);\n\n if (sharedX1 === 0) {\n sharedX1 = entry.x1;\n sharedY1 = y1;\n universalSpineX = centerX;\n sharedColor = entry.styleColor;\n sharedBg = entry.styleBg || \"#FFFFFF\";\n sharedTextCol = entry.styleText || \"#A16207\";\n }\n\n if (rhsViewportY < rightTop - 4) {\n topCount++; showLine = false; \n } else if (rhsViewportY > rightBottom + 4) {\n bottomCount++; showLine = false; \n } \n \n const pathD = getRoundedStaggeredPath(entry.x1, y1, entry.x2, y2, universalSpineX, lhsVisible, rhsVisible);\n \n if (strokeEl) {\n if (showLine && pathD) {\n strokeEl.setAttribute(\"visibility\", \"visible\");\n strokeEl.setAttribute(\"d\", pathD);\n } else { strokeEl.setAttribute(\"visibility\", \"hidden\"); }\n }\n \n if (bgEl) {\n if (showLine && pathD) {\n bgEl.setAttribute(\"visibility\", \"visible\");\n bgEl.setAttribute(\"d\", pathD);\n } else { bgEl.setAttribute(\"visibility\", \"hidden\"); }\n }\n\n if (btnEl) {\n if (!lhsVisible || !showLine) {\n btnEl.setAttribute(\"visibility\", \"hidden\");\n } else {\n btnEl.setAttribute(\"visibility\", \"visible\");\n btnEl.setAttribute(\"y\", String(y1 - 12)); \n }\n }\n\n if (numberBadgeEl) {\n if (!lhsVisible || !showLine) {\n numberBadgeEl.setAttribute(\"visibility\", \"hidden\");\n } else {\n numberBadgeEl.setAttribute(\"visibility\", \"visible\");\n numberBadgeEl.setAttribute(\"transform\", `translate(${entry.x2 - 42}, ${y2})`);\n }\n }\n });\n\n // ── UNIVERSAL OFF-SCREEN ARROWS (ALWAYS ORIGINATE EXACTLY AT THE SPINE: X1 + 75) ──\n if (hasActiveConnections && universalSpineX > 0) {\n const upStroke = pathRefs.current[\"guideline-up-stroke\"];\n const upBadge = pathRefs.current[\"guideline-up-badge\"];\n const upArrow = pathRefs.current[\"guideline-up-arrow\"];\n const upText = pathRefs.current[\"guideline-up-text\"];\n const upRect = pathRefs.current[\"guideline-up-badge-rect\"];\n\n if (topCount > 0) {\n const upY = Math.max(15, rightTop - containerTop + 15); \n const r = Math.min(15, Math.abs(universalSpineX - sharedX1), Math.max(0, sharedY1 - upY));\n const pathD = `M ${sharedX1},${sharedY1} L ${universalSpineX - r},${sharedY1} Q ${universalSpineX},${sharedY1} ${universalSpineX},${sharedY1 - r} L ${universalSpineX},${upY}`;\n\n upStroke?.setAttribute(\"visibility\", \"visible\");\n upStroke?.setAttribute(\"d\", pathD);\n upStroke?.setAttribute(\"stroke\", sharedColor);\n\n upBadge?.setAttribute(\"visibility\", \"visible\");\n upBadge?.setAttribute(\"transform\", `translate(${universalSpineX}, ${upY})`);\n \n if (upArrow) { upArrow.setAttribute(\"fill\", sharedColor); }\n if (upText) { upText.textContent = `+${topCount}`; upText.setAttribute(\"fill\", sharedTextCol); }\n if (upRect) { upRect.setAttribute(\"stroke\", sharedColor); }\n } else {\n upStroke?.setAttribute(\"visibility\", \"hidden\");\n upBadge?.setAttribute(\"visibility\", \"hidden\");\n }\n\n const downStroke = pathRefs.current[\"guideline-down-stroke\"];\n const downBadge = pathRefs.current[\"guideline-down-badge\"];\n const downArrow = pathRefs.current[\"guideline-down-arrow\"];\n const downText = pathRefs.current[\"guideline-down-text\"];\n const downRect = pathRefs.current[\"guideline-down-badge-rect\"];\n\n if (bottomCount > 0) {\n const downY = Math.min(containerHeight - 15, rightBottom - containerTop - 15);\n const r = Math.min(15, Math.abs(universalSpineX - sharedX1), Math.max(0, downY - sharedY1));\n const pathD = `M ${sharedX1},${sharedY1} L ${universalSpineX - r},${sharedY1} Q ${universalSpineX},${sharedY1} ${universalSpineX},${sharedY1 + r} L ${universalSpineX},${downY}`;\n\n downStroke?.setAttribute(\"visibility\", \"visible\");\n downStroke?.setAttribute(\"d\", pathD);\n downStroke?.setAttribute(\"stroke\", sharedColor);\n\n downBadge?.setAttribute(\"visibility\", \"visible\");\n downBadge?.setAttribute(\"transform\", `translate(${universalSpineX}, ${downY})`);\n \n if (downArrow) { downArrow.setAttribute(\"fill\", sharedColor); }\n if (downText) { downText.textContent = `+${bottomCount}`; downText.setAttribute(\"fill\", sharedTextCol); }\n if (downRect) { downRect.setAttribute(\"stroke\", sharedColor); }\n } else {\n downStroke?.setAttribute(\"visibility\", \"hidden\");\n downBadge?.setAttribute(\"visibility\", \"hidden\");\n }\n }\n }, []);\n\n const calculateLinesDebounced = useCallback(() => {\n if (cachedConnectedPositions.current.length > 0 && !isAnimatingRef.current) {\n return;\n }\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n timerRef.current = setTimeout(() => {\n calculateLinesRef.current();\n timerRef.current = null;\n }, 50);\n }, []); \n \n \n const handleColumnScroll = useCallback((e: any) => {\n if (pendingScrollTargetRef.current !== null && pendingScrollCallbackRef.current) {\n if (Math.abs(e.currentTarget.scrollTop - pendingScrollTargetRef.current) <= 2) {\n const callback = pendingScrollCallbackRef.current;\n pendingScrollTargetRef.current = null;\n pendingScrollCallbackRef.current = null;\n callback();\n }\n }\n \n if (scrollSyncing.current) return;\n if (scrollLock.current) return;\n\n if (\n maintainRelativeOrder &&\n scrollSyncLocked &&\n (isSideBySideRef.current || connectedSections.size > 0)\n ) {\n const source = e.currentTarget as HTMLElement;\n const leftContainer = leftContainerRef.current;\n const rightContainer = rightContainerRef.current;\n const target =\n source === leftContainer\n ? rightContainer\n : source === rightContainer\n ? leftContainer\n : null;\n\n if (source && target) {\n const resolveActiveAnchors = () => {\n const activeLeftIdx = activeSideBySideSectionRef.current;\n const activeRightIdx = activeSideBySideRightSectionRef.current;\n\n if (activeLeftIdx === null) return { leftAnchor: null, rightAnchor: null };\n\n if (\n typeof activeLeftIdx === \"string\" &&\n activeLeftIdx.includes(DEVIATION_BADGE_SEPARATOR)\n ) {\n const parts = activeLeftIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${parts[0]}${DEVIATION_BADGE_SEPARATOR}${parts[1]}`;\n\n return {\n leftAnchor:\n lhsBadgeRefs.current[refId]?.current ||\n subSectionLeftRefs.current[parts[2]]?.current ||\n sectionLeftRefs.current[Number(parts[2])]?.current ||\n null,\n rightAnchor:\n rhsBadgeRefs.current[refId]?.current ||\n subSectionRightRefs.current[parts[3]]?.current ||\n sectionRightRefs.current[Number(parts[3])]?.current ||\n null,\n };\n }\n\n const leftIdx = Number(activeLeftIdx);\n const rightIdx = activeRightIdx !== null ? Number(activeRightIdx) : leftIdx;\n\n return {\n leftAnchor:\n lhsBadgeRefs.current[leftIdx]?.current ||\n sectionRowRefs.current[leftIdx]?.current ||\n sectionLeftRefs.current[leftIdx]?.current ||\n null,\n rightAnchor:\n rhsBadgeRefs.current[rightIdx]?.current ||\n sectionRightRefs.current[rightIdx]?.current ||\n null,\n };\n };\n\n const { leftAnchor, rightAnchor } = resolveActiveAnchors();\n const sourceAnchor = source === leftContainer ? leftAnchor : rightAnchor;\n const targetAnchor = source === leftContainer ? rightAnchor : leftAnchor;\n\n let nextTargetTop: number | null = null;\n\n if (sourceAnchor && targetAnchor) {\n const sourceAnchorRect = sourceAnchor.getBoundingClientRect();\n const targetAnchorRect = targetAnchor.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n\n const sourceAnchorCenterY =\n sourceAnchorRect.top + sourceAnchorRect.height / 2;\n const targetAnchorAbsoluteCenterY =\n targetAnchorRect.top -\n targetRect.top +\n target.scrollTop +\n targetAnchorRect.height / 2;\n\n nextTargetTop =\n targetAnchorAbsoluteCenterY - (sourceAnchorCenterY - targetRect.top);\n } else {\n const sourceMaxScroll = Math.max(0, source.scrollHeight - source.clientHeight);\n const targetMaxScroll = Math.max(0, target.scrollHeight - target.clientHeight);\n nextTargetTop = sourceMaxScroll > 0\n ? (source.scrollTop / sourceMaxScroll) * targetMaxScroll\n : source.scrollTop;\n }\n\n const targetMaxScroll = Math.max(0, target.scrollHeight - target.clientHeight);\n nextTargetTop = Math.max(0, Math.min(nextTargetTop, targetMaxScroll));\n\n if (Math.abs(target.scrollTop - nextTargetTop) > 1) {\n scrollSyncing.current = true;\n target.scrollTop = nextTargetTop;\n requestAnimationFrame(() => {\n scrollSyncing.current = false;\n });\n }\n }\n }\n \n if (!maintainRelativeOrder) {\n calculateLinesDebounced();\n }\n \n if (!scrollTicking.current) {\n scrollTicking.current = true;\n \n requestAnimationFrame(() => {\n if (isSideBySideRef.current) {\n const leftContainer = leftContainerRef.current;\n const rightContainer = rightContainerRef.current;\n \n if (leftContainer && rightContainer && sideBySideLineRef.current) {\n if (!sideBySideCacheRef.current) {\n const activeLeftIdx = activeSideBySideSectionRef.current;\n let lBadge;\n \n if (typeof activeLeftIdx === 'string' && activeLeftIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const parts = activeLeftIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${parts[0]}${DEVIATION_BADGE_SEPARATOR}${parts[1]}`;\n lBadge = lhsBadgeRefs.current[refId]?.current;\n } else {\n lBadge = lhsBadgeRefs.current[activeLeftIdx as number]?.current;\n }\n \n if (lBadge) {\n const lRect = lBadge.getBoundingClientRect();\n sideBySideCacheRef.current = {\n badgeScreenY: lRect.top + lRect.height / 2, \n initialScrollTop: leftContainer.scrollTop, \n leftTop: leftContainer.getBoundingClientRect().top,\n leftBottom: leftContainer.getBoundingClientRect().top + leftContainer.clientHeight,\n cTop: containerRef.current?.getBoundingClientRect().top ?? 0\n };\n }\n }\n \n if (sideBySideCacheRef.current) {\n const cache = sideBySideCacheRef.current;\n const scrollDelta = leftContainer.scrollTop - cache.initialScrollTop;\n const rawLhsY = cache.badgeScreenY - scrollDelta;\n const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));\n const clampedLhsY = clamp(rawLhsY, cache.leftTop, cache.leftBottom);\n const horizontalY = (clampedLhsY - cache.cTop).toString();\n const isVisible = rawLhsY >= cache.leftTop - 4 && rawLhsY <= cache.leftBottom + 4;\n \n sideBySideLineRef.current.setAttribute(\"y1\", horizontalY);\n sideBySideLineRef.current.setAttribute(\"y2\", horizontalY); \n sideBySideLineRef.current.setAttribute(\"visibility\", isVisible ? \"visible\" : \"hidden\");\n }\n }\n }\n \n updateConnectedLinesOnScroll(); \n scrollTicking.current = false;\n });\n }\n }, [\n updateConnectedLinesOnScroll,\n maintainRelativeOrder,\n scrollSyncLocked,\n connectedSections,\n calculateLinesDebounced,\n ]);\n\n\n useEffect(() => {\n calculateLinesRef.current = calculateLines;\n }, [calculateLines]);\n\n useEffect(() => {\n const timer = setTimeout(calculateLinesDebounced, 250);\n const onWindowResize = () => handleResizeRef.current();\n window.addEventListener(\"resize\", onWindowResize);\n \n return () => {\n clearTimeout(timer);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n if (resizeTimerRef.current !== null) clearTimeout(resizeTimerRef.current);\n window.removeEventListener(\"resize\", onWindowResize);\n };\n }, [\n activeProposed,\n existingRule,\n analysisData,\n visibleFields,\n expandedSections,\n expandedSubSections,\n proposedSections,\n existingSections,\n resolvedComparisonConfig,\n calculateLinesDebounced,\n isSideBySide,\n activeSideBySideSection,\n isArrowVisible,\n connectedSections,\n ]);\n\n\n return {\n lines, setLines,\n overallConnector, setOverallConnector,\n connectedLines, setConnectedLines,\n svgDimensions,\n cachedConnectedPositions,\n calculateLines,\n calculateLinesRef,\n calculateLinesDebounced,\n handleColumnScroll,\n}\n\n}\n"],"names":["useLinesCalculator","containerRef","leftContainerRef","rightContainerRef","svgContainerRef","pathRefs","leftHeaderRef","rightHeaderRef","proposedSections","existingSections","visibleFields","leftRefs","rightRefs","sectionLeftRefs","sectionRightRefs","subSectionLeftRefs","subSectionRightRefs","lhsBadgeRefs","rhsBadgeRefs","sectionRowRefs","expandedSections","expandedSubSections","connectedSections","isSideBySide","activeSideBySideSection","maintainRelativeOrder","isGuidelineMode","cognitiveMap","getSectionCompareStyle","getSubSectionCompareStyle","getDeviationStyleByKey","isArrowVisible","isAnimatingRef","isSideBySideRef","sideBySideCacheRef","sideBySideLineRef","activeSideBySideSectionRef","activeSideBySideRightSectionRef","connectedLines","providedConnectedLines","setConnectedLines","providedSetConnectedLines","cachedConnectedPositions","providedCachedConnectedPositions","calculateLinesRef","resizeTimerRef","scrollLock","scrollSyncLocked","handleResizeRef","activeProposed","existingRule","analysisData","pendingScrollTargetRef","pendingScrollCallbackRef","resolvedComparisonConfig","getFieldData","lines","setLines","useState","overallConnector","setOverallConnector","internalConnectedLines","internalSetConnectedLines","svgDimensions","setSvgDimensions","width","height","isCalculatingLines","useRef","scrollTicking","scrollSyncing","timerRef","internalCachedConnectedPositions","getRoundedStaggeredPath","x1","y1","x2","y2","cX","visL","visR","Math","abs","r1","min","r2","dy1","dy2","dx2","calculateLines","useCallback","current","isSubSectionVisible","keyPath","pathParts","split","rootIdx","ancestorPath","i","length","containerRect","getBoundingClientRect","newLines","forEach","key","l","r","style","minHeight","idx","max","Object","keys","fieldHeights","lRect","rRect","syncHeights","left","right","subSectionHeights","leftIdx","leftSec","refIndexes","rhsSelfIdx","rhsArrayIdx","findIndex","s","selfIndex","maxH","DEVIATION_BADGE_SEPARATOR","offsetParent","entries","Number","getMappedRightIndexes","mapped","map","filter","Array","from","Set","continuationSourceIdx","continuationSourceRowId","section","comparisonRowId","resolvedLeftIdx","lWrap","rWrap","leftRect","rightRect","top","leftTop","rightTop","leftBottom","clientHeight","Infinity","rightBottom","clamp","v","push","id","sectionIdx","targetRightIdx","isSubSection","isMappingContinuation","hasCognitive","cognitiveData","nodeId","includes","devKey","leftKeyPath","rightKeyPath","refId","lBadgeEl","rBadgeEl","subSectionKeyPath","leftHeaderRect","rightHeaderRect","overallY","y","size","newConnectedLines","leftContainer","rightContainer","newCache","leftScrollTop","scrollTop","rightScrollTop","cTop","connectedIdx","lBadge","leftIdxNum","targetMarks","document","querySelectorAll","rBadge","index","centerX","rawLhsY","rawRhsY","lhsScrollY","rhsScrollY","styleId","baseLabel","n","join","String","letter","fromCharCode","matchLabel","containerTop","styleColor","badgeBorder","styleBg","badgeBg","styleText","badgeText","clampedLhsY","clampedRhsY","pathD","isGuideline","setTimeout","updateConnectedLinesOnScroll","e","console","error","cache","setAttribute","leftScroll","rightScroll","leftHeight","rightHeight","containerHeight","topCount","bottomCount","sharedX1","sharedY1","sharedColor","sharedTextCol","hasActiveConnections","universalSpineX","entry","lhsViewportY","rhsViewportY","strokeEl","bgEl","btnEl","numberBadgeEl","visibleLhsY","visibleRhsY","lhsVisible","rhsVisible","showLine","upStroke","upBadge","upArrow","upText","upRect","upY","textContent","downStroke","downBadge","downArrow","downText","downRect","downY","calculateLinesDebounced","clearTimeout","handleColumnScroll","currentTarget","callback","source","target","resolveActiveAnchors","activeLeftIdx","activeRightIdx","leftAnchor","rightAnchor","parts","rightIdx","sourceAnchor","targetAnchor","nextTargetTop","sourceAnchorRect","targetAnchorRect","targetRect","sourceAnchorCenterY","sourceMaxScroll","scrollHeight","targetMaxScroll","requestAnimationFrame","badgeScreenY","initialScrollTop","scrollDelta","horizontalY","toString","isVisible","useEffect","timer","onWindowResize","window","addEventListener","removeEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"useLinesCalculator.js","sources":["../../../../src/features/CognitiveCompare/hooks/useLinesCalculator.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { CachedBadgePosition, SectionBlock } from \"../CognitiveCompareTypes\";\nimport { DEVIATION_BADGE_SEPARATOR, getBentArrowPath, hasValue } from \"../CognitiveComparehelpers\";\nimport { maxHeight } from \"@mui/system\";\nimport { getVisibleGuidelineTargets } from \"../Guidelines/utils/guidelineTargets\";\n\nexport const useLinesCalculator = ({\n containerRef,\n leftContainerRef,\n rightContainerRef,\n svgContainerRef,\n pathRefs,\n leftHeaderRef, rightHeaderRef,\n proposedSections, existingSections,\n visibleFields,\n leftRefs, rightRefs,\n sectionLeftRefs, sectionRightRefs,\n subSectionLeftRefs, subSectionRightRefs,\n lhsBadgeRefs, rhsBadgeRefs,\n sectionRowRefs,\n expandedSections, expandedSubSections,\n connectedSections,\n isSideBySide, activeSideBySideSection,\n maintainRelativeOrder,\n isGuidelineMode, // ── NEW PROP ──\n cognitiveMap,\n getSectionCompareStyle, getSubSectionCompareStyle, getDeviationStyleByKey,\n isArrowVisible,\n\n isAnimatingRef,\n isSideBySideRef,\n sideBySideCacheRef,\n sideBySideLineRef,\n activeSideBySideSectionRef,\n activeSideBySideRightSectionRef,\n connectedLines: providedConnectedLines,\n setConnectedLines: providedSetConnectedLines,\n cachedConnectedPositions: providedCachedConnectedPositions,\n calculateLinesRef,\n resizeTimerRef,\n scrollLock,\n scrollSyncLocked,\n\n handleResizeRef,\n activeProposed, existingRule, analysisData,\n pendingScrollTargetRef, pendingScrollCallbackRef,\n\n resolvedComparisonConfig,\n getFieldData\n}: any) => {\n // States and Refs\n const [lines, setLines] = useState<Record<string, any>[]>([]);\n const [overallConnector, setOverallConnector] = useState<{ x1: number; x2: number; y: number; } | null>(null);\n const [internalConnectedLines, internalSetConnectedLines] = useState<Record<string, any>[]>([]);\n const connectedLines = providedConnectedLines ?? internalConnectedLines;\n const setConnectedLines = providedSetConnectedLines ?? internalSetConnectedLines;\n const [svgDimensions, setSvgDimensions] = useState<{ width: number; height: number }>({ width: 0, height: 0 });\n\n const isCalculatingLines = useRef(false);\n const scrollTicking = useRef(false);\n const scrollSyncing = useRef(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const internalCachedConnectedPositions = useRef<CachedBadgePosition[]>([]);\n const cachedConnectedPositions =\n providedCachedConnectedPositions ?? internalCachedConnectedPositions;\n\n\n \n // Helpers\n // ── UNIFIED ROUNDED PATH GENERATOR (Guarantees shared trunk for ALL modes) ──\n const getRoundedStaggeredPath = (x1: number, y1: number, x2: number, y2: number, cX: number, visL: boolean, visR: boolean) => {\n if (Math.abs(y2 - y1) <= 1) {\n if (visL && visR) return `M ${x1},${y1} L ${x2},${y2}`;\n if (visL && !visR) return `M ${x1},${y1} L ${cX},${y1}`;\n if (!visL && visR) return `M ${cX},${y1} L ${x2},${y2}`;\n return `M ${cX},${y1} L ${cX},${y2}`;\n }\n const r1 = Math.min(15, Math.abs(cX - x1), Math.abs(y2 - y1) / 2);\n const r2 = Math.min(15, Math.abs(x2 - cX), Math.abs(y2 - y1) / 2);\n const dy1 = y2 > y1 ? r1 : -r1;\n const dy2 = y2 > y1 ? r2 : -r2;\n const dx2 = x2 > cX ? r2 : -r2; // Safe horizontal direction\n \n if (visL && visR) {\n return `M ${x1},${y1} L ${cX - r1},${y1} Q ${cX},${y1} ${cX},${y1 + dy1} L ${cX},${y2 - dy2} Q ${cX},${y2} ${cX + dx2},${y2} L ${x2},${y2}`;\n } else if (visL && !visR) {\n return `M ${x1},${y1} L ${cX - r1},${y1} Q ${cX},${y1} ${cX},${y1 + dy1} L ${cX},${y2}`;\n } else if (!visL && visR) {\n return `M ${cX},${y1} L ${cX},${y2 - dy2} Q ${cX},${y2} ${cX + dx2},${y2} L ${x2},${y2}`;\n } else {\n return `M ${cX},${y1} L ${cX},${y2}`;\n }\n };\n\n // Helper to check if a subsection is actually visible in the expanded section\n const isSubSectionVisible = (keyPath: string) => {\n const pathParts = keyPath.split('-');\n const rootIdx = pathParts[0];\n\n // Edge case\n // Early return if root parent is not expanded\n // Only happens in side by side view for deeply nested children\n if (!expandedSections[rootIdx] && maintainRelativeOrder === false) return;\n\n if (maintainRelativeOrder) {\n if (!expandedSections[`left-${rootIdx}`] && !expandedSections[`right-${rootIdx}`] && !expandedSections[rootIdx]) return false;\n }\n\n // Check to confirm if all the ancestors of the node are expanded otherwise early return\n let ancestorPath = rootIdx;\n for (let i = 1; i < pathParts.length - 1; i++) {\n ancestorPath += `-${pathParts[i]}`;\n if (!expandedSections[ancestorPath]) return false;\n }\n\n return true;\n };\n\n // Callbacks\n const calculateLines = useCallback(() => {\n if (isCalculatingLines.current) return;\n if (isAnimatingRef.current) return;\n isCalculatingLines.current = true;\n try {\n if (!containerRef.current) return;\n\n // Helper to check if a subsection is actually visible in the expanded accordion tree\n const isSubSectionVisible = (keyPath: string) => {\n const pathParts = keyPath.split('-');\n const rootIdx = pathParts[0];\n\n // 1. Root Parent must be expanded\n if (!expandedSections[rootIdx] && maintainRelativeOrder === false) return false;\n if (maintainRelativeOrder) {\n if (!expandedSections[`left-${rootIdx}`] && !expandedSections[`right-${rootIdx}`] && !expandedSections[rootIdx]) return false;\n }\n\n // 2. All intermediate ancestor subsections must be expanded\n let ancestorPath = rootIdx;\n for (let i = 1; i < pathParts.length - 1; i++) {\n ancestorPath += `-${pathParts[i]}`;\n if (!expandedSubSections[ancestorPath]) {\n return false;\n }\n }\n return true;\n };\n\n // 3. Keep the SVG setup and field heights logic intact\n const containerRect = containerRef.current.getBoundingClientRect();\n setSvgDimensions({\n width: containerRect.width,\n height: containerRect.height,\n });\n\n const newLines: Record<string, any>[] = [];\n\n // RESET STYLES (WRITE ONLY)\n visibleFields.forEach(({ key }: {key: any}) => {\n const l = leftRefs.current[key]?.current;\n const r = rightRefs.current[key]?.current;\n\n if (l && r) {\n l.style.height = \"auto\";\n r.style.height = \"auto\";\n l.style.minHeight = \"0px\";\n r.style.minHeight = \"0px\";\n }\n });\n\n if (!isAnimatingRef.current) {\n for (let idx = 0; idx < Math.max(proposedSections.length, existingSections.length); idx++) {\n const l = sectionLeftRefs.current[idx]?.current;\n const r = sectionRightRefs.current[idx]?.current;\n\n if (l) {\n l.style.height = \"auto\";\n l.style.minHeight = \"0px\";\n }\n if (r) {\n r.style.height = \"auto\";\n r.style.minHeight = \"0px\";\n }\n }\n \n if (!maintainRelativeOrder) {\n // Subsections reset\n Object.keys(subSectionLeftRefs.current).forEach(keyPath => {\n if (!isSubSectionVisible(keyPath)) return;\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r) {\n l.style.height = \"auto\";\n r.style.height = \"auto\";\n l.style.minHeight = \"0px\";\n r.style.minHeight = \"0px\";\n }\n });\n }\n }\n\n // READ HEIGHTS (READ ONLY)\n const fieldHeights: Record<string, number> = {};\n\n visibleFields.forEach(({ key } : {key: any}) => {\n const l = leftRefs.current[key]?.current;\n const r = rightRefs.current[key]?.current;\n\n if (l && r) {\n const lRect = l.getBoundingClientRect();\n const rRect = r.getBoundingClientRect();\n fieldHeights[key] = Math.max(lRect.height, rRect.height);\n }\n });\n\n const syncHeights = { left: {} as Record<number, number>, right: {} as Record<number, number> };\n const subSectionHeights: Record<string, number> = {};\n\n if (!isAnimatingRef.current) {\n if (!maintainRelativeOrder) {\n // ── FIX: Measure and apply subsection heights FIRST so their new heights push the parent containers ──\n Object.keys(subSectionLeftRefs.current).forEach(keyPath => {\n if (!isSubSectionVisible(keyPath)) return;\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r && l.offsetParent !== null && r.offsetParent !== null) {\n const lRect = l.getBoundingClientRect();\n const rRect = r.getBoundingClientRect();\n const maxH = Math.max(lRect.height, rRect.height);\n subSectionHeights[keyPath] = maxH;\n \n // Apply immediately so the browser recalculates layout for the parent block below\n l.style.minHeight = `${maxH}px`;\n r.style.minHeight = `${maxH}px`;\n }\n });\n\n // ── NOW measure main sections (which will naturally wrap the aligned subsections) ──\n for (let idx = 0; idx < Math.min(proposedSections.length, existingSections.length); idx++) {\n const l = sectionLeftRefs.current[idx]?.current;\n const r = sectionRightRefs.current[idx]?.current;\n\n if (l && r) {\n const maxH = Math.max(l.getBoundingClientRect().height, r.getBoundingClientRect().height);\n syncHeights.left[idx] = maxH;\n syncHeights.right[idx] = maxH;\n }\n }\n\n } else if (isSideBySide && activeSideBySideSection !== null) {\n if (typeof activeSideBySideSection === \"number\") {\n const leftIdx = activeSideBySideSection;\n const leftSec = proposedSections[leftIdx] as any;\n const l = sectionLeftRefs.current[leftIdx]?.current;\n\n if (l && leftSec) {\n (leftSec.refIndexes || []).forEach((rhsSelfIdx: number) => {\n const rhsArrayIdx = existingSections.findIndex((s: any) => s.selfIndex === rhsSelfIdx);\n const r = sectionRightRefs.current[rhsArrayIdx]?.current;\n if (!r) return;\n\n if (expandedSections[`left-${leftIdx}`] || expandedSections[`right-${rhsArrayIdx}`]) {\n const maxH = Math.max(l.getBoundingClientRect().height, r.getBoundingClientRect().height);\n syncHeights.left[leftIdx] = Math.max(syncHeights.left[leftIdx] || 0, maxH);\n syncHeights.right[rhsArrayIdx] = Math.max(syncHeights.right[rhsArrayIdx] || 0, maxH);\n }\n });\n }\n } else {\n const keyPath = activeSideBySideSection.split(DEVIATION_BADGE_SEPARATOR)[2]; \n if (keyPath) {\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r) {\n const maxH = Math.max(l.getBoundingClientRect().height, r.getBoundingClientRect().height);\n subSectionHeights[keyPath] = Math.max(subSectionHeights[keyPath] || 0, maxH);\n }\n }\n }\n }\n }\n\n visibleFields.forEach(({ key } : {key : any}) => {\n const l = leftRefs.current[key]?.current;\n const r = rightRefs.current[key]?.current;\n\n if (l && r) {\n const maxH = fieldHeights[key];\n l.style.minHeight = `${maxH}px`;\n r.style.minHeight = `${maxH}px`;\n }\n });\n\n if (!isAnimatingRef.current) {\n Object.entries(syncHeights.left).forEach(([idx, maxH]) => {\n const l = sectionLeftRefs.current[Number(idx)]?.current;\n if (l) l.style.minHeight = `${maxH}px`;\n });\n \n Object.entries(syncHeights.right).forEach(([idx, maxH]) => {\n const r = sectionRightRefs.current[Number(idx)]?.current;\n if (r) r.style.minHeight = `${maxH}px`;\n });\n\n if (!maintainRelativeOrder) {\n Object.keys(subSectionHeights).forEach(keyPath => {\n const l = subSectionLeftRefs.current[keyPath]?.current;\n const r = subSectionRightRefs.current[keyPath]?.current;\n if (l && r && subSectionHeights[keyPath]) {\n const maxH = subSectionHeights[keyPath];\n l.style.minHeight = `${maxH}px`;\n r.style.minHeight = `${maxH}px`;\n }\n });\n }\n }\n\n // SECTION CONNECTORS\n // ── SKIP SECTION LINES IF IN GUIDELINE MODE ──\n if (!isGuidelineMode) {\n const getMappedRightIndexes = (leftSec: any, leftIdx: number) => {\n // Standard/Side-by-Side data is already materialized as explicit\n // mapping rows, so its counterpart is always at the same row index.\n // Looking up by display_index is ambiguous when a target section is\n // intentionally repeated for more than one mapping edge.\n if (!maintainRelativeOrder) {\n return existingSections[leftIdx] ? [leftIdx] : [];\n }\n\n const mapped = (leftSec.refIndexes || [])\n .map((rhsSelfIdx: number) =>\n existingSections.findIndex((s: any) => s.selfIndex === rhsSelfIdx),\n )\n .filter((idx: number) => idx !== -1);\n\n // Backward-compatible fallback for old one-to-one/index-based data\n if (!mapped.length && existingSections[leftIdx]) {\n return [leftIdx];\n }\n\n return Array.from(new Set(mapped));\n };\n\n proposedSections.forEach((leftSec: any, leftIdx: number) => {\n const continuationSourceIdx = leftSec.continuationSourceRowId\n ? proposedSections.findIndex(\n (section: any) =>\n section.comparisonRowId === leftSec.continuationSourceRowId,\n )\n : -1;\n const resolvedLeftIdx =\n continuationSourceIdx >= 0 ? continuationSourceIdx : leftIdx;\n const lWrap = sectionLeftRefs.current[resolvedLeftIdx]?.current;\n if (!lWrap) return;\n\n const rightIndexes = getMappedRightIndexes(leftSec, leftIdx);\n\n rightIndexes.forEach((rhsArrayIdx: any) => {\n const rWrap = sectionRightRefs.current[rhsArrayIdx]?.current;\n if (!rWrap) return;\n\n const leftRect = lWrap.getBoundingClientRect();\n const rightRect = rWrap.getBoundingClientRect();\n\n const x1 = leftRect.right - containerRect.left;\n const x2 = rightRect.left - containerRect.left;\n\n let y1 = leftRect.top + 18 - containerRect.top;\n let y2 = rightRect.top + 18 - containerRect.top;\n\n if (maintainRelativeOrder && isSideBySide && activeSideBySideSection === leftIdx) {\n const leftTop = leftContainerRef.current?.getBoundingClientRect().top ?? 0;\n const rightTop = rightContainerRef.current?.getBoundingClientRect().top ?? 0;\n const leftBottom = leftTop + (leftContainerRef.current?.clientHeight ?? Infinity);\n const rightBottom = rightTop + (rightContainerRef.current?.clientHeight ?? Infinity);\n\n const clamp = (v: number, min: number, max: number) =>\n Math.max(min, Math.min(max, v));\n\n y1 = clamp(leftRect.top + 18, leftTop, leftBottom) - containerRect.top;\n y2 = clamp(rightRect.top + 18, rightTop, rightBottom) - containerRect.top;\n }\n\n const style = getSectionCompareStyle(resolvedLeftIdx);\n\n if (style) {\n newLines.push({\n id: `line-${resolvedLeftIdx}-${rhsArrayIdx}`,\n x1,\n y1,\n x2,\n y2,\n style,\n sectionIdx: resolvedLeftIdx,\n targetRightIdx: rhsArrayIdx,\n isSubSection: false,\n isMappingContinuation: continuationSourceIdx >= 0,\n hasCognitive: !!(\n proposedSections[resolvedLeftIdx]?.cognitiveData ||\n existingSections[rhsArrayIdx]?.cognitiveData ||\n proposedSections[resolvedLeftIdx]?.nodeId &&\n cognitiveMap[proposedSections[resolvedLeftIdx].nodeId as string]\n ),\n });\n }\n });\n });\n }\n\n if (!isGuidelineMode && isSideBySide && typeof activeSideBySideSection === 'string' && activeSideBySideSection.includes(DEVIATION_BADGE_SEPARATOR)) {\n const [nodeId, devKey, leftKeyPath, rightKeyPath] = activeSideBySideSection.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${nodeId}${DEVIATION_BADGE_SEPARATOR}${devKey}`;\n\n const lBadgeEl = lhsBadgeRefs.current[refId]?.current;\n const rBadgeEl = rhsBadgeRefs.current[refId]?.current;\n\n if (lBadgeEl && rBadgeEl) {\n const lRect = lBadgeEl.getBoundingClientRect();\n const rRect = rBadgeEl.getBoundingClientRect();\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left;\n \n let y1 = lRect.top + lRect.height / 2 - containerRect.top;\n let y2 = rRect.top + rRect.height / 2 - containerRect.top;\n\n if (maintainRelativeOrder) {\n const leftTop = leftContainerRef.current?.getBoundingClientRect().top ?? 0;\n const rightTop = rightContainerRef.current?.getBoundingClientRect().top ?? 0;\n const leftBottom = leftTop + (leftContainerRef.current?.clientHeight ?? Infinity);\n const rightBottom = rightTop + (rightContainerRef.current?.clientHeight ?? Infinity);\n const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));\n\n y1 = clamp(lRect.top + lRect.height / 2, leftTop, leftBottom) - containerRect.top;\n y2 = clamp(rRect.top + rRect.height / 2, rightTop, rightBottom) - containerRect.top;\n }\n \n const style =\n getDeviationStyleByKey(nodeId, devKey) ??\n getSubSectionCompareStyle(leftKeyPath);\n if (style) {\n newLines.push({\n id: `line-subsec-${refId}`,\n x1, y1, x2, y2,\n style,\n sectionIdx: Number(leftKeyPath.split('-')[0]),\n isSubSection: true,\n subSectionKeyPath: activeSideBySideSection,\n });\n }\n }\n }\n\n setLines(newLines);\n\n if (leftHeaderRef.current && rightHeaderRef.current) {\n const leftHeaderRect = leftHeaderRef.current.getBoundingClientRect();\n const rightHeaderRect = rightHeaderRef.current.getBoundingClientRect();\n const overallY =\n (leftHeaderRect.top +\n leftHeaderRect.height / 2 -\n containerRect.top +\n rightHeaderRect.top +\n rightHeaderRect.height / 2 -\n containerRect.top) /\n 2;\n setOverallConnector({\n x1: leftHeaderRect.right - containerRect.left,\n x2: rightHeaderRect.left - containerRect.left,\n y: overallY,\n });\n } else {\n setOverallConnector(null);\n }\n\n if (connectedSections.size > 0) {\n const newConnectedLines: Record<string, any>[] = [];\n const leftContainer = leftContainerRef.current;\n const rightContainer = rightContainerRef.current;\n\n if (leftContainer && rightContainer) {\n const newCache: CachedBadgePosition[] = [];\n \n const leftTop = leftContainer.getBoundingClientRect().top;\n const rightTop = rightContainer.getBoundingClientRect().top;\n const leftBottom = leftTop + leftContainer.clientHeight;\n const rightBottom = rightTop + rightContainer.clientHeight;\n\n const leftScrollTop = leftContainer.scrollTop;\n const rightScrollTop = rightContainer.scrollTop;\n const cTop = containerRect.top;\n\n const clamp = (v: number, min: number, max: number) =>\n Math.max(min, Math.min(max, v));\n\n connectedSections.forEach((connectedIdx:any) => {\n // ── GUIDELINE MODE LOGIC ──\n if (isGuidelineMode) {\n let lBadge: HTMLElement | null = null;\n let leftIdxNum: number | null = null;\n let style: any = null;\n\n if (typeof connectedIdx === 'string' && connectedIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const [nodeId, devKey, leftKeyPath] = connectedIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${nodeId}${DEVIATION_BADGE_SEPARATOR}${devKey}`;\n lBadge = lhsBadgeRefs.current[refId]?.current;\n style = getDeviationStyleByKey(nodeId, devKey) ?? getSubSectionCompareStyle(leftKeyPath);\n leftIdxNum = Number(leftKeyPath?.split('-')[0] || 0);\n } else {\n leftIdxNum = Number(connectedIdx);\n lBadge = lhsBadgeRefs.current[leftIdxNum]?.current;\n style = getSectionCompareStyle(leftIdxNum);\n }\n\n if (!lBadge) return;\n\n const targetMarks = getVisibleGuidelineTargets(rightContainer);\n \n targetMarks.forEach((rBadge: any, index) => {\n const lRect = lBadge!.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n \n // ── UNIVERSAL SPINE JUNCTION PUSHED TO X1+75 TO CLEAR LOCK ICON ──\n const centerX = x1 + 75;\n\n const rawLhsY = lRect.top + lRect.height / 2;\n // Target the middle of the highlighted text vertically\n const rawRhsY = rRect.top + rRect.height / 2;\n\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n \n const styleId = `conn-guide-${connectedIdx}-${index}`;\n \n // ── BULLETPROOF MATH LABEL GENERATION ──\n let baseLabel = \"\";\n if (typeof connectedIdx === 'string' && connectedIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const parts = connectedIdx.split(DEVIATION_BADGE_SEPARATOR);\n const leftKeyPath = parts[2] || \"\";\n baseLabel = leftKeyPath.split('-').map(n => Number(n) + 1).join('.');\n } else {\n baseLabel = String(Number(connectedIdx) + 1);\n }\n const letter = String.fromCharCode(97 + index); // a, b, c...\n const matchLabel = targetMarks.length === 1 ? null : `${baseLabel}(${letter})`;\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx: connectedIdx, rhsArrayIdx: index, \n styleColor: style?.badgeBorder || \"#6366F1\", \n styleBg: style?.badgeBg || \"#FFFFFF\",\n styleText: style?.badgeText || \"#A16207\",\n styleId, centerX,\n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({ \n id: styleId, pathD, style, leftIdx: connectedIdx, rhsArrayIdx: index, \n x1, x2, y1, y2, centerX, matchLabel, isGuideline: true \n });\n });\n } else {\n // ── UNIFIED CONTRACT TO CONTRACT LOGIC ──\n if (typeof connectedIdx === 'string' && connectedIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const [nodeId, devKey, leftKeyPath, rightKeyPath] = connectedIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${nodeId}${DEVIATION_BADGE_SEPARATOR}${devKey}`;\n\n const lBadge = lhsBadgeRefs.current[refId]?.current;\n const rBadge = rhsBadgeRefs.current[refId]?.current;\n if (!lBadge || !rBadge) return;\n\n const lRect = lBadge.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n const style = getDeviationStyleByKey(nodeId, devKey) ?? getSubSectionCompareStyle(leftKeyPath);\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n const centerX = x1 + 75; // ── UNIVERSAL SPINE JUNCTION ──\n\n const rawLhsY = lRect.top + lRect.height / 2;\n const rawRhsY = rRect.top + rRect.height / 2;\n\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n const styleId = `conn-subsec-${refId}`;\n \n const leftKeyP = leftKeyPath || \"\";\n const baseLabel = leftKeyP.split('-').map(n => Number(n) + 1).join('.');\n const matchLabel = null; // 1-to-1 connection, no badge needed\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx: connectedIdx, rhsArrayIdx: connectedIdx,\n styleColor: style?.badgeBorder || \"#6366F1\", styleBg: style?.badgeBg || \"#FFFFFF\", styleText: style?.badgeText || \"#A16207\",\n styleId, centerX, \n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({ id: styleId, pathD, style, leftIdx: connectedIdx, rhsArrayIdx: connectedIdx, x1, x2, y1, y2, matchLabel });\n } else {\n if (!maintainRelativeOrder) {\n const leftIdx = connectedIdx;\n const rhsArrayIdx = leftIdx as number;\n const lBadge = lhsBadgeRefs.current[leftIdx]?.current;\n const rBadge = rhsBadgeRefs.current[rhsArrayIdx]?.current;\n if (!lBadge || !rBadge) return;\n\n const lRect = lBadge.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n const style = getSectionCompareStyle(leftIdx as number);\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n const centerX = x1 + 75; // ── UNIVERSAL SPINE JUNCTION ──\n\n const rawLhsY = lRect.top + lRect.height / 2;\n const rawRhsY = rRect.top + rRect.height / 2;\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n const styleId = `conn-${leftIdx}-${rhsArrayIdx}`;\n \n const baseLabel = String(Number(connectedIdx) + 1);\n const matchLabel = null; // 1-to-1 connection, no badge needed\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx, rhsArrayIdx, \n styleColor: style?.badgeBorder || \"#6366F1\", styleBg: style?.badgeBg || \"#FFFFFF\", styleText: style?.badgeText || \"#A16207\",\n styleId, centerX,\n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({ id: styleId, pathD, style, leftIdx, rhsArrayIdx, x1, x2, y1, y2, matchLabel });\n } else {\n const leftIdx = connectedIdx as number;\n const leftSec = proposedSections[leftIdx] as any;\n if (!leftSec?.refIndexes?.length) return;\n\n leftSec.refIndexes.forEach((rhsSelfIdx: number, index: number) => {\n const rhsArrayIdx = existingSections.findIndex((s: any) => s.selfIndex === rhsSelfIdx);\n if (rhsArrayIdx === -1) return;\n\n const lBadge = lhsBadgeRefs.current[leftIdx]?.current;\n const rBadge = rhsBadgeRefs.current[rhsArrayIdx]?.current;\n if (!lBadge || !rBadge) return;\n\n const lRect = lBadge.getBoundingClientRect();\n const rRect = rBadge.getBoundingClientRect();\n const style = getSectionCompareStyle(leftIdx);\n\n const x1 = lRect.right - containerRect.left;\n const x2 = rRect.left - containerRect.left - 0;\n \n const centerX = x1 + 75; // ── UNIVERSAL SPINE JUNCTION ──\n\n const rawLhsY = lRect.top + lRect.height / 2;\n const rawRhsY = rRect.top + rRect.height / 2;\n const lhsScrollY = (rawLhsY - leftTop) + leftScrollTop;\n const rhsScrollY = (rawRhsY - rightTop) + rightScrollTop;\n const styleId = `conn-${leftIdx}-${rhsArrayIdx}`;\n \n const baseLabel = String(Number(connectedIdx) + 1);\n const letter = String.fromCharCode(97 + index); \n const matchLabel = leftSec.refIndexes.length === 1 ? null : `${baseLabel}(${letter})`;\n\n newCache.push({\n lhsScrollY, rhsScrollY, x1, x2, containerTop: cTop,\n leftIdx, rhsArrayIdx,\n styleColor: style?.badgeBorder || \"#6366F1\", styleBg: style?.badgeBg || \"#FFFFFF\", styleText: style?.badgeText || \"#A16207\",\n styleId, centerX,\n });\n\n const clampedLhsY = clamp(rawLhsY, leftTop, leftBottom);\n const clampedRhsY = clamp(rawRhsY, rightTop, rightBottom);\n const y1 = clampedLhsY - cTop;\n const y2 = clampedRhsY - cTop;\n const lhsVisible = rawLhsY >= leftTop - 4 && rawLhsY <= leftBottom + 4;\n const rhsVisible = rawRhsY >= rightTop - 4 && rawRhsY <= rightBottom + 4;\n\n const pathD = getRoundedStaggeredPath(x1, y1, x2, y2, centerX, lhsVisible, rhsVisible);\n\n newConnectedLines.push({\n id: styleId, pathD, style, leftIdx, rhsArrayIdx, x1, x2, y1, y2, matchLabel,\n });\n });\n }\n }\n }\n });\n cachedConnectedPositions.current = newCache;\n }\n setConnectedLines(newConnectedLines);\n\n setTimeout(() => updateConnectedLinesOnScroll(), 10);\n } else {\n setConnectedLines([]);\n cachedConnectedPositions.current = [];\n setTimeout(() => updateConnectedLinesOnScroll(), 10);\n }\n } catch (e) {\n console.error(\"Line render safe fail: \", e);\n } finally {\n isCalculatingLines.current = false;\n }\n }, [\n visibleFields,\n proposedSections,\n existingSections,\n cognitiveMap,\n resolvedComparisonConfig,\n getFieldData,\n getSectionCompareStyle,\n getDeviationStyleByKey,\n maintainRelativeOrder,\n isSideBySide, \n activeSideBySideSection, \n connectedSections,\n expandedSections,\n expandedSubSections,\n isGuidelineMode, \n ]);\n\n const updateConnectedLinesOnScroll = useCallback(() => {\n const cache = cachedConnectedPositions.current;\n \n if (!cache.length) {\n pathRefs.current[\"guideline-up-stroke\"]?.setAttribute(\"visibility\", \"hidden\");\n pathRefs.current[\"guideline-up-badge\"]?.setAttribute(\"visibility\", \"hidden\");\n pathRefs.current[\"guideline-down-stroke\"]?.setAttribute(\"visibility\", \"hidden\");\n pathRefs.current[\"guideline-down-badge\"]?.setAttribute(\"visibility\", \"hidden\");\n return;\n }\n\n if (isAnimatingRef.current) return;\n \n const leftScroll = leftContainerRef.current?.scrollTop ?? 0;\n const rightScroll = rightContainerRef.current?.scrollTop ?? 0;\n \n const leftHeight = leftContainerRef.current?.clientHeight ?? Infinity;\n const rightHeight = rightContainerRef.current?.clientHeight ?? Infinity;\n \n const leftTop = leftContainerRef.current?.getBoundingClientRect().top ?? 0;\n const rightTop = rightContainerRef.current?.getBoundingClientRect().top ?? 0;\n \n const leftBottom = leftTop + leftHeight;\n const rightBottom = rightTop + rightHeight;\n \n const containerRect = containerRef.current?.getBoundingClientRect();\n const containerTop = containerRect?.top ?? 0;\n const containerHeight = containerRect?.height ?? Infinity;\n \n const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));\n \n let topCount = 0;\n let bottomCount = 0;\n let sharedX1 = 0, sharedY1 = 0;\n let sharedColor = \"#6366F1\", sharedBg = \"#FFFFFF\", sharedTextCol = \"#A16207\";\n let hasActiveConnections = false;\n let universalSpineX = 0; \n\n cache.forEach((entry: any) => {\n const lhsViewportY = (entry.lhsScrollY - leftScroll) + leftTop;\n const rhsViewportY = (entry.rhsScrollY - rightScroll) + rightTop;\n \n const strokeEl = pathRefs.current[entry.styleId + \"-stroke\"];\n const bgEl = pathRefs.current[entry.styleId + \"-bg\"];\n const btnEl = pathRefs.current[entry.styleId + \"-btn\"];\n const numberBadgeEl = pathRefs.current[entry.styleId + \"-number\"];\n \n if (!strokeEl && !bgEl) return;\n \n const visibleLhsY = clamp(lhsViewportY, leftTop, leftBottom);\n const visibleRhsY = clamp(rhsViewportY, rightTop, rightBottom);\n \n const y1 = visibleLhsY - containerTop;\n const y2 = visibleRhsY - containerTop;\n \n const lhsVisible = lhsViewportY >= leftTop - 4 && lhsViewportY <= leftBottom + 4;\n const rhsVisible = rhsViewportY >= rightTop - 4 && rhsViewportY <= rightBottom + 4;\n \n let showLine = true;\n hasActiveConnections = true;\n\n // Enforce absolute strict universal spine\n const centerX = entry.centerX || (entry.x1 + 75);\n\n if (sharedX1 === 0) {\n sharedX1 = entry.x1;\n sharedY1 = y1;\n universalSpineX = centerX;\n sharedColor = entry.styleColor;\n sharedBg = entry.styleBg || \"#FFFFFF\";\n sharedTextCol = entry.styleText || \"#A16207\";\n }\n\n if (rhsViewportY < rightTop - 4) {\n topCount++; showLine = false; \n } else if (rhsViewportY > rightBottom + 4) {\n bottomCount++; showLine = false; \n } \n \n const pathD = getRoundedStaggeredPath(entry.x1, y1, entry.x2, y2, universalSpineX, lhsVisible, rhsVisible);\n \n if (strokeEl) {\n if (showLine && pathD) {\n strokeEl.setAttribute(\"visibility\", \"visible\");\n strokeEl.setAttribute(\"d\", pathD);\n } else { strokeEl.setAttribute(\"visibility\", \"hidden\"); }\n }\n \n if (bgEl) {\n if (showLine && pathD) {\n bgEl.setAttribute(\"visibility\", \"visible\");\n bgEl.setAttribute(\"d\", pathD);\n } else { bgEl.setAttribute(\"visibility\", \"hidden\"); }\n }\n\n if (btnEl) {\n if (!lhsVisible || !showLine) {\n btnEl.setAttribute(\"visibility\", \"hidden\");\n } else {\n btnEl.setAttribute(\"visibility\", \"visible\");\n btnEl.setAttribute(\"y\", String(y1 - 12)); \n }\n }\n\n if (numberBadgeEl) {\n if (!lhsVisible || !showLine) {\n numberBadgeEl.setAttribute(\"visibility\", \"hidden\");\n } else {\n numberBadgeEl.setAttribute(\"visibility\", \"visible\");\n numberBadgeEl.setAttribute(\"transform\", `translate(${entry.x2 - 42}, ${y2})`);\n }\n }\n });\n\n // ── UNIVERSAL OFF-SCREEN ARROWS (ALWAYS ORIGINATE EXACTLY AT THE SPINE: X1 + 75) ──\n if (hasActiveConnections && universalSpineX > 0) {\n const upStroke = pathRefs.current[\"guideline-up-stroke\"];\n const upBadge = pathRefs.current[\"guideline-up-badge\"];\n const upArrow = pathRefs.current[\"guideline-up-arrow\"];\n const upText = pathRefs.current[\"guideline-up-text\"];\n const upRect = pathRefs.current[\"guideline-up-badge-rect\"];\n\n if (topCount > 0) {\n const upY = Math.max(15, rightTop - containerTop + 15); \n const r = Math.min(15, Math.abs(universalSpineX - sharedX1), Math.max(0, sharedY1 - upY));\n const pathD = `M ${sharedX1},${sharedY1} L ${universalSpineX - r},${sharedY1} Q ${universalSpineX},${sharedY1} ${universalSpineX},${sharedY1 - r} L ${universalSpineX},${upY}`;\n\n upStroke?.setAttribute(\"visibility\", \"visible\");\n upStroke?.setAttribute(\"d\", pathD);\n upStroke?.setAttribute(\"stroke\", sharedColor);\n\n upBadge?.setAttribute(\"visibility\", \"visible\");\n upBadge?.setAttribute(\"transform\", `translate(${universalSpineX}, ${upY})`);\n \n if (upArrow) { upArrow.setAttribute(\"fill\", sharedColor); }\n if (upText) { upText.textContent = `+${topCount}`; upText.setAttribute(\"fill\", sharedTextCol); }\n if (upRect) { upRect.setAttribute(\"stroke\", sharedColor); }\n } else {\n upStroke?.setAttribute(\"visibility\", \"hidden\");\n upBadge?.setAttribute(\"visibility\", \"hidden\");\n }\n\n const downStroke = pathRefs.current[\"guideline-down-stroke\"];\n const downBadge = pathRefs.current[\"guideline-down-badge\"];\n const downArrow = pathRefs.current[\"guideline-down-arrow\"];\n const downText = pathRefs.current[\"guideline-down-text\"];\n const downRect = pathRefs.current[\"guideline-down-badge-rect\"];\n\n if (bottomCount > 0) {\n const downY = Math.min(containerHeight - 15, rightBottom - containerTop - 15);\n const r = Math.min(15, Math.abs(universalSpineX - sharedX1), Math.max(0, downY - sharedY1));\n const pathD = `M ${sharedX1},${sharedY1} L ${universalSpineX - r},${sharedY1} Q ${universalSpineX},${sharedY1} ${universalSpineX},${sharedY1 + r} L ${universalSpineX},${downY}`;\n\n downStroke?.setAttribute(\"visibility\", \"visible\");\n downStroke?.setAttribute(\"d\", pathD);\n downStroke?.setAttribute(\"stroke\", sharedColor);\n\n downBadge?.setAttribute(\"visibility\", \"visible\");\n downBadge?.setAttribute(\"transform\", `translate(${universalSpineX}, ${downY})`);\n \n if (downArrow) { downArrow.setAttribute(\"fill\", sharedColor); }\n if (downText) { downText.textContent = `+${bottomCount}`; downText.setAttribute(\"fill\", sharedTextCol); }\n if (downRect) { downRect.setAttribute(\"stroke\", sharedColor); }\n } else {\n downStroke?.setAttribute(\"visibility\", \"hidden\");\n downBadge?.setAttribute(\"visibility\", \"hidden\");\n }\n }\n }, []);\n\n const calculateLinesDebounced = useCallback(() => {\n if (cachedConnectedPositions.current.length > 0 && !isAnimatingRef.current) {\n return;\n }\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n timerRef.current = setTimeout(() => {\n calculateLinesRef.current();\n timerRef.current = null;\n }, 50);\n }, []); \n \n \n const handleColumnScroll = useCallback((e: any) => {\n if (pendingScrollTargetRef.current !== null && pendingScrollCallbackRef.current) {\n if (Math.abs(e.currentTarget.scrollTop - pendingScrollTargetRef.current) <= 2) {\n const callback = pendingScrollCallbackRef.current;\n pendingScrollTargetRef.current = null;\n pendingScrollCallbackRef.current = null;\n callback();\n }\n }\n \n if (scrollSyncing.current) return;\n if (scrollLock.current) return;\n\n if (\n maintainRelativeOrder &&\n scrollSyncLocked &&\n (isSideBySideRef.current || connectedSections.size > 0)\n ) {\n const source = e.currentTarget as HTMLElement;\n const leftContainer = leftContainerRef.current;\n const rightContainer = rightContainerRef.current;\n const target =\n source === leftContainer\n ? rightContainer\n : source === rightContainer\n ? leftContainer\n : null;\n\n if (source && target) {\n const resolveActiveAnchors = () => {\n const activeLeftIdx = activeSideBySideSectionRef.current;\n const activeRightIdx = activeSideBySideRightSectionRef.current;\n\n if (activeLeftIdx === null) return { leftAnchor: null, rightAnchor: null };\n\n if (\n typeof activeLeftIdx === \"string\" &&\n activeLeftIdx.includes(DEVIATION_BADGE_SEPARATOR)\n ) {\n const parts = activeLeftIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${parts[0]}${DEVIATION_BADGE_SEPARATOR}${parts[1]}`;\n\n return {\n leftAnchor:\n lhsBadgeRefs.current[refId]?.current ||\n subSectionLeftRefs.current[parts[2]]?.current ||\n sectionLeftRefs.current[Number(parts[2])]?.current ||\n null,\n rightAnchor:\n rhsBadgeRefs.current[refId]?.current ||\n subSectionRightRefs.current[parts[3]]?.current ||\n sectionRightRefs.current[Number(parts[3])]?.current ||\n null,\n };\n }\n\n const leftIdx = Number(activeLeftIdx);\n const rightIdx = activeRightIdx !== null ? Number(activeRightIdx) : leftIdx;\n\n return {\n leftAnchor:\n lhsBadgeRefs.current[leftIdx]?.current ||\n sectionRowRefs.current[leftIdx]?.current ||\n sectionLeftRefs.current[leftIdx]?.current ||\n null,\n rightAnchor:\n rhsBadgeRefs.current[rightIdx]?.current ||\n sectionRightRefs.current[rightIdx]?.current ||\n null,\n };\n };\n\n const { leftAnchor, rightAnchor } = resolveActiveAnchors();\n const sourceAnchor = source === leftContainer ? leftAnchor : rightAnchor;\n const targetAnchor = source === leftContainer ? rightAnchor : leftAnchor;\n\n let nextTargetTop: number | null = null;\n\n if (sourceAnchor && targetAnchor) {\n const sourceAnchorRect = sourceAnchor.getBoundingClientRect();\n const targetAnchorRect = targetAnchor.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n\n const sourceAnchorCenterY =\n sourceAnchorRect.top + sourceAnchorRect.height / 2;\n const targetAnchorAbsoluteCenterY =\n targetAnchorRect.top -\n targetRect.top +\n target.scrollTop +\n targetAnchorRect.height / 2;\n\n nextTargetTop =\n targetAnchorAbsoluteCenterY - (sourceAnchorCenterY - targetRect.top);\n } else {\n const sourceMaxScroll = Math.max(0, source.scrollHeight - source.clientHeight);\n const targetMaxScroll = Math.max(0, target.scrollHeight - target.clientHeight);\n nextTargetTop = sourceMaxScroll > 0\n ? (source.scrollTop / sourceMaxScroll) * targetMaxScroll\n : source.scrollTop;\n }\n\n const targetMaxScroll = Math.max(0, target.scrollHeight - target.clientHeight);\n nextTargetTop = Math.max(0, Math.min(nextTargetTop, targetMaxScroll));\n\n if (Math.abs(target.scrollTop - nextTargetTop) > 1) {\n scrollSyncing.current = true;\n target.scrollTop = nextTargetTop;\n requestAnimationFrame(() => {\n scrollSyncing.current = false;\n });\n }\n }\n }\n \n if (!maintainRelativeOrder) {\n calculateLinesDebounced();\n }\n \n if (!scrollTicking.current) {\n scrollTicking.current = true;\n \n requestAnimationFrame(() => {\n if (isSideBySideRef.current) {\n const leftContainer = leftContainerRef.current;\n const rightContainer = rightContainerRef.current;\n \n if (leftContainer && rightContainer && sideBySideLineRef.current) {\n if (!sideBySideCacheRef.current) {\n const activeLeftIdx = activeSideBySideSectionRef.current;\n let lBadge;\n \n if (typeof activeLeftIdx === 'string' && activeLeftIdx.includes(DEVIATION_BADGE_SEPARATOR)) {\n const parts = activeLeftIdx.split(DEVIATION_BADGE_SEPARATOR);\n const refId = `${parts[0]}${DEVIATION_BADGE_SEPARATOR}${parts[1]}`;\n lBadge = lhsBadgeRefs.current[refId]?.current;\n } else {\n lBadge = lhsBadgeRefs.current[activeLeftIdx as number]?.current;\n }\n \n if (lBadge) {\n const lRect = lBadge.getBoundingClientRect();\n sideBySideCacheRef.current = {\n badgeScreenY: lRect.top + lRect.height / 2, \n initialScrollTop: leftContainer.scrollTop, \n leftTop: leftContainer.getBoundingClientRect().top,\n leftBottom: leftContainer.getBoundingClientRect().top + leftContainer.clientHeight,\n cTop: containerRef.current?.getBoundingClientRect().top ?? 0\n };\n }\n }\n \n if (sideBySideCacheRef.current) {\n const cache = sideBySideCacheRef.current;\n const scrollDelta = leftContainer.scrollTop - cache.initialScrollTop;\n const rawLhsY = cache.badgeScreenY - scrollDelta;\n const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));\n const clampedLhsY = clamp(rawLhsY, cache.leftTop, cache.leftBottom);\n const horizontalY = (clampedLhsY - cache.cTop).toString();\n const isVisible = rawLhsY >= cache.leftTop - 4 && rawLhsY <= cache.leftBottom + 4;\n \n sideBySideLineRef.current.setAttribute(\"y1\", horizontalY);\n sideBySideLineRef.current.setAttribute(\"y2\", horizontalY); \n sideBySideLineRef.current.setAttribute(\"visibility\", isVisible ? \"visible\" : \"hidden\");\n }\n }\n }\n \n updateConnectedLinesOnScroll(); \n scrollTicking.current = false;\n });\n }\n }, [\n updateConnectedLinesOnScroll,\n maintainRelativeOrder,\n scrollSyncLocked,\n connectedSections,\n calculateLinesDebounced,\n ]);\n\n\n useEffect(() => {\n calculateLinesRef.current = calculateLines;\n }, [calculateLines]);\n\n useEffect(() => {\n const timer = setTimeout(calculateLinesDebounced, 250);\n const onWindowResize = () => handleResizeRef.current();\n window.addEventListener(\"resize\", onWindowResize);\n \n return () => {\n clearTimeout(timer);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n if (resizeTimerRef.current !== null) clearTimeout(resizeTimerRef.current);\n window.removeEventListener(\"resize\", onWindowResize);\n };\n }, [\n activeProposed,\n existingRule,\n analysisData,\n visibleFields,\n expandedSections,\n expandedSubSections,\n proposedSections,\n existingSections,\n resolvedComparisonConfig,\n calculateLinesDebounced,\n isSideBySide,\n activeSideBySideSection,\n isArrowVisible,\n connectedSections,\n ]);\n\n\n return {\n lines, setLines,\n overallConnector, setOverallConnector,\n connectedLines, setConnectedLines,\n svgDimensions,\n cachedConnectedPositions,\n calculateLines,\n calculateLinesRef,\n calculateLinesDebounced,\n handleColumnScroll,\n}\n\n}"],"names":["useLinesCalculator","containerRef","leftContainerRef","rightContainerRef","svgContainerRef","pathRefs","leftHeaderRef","rightHeaderRef","proposedSections","existingSections","visibleFields","leftRefs","rightRefs","sectionLeftRefs","sectionRightRefs","subSectionLeftRefs","subSectionRightRefs","lhsBadgeRefs","rhsBadgeRefs","sectionRowRefs","expandedSections","expandedSubSections","connectedSections","isSideBySide","activeSideBySideSection","maintainRelativeOrder","isGuidelineMode","cognitiveMap","getSectionCompareStyle","getSubSectionCompareStyle","getDeviationStyleByKey","isArrowVisible","isAnimatingRef","isSideBySideRef","sideBySideCacheRef","sideBySideLineRef","activeSideBySideSectionRef","activeSideBySideRightSectionRef","connectedLines","providedConnectedLines","setConnectedLines","providedSetConnectedLines","cachedConnectedPositions","providedCachedConnectedPositions","calculateLinesRef","resizeTimerRef","scrollLock","scrollSyncLocked","handleResizeRef","activeProposed","existingRule","analysisData","pendingScrollTargetRef","pendingScrollCallbackRef","resolvedComparisonConfig","getFieldData","lines","setLines","useState","overallConnector","setOverallConnector","internalConnectedLines","internalSetConnectedLines","svgDimensions","setSvgDimensions","width","height","isCalculatingLines","useRef","scrollTicking","scrollSyncing","timerRef","internalCachedConnectedPositions","getRoundedStaggeredPath","x1","y1","x2","y2","cX","visL","visR","Math","abs","r1","min","r2","dy1","dy2","dx2","calculateLines","useCallback","current","isSubSectionVisible","keyPath","pathParts","split","rootIdx","ancestorPath","i","length","containerRect","getBoundingClientRect","newLines","forEach","key","l","r","style","minHeight","idx","max","Object","keys","fieldHeights","lRect","rRect","syncHeights","left","right","subSectionHeights","leftIdx","leftSec","refIndexes","rhsSelfIdx","rhsArrayIdx","findIndex","s","selfIndex","maxH","DEVIATION_BADGE_SEPARATOR","offsetParent","entries","Number","getMappedRightIndexes","mapped","map","filter","Array","from","Set","continuationSourceIdx","continuationSourceRowId","section","comparisonRowId","resolvedLeftIdx","lWrap","rWrap","leftRect","rightRect","top","leftTop","rightTop","leftBottom","clientHeight","Infinity","rightBottom","clamp","v","push","id","sectionIdx","targetRightIdx","isSubSection","isMappingContinuation","hasCognitive","cognitiveData","nodeId","includes","devKey","leftKeyPath","rightKeyPath","refId","lBadgeEl","rBadgeEl","subSectionKeyPath","leftHeaderRect","rightHeaderRect","overallY","y","size","newConnectedLines","leftContainer","rightContainer","newCache","leftScrollTop","scrollTop","rightScrollTop","cTop","connectedIdx","lBadge","leftIdxNum","targetMarks","getVisibleGuidelineTargets","rBadge","index","centerX","rawLhsY","rawRhsY","lhsScrollY","rhsScrollY","styleId","baseLabel","n","join","String","letter","fromCharCode","matchLabel","containerTop","styleColor","badgeBorder","styleBg","badgeBg","styleText","badgeText","clampedLhsY","clampedRhsY","pathD","isGuideline","setTimeout","updateConnectedLinesOnScroll","e","console","error","cache","setAttribute","leftScroll","rightScroll","leftHeight","rightHeight","containerHeight","topCount","bottomCount","sharedX1","sharedY1","sharedColor","sharedTextCol","hasActiveConnections","universalSpineX","entry","lhsViewportY","rhsViewportY","strokeEl","bgEl","btnEl","numberBadgeEl","visibleLhsY","visibleRhsY","lhsVisible","rhsVisible","showLine","upStroke","upBadge","upArrow","upText","upRect","upY","textContent","downStroke","downBadge","downArrow","downText","downRect","downY","calculateLinesDebounced","clearTimeout","handleColumnScroll","currentTarget","callback","source","target","resolveActiveAnchors","activeLeftIdx","activeRightIdx","leftAnchor","rightAnchor","parts","rightIdx","sourceAnchor","targetAnchor","nextTargetTop","sourceAnchorRect","targetAnchorRect","targetRect","sourceAnchorCenterY","sourceMaxScroll","scrollHeight","targetMaxScroll","requestAnimationFrame","badgeScreenY","initialScrollTop","scrollDelta","horizontalY","toString","isVisible","useEffect","timer","onWindowResize","window","addEventListener","removeEventListener"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{useRef as t,useState as e,useEffect as r,useCallback as n}from"react";import{buildOnDemandCitationCacheKey as o}from"../onDemandCitations/cacheKey.js";import{buildOnDemandCitationPayload as a}from"../onDemandCitations/payload.js";import{normalizeOnDemandCitationResponse as s}from"../onDemandCitations/response.js";const c=6e5,i=(t,e=6e5)=>Date.now()-t.updatedAt>e,u=t=>{const e={"content-type":"application/json",...t.request.headers||{}},r=Object.keys(e).some(t=>"authorization"===t.toLowerCase());return t.request.authToken&&!r&&(e.Authorization=`Bearer ${t.request.authToken}`),e},l=l=>{const h=t(new Map),[d,p]=e(0);r(()=>()=>{h.current.forEach(t=>t.controller?.abort())},[]);const f=n(()=>{p(t=>t+1)},[]),m=n(t=>o(t),[]),y=n(t=>{const e="string"==typeof t?t:m(t);return h.current.get(e)},[m,d]),g=n((t,e)=>{h.current.set(t,e),f()},[f]),w=n(async t=>{if(!l?.enabled||!l.request.url)return null;const e=m(t),r=l.cacheTtlMs??c,n=h.current.get(e);if("success"===n?.status&&!i(n,r))return n.data;if("loading"===n?.status&&n.promise)return n.promise;if("error"===n?.status&&!1===l.retryFailed&&!i(n,r))return null;const o=new AbortController,d=fetch(l.request.url,{method:l.request.method||"POST",headers:u(l),credentials:l.request.credentials,body:JSON.stringify(a(l,t)),signal:o.signal}).then(async e=>{const r=await(async t=>{if((t.headers.get("content-type")||"").includes("application/json"))return t.json();const e=await t.text();try{return JSON.parse(e)}catch{return e}})(e);if(!e.ok)throw new Error("string"==typeof r?r:r?.error?.errorMessage||r?.message||`Failed to fetch on-demand citation (${e.status})`);return l.parseResponse?.(r,t)??s(r,t)}).then(t=>(h.current.set(e,{status:"success",data:t,updatedAt:Date.now()}),f(),t)).catch(t=>{const r=t instanceof DOMException&&"AbortError"===t.name;if(h.current.set(e,{status:"error",error:t,updatedAt:Date.now()}),f(),r)return null;throw t});return g(e,{status:"loading",promise:d,controller:o,updatedAt:Date.now()}),d},[l,m,f,g]),C=n(async t=>{l?.enabled&&0!==t.length&&await(async(t,e,r)=>{const n=[...t],o=Array.from({length:Math.max(1,Math.min(e,n.length))},async()=>{for(;n.length>0;){const t=n.shift();if(!t)return;try{await r(t)}catch{}}});await Promise.all(o)})(t,l.maxConcurrentRequests||3,w)},[l,w]),b=n(t=>{t.forEach(t=>{const e=m(t),r=h.current.get(e);"loading"===r?.status&&r.controller?.abort()})},[m]);return{cacheVersion:d,getCacheKey:m,getCacheEntry:y,fetchCitationContext:w,prefetchCitationContexts:C,abortCitationContexts:b}};export{l as useOnDemandCitationCache};
2
+ //# sourceMappingURL=useOnDemandCitationCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOnDemandCitationCache.js","sources":["../../../../src/features/CognitiveCompare/hooks/useOnDemandCitationCache.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n CognitiveCompareOnDemandCitationConfig,\n OnDemandCitationCacheEntry,\n OnDemandCitationContext,\n} from \"../CognitiveCompareTypes\";\nimport {\n buildOnDemandCitationCacheKey,\n buildOnDemandCitationPayload,\n normalizeOnDemandCitationResponse,\n} from \"../onDemandCitations\";\n\nconst DEFAULT_CACHE_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_MAX_CONCURRENT_REQUESTS = 3;\n\nconst isExpired = (\n entry: OnDemandCitationCacheEntry,\n ttlMs = DEFAULT_CACHE_TTL_MS,\n) => Date.now() - entry.updatedAt > ttlMs;\n\nconst withConcurrencyLimit = async <T,>(\n items: T[],\n limit: number,\n worker: (item: T) => Promise<unknown>,\n) => {\n const queue = [...items];\n const workers = Array.from(\n { length: Math.max(1, Math.min(limit, queue.length)) },\n async () => {\n while (queue.length > 0) {\n const item = queue.shift();\n if (!item) return;\n try {\n await worker(item);\n } catch {\n // Individual request errors are written to cache by the worker.\n }\n }\n },\n );\n\n await Promise.all(workers);\n};\n\nconst getFetchHeaders = (\n config: CognitiveCompareOnDemandCitationConfig,\n) => {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n ...(config.request.headers || {}),\n };\n const hasAuthorizationHeader = Object.keys(headers).some(\n (key) => key.toLowerCase() === \"authorization\",\n );\n\n if (config.request.authToken && !hasAuthorizationHeader) {\n headers.Authorization = `Bearer ${config.request.authToken}`;\n }\n\n return headers;\n};\n\nconst readResponseBody = async (response: Response) => {\n const contentType = response.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n const text = await response.text();\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n};\n\nexport const useOnDemandCitationCache = (\n config?: CognitiveCompareOnDemandCitationConfig,\n) => {\n const cacheRef = useRef<Map<string, OnDemandCitationCacheEntry>>(new Map());\n const [cacheVersion, setCacheVersion] = useState(0);\n\n useEffect(() => {\n return () => {\n cacheRef.current.forEach((entry) => entry.controller?.abort());\n };\n }, []);\n\n const notifyCacheUpdated = useCallback(() => {\n setCacheVersion((version) => version + 1);\n }, []);\n\n const getCacheKey = useCallback(\n (context: OnDemandCitationContext) => buildOnDemandCitationCacheKey(context),\n [],\n );\n\n const getCacheEntry = useCallback(\n (contextOrKey: OnDemandCitationContext | string) => {\n const key =\n typeof contextOrKey === \"string\"\n ? contextOrKey\n : getCacheKey(contextOrKey);\n return cacheRef.current.get(key);\n },\n [getCacheKey, cacheVersion],\n );\n\n const setCacheEntry = useCallback(\n (key: string, entry: OnDemandCitationCacheEntry) => {\n cacheRef.current.set(key, entry);\n notifyCacheUpdated();\n },\n [notifyCacheUpdated],\n );\n\n const fetchCitationContext = useCallback(\n async (context: OnDemandCitationContext) => {\n if (!config?.enabled || !config.request.url) {\n return null;\n }\n\n const key = getCacheKey(context);\n const ttlMs = config.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n const existingEntry = cacheRef.current.get(key);\n\n if (\n existingEntry?.status === \"success\" &&\n !isExpired(existingEntry, ttlMs)\n ) {\n return existingEntry.data;\n }\n\n if (existingEntry?.status === \"loading\" && existingEntry.promise) {\n return existingEntry.promise;\n }\n\n if (\n existingEntry?.status === \"error\" &&\n config.retryFailed === false &&\n !isExpired(existingEntry, ttlMs)\n ) {\n return null;\n }\n\n const controller = new AbortController();\n const promise = fetch(config.request.url, {\n method: config.request.method || \"POST\",\n headers: getFetchHeaders(config),\n credentials: config.request.credentials,\n body: JSON.stringify(buildOnDemandCitationPayload(config, context)),\n signal: controller.signal,\n })\n .then(async (response) => {\n const body = await readResponseBody(response);\n if (!response.ok) {\n throw new Error(\n typeof body === \"string\"\n ? body\n : body?.error?.errorMessage ||\n body?.message ||\n `Failed to fetch on-demand citation (${response.status})`,\n );\n }\n\n return (\n config.parseResponse?.(body, context) ??\n normalizeOnDemandCitationResponse(body, context)\n );\n })\n .then((data) => {\n cacheRef.current.set(key, {\n status: \"success\",\n data,\n updatedAt: Date.now(),\n });\n notifyCacheUpdated();\n return data;\n })\n .catch((error) => {\n const isAbortError =\n error instanceof DOMException && error.name === \"AbortError\";\n cacheRef.current.set(key, {\n status: \"error\",\n error,\n updatedAt: Date.now(),\n });\n notifyCacheUpdated();\n\n if (isAbortError) return null;\n throw error;\n });\n\n setCacheEntry(key, {\n status: \"loading\",\n promise,\n controller,\n updatedAt: Date.now(),\n });\n\n return promise;\n },\n [config, getCacheKey, notifyCacheUpdated, setCacheEntry],\n );\n\n const prefetchCitationContexts = useCallback(\n async (contexts: OnDemandCitationContext[]) => {\n if (!config?.enabled || contexts.length === 0) return;\n\n await withConcurrencyLimit(\n contexts,\n config.maxConcurrentRequests || DEFAULT_MAX_CONCURRENT_REQUESTS,\n fetchCitationContext,\n );\n },\n [config, fetchCitationContext],\n );\n\n const abortCitationContexts = useCallback(\n (contexts: OnDemandCitationContext[]) => {\n contexts.forEach((context) => {\n const key = getCacheKey(context);\n const entry = cacheRef.current.get(key);\n if (entry?.status === \"loading\") {\n entry.controller?.abort();\n }\n });\n },\n [getCacheKey],\n );\n\n return {\n cacheVersion,\n getCacheKey,\n getCacheEntry,\n fetchCitationContext,\n prefetchCitationContexts,\n abortCitationContexts,\n };\n};\n"],"names":["DEFAULT_CACHE_TTL_MS","isExpired","entry","ttlMs","Date","now","updatedAt","getFetchHeaders","config","headers","request","hasAuthorizationHeader","Object","keys","some","key","toLowerCase","authToken","Authorization","useOnDemandCitationCache","cacheRef","useRef","Map","cacheVersion","setCacheVersion","useState","useEffect","current","forEach","controller","abort","notifyCacheUpdated","useCallback","version","getCacheKey","context","buildOnDemandCitationCacheKey","getCacheEntry","contextOrKey","get","setCacheEntry","set","fetchCitationContext","async","enabled","url","cacheTtlMs","existingEntry","status","data","promise","retryFailed","AbortController","fetch","method","credentials","body","JSON","stringify","buildOnDemandCitationPayload","signal","then","response","includes","json","text","parse","readResponseBody","ok","Error","error","errorMessage","message","parseResponse","normalizeOnDemandCitationResponse","catch","isAbortError","DOMException","name","prefetchCitationContexts","contexts","length","items","limit","worker","queue","workers","Array","from","Math","max","min","item","shift","Promise","all","withConcurrencyLimit","maxConcurrentRequests","abortCitationContexts"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{useState as e,useRef as t,useCallback as n,useEffect as r}from"react";import{DEVIATION_BADGE_SEPARATOR as c,resetClauseHighlight as i,smoothScrollTo as u}from"../CognitiveComparehelpers.js";const l=({isGuidelineMode:l,maintainRelativeOrder:o,proposedSections:s,existingSections:d,leftContainerRef:p,rightContainerRef:g,scrollContainerRef:a,sectionLeftRefs:f,sectionRightRefs:h,subSectionLeftRefs:R,subSectionRightRefs:S,lhsBadgeRefs:y,rhsBadgeRefs:m,sectionRowRefs:B,sectionRightRowRefs:x,rhsTopSpacerRef:C,rhsBottomSpacerRef:T,lhsTopSpacerRef:v,lhsBottomSpacerRef:b,calculateLinesRef:$,setConnectedSections:A,setConnectedLines:I,cachedConnectedPositions:w,closeMoreFunctionsPopup:L,setErrorToast:E,moreFunctions:F,closeSummaryPopup:N})=>{const[q,H]=e(!1),[M,P]=e(!1),[z,V]=e(!1),[j,k]=e(!1),[G,O]=e(null),D=t(!1),J=t(null),K=t(!1),Q=t(null),U=t(null),W=t(null),X=t(new Set),Y=()=>{X.current.forEach(e=>{i(e)}),X.current.clear()},Z=(e,t,n)=>{let r=null,i=null,u=null,l=null,o=null,s=null;const d=(e,t)=>{if(!e||!t)return!0;const n=e.getBoundingClientRect(),r=t.getBoundingClientRect();return n.bottom>=r.top&&n.top<=r.bottom};if(e){const e=t.split(c),n=`${e[0]}${c}${e[1]}`;r=R.current[e[2]]?.current||f.current[Number(e[2])]?.current||null,i=S.current[e[3]]?.current||h.current[Number(e[3])]?.current||null,u=y.current[n]?.current||r,l=m.current[n]?.current||i}else{const e=Number(t),c=null!==n?Number(n):e;r=f.current[e]?.current||null,i=h.current[c]?.current||null,o=y.current[e]?.current||null,s=m.current[c]?.current||null,u=o||B.current[e]?.current||r,l=s||x.current[c]?.current||i}if(r&&(r.style.paddingTop="0px"),i&&(i.style.paddingTop="0px"),e||(o&&(o.style.marginTop="0px"),s&&(s.style.marginTop="0px")),!e&&o&&s){const e=p.current,t=g.current;if(!d(o,e)||!d(s,t))return;const n=o.getBoundingClientRect(),r=s.getBoundingClientRect(),c=n.top-r.top;if(Math.abs(c)>32)return;return void(c>0&&(s.style.marginTop=`${c}px`))}if(u&&l&&r&&i){const e=u.getBoundingClientRect(),t=l.getBoundingClientRect(),n=e.top-t.top;n>0&&(i.style.paddingTop=`${n}px`)}},_=n(()=>{const e=Q.current,t=U.current;if(null!==e)if("string"==typeof e&&e.includes(c)){const t=e.split(c),n=R.current[t[2]]?.current||f.current[Number(t[2])]?.current||null,r=S.current[t[3]]?.current||h.current[Number(t[3])]?.current||null;n&&(n.style.paddingTop="0px"),r&&(r.style.paddingTop="0px")}else{const n=f.current[e]?.current||null,r=h.current[t??e]?.current||null;n&&(n.style.paddingTop="0px"),r&&(r.style.paddingTop="0px");const c=y.current[e]?.current||null,i=m.current[t??e]?.current||null;c&&(c.style.marginTop="0px"),i&&(i.style.marginTop="0px")}C.current&&(C.current.style.height="0px"),T.current&&(T.current.style.height="0px"),v.current&&(v.current.style.height="0px"),b.current&&(b.current.style.height="0px")},[]);r(()=>{K.current=q},[q]),r(()=>{Q.current=G},[G]);const ee=n(()=>{Y(),H(!1),K.current=!1,J.current=null,_(),O(null),Q.current=null,U.current=null,P(!1),k(!1)},[_]),te=n((e,t,n)=>{const r=n?.toggleIfSame??!0,i=n?.onReady,R=n?.sourceSide??"left";if(L(),null==e)return;if(t&&!l)return void E("No counterpart exists for this section.");Y();const S=q&&G===e;q&&null!==G&&_(),S&&r?ee():(A(new Set([e])),I([]),w.current=[],k(!0),D.current=!0,O(e),Q.current=e,H(!0),K.current=!0,P(!1),C.current&&(C.current.style.height="0px"),T.current&&(T.current.style.height="0px"),v.current&&(v.current.style.height="0px"),b.current&&(b.current.style.height="0px"),requestAnimationFrame(()=>{const t=()=>{const t="string"==typeof e&&e.includes(c);let n=null,r=null,S=null;if(l){if(t){const t=e.split(c),r=`${t[0]}${c}${t[1]}`;n=y.current[r]?.current||null}else n=f.current[e]?.current||B.current[e]?.current||null;r=document.getElementById("guideline-target-0"),S=r?e:null}else if(t){const t=e.split(c),i=`${t[0]}${c}${t[1]}`;n=y.current[i]?.current||null,r=m.current[i]?.current||null,S=r?e:null}else if(n=f.current[e]?.current||B.current[e]?.current||null,o){const t=s[e],n=t?.refIndexes||[];if(n.length>0){const e=n[0],t=d.findIndex(t=>t.selfIndex===e);-1!==t&&(r=h.current[t]?.current||x.current[t]?.current||null,S=t)}}else r=h.current[e]?.current||x.current[e]?.current||null,S=r?e:null;U.current=S;const v=p.current,b=g.current,A=()=>{Z(t,e,S),P(!0),$.current&&$.current(),D.current=!1,"right"===R&&b?b.dispatchEvent(new Event("scroll")):v&&v.dispatchEvent(new Event("scroll")),k(!1),i?.()};if(!n||!v)return D.current=!1,k(!1),void i?.();if(!r||!b)return void A();if(!o){let e=0;e="right"===R?r?r.getBoundingClientRect().top:0:n?n.getBoundingClientRect().top:0;const t=a.current,c=t?.getBoundingClientRect().top||0,i=t?t.scrollTop+e-c-150:0;return t?void u(t,i,200,A):void A()}const I=n.getBoundingClientRect().top-v.getBoundingClientRect().top+v.scrollTop,w=r.getBoundingClientRect().top-b.getBoundingClientRect().top+b.scrollTop,L=200;if("left"===R){const e=w-(I-v.scrollTop);e<0&&C.current&&!l&&(C.current.style.height=`${Math.abs(e)}px`),requestAnimationFrame(()=>{const t=b.scrollHeight-b.clientHeight;let n;if(e<0)n=0;else{if(e>t){const n=e-t;return T.current&&!l&&(T.current.style.height=`${n+150}px`),void requestAnimationFrame(()=>{u(b,e,L,A)})}n=e}u(b,n,L,A)})}else{const e=I-(w-b.scrollTop);requestAnimationFrame(()=>{const t=v.scrollHeight-v.clientHeight;let n;if(e<0)n=0;else{if(e>t)return void requestAnimationFrame(()=>u(v,t,L,A));n=e}u(v,n,L,A)})}};l?setTimeout(t,100):t()}))},[G,L,d,q,o,s,_,ee,l]);return{isSideBySide:q,setIsSideBySide:H,isArrowVisible:M,setIsArrowVisible:P,isResizing:z,setIsResizing:V,isSideBySideLoading:j,setIsSideBySideLoading:k,activeSideBySideSection:G,setActiveSideBySideSection:O,scrollLock:D,sideBySideCacheRef:J,isSideBySideRef:K,activeSideBySideSectionRef:Q,activeSideBySideRightSectionRef:U,sideBySideLineRef:W,highlightedClauseRefs:X,clearClauseHighlight:Y,applyAlignmentPadding:Z,resetSideBySide:ee,activateSideBySide:te}};export{l as useSideBySide};
1
+ import{useState as e,useRef as t,useCallback as n,useEffect as r}from"react";import{DEVIATION_BADGE_SEPARATOR as i,resetClauseHighlight as c,smoothScrollTo as u}from"../CognitiveComparehelpers.js";import{getVisibleGuidelineTargets as l}from"../Guidelines/utils/guidelineTargets.js";const o=({isGuidelineMode:o,maintainRelativeOrder:s,proposedSections:d,existingSections:p,leftContainerRef:g,rightContainerRef:a,scrollContainerRef:f,sectionLeftRefs:h,sectionRightRefs:R,subSectionLeftRefs:S,subSectionRightRefs:y,lhsBadgeRefs:m,rhsBadgeRefs:B,sectionRowRefs:x,sectionRightRowRefs:C,rhsTopSpacerRef:T,rhsBottomSpacerRef:v,lhsTopSpacerRef:b,lhsBottomSpacerRef:$,calculateLinesRef:A,setConnectedSections:w,setConnectedLines:I,cachedConnectedPositions:L,closeMoreFunctionsPopup:F,setErrorToast:N,moreFunctions:E,closeSummaryPopup:q})=>{const[H,M]=e(!1),[P,j]=e(!1),[z,G]=e(!1),[V,k]=e(!1),[O,D]=e(null),J=t(!1),K=t(null),Q=t(!1),U=t(null),W=t(null),X=t(null),Y=t(new Set),Z=()=>{Y.current.forEach(e=>{c(e)}),Y.current.clear()},_=(e,t,n)=>{let r=null,c=null,u=null,l=null,o=null,s=null;const d=(e,t)=>{if(!e||!t)return!0;const n=e.getBoundingClientRect(),r=t.getBoundingClientRect();return n.bottom>=r.top&&n.top<=r.bottom};if(e){const e=t.split(i),n=`${e[0]}${i}${e[1]}`;r=S.current[e[2]]?.current||h.current[Number(e[2])]?.current||null,c=y.current[e[3]]?.current||R.current[Number(e[3])]?.current||null,u=m.current[n]?.current||r,l=B.current[n]?.current||c}else{const e=Number(t),i=null!==n?Number(n):e;r=h.current[e]?.current||null,c=R.current[i]?.current||null,o=m.current[e]?.current||null,s=B.current[i]?.current||null,u=o||x.current[e]?.current||r,l=s||C.current[i]?.current||c}if(r&&(r.style.paddingTop="0px"),c&&(c.style.paddingTop="0px"),e||(o&&(o.style.marginTop="0px"),s&&(s.style.marginTop="0px")),!e&&o&&s){const e=g.current,t=a.current;if(!d(o,e)||!d(s,t))return;const n=o.getBoundingClientRect(),r=s.getBoundingClientRect(),i=n.top-r.top;if(Math.abs(i)>32)return;return void(i>0&&(s.style.marginTop=`${i}px`))}if(u&&l&&r&&c){const e=u.getBoundingClientRect(),t=l.getBoundingClientRect(),n=e.top-t.top;n>0&&(c.style.paddingTop=`${n}px`)}},ee=n(()=>{const e=U.current,t=W.current;if(null!==e)if("string"==typeof e&&e.includes(i)){const t=e.split(i),n=S.current[t[2]]?.current||h.current[Number(t[2])]?.current||null,r=y.current[t[3]]?.current||R.current[Number(t[3])]?.current||null;n&&(n.style.paddingTop="0px"),r&&(r.style.paddingTop="0px")}else{const n=h.current[e]?.current||null,r=R.current[t??e]?.current||null;n&&(n.style.paddingTop="0px"),r&&(r.style.paddingTop="0px");const i=m.current[e]?.current||null,c=B.current[t??e]?.current||null;i&&(i.style.marginTop="0px"),c&&(c.style.marginTop="0px")}T.current&&(T.current.style.height="0px"),v.current&&(v.current.style.height="0px"),b.current&&(b.current.style.height="0px"),$.current&&($.current.style.height="0px")},[]);r(()=>{Q.current=H},[H]),r(()=>{U.current=O},[O]);const te=n(()=>{Z(),M(!1),Q.current=!1,K.current=null,ee(),D(null),U.current=null,W.current=null,j(!1),k(!1)},[ee]),ne=n((e,t,n)=>{const r=n?.toggleIfSame??!0,c=n?.onReady,S=n?.sourceSide??"left";if(F(),null==e)return;if(t&&!o)return void N("No counterpart exists for this section.");Z();const y=H&&O===e;H&&null!==O&&ee(),y&&r?te():(w(new Set([e])),I([]),L.current=[],k(!0),J.current=!0,D(e),U.current=e,M(!0),Q.current=!0,j(!1),T.current&&(T.current.style.height="0px"),v.current&&(v.current.style.height="0px"),b.current&&(b.current.style.height="0px"),$.current&&($.current.style.height="0px"),requestAnimationFrame(()=>{const t=()=>{const t="string"==typeof e&&e.includes(i);let n=null,r=null,y=null;if(o){if(t){const t=e.split(i),r=`${t[0]}${i}${t[1]}`;n=m.current[r]?.current||null}else n=h.current[e]?.current||x.current[e]?.current||null;r=l(a.current)[0]||null,y=r?e:null}else if(t){const t=e.split(i),c=`${t[0]}${i}${t[1]}`;n=m.current[c]?.current||null,r=B.current[c]?.current||null,y=r?e:null}else if(n=h.current[e]?.current||x.current[e]?.current||null,s){const t=d[e],n=t?.refIndexes||[];if(n.length>0){const e=n[0],t=p.findIndex(t=>t.selfIndex===e);-1!==t&&(r=R.current[t]?.current||C.current[t]?.current||null,y=t)}}else r=R.current[e]?.current||C.current[e]?.current||null,y=r?e:null;W.current=y;const b=g.current,$=a.current,w=()=>{_(t,e,y),j(!0),A.current&&A.current(),J.current=!1,"right"===S&&$?$.dispatchEvent(new Event("scroll")):b&&b.dispatchEvent(new Event("scroll")),k(!1),c?.()};if(!n||!b)return J.current=!1,k(!1),void c?.();if(!r||!$)return void w();if(!s){let e=0;e="right"===S?r?r.getBoundingClientRect().top:0:n?n.getBoundingClientRect().top:0;const t=f.current,i=t?.getBoundingClientRect().top||0,c=t?t.scrollTop+e-i-150:0;return t?void u(t,c,200,w):void w()}const I=n.getBoundingClientRect().top-b.getBoundingClientRect().top+b.scrollTop,L=r.getBoundingClientRect().top-$.getBoundingClientRect().top+$.scrollTop,F=200;if("left"===S){const e=L-(I-b.scrollTop);e<0&&T.current&&!o&&(T.current.style.height=`${Math.abs(e)}px`),requestAnimationFrame(()=>{const t=$.scrollHeight-$.clientHeight;let n;if(e<0)n=0;else{if(e>t){const n=e-t;return v.current&&!o&&(v.current.style.height=`${n+150}px`),void requestAnimationFrame(()=>{u($,e,F,w)})}n=e}u($,n,F,w)})}else{const e=I-(L-$.scrollTop);requestAnimationFrame(()=>{const t=b.scrollHeight-b.clientHeight;let n;if(e<0)n=0;else{if(e>t)return void requestAnimationFrame(()=>u(b,t,F,w));n=e}u(b,n,F,w)})}};o?setTimeout(t,100):t()}))},[O,F,p,H,s,d,ee,te,o]);return{isSideBySide:H,setIsSideBySide:M,isArrowVisible:P,setIsArrowVisible:j,isResizing:z,setIsResizing:G,isSideBySideLoading:V,setIsSideBySideLoading:k,activeSideBySideSection:O,setActiveSideBySideSection:D,scrollLock:J,sideBySideCacheRef:K,isSideBySideRef:Q,activeSideBySideSectionRef:U,activeSideBySideRightSectionRef:W,sideBySideLineRef:X,highlightedClauseRefs:Y,clearClauseHighlight:Z,applyAlignmentPadding:_,resetSideBySide:te,activateSideBySide:ne}};export{o as useSideBySide};
2
2
  //# sourceMappingURL=useSideBySide.js.map