semiotic 3.8.3 → 3.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/CLAUDE.md +13 -10
  2. package/README.md +52 -45
  3. package/ai/componentMetadata.cjs +1 -1
  4. package/ai/dist/mcp-server.js +4 -2
  5. package/ai/examples.md +168 -1
  6. package/ai/schema.json +3756 -327
  7. package/ai/surface-manifest.json +6 -4
  8. package/ai/system-prompt.md +1 -1
  9. package/dist/chunk-chartContainerDataAudit-74TLKIP6.module.min.js +2 -0
  10. package/dist/chunk-chunk-2JGJ5GUG.module.min.js +0 -1
  11. package/dist/chunk-chunk-4AANPFOX.module.min.js +2 -0
  12. package/dist/{chunk-chunk-JNCHKRIR.module.min.js → chunk-chunk-5I3UZV4Q.module.min.js} +1 -1
  13. package/dist/chunk-chunk-74CCPVXB.module.min.js +1 -0
  14. package/dist/{chunk-chunk-VVCA3DB7.module.min.js → chunk-chunk-7ALTGHK6.module.min.js} +1 -1
  15. package/dist/chunk-chunk-ACLDBMRH.module.min.js +2 -0
  16. package/dist/chunk-chunk-AVBI6GDT.module.min.js +1 -0
  17. package/dist/{chunk-chunk-XQYVEKEJ.module.min.js → chunk-chunk-BANTPINB.module.min.js} +1 -1
  18. package/dist/chunk-chunk-C4YA6TDR.module.min.js +1 -0
  19. package/dist/chunk-chunk-C57LR3YG.module.min.js +1 -0
  20. package/dist/chunk-chunk-CKMD5NV3.module.min.js +2 -0
  21. package/dist/chunk-chunk-CO5KQMGH.module.min.js +1 -0
  22. package/dist/chunk-chunk-CWQ5YIHX.module.min.js +2 -0
  23. package/dist/chunk-chunk-E6TXX6MI.module.min.js +1 -0
  24. package/dist/{chunk-chunk-7FW6EGLP.module.min.js → chunk-chunk-I36PJ4OC.module.min.js} +1 -1
  25. package/dist/chunk-chunk-IY7RYD4S.module.min.js +1 -0
  26. package/dist/chunk-chunk-K3DMEW22.module.min.js +1 -0
  27. package/dist/chunk-chunk-KT2VAZMZ.module.min.js +1 -0
  28. package/dist/{chunk-chunk-AZJUDQRM.module.min.js → chunk-chunk-L6EA5V3G.module.min.js} +1 -1
  29. package/dist/{chunk-chunk-SANERMIZ.module.min.js → chunk-chunk-LJLS6DY7.module.min.js} +1 -1
  30. package/dist/chunk-chunk-LJPCLYSC.module.min.js +2 -0
  31. package/dist/chunk-chunk-LRIFN2HK.module.min.js +1 -0
  32. package/dist/chunk-chunk-N5DDKCCF.module.min.js +1 -0
  33. package/dist/chunk-chunk-NEVE562N.module.min.js +1 -0
  34. package/dist/chunk-chunk-NLO44TOS.module.min.js +2 -0
  35. package/dist/{chunk-chunk-FYY2ACNJ.module.min.js → chunk-chunk-PRDGLMJT.module.min.js} +1 -1
  36. package/dist/chunk-chunk-PZJ2SBLL.module.min.js +2 -0
  37. package/dist/chunk-chunk-QUJ6TTLY.module.min.js +1 -0
  38. package/dist/chunk-chunk-RBIDBUT4.module.min.js +2 -0
  39. package/dist/chunk-chunk-RFLAG356.module.min.js +1 -0
  40. package/dist/chunk-chunk-RPU4IZAV.module.min.js +2 -0
  41. package/dist/chunk-chunk-SKMBCFIL.module.min.js +2 -0
  42. package/dist/chunk-chunk-TAE7W424.module.min.js +2 -0
  43. package/dist/{chunk-chunk-OQTLSTGI.module.min.js → chunk-chunk-TMWIZL3K.module.min.js} +1 -1
  44. package/dist/chunk-chunk-TUBMTZMU.module.min.js +2 -0
  45. package/dist/chunk-chunk-UFFEXJQY.module.min.js +1 -0
  46. package/dist/chunk-chunk-XSCHTS4D.module.min.js +2 -0
  47. package/dist/chunk-chunk-XXWSHGPL.module.min.js +2 -0
  48. package/dist/chunk-chunk-ZOAQDIJO.module.min.js +1 -0
  49. package/dist/chunk-chunk-ZXIXAPRE.module.min.js +2 -0
  50. package/dist/chunk-minimapBrushOverlay-JU57U7NM.module.min.js +2 -0
  51. package/dist/chunk-scatterplotMatrixBrushOverlay-SDIZSN66.module.min.js +2 -0
  52. package/dist/chunk-statisticalOverlays-QGDLRUHX.module.min.js +1 -0
  53. package/dist/chunk-statisticalOverlays-T77OKLDY.module.min.js +1 -0
  54. package/dist/components/ChartContainer.d.ts +12 -2
  55. package/dist/components/ai/chartCapabilities.d.ts +2 -1
  56. package/dist/components/ai/chartCapabilityTypes.d.ts +19 -0
  57. package/dist/components/chartContainerDataAudit.d.ts +10 -0
  58. package/dist/components/charts/geo/ChoroplethMap.d.ts +2 -0
  59. package/dist/components/charts/geo/DistanceCartogram.d.ts +35 -5
  60. package/dist/components/charts/geo/FlowMap.d.ts +4 -0
  61. package/dist/components/charts/geo/ProportionalSymbolMap.d.ts +3 -1
  62. package/dist/components/charts/index.d.ts +1 -0
  63. package/dist/components/charts/network/ForceDirectedGraph.d.ts +36 -1
  64. package/dist/components/charts/physics/CollisionSwarmChart.d.ts +6 -1
  65. package/dist/components/charts/physics/CrucibleChart.capability.d.ts +8 -0
  66. package/dist/components/charts/physics/CrucibleChart.d.ts +63 -0
  67. package/dist/components/charts/physics/GaltonBoardChart.d.ts +6 -1
  68. package/dist/components/charts/physics/crucibleBodyRenderers.d.ts +27 -0
  69. package/dist/components/charts/physics/crucibleChartProps.d.ts +90 -0
  70. package/dist/components/charts/physics/crucibleChrome.d.ts +47 -0
  71. package/dist/components/charts/physics/crucibleController.d.ts +59 -0
  72. package/dist/components/charts/physics/crucibleEffects.d.ts +30 -0
  73. package/dist/components/charts/physics/cruciblePhysics.d.ts +54 -0
  74. package/dist/components/charts/physics/crucibleProgram.d.ts +38 -0
  75. package/dist/components/charts/physics/crucibleTypes.d.ts +415 -0
  76. package/dist/components/charts/physics/gauntletChartProps.d.ts +7 -1
  77. package/dist/components/charts/physics/gauntletChrome.d.ts +2 -1
  78. package/dist/components/charts/physics/gauntletPhysics.d.ts +19 -4
  79. package/dist/components/charts/physics/gauntletRuntime.d.ts +3 -0
  80. package/dist/components/charts/physics/physicsHocUtils.d.ts +12 -0
  81. package/dist/components/charts/shared/chartMode.d.ts +8 -0
  82. package/dist/components/charts/shared/chartSpecCore.d.ts +10 -2
  83. package/dist/components/charts/shared/crucibleWireSchema.d.ts +5 -0
  84. package/dist/components/charts/shared/diagnoseTypes.d.ts +10 -0
  85. package/dist/components/charts/shared/hatchPattern.d.ts +8 -3
  86. package/dist/components/charts/shared/knownChartComponents.d.ts +1 -1
  87. package/dist/components/charts/shared/lineSeriesSsr.d.ts +55 -0
  88. package/dist/components/charts/shared/types.d.ts +2 -2
  89. package/dist/components/charts/shared/validateProps.d.ts +1 -1
  90. package/dist/components/charts/xy/AreaChart.d.ts +10 -0
  91. package/dist/components/charts/xy/minimapBrushOverlay.d.ts +17 -0
  92. package/dist/components/charts/xy/minimapBrushOverlayLazy.d.ts +4 -0
  93. package/dist/components/charts/xy/scatterplotMatrixBrushOverlay.d.ts +8 -0
  94. package/dist/components/charts/xy/scatterplotMatrixBrushOverlayLazy.d.ts +3 -0
  95. package/dist/components/data/auditData.d.ts +51 -0
  96. package/dist/components/data/dataAuditPresentation.d.ts +18 -0
  97. package/dist/components/data/dataAuditSources.d.ts +9 -0
  98. package/dist/components/data/numericContracts.d.ts +59 -0
  99. package/dist/components/data/numericFieldProfiler.d.ts +23 -0
  100. package/dist/components/realtime/types.d.ts +5 -0
  101. package/dist/components/recipes/gridObservatory.d.ts +176 -0
  102. package/dist/components/recipes/netEnsembleLayout.d.ts +167 -0
  103. package/dist/components/recipes/netEnsembleOverlays.d.ts +20 -0
  104. package/dist/components/recipes/recipeChrome.d.ts +24 -0
  105. package/dist/components/recipes/sequenceLayout.d.ts +139 -0
  106. package/dist/components/recipes/wordTrails.d.ts +156 -0
  107. package/dist/components/recipes/wordTrailsProgressiveReveal.d.ts +42 -0
  108. package/dist/components/semiotic-ai-core.d.ts +3 -0
  109. package/dist/components/semiotic-ai-data-audit.d.ts +4 -0
  110. package/dist/components/semiotic-ai.d.ts +7 -5
  111. package/dist/components/semiotic-physics.d.ts +1 -0
  112. package/dist/components/semiotic-recipes-core.d.ts +10 -2
  113. package/dist/components/semiotic-utils-core.d.ts +3 -0
  114. package/dist/components/semiotic.d.ts +1 -1
  115. package/dist/components/server/renderEvidence.d.ts +27 -0
  116. package/dist/components/server/serverChartConfigs.d.ts +1 -0
  117. package/dist/components/server/serverChartConfigsPhysics.d.ts +9 -0
  118. package/dist/components/server/staticAnnotations.d.ts +15 -1
  119. package/dist/components/stream/GeoPipelineStore.d.ts +1 -0
  120. package/dist/components/stream/GeoSVGOverlay.d.ts +7 -0
  121. package/dist/components/stream/SceneToSVG.d.ts +6 -6
  122. package/dist/components/stream/SceneToSVGOrdinal.d.ts +12 -0
  123. package/dist/components/stream/geoCartogram.d.ts +7 -0
  124. package/dist/components/stream/geoTypes.d.ts +17 -2
  125. package/dist/components/stream/networkFrameHandleTypes.d.ts +4 -0
  126. package/dist/components/stream/networkFramePaint.d.ts +2 -0
  127. package/dist/components/stream/physics/PhysicsPipelineStore.d.ts +18 -2
  128. package/dist/components/stream/physics/PhysicsSettledSVG.d.ts +8 -0
  129. package/dist/components/stream/physics/physicsBodyCanvas.d.ts +7 -0
  130. package/dist/components/stream/physics/physicsPipelineEviction.d.ts +15 -0
  131. package/dist/components/stream/physics/physicsPipelineObservations.d.ts +1 -1
  132. package/dist/components/stream/physics/physicsPipelineQuiescence.d.ts +20 -0
  133. package/dist/components/stream/sceneToSVGShared.d.ts +30 -1
  134. package/dist/components/stream/types.d.ts +4 -0
  135. package/dist/components/stream/useHydration.d.ts +7 -1
  136. package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +1 -1
  137. package/dist/components/useChartContainerDataAudit.d.ts +7 -0
  138. package/dist/forceLayoutWorker.js +1 -1
  139. package/dist/geo.min.js +1 -1
  140. package/dist/geo.module.min.js +1 -1
  141. package/dist/network.min.js +1 -1
  142. package/dist/network.module.min.js +1 -1
  143. package/dist/ordinal.min.js +1 -1
  144. package/dist/ordinal.module.min.js +1 -1
  145. package/dist/physics.min.js +1 -1
  146. package/dist/physics.module.min.js +1 -1
  147. package/dist/physicsWorker.js +1 -1
  148. package/dist/realtime.min.js +1 -1
  149. package/dist/realtime.module.min.js +1 -1
  150. package/dist/rough.min.js +1 -1
  151. package/dist/rough.module.min.js +1 -1
  152. package/dist/semiotic-ai-core.d.ts +3 -0
  153. package/dist/semiotic-ai-core.min.js +1 -1
  154. package/dist/semiotic-ai-core.module.min.js +1 -1
  155. package/dist/semiotic-ai.d.ts +7 -5
  156. package/dist/semiotic-ai.min.js +1 -1
  157. package/dist/semiotic-ai.module.min.js +1 -1
  158. package/dist/semiotic-experimental.min.js +1 -1
  159. package/dist/semiotic-experimental.module.min.js +1 -1
  160. package/dist/semiotic-physics.d.ts +1 -0
  161. package/dist/semiotic-realtime-core.min.js +1 -1
  162. package/dist/semiotic-realtime-core.module.min.js +1 -1
  163. package/dist/semiotic-recipes-core.d.ts +10 -2
  164. package/dist/semiotic-recipes-core.min.js +1 -1
  165. package/dist/semiotic-recipes-core.module.min.js +1 -1
  166. package/dist/semiotic-recipes.min.js +1 -1
  167. package/dist/semiotic-recipes.module.min.js +1 -1
  168. package/dist/semiotic-server-edge.min.js +1 -1
  169. package/dist/semiotic-server-edge.module.min.js +1 -1
  170. package/dist/semiotic-server-node.min.js +1 -1
  171. package/dist/semiotic-server-node.module.min.js +1 -1
  172. package/dist/semiotic-utils-core.d.ts +3 -0
  173. package/dist/semiotic-utils-core.min.js +1 -1
  174. package/dist/semiotic-utils-core.module.min.js +1 -1
  175. package/dist/semiotic-utils.min.js +1 -1
  176. package/dist/semiotic-utils.module.min.js +1 -1
  177. package/dist/semiotic-value.module.min.js +1 -1
  178. package/dist/semiotic.d.ts +1 -1
  179. package/dist/semiotic.min.js +1 -1
  180. package/dist/semiotic.module.min.js +1 -1
  181. package/dist/server.min.js +1 -1
  182. package/dist/server.module.min.js +1 -1
  183. package/dist/xy.min.js +1 -1
  184. package/dist/xy.module.min.js +1 -1
  185. package/package.json +4 -3
  186. package/dist/chunk-chunk-255KDHW5.module.min.js +0 -1
  187. package/dist/chunk-chunk-2CCFBTQC.module.min.js +0 -2
  188. package/dist/chunk-chunk-2RXP3FS3.module.min.js +0 -1
  189. package/dist/chunk-chunk-2WVCH4PL.module.min.js +0 -1
  190. package/dist/chunk-chunk-4TMZXLCR.module.min.js +0 -1
  191. package/dist/chunk-chunk-5APBQXZA.module.min.js +0 -1
  192. package/dist/chunk-chunk-6HSGDMTA.module.min.js +0 -2
  193. package/dist/chunk-chunk-7OEOSCBP.module.min.js +0 -1
  194. package/dist/chunk-chunk-A63CTACR.module.min.js +0 -2
  195. package/dist/chunk-chunk-B6V35LMY.module.min.js +0 -2
  196. package/dist/chunk-chunk-BOSVL645.module.min.js +0 -2
  197. package/dist/chunk-chunk-CP3EN6KZ.module.min.js +0 -1
  198. package/dist/chunk-chunk-F25UA5HT.module.min.js +0 -1
  199. package/dist/chunk-chunk-FRIO6MCV.module.min.js +0 -1
  200. package/dist/chunk-chunk-GWSWSPXN.module.min.js +0 -1
  201. package/dist/chunk-chunk-I6C3KR5H.module.min.js +0 -2
  202. package/dist/chunk-chunk-IP2UE74X.module.min.js +0 -1
  203. package/dist/chunk-chunk-J3ELI22J.module.min.js +0 -1
  204. package/dist/chunk-chunk-J5RL6GXU.module.min.js +0 -2
  205. package/dist/chunk-chunk-L3H6DQCR.module.min.js +0 -2
  206. package/dist/chunk-chunk-M337NY6L.module.min.js +0 -1
  207. package/dist/chunk-chunk-M7VYYHCE.module.min.js +0 -2
  208. package/dist/chunk-chunk-MC35ILYP.module.min.js +0 -2
  209. package/dist/chunk-chunk-N72SWNBV.module.min.js +0 -1
  210. package/dist/chunk-chunk-OBQRFTIL.module.min.js +0 -2
  211. package/dist/chunk-chunk-QRIBHZYW.module.min.js +0 -1
  212. package/dist/chunk-chunk-SA3D43RA.module.min.js +0 -2
  213. package/dist/chunk-chunk-UHSZEB74.module.min.js +0 -1
  214. package/dist/chunk-chunk-Y6AXCRVO.module.min.js +0 -1
  215. package/dist/chunk-chunk-ZCNBUZPL.module.min.js +0 -2
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{bandFromAge as t,defaultTooltipStyle as e,normalizeTooltip as n,opacityFromAge as r,resolveCanvasFill as o}from"./chunk-chunk-CWQ5YIHX.module.min.js";import{drawGlyphParts as a,glyphFractionClipRect as s,glyphHitGeometry as l,glyphPlacement as c}from"./chunk-chunk-KTWEBFMX.module.min.js";function i(t,e){const n={...t};return e.provenance&&(n.provenance=e.provenance),e.lifecycle&&(n.lifecycle=e.lifecycle),n}function u(){return(new Date).toISOString()}function f(t,e={}){const n=t.provenance;return{...t,provenance:{...n,...e,createdAt:e.createdAt??n?.createdAt??u()}}}function d(t){if(null==t)return null;if("number"==typeof t)return t;if(t instanceof Date)return t.getTime();const e=Date.parse(t);return Number.isFinite(e)?e:null}function p(t){const e=d(t?.now);if(null!=e)return e;const n=t?.dataExtent;if(n)if(Array.isArray(n)){const t=d(n[n.length-1]);if(null!=t)return t}else if("max"in n){const t=d(n.max);if(null!=t)return t}return Date.now()}function h(e,n,r={}){const o=e?.lifecycle?.freshness,a=d(e?.provenance?.createdAt),s=function(t){if(null==t)return null;if("number"==typeof t)return t;const e=function(t){const e=/^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/.exec(t);return e?1e3*(3600*(24*parseInt(e[1]||"0",10)+parseInt(e[2]||"0",10))+60*parseInt(e[3]||"0",10)+parseInt(e[4]||"0",10)):0}(t);return e>0?e:null}(e?.lifecycle?.ttlHint);return null==a||null==s?o??"fresh":t(n-a,s,r)}function y(t,e={}){const n=p(e);return t.map(t=>{const r=h(t,n,e.thresholds);return{...t,lifecycle:{...t.lifecycle,freshness:r}}})}var g={fresh:null,aging:.55,stale:.35,expired:.2},m={fresh:null,aging:null,stale:"4 4",expired:"2 4"};function x(t,e,n){return t&&n in t?t[n]:e[n]}function b(t,e={}){const n=p(e),r=!0===e.showExpiredAnnotations,o=[];for(const a of t){const t=h(a,n,e.thresholds);if("expired"===t&&!r)continue;const s=x(e.opacity,g,t),l=x(e.strokeDasharray,m,t),c=e.labelSuffix?.[t],i={...a,lifecycle:{...a.lifecycle,freshness:t}};null!=s&&null==i.opacity&&(i.opacity=s),null!=l&&null==i.strokeDasharray&&(i.strokeDasharray=l),c&&"string"==typeof i.label&&(i.label=i.label+c);const u=a.lifecycle?.anchor;u&&null==i.anchor&&(i.anchor=u),o.push(i)}return o}var v={proposed:.7,accepted:null,disputed:.7,retracted:.25},w={proposed:"3 3",accepted:null,disputed:"2 3",retracted:"2 4"},A={proposed:" (proposed)",accepted:"",disputed:" (?)",retracted:""};function I(t,e,n){return t&&n in t?t[n]:e[n]}function k(t,e={}){const n=!0===e.showRetractedAnnotations,r=!0===e.showSupersededAnnotations,o=new Set;for(const e of t){const t=e?.lifecycle?.supersedes;t&&"retracted"!==e?.lifecycle?.status&&o.add(t)}return t.filter(t=>{if("retracted"===t?.lifecycle?.status&&!n)return!1;const e=t?.provenance?.stableId;return!(e&&o.has(e)&&!r)})}function _(t,e={}){const n=[];for(const r of k(t,e)){const t=r?.lifecycle?.status;if(!t){n.push(r);continue}const o=I(e.opacity,v,t),a=I(e.strokeDasharray,w,t),s=e.labelSuffix?.[t]??A[t],l={...r};null!=o&&(l.opacity=("number"==typeof l.opacity?l.opacity:1)*o),null!=a&&null==l.strokeDasharray&&(l.strokeDasharray=a),s&&"string"==typeof l.label&&(l.label=l.label+s),n.push(l)}return n}import{jsx as M,jsxs as S}from"react/jsx-runtime";function D(t){return"string"==typeof t?t:"value"}function O(t){return null==t?"–":"number"==typeof t?Math.abs(t)>9999?t.toLocaleString():t+"":t instanceof Date?t.toLocaleDateString():t+""}function E(t,e){if(!e)return O(t);try{const n=e(t);return null==n?O(t):n}catch{return O(t)}}function R(t,e){return"function"==typeof e?e(t):t[e]}function P(t,e){if(!t)return[];const n=[];return(Array.isArray(t)?t:[t]).forEach((t,r)=>{const o="string"==typeof t?.y0Accessor?t.y0Accessor:"low",a="string"==typeof t?.y1Accessor?t.y1Accessor:"high";n.push({label:o,accessor:t=>t.bands?.[r]?.y0??(0===r?t.band?.y0:void 0),format:e}),n.push({label:a,accessor:t=>t.bands?.[r]?.y1??(0===r?t.band?.y1:void 0),format:e})}),n}function j(t){const n=t.find(t=>"title"===t.role),r=t.filter(t=>"title"!==t.role);return t=>{const o=t.data;if(!o)return null;const a=n?E(R(o,n.accessor),n.format):null;return S("div",{className:"semiotic-tooltip",style:e,children:[null!=a&&M("div",{style:{fontWeight:"bold",marginBottom:r.length>0?4:0},children:a}),r.map((t,e)=>{const n=E(R(o,t.accessor),t.format);return S("div",{style:e>0?{marginTop:2}:void 0,children:[S("span",{style:{opacity:.7},children:[t.label,": "]}),M("span",{children:n})]},e)})]})}}function C({categoryAccessor:t,valueAccessor:n,groupAccessor:r,groupLabel:o,pieData:a=!1,valueFormat:s}){return l=>{const c=a?l.data?.[0]||l.data||l:l.data||l,i=R(c,t),u=R(c,n),f=r?R(c,r):void 0;return S("div",{className:"semiotic-tooltip",style:e,children:[M("div",{style:{fontWeight:"bold"},children:O(i)}),M("div",{style:{marginTop:4},children:E(u,s)}),null!=f&&S("div",{style:{marginTop:2,opacity:.8},children:[o||D(r),": ",O(f)]})]})}}import*as T from"react";function L(...t){const e=t.filter(t=>null!=t);return 0===e.length?null:1===e.length?e[0]:T.createElement(T.Fragment,null,...e)}import{useEffect as z,useRef as H}from"react";function $(t,e,n,r){z(()=>{t.current?.updateConfig(e),n.current=!0,r()},[e,r,t,n])}function N(t,e,n,r){const o=H(null);z(()=>{const a=t.current;if(!a)return;const s=e??null;o.current!==s&&(o.current=s,a.setLayoutSelection(s),a.hasCustomRestyle?a.restyleScene(s):n.current=!0,r())},[e,r,t,n])}var W={fresh:1,aging:.7,stale:.45,expired:.25},G={alpha:1,band:"fresh",isStale:!1};function U(e,n){if(!e||0>=n)return G;const r=null!=e.threshold&&e.threshold>0?e.threshold:5e3,o=e.graded;if(o){const e="object"==typeof o?o:{},a=t(n,r,e.thresholds);return{alpha:{...W,...e.opacities??{}}[a],band:a,isStale:"fresh"!==a}}return n>r?{alpha:e.dimOpacity??.5,band:"stale",isStale:!0}:G}import{useEffect as B,useRef as F}from"react";function V(t,e,n,r,o,a){const s=F("fresh");B(()=>{if(!t)return;const l=setInterval(()=>{const l=e.current;if(!l||0===l.lastIngestTime)return;const c="undefined"!=typeof performance?performance.now():Date.now(),i=U(t,c-l.lastIngestTime);i.band===s.current&&i.isStale===o||(s.current=i.band,i.isStale!==o&&a(i.isStale),n.current=!0,r())},1e3);return()=>clearInterval(l)},[t,o,r,e,a,n])}import{jsx as Y}from"react/jsx-runtime";function X({isStale:t,position:e}){return Y("div",{className:"stream-staleness-badge",style:{position:"absolute",..."top-left"===e?{top:4,left:4}:"bottom-left"===e?{bottom:4,left:4}:"bottom-right"===e?{bottom:4,right:4}:{top:4,right:4},padding:"2px 8px",borderRadius:4,fontSize:11,fontWeight:600,pointerEvents:"none",zIndex:3,background:t?"#dc3545":"#28a745",color:"white"},children:t?"STALE":"LIVE"})}import{useRef as K}from"react";function q(t){const e=K(t);return function(t,e){if(Object.is(t,e))return!0;if(Array.isArray(t)&&Array.isArray(e))return J(t,e);if(!Z(t)||!Z(e))return!1;const n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(const r of n){if(!Object.prototype.hasOwnProperty.call(e,r))return!1;const n=t[r],o=e[r];if(!Object.is(n,o))if(Array.isArray(n)&&Array.isArray(o)){if(!J(n,o))return!1}else{if(!Z(n)||!Z(o))return!1;if(!Q(n,o))return!1}}return!0}(e.current,t)||(e.current=t),e.current}function Q(t,e){const n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(const r of n){if(!Object.prototype.hasOwnProperty.call(e,r))return!1;if(!Object.is(t[r],e[r]))return!1}return!0}function J(t,e){if(t.length!==e.length)return!1;for(let n=0;t.length>n;n++)if(!Object.is(t[n],e[n]))return!1;return!0}function Z(t){if(null===t||"object"!=typeof t)return!1;if(Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||null===e}function tt(t,e,n,r,l){if(0>=e.size)return;const i=e.glyph;if(!i||!i.parts?.length)return;const u=c(i,e.size);if(0>=u.scale)return;const f=(e.style.opacity??1)*(e._decayOpacity??1);if(0>=f)return;const d=e=>{const n=o(t,e,e);return"string"==typeof n?n:e},p=e.color??("string"==typeof e.style.fill?e.style.fill:void 0);t.save(),t.translate(n,r),e.rotation&&t.rotate(e.rotation),t.translate(u.offsetX,u.offsetY),t.scale(u.scale,u.scale),t.globalAlpha=l*f*(e.style.fillOpacity??1);const h=s(i,e.fraction??1,e.fractionStart??0,e.fractionDirection??"horizontal");h&&e.ghostColor&&a(t,i,p,e.accent,e.ghostColor,d),h&&(t.beginPath(),t.rect(h.x,h.y,h.width,h.height),t.clip()),a(t,i,p,e.accent,void 0,d),t.restore()}var et=(t,e)=>{const n=t.globalAlpha;for(const r of e)"glyph"===r.type&&tt(t,r,r.x,r.y,n);t.globalAlpha=n};function nt(t,e){const n=t.globalAlpha;for(const r of e)"glyph"===r.type&&tt(t,r,r.cx,r.cy,n);t.globalAlpha=n}var rt=new Set;function ot(t,e){const n="function"==typeof t?t(e.datum??null,e):t;return(r=n)&&"object"==typeof r&&"string"==typeof r.id&&"function"==typeof r.cacheKey&&"function"==typeof r.drawCanvas&&"function"==typeof r.renderStaticSVG?n:void 0;var r}function at(t,e){if("undefined"!=typeof process&&"production"===process.env?.NODE_ENV)return;const n=`${t}:${e}`;rt.has(n)||(rt.add(n),console.warn(`[Semiotic] Render backend "${t}" does not support scene node "${e}"; using the built-in renderer.`))}function st(t){const{context:e,nodes:n,renderMode:r,pixelRatio:o,paintBuiltIn:a}=t;if(!r||"sketchy"===r)return void a(n);let s=[];const l=()=>{s.length&&(a(s),s=[])};for(const t of n){const n=ot(r,t);if(!n){s.push(t);continue}let c;l(),e.save();try{c=n.drawCanvas({context:e,node:t,style:t.style??{},pixelRatio:o})}finally{e.restore()}c||(at(n.id,t.type??"unknown"),a([t]))}l()}function lt(t){const{node:e,index:n,renderMode:r,fallback:o}=t,a=ot(r,e);if(!a)return o();const s=a.renderStaticSVG({node:e,style:e.style??{},key:`${a.id}-${n}`});return null!=s?s:(at(a.id,e.type??"unknown"),o())}function ct(t){const e=new Map;for(const n of t){const t=n.group??"_default";let r=e.get(t);r||(r=[],e.set(t,r)),r.push(n)}for(const t of e.values()){t.sort((t,e)=>t.x-e.x||t.y-e.y);for(let e=0;t.length>e;e++)t[e]._groupIndex=e}const n=Array.from(e.keys()).sort((t,n)=>{const r=e.get(t),o=e.get(n);return(r.length>0?r[0].y:0)-(o.length>0?o[0].y:0)}),r=Array.from(e.values()).flat();r.sort((t,e)=>t.x-e.x||t.y-e.y);const o=new Map;for(let t=0;r.length>t;t++){r[t]._flatIndex=t;const e=r[t].datum?.id;null!=e&&o.set(e+"",t)}return{flat:r,groups:n,byGroup:e,idToIdx:o}}function it(t,e){if(0===t.flat.length)return{flatIndex:-1,group:"_default",indexInGroup:-1};const n=Math.max(0,Math.min(e,t.flat.length-1)),r=t.flat[n];return{flatIndex:n,group:r.group??"_default",indexInGroup:r._groupIndex??0}}function ut(t,e,n){const{group:r,indexInGroup:o}=e,a=n.byGroup.get(r);switch(t){case"ArrowRight":return a.length-1>o?a[o+1]._flatIndex:e.flatIndex;case"ArrowLeft":return o>0?a[o-1]._flatIndex:e.flatIndex;case"ArrowDown":{const t=n.groups.indexOf(r);return n.groups.length-1>t?ft(n,n.groups[t+1],a[o]):e.flatIndex}case"ArrowUp":{const t=n.groups.indexOf(r);return t>0?ft(n,n.groups[t-1],a[o]):e.flatIndex}case"PageDown":return Math.min(e.flatIndex+Math.max(1,Math.floor(.1*n.flat.length)),n.flat.length-1);case"PageUp":return Math.max(e.flatIndex-Math.max(1,Math.floor(.1*n.flat.length)),0);case"Home":return 0;case"End":return n.flat.length-1;case"Escape":return-1;default:return null}}function ft(t,e,n){const r=t.byGroup.get(e);let o=0,a=Math.abs(r[0].x-n.x);for(let t=1;r.length>t;t++){const e=Math.abs(r[t].x-n.x);a>e&&(a=e,o=t)}return r[o]._flatIndex}function dt(t){const e=[];for(const n of t)switch(n.type){case"point":e.push({x:n.x,y:n.y,datum:n.datum,shape:"circle",group:"_default"});break;case"symbol":if(0>=n.size)break;e.push({x:n.x,y:n.y,datum:n.datum,shape:"circle",group:"_default"});break;case"glyph":{if(0>=n.size||null==n.datum)break;const t=l(n.glyph,n.size);e.push({x:n.x+t.centerDx,y:n.y+t.centerDy,datum:n.datum,shape:"rect",w:2*t.halfWidth,h:2*t.halfHeight,group:"_default"});break}case"line":{const t=n,r=Array.isArray(t.datum)?t.datum:[],o=t.group??"_default";for(let n=0;t.path.length>n&&r.length>n;n++)e.push({x:t.path[n][0],y:t.path[n][1],datum:r[n],shape:"circle",group:o});break}case"area":{const t=n,r=Array.isArray(t.datum)?t.datum:[],o=t.group??"_default";for(let n=0;t.topPath.length>n&&r.length>n;n++)e.push({x:t.topPath[n][0],y:t.topPath[n][1],datum:r[n],shape:"circle",group:o});break}case"rect":e.push({x:n.x+n.w/2,y:n.y+n.h/2,datum:n.datum,shape:"rect",w:n.w,h:n.h,group:n.group??"_default"});break;case"heatcell":e.push({x:n.x+n.w/2,y:n.y+n.h/2,datum:n.datum,shape:"rect",w:n.w,h:n.h,group:"_default"})}return e.sort((t,e)=>t.x-e.x||t.y-e.y),e}function pt(t){const e=[];for(const n of t)if("rect"===n.type&&null!=n.x){if(null==n.datum)continue;e.push({x:n.x+n.w/2,y:n.y+n.h/2,datum:n.datum,shape:"rect",w:n.w,h:n.h,group:n.group??n.datum?.category??""})}else if("point"===n.type)e.push({x:n.x,y:n.y,datum:n.datum,shape:"circle",group:"_default"});else if("symbol"===n.type){if(0>=n.size)continue;e.push({x:n.x,y:n.y,datum:n.datum,shape:"circle",group:"_default"})}else if("glyph"===n.type){if(0>=n.size||null==n.datum)continue;const t=l(n.glyph,n.size);e.push({x:n.x+t.centerDx,y:n.y+t.centerDy,datum:n.datum,shape:"rect",w:2*t.halfWidth,h:2*t.halfHeight,group:"_default"})}else if("wedge"===n.type&&null!=n.cx){if(null===n.datum)continue;const t=((n.startAngle||0)+(n.endAngle||0))/2,r=((n.innerRadius||0)+(n.outerRadius||50))/2;e.push({x:n.cx+Math.cos(t)*r,y:n.cy+Math.sin(t)*r,datum:n.datum,shape:"wedge",group:"_default"})}return e.sort((t,e)=>t.x-e.x||t.y-e.y),e}function ht(t){const e=[];for(const n of t)if("circle"===n.type&&null!=n.cx){if(0>=n.r)continue;e.push({x:n.cx,y:n.cy,datum:n.datum,shape:"circle",group:n.datum?.id??"_default"})}else if("rect"===n.type&&null!=n.x){if(0>=n.w||0>=n.h)continue;e.push({x:n.x+n.w/2,y:n.y+n.h/2,datum:n.datum,shape:"rect",w:n.w,h:n.h,group:n.datum?.id??"_default"})}else if("arc"===n.type&&null!=n.cx)e.push({x:n.cx,y:n.cy,datum:n.datum,shape:"circle",group:n.datum?.id??"_default"});else if("symbol"===n.type&&null!=n.cx){if(0>=n.size)continue;e.push({x:n.cx,y:n.cy,datum:n.datum,shape:"circle",group:n.datum?.id??"_default"})}else if("glyph"===n.type&&null!=n.cx){if(0>=n.size||null==n.datum)continue;const t=l(n.glyph,n.size);e.push({x:n.cx+t.centerDx,y:n.cy+t.centerDy,datum:n.datum,shape:"rect",w:2*t.halfWidth,h:2*t.halfHeight,group:n.datum?.id??"_default"})}return e.sort((t,e)=>t.x-e.x||t.y-e.y),e}function yt(t,e,n,r,o){const a=n.flat[e.flatIndex];if(!a)return ut(t,e,n);const s=a.datum?.id;switch(t){case"ArrowRight":case"ArrowLeft":case"ArrowDown":case"ArrowUp":{const r=function(t,e,n){let r=null,o=1/0;for(let a=0;t.flat.length>a;a++){const s=t.flat[a];if(s===e)continue;const l=s.x-e.x,c=s.y-e.y;let i=!1;switch(n){case"right":i=l>0&&Math.abs(l)>=Math.abs(c);break;case"left":i=0>l&&Math.abs(l)>=Math.abs(c);break;case"down":i=c>0&&Math.abs(c)>=Math.abs(l);break;case"up":i=0>c&&Math.abs(c)>=Math.abs(l)}if(!i)continue;const u=l*l+c*c;o>u&&(o=u,r=a)}return r}(n,a,"ArrowRight"===t?"right":"ArrowLeft"===t?"left":"ArrowDown"===t?"down":"up")??e.flatIndex;return r!==e.flatIndex&&(o.current=-1),r}case"Enter":{if(null==s)return e.flatIndex;const t=function(t,e){const n=t+"",r=[];for(const t of e){const e=t.datum??t,o=gt(e.source),a=gt(e.target),s=null!=o,l=null!=a;s&&o+""===n&&l?r.push(a+""):l&&a+""===n&&s&&r.push(o+"")}return r}(s,r);if(0===t.length)return e.flatIndex;const a=n.idToIdx.get(t[(o.current+1)%t.length])??-1;return 0>a?e.flatIndex:(o.current=-1,a)}default:{const r=ut(t,e,n);return null!==r&&r!==e.flatIndex&&(o.current=-1),r}}}function gt(t){return"object"==typeof t&&null!==t&&"id"in t?t.id:t}function mt(t){const e=[];for(const n of t)if("point"===n.type&&null!=n.x)e.push({x:n.x,y:n.y,datum:n.datum,shape:"circle"});else if("glyph"===n.type){if(0>=n.size||null==n.datum)continue;const t=l(n.glyph,n.size);e.push({x:n.x+t.centerDx,y:n.y+t.centerDy,datum:n.datum,shape:"rect",w:2*t.halfWidth,h:2*t.halfHeight})}else"geoarea"===n.type&&n.centroid&&!1!==n.interactive&&e.push({x:n.centroid[0],y:n.centroid[1],datum:n.datum,shape:"geoarea",pathData:n.pathData});return e.sort((t,e)=>t.x-e.x||t.y-e.y),e}function xt(t,e,n){switch(t){case"ArrowRight":case"ArrowDown":return n-1>e?e+1:e;case"ArrowLeft":case"ArrowUp":return e>0?e-1:e;case"PageDown":return Math.min(e+Math.max(1,Math.floor(.1*n)),n-1);case"PageUp":return Math.max(e-Math.max(1,Math.floor(.1*n)),0);case"Home":return 0;case"End":return n-1;case"Escape":return-1;default:return null}}function bt(t){return{data:t.datum||{},x:t.x,y:t.y,__semioticHoverData:!0}}function vt(t){const{title:e,description:n,summary:r,accessibleTable:o,className:a,animate:s,axisExtent:l,autoPlaceAnnotations:c}=t,i={};return e&&(i.title=e),n&&(i.description=n),r&&(i.summary=r),void 0!==o&&(i.accessibleTable=o),a&&(i.className=a),null!=s&&(i.animate=s),void 0!==l&&(i.axisExtent=l),void 0!==c&&(i.autoPlaceAnnotations=c),i}function wt(t){const{linkedHover:e,selection:n,onObservation:r,onClick:o,hoverRadius:a,hoverHighlight:s,forceHoverBehavior:l,forceClickBehavior:c,mobileInteraction:i,customHoverBehavior:u,customClickBehavior:f,linkedHoverInClickPredicate:d=!0}=t,p={};r&&(p.annotationObservationCallback=r);const h=i?.enabled?Math.max(a??30,Math.ceil((i.targetSize||44)/2),24):a;return(l||e||r||o||s)&&(p.customHoverBehavior=u),f&&(c||(d?r||o||e:r||o)||i?.enabled&&(i.tapToSelect||i.tapToLockTooltip)&&(e||s||n))&&(p.customClickBehavior=f),null!=h&&(p.hoverRadius=h),p}function At(t){const{tooltip:e,defaultTooltipContent:r}=t;return{tooltipContent:!1===e?()=>null:n(e)||r}}function It(t,e,n){if(1>=n)return 1;const o=n-1;return r({age:o-e,extent:o,type:t.type,halfLife:t.halfLife??n/2,threshold:t.stepThreshold??.5*n,minOpacity:t.minOpacity??.1})}function kt(t){const e=new Map;for(let n=0;t.length>n;n++)e.set(t[n],n);return e}function _t(t,e,n,r=kt(n)){const o=n.length;if(o>1)for(const n of e){if("line"===n.type){const e=Array.isArray(n.datum)?n.datum:[];if(2>e.length)continue;const a=Array(e.length);let s=!1;for(let n=0;e.length>n;n++){const l=r.get(e[n]);null!=l?(a[n]=It(t,l,o),1>a[n]&&(s=!0)):a[n]=1}s&&(n._decayOpacities=a);continue}if("area"===n.type){const e=Array.isArray(n.datum)?n.datum:[],a=n.topPath?n.topPath.length:e.length;if(2>a)continue;if(e.length===a){const s=Array(a);let l=!1;for(let n=0;e.length>n;n++){const a=r.get(e[n]);null!=a?(s[n]=It(t,a,o),1>s[n]&&(l=!0)):s[n]=1}l&&(n._decayOpacities=s)}else{let s=1;for(const n of e){const e=r.get(n);if(null!=e){const n=It(t,e,o);s>n&&(s=n)}}if(1>s){const t=Array(a);t.fill(s),n._decayOpacities=t}}continue}const e=r.get(n.datum);if(null==e)continue;const a=It(t,e,o);"heatcell"===n.type?n.style={opacity:a}:"candlestick"===n.type?n._decayOpacity=a:n.style={...n.style,opacity:(n.style?.opacity??1)*a}}}function Mt(t){if("production"===process.env.NODE_ENV)return;const{label:e,nodes:n,overlays:r,warned:o}=t;St(r)&&0===n.length&&Dt(o,"overlay-only",`[semiotic] ${e} returned overlays but no data-bearing scene nodes. Overlays do not participate in hover, selection, transitions, SSR evidence, or accessibility tables. Emit at least one scene node with a datum, or mark the overlay-only chart as intentionally decorative.`),n.length>0&&n.every(t=>null==t.datum)&&Dt(o,"null-datums",`[semiotic] ${e} returned scene nodes, but every scene-node datum is null. Hover, callbacks, selection, and tooltip helpers need data-bearing nodes. Attach a user-facing datum to each interactive node, or set interactive overlays outside the chart.`)}function St(t){return null!=t&&!1!==t&&""!==t&&(!Array.isArray(t)||t.some(St))}function Dt(t,e,n){t.has(e)||(t.add(e),console.warn(n))}function Ot(t,e,n,r){const o=function(t){if(t instanceof Error)return{name:t.name||"Error",message:t.message||"Custom layout threw."};if("string"==typeof t)return{name:"Error",message:t};if(null==t)return{name:"Error",message:"Custom layout threw a nullish value."};try{return{name:"Error",message:t+""}}catch{return{name:"Error",message:"Custom layout threw a non-stringifiable value."}}}(e),a="network"===t?"customNetworkLayout":"customLayout";return{code:"CUSTOM_LAYOUT_ERROR",severity:"error",phase:"layout",component:t,source:a,message:`Semiotic ${t} ${a} failed: ${o.message}`,error:o,recovery:n?"preserved-last-good-scene":"empty-scene",preservedLastGoodScene:n,affectedRevision:r}}var Et=new WeakMap;function Rt(){return this.updateResults.last}function Pt(){return this.updateResults.last}function jt(t){return this.updateResults.subscribe(t)}function Ct(t){this.config.layoutSelection=t}function Tt(){Et.set(this,!0)}function Lt(){const t=!0===Et.get(this);return Et.delete(this),t}function zt(t){Object.assign(t.prototype,{getLastUpdateResult:Rt,getUpdateSnapshot:Pt,subscribeUpdateResult:jt,setLayoutSelection:Ct,markStylePaintPending:Tt,consumeStylePaintPending:Lt})}function Ht(t,e,n){return n.x>t||t>n.x+n.w||n.y>e||e>n.y+n.h?{hit:!1,cx:0,cy:0}:{hit:!0,cx:n.x+n.w/2,cy:n.y+n.h/2}}function $t(t,e=30){return Math.max((t??4)+5,12,e)}function Nt(t){return t instanceof Date?t:"number"==typeof t&&t>1e9?new Date(t):null}function Wt(t,e){const n=Nt(t);if(!n)return!1;const r=Nt(e);return!r||n.getFullYear()!==r.getFullYear()||n.getMonth()!==r.getMonth()}function Gt(t){let e=t%(2*Math.PI);return 0>e&&(e+=2*Math.PI),e}function Ut(t,e,n,r,o,a=t=>t.x,s=t=>t.y,l=t=>t.r){const c=Math.max(r,o+5,12),i=e-c,u=e+c,f=n-c,d=n+c;let p=null,h=1/0;return t.visit((t,o,c,y,g)=>{if(o>u||i>y||c>d||f>g)return!0;if(!t.length){let o=t;do{const t=o.data,c=a(t)-e,i=s(t)-n,u=Math.sqrt(c*c+i*i);$t(l(t),r)>=u&&h>u&&(p=t,h=u),o=o.next}while(o)}return!1}),p?{node:p,distance:h}:null}function Bt(t){return!(!t._pulseIntensity||0>=t._pulseIntensity)}function Ft(t,e,n=.3){Bt(e)&&(t.globalAlpha=e._pulseIntensity*n,t.fillStyle=e._pulseColor||"rgba(255,255,255,0.6)",t.fillRect(e.x,e.y,e.w,e.h))}function Vt(t,e,n=.6){if(!Bt(e))return;const r=e.r+(e._pulseGlowRadius??4)*e._pulseIntensity,o=e.cx??e.x??0,a=e.cy??e.y??0;t.beginPath(),t.arc(o,a,r,0,2*Math.PI),t.strokeStyle=e._pulseColor||"rgba(255,255,255,0.6)",t.lineWidth=2*e._pulseIntensity,t.globalAlpha=e._pulseIntensity*n,t.stroke()}function Yt(t,e,n,r=.35){Bt(e)&&(t.globalAlpha=e._pulseIntensity*r,t.fillStyle=e._pulseColor||"rgba(255,255,255,0.6)",n?t.fill(n):t.fill())}export{It as computeDecayOpacity,kt as buildDatumIndexMap,_t as applyDecay,Mt as warnCustomLayoutDiagnostics,Ot as createCustomLayoutFailureDiagnostic,zt as attachUpdateResultStore,L as composeOverlays,$ as useConfigSync,N as useLayoutSelectionSync,Ht as hitTestRect,$t as getHitRadius,Wt as isTimeLandmark,Gt as normalizeAngle,Ut as findHitPointInQuadtree,U as resolveStaleness,V as useStalenessCheck,X as StalenessBadge,i as withProvenance,u as currentTimestamp,f as withCurrentProvenance,h as annotationFreshnessFor,y as computeAnnotationFreshness,b as applyAnnotationLifecycle,k as filterAnnotationsByStatus,_ as applyAnnotationStatus,q as useStableShallow,Ft as renderRectPulse,Vt as renderCirclePulse,Yt as renderPathPulse,et as glyphCanvasRenderer,nt as networkGlyphRenderer,st as paintSceneWithBackend,lt as renderSceneWithBackend,D as accessorName,O as formatVal,P as bandTooltipFields,j as buildDefaultTooltip,C as buildOrdinalTooltip,ct as buildNavGraph,it as resolvePosition,ut as nextGraphIndex,dt as extractXYNavPoints,pt as extractOrdinalNavPoints,ht as extractNetworkNavPoints,yt as nextNetworkIndex,mt as extractGeoNavPoints,xt as nextIndex,bt as navPointToHover,vt as buildBaseMetadataProps,wt as buildCustomBehaviorProps,At as buildTooltipProps};
@@ -0,0 +1 @@
1
+ import{commonJsWorkerModuleUrl as e}from"./chunk-chunk-SV4XAZ3Q.module.min.js";import{resolveNodeSizeFn as r}from"./chunk-chunk-C4YA6TDR.module.min.js";function t(e,r,t,o,n=4e4){return"sync"!==e&&("worker"===e||o*(r+t)>=n)}function o(){return"undefined"!=typeof window&&"undefined"!=typeof Worker}function n(e,t,o,n,i){const s=r(o.nodeSize,o.nodeSizeRange,e);return{kind:"frame",nodes:e.map(e=>{const r=i?.get(e.id);return{id:e.id,x:0!==e.x||0!==e.y?e.x:r?.x??0,y:0!==e.x||0!==e.y?e.y:r?.y??0,x0:0,x1:0,y0:0,y1:0,width:0,height:0,value:e.value,__forceRadius:s(e)}}),edges:t.map(e=>{const r="string"==typeof e.source?e.source:e.source.id,t="string"==typeof e.target?e.target:e.target.id,o=e.data?.weight,n="number"==typeof o&&Number.isFinite(o)?o:e.value;return{source:r,target:t,value:e.value,y0:0,y1:0,sankeyWidth:0,weight:n}}),config:{chartType:"force",iterations:o.iterations,forceStrength:o.forceStrength,seed:o.seed},size:n}}function i(){if("undefined"!=typeof DOMException)return new DOMException("Force layout aborted","AbortError");const e=Error("Force layout aborted");return e.name="AbortError",e}var s=class{constructor(r=function(){const r="string"==typeof import.meta.url&&import.meta.url?new URL("./forceLayoutWorker.js",import.meta.url):e("forceLayoutWorker.js");return new Worker(r,{type:"module",name:"semiotic-force-layout"})}()){this.nextRequestId=1,this.pending=new Map,this.dead=!1,this.worker=r,this.worker.onmessage=e=>{const r=e.data,t=r.requestId,o=null!=t?this.pending.get(t):this.pending.values().next().value;if(o){if(null!=t?this.pending.delete(t):this.pending.clear(),o.cleanup(),r.error){const e=Error(r.error.message);return e.name=r.error.name??"Error",r.error.stack&&(e.stack=r.error.stack),void o.reject(e)}o.resolve({positions:r.positions??{}})}},this.worker.onerror=e=>{this.rejectAll(Error(e.message||"Force layout worker failed")),this.terminate()}}get isDead(){return this.dead}request(e,r){if(this.dead)return Promise.reject(Error("Force layout worker session is closed"));if(r?.aborted)return Promise.reject(i());const t=this.nextRequestId;this.nextRequestId+=1;const o={requestId:t,request:e};return new Promise((e,n)=>{const s=()=>{this.pending.delete(t),r?.removeEventListener("abort",s),n(i())},a=()=>r?.removeEventListener("abort",s);this.pending.set(t,{cleanup:a,reject:n,resolve:e}),r?.addEventListener("abort",s,{once:!0});try{this.worker.postMessage(o)}catch(e){this.pending.delete(t),a(),n(e instanceof Error?e:Error(e+""))}})}terminate(){this.dead||(this.dead=!0,this.rejectAll(Error("Force layout worker terminated")),this.worker.terminate())}rejectAll(e){for(const r of this.pending.values())r.cleanup(),r.reject(e);this.pending.clear()}},a=null;function u(e,r){return o()?r?.aborted?Promise.reject(i()):(a&&!a.isDead||(a=new s),a).request(e,r):Promise.reject(Error("Web Workers are unavailable"))}export{t as shouldUseForceWorker,o as canUseForceWorker,n as createFrameForceWorkerRequest,u as runForceLayoutWorker};
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ var t=/^\d{4}-\d{1,2}$/;function e(e){const n=e.trim();if(!n||!Number.isNaN(Number(n)))return NaN;const r=t.test(n)?n+"-01":n;if(r===n&&10>n.length)return NaN;const i=Date.parse(r);return Number.isFinite(i)?i:NaN}function n(t){return t instanceof Date?t.getTime():"string"==typeof t?e(t):+t}export{e as parseDateLikeString,n as coerceDateLikeValue};
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{useRef as t,useEffect as r}from"react";import{brushX as e,brushY as n}from"d3-brush";import{select as o}from"d3-selection";import{jsx as l}from"react/jsx-runtime";function u({width:u,height:s,margin:c,scales:i,brushDirection:f,extent:a,onBrush:h}){const m=t(null),p=t(null),b=t(!1),x=u+c.left+c.right,d=s+c.top+c.bottom;return r(()=>{if(!m.current||!i)return;const t=o(m.current).select(".brush-group"),r="x"===f?e().extent([[0,0],[u,s]]):n().extent([[0,0],[u,s]]);return r.on("brush end",t=>{if(b.current)return;if(!t.sourceEvent)return;const r=t.selection;if(!r)return void h(null);const e=("x"===f?i.x:i.y).invert;if(!e)return;const n=[e(r[0]),e(r[1])];h(n)}),t.call(r),p.current=e=>{t.call(r.move,e)},t.select(".selection").attr("fill","steelblue").attr("fill-opacity",.2).attr("stroke","steelblue").attr("stroke-width",1),()=>{p.current=null,r.on("brush end",null)}},[i,u,s,f,h]),r(()=>{if(!p.current||!i||!m.current)return;const t="x"===f?i.x:i.y;if(b.current=!0,a){const r=[t(a[0]),t(a[1])];p.current(r)}else p.current(null);b.current=!1},[a,i,f]),l("svg",{ref:m,width:x,height:d,style:{position:"absolute",top:0,left:0,pointerEvents:"all"},children:l("g",{className:"brush-group",transform:`translate(${c.left},${c.top})`})})}export{u as MinimapBrushOverlay};
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{useRef as t,useEffect as e}from"react";import{brush as r}from"d3-brush";import{select as n}from"d3-selection";import{jsx as s}from"react/jsx-runtime";function l({frameRef:l,cellSize:o,onBrush:i}){const c=t(null),u=o-4-4,a=o-4-4;return e(()=>{if(!c.current)return;const t=n(c.current).select(".brush-g"),e=r().extent([[0,0],[u,a]]).on("brush end",t=>{const e=l.current?.getScales();if(!e)return;if(!(r=t.selection)||!Array.isArray(r[0]))return void i(null);var r;const[[n,s],[o,c]]=t.selection,u=[[e.x.invert(n),e.y.invert(s)],[e.x.invert(o),e.y.invert(c)]];i(u)});return t.call(e),t.select(".selection").attr("fill","steelblue").attr("fill-opacity",.15).attr("stroke","steelblue").attr("stroke-width",1),()=>{e.on("brush end",null)}},[u,a,l,i]),s("svg",{ref:c,width:o,height:o,style:{position:"absolute",top:0,left:0},children:s("g",{className:"brush-g",transform:"translate(4,4)"})})}export{l as ScatterplotMatrixBrushOverlay};
@@ -0,0 +1 @@
1
+ import{FORECAST_OPACITY_FIELD as m,SEGMENT_FIELD as n,buildAnomalyAnnotations as o,buildForecast as u,createSegmentLineStyle as c,stampForecastOpacity as h}from"./chunk-chunk-C57LR3YG.module.min.js";import{darkenColor as i,lightenColor as k}from"./chunk-chunk-2JGJ5GUG.module.min.js";import"./chunk-chunk-JJ2OOIET.module.min.js";export{m as FORECAST_OPACITY_FIELD,n as SEGMENT_FIELD,o as buildAnomalyAnnotations,u as buildForecast,c as createSegmentLineStyle,i as darkenColor,k as lightenColor,h as stampForecastOpacity};
@@ -0,0 +1 @@
1
+ import{FORECAST_OPACITY_FIELD as m,SEGMENT_FIELD as o,buildAnomalyAnnotations as n,buildForecast as r,createSegmentLineStyle as u,darkenColor as c,lightenColor as e,stampForecastOpacity as h}from"./chunk-chunk-AVBI6GDT.module.min.js";export{m as FORECAST_OPACITY_FIELD,o as SEGMENT_FIELD,n as buildAnomalyAnnotations,r as buildForecast,u as createSegmentLineStyle,c as darkenColor,e as lightenColor,h as stampForecastOpacity};
@@ -4,6 +4,8 @@ import { type DescribeLevel } from "./ai/describeChart";
4
4
  import type { ChartMode, MobileInteractionProp } from "./charts/shared/types";
5
5
  import { type MobileStandardControlRequest, type MobileStandardControlsProps } from "./MobileStandardControls";
6
6
  import { type MobileVisualizationContract } from "./charts/shared/auditMobileVisualization";
7
+ import type { ChartContainerDataAudit } from "./chartContainerDataAudit";
8
+ export type { ChartContainerDataAudit, ChartContainerDataAuditOptions } from "./chartContainerDataAudit";
7
9
  export type ChartNotificationLevel = "info" | "success" | "warning" | "error" | "neutral";
8
10
  /**
9
11
  * One entry in a ChartContainer's notification stack — chart-level context
@@ -58,8 +60,8 @@ export interface ChartContainerMobileAuditOptions {
58
60
  }
59
61
  export type ChartContainerMobileAudit = boolean | "warn" | ChartContainerMobileAuditOptions;
60
62
  export interface ChartContainerProps {
61
- /** Chart title */
62
- title?: string;
63
+ /** Chart title (string or inline nodes — e.g. a secret debug hit-target) */
64
+ title?: React.ReactNode;
63
65
  /** Subtitle / description */
64
66
  subtitle?: string;
65
67
  /** Chart children (any Semiotic chart component) */
@@ -131,6 +133,14 @@ export interface ChartContainerProps {
131
133
  * so notifications that arrive while streaming are announced.
132
134
  */
133
135
  notifications?: ChartNotification[];
136
+ /**
137
+ * Run Semiotic's numeric input audit over `chartConfig.props` and merge its
138
+ * findings into the notification bell. Re-evaluates when the config/data
139
+ * identity changes. Ref-only push mutations are intentionally not observable
140
+ * here; audit a bounded stream snapshot and pass its notifications instead.
141
+ * Requires `chartConfig`.
142
+ */
143
+ dataAudit?: ChartContainerDataAudit;
134
144
  /**
135
145
  * Called when a notification's dismiss button is clicked. Dismissal state
136
146
  * is tracked internally (keyed by `notification.id`, falling back to array
@@ -45,6 +45,7 @@ import { CollisionSwarmChartCapability } from "../charts/physics/CollisionSwarmC
45
45
  import { PhysicalFlowChartCapability } from "../charts/physics/PhysicalFlowChart.capability";
46
46
  import { ProcessFlowChartCapability } from "../charts/physics/ProcessFlowChart.capability";
47
47
  import { GauntletChartCapability } from "../charts/physics/GauntletChart.capability";
48
+ import { CrucibleChartCapability } from "../charts/physics/CrucibleChart.capability";
48
49
  /**
49
50
  * Register a capability for a chart (built-in or third-party). Re-registering by
50
51
  * component name replaces the previous descriptor — useful for overriding defaults.
@@ -59,4 +60,4 @@ export declare function unregisterChartCapability(component: string): void;
59
60
  export declare function getCapabilities(): ReadonlyArray<ChartCapability>;
60
61
  /** Look up a capability by component name. */
61
62
  export declare function getCapability(component: string): ChartCapability | undefined;
62
- export { LineChartCapability, AreaChartCapability, StackedAreaChartCapability, ScatterplotCapability, ConnectedScatterplotCapability, BubbleChartCapability, QuadrantChartCapability, MultiAxisLineChartCapability, MinimapChartCapability, DifferenceChartCapability, CandlestickChartCapability, HeatmapCapability, BarChartCapability, GroupedBarChartCapability, StackedBarChartCapability, DotPlotCapability, PieChartCapability, DonutChartCapability, FunnelChartCapability, GaugeChartCapability, LikertChartCapability, SwimlaneChartCapability, HistogramCapability, BoxPlotCapability, SwarmPlotCapability, ViolinPlotCapability, RidgelinePlotCapability, ForceDirectedGraphCapability, SankeyDiagramCapability, ChordDiagramCapability, ProcessSankeyCapability, TreeDiagramCapability, TreemapCapability, CirclePackCapability, OrbitDiagramCapability, ChoroplethMapCapability, ProportionalSymbolMapCapability, FlowMapCapability, DistanceCartogramCapability, GaltonBoardChartCapability, EventDropChartCapability, PhysicsPileChartCapability, CollisionSwarmChartCapability, PhysicalFlowChartCapability, ProcessFlowChartCapability, GauntletChartCapability, };
63
+ export { LineChartCapability, AreaChartCapability, StackedAreaChartCapability, ScatterplotCapability, ConnectedScatterplotCapability, BubbleChartCapability, QuadrantChartCapability, MultiAxisLineChartCapability, MinimapChartCapability, DifferenceChartCapability, CandlestickChartCapability, HeatmapCapability, BarChartCapability, GroupedBarChartCapability, StackedBarChartCapability, DotPlotCapability, PieChartCapability, DonutChartCapability, FunnelChartCapability, GaugeChartCapability, LikertChartCapability, SwimlaneChartCapability, HistogramCapability, BoxPlotCapability, SwarmPlotCapability, ViolinPlotCapability, RidgelinePlotCapability, ForceDirectedGraphCapability, SankeyDiagramCapability, ChordDiagramCapability, ProcessSankeyCapability, TreeDiagramCapability, TreemapCapability, CirclePackCapability, OrbitDiagramCapability, ChoroplethMapCapability, ProportionalSymbolMapCapability, FlowMapCapability, DistanceCartogramCapability, GaltonBoardChartCapability, EventDropChartCapability, PhysicsPileChartCapability, CollisionSwarmChartCapability, PhysicalFlowChartCapability, ProcessFlowChartCapability, GauntletChartCapability, CrucibleChartCapability };
@@ -1,5 +1,7 @@
1
1
  import type { Datum } from "../charts/shared/datumTypes";
2
2
  import type { DataSummary } from "../data/DataSummarizer";
3
+ import type { NumericContracts } from "../data/numericContracts";
4
+ import type { NumericFieldProfile } from "../data/auditData";
3
5
  import type { IntentId } from "./intents";
4
6
  import type { ChartRecipe, ChartRecipeFrameFamily, MobileDesignDefinition } from "./chartRecipes";
5
7
  import type { ScaleFitFn, QualityFitFn, ScaleBand, CardinalityBand, EffectiveScale } from "./dataScaleProfile";
@@ -52,6 +54,12 @@ export interface FieldCandidate {
52
54
  export interface ChartDataProfile extends DataSummary {
53
55
  /** Original rows (read-only); used by capabilities to compute their own stats. */
54
56
  data: ReadonlyArray<Datum>;
57
+ /**
58
+ * Per-field numeric health, including invalid/missing counts and extrema.
59
+ * Unlike `fields`, categorical values assigned to a numeric role remain
60
+ * visible here as `nonNumericCount` rather than being silently discarded.
61
+ */
62
+ numericFields?: Readonly<Record<string, NumericFieldProfile>>;
55
63
  /** Candidate fields per role, sorted best-first. */
56
64
  candidates: {
57
65
  x: FieldCandidate[];
@@ -146,6 +154,11 @@ export interface ChartVariant {
146
154
  description?: string;
147
155
  /** Props to merge into the base chart props. */
148
156
  props: Record<string, unknown>;
157
+ /**
158
+ * When set, suggestions use this component instead of `capability.component`
159
+ * (e.g. PieChart's "donut" variant → DonutChart, which actually honors innerRadius).
160
+ */
161
+ component?: string;
149
162
  /** Style/role tags (used by consumers like vizmart for filtering). */
150
163
  tags?: ReadonlyArray<string>;
151
164
  /** Per-intent additive score deltas (e.g. {"trend": +1, "outlier-detection": -2}). */
@@ -178,6 +191,12 @@ export interface ChartCapability {
178
191
  importPath: ChartImportPath;
179
192
  /** Base rubric, before variant/profile adjustments. */
180
193
  rubric: ChartRubric;
194
+ /**
195
+ * JSON-safe Semiotic runtime declaration of the numeric assumptions this
196
+ * chart makes about accessor-bound data. Consumed by `auditData` and
197
+ * `diagnoseConfig`; not part of the library-neutral IDID v0.1 subset.
198
+ */
199
+ numericContracts?: NumericContracts;
181
200
  /**
182
201
  * Hard requirements gate. Return null if the chart can render this profile,
183
202
  * or a human-readable string explaining why not (e.g. "no numeric y candidate").
@@ -0,0 +1,10 @@
1
+ import type { ChartNotification } from "./ChartContainer";
2
+ import type { ChartConfig } from "./export/chartConfig";
3
+ import { type DataAuditNotificationOptions } from "./data/dataAuditPresentation";
4
+ import type { AuditDataOptions } from "./data/auditData";
5
+ export interface ChartContainerDataAuditOptions extends Pick<AuditDataOptions, "checkOutliers">, DataAuditNotificationOptions {
6
+ }
7
+ export type ChartContainerDataAudit = boolean | ChartContainerDataAuditOptions;
8
+ type AuditableChartConfig = Pick<ChartConfig, "component" | "props">;
9
+ export declare function buildChartDataAuditNotifications(chartConfig: AuditableChartConfig | undefined, dataAudit: ChartContainerDataAudit | undefined): ChartNotification[];
10
+ export {};
@@ -51,6 +51,8 @@ export interface ChoroplethMapProps<TDatum extends Datum = Datum> extends BaseCh
51
51
  graticule?: boolean | import("../../stream/geoTypes").GraticuleConfig;
52
52
  /** Tooltip config */
53
53
  tooltip?: TooltipProp;
54
+ /** Enable hover interaction. Defaults by chart mode. */
55
+ enableHover?: boolean;
54
56
  /** Show legend @default true */
55
57
  showLegend?: boolean;
56
58
  /** Legend interaction mode */
@@ -45,10 +45,12 @@ export interface DistanceCartogramProps<TDatum extends Datum = Datum> extends Ba
45
45
  styleRules?: StyleRule[];
46
46
  /** Color scheme @default "category10" */
47
47
  colorScheme?: string | string[] | Record<string, string>;
48
- /** Point radius @default 5 */
48
+ /** Point radius. Defaults to 5, or 1.5 in sparkline mode. */
49
49
  pointRadius?: number;
50
50
  /** Tooltip */
51
51
  tooltip?: TooltipProp;
52
+ /** Enable hover interaction. Defaults by chart mode. */
53
+ enableHover?: boolean;
52
54
  /** Show legend */
53
55
  showLegend?: boolean;
54
56
  /** Legend position */
@@ -77,9 +79,16 @@ export interface DistanceCartogramProps<TDatum extends Datum = Datum> extends Ba
77
79
  tileAttribution?: string;
78
80
  /** Max cached tiles @default 256 */
79
81
  tileCacheSize?: number;
80
- /** Show concentric distance rings around center. true for auto intervals, number for ring count, or number[] for explicit cost values. @default true */
82
+ /**
83
+ * Cost reference marks.
84
+ * - Radial layout: concentric rings around center.
85
+ * - Strip (sparkline) layout: baseline tick marks on the cost axis.
86
+ * @default true (radial); true as axis ticks in sparkline
87
+ */
81
88
  showRings?: boolean | number | number[];
82
- /** Ring style overrides */
89
+ /** Show numeric labels on distance rings. Defaults to false in context and sparkline modes. */
90
+ showRingLabels?: boolean;
91
+ /** Ring / strip-tick style overrides */
83
92
  ringStyle?: {
84
93
  stroke?: string;
85
94
  strokeWidth?: number;
@@ -87,10 +96,15 @@ export interface DistanceCartogramProps<TDatum extends Datum = Datum> extends Ba
87
96
  labelColor?: string;
88
97
  labelSize?: number;
89
98
  };
90
- /** Show north indicator arrow @default true */
99
+ /** Show north indicator arrow. Defaults to true, or false in sparkline mode. */
91
100
  showNorth?: boolean;
92
101
  /** Label for cost units shown on rings (e.g. "hrs", "km") */
93
102
  costLabel?: string;
103
+ /**
104
+ * Cartogram layout encoding. Defaults to `"strip"` (1D Langren cost axis)
105
+ * in sparkline mode and `"radial"` otherwise.
106
+ */
107
+ cartogramLayout?: "radial" | "strip";
94
108
  /** Annotations */
95
109
  annotations?: Datum[];
96
110
  /** Passthrough */
@@ -103,7 +117,10 @@ export interface DistanceCartogramProps<TDatum extends Datum = Datum> extends Ba
103
117
  * proportional to `costAccessor` (commute time, fare, hops, etc.) rather
104
118
  * than great-circle distance. `strength` interpolates between the
105
119
  * geographic positions (0) and the fully-distorted cartogram (1).
106
- * Concentric rings show iso-cost contours by default.
120
+ * Concentric rings show iso-cost contours by default. In `mode="sparkline"`
121
+ * the chart collapses to a Langren-style 1D cost strip (origin at left,
122
+ * cost growing right) so dense estimates of the same distance stay legible
123
+ * without map chrome.
107
124
  *
108
125
  * @example
109
126
  * ```tsx
@@ -143,6 +160,19 @@ export interface DistanceCartogramProps<TDatum extends Datum = Datum> extends Ba
143
160
  * lineMode="fractional"
144
161
  * />
145
162
  * ```
163
+ *
164
+ * @example
165
+ * ```tsx
166
+ * // Sparkline: Langren-style 1D cost strip (origin left, cost right)
167
+ * <DistanceCartogram
168
+ * points={estimates}
169
+ * center="Toledo"
170
+ * costAccessor="degrees"
171
+ * mode="sparkline"
172
+ * width={160}
173
+ * height={28}
174
+ * />
175
+ * ```
146
176
  */
147
177
  export declare const DistanceCartogram: {
148
178
  <TDatum extends Datum = Datum>(props: DistanceCartogramProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
@@ -43,6 +43,8 @@ export interface FlowMapProps<TDatum extends Datum = Datum> extends BaseChartPro
43
43
  edgeOpacity?: number;
44
44
  /** Min/max pixel width for proportional edge width @default [1, 8] */
45
45
  edgeWidthRange?: [number, number];
46
+ /** Node radius in pixels. Defaults to 5, or 1.5 in sparkline mode. */
47
+ pointRadius?: number;
46
48
  /** Line cap style for flow edges @default "round" */
47
49
  edgeLinecap?: "butt" | "round" | "square";
48
50
  /** Color scheme for edges @default "category10" */
@@ -53,6 +55,8 @@ export interface FlowMapProps<TDatum extends Datum = Datum> extends BaseChartPro
53
55
  particleStyle?: GeoParticleStyle;
54
56
  /** Tooltip */
55
57
  tooltip?: TooltipProp;
58
+ /** Enable hover interaction. Defaults by chart mode. */
59
+ enableHover?: boolean;
56
60
  /** Show legend */
57
61
  showLegend?: boolean;
58
62
  /** Legend interaction mode */
@@ -17,7 +17,7 @@ export interface ProportionalSymbolMapProps<TDatum extends Datum = Datum> extend
17
17
  yAccessor?: ChartAccessor<TDatum, number>;
18
18
  /** Field to scale point size */
19
19
  sizeBy: ChartAccessor<TDatum, number>;
20
- /** Min and max radius @default [3, 30] */
20
+ /** Min and max radius. Defaults to [3, 30], or [1, 4] in sparkline mode. */
21
21
  sizeRange?: [number, number];
22
22
  /** Field to determine point color */
23
23
  colorBy?: ChartAccessor<TDatum, string>;
@@ -39,6 +39,8 @@ export interface ProportionalSymbolMapProps<TDatum extends Datum = Datum> extend
39
39
  areaStyle?: Style;
40
40
  /** Tooltip config */
41
41
  tooltip?: TooltipProp;
42
+ /** Enable hover interaction. Defaults by chart mode. */
43
+ enableHover?: boolean;
42
44
  /** Show legend */
43
45
  showLegend?: boolean;
44
46
  /** Legend interaction mode */
@@ -104,6 +104,7 @@ export { PhysicsPileChart } from "./physics/PhysicsPileChart";
104
104
  export type { PhysicsPileChartProps } from "./physics/PhysicsPileChart";
105
105
  export { CollisionSwarmChart } from "./physics/CollisionSwarmChart";
106
106
  export type { CollisionSwarmChartProps } from "./physics/CollisionSwarmChart";
107
+ export * from "./physics/CrucibleChart";
107
108
  export { GauntletChart, GuantletChart, planGauntletPropertyWork, replaceGauntletNegative } from "./physics/GauntletChart";
108
109
  export type { GauntletChartProps, GauntletEffect, GauntletEvent, GauntletEventContext, GauntletEventLogItem, GauntletGate, GauntletLayout, GauntletNegativeReplacementOptions, GauntletPopSpec, GauntletProjectPlacement, GauntletProjectState, GauntletPropertyForceContext, GauntletPropertyDefinition, GauntletPropertyWorkPlan, GauntletPropertyWorkPlanOptions } from "./physics/GauntletChart";
109
110
  export { physicsProcessBoundaryColliders, physicsProcessGroupSemanticItems, physicsProcessRegionSemanticItem, physicsProcessStageSemanticItems } from "./physics/physicsProcessPrimitives";
@@ -90,13 +90,48 @@ export interface ForceDirectedGraphProps<TNode extends Datum = Datum, TEdge exte
90
90
  * @default [5, 20]
91
91
  */
92
92
  nodeSizeRange?: [number, number];
93
+ /**
94
+ * Outline color for **node** marks only, leaving edges untouched — the
95
+ * node half of independent node/edge stroking (the edge half is
96
+ * {@link ForceDirectedGraphProps.edgeColor}). Overrides the generic
97
+ * {@link BaseChartProps.stroke} for nodes; pass `"none"` to remove the
98
+ * default node outline. Precedence per property: `nodeStroke` > `stroke`
99
+ * > the built-in node outline.
100
+ * @example
101
+ * ```tsx
102
+ * // Ringless nodes, blue edges — styled separately
103
+ * <ForceDirectedGraph nodeStroke="none" edgeColor="#4c78a8" />
104
+ * // White node ring, unchanged edges
105
+ * <ForceDirectedGraph nodeStroke="#fff" nodeStrokeWidth={1.5} />
106
+ * ```
107
+ */
108
+ nodeStroke?: string;
109
+ /**
110
+ * Outline width for **node** marks only. Overrides the generic
111
+ * {@link BaseChartProps.strokeWidth} for nodes.
112
+ * @default the generic `strokeWidth`
113
+ */
114
+ nodeStrokeWidth?: number;
93
115
  /**
94
116
  * Constant pixel width, or a function/field returning a numeric value
95
- * scaled to a default width range.
117
+ * scaled to a default width range. The **edge** stroke width; overrides
118
+ * the generic `strokeWidth` for edges.
96
119
  * @default 1
97
120
  */
98
121
  edgeWidth?: number | ChartAccessor<TEdge, number>;
122
+ /**
123
+ * Stroke color for **edge** marks only, leaving nodes untouched — the edge
124
+ * half of independent node/edge stroking (the node half is
125
+ * {@link ForceDirectedGraphProps.nodeStroke}). Overrides the generic
126
+ * {@link BaseChartProps.stroke} for edges. Precedence per property:
127
+ * `edgeColor` > `stroke` > the built-in `#999`.
128
+ * @default "#999"
129
+ */
99
130
  edgeColor?: string;
131
+ /**
132
+ * Opacity for **edge** marks only. Overrides the generic `opacity` for edges.
133
+ * @default 0.6
134
+ */
100
135
  edgeOpacity?: number;
101
136
  /**
102
137
  * Number of force-simulation ticks before the layout settles.
@@ -3,7 +3,7 @@ import type { Datum } from "../shared/datumTypes";
3
3
  import type { BaseChartProps, ChartAccessor } from "../shared/types";
4
4
  import type { StyleRule } from "../shared/styleRules";
5
5
  import { type PhysicsFrameHandle } from "./physicsHocHandle";
6
- import { type PhysicsHocFrameProps, type PhysicsSharedChartProps, type TooltipProp } from "./physicsHocUtils";
6
+ import { type PhysicsHocFrameProps, type PhysicsRerunMS, type PhysicsSharedChartProps, type TooltipProp } from "./physicsHocUtils";
7
7
  export interface CollisionSwarmChartProps<TDatum extends Datum = Datum> extends Omit<BaseChartProps, "margin">, PhysicsSharedChartProps {
8
8
  data?: TDatum[];
9
9
  size?: [number, number];
@@ -22,6 +22,11 @@ export interface CollisionSwarmChartProps<TDatum extends Datum = Datum> extends
22
22
  xExtent?: [number, number];
23
23
  collisionIterations?: number;
24
24
  settle?: boolean;
25
+ /**
26
+ * Replay the seeded simulation this many milliseconds after it settles.
27
+ * Omit or pass `null` for a single run; `0` replays on the next timer turn.
28
+ */
29
+ rerunMS?: PhysicsRerunMS;
25
30
  showProjection?: boolean;
26
31
  tooltip?: TooltipProp;
27
32
  paused?: boolean;
@@ -0,0 +1,8 @@
1
+ import type { ChartCapability } from "../../ai/chartCapabilityTypes";
2
+ /**
3
+ * CrucibleChart is intentionally known to the AI surface but never selected
4
+ * from a flat data profile. A valid chart needs an authored treatment program,
5
+ * declared products, and explicit destinations that dataset profiling cannot
6
+ * responsibly invent.
7
+ */
8
+ export declare const CrucibleChartCapability: ChartCapability;
@@ -0,0 +1,63 @@
1
+ import * as React from "react";
2
+ import type { Datum } from "../shared/datumTypes";
3
+ import type { CrucibleChartHandle, CrucibleChartProps } from "./crucibleChartProps";
4
+ export * from "./crucibleTypes";
5
+ export * from "./crucibleProgram";
6
+ export { applyCrucibleEvent, buildCrucibleEvidence, buildCrucibleProjection, cloneCrucibleState, crucibleProjectionRows, evaluateCrucibleConservation, resolveCrucibleSelector } from "./crucibleEffects";
7
+ export { DEFAULT_CRUCIBLE_HEIGHT, DEFAULT_CRUCIBLE_OUTLETS, DEFAULT_CRUCIBLE_SIZE, DEFAULT_CRUCIBLE_WIDTH, buildCrucibleInitialSpawns, buildCrucibleLayout, buildCruciblePhysicsConfig, buildCrucibleStateSpawns, buildCrucibleTerminalSpawns, compileCruciblePlan, createInitialCrucibleState, crucibleBoundaryColliders, crucibleBondId, crucibleComponentBodyId, crucibleProductBodyId, crucibleSemanticKey, replayCruciblePlan, resolveCrucibleSnapshotAt, resolveCrucibleTime } from "./cruciblePhysics";
8
+ export type { CrucibleSelectorResult } from "./crucibleEffects";
9
+ export type { CrucibleInitialStateResult, CrucibleResolvedTime, CrucibleSpawnOptions } from "./cruciblePhysics";
10
+ export type { CrucibleChartHandle, CrucibleChartProps, CrucibleColorBy, CrucibleControls, CrucibleSnapshotAt } from "./crucibleChartProps";
11
+ /**
12
+ * A bounded, deterministic treatment tape for peer components. Authored
13
+ * events own every semantic transition; physics only explains co-presence,
14
+ * agitation, binding, separation, and settling.
15
+ *
16
+ * @example One authored event forms and completes a declared product.
17
+ * ```tsx
18
+ * <CrucibleChart
19
+ * data={[{ id: "crm", amount: 1 }, { id: "billing", amount: 1 }]}
20
+ * phases={[{ id: "resolve", duration: 2, motion: "bind" }]}
21
+ * products={[{ id: "golden-record", outletId: "published" }]}
22
+ * outlets={[{ id: "published", side: "bottom" }]}
23
+ * events={[{
24
+ * id: "publish-record",
25
+ * at: { phaseId: "resolve", progress: 0.7 },
26
+ * effects: [{
27
+ * type: "combine",
28
+ * sourceIds: ["crm", "billing"],
29
+ * productId: "golden-record",
30
+ * complete: true
31
+ * }]
32
+ * }]}
33
+ * idAccessor="id"
34
+ * amountAccessor="amount"
35
+ * />
36
+ * ```
37
+ *
38
+ * @example Build an explicit lifecycle and replay it without remount state.
39
+ * ```tsx
40
+ * const chartRef = React.createRef<CrucibleChartHandle>()
41
+ * const events = buildCrucibleProductEvents({
42
+ * productId: "finding",
43
+ * form: { at: { time: 0.5 }, sourceIds: ["trace", "metric"] },
44
+ * contributions: [{ at: { time: 1 }, sourceIds: ["experiment"] }],
45
+ * complete: { at: { time: 1.5 }, outletId: "supported" }
46
+ * })
47
+ *
48
+ * <button onClick={() => chartRef.current?.replay()}>Replay</button>
49
+ * <CrucibleChart
50
+ * ref={chartRef}
51
+ * data={evidence}
52
+ * phases={[{ id: "assay", duration: 2, motion: "mix" }]}
53
+ * products={[{ id: "finding", outletId: "supported" }]}
54
+ * outlets={[{ id: "supported", side: "bottom" }]}
55
+ * events={events}
56
+ * />
57
+ * ```
58
+ */
59
+ export declare const CrucibleChart: {
60
+ <TDatum extends Datum = Datum>(props: CrucibleChartProps<TDatum> & React.RefAttributes<CrucibleChartHandle<TDatum>>): React.ReactElement | null;
61
+ displayName?: string;
62
+ };
63
+ export default CrucibleChart;
@@ -3,7 +3,7 @@ import type { Datum } from "../shared/datumTypes";
3
3
  import type { BaseChartProps, ChartAccessor } from "../shared/types";
4
4
  import type { StyleRule } from "../shared/styleRules";
5
5
  import { type PhysicsFrameHandle } from "./physicsHocHandle";
6
- import { type PhysicsHocFrameProps, type PhysicsSharedChartProps, type PhysicsSimulationMode, type TooltipProp } from "./physicsHocUtils";
6
+ import { type PhysicsHocFrameProps, type PhysicsRerunMS, type PhysicsSharedChartProps, type PhysicsSimulationMode, type TooltipProp } from "./physicsHocUtils";
7
7
  import type { ChartMode } from "../shared/types";
8
8
  export interface GaltonBoardReferenceLine {
9
9
  value: number;
@@ -42,6 +42,11 @@ export interface GaltonBoardChartProps<TDatum extends Datum = Datum> extends Omi
42
42
  styleRules?: StyleRule[];
43
43
  referenceLines?: GaltonBoardReferenceLine | GaltonBoardReferenceLine[];
44
44
  seed?: number;
45
+ /**
46
+ * Replay the seeded simulation this many milliseconds after it settles.
47
+ * Omit or pass `null` for a single run; `0` replays on the next timer turn.
48
+ */
49
+ rerunMS?: PhysicsRerunMS;
45
50
  showProjection?: boolean;
46
51
  tooltip?: TooltipProp;
47
52
  paused?: boolean;
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ import type { Style } from "../../stream/types";
3
+ import type { PhysicsBodyState } from "../../stream/physics/PhysicsKernel";
4
+ import type { PhysicsSemanticItem } from "../../stream/physics/StreamPhysicsFrame";
5
+ import type { Datum } from "../shared/datumTypes";
6
+ import type { CrucibleComponentState, CrucibleProductState, CrucibleRunState } from "./crucibleTypes";
7
+ export declare function displayNumber(value: number): string;
8
+ export declare function componentDescription(component: CrucibleComponentState): string;
9
+ export declare function productDescription(product: CrucibleProductState): string;
10
+ /** Default accessible description for each live crucible body. */
11
+ export declare function crucibleBodySemanticItem<TDatum extends Datum>(body: PhysicsBodyState, state: CrucibleRunState<TDatum>): false | Partial<PhysicsSemanticItem>;
12
+ /** Canvas mark used when callers do not supply frameProps.renderBody. */
13
+ export declare function drawCrucibleBody(ctx: CanvasRenderingContext2D, body: PhysicsBodyState, style: Style): void;
14
+ /**
15
+ * SSR sibling of `drawCrucibleBody` — the same shadowed hexagon + inner ring
16
+ * for settled products, and highlight dot for source components, as an SVG
17
+ * fragment instead of canvas draw calls. Returns `undefined` for non-crucible
18
+ * bodies so the SVG renderer falls back to its default circle mark.
19
+ *
20
+ * `idPrefix` is the sanitized prefix the owning `PhysicsSettledSVG` document
21
+ * uses for its own ids — folded into this body's `<filter>` id so multiple
22
+ * settled Crucible SVGs on one page (SVG ids are document-global) can't
23
+ * collide and mis-apply each other's glow filter.
24
+ */
25
+ export declare function drawCrucibleBodySVG(body: PhysicsBodyState, style: Style, index: number, idPrefix?: string): React.ReactNode | undefined;
26
+ /** Draw supplied relations and committed source-to-product lineage. */
27
+ export declare function drawCrucibleBonds<TDatum extends Datum>(ctx: CanvasRenderingContext2D, bodies: readonly PhysicsBodyState[], state: CrucibleRunState<TDatum>): void;