@awc-ui/core 1.0.0-beta → 1.0.0-beta.1

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 (79) hide show
  1. package/dist/components/p-6wZSqm_2.js +2 -0
  2. package/dist/components/{p-Bx5sxRqa.js.map → p-6wZSqm_2.js.map} +1 -1
  3. package/dist/components/p-7fN_yCXW.js +2 -0
  4. package/dist/components/{p-CJdqKSuf.js.map → p-7fN_yCXW.js.map} +1 -1
  5. package/dist/components/{p-G5m2pHZ2.js → p-B0Opn6dK.js} +2 -2
  6. package/dist/components/{p-pDrTJmeT.js → p-B3MWYEEJ.js} +2 -2
  7. package/dist/components/{p-DGGkdSZk.js → p-BwXpiUsu.js} +2 -2
  8. package/dist/{md3/p-B0NLeNWu.js → components/p-Bx6--dQF.js} +2 -2
  9. package/dist/components/{p-BIIp3Qod.js → p-C8EP4S21.js} +2 -2
  10. package/dist/components/{p-CWM3KSti.js → p-C_ogF68H.js} +2 -2
  11. package/dist/components/{p-BlwGYUkt.js → p-Ch2-tttM.js} +2 -2
  12. package/dist/components/p-DXXUoRSH.js +2 -0
  13. package/dist/components/{p-DWUCvzfU.js.map → p-DXXUoRSH.js.map} +1 -1
  14. package/dist/components/p-Dp-w93ot.js +2 -0
  15. package/dist/components/{p-BUYYCrGa.js.map → p-Dp-w93ot.js.map} +1 -1
  16. package/dist/{md3/p-CGStn3Iq.js → components/p-DvOKnoqK.js} +2 -2
  17. package/dist/components/{p-B7yMxWo-.js → p-DzPKu-Ma.js} +2 -2
  18. package/dist/components/{p-CXpXrhQH.js → p-RLxbNqRv.js} +2 -2
  19. package/dist/components/p-UdGDg2oJ.js +2 -0
  20. package/dist/components/{p-BujtL9xW.js.map → p-UdGDg2oJ.js.map} +1 -1
  21. package/dist/components/p-e2HRV63Y.js +2 -0
  22. package/dist/components/{p-CrlkPxeB.js.map → p-e2HRV63Y.js.map} +1 -1
  23. package/dist/components/p-stybaFzj.js +2 -0
  24. package/dist/components/{p-JbwZ84YK.js.map → p-stybaFzj.js.map} +1 -1
  25. package/dist/components/p-uTEkf0sE.js +2 -0
  26. package/dist/components/{p-BXwh1zjF.js.map → p-uTEkf0sE.js.map} +1 -1
  27. package/dist/esm/{a11y-C9_cZAF_.js → a11y-C6CRqodW.js} +3 -3
  28. package/dist/esm/{a11y-C9_cZAF_.js.map → a11y-C6CRqodW.js.map} +1 -1
  29. package/dist/esm/{bar-chart-IvBgAmmF.js → bar-chart-ZZrajEkM.js} +4 -4
  30. package/dist/esm/{bar-chart-IvBgAmmF.js.map → bar-chart-ZZrajEkM.js.map} +1 -1
  31. package/dist/esm/{chart-D1kP9gfW.js → chart-32olae06.js} +4 -4
  32. package/dist/esm/{chart-D1kP9gfW.js.map → chart-32olae06.js.map} +1 -1
  33. package/dist/esm/{hit-test-DFfwlMb9.js → hit-test-DHldf5Lm.js} +3 -3
  34. package/dist/esm/{hit-test-DFfwlMb9.js.map → hit-test-DHldf5Lm.js.map} +1 -1
  35. package/dist/esm/{rtl-CGStn3Iq.js → rtl-DvOKnoqK.js} +3 -3
  36. package/dist/esm/{rtl-CGStn3Iq.js.map → rtl-DvOKnoqK.js.map} +1 -1
  37. package/dist/md3/p-04e97f5d.entry.js +2 -0
  38. package/dist/md3/{p-ec14eaca.entry.js.map → p-04e97f5d.entry.js.map} +1 -1
  39. package/dist/md3/p-3cce1de3.entry.js +2 -0
  40. package/dist/md3/{p-2121c939.entry.js.map → p-3cce1de3.entry.js.map} +1 -1
  41. package/dist/md3/p-4d82132d.entry.js +2 -0
  42. package/dist/md3/{p-fe78659d.entry.js.map → p-4d82132d.entry.js.map} +1 -1
  43. package/dist/{components/p-Bu-m4Gm2.js → md3/p-Bx6--dQF.js} +2 -2
  44. package/dist/md3/{p-B0NLeNWu.js.map → p-Bx6--dQF.js.map} +1 -1
  45. package/dist/md3/{p-CWM3KSti.js → p-C_ogF68H.js} +2 -2
  46. package/dist/md3/{p-CWM3KSti.js.map → p-C_ogF68H.js.map} +1 -1
  47. package/dist/{components/p-CGStn3Iq.js → md3/p-DvOKnoqK.js} +2 -2
  48. package/dist/md3/{p-CGStn3Iq.js.map → p-DvOKnoqK.js.map} +1 -1
  49. package/dist/md3/{p-B7yMxWo-.js → p-DzPKu-Ma.js} +2 -2
  50. package/dist/md3/{p-B7yMxWo-.js.map → p-DzPKu-Ma.js.map} +1 -1
  51. package/dist/md3/{p-CXpXrhQH.js → p-RLxbNqRv.js} +2 -2
  52. package/dist/md3/{p-CXpXrhQH.js.map → p-RLxbNqRv.js.map} +1 -1
  53. package/dist/md3/{p-f6373c6c.entry.js → p-aaec2698.entry.js} +2 -2
  54. package/dist/md3/{p-9ff2d5d1.entry.js → p-c063c823.entry.js} +2 -2
  55. package/main-llm.md +2 -2
  56. package/package.json +24 -3
  57. package/dist/components/p-BUYYCrGa.js +0 -2
  58. package/dist/components/p-BXwh1zjF.js +0 -2
  59. package/dist/components/p-BujtL9xW.js +0 -2
  60. package/dist/components/p-Bx5sxRqa.js +0 -2
  61. package/dist/components/p-CJdqKSuf.js +0 -2
  62. package/dist/components/p-CrlkPxeB.js +0 -2
  63. package/dist/components/p-DWUCvzfU.js +0 -2
  64. package/dist/components/p-JbwZ84YK.js +0 -2
  65. package/dist/md3/p-2121c939.entry.js +0 -2
  66. package/dist/md3/p-ec14eaca.entry.js +0 -2
  67. package/dist/md3/p-fe78659d.entry.js +0 -2
  68. /package/dist/components/{p-G5m2pHZ2.js.map → p-B0Opn6dK.js.map} +0 -0
  69. /package/dist/components/{p-pDrTJmeT.js.map → p-B3MWYEEJ.js.map} +0 -0
  70. /package/dist/components/{p-DGGkdSZk.js.map → p-BwXpiUsu.js.map} +0 -0
  71. /package/dist/components/{p-Bu-m4Gm2.js.map → p-Bx6--dQF.js.map} +0 -0
  72. /package/dist/components/{p-BIIp3Qod.js.map → p-C8EP4S21.js.map} +0 -0
  73. /package/dist/components/{p-CWM3KSti.js.map → p-C_ogF68H.js.map} +0 -0
  74. /package/dist/components/{p-BlwGYUkt.js.map → p-Ch2-tttM.js.map} +0 -0
  75. /package/dist/components/{p-CGStn3Iq.js.map → p-DvOKnoqK.js.map} +0 -0
  76. /package/dist/components/{p-B7yMxWo-.js.map → p-DzPKu-Ma.js.map} +0 -0
  77. /package/dist/components/{p-CXpXrhQH.js.map → p-RLxbNqRv.js.map} +0 -0
  78. /package/dist/md3/{p-f6373c6c.entry.js.map → p-aaec2698.entry.js.map} +0 -0
  79. /package/dist/md3/{p-9ff2d5d1.entry.js.map → p-c063c823.entry.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"names":["mdProgressIndicatorCss","GAP_DP","LINEAR_DET_WAVELENGTH","CIRCULAR_WAVELENGTH","LINEAR_AMPLITUDE","CIRCULAR_AMPLITUDE","CIRCULAR_SIZE_FLAT","CIRCULAR_SIZE_WAVE","CIRCULAR_SIZE_MIN","CIRCULAR_SIZE_MAX","WAVE_SAMPLES_PER_WL","AMP_DURATION","AMP_IN","AMP_OUT","CIRCULAR_INDET_CYCLE","CIRCULAR_INDET_MIN","CIRCULAR_INDET_MAX","CIRCULAR_GLOBAL_ROTATION","MIN_CIRCULAR_VERTICES","bezierEasing","x1","y1","x2","y2","t","cx","bx","ax","cy","by","ay","sampleX","sampleY","slopeX","x","i","xt","d","Math","abs","min","max","EASE_IN","EASE_OUT","EASE_STANDARD","MdProgressIndicator","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","value","indeterminate","thickness","wave","waveAmplitude","waveLength","waveSpeed","size","fourColor","label","complete","density","reducedMotion","_completing","_completed","_completedTrack","_fillComplete","raf","phase","linearPhase","amp","ampFrom","ampTo","ampStartTs","ampEase","lastTs","indetStartTs","renderFraction","linearRenderFraction","linearWaveRef","linearWaveSvgRef","linearWaveTrackRef","flatActiveRef","flatTrackRef","indetBar1Ref","indetBar2Ref","indetPath1Ref","indetPath2Ref","indetTrackRef","linearWidth","visible","rtl","completingFromFrac","circularFlatTrackRef","circularFlatCompleteRef","ccPhase","ccStart","ccFrac","ccErase","CC_FILL_DUR","CC_FLATTEN_DUR","CC_WAIT","CC_ERASE_DUR","CC_TRACK_REVEAL_DUR","wlcPhase","wlcStart","wlcFromFrac","wlcFrac","WLC_FILL_DUR","WLC_FLATTEN_DUR","flcPhase","onReducedMotionChange","e","matches","onLinearAnimEnd","animationName","handleComplete","frame","ts","dt","speedFactor","resolvedWaveSpeed","resolvedWavelength","PI","paintCircularCompletion","stopLoop","setAttribute","activeCircleRef","style","opacity","tr","removeAttribute","requestAnimationFrame","updateLinearPath","k","exp","fraction","updateCircularPath","updateCircularFlat","updateLinearIndeterminate","target","updateLinearFlat","applyAmplitude","shouldAnimate","densityScale","el","v","getComputedStyle","getPropertyValue","trim","Number","resolvedSize","s","resolvedAmplitude","resolvedThickness","resolvedWaveStroke","effectiveThickness","linearWaveHeight","amplitudeTarget","componentWillLoad","syncHostStyles","window","matchMedia","mql","addEventListener","componentDidLoad","IntersectionObserver","io","entries","some","isIntersecting","ensureLoop","observe","ResizeObserver","ro","measureLinearWidth","componentDidRender","computeRtl","w","getBoundingClientRect","width","clientWidth","direction","disconnectedCallback","removeEventListener","disconnect","onDimensionChange","onAmplitudeInputChange","retargetAmplitude","onCompleteChange","next","mdComplete","emit","setProperty","removeProperty","wl","dur","round","updateLinearMask","forEach","p","syncSpinnerTrackVars","r","circularRadius","C","g","key","L","O","T","toFixed","cancelAnimationFrame","W","frac","fillX","buildLinearWaveSVGPath","pct","svgRect","containerRect","intervals","drawBar","barRef","pathRef","br","startX","left","endX","right","push","mask","buildTrackMask","intervalsPx","pcts","map","filter","sort","a","b","merged","last","length","stops","cursor","join","inset","h","bodyStart","bodyEnd","bodyLen","A","rr","steps","bot","top","wy","sin","unshift","lw","rw","start","leftCap","botPath","catmullRom","replace","rightCap","topPath","buildLinearMask","svg","encodeURIComponent","base","circularVertices","wavyArcPath","a0","a1","n","span","ceil","pts","th","cos","arcPath","large","sweep","x0","y0","circularPaths","active","track","gapAng","trackStart","trackEnd","erasing","a0frac","a1frac","fadeSpan","endOpacity","activeRef","trackRef","flatCompletionD","indeterminateSweep","undefined","rot","indeterminateRotation","rotRef","rotRad","arcSpan","arcEndScreen","arcStartScreen","f","idealGap","trackFrac","range","elapsed","ariaValueMax","isFinite","ariaValueNow","renderLinear","renderLinearIndeterminate","renderLinearDeterminate","fillPct","hasProgress","class","onAnimationEnd","part","ref","barClass","modifier","renderCircular","renderCircularWave","renderCircularFlat","sz","center","showGap","trackVisible","viewBox","fill","pathLength","transform","render","Host","role","p0","p1","p2","p3","c1x","c1y","c2x","c2y"],"sources":["src/components/md-progress-indicator/md-progress-indicator.css?tag=md-progress-indicator&encapsulation=shadow","src/components/md-progress-indicator/md-progress-indicator.tsx"],"sourcesContent":["/* ==========================================================\n md-progress-indicator — Material Design 3 Progress Indicator\n (Expressive generation)\n Spec: https://m3.material.io/components/progress-indicators/specs\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-progress-indicator-active-indicator-color Active indicator fill\n --md-progress-indicator-active-indicator-shape Active indicator corner radius\n --md-progress-indicator-track-color Track background\n --md-progress-indicator-track-shape Track corner radius\n --md-progress-indicator-stop-indicator-color Stop dot color\n --md-progress-indicator-stop-indicator-shape Stop dot corner radius\n --md-progress-indicator-stop-indicator-size Stop dot diameter\n --md-progress-indicator-stop-indicator-trailing-space Space past the stop dot to the trailing edge (default 0)\n --md-progress-indicator-track-active-indicator-space Gap between track and active indicator (default 4px)\n --md-progress-indicator-four-color-1..4 Four-color cycle colors\n\n CSS PARTS:\n track Background track (rect or SVG circle/path)\n active-indicator Active progress fill\n stop-indicator Stop dot at track end (linear determinate)\n ========================================================== */\n\n/* ── Host ──────────────────────────────────────────────── */\n\n:host {\n --_active-color: var(--md-progress-indicator-active-indicator-color, var(--md-sys-color-primary, #6750A4));\n --_active-shape: var(--md-progress-indicator-active-indicator-shape, var(--_track-shape));\n --_track-color: var(--md-progress-indicator-track-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_track-shape: var(--md-progress-indicator-track-shape, var(--md-sys-shape-corner-full, 9999px));\n --_stop-color: var(--md-progress-indicator-stop-indicator-color, var(--md-sys-color-primary, #6750A4));\n --_stop-shape: var(--md-progress-indicator-stop-indicator-shape, var(--md-sys-shape-corner-full, 9999px));\n --_stop-size: var(--md-progress-indicator-stop-indicator-size, max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px)));\n\n /* M3 verified four-color order: primary → primary-container → tertiary → tertiary-container */\n --_four-color-1: var(--md-progress-indicator-four-color-1, var(--md-sys-color-primary, #6750A4));\n --_four-color-2: var(--md-progress-indicator-four-color-2, var(--md-sys-color-primary-container, #EADDFF));\n --_four-color-3: var(--md-progress-indicator-four-color-3, var(--md-sys-color-tertiary, #7D5260));\n --_four-color-4: var(--md-progress-indicator-four-color-4, var(--md-sys-color-tertiary-container, #FFD8E4));\n\n /* Linear baseline dimensions (M3): gap between track and active indicator,\n and the space reserved past the stop dot to the trailing edge. */\n --_gap: var(--md-progress-indicator-track-active-indicator-space, max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px)));\n --_stop-trailing-space: var(--md-progress-indicator-stop-indicator-trailing-space, 0px);\n --_thickness: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n --_linear-height: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n --_size: max(28px, calc(40px + var(--md-sys-density-scale, 0) * 3px));\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n/* ── Linear layout ─────────────────────────────────────── */\n\n:host(.md-progress-indicator--linear) {\n display: flex;\n inline-size: 100%;\n block-size: var(--_linear-height, 4px);\n}\n\n.md-progress-indicator__linear {\n position: relative;\n display: flex;\n align-items: center;\n inline-size: 100%;\n block-size: 100%;\n /* Clip the indeterminate bars (translateX from -100% → +80/100%) to the\n track bounds so they don't appear sliding in from outside the component;\n border-radius keeps the clipped ends following the rounded track shape. */\n overflow: hidden;\n border-radius: var(--_track-shape);\n}\n\n/* ── Track (inactive) ──────────────────────────────────── */\n\n.md-progress-indicator__track {\n position: absolute;\n inset-inline-start: var(--_track-start, 0);\n inset-inline-end: 0;\n inset-block: 0;\n margin-block: auto;\n block-size: var(--_thickness, 4px);\n border-radius: var(--_track-shape);\n background-color: var(--_track-color);\n}\n\n.md-progress-indicator__track--full {\n inset-inline-start: 0;\n}\n\n/* Determinate (flat) track: its start edge is rAF-driven per-frame by\n updateLinearFlat() from the same eased fraction as the active fill, so the two\n move in lockstep and the gap stays a constant 4dp. No CSS transition — that\n would re-tween each per-frame write and break the lockstep with the fill. */\n.md-progress-indicator__track--determinate {\n transition: none;\n}\n\n/* ── Active indicator (determinate) ────────────────────── */\n\n.md-progress-indicator__active {\n position: absolute;\n inset-inline-start: 0;\n inset-block: 0;\n margin-block: auto;\n inline-size: var(--_fill-width, 0);\n block-size: var(--_thickness, 4px);\n background-color: var(--_active-color);\n border-radius: var(--_active-shape);\n /* No CSS transition: the fill is rAF-driven per-frame by updateLinearFlat()\n using the SAME eased fraction as the wavy variant, so the flat and wavy\n determinate bars move identically and in lockstep. A CSS transition here\n would re-tween each per-frame write and lag the flat variant behind wavy. */\n transition: none;\n}\n\n/* Wavy active indicator — a band masked to a travelling stroked sine.\n Amplitude (mask geometry) is driven from JS via --_wave-mask;\n the crest travel is GPU-only via mask-position. */\n.md-progress-indicator__active--wave {\n block-size: var(--_linear-height, 10px);\n border-radius: 0;\n background-color: var(--_active-color);\n mask-image: var(--_wave-mask);\n mask-size: var(--_wave-mask-size);\n mask-repeat: repeat-x;\n mask-position: left center;\n animation: md-wave-travel var(--_wave-duration, 1000ms) linear infinite;\n}\n\n/* crests travel toward the leading edge (+x in LTR); tile is exactly one\n wavelength wide so the loop is seamless */\n@keyframes md-wave-travel {\n to {\n mask-position: var(--_wave-length-px, 40px) center;\n }\n}\n\n/* ── Wavy linear determinate SVG path ──────────────────────── */\n\n/* Full-width SVG overlay; the rAF loop writes a closed filled path that\n contains both the wave body and the right-side round cap in one element,\n so there is no coordinate-space mismatch between the two. */\n.md-progress-indicator__linear-wave-svg {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.md-progress-indicator__linear-wave-path {\n fill: var(--_active-color);\n}\n\n/* RTL (determinate) is handled in JS: updateLinearPath() draws the wave at\n [W−fillX, W] so it anchors at the right edge — matching the track and stop dot,\n which flip via CSS logical properties. No CSS transform needed here (transforms\n on <svg> elements have cross-browser transform-origin/transform-box quirks).\n Indeterminate RTL is handled by the .__linear container scaleX(-1) flip below. */\n\n/* ── Stop indicator (linear determinate, all states incl. 0%) ─ */\n\n.md-progress-indicator__stop {\n position: absolute;\n inset-inline-end: var(--_stop-trailing-space, 0);\n inset-block: 0;\n margin-block: auto;\n /* clamp to the track thickness so a thin track never overflows */\n inline-size: min(var(--_stop-size), var(--_thickness, 4px));\n block-size: min(var(--_stop-size), var(--_thickness, 4px));\n border-radius: var(--_stop-shape);\n background-color: var(--_stop-color);\n}\n\n/* ── Linear indeterminate bars (authentic M3 two-bar motion, 2000ms) ─────\n Two phase-offset bars sweep the track. The translate lives on the OUTER\n `.md-progress-indicator__bar` and the width-pulse (scale) on the INNER\n `.md-progress-indicator__bar-inner`, run as separate animations with\n per-keyframe easing — this split is what produces the continuous \"chasing\"\n motion (one bar is always entering while the other exits, so the track is\n never empty → no full stop). The keyframes + the off-screen\n `inset-inline-start` pre-offsets are the verified Material Design values; the\n 0px translate holds are masked because the bar is parked off-screen-left\n during them. translateX is physical %, so the container scaleX(-1) flip\n (below) handles RTL. */\n.md-progress-indicator__bar {\n position: absolute;\n inset-block: 0;\n margin-block: auto;\n inline-size: 100%;\n block-size: var(--_thickness, 4px);\n transform-origin: left center;\n}\n\n.md-progress-indicator__bar-inner {\n position: absolute;\n inset: 0;\n inline-size: 100%;\n block-size: 100%;\n background-color: var(--_active-color);\n border-radius: var(--_active-shape);\n /* scale from the CENTRE (the M3 keyframes assume this): the width pulse keeps\n the band centred in its translating .bar, so the shrinking tail sweeps off\n the right edge instead of pinning a sliver mid-track. */\n transform-origin: center;\n}\n\n/* Two DISTINCT sweeps timed to hand off with minimal gap. The secondary enters\n immediately (secondary visible ~0–1400ms); the primary is phase-shifted by\n -1666ms so it enters visible right as the secondary exits (~1400ms) and itself\n exits right before the cycle wraps (~1940ms) — gap ≈60ms, the minimum\n possible with these two keyframe windows. Both bars start off-screen-left so\n neither pops in mid-track at load. */\n.md-progress-indicator__bar--primary {\n inset-inline-start: -145%;\n animation: md-linear-primary-translate 2000ms linear infinite;\n animation-delay: -1666ms;\n}\n.md-progress-indicator__bar--primary > .md-progress-indicator__bar-inner {\n animation: md-linear-primary-scale 2000ms linear infinite;\n animation-delay: -1666ms;\n}\n.md-progress-indicator__bar--secondary {\n inset-inline-start: -55%;\n animation: md-linear-secondary-translate 2000ms linear infinite;\n}\n.md-progress-indicator__bar--secondary > .md-progress-indicator__bar-inner {\n animation: md-linear-secondary-scale 2000ms linear infinite;\n}\n\n/* Primary: parks off-left, then ACCELERATES across (per-keyframe ease curves). */\n@keyframes md-linear-primary-translate {\n 0% { transform: translateX(0); }\n 20% { animation-timing-function: cubic-bezier(0.5, 0, 0.7017, 0.4958); transform: translateX(0); }\n 59.15% { animation-timing-function: cubic-bezier(0.3024, 0.3814, 0.55, 0.9564); transform: translateX(83.6714%); }\n 100% { transform: translateX(250%); }\n}\n\n/* Primary width: expands as it accelerates, then HOLDS wide through the exit so\n it slides off the end at full width (M3 shrinks here; we keep it wide). */\n@keyframes md-linear-primary-scale {\n 0% { transform: scaleX(0.08); }\n 36.65% { animation-timing-function: cubic-bezier(0.3347, 0.1248, 0.7858, 1); transform: scaleX(0.08); }\n 69.15% { animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1); transform: scaleX(0.58); }\n 100% { transform: scaleX(0.62); }\n}\n\n/* Secondary: enters from the left edge straight away (no park), its own faster\n accelerating sweep — this is what fills the track while the primary is parked,\n so each bar still reads as entering from 0. */\n@keyframes md-linear-secondary-translate {\n 0% { animation-timing-function: cubic-bezier(0.15, 0, 0.5151, 0.4097); transform: translateX(0); }\n 25% { animation-timing-function: cubic-bezier(0.3103, 0.2841, 0.8, 0.7337); transform: translateX(37.6519%); }\n 48.35% { animation-timing-function: cubic-bezier(0.4, 0.627, 0.6, 0.902); transform: translateX(84.3862%); }\n 100% { transform: translateX(160.278%); }\n}\n@keyframes md-linear-secondary-scale {\n 0% { animation-timing-function: cubic-bezier(0.205, 0.0571, 0.5766, 0.454); transform: scaleX(0.08); }\n 19.15% { animation-timing-function: cubic-bezier(0.1523, 0.1964, 0.6484, 1.0043); transform: scaleX(0.4571); }\n 44.15% { animation-timing-function: cubic-bezier(0.2578, -0.0032, 0.2118, 1.3818); transform: scaleX(0.58); }\n 100% { transform: scaleX(0.62); }\n}\n\n/* ── Wavy indeterminate (M3 Expressive) ──────────────────────────────────\n Same continuous two-bar choreography, rendered as bold wavy bands. The OUTER\n bar carries the travelling wave mask: the wave is rigid in the bar's own box\n (so it slides bodily with the bar) plus a gentle crest travel; the INNER\n scale still grows/shrinks the band's length. The bolder stroke makes the\n band tall enough to cover the flat track where it passes. */\n.md-progress-indicator__bar--wave {\n block-size: var(--_linear-height, 10px);\n mask-image: var(--_wave-mask);\n mask-size: var(--_wave-mask-size);\n mask-repeat: repeat-x;\n mask-position: left center;\n}\n.md-progress-indicator__bar--wave > .md-progress-indicator__bar-inner {\n border-radius: 0;\n}\n\n/* Ghost bar-inner: drives CSS animations for position tracking but no visual */\n.md-progress-indicator__bar-inner--ghost {\n background-color: transparent;\n}\n\n/* Add the crest travel alongside each bar's sweep (two animations on the outer;\n the mask-position travel is independent of the transform). These rules\n override the base single-animation sweep, so they must re-declare the sweep\n translate (and the secondary's half-cycle offset) to keep both bars moving. */\n.md-progress-indicator__bar--primary.md-progress-indicator__bar--wave {\n animation:\n md-linear-primary-translate 2000ms linear infinite,\n md-wave-travel var(--_wave-duration, 500ms) linear infinite;\n animation-delay: -1666ms, 0ms;\n}\n.md-progress-indicator__bar--secondary.md-progress-indicator__bar--wave {\n animation:\n md-linear-secondary-translate 2000ms linear infinite,\n md-wave-travel var(--_wave-duration, 500ms) linear infinite;\n}\n\n/* RTL: flip the indeterminate animation (the bars translate with physical %,\n so the container flip reverses their sweep direction). */\n:host-context([dir=\"rtl\"]).md-progress-indicator--indeterminate .md-progress-indicator__linear,\n:host([dir=\"rtl\"]).md-progress-indicator--indeterminate .md-progress-indicator__linear {\n transform: scaleX(-1);\n}\n\n/* ── Circular layout ───────────────────────────────────── */\n\n:host(.md-progress-indicator--circular) {\n inline-size: var(--_size, 40px);\n block-size: var(--_size, 40px);\n}\n\n.md-progress-indicator__circular {\n inline-size: 100%;\n block-size: 100%;\n}\n\n.md-progress-indicator__circular-track {\n stroke: var(--_track-color);\n}\n\n/* Determinate (flat) circular track: rAF-driven per-frame by updateCircularFlat()\n from the eased renderFraction, in lockstep with the active arc, so the 4dp gap\n stays constant and the track recedes exactly as the arc grows (its final sliver\n fades via opacity instead of popping). No CSS transition — that would re-tween\n each per-frame write and reintroduce the lag/pop this fix removes. */\n.md-progress-indicator__circular-track--determinate {\n transition: none;\n}\n\n.md-progress-indicator__circular-active {\n stroke: var(--_active-color);\n /* Flat determinate arc is rAF-driven per-frame by updateCircularFlat() from the\n SAME eased renderFraction (and ease) as its track, so the two move in lockstep.\n No CSS transition — it would re-tween each per-frame write and desync the track.\n (The wavy active is a <path>; the indeterminate active overrides this with\n transition:none plus its own md-circular-dash animation.) */\n transition: none;\n}\n\n/* Flat completion arc: an explicit round-capped <path> used only during the closing\n animation (drawn instead of the dashed circle so the shrinking head stays smooth).\n Empty (d=\"\") at all other times, so it paints nothing in steady state. */\n.md-progress-indicator__circular-active-path {\n stroke: var(--_active-color);\n}\n\n/* ── Circular indeterminate (rotation + arc grow/shrink) ─\n These CSS animations drive the FLAT spinner only — :not(--wave). The wavy\n variant is painted + rotated entirely in JS (rAF); without the guard the\n md-circular-dash dasharray would shatter the JS-drawn wavy <path> (it has no\n pathLength) and md-circular-rotate would double-rotate it on top of the JS\n rotation. Reduced-motion re-adds a slow rotation for the wavy variant below. */\n\n:host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular {\n animation: md-circular-rotate 1568ms linear infinite;\n}\n\n:host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active {\n transition: none;\n animation: md-circular-dash 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite;\n}\n\n/* Indeterminate track follows the active arc as its angular complement, leaving a\n gap on each side. Same keyframe timing as md-circular-dash so the two stay\n complementary at every frame; the dash/offset values are precomputed per\n instance (gap-aware) into --_spin-* vars by syncSpinnerTrackVars(). */\n:host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-track--spinner {\n transition: none;\n animation: md-circular-dash-track 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite;\n}\n\n@keyframes md-circular-rotate {\n 100% { transform: rotate(360deg); }\n}\n\n/* pathLength=1 → dash values are fractions of the circumference */\n@keyframes md-circular-dash {\n 0% { stroke-dasharray: 0.05 1; stroke-dashoffset: 0; }\n 50% { stroke-dasharray: 0.70 1; stroke-dashoffset: -0.18; }\n 100% { stroke-dasharray: 0.05 1; stroke-dashoffset: -0.92; }\n}\n\n/* Complement of md-circular-dash (gap-aware). --_spin-* are resolved numbers.\n The dash is `T (1−T)` so the period equals the path length (1) and a track arc\n crossing the 12-o'clock seam wraps correctly (see syncSpinnerTrackVars). */\n@keyframes md-circular-dash-track {\n 0% { stroke-dasharray: var(--_spin-da-0, 0.81) var(--_spin-gap-0, 0.19); stroke-dashoffset: var(--_spin-do-0, -0.12); }\n 50% { stroke-dasharray: var(--_spin-da-50, 0.16) var(--_spin-gap-50, 0.84); stroke-dashoffset: var(--_spin-do-50, -0.95); }\n 100% { stroke-dasharray: var(--_spin-da-100, 0.81) var(--_spin-gap-100, 0.19); stroke-dashoffset: var(--_spin-do-100, -1.04); }\n}\n\n/* ── Four-color cycle (circular indeterminate) ─────────── */\n\n:host(.md-progress-indicator--four-color.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active {\n animation:\n md-circular-dash 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite,\n md-four-color 5332ms linear infinite;\n}\n\n@keyframes md-four-color {\n 0%, 15% { stroke: var(--_four-color-1); }\n 25%, 40% { stroke: var(--_four-color-2); }\n 50%, 65% { stroke: var(--_four-color-3); }\n 75%, 90% { stroke: var(--_four-color-4); }\n 100% { stroke: var(--_four-color-1); }\n}\n\n/* ── Reduced motion ────────────────────────────────────── */\n/* Wave amplitude is flattened to 0 from JS; here we stop the crest travel\n and slow (never freeze) the looping indeterminate so progress is still\n conveyed. Determinate transitions are made instant. */\n@media (prefers-reduced-motion: reduce) {\n .md-progress-indicator__active,\n .md-progress-indicator__circular-active {\n transition-duration: 0s;\n }\n\n /* Stop crest travel on the determinate wave (amplitude flattened to 0 from\n JS). */\n .md-progress-indicator__active--wave {\n animation: none;\n }\n\n /* Linear indeterminate two-bar motion: slow it down (never freeze) so progress\n is still conveyed, and drop the wavy crest travel (the wave is already flat\n from JS). Re-declare the wavy bars' single (translate-only) animation so the\n base dual-animation rule doesn't reinstate the crest travel; keep both bars'\n translate+scale on the same period so primary/secondary stay in sync. */\n .md-progress-indicator__bar--primary,\n .md-progress-indicator__bar--primary > .md-progress-indicator__bar-inner,\n .md-progress-indicator__bar--secondary,\n .md-progress-indicator__bar--secondary > .md-progress-indicator__bar-inner {\n animation-duration: 6s;\n }\n /* Scale the primary phase-offset proportionally to the slowed duration. */\n .md-progress-indicator__bar--primary,\n .md-progress-indicator__bar--primary > .md-progress-indicator__bar-inner {\n animation-delay: -4998ms;\n }\n .md-progress-indicator__bar--primary.md-progress-indicator__bar--wave {\n animation: md-linear-primary-translate 6s linear infinite;\n animation-delay: -4998ms;\n }\n .md-progress-indicator__bar--secondary.md-progress-indicator__bar--wave {\n animation: md-linear-secondary-translate 6s linear infinite;\n }\n\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular {\n animation-duration: 4s;\n }\n\n /* Keep the active arc and its complement track on the same period so the gap\n stays aligned when slowed for reduced motion. */\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active,\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-track--spinner {\n animation-duration: 3s;\n }\n\n :host(.md-progress-indicator--four-color.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active {\n animation-duration: 3s, 16s;\n }\n\n /* Wavy circular indeterminate is JS-driven and its rAF loop is paused under\n reduced motion (shouldAnimate() returns false), which would otherwise leave\n it frozen. Give it a slow CSS rotation of the last-painted wavy arc+track so\n progress is still conveyed (the gap between them was baked in at paint time,\n so they rotate together and stay aligned). */\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate.md-progress-indicator--wave)\n .md-progress-indicator__circular {\n animation: md-circular-rotate 4s linear infinite;\n }\n}\n\n/* ── Completion (\"closing TV\") animation ──────────────────\n Linear: the full container collapses vertically from the centre (both the\n top and bottom edges meet at the midline), like a CRT powering off.\n Flat circular: handled via WAAPI in JS (arc retracts from its starting\n point). Wavy circular: handled via the rAF loop tween in JS.\n After any variant finishes, --complete hides the host. */\n\n@keyframes md-linear-complete {\n 0% { transform: scaleY(1); }\n 60% { transform: scaleY(0.1); }\n 100% { transform: scaleY(0); }\n}\n\n:host(.md-progress-indicator--linear.md-progress-indicator--completing) .md-progress-indicator__linear {\n transform-origin: center;\n animation: md-linear-complete 300ms cubic-bezier(0.2, 0, 1, 0.8) forwards;\n}\n\n:host(.md-progress-indicator--complete) {\n visibility: hidden;\n}\n\n/* ── Forced colors (high contrast) ─────────────────────── */\n\n@media (forced-colors: active) {\n .md-progress-indicator__active,\n .md-progress-indicator__active--wave,\n .md-progress-indicator__bar,\n .md-progress-indicator__stop {\n background-color: CanvasText;\n }\n\n .md-progress-indicator__track {\n background-color: GrayText;\n }\n\n .md-progress-indicator__circular-track {\n stroke: GrayText;\n }\n\n .md-progress-indicator__circular-active,\n .md-progress-indicator__circular-active-path {\n stroke: CanvasText;\n }\n\n .md-progress-indicator__linear-wave-path {\n fill: CanvasText;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, Element, Watch, State, Event, EventEmitter } from '@stencil/core';\n\n/* ============================================================================\n * Material Design 3 — Progress Indicator (Expressive generation)\n * Spec: https://m3.material.io/components/progress-indicators/specs\n *\n * Conforms to the 2024+ \"expressive\" generation (the version shown on\n * m3.material.io today): animated wavy waveforms, 4dp indicator↔track gaps,\n * round caps, and the expressive indeterminate motion. Constants below were\n * verified against the Compose Material3 source (the authoritative source for\n * the wavy geometry/motion) and Material Web (baseline CSS/tokens).\n * ==========================================================================*/\n\n/** Indicator↔track gap (dp). Fixed token — NOT coupled to thickness. */\nconst GAP_DP = 4;\n/** Wavelength (dp) for the linear wave (both determinate and indeterminate). */\nconst LINEAR_DET_WAVELENGTH = 40;\nconst CIRCULAR_WAVELENGTH = 15;\n/** Peak amplitudes (dp) at amplitude factor = 1. */\nconst LINEAR_AMPLITUDE = 3;\nconst CIRCULAR_AMPLITUDE = 1.6;\n/** Circular container sizes (dp): non-wavy 40, wavy 48. */\nconst CIRCULAR_SIZE_FLAT = 40;\nconst CIRCULAR_SIZE_WAVE = 48;\n/** M3 circular size range (dp): 24 (min) … 240 (max). Sizes are clamped here. */\nconst CIRCULAR_SIZE_MIN = 24;\nconst CIRCULAR_SIZE_MAX = 240;\n/** Wave path sampling density (control points per wavelength). Catmull-Rom\n * smooths between samples, so ~8 is plenty for a clean sine and keeps the\n * per-frame path rebuild cheap. */\nconst WAVE_SAMPLES_PER_WL = 8;\n/** Amplitude in/out animation: 500ms; in = EasingStandard, out = EmphasizedAccelerate. */\nconst AMP_DURATION = 500;\nconst AMP_IN: Bezier = [0.2, 0, 0, 1];\nconst AMP_OUT: Bezier = [0.3, 0, 0.8, 0.15];\n/** Circular indeterminate choreography (Compose expressive). */\nconst CIRCULAR_INDET_CYCLE = 6000;\nconst CIRCULAR_INDET_MIN = 0.1;\nconst CIRCULAR_INDET_MAX = 0.87;\nconst CIRCULAR_GLOBAL_ROTATION = 1080; // deg per cycle\nconst MIN_CIRCULAR_VERTICES = 5;\n\ntype Bezier = [number, number, number, number];\n\n/* ── cubic-bézier easing solver (maps time fraction → eased fraction) ──────*/\nfunction bezierEasing([x1, y1, x2, y2]: Bezier): (t: number) => number {\n if (x1 === y1 && x2 === y2) return (t) => t; // linear\n const cx = 3 * x1;\n const bx = 3 * (x2 - x1) - cx;\n const ax = 1 - cx - bx;\n const cy = 3 * y1;\n const by = 3 * (y2 - y1) - cy;\n const ay = 1 - cy - by;\n const sampleX = (t: number) => ((ax * t + bx) * t + cx) * t;\n const sampleY = (t: number) => ((ay * t + by) * t + cy) * t;\n const slopeX = (t: number) => (3 * ax * t + 2 * bx) * t + cx;\n return (x) => {\n if (x <= 0) return 0;\n if (x >= 1) return 1;\n let t = x;\n for (let i = 0; i < 8; i++) {\n const xt = sampleX(t) - x;\n const d = slopeX(t);\n if (Math.abs(xt) < 1e-5) break;\n if (Math.abs(d) < 1e-6) break;\n t -= xt / d;\n }\n return sampleY(Math.min(1, Math.max(0, t)));\n };\n}\nconst EASE_IN = bezierEasing(AMP_IN);\nconst EASE_OUT = bezierEasing(AMP_OUT);\nconst EASE_STANDARD = bezierEasing([0.2, 0, 0, 1]);\n\n@Component({\n tag: 'md-progress-indicator',\n styleUrl: 'md-progress-indicator.css',\n shadow: true,\n})\nexport class MdProgressIndicator {\n @Element() el!: HTMLElement;\n\n /** Visual variant: linear (horizontal bar) or circular (ring). */\n @Prop() variant: 'circular' | 'linear' = 'linear';\n\n /** Current progress value (0 to max). */\n @Prop() value: number = 0;\n\n /** Maximum progress value. */\n @Prop() max: number = 100;\n\n /** Indeterminate mode — looping animation when progress is unknown. */\n @Prop({ reflect: true }) indeterminate: boolean = false;\n\n /** Track / stroke thickness in dp. */\n @Prop() thickness: number = 4;\n\n /** Enable the wavy (M3 Expressive) active indicator. */\n @Prop({ reflect: true }) wave: boolean = false;\n\n /**\n * Wave amplitude (center-to-peak) in dp. `0` = auto per M3 spec\n * (linear 3dp, circular 1.6dp).\n */\n @Prop({ attribute: 'wave-amplitude' }) waveAmplitude: number = 0;\n\n /**\n * Wavelength (peak-to-peak) in dp. `0` = auto\n * (linear 40dp for both determinate + indeterminate, circular 15dp).\n */\n @Prop({ attribute: 'wave-length' }) waveLength: number = 0;\n\n /**\n * Wave travel speed in dp/second. `0` = auto (= wavelength, i.e. one\n * wavelength per second per the M3 default).\n */\n @Prop({ attribute: 'wave-speed' }) waveSpeed: number = 0;\n\n /**\n * Circular indicator outer size in dp. `0` = auto (non-wavy 40dp,\n * wavy 48dp per the M3 expressive spec). Clamped to the M3 range 24–240dp.\n */\n @Prop() size: number = 0;\n\n /** Four-color cycling animation (circular indeterminate only). */\n @Prop({ attribute: 'four-color', reflect: true }) fourColor: boolean = false;\n\n /** Accessible label for screen readers. */\n @Prop() label: string = 'Progress';\n\n /**\n * Set to `true` to trigger the completion (\"closing TV\") animation. After it\n * plays, the indicator self-hides (`visibility:hidden`) and emits `mdComplete` —\n * EXCEPT the flat (non-wavy) circular variant, which instead rests showing its\n * empty track ring (the active indicator erases away and the track fades in).\n * No-op on indeterminate indicators.\n */\n @Prop() complete: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fired when the completion animation finishes (and the indicator has hidden\n * itself, or — for flat circular — settled on its empty track ring). */\n @Event() mdComplete!: EventEmitter<void>;\n\n /** Tracks the user's reduced-motion preference (drives the flat wave). */\n @State() private reducedMotion: boolean = false;\n @State() private _completing = false;\n @State() private _completed = false;\n /** Flat circular terminal state: active erased, empty track ring left visible\n * (the variant that does NOT self-hide on completion). */\n @State() private _completedTrack = false;\n @State() private _fillComplete = false;\n\n // ── animation state ──────────────────────────────────────────────────────\n private raf = 0;\n private phase = 0; // circular wave phase (radians)\n private linearPhase = 0; // linear wavy determinate phase (radians)\n private amp = 0; // current animated amplitude factor (0..1)\n private ampFrom = 0;\n private ampTo = 0;\n private ampStartTs = -1;\n private ampEase: (t: number) => number = EASE_IN;\n private lastTs = -1;\n private indetStartTs = -1;\n private renderFraction = 0; // eased sweep for the wavy circular determinate arc\n private linearRenderFraction = 0; // eased fill for the wavy linear determinate path\n private activeRef?: SVGPathElement;\n private trackRef?: SVGPathElement;\n private linearWaveRef: SVGPathElement | null = null;\n private linearWaveSvgRef: SVGSVGElement | null = null;\n private linearWaveTrackRef: HTMLDivElement | null = null;\n private flatActiveRef: HTMLDivElement | null = null;\n private flatTrackRef: HTMLDivElement | null = null;\n private indetBar1Ref: HTMLDivElement | null = null;\n private indetBar2Ref: HTMLDivElement | null = null;\n private indetPath1Ref: SVGPathElement | null = null;\n private indetPath2Ref: SVGPathElement | null = null;\n private indetTrackRef: HTMLDivElement | null = null;\n private rotRef?: SVGGElement;\n private mql?: MediaQueryList;\n private io?: IntersectionObserver;\n private ro?: ResizeObserver;\n private linearWidth = 0; // cached layout width (refreshed on render + resize)\n private visible = true;\n private rtl = false; // cached layout direction (refreshed each render)\n\n // ── completion animation state ────────────────────────────────────────────\n private completingFromFrac = 0;\n private activeCircleRef?: SVGCircleElement;\n private circularFlatTrackRef: SVGCircleElement | null = null;\n // Path used ONLY during the flat completion sequence: the erase/fill arc is drawn\n // here as an explicit round-capped <path> (not the dashed <circle>) so the head\n // doesn't jitter the way an animated stroke-dashoffset on a circle does.\n private circularFlatCompleteRef: SVGPathElement | null = null;\n\n // ── circular completion (unified flat + wavy rAF state machine) ───────────\n // Phase 1: fill the arc from the current fraction → a full circle (one pass).\n // Phase 2: (wavy only) flatten the wave amplitude → 0 so it becomes a ring.\n // Phase 3: after a brief hold, erase the ring from the START point, progressively\n // shrinking it clockwise until nothing is left (no track shown).\n // Phase 4: (flat circular only) the line is gone — fade the empty track ring IN,\n // then settle on it (flat circular rests on its track, doesn't self-hide).\n // Driven entirely by plain fields + rAF (NOT @State) so no Stencil re-render\n // detaches the SVG elements mid-animation — that detach was what produced the\n // \"two passes\" (the CSS stroke-dasharray transition re-drawing the arc while\n // the JS animation was also drawing it).\n private ccPhase: 0 | 1 | 2 | 3 | 4 = 0;\n private ccStart = -1;\n private ccFrac = 0; // animated fill fraction during phase 1\n private ccErase = 0; // erase progress 0..1 during phase 3\n private readonly CC_FILL_DUR = 500; // ms\n private readonly CC_FLATTEN_DUR = 300; // ms (wavy only)\n private readonly CC_WAIT = 150; // ms hold at full circle before erasing\n private readonly CC_ERASE_DUR = 550; // ms\n private readonly CC_TRACK_REVEAL_DUR = 300; // ms (flat circular: fade the empty track ring in after the erase)\n\n // ── wave linear completion (multi-phase rAF sequence) ─────────────────────\n // Phase 1: fill the wave path from current fraction → 1 (WLC_FILL_DUR ms)\n // Phase 2: tween amplitude → 0 so the wave flattens (AMP_DURATION ms)\n // After phase 2: set _completing = true → CSS scaleY collapse plays\n private wlcPhase: 0 | 1 | 2 = 0;\n private wlcStart = -1;\n private wlcFromFrac = 0;\n private wlcFrac = 0;\n private readonly WLC_FILL_DUR = 300; // ms to fill wave path to 100%\n private readonly WLC_FLATTEN_DUR = 300; // ms to flatten wave to a straight line\n\n // ── flat linear completion (rAF fill phase) ───────────────────────────────\n // Phase 1: ease the fill fraction → 1 (sharing the wavy variant's ease), then\n // hand off to the CSS scaleY collapse. Driven by the same linearRenderFraction\n // as the steady-state fill so the flat + wavy variants stay perfectly in sync.\n private flcPhase: 0 | 1 = 0;\n\n // ── derived geometry ──────────────────────────────────────────────────────\n private get fraction(): number {\n if (!this.max) return 0;\n return Math.min(1, Math.max(0, this.value / this.max));\n }\n\n private get densityScale(): number {\n if (!this.el) return 0;\n const v = getComputedStyle(this.el).getPropertyValue('--md-sys-density-scale').trim();\n return v ? Number(v) : 0;\n }\n\n private get resolvedSize(): number {\n const density = this.densityScale;\n const s = this.size > 0 ? this.size : (this.wave ? CIRCULAR_SIZE_WAVE : CIRCULAR_SIZE_FLAT) + density * 3;\n return Math.min(CIRCULAR_SIZE_MAX, Math.max(CIRCULAR_SIZE_MIN, s));\n }\n\n private get resolvedWavelength(): number {\n if (this.waveLength > 0) return this.waveLength;\n if (this.variant === 'circular') return CIRCULAR_WAVELENGTH;\n return LINEAR_DET_WAVELENGTH;\n }\n\n private get resolvedAmplitude(): number {\n if (this.waveAmplitude > 0) return this.waveAmplitude;\n if (this.variant === 'circular') return CIRCULAR_AMPLITUDE;\n return LINEAR_AMPLITUDE;\n }\n\n private get resolvedThickness(): number {\n if (this.thickness !== 4) return this.thickness;\n return Math.max(2, 4 + this.densityScale * 0.5);\n }\n\n /** Stroke width of the wave path — density-scaled like everything else. */\n private get resolvedWaveStroke(): number {\n return this.resolvedThickness;\n }\n\n /** Effective thickness for all geometry. */\n private get effectiveThickness(): number {\n return this.resolvedThickness;\n }\n\n private get resolvedWaveSpeed(): number {\n if (this.waveSpeed > 0) return this.waveSpeed;\n return this.resolvedWavelength;\n }\n\n /** Fixed wavy linear container height (2·amp + wave stroke; 10dp at determinate\n * defaults). Uses the (possibly bolder) wave stroke so the mask viewBox and\n * the band height both contain the round caps. */\n private get linearWaveHeight(): number {\n return 2 * this.resolvedAmplitude + this.resolvedWaveStroke;\n }\n\n /**\n * Amplitude *target* (0..1). Indeterminate is always full; determinate\n * flattens to 0 at the endpoints (≤10% / ≥95%). Reduced motion → flat.\n */\n private get amplitudeTarget(): number {\n if (!this.wave || this.reducedMotion) return 0;\n if (this.indeterminate) return 1;\n // Determinate: fully wavy from the first bit of progress all the way through\n // 100 % (and through the closing animation) — NO endpoint flatten. At the\n // very start the fill is shorter than one wavelength, so it naturally reads\n // as a dot, then progresses DIRECTLY to wavy; at 100 % it stays wavy and the\n // \"closing TV\" animation collapses the wave shape rather than a flat line.\n return this.fraction > 0 ? 1 : 0;\n }\n\n // ── lifecycle ─────────────────────────────────────────────────────────────\n componentWillLoad() {\n this.amp = this.amplitudeTarget;\n this.ampTo = this.amp;\n this.renderFraction = this.fraction;\n this.linearRenderFraction = this.fraction;\n this.syncHostStyles();\n if (typeof window !== 'undefined' && window.matchMedia) {\n this.mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n this.reducedMotion = this.mql.matches;\n this.mql.addEventListener?.('change', this.onReducedMotionChange);\n }\n }\n\n componentDidLoad() {\n if (typeof IntersectionObserver !== 'undefined') {\n this.io = new IntersectionObserver((entries) => {\n this.visible = entries.some((e) => e.isIntersecting);\n this.ensureLoop();\n });\n this.io.observe(this.el);\n }\n // Refresh the cached width (and repaint) only on actual resizes — so the\n // per-frame loop never has to call getBoundingClientRect (which would force\n // a synchronous layout every frame).\n if (typeof ResizeObserver !== 'undefined') {\n this.ro = new ResizeObserver(() => {\n this.measureLinearWidth();\n this.updateLinearPath();\n });\n this.ro.observe(this.el);\n }\n this.ensureLoop();\n }\n\n componentDidRender() {\n this.ensureLoop();\n // Refresh the cached layout direction (inherited from ancestors via dir=rtl).\n this.rtl = this.computeRtl();\n // Keep the SVG path in sync when the fill width changes while the phase\n // loop isn't running (e.g. the wave is flat near 0% / ≥95%).\n if (this.wave && this.variant === 'linear' && !this.indeterminate) {\n this.measureLinearWidth(); // once per render, NOT per animation frame\n // Don't overwrite the path while the rAF loop owns it (wlcPhase > 0)\n // or after completion has frozen it (_completing / _completed).\n if (this.wlcPhase === 0 && !this._completing && !this._completed) {\n // If the rAF loop isn't running (amp=0, reduced motion), snap the eased\n // fraction so the path stays at the actual value with no lag.\n if (!this.raf) this.linearRenderFraction = this.fraction;\n this.updateLinearPath();\n }\n }\n // Flat linear determinate: the fill + track are rAF-driven (same as the wavy\n // variant) so they share its motion exactly. Keep them in sync when the loop\n // isn't running (reduced motion, off-screen, settled) by snapping the value.\n if (!this.wave && this.variant === 'linear' && !this.indeterminate) {\n if (this.flcPhase === 0 && !this._completing && !this._completed) {\n if (!this.raf) this.linearRenderFraction = this.fraction;\n this.updateLinearFlat();\n }\n }\n // Flat circular determinate: active arc + track are rAF-driven (mirrors the wavy\n // variant) so they recede in lockstep. Keep them in sync when the loop isn't\n // running (reduced motion, off-screen, settled) by snapping the eased value.\n if (this.variant === 'circular' && !this.wave && !this.indeterminate) {\n if (this.ccPhase === 0 && !this._completing && !this._completed && !this._completedTrack) {\n if (!this.raf) this.renderFraction = this.fraction;\n this.updateCircularFlat();\n }\n }\n }\n\n /** Measure + cache the linear layout width. Called on render and on resize\n * (never inside the rAF loop) so the per-frame path repaint stays layout-free. */\n private measureLinearWidth(): number {\n const w =\n this.linearWaveSvgRef?.getBoundingClientRect().width ||\n this.el.getBoundingClientRect().width ||\n this.el.clientWidth ||\n 0;\n if (w) this.linearWidth = w;\n return this.linearWidth;\n }\n\n private computeRtl(): boolean {\n if (typeof getComputedStyle === 'undefined' || !this.el) return false;\n return getComputedStyle(this.el).direction === 'rtl';\n }\n\n disconnectedCallback() {\n this.stopLoop();\n this.mql?.removeEventListener?.('change', this.onReducedMotionChange);\n this.io?.disconnect();\n this.ro?.disconnect();\n }\n\n private onReducedMotionChange = (e: MediaQueryListEvent) => {\n this.reducedMotion = e.matches;\n };\n\n @Watch('thickness')\n @Watch('size')\n @Watch('wave')\n @Watch('waveAmplitude')\n @Watch('waveLength')\n @Watch('variant')\n onDimensionChange() {\n this.syncHostStyles();\n }\n\n @Watch('value')\n @Watch('max')\n @Watch('indeterminate')\n @Watch('wave')\n @Watch('reducedMotion')\n onAmplitudeInputChange() {\n if (this.ccPhase > 0) return; // a completion sequence owns the geometry\n this.retargetAmplitude();\n // A value change also needs to wake the loop so the wavy circular sweep\n // can ease toward its new target (renderFraction → fraction).\n this.ensureLoop();\n }\n\n @Watch('complete')\n onCompleteChange(next: boolean) {\n if (!next || this.indeterminate || this._completing || this._completed || this._completedTrack || this.ccPhase > 0) return;\n\n // Wave linear: multi-phase rAF sequence (fill → flatten → scaleY collapse).\n // Snap amp to 1 now so the flatten always starts from a fully visible wave.\n if (this.variant === 'linear' && this.wave) {\n this.amp = 1;\n this.ampFrom = 1;\n this.ampTo = 1;\n this.ampStartTs = -2;\n this.wlcPhase = 1;\n this.wlcStart = -1;\n this.wlcFromFrac = this.fraction;\n this.wlcFrac = this.fraction;\n this.ensureLoop();\n return;\n }\n\n // Flat linear: ease the fill to 100% (driven by the SAME linearRenderFraction\n // + ease as the wavy variant, so both fill identically), then collapse.\n if (this.variant === 'linear' && !this.wave) {\n if (this.reducedMotion || typeof requestAnimationFrame === 'undefined') {\n // No rAF available — snap to full, then collapse (transitions are 0s under\n // reduced motion so the fill jumps and the scaleY collapse plays).\n this._fillComplete = true;\n this._completing = true;\n return;\n }\n this.flcPhase = 1;\n this.ensureLoop();\n return;\n }\n\n // Circular (flat + wavy): unified rAF state machine (fill → flatten → erase).\n // Reduced motion has no rAF loop — snap straight to hidden.\n if (this.reducedMotion || typeof requestAnimationFrame === 'undefined') {\n this.handleComplete();\n return;\n }\n // Snap the eased sweep to its target so the determinate fill that just finished\n // is NOT re-driven from a lagging renderFraction (the wavy \"second pass\" where\n // Phase 1 grew the arc ~93% → 100% again), and so the flat hand-off from the\n // dashed <circle> to the completion <path> starts at exactly the shown arc.\n this.renderFraction = this.fraction;\n this.completingFromFrac = this.fraction;\n this.ccFrac = this.completingFromFrac;\n this.ccErase = 0;\n this.ccStart = -1;\n // Wavy closes on the wave shape: hold full amplitude through fill + flatten.\n if (this.wave) {\n this.amp = 1;\n this.ampTo = 1;\n this.ampStartTs = -2;\n this.ampFrom = this.amp;\n }\n // Already at (or essentially at) 100% — there is nothing to fill, so skip the\n // dead Phase-1 hold and go straight to flatten (wavy) / erase (flat).\n if (this.completingFromFrac >= 1 - 1e-3) {\n this.ccFrac = 1;\n this.ccPhase = this.wave ? 2 : 3;\n } else {\n this.ccPhase = 1;\n }\n this.ensureLoop();\n }\n\n private handleComplete() {\n this._completing = false;\n this._fillComplete = false;\n this.ccPhase = 0;\n this.flcPhase = 0;\n // Flat circular rests on its empty track ring instead of self-hiding; every\n // other variant hides via the --complete host rule.\n if (this.variant === 'circular' && !this.wave) {\n this._completedTrack = true;\n } else {\n this._completed = true;\n }\n this.mdComplete.emit();\n }\n\n private onLinearAnimEnd = (e: AnimationEvent) => {\n if (e.animationName === 'md-linear-complete') this.handleComplete();\n };\n\n private syncHostStyles() {\n const s = this.el?.style;\n if (!s) return;\n const t = this.resolvedThickness;\n s.setProperty('--_thickness', `${t}px`);\n s.setProperty('--_linear-height', `${this.wave ? this.linearWaveHeight : t}px`);\n if (this.variant === 'circular' || this.size > 0) {\n s.setProperty('--_size', `${this.resolvedSize}px`);\n } else {\n s.removeProperty('--_size');\n }\n\n if (this.wave && this.variant === 'linear') {\n const wl = this.resolvedWavelength;\n s.setProperty('--_wave-length-px', `${wl}px`);\n s.setProperty('--_wave-mask-size', `${wl}px ${this.linearWaveHeight}px`);\n // duration (ms) for one wavelength of travel at the resolved speed\n const dur = Math.max(50, Math.round((wl / this.resolvedWaveSpeed) * 1000));\n s.setProperty('--_wave-duration', `${dur}ms`);\n this.updateLinearMask();\n } else {\n ['--_wave-length-px', '--_wave-mask', '--_wave-mask-size', '--_wave-duration'].forEach((p) =>\n s.removeProperty(p),\n );\n }\n\n this.syncSpinnerTrackVars(s);\n }\n\n /**\n * Precompute the flat circular-indeterminate \"complement track\" keyframe values\n * as resolved CSS vars. The active arc (md-circular-dash) occupies path-fraction\n * [k, k+L] with k = −dashoffset; the gap-following track is the complement\n * [k+L+g, k+1−g] → dash length T = (1 − L − 2g), arc start offset = (O − L − g).\n *\n * CRITICAL: the dash is emitted as `T (1−T)` — NOT `T 1` — so the dash PERIOD\n * equals the path length (pathLength=1). Only then does a track arc that crosses\n * the 12-o'clock seam wrap correctly (with `T 1` the period is T+1 > 1, so the\n * wrapped portion lands outside [0,1) and is never painted — the track would\n * vanish for most of the cycle). Both `T (1−T)` endpoints sum to 1, so linear\n * keyframe interpolation keeps the period exactly 1 at every intermediate frame,\n * and the complement (T = 1−L−2g, affine in the same eased L,O) holds throughout.\n */\n private syncSpinnerTrackVars(s: CSSStyleDeclaration) {\n if (this.variant !== 'circular') return;\n const r = this.circularRadius;\n const C = 2 * Math.PI * r;\n const g = C > 0 ? (GAP_DP + this.effectiveThickness) / C : 0;\n // Active keyframes (L, O): 0.05/0 → 0.70/−0.18 → 0.05/−0.92\n const emit = (key: string, L: number, O: number) => {\n const T = Math.max(0.0001, Math.min(1, 1 - L - 2 * g));\n s.setProperty(`--_spin-da-${key}`, T.toFixed(4)); // dash length\n s.setProperty(`--_spin-gap-${key}`, (1 - T).toFixed(4)); // gap → period = 1\n s.setProperty(`--_spin-do-${key}`, (O - L - g).toFixed(4)); // arc-start offset\n };\n emit('0', 0.05, 0);\n emit('50', 0.7, -0.18);\n emit('100', 0.05, -0.92);\n }\n\n // ── amplitude animation (rAF tween shared by linear + circular) ───────────\n private retargetAmplitude() {\n if (this.wlcPhase > 0 || this.ccPhase > 0) return; // completion drives amp directly\n const target = this.amplitudeTarget;\n if (target === this.ampTo && this.ampStartTs < 0) return;\n if (target === this.ampTo) return;\n this.ampFrom = this.amp;\n this.ampTo = target;\n this.ampEase = target > this.ampFrom ? EASE_IN : EASE_OUT;\n this.ampStartTs = -1; // (re)start on next frame\n if (this.reducedMotion || typeof requestAnimationFrame === 'undefined') {\n // No animation available — snap.\n this.amp = target;\n this.ampStartTs = -2;\n this.applyAmplitude();\n return;\n }\n this.ensureLoop();\n }\n\n /** Push the current amplitude into the active renderer (mask or path). */\n private applyAmplitude() {\n if (this.variant === 'linear') {\n if (this.wave && !this.indeterminate) this.updateLinearPath();\n else if (!this.wave) this.updateLinearMask();\n // wave + indeterminate: the rAF loop calls updateLinearIndeterminate() each frame\n } else {\n this.updateCircularPath();\n }\n }\n\n // ── the rAF loop ──────────────────────────────────────────────────────────\n private shouldAnimate(): boolean {\n if (typeof requestAnimationFrame === 'undefined') return false;\n if (!this.visible || this.reducedMotion) return false;\n // Circular completion (flat + wavy) runs its own multi-phase rAF sequence.\n if (this.ccPhase > 0) return true;\n // Wave linear completion runs its own multi-phase rAF sequence.\n if (this.wlcPhase > 0) return true;\n // Linear completion is CSS-driven; no rAF needed while completing.\n if (this._completing && this.variant === 'linear') return false;\n // Circular wavy needs a persistent loop for phase travel (amp > 0), an\n // in-flight amplitude tween, an unsettled sweep, or indeterminate motion.\n if (this.variant === 'circular' && this.wave) {\n if (this.indeterminate) return true;\n return (\n this.amp > 0 ||\n this.amp !== this.ampTo ||\n Math.abs(this.renderFraction - this.fraction) > 1e-3\n );\n }\n // Flat circular determinate: loop while the eased sweep hasn't caught up to the\n // value, so the active arc + track repaint in lockstep (mirrors wavy circular).\n // Once it has settled on its terminal track ring, stay put.\n if (this.variant === 'circular' && !this.wave && !this.indeterminate) {\n return !this._completedTrack && Math.abs(this.renderFraction - this.fraction) > 1e-3;\n }\n // Linear wavy determinate: loop while wave is active, tween in-flight, or\n // the fill fraction hasn't caught up yet (keeps the path in sync with value).\n if (this.variant === 'linear' && this.wave && !this.indeterminate) {\n return this.amp > 0 || this.amp !== this.ampTo ||\n Math.abs(this.linearRenderFraction - this.fraction) > 1e-3;\n }\n // Linear wavy indeterminate: always loop (JS draws both bars each frame).\n if (this.variant === 'linear' && this.wave && this.indeterminate) return true;\n // Flat linear determinate: loop while the fill is easing toward the value (so\n // it moves with the SAME smoothness as the wavy variant) or while completing.\n if (this.variant === 'linear' && !this.wave && !this.indeterminate) {\n if (this.flcPhase > 0) return true;\n return Math.abs(this.linearRenderFraction - this.fraction) > 1e-3;\n }\n return false;\n }\n\n private ensureLoop() {\n if (this.shouldAnimate()) {\n if (!this.raf) this.raf = requestAnimationFrame(this.frame);\n } else if (this.amp === this.ampTo) {\n this.stopLoop();\n }\n }\n\n private stopLoop() {\n if (this.raf) cancelAnimationFrame(this.raf);\n this.raf = 0;\n this.lastTs = -1;\n // Re-anchor the indeterminate choreography on the next resume so it\n // restarts at t=0 instead of jumping by the elapsed wall-clock time.\n this.indetStartTs = -1;\n }\n\n private frame = (ts: number) => {\n this.raf = 0;\n if (this.lastTs < 0) this.lastTs = ts;\n const dt = Math.min(64, ts - this.lastTs); // clamp long gaps\n this.lastTs = ts;\n\n // Circular completion (flat + wavy): fill → (wavy) flatten → hold → erase.\n if (this.ccPhase > 0 && this.variant === 'circular') {\n if (this.ccStart < 0) this.ccStart = ts;\n // Keep the wave travelling for visual continuity through fill + flatten.\n if (this.wave) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.phase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.phase > 1e6) this.phase = this.phase % (2 * Math.PI);\n }\n\n if (this.ccPhase === 1) {\n // Fill: arc grows from the current fraction to a full circle (one pass).\n const t = Math.min(1, (ts - this.ccStart) / this.CC_FILL_DUR);\n this.ccFrac = this.completingFromFrac + (1 - this.completingFromFrac) * EASE_STANDARD(t);\n this.paintCircularCompletion();\n if (t >= 1) {\n this.ccFrac = 1;\n this.ccStart = ts;\n if (this.wave) {\n this.ccPhase = 2;\n this.ampFrom = this.amp;\n } else {\n this.ccPhase = 3;\n }\n }\n } else if (this.ccPhase === 2) {\n // Flatten (wavy only): wave amplitude eases to 0 → a plain ring.\n const t = Math.min(1, (ts - this.ccStart) / this.CC_FLATTEN_DUR);\n this.amp = this.ampFrom * (1 - EASE_IN(t));\n this.paintCircularCompletion();\n if (t >= 1) {\n this.amp = 0;\n this.ccPhase = 3;\n this.ccStart = ts;\n }\n } else if (this.ccPhase === 3) {\n // Erase: after a brief hold, remove the ring from the 12 o'clock start\n // outward (clockwise) until nothing remains. The track stays hidden.\n const t = Math.min(1, (ts - this.ccStart - this.CC_WAIT) / this.CC_ERASE_DUR);\n this.ccErase = t <= 0 ? 0 : EASE_STANDARD(t);\n this.paintCircularCompletion();\n if (t >= 1) {\n if (!this.wave) {\n // Flat circular: line is gone — fade the empty track ring IN (Phase 4).\n this.ccPhase = 4;\n this.ccStart = ts;\n } else {\n // Wavy circular self-hides.\n this.handleComplete();\n this.stopLoop();\n return;\n }\n }\n } else {\n // Phase 4 (flat circular only): the line has fully erased; fade the empty\n // track ring in, then settle on it (handleComplete → _completedTrack).\n const t = Math.min(1, (ts - this.ccStart) / this.CC_TRACK_REVEAL_DUR);\n this.circularFlatCompleteRef?.setAttribute('d', ''); // line gone\n if (this.activeCircleRef) this.activeCircleRef.style.opacity = '0';\n if (this.circularFlatTrackRef) {\n const tr = this.circularFlatTrackRef;\n tr.removeAttribute('stroke-dasharray'); // full ring\n tr.removeAttribute('stroke-dashoffset');\n tr.style.opacity = `${EASE_STANDARD(t)}`;\n }\n if (t >= 1) {\n this.handleComplete();\n this.stopLoop();\n return;\n }\n }\n this.raf = requestAnimationFrame(this.frame);\n return;\n }\n\n // Wave linear completion: phase 1 fills the path to 100%, phase 2 flattens amp to 0.\n if (this.wlcPhase > 0) {\n if (this.wlcStart < 0) this.wlcStart = ts;\n // Keep the wave travelling for visual continuity throughout.\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.linearPhase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.linearPhase > 1e6) this.linearPhase = this.linearPhase % (2 * Math.PI);\n\n if (this.wlcPhase === 1) {\n const t = Math.min(1, (ts - this.wlcStart) / this.WLC_FILL_DUR);\n this.wlcFrac = this.wlcFromFrac + (1 - this.wlcFromFrac) * EASE_STANDARD(t);\n this.updateLinearPath();\n if (t >= 1) {\n this.wlcFrac = 1;\n this.wlcPhase = 2;\n this.wlcStart = ts;\n this.ampFrom = 1; // always flatten from full amplitude\n this.ampTo = 0;\n this.ampEase = EASE_IN; // holds the wave shape longer then snaps flat\n this.ampStartTs = ts;\n }\n } else {\n const t = Math.min(1, (ts - this.ampStartTs) / this.WLC_FLATTEN_DUR);\n this.amp = this.ampFrom * (1 - this.ampEase(t));\n this.updateLinearPath();\n if (t >= 1) {\n this.amp = 0;\n this.wlcPhase = 0;\n this._completing = true; // scaleY collapse plays, then onLinearAnimEnd → handleComplete\n this.stopLoop();\n return;\n }\n }\n this.raf = requestAnimationFrame(this.frame);\n return;\n }\n\n // amplitude tween\n if (this.amp !== this.ampTo) {\n if (this.ampStartTs < 0) this.ampStartTs = ts;\n const t = Math.min(1, (ts - this.ampStartTs) / AMP_DURATION);\n this.amp = this.ampFrom + (this.ampTo - this.ampFrom) * this.ampEase(t);\n if (t >= 1) {\n this.amp = this.ampTo;\n this.ampStartTs = -2;\n }\n }\n\n // circular phase travel + eased determinate sweep\n if (this.variant === 'circular' && this.wave) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength; // waves/sec\n this.phase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.phase > 1e6) this.phase = this.phase % (2 * Math.PI);\n // ease the rendered sweep toward the target (~500ms settle)\n const k = 1 - Math.exp(-dt / 160);\n this.renderFraction += (this.fraction - this.renderFraction) * k;\n if (Math.abs(this.fraction - this.renderFraction) < 1e-3) this.renderFraction = this.fraction;\n this.updateCircularPath();\n } else if (this.variant === 'circular' && !this.wave && !this.indeterminate) {\n // Flat circular determinate: ease the sweep toward the value with the SAME\n // ~500ms (160ms time-constant) settle the wavy circular uses, then repaint the\n // active arc + track in lockstep — the track recedes exactly as the arc grows\n // (no early unmount) and its final sliver fades out (no pop).\n const k = 1 - Math.exp(-dt / 160);\n this.renderFraction += (this.fraction - this.renderFraction) * k;\n if (Math.abs(this.fraction - this.renderFraction) < 1e-3) this.renderFraction = this.fraction;\n this.updateCircularFlat();\n } else if (this.variant === 'linear' && this.wave && !this.indeterminate) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.linearPhase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.linearPhase > 1e6) this.linearPhase = this.linearPhase % (2 * Math.PI);\n // Ease the fill toward the target with the same ~80ms time constant as the\n // flat linear's 250ms CSS transition so both variants move in sync.\n if (this.wlcPhase === 0) {\n const k = 1 - Math.exp(-dt / 80);\n this.linearRenderFraction += (this.fraction - this.linearRenderFraction) * k;\n if (Math.abs(this.fraction - this.linearRenderFraction) < 1e-3)\n this.linearRenderFraction = this.fraction;\n }\n this.updateLinearPath();\n } else if (this.variant === 'linear' && this.wave && this.indeterminate) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.linearPhase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.linearPhase > 1e6) this.linearPhase = this.linearPhase % (2 * Math.PI);\n this.updateLinearIndeterminate();\n } else if (this.variant === 'linear' && !this.wave && !this.indeterminate) {\n // Flat linear determinate: ease the fill toward the value (or → 1 while\n // completing) with the SAME 80ms time-constant the wavy variant uses, so the\n // two move in lockstep and the track recedes with identical smoothness.\n const target = this.flcPhase === 1 ? 1 : this.fraction;\n const k = 1 - Math.exp(-dt / 80);\n this.linearRenderFraction += (target - this.linearRenderFraction) * k;\n if (Math.abs(target - this.linearRenderFraction) < 1e-3) {\n this.linearRenderFraction = target;\n if (this.flcPhase === 1) {\n this.flcPhase = 0;\n this.updateLinearFlat();\n this._completing = true; // scaleY collapse → onLinearAnimEnd → handleComplete\n this.stopLoop();\n return;\n }\n }\n this.updateLinearFlat();\n } else {\n this.applyAmplitude();\n }\n\n if (this.shouldAnimate()) {\n this.raf = requestAnimationFrame(this.frame);\n } else {\n this.stopLoop();\n }\n };\n\n // ── linear wave SVG path (determinate) ───────────────────────────────────\n /**\n * Repaint the filled wave path each frame. The path is a closed filled shape\n * (top edge + right round-cap arc + bottom edge + Z) so the wave body and\n * cap are one continuous element — no coordinate-space mismatch possible.\n */\n private updateLinearPath() {\n if (!(this.wave && this.variant === 'linear' && !this.indeterminate)) return;\n if (!this.linearWaveRef) return;\n // Use the cached width (refreshed on render + resize, not per frame) so the\n // hot loop never forces a synchronous layout. Measure lazily if not set yet.\n const W = this.linearWidth || this.measureLinearWidth();\n if (!W) return;\n // During completion wlcFrac drives the fill; otherwise use the eased\n // linearRenderFraction so the wavy path moves in sync with the flat bar.\n const frac = this.wlcPhase > 0 ? this.wlcFrac : this.linearRenderFraction;\n const fillX = frac * W;\n // RTL: progress fills from the right edge, so draw the wave at [W−fillX, W]\n // (the round leading cap then lands at W−fillX, the growing tip). LTR draws\n // at [0, fillX]. Done in JS — in the same coordinate space as the logical-\n // property track/stop — so there is no CSS transform-origin ambiguity.\n let d = '';\n if (fillX > 0) {\n // inset=true → round caps sit inside [edge, fillX] like the flat bar, so the\n // start (x=0 / RTL x=W) and the leading tip aren't sheared square by the clip.\n d = this.rtl\n ? this.buildLinearWaveSVGPath(W - fillX, W, this.amp, this.linearPhase, true)\n : this.buildLinearWaveSVGPath(0, fillX, this.amp, this.linearPhase, true);\n }\n this.linearWaveRef.setAttribute('d', d);\n\n // Lock the track's leading edge to the SAME eased fraction that drew the wave\n // (NOT the instant `fraction`), so the indicator↔track gap stays a constant\n // 4dp while the value animates. The flat variant achieves this by CSS-\n // transitioning the track in lockstep with the bar; the wave path is repainted\n // per-frame in JS, so its track must be driven per-frame from the same source —\n // otherwise the track jumps to the target while the wave edge eases behind it,\n // stretching the gap mid-animation. Logical `% + gap` works in LTR and RTL.\n if (this.linearWaveTrackRef) {\n const pct = +(frac * 100).toFixed(3);\n this.linearWaveTrackRef.style.setProperty(\n '--_track-start',\n pct > 0 ? `calc(${pct}% + var(--_gap))` : '0',\n );\n }\n }\n\n /**\n * Drive the flat linear determinate fill + track from the eased\n * linearRenderFraction (the SAME source + ease the wavy variant uses), so the\n * flat bar advances and its track recedes with identical smoothness and the two\n * variants stay perfectly in sync. Both elements have their CSS transitions\n * removed — this per-frame write is the sole animator. `% + gap` is logical, so\n * it lands correctly in LTR and RTL.\n */\n private updateLinearFlat() {\n if (!(this.variant === 'linear' && !this.wave && !this.indeterminate)) return;\n // Round to 3dp then drop trailing zeros (unary +) so settled integer values\n // read as e.g. \"60%\" (matching the declarative render) rather than \"60.000%\".\n const pct = +(this.linearRenderFraction * 100).toFixed(3);\n this.flatActiveRef?.style.setProperty('--_fill-width', `${pct}%`);\n this.flatTrackRef?.style.setProperty(\n '--_track-start',\n pct >= 100\n ? 'calc(100% + var(--_gap))'\n : pct > 0\n ? `calc(${pct}% + var(--_gap))`\n : '0',\n );\n }\n\n /** Draw two indeterminate wave bars each frame by reading bar-inner positions. */\n private updateLinearIndeterminate() {\n if (!(this.wave && this.variant === 'linear' && this.indeterminate)) return;\n const svgRect = this.linearWaveSvgRef?.getBoundingClientRect();\n const containerRect = svgRect ?? this.el.getBoundingClientRect();\n const W = containerRect.width;\n if (!W) return;\n\n const r = this.effectiveThickness / 2;\n const intervals: Array<[number, number]> = [];\n\n const drawBar = (barRef: HTMLDivElement | null, pathRef: SVGPathElement | null) => {\n if (!barRef || !pathRef) return;\n const br = barRef.getBoundingClientRect();\n const startX = br.left - containerRect.left;\n const endX = br.right - containerRect.left;\n if (endX - startX < 1) { pathRef.setAttribute('d', ''); return; }\n pathRef.setAttribute('d', this.buildLinearWaveSVGPath(startX, endX, this.amp, this.linearPhase));\n // Widen by r so the round caps don't leave a sliver of track showing.\n intervals.push([startX - r, endX + r]);\n };\n drawBar(this.indetBar1Ref, this.indetPath1Ref);\n drawBar(this.indetBar2Ref, this.indetPath2Ref);\n\n // Punch the bar x-ranges out of the track so it's hidden under each bar\n // but stays visible (track colour) everywhere else.\n if (this.indetTrackRef) {\n const mask = this.buildTrackMask(intervals, W);\n this.indetTrackRef.style.setProperty('-webkit-mask-image', mask);\n this.indetTrackRef.style.setProperty('mask-image', mask);\n }\n }\n\n /**\n * Build a horizontal mask gradient: opaque (track visible) outside the given\n * x-intervals, transparent (track hidden) inside them. Intervals are merged so\n * overlapping bars produce valid, monotonically-increasing gradient stops.\n */\n private buildTrackMask(intervalsPx: Array<[number, number]>, W: number): string {\n const pcts = intervalsPx\n .map(([s, e]) => [\n Math.max(0, Math.min(100, (s / W) * 100)),\n Math.max(0, Math.min(100, (e / W) * 100)),\n ] as [number, number])\n .filter(([s, e]) => e > s)\n .sort((a, b) => a[0] - b[0]);\n\n const merged: Array<[number, number]> = [];\n for (const [s, e] of pcts) {\n const last = merged[merged.length - 1];\n if (last && s <= last[1]) last[1] = Math.max(last[1], e);\n else merged.push([s, e]);\n }\n if (!merged.length) return 'none';\n\n const stops: string[] = [];\n let cursor = 0;\n for (const [s, e] of merged) {\n stops.push(\n `#fff ${cursor.toFixed(2)}%`,\n `#fff ${s.toFixed(2)}%`,\n `transparent ${s.toFixed(2)}%`,\n `transparent ${e.toFixed(2)}%`,\n `#fff ${e.toFixed(2)}%`,\n );\n cursor = e;\n }\n stops.push(`#fff ${cursor.toFixed(2)}%`, `#fff 100%`);\n return `linear-gradient(to right, ${stops.join(', ')})`;\n }\n\n /**\n * Closed filled wave path spanning [startX, endX] with a round cap on each end.\n * Loop: left cap (CCW) → bottom edge L→R → right cap (CCW) → top edge R→L → Z.\n *\n * inset=true (determinate): the caps are pulled INWARD so the rounded ends sit\n * inside the fill bounds — the wave body spans [startX+r, endX−r] and each cap\n * bulges out to reach exactly startX / endX, like the flat bar's border-radius.\n * Without this the caps bulge PAST the edges (to startX−r / endX+r), where the\n * container's overflow:hidden and the SVG's own clip shear them into square ends\n * (most visible at 0 % start and ~100 %, where the ends sit at the viewport edge).\n * inset=false (indeterminate): caps bulge outward from [startX, endX]; the moving\n * bars live mid-track and their cap overhang is hidden by the track mask widening.\n */\n private buildLinearWaveSVGPath(\n startX: number,\n endX: number,\n amp: number,\n phase: number,\n inset = false,\n ): string {\n if (endX <= startX) return '';\n const h = this.linearWaveHeight;\n const cy = h / 2;\n const wl = this.resolvedWavelength;\n const r = this.effectiveThickness / 2;\n\n // Cap centres: inset by r (caps reach the true edges) or at the edges (caps\n // bulge beyond). The wave body is sampled between the cap centres.\n const bodyStart = inset ? startX + r : startX;\n const bodyEnd = inset ? endX - r : endX;\n\n // Scale amplitude to zero when the fill body is shorter than one wavelength so\n // small fills emerge as a flat dot/pill rather than a partial sine comma. The wave\n // grows in naturally as the fill lengthens past one wavelength.\n const bodyLen = Math.max(0, bodyEnd - bodyStart);\n const A = amp * this.resolvedAmplitude * Math.min(1, bodyLen / wl);\n\n // Inset fill shorter than one cap-to-cap band (≤ thickness): the two caps would\n // cross, so render a single growing round dot centred in the fill. Progress then\n // emerges as a dot that grows to full thickness, rather than a clipped nub.\n if (inset && bodyEnd <= bodyStart) {\n const cx = (startX + endX) / 2;\n const rr = (endX - startX) / 2;\n return (\n `M ${(cx - rr).toFixed(2)} ${cy.toFixed(2)} ` +\n `a ${rr.toFixed(2)} ${rr.toFixed(2)} 0 1 0 ${(2 * rr).toFixed(2)} 0 ` +\n `a ${rr.toFixed(2)} ${rr.toFixed(2)} 0 1 0 ${(-2 * rr).toFixed(2)} 0 Z`\n );\n }\n\n // Sample ~8 points per wavelength. Catmull-Rom smooths between them, so this\n // reproduces the sine cleanly while building ~2.5× fewer bézier segments per\n // frame than the previous fixed 1-point-per-2px sampling (a hot-loop cost).\n const steps = Math.max(8, Math.round(((bodyEnd - bodyStart) / wl) * WAVE_SAMPLES_PER_WL));\n\n const bot: Array<[number, number]> = [];\n const top: Array<[number, number]> = [];\n for (let i = 0; i <= steps; i++) {\n const x = bodyStart + ((bodyEnd - bodyStart) * i) / steps;\n const wy = cy - A * Math.sin((2 * Math.PI * x) / wl + phase);\n bot.push([x, wy + r]);\n top.unshift([x, wy - r]);\n }\n\n const lw = cy - A * Math.sin((2 * Math.PI * bodyStart) / wl + phase);\n const rw = cy - A * Math.sin((2 * Math.PI * bodyEnd) / wl + phase);\n\n const start = `M ${bodyStart.toFixed(2)} ${(lw - r).toFixed(2)}`;\n const leftCap = `A ${r.toFixed(2)} ${r.toFixed(2)} 0 0 0 ${bodyStart.toFixed(2)} ${(lw + r).toFixed(2)}`;\n const botPath = catmullRom(bot).replace(/^M \\S+ \\S+ /, '');\n const rightCap = `A ${r.toFixed(2)} ${r.toFixed(2)} 0 0 0 ${bodyEnd.toFixed(2)} ${(rw - r).toFixed(2)}`;\n const topPath = catmullRom(top).replace(/^M \\S+ \\S+ /, '');\n\n return `${start} ${leftCap} ${botPath} ${rightCap} ${topPath} Z`;\n }\n\n // ── linear wave mask (data-URL stroked sine, one wavelength tile) ─────────\n private updateLinearMask() {\n if (!(this.wave && this.variant === 'linear')) return;\n const s = this.el?.style;\n if (!s) return;\n s.setProperty('--_wave-mask', this.buildLinearMask(this.amp));\n }\n\n private buildLinearMask(amp: number): string {\n const wl = this.resolvedWavelength;\n const t = this.resolvedWaveStroke;\n const h = this.linearWaveHeight;\n const cy = h / 2;\n const A = amp * this.resolvedAmplitude;\n // Build a CLOSED FILLED band instead of a stroked open path. A stroked path\n // clips its round caps at the SVG tile boundary, creating visible seams where\n // adjacent tiles meet. A filled closed path has no caps and tiles seamlessly.\n // Top edge (x: 0→wl): y = cy − A·sin(2π·x/wl) − t/2\n // Bottom edge (x: wl→0): y = cy − A·sin(2π·x/wl) + t/2\n const steps = Math.max(16, Math.round(wl / 2));\n const top: Array<[number, number]> = [];\n const bot: Array<[number, number]> = [];\n for (let i = 0; i <= steps; i++) {\n const x = (wl * i) / steps;\n const wy = A * Math.sin((2 * Math.PI * x) / wl);\n top.push([x, cy - wy - t / 2]);\n bot.unshift([x, cy - wy + t / 2]);\n }\n const topPath = catmullRom(top);\n // Continue from the top edge endpoint into the bottom edge (L instead of M).\n const botPath = catmullRom(bot).replace(/^M \\S+ \\S+/, `L ${bot[0][0].toFixed(2)} ${bot[0][1].toFixed(2)}`);\n const d = `${topPath} ${botPath} Z`;\n const svg =\n `<svg xmlns='http://www.w3.org/2000/svg' width='${wl}' height='${h}' viewBox='0 0 ${wl} ${h}'>` +\n `<path d='${d}' fill='black'/></svg>`;\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n }\n\n // ── circular geometry ─────────────────────────────────────────────────────\n private get circularRadius(): number {\n // Reserve the wave amplitude so travelling crests stay inside the viewBox\n // (the non-root SVG clips overflow); floor positive so thickness >= size\n // can't produce a degenerate / NaN geometry.\n const base = (this.resolvedSize - this.effectiveThickness) / 2 - (this.wave ? this.resolvedAmplitude : 0);\n return Math.max(0.5, base);\n }\n\n /** Number of waves around the ring — snapped to an integer so it closes. */\n private get circularVertices(): number {\n const r = this.circularRadius;\n const wl = this.resolvedWavelength;\n return Math.max(MIN_CIRCULAR_VERTICES, Math.round((2 * Math.PI * r) / wl));\n }\n\n /** Build a wavy (or, at amp 0, plain) arc centerline path. */\n private wavyArcPath(a0: number, a1: number, amp: number, phase: number): string {\n const cx = this.resolvedSize / 2;\n const cy = this.resolvedSize / 2;\n const r = this.circularRadius;\n const n = this.circularVertices;\n const A = amp * this.resolvedAmplitude;\n const span = a1 - a0;\n const steps = Math.max(8, Math.ceil((Math.abs(span) / (2 * Math.PI)) * n * 8));\n const pts: Array<[number, number]> = [];\n for (let i = 0; i <= steps; i++) {\n const th = a0 + span * (i / steps);\n const rr = r + A * Math.cos(n * th - phase);\n pts.push([cx + rr * Math.cos(th), cy + rr * Math.sin(th)]);\n }\n return catmullRom(pts);\n }\n\n /** Plain circular arc (used for the track). */\n private arcPath(a0: number, a1: number): string {\n const cx = this.resolvedSize / 2;\n const cy = this.resolvedSize / 2;\n const r = this.circularRadius;\n const large = Math.abs(a1 - a0) > Math.PI ? 1 : 0;\n const sweep = a1 > a0 ? 1 : 0;\n const x0 = cx + r * Math.cos(a0);\n const y0 = cy + r * Math.sin(a0);\n const x1 = cx + r * Math.cos(a1);\n const y1 = cy + r * Math.sin(a1);\n return `M ${x0.toFixed(2)} ${y0.toFixed(2)} A ${r} ${r} 0 ${large} ${sweep} ${x1.toFixed(2)} ${y1.toFixed(2)}`;\n }\n\n /**\n * Compute the wavy active + track arc paths for a given sweep fraction.\n * Shared by the declarative render (initial/SSR paint) and the rAF loop so\n * both stay perfectly in sync as the sweep eases and the wave travels.\n */\n private circularPaths(\n frac: number,\n amp: number,\n phase: number,\n indeterminate: boolean,\n sweep?: number,\n ): { active: string; track: string } {\n const start = -Math.PI / 2; // 12 o'clock\n const t = this.effectiveThickness;\n const r = this.circularRadius;\n const a1 = start + (indeterminate ? sweep ?? CIRCULAR_INDET_MIN : frac) * 2 * Math.PI;\n const active = a1 - start < 1e-4 ? '' : this.wavyArcPath(start, a1, amp, phase);\n\n let track: string;\n if (!indeterminate && frac > 0 && frac < 1) {\n // Determinate mid-progress: arc behind the gap after the active end.\n // Use the current animated amplitude (amp · resolvedAmplitude) so the\n // gap scales with the wave as it tweens in/out, matching indeterminate.\n const gapAng = (GAP_DP + t + amp * this.resolvedAmplitude) / r;\n const trackStart = a1 + gapAng;\n const trackEnd = start + 2 * Math.PI - gapAng;\n // If progress is so high that trackEnd ≤ trackStart, the remaining arc\n // fits entirely inside the gap — hide the track rather than showing the\n // full ring (which would sit flush against the active arc with no gap).\n track = trackEnd > trackStart ? this.arcPath(trackStart, trackEnd) : '';\n } else if (!indeterminate) {\n // 0 % or 100 %: full ring track.\n track = this.arcPath(start, start + 2 * Math.PI - 1e-3);\n } else {\n // Indeterminate: track is computed imperatively each frame in\n // updateCircularPath() after the rotation offset is known, so the track\n // stays as the complement of the rotating arc rather than a static ring.\n track = '';\n }\n return { active, track };\n }\n\n /**\n * Paint a frame of the circular completion sequence (flat or wavy), driven by\n * ccFrac (fill) / ccErase (erase). Sets SVG attributes directly so no Stencil\n * re-render is involved. The track is hidden throughout so the erasing ring is\n * the only thing visible and the indicator ends up completely empty.\n */\n private paintCircularCompletion() {\n const start = -Math.PI / 2; // 12 o'clock\n // Fill grows the arc to [0, ccFrac]. Erase removes it FROM THE BEGINNING: the\n // visible arc is [ccErase, 1], so the 12 o'clock start goes invisible first and\n // the disappearance progresses clockwise — \"starts from the beginning to become\n // progressively invisible\". Round caps are kept throughout so the head/tail stay\n // rounded (the \"restart at ~75%\" was a keyless-reconciliation bug, now keyed —\n // it was never the round cap, so no need for a butt cap here).\n const erasing = this.ccPhase === 3;\n const a0frac = erasing ? this.ccErase : 0;\n const a1frac = erasing ? 1 : this.ccFrac;\n const span = a1frac - a0frac;\n\n // Fade the final sliver out smoothly: once the visible arc is shorter than the\n // stroke width its two round caps merge into an unstable dot at the 12 o'clock\n // seam, so ramp opacity to 0 over that last stretch instead of drawing it.\n const C = 2 * Math.PI * this.circularRadius;\n const fadeSpan = C > 0 ? this.effectiveThickness / C : 0.04;\n const endOpacity = !erasing\n ? 1\n : span <= 1e-4\n ? 0\n : span < fadeSpan\n ? Math.max(0, span / fadeSpan)\n : 1;\n\n const a0 = start + a0frac * 2 * Math.PI;\n const a1 = start + a1frac * 2 * Math.PI;\n\n if (this.wave) {\n const active = span < 1e-4 ? '' : this.wavyArcPath(a0, a1, this.amp, this.phase);\n if (this.activeRef) {\n this.activeRef.style.opacity = endOpacity >= 1 ? '' : `${endOpacity}`;\n this.activeRef.setAttribute('d', active);\n }\n this.trackRef?.setAttribute('d', ''); // hide track during completion\n } else {\n // Flat completion is drawn as an explicit arc <path> (exact endpoint geometry,\n // round caps) — the SAME approach as the wavy variant, just with zero amplitude\n // (a plain arc). Drawing it this way means the shrinking head moves smoothly,\n // instead of the jitter an animated stroke-dashoffset on a <circle> produces as\n // the dash boundary is re-rasterized each frame.\n const d = span < 1e-4 ? '' : this.wavyArcPath(a0, a1, 0, this.phase);\n if (this.circularFlatCompleteRef) {\n this.circularFlatCompleteRef.style.opacity = endOpacity >= 1 ? '' : `${endOpacity}`;\n this.circularFlatCompleteRef.setAttribute('d', d);\n }\n // Hide the dashed determinate active circle; the path is the only active part.\n if (this.activeCircleRef) this.activeCircleRef.style.opacity = '0';\n // Track stays hidden through the whole fill + erase — nothing should show\n // alongside the disappearing line. It is faded in AFTERWARDS, once the line is\n // fully gone, by the Phase-4 reveal in the frame loop. (Kept a full ring, ready\n // to reveal.)\n if (this.circularFlatTrackRef) {\n const tr = this.circularFlatTrackRef;\n tr.removeAttribute('stroke-dasharray');\n tr.removeAttribute('stroke-dashoffset');\n tr.style.opacity = '0';\n }\n }\n }\n\n /** Completion arc `d` for the flat variant's path, computed from the current cc\n * state. Used by the initial completion render so the path is never momentarily\n * empty (which would flash) before the rAF loop takes over the imperative paint. */\n private get flatCompletionD(): string {\n if (this.ccPhase === 0) return '';\n const start = -Math.PI / 2;\n const erasing = this.ccPhase === 3;\n const a0frac = erasing ? this.ccErase : 0;\n const a1frac = erasing ? 1 : this.ccFrac;\n if (a1frac - a0frac < 1e-4) return '';\n return this.wavyArcPath(start + a0frac * 2 * Math.PI, start + a1frac * 2 * Math.PI, 0, this.phase);\n }\n\n /** Imperatively repaint the wavy circular arcs (+ rotation) each frame. */\n private updateCircularPath() {\n if (!(this.wave && this.variant === 'circular')) return;\n const sweep = this.indeterminate ? this.indeterminateSweep() : undefined;\n const { active, track } = this.circularPaths(\n this.renderFraction,\n this.amp,\n this.phase,\n this.indeterminate,\n sweep,\n );\n this.activeRef?.setAttribute('d', active);\n\n if (this.indeterminate) {\n const rot = this.indeterminateRotation();\n const cx = this.resolvedSize / 2;\n this.rotRef?.setAttribute('transform', `rotate(${rot.toFixed(2)} ${cx} ${cx})`);\n\n // The active arc lives inside rotRef and rotates with it. The track is\n // outside rotRef and must be positioned as the angular complement of the\n // arc in SCREEN SPACE, so we offset by the current rotation.\n const rotRad = (rot * Math.PI) / 180;\n const r = this.circularRadius;\n const gapAng = (GAP_DP + this.effectiveThickness + this.amp * this.resolvedAmplitude) / r;\n const start = -Math.PI / 2;\n const arcSpan = (sweep ?? CIRCULAR_INDET_MIN) * 2 * Math.PI;\n const arcEndScreen = start + rotRad + arcSpan;\n const arcStartScreen = start + rotRad;\n const trackStart = arcEndScreen + gapAng;\n const trackEnd = arcStartScreen + 2 * Math.PI - gapAng;\n this.trackRef?.setAttribute('d', trackEnd > trackStart\n ? this.arcPath(trackStart, trackEnd)\n : '');\n } else {\n this.trackRef?.setAttribute('d', track);\n }\n }\n\n /**\n * Drive the flat (non-wave) circular determinate active arc + track from the eased\n * renderFraction (the SAME source the wavy variant uses) so both repaint in\n * lockstep: the track recedes exactly as the active arc grows and disappears the\n * instant the arc catches it — no early unmount — and the final sub-stroke sliver\n * fades via opacity rather than popping (round caps paint a dot at zero dash\n * length). The active + track CSS transitions are removed (transition:none) so\n * this per-frame write is the sole animator (mirrors updateLinearFlat).\n */\n private updateCircularFlat() {\n if (!(this.variant === 'circular' && !this.wave && !this.indeterminate)) return;\n if (this.ccPhase > 0 || this._completedTrack) return; // completion / terminal track ring owns the geometry\n const f = this.renderFraction;\n const r = this.circularRadius;\n const C = 2 * Math.PI * r;\n const t = this.effectiveThickness;\n const idealGap = C > 0 ? (GAP_DP + t) / C : 0;\n\n // Active arc spans [0, f] from 12 o'clock; full ring (no dash) at ≥100%.\n const active = this.activeCircleRef;\n if (active) {\n if (f >= 1 - 1e-4) active.removeAttribute('stroke-dasharray');\n else active.setAttribute('stroke-dasharray', `${f.toFixed(4)} 1`);\n }\n\n // Track: full ring at 0%; a gapped arc [f+gap, 1−gap] mid-progress; hidden once\n // the remaining arc no longer fits both 4dp gaps. The last sliver (shorter than\n // the round-cap dot ≈ one stroke width) fades out via opacity so it never pops.\n const tr = this.circularFlatTrackRef;\n if (tr) {\n if (f <= 1e-4) {\n tr.removeAttribute('stroke-dasharray');\n tr.removeAttribute('stroke-dashoffset');\n tr.style.opacity = '';\n } else if (f >= 1 - 1e-4) {\n // Active is a full ring covering everything — keep the track hidden.\n tr.style.opacity = '0';\n } else {\n const trackFrac = 1 - f - 2 * idealGap;\n // Below ≈one stroke width a dashed round-cap arc renders as an unstable dot\n // that drifts/twitches as the dash shrinks and the offset moves each frame\n // (the \"jumpy tail\" near 12 o'clock). So once the sliver reaches that size,\n // FREEZE its geometry — a fixed-length segment pinned at the tail (the end at\n // 1−gap, nearest 12 o'clock) — and fade ONLY its opacity to 0. The frozen\n // segment is continuous with the normal one at the threshold (both occupy\n // [1−gap−fadeSpan, 1−gap] there), so there's no seam when it locks.\n const fadeSpan = C > 0 ? t / C : 0.04;\n if (trackFrac <= 1e-4) {\n tr.style.opacity = '0';\n } else if (trackFrac < fadeSpan) {\n tr.style.opacity = Math.max(0, trackFrac / fadeSpan).toFixed(3);\n tr.setAttribute('stroke-dasharray', `${fadeSpan.toFixed(4)} 1`);\n tr.setAttribute('stroke-dashoffset', `${(-(1 - idealGap - fadeSpan)).toFixed(4)}`);\n } else {\n tr.style.opacity = '';\n tr.setAttribute('stroke-dasharray', `${trackFrac.toFixed(4)} 1`);\n tr.setAttribute('stroke-dashoffset', `${(-(f + idealGap)).toFixed(4)}`);\n }\n }\n }\n }\n\n /** Compose expressive sweep: 0.1 → 0.87 (at 3s) → 0.1 (at 6s). */\n private indeterminateSweep(): number {\n if (this.indetStartTs < 0) this.indetStartTs = this.lastTs;\n const t = ((this.lastTs - this.indetStartTs) % CIRCULAR_INDET_CYCLE) / CIRCULAR_INDET_CYCLE;\n const range = CIRCULAR_INDET_MAX - CIRCULAR_INDET_MIN;\n if (t < 0.5) return CIRCULAR_INDET_MIN + range * EASE_STANDARD(t / 0.5);\n return CIRCULAR_INDET_MAX - range * EASE_STANDARD((t - 0.5) / 0.5);\n }\n\n /**\n * Smooth, monotonic rotation (~1440°/cycle = the 1080° global rotation plus\n * the +360° stepped accumulation), wrapped to [0,360) so it advances forward\n * and never snaps backward at the cycle boundary.\n */\n private indeterminateRotation(): number {\n if (this.indetStartTs < 0) this.indetStartTs = this.lastTs;\n const elapsed = this.lastTs - this.indetStartTs;\n return ((CIRCULAR_GLOBAL_ROTATION + 360) * (elapsed / CIRCULAR_INDET_CYCLE)) % 360;\n }\n\n // ── render helpers ─────────────────────────────────────────────────────────\n /** Sanitized maximum — always a finite, positive number for valid ARIA. */\n private get ariaValueMax(): number {\n return Number.isFinite(this.max) && this.max > 0 ? this.max : 0;\n }\n\n private get ariaValueNow(): number | undefined {\n // M3 / Material Web report the raw value (not a 0–100 percentage); clamp\n // into [0, max] so the announced value stays a valid ARIA range value.\n if (this.indeterminate) return undefined;\n const n = Math.min(this.ariaValueMax, Math.max(0, this.value));\n return Number.isFinite(n) ? n : 0;\n }\n\n private renderLinear() {\n return this.indeterminate ? this.renderLinearIndeterminate() : this.renderLinearDeterminate();\n }\n\n private renderLinearDeterminate() {\n // fillPct drives --_fill-width: jumps to 100 immediately so the CSS transition\n // animates the bar to full. pct controls track/stop visibility: always uses\n // the real fraction so the track and stop dot stay in place while the bar\n // travels — the scaleY collapse hides everything together.\n const fillPct = (this._fillComplete || this._completing) ? 100 : this.fraction * 100;\n const pct = this.fraction * 100;\n const hasProgress = fillPct > 0;\n\n if (this.wave) {\n // Wave mode: a single SVG filled path covers both the wave body and the\n // round cap — both live in the same coordinate space so there is no\n // pixel-rounding mismatch between the body edge and the cap circle.\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\" onAnimationEnd={this.onLinearAnimEnd}>\n {pct < 100 && (\n <div\n class=\"md-progress-indicator__track\"\n part=\"track\"\n ref={(el) => { this.linearWaveTrackRef = el as HTMLDivElement; }}\n style={{\n // Same formula as the flat linear — gap from the nominal fill edge.\n // Adding thickness/2 on top made the visual gap feel larger than\n // the flat's 4dp because the eye reads the wave end as the last\n // full-height section, not the tapered cap tip.\n // This declarative value is the steady-state / SSR position; while\n // the value animates, updateLinearPath() overrides it per-frame from\n // the eased fraction so the track tracks the wave's leading edge and\n // the gap stays a constant 4dp (see updateLinearPath).\n '--_track-start': hasProgress\n ? `calc(${pct}% + var(--_gap))`\n : '0',\n }}\n />\n )}\n <div class=\"md-progress-indicator__stop\" part=\"stop-indicator\" />\n {/* Always rendered; the path is empty at 0 % and grows with the fill,\n so it emerges from the leading edge rather than popping in as a dot. */}\n <svg\n class=\"md-progress-indicator__linear-wave-svg\"\n width=\"100%\"\n aria-hidden=\"true\"\n ref={(el) => { this.linearWaveSvgRef = el as SVGSVGElement; }}\n >\n <path\n class=\"md-progress-indicator__linear-wave-path\"\n part=\"active-indicator\"\n ref={(el) => { this.linearWaveRef = el as SVGPathElement; }}\n />\n </svg>\n </div>\n );\n }\n\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\" onAnimationEnd={this.onLinearAnimEnd}>\n {/* Always rendered (even at 0 %): the fill grows out of the leading edge\n rather than popping in as a dot. The width is rAF-driven per-frame by\n updateLinearFlat() (shared ease with the wavy variant); these declarative\n values are the steady-state / SSR fallback. */}\n <div\n class=\"md-progress-indicator__active\"\n part=\"active-indicator\"\n ref={(el) => { this.flatActiveRef = el as HTMLDivElement; }}\n style={{ '--_fill-width': `${fillPct}%` }}\n />\n\n {/* Always rendered: as the bar grows, --_track-start follows it (+gap) so\n the track recedes in lockstep and slides off at 100%. updateLinearFlat()\n drives both per-frame from the same eased fraction as the bar, so the\n 4dp gap stays constant and the flat variant moves identically to wavy. */}\n <div\n class=\"md-progress-indicator__track md-progress-indicator__track--determinate\"\n part=\"track\"\n ref={(el) => { this.flatTrackRef = el as HTMLDivElement; }}\n style={{\n // No min() here: a min()/max() inside the calc makes the browser fall\n // back to DISCRETE interpolation of inset-inline-start, so the track\n // jumps each value update (jitter). A plain `% + px` stays in lockstep\n // with the active fill. (Steady-state / SSR fallback; the rAF loop\n // overrides this per-frame while the value animates.)\n '--_track-start': fillPct >= 100\n ? 'calc(100% + var(--_gap))'\n : hasProgress\n ? `calc(${pct}% + var(--_gap))`\n : '0',\n }}\n />\n\n <div class=\"md-progress-indicator__stop\" part=\"stop-indicator\" />\n </div>\n );\n }\n\n private renderLinearIndeterminate() {\n if (this.wave && !this.reducedMotion) {\n // Wave indeterminate: JS draws both bars as filled SVG paths each rAF frame.\n // Ghost bar divs drive the CSS position/scale animations so we can read their\n // bounding rects; the SVG overlay renders the actual wavy shapes with round caps.\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\">\n {/* Track is visible in the gaps; updateLinearIndeterminate() masks out\n the x-range under each bar every frame so the clean wave floats over\n a hidden segment instead of overlapping a straight track line. */}\n <div\n class=\"md-progress-indicator__track md-progress-indicator__track--full\"\n part=\"track\"\n ref={(el) => { this.indetTrackRef = el as HTMLDivElement; }}\n />\n <div class=\"md-progress-indicator__bar md-progress-indicator__bar--primary\">\n <div\n class=\"md-progress-indicator__bar-inner md-progress-indicator__bar-inner--ghost\"\n ref={(el) => { this.indetBar1Ref = el as HTMLDivElement; }}\n />\n </div>\n <div class=\"md-progress-indicator__bar md-progress-indicator__bar--secondary\">\n <div\n class=\"md-progress-indicator__bar-inner md-progress-indicator__bar-inner--ghost\"\n ref={(el) => { this.indetBar2Ref = el as HTMLDivElement; }}\n />\n </div>\n <svg\n class=\"md-progress-indicator__linear-wave-svg\"\n width=\"100%\"\n aria-hidden=\"true\"\n ref={(el) => { this.linearWaveSvgRef = el as SVGSVGElement; }}\n >\n <path\n class=\"md-progress-indicator__linear-wave-path\"\n ref={(el) => { this.indetPath1Ref = el as SVGPathElement; }}\n />\n <path\n class=\"md-progress-indicator__linear-wave-path\"\n ref={(el) => { this.indetPath2Ref = el as SVGPathElement; }}\n />\n </svg>\n </div>\n );\n }\n\n // Flat or reduced-motion indeterminate: standard CSS two-bar motion.\n const barClass = (modifier: string) => ({\n 'md-progress-indicator__bar': true,\n [`md-progress-indicator__bar--${modifier}`]: true,\n 'md-progress-indicator__bar--wave': this.wave,\n });\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\">\n <div class=\"md-progress-indicator__track md-progress-indicator__track--full\" part=\"track\" />\n <div class={barClass('primary')} part=\"active-indicator\">\n <div class=\"md-progress-indicator__bar-inner\" />\n </div>\n <div class={barClass('secondary')}>\n <div class=\"md-progress-indicator__bar-inner\" />\n </div>\n </div>\n );\n }\n\n private renderCircular() {\n return this.wave ? this.renderCircularWave() : this.renderCircularFlat();\n }\n\n private renderCircularFlat() {\n const sz = this.resolvedSize;\n const t = this.effectiveThickness;\n const r = this.circularRadius;\n const center = sz / 2;\n const f = this.fraction;\n const C = 2 * Math.PI * r;\n const idealGap = C > 0 ? (GAP_DP + t) / C : 0;\n const showGap = f > 0 && f < 1;\n // Track = the leftover arc after a constant idealGap is removed at each end:\n // trackFrac = remaining − 2·gap. Constant gap → the active end (f) and the track\n // start (f + gap) move in perfect lockstep, so the 4dp gap never stretches. These\n // are the steady-state / SSR values; while the value animates updateCircularFlat()\n // overrides the dash/offset/opacity per-frame from the eased renderFraction, in\n // lockstep with the active arc (so the track recedes exactly as the arc grows and\n // its final sliver fades out instead of popping — see updateCircularFlat()).\n const trackFrac = showGap ? Math.max(0, 1 - f - 2 * idealGap) : 0;\n const trackVisible = showGap && trackFrac > 0;\n\n return (\n <svg class=\"md-progress-indicator__circular\" viewBox={`0 0 ${sz} ${sz}`} aria-hidden=\"true\">\n {/* Stable key=\"circ-track\" pins element identity so Stencil never repurposes\n the track as the active circle (which would restart the active's dash and\n read as the fill \"starting again\").\n - Indeterminate: a complement arc that follows the spinning active arc,\n animated purely in CSS via md-circular-dash-track.\n - Determinate: a SINGLE always-mounted arc driven per-frame by\n updateCircularFlat() (full ring at 0 %, a gapped arc mid-progress, faded\n out near ≥86 % / 100 %). It stays mounted across the whole range so the\n rAF loop fades it smoothly — rather than the DOM yanking it to null,\n which cut the CSS transition mid-flight and popped (the bug this fixes). */}\n {this.indeterminate ? (\n <circle\n key=\"circ-track\"\n class=\"md-progress-indicator__circular-track md-progress-indicator__circular-track--spinner\"\n part=\"track\"\n cx={center}\n cy={center}\n r={r}\n stroke-width={t}\n fill=\"none\"\n pathLength={1}\n stroke-linecap=\"round\"\n transform={`rotate(-90 ${center} ${center})`}\n ref={(el) => { this.circularFlatTrackRef = el as SVGCircleElement; }}\n />\n ) : (\n <circle\n key=\"circ-track\"\n class=\"md-progress-indicator__circular-track md-progress-indicator__circular-track--determinate\"\n part=\"track\"\n cx={center}\n cy={center}\n r={r}\n stroke-width={t}\n fill=\"none\"\n pathLength={1}\n stroke-linecap=\"round\"\n transform={`rotate(-90 ${center} ${center})`}\n stroke-dasharray={this._completedTrack ? undefined : trackVisible ? `${trackFrac} 1` : undefined}\n stroke-dashoffset={this._completedTrack ? undefined : trackVisible ? -(f + idealGap) : undefined}\n style={\n // _completedTrack: rest on a full, visible track ring (the terminal\n // state). Otherwise hide it while completing / when it no longer fits.\n this._completedTrack\n ? undefined\n : this.ccPhase > 0 || (showGap && trackFrac <= 0)\n ? { opacity: '0' }\n : undefined\n }\n ref={(el) => { this.circularFlatTrackRef = el as SVGCircleElement; }}\n />\n )}\n <circle\n key=\"circ-active\"\n class=\"md-progress-indicator__circular-active\"\n part=\"active-indicator\"\n cx={center}\n cy={center}\n r={r}\n stroke-width={t}\n fill=\"none\"\n pathLength={1}\n stroke-linecap=\"round\"\n stroke-dasharray={this.indeterminate || f >= 1 ? undefined : `${f} ${1}`}\n // During completion the dashed circle is hidden and the completion <path>\n // below draws the arc instead (so the head doesn't jitter). _completed hides\n // it before visibility:hidden lands; _completedTrack hides it for good (the\n // flat circular terminal state shows only the empty track ring).\n style={this.ccPhase > 0 || this._completed || this._completedTrack ? { opacity: '0' } : undefined}\n transform={`rotate(-90 ${center} ${center})`}\n ref={(el) => { this.activeCircleRef = el as SVGCircleElement; }}\n />\n {/* Completion-only arc, drawn as an explicit round-capped <path> (empty\n outside the completion sequence). Painted imperatively by\n paintCircularCompletion(); flatCompletionD seeds the first frame so the\n path is never momentarily empty (no flash) before the rAF loop runs. */}\n <path\n class=\"md-progress-indicator__circular-active-path\"\n stroke-width={t}\n fill=\"none\"\n stroke-linecap=\"round\"\n d={this.flatCompletionD}\n ref={(el) => { this.circularFlatCompleteRef = el as SVGPathElement; }}\n />\n </svg>\n );\n }\n\n private renderCircularWave() {\n const sz = this.resolvedSize;\n const t = this.effectiveThickness;\n // Initial (SSR / pre-rAF) paths from the eased fraction; the rAF loop then\n // repaints both arcs in lockstep.\n const { active, track } = this.circularPaths(\n this.renderFraction,\n this.amp,\n this.phase,\n this.indeterminate,\n this.indeterminate ? CIRCULAR_INDET_MIN : undefined,\n );\n\n return (\n <svg class=\"md-progress-indicator__circular\" viewBox={`0 0 ${sz} ${sz}`} aria-hidden=\"true\">\n <path\n class=\"md-progress-indicator__circular-track\"\n part=\"track\"\n d={this.ccPhase > 0 ? '' : track}\n stroke-width={t}\n fill=\"none\"\n stroke-linecap=\"round\"\n ref={(e) => (this.trackRef = e as SVGPathElement)}\n />\n <g ref={(e) => (this.rotRef = e as SVGGElement)}>\n <path\n class=\"md-progress-indicator__circular-active\"\n part=\"active-indicator\"\n d={active}\n stroke-width={t}\n fill=\"none\"\n stroke-linecap=\"round\"\n ref={(e) => (this.activeRef = e as SVGPathElement)}\n />\n </g>\n </svg>\n );\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-progress-indicator': true,\n [`md-progress-indicator--${this.variant}`]: true,\n 'md-progress-indicator--indeterminate': this.indeterminate,\n 'md-progress-indicator--wave': this.wave,\n 'md-progress-indicator--four-color': this.fourColor,\n 'md-progress-indicator--completing': this._completing,\n 'md-progress-indicator--complete': this._completed,\n }}\n role=\"progressbar\"\n aria-label={this.label || undefined}\n aria-valuemin={0}\n aria-valuemax={this.ariaValueMax}\n aria-valuenow={this.ariaValueNow}\n >\n {this.variant === 'circular' ? this.renderCircular() : this.renderLinear()}\n </Host>\n );\n }\n}\n\n/* ── Catmull-Rom → cubic-bézier smoothing for the wavy ring path ───────────*/\nfunction catmullRom(pts: Array<[number, number]>): string {\n if (pts.length < 2) return '';\n const d: string[] = [`M ${pts[0][0].toFixed(2)} ${pts[0][1].toFixed(2)}`];\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[i - 1] || pts[i];\n const p1 = pts[i];\n const p2 = pts[i + 1];\n const p3 = pts[i + 2] || p2;\n const c1x = p1[0] + (p2[0] - p0[0]) / 6;\n const c1y = p1[1] + (p2[1] - p0[1]) / 6;\n const c2x = p2[0] - (p3[0] - p1[0]) / 6;\n const c2y = p2[1] - (p3[1] - p1[1]) / 6;\n d.push(\n `C ${c1x.toFixed(2)} ${c1y.toFixed(2)} ${c2x.toFixed(2)} ${c2y.toFixed(2)} ${p2[0].toFixed(2)} ${p2[1].toFixed(2)}`,\n );\n }\n return d.join(' ');\n}\n"],"mappings":"kEAAA,MAAMA,EAAyB,IAAM,41WCcrC,MAAMC,EAAS,EAEf,MAAMC,EAAwB,GAC9B,MAAMC,EAAsB,GAE5B,MAAMC,EAAmB,EACzB,MAAMC,EAAqB,IAE3B,MAAMC,EAAqB,GAC3B,MAAMC,EAAqB,GAE3B,MAAMC,EAAoB,GAC1B,MAAMC,EAAoB,IAI1B,MAAMC,EAAsB,EAE5B,MAAMC,EAAe,IACrB,MAAMC,EAAiB,CAAC,GAAK,EAAG,EAAG,GACnC,MAAMC,EAAkB,CAAC,GAAK,EAAG,GAAK,KAEtC,MAAMC,EAAuB,IAC7B,MAAMC,EAAqB,GAC3B,MAAMC,EAAqB,IAC3B,MAAMC,EAA2B,KACjC,MAAMC,EAAwB,EAK9B,SAASC,GAAcC,EAAIC,EAAIC,EAAIC,IACjC,GAAIH,IAAOC,GAAMC,IAAOC,EAAI,OAAQC,GAAMA,EAC1C,MAAMC,EAAK,EAAIL,EACf,MAAMM,EAAK,GAAKJ,EAAKF,GAAMK,EAC3B,MAAME,EAAK,EAAIF,EAAKC,EACpB,MAAME,EAAK,EAAIP,EACf,MAAMQ,EAAK,GAAKN,EAAKF,GAAMO,EAC3B,MAAME,EAAK,EAAIF,EAAKC,EACpB,MAAME,EAAWP,KAAgBG,EAAKH,EAAIE,GAAMF,EAAIC,GAAMD,EAC1D,MAAMQ,EAAWR,KAAgBM,EAAKN,EAAIK,GAAML,EAAII,GAAMJ,EAC1D,MAAMS,EAAUT,IAAe,EAAIG,EAAKH,EAAI,EAAIE,GAAMF,EAAIC,EAC1D,OAAQS,IACN,GAAIA,GAAK,EAAG,OAAO,EACnB,GAAIA,GAAK,EAAG,OAAO,EACnB,IAAIV,EAAIU,EACR,IAAK,IAAIC,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,MAAMC,EAAKL,EAAQP,GAAKU,EACxB,MAAMG,EAAIJ,EAAOT,GACjB,GAAIc,KAAKC,IAAIH,GAAM,KAAM,MACzB,GAAIE,KAAKC,IAAIF,GAAK,KAAM,MACxBb,GAAKY,EAAKC,C,CAEZ,OAAOL,EAAQM,KAAKE,IAAI,EAAGF,KAAKG,IAAI,EAAGjB,IAAI,CAE/C,CACA,MAAMkB,EAAUvB,EAAaP,GAC7B,MAAM+B,EAAWxB,EAAaN,GAC9B,MAAM+B,EAAgBzB,EAAa,CAAC,GAAK,EAAG,EAAG,I,MAOlC0B,EAAmBC,EAAA,MAAAD,UAAAE,EALhC,WAAAC,CAAAC,G,yGASUC,KAAAC,QAAiC,SAGjCD,KAAAE,MAAgB,EAGhBF,KAAAT,IAAc,IAGGS,KAAAG,cAAyB,MAG1CH,KAAAI,UAAoB,EAGHJ,KAAAK,KAAgB,MAMFL,KAAAM,cAAwB,EAM3BN,KAAAO,WAAqB,EAMtBP,KAAAQ,UAAoB,EAM/CR,KAAAS,KAAe,EAG2BT,KAAAU,UAAqB,MAG/DV,KAAAW,MAAgB,WAShBX,KAAAY,SAAoB,MAOHZ,KAAAa,QAAiC,EAOzCb,KAAAc,cAAyB,MACzBd,KAAAe,YAAc,MACdf,KAAAgB,WAAa,MAGbhB,KAAAiB,gBAAkB,MAClBjB,KAAAkB,cAAgB,MAGzBlB,KAAAmB,IAAM,EACNnB,KAAAoB,MAAQ,EACRpB,KAAAqB,YAAc,EACdrB,KAAAsB,IAAM,EACNtB,KAAAuB,QAAU,EACVvB,KAAAwB,MAAQ,EACRxB,KAAAyB,YAAa,EACbzB,KAAA0B,QAAiClC,EACjCQ,KAAA2B,QAAS,EACT3B,KAAA4B,cAAe,EACf5B,KAAA6B,eAAiB,EACjB7B,KAAA8B,qBAAuB,EAGvB9B,KAAA+B,cAAuC,KACvC/B,KAAAgC,iBAAyC,KACzChC,KAAAiC,mBAA4C,KAC5CjC,KAAAkC,cAAuC,KACvClC,KAAAmC,aAAsC,KACtCnC,KAAAoC,aAAsC,KACtCpC,KAAAqC,aAAsC,KACtCrC,KAAAsC,cAAuC,KACvCtC,KAAAuC,cAAuC,KACvCvC,KAAAwC,cAAuC,KAKvCxC,KAAAyC,YAAc,EACdzC,KAAA0C,QAAU,KACV1C,KAAA2C,IAAM,MAGN3C,KAAA4C,mBAAqB,EAErB5C,KAAA6C,qBAAgD,KAIhD7C,KAAA8C,wBAAiD,KAajD9C,KAAA+C,QAA6B,EAC7B/C,KAAAgD,SAAU,EACVhD,KAAAiD,OAAS,EACTjD,KAAAkD,QAAU,EACDlD,KAAAmD,YAAc,IACdnD,KAAAoD,eAAiB,IACjBpD,KAAAqD,QAAU,IACVrD,KAAAsD,aAAe,IACftD,KAAAuD,oBAAsB,IAM/BvD,KAAAwD,SAAsB,EACtBxD,KAAAyD,UAAW,EACXzD,KAAA0D,YAAc,EACd1D,KAAA2D,QAAU,EACD3D,KAAA4D,aAAe,IACf5D,KAAA6D,gBAAkB,IAM3B7D,KAAA8D,SAAkB,EA0KlB9D,KAAA+D,sBAAyBC,IAC/BhE,KAAKc,cAAgBkD,EAAEC,OAAO,EA4GxBjE,KAAAkE,gBAAmBF,IACzB,GAAIA,EAAEG,gBAAkB,qBAAsBnE,KAAKoE,gBAAgB,EA0J7DpE,KAAAqE,MAASC,IACftE,KAAKmB,IAAM,EACX,GAAInB,KAAK2B,OAAS,EAAG3B,KAAK2B,OAAS2C,EACnC,MAAMC,EAAKnF,KAAKE,IAAI,GAAIgF,EAAKtE,KAAK2B,QAClC3B,KAAK2B,OAAS2C,EAGd,GAAItE,KAAK+C,QAAU,GAAK/C,KAAKC,UAAY,WAAY,CACnD,GAAID,KAAKgD,QAAU,EAAGhD,KAAKgD,QAAUsB,EAErC,GAAItE,KAAKK,KAAM,CACb,MAAMmE,EAAcxE,KAAKyE,kBAAoBzE,KAAK0E,mBAClD1E,KAAKoB,OAAS,EAAIhC,KAAKuF,GAAKH,GAAeD,EAAK,KAChD,GAAIvE,KAAKoB,MAAQ,IAAKpB,KAAKoB,MAAQpB,KAAKoB,OAAS,EAAIhC,KAAKuF,G,CAG5D,GAAI3E,KAAK+C,UAAY,EAAG,CAEtB,MAAMzE,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKgD,SAAWhD,KAAKmD,aACjDnD,KAAKiD,OAASjD,KAAK4C,oBAAsB,EAAI5C,KAAK4C,oBAAsBlD,EAAcpB,GACtF0B,KAAK4E,0BACL,GAAItG,GAAK,EAAG,CACV0B,KAAKiD,OAAS,EACdjD,KAAKgD,QAAUsB,EACf,GAAItE,KAAKK,KAAM,CACbL,KAAK+C,QAAU,EACf/C,KAAKuB,QAAUvB,KAAKsB,G,KACf,CACLtB,KAAK+C,QAAU,C,QAGd,GAAI/C,KAAK+C,UAAY,EAAG,CAE7B,MAAMzE,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKgD,SAAWhD,KAAKoD,gBACjDpD,KAAKsB,IAAMtB,KAAKuB,SAAW,EAAI/B,EAAQlB,IACvC0B,KAAK4E,0BACL,GAAItG,GAAK,EAAG,CACV0B,KAAKsB,IAAM,EACXtB,KAAK+C,QAAU,EACf/C,KAAKgD,QAAUsB,C,OAEZ,GAAItE,KAAK+C,UAAY,EAAG,CAG7B,MAAMzE,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKgD,QAAUhD,KAAKqD,SAAWrD,KAAKsD,cAChEtD,KAAKkD,QAAU5E,GAAK,EAAI,EAAIoB,EAAcpB,GAC1C0B,KAAK4E,0BACL,GAAItG,GAAK,EAAG,CACV,IAAK0B,KAAKK,KAAM,CAEdL,KAAK+C,QAAU,EACf/C,KAAKgD,QAAUsB,C,KACV,CAELtE,KAAKoE,iBACLpE,KAAK6E,WACL,M,OAGC,CAGL,MAAMvG,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKgD,SAAWhD,KAAKuD,qBACjDvD,KAAK8C,yBAAyBgC,aAAa,IAAK,IAChD,GAAI9E,KAAK+E,gBAAiB/E,KAAK+E,gBAAgBC,MAAMC,QAAU,IAC/D,GAAIjF,KAAK6C,qBAAsB,CAC7B,MAAMqC,EAAKlF,KAAK6C,qBAChBqC,EAAGC,gBAAgB,oBACnBD,EAAGC,gBAAgB,qBACnBD,EAAGF,MAAMC,QAAU,GAAGvF,EAAcpB,I,CAEtC,GAAIA,GAAK,EAAG,CACV0B,KAAKoE,iBACLpE,KAAK6E,WACL,M,EAGJ7E,KAAKmB,IAAMiE,sBAAsBpF,KAAKqE,OACtC,M,CAIF,GAAIrE,KAAKwD,SAAW,EAAG,CACrB,GAAIxD,KAAKyD,SAAW,EAAGzD,KAAKyD,SAAWa,EAEvC,MAAME,EAAcxE,KAAKyE,kBAAoBzE,KAAK0E,mBAClD1E,KAAKqB,aAAe,EAAIjC,KAAKuF,GAAKH,GAAeD,EAAK,KACtD,GAAIvE,KAAKqB,YAAc,IAAKrB,KAAKqB,YAAcrB,KAAKqB,aAAe,EAAIjC,KAAKuF,IAE5E,GAAI3E,KAAKwD,WAAa,EAAG,CACvB,MAAMlF,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKyD,UAAYzD,KAAK4D,cAClD5D,KAAK2D,QAAU3D,KAAK0D,aAAe,EAAI1D,KAAK0D,aAAehE,EAAcpB,GACzE0B,KAAKqF,mBACL,GAAI/G,GAAK,EAAG,CACV0B,KAAK2D,QAAU,EACf3D,KAAKwD,SAAW,EAChBxD,KAAKyD,SAAWa,EAChBtE,KAAKuB,QAAU,EACfvB,KAAKwB,MAAQ,EACbxB,KAAK0B,QAAUlC,EACfQ,KAAKyB,WAAa6C,C,MAEf,CACL,MAAMhG,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKyB,YAAczB,KAAK6D,iBACpD7D,KAAKsB,IAAMtB,KAAKuB,SAAW,EAAIvB,KAAK0B,QAAQpD,IAC5C0B,KAAKqF,mBACL,GAAI/G,GAAK,EAAG,CACV0B,KAAKsB,IAAM,EACXtB,KAAKwD,SAAW,EAChBxD,KAAKe,YAAc,KACnBf,KAAK6E,WACL,M,EAGJ7E,KAAKmB,IAAMiE,sBAAsBpF,KAAKqE,OACtC,M,CAIF,GAAIrE,KAAKsB,MAAQtB,KAAKwB,MAAO,CAC3B,GAAIxB,KAAKyB,WAAa,EAAGzB,KAAKyB,WAAa6C,EAC3C,MAAMhG,EAAIc,KAAKE,IAAI,GAAIgF,EAAKtE,KAAKyB,YAAchE,GAC/CuC,KAAKsB,IAAMtB,KAAKuB,SAAWvB,KAAKwB,MAAQxB,KAAKuB,SAAWvB,KAAK0B,QAAQpD,GACrE,GAAIA,GAAK,EAAG,CACV0B,KAAKsB,IAAMtB,KAAKwB,MAChBxB,KAAKyB,YAAa,C,EAKtB,GAAIzB,KAAKC,UAAY,YAAcD,KAAKK,KAAM,CAC5C,MAAMmE,EAAcxE,KAAKyE,kBAAoBzE,KAAK0E,mBAClD1E,KAAKoB,OAAS,EAAIhC,KAAKuF,GAAKH,GAAeD,EAAK,KAChD,GAAIvE,KAAKoB,MAAQ,IAAKpB,KAAKoB,MAAQpB,KAAKoB,OAAS,EAAIhC,KAAKuF,IAE1D,MAAMW,EAAI,EAAIlG,KAAKmG,KAAKhB,EAAK,KAC7BvE,KAAK6B,iBAAmB7B,KAAKwF,SAAWxF,KAAK6B,gBAAkByD,EAC/D,GAAIlG,KAAKC,IAAIW,KAAKwF,SAAWxF,KAAK6B,gBAAkB,KAAM7B,KAAK6B,eAAiB7B,KAAKwF,SACrFxF,KAAKyF,oB,MACA,GAAIzF,KAAKC,UAAY,aAAeD,KAAKK,OAASL,KAAKG,cAAe,CAK3E,MAAMmF,EAAI,EAAIlG,KAAKmG,KAAKhB,EAAK,KAC7BvE,KAAK6B,iBAAmB7B,KAAKwF,SAAWxF,KAAK6B,gBAAkByD,EAC/D,GAAIlG,KAAKC,IAAIW,KAAKwF,SAAWxF,KAAK6B,gBAAkB,KAAM7B,KAAK6B,eAAiB7B,KAAKwF,SACrFxF,KAAK0F,oB,MACA,GAAI1F,KAAKC,UAAY,UAAYD,KAAKK,OAASL,KAAKG,cAAe,CACxE,MAAMqE,EAAcxE,KAAKyE,kBAAoBzE,KAAK0E,mBAClD1E,KAAKqB,aAAe,EAAIjC,KAAKuF,GAAKH,GAAeD,EAAK,KACtD,GAAIvE,KAAKqB,YAAc,IAAKrB,KAAKqB,YAAcrB,KAAKqB,aAAe,EAAIjC,KAAKuF,IAG5E,GAAI3E,KAAKwD,WAAa,EAAG,CACvB,MAAM8B,EAAI,EAAIlG,KAAKmG,KAAKhB,EAAK,IAC7BvE,KAAK8B,uBAAyB9B,KAAKwF,SAAWxF,KAAK8B,sBAAwBwD,EAC3E,GAAIlG,KAAKC,IAAIW,KAAKwF,SAAWxF,KAAK8B,sBAAwB,KACxD9B,KAAK8B,qBAAuB9B,KAAKwF,Q,CAErCxF,KAAKqF,kB,MACA,GAAIrF,KAAKC,UAAY,UAAYD,KAAKK,MAAQL,KAAKG,cAAe,CACvE,MAAMqE,EAAcxE,KAAKyE,kBAAoBzE,KAAK0E,mBAClD1E,KAAKqB,aAAe,EAAIjC,KAAKuF,GAAKH,GAAeD,EAAK,KACtD,GAAIvE,KAAKqB,YAAc,IAAKrB,KAAKqB,YAAcrB,KAAKqB,aAAe,EAAIjC,KAAKuF,IAC5E3E,KAAK2F,2B,MACA,GAAI3F,KAAKC,UAAY,WAAaD,KAAKK,OAASL,KAAKG,cAAe,CAIzE,MAAMyF,EAAS5F,KAAK8D,WAAa,EAAI,EAAI9D,KAAKwF,SAC9C,MAAMF,EAAI,EAAIlG,KAAKmG,KAAKhB,EAAK,IAC7BvE,KAAK8B,uBAAyB8D,EAAS5F,KAAK8B,sBAAwBwD,EACpE,GAAIlG,KAAKC,IAAIuG,EAAS5F,KAAK8B,sBAAwB,KAAM,CACvD9B,KAAK8B,qBAAuB8D,EAC5B,GAAI5F,KAAK8D,WAAa,EAAG,CACvB9D,KAAK8D,SAAW,EAChB9D,KAAK6F,mBACL7F,KAAKe,YAAc,KACnBf,KAAK6E,WACL,M,EAGJ7E,KAAK6F,kB,KACA,CACL7F,KAAK8F,gB,CAGP,GAAI9F,KAAK+F,gBAAiB,CACxB/F,KAAKmB,IAAMiE,sBAAsBpF,KAAKqE,M,KACjC,CACLrE,KAAK6E,U,EAs4BV,CAp/CC,YAAYW,GACV,IAAKxF,KAAKT,IAAK,OAAO,EACtB,OAAOH,KAAKE,IAAI,EAAGF,KAAKG,IAAI,EAAGS,KAAKE,MAAQF,KAAKT,K,CAGnD,gBAAYyG,GACV,IAAKhG,KAAKiG,GAAI,OAAO,EACrB,MAAMC,EAAIC,iBAAiBnG,KAAKiG,IAAIG,iBAAiB,0BAA0BC,OAC/E,OAAOH,EAAII,OAAOJ,GAAK,C,CAGzB,gBAAYK,GACV,MAAM1F,EAAUb,KAAKgG,aACrB,MAAMQ,EAAIxG,KAAKS,KAAO,EAAIT,KAAKS,MAAQT,KAAKK,KAAOhD,EAAqBD,GAAsByD,EAAU,EACxG,OAAOzB,KAAKE,IAAI/B,EAAmB6B,KAAKG,IAAIjC,EAAmBkJ,G,CAGjE,sBAAY9B,GACV,GAAI1E,KAAKO,WAAa,EAAG,OAAOP,KAAKO,WACrC,GAAIP,KAAKC,UAAY,WAAY,OAAOhD,EACxC,OAAOD,C,CAGT,qBAAYyJ,GACV,GAAIzG,KAAKM,cAAgB,EAAG,OAAON,KAAKM,cACxC,GAAIN,KAAKC,UAAY,WAAY,OAAO9C,EACxC,OAAOD,C,CAGT,qBAAYwJ,GACV,GAAI1G,KAAKI,YAAc,EAAG,OAAOJ,KAAKI,UACtC,OAAOhB,KAAKG,IAAI,EAAG,EAAIS,KAAKgG,aAAe,G,CAI7C,sBAAYW,GACV,OAAO3G,KAAK0G,iB,CAId,sBAAYE,GACV,OAAO5G,KAAK0G,iB,CAGd,qBAAYjC,GACV,GAAIzE,KAAKQ,UAAY,EAAG,OAAOR,KAAKQ,UACpC,OAAOR,KAAK0E,kB,CAMd,oBAAYmC,GACV,OAAO,EAAI7G,KAAKyG,kBAAoBzG,KAAK2G,kB,CAO3C,mBAAYG,GACV,IAAK9G,KAAKK,MAAQL,KAAKc,cAAe,OAAO,EAC7C,GAAId,KAAKG,cAAe,OAAO,EAM/B,OAAOH,KAAKwF,SAAW,EAAI,EAAI,C,CAIjC,iBAAAuB,GACE/G,KAAKsB,IAAMtB,KAAK8G,gBAChB9G,KAAKwB,MAAQxB,KAAKsB,IAClBtB,KAAK6B,eAAiB7B,KAAKwF,SAC3BxF,KAAK8B,qBAAuB9B,KAAKwF,SACjCxF,KAAKgH,iBACL,UAAWC,SAAW,aAAeA,OAAOC,WAAY,CACtDlH,KAAKmH,IAAMF,OAAOC,WAAW,oCAC7BlH,KAAKc,cAAgBd,KAAKmH,IAAIlD,QAC9BjE,KAAKmH,IAAIC,mBAAmB,SAAUpH,KAAK+D,sB,EAI/C,gBAAAsD,GACE,UAAWC,uBAAyB,YAAa,CAC/CtH,KAAKuH,GAAK,IAAID,sBAAsBE,IAClCxH,KAAK0C,QAAU8E,EAAQC,MAAMzD,GAAMA,EAAE0D,iBACrC1H,KAAK2H,YAAY,IAEnB3H,KAAKuH,GAAGK,QAAQ5H,KAAKiG,G,CAKvB,UAAW4B,iBAAmB,YAAa,CACzC7H,KAAK8H,GAAK,IAAID,gBAAe,KAC3B7H,KAAK+H,qBACL/H,KAAKqF,kBAAkB,IAEzBrF,KAAK8H,GAAGF,QAAQ5H,KAAKiG,G,CAEvBjG,KAAK2H,Y,CAGP,kBAAAK,GACEhI,KAAK2H,aAEL3H,KAAK2C,IAAM3C,KAAKiI,aAGhB,GAAIjI,KAAKK,MAAQL,KAAKC,UAAY,WAAaD,KAAKG,cAAe,CACjEH,KAAK+H,qBAGL,GAAI/H,KAAKwD,WAAa,IAAMxD,KAAKe,cAAgBf,KAAKgB,WAAY,CAGhE,IAAKhB,KAAKmB,IAAKnB,KAAK8B,qBAAuB9B,KAAKwF,SAChDxF,KAAKqF,kB,EAMT,IAAKrF,KAAKK,MAAQL,KAAKC,UAAY,WAAaD,KAAKG,cAAe,CAClE,GAAIH,KAAK8D,WAAa,IAAM9D,KAAKe,cAAgBf,KAAKgB,WAAY,CAChE,IAAKhB,KAAKmB,IAAKnB,KAAK8B,qBAAuB9B,KAAKwF,SAChDxF,KAAK6F,kB,EAMT,GAAI7F,KAAKC,UAAY,aAAeD,KAAKK,OAASL,KAAKG,cAAe,CACpE,GAAIH,KAAK+C,UAAY,IAAM/C,KAAKe,cAAgBf,KAAKgB,aAAehB,KAAKiB,gBAAiB,CACxF,IAAKjB,KAAKmB,IAAKnB,KAAK6B,eAAiB7B,KAAKwF,SAC1CxF,KAAK0F,oB,GAOH,kBAAAqC,GACN,MAAMG,EACJlI,KAAKgC,kBAAkBmG,wBAAwBC,OAC/CpI,KAAKiG,GAAGkC,wBAAwBC,OAChCpI,KAAKiG,GAAGoC,aACR,EACF,GAAIH,EAAGlI,KAAKyC,YAAcyF,EAC1B,OAAOlI,KAAKyC,W,CAGN,UAAAwF,GACN,UAAW9B,mBAAqB,cAAgBnG,KAAKiG,GAAI,OAAO,MAChE,OAAOE,iBAAiBnG,KAAKiG,IAAIqC,YAAc,K,CAGjD,oBAAAC,GACEvI,KAAK6E,WACL7E,KAAKmH,KAAKqB,sBAAsB,SAAUxI,KAAK+D,uBAC/C/D,KAAKuH,IAAIkB,aACTzI,KAAK8H,IAAIW,Y,CAaX,iBAAAC,GACE1I,KAAKgH,gB,CAQP,sBAAA2B,GACE,GAAI3I,KAAK+C,QAAU,EAAG,OACtB/C,KAAK4I,oBAGL5I,KAAK2H,Y,CAIP,gBAAAkB,CAAiBC,GACf,IAAKA,GAAQ9I,KAAKG,eAAiBH,KAAKe,aAAef,KAAKgB,YAAchB,KAAKiB,iBAAmBjB,KAAK+C,QAAU,EAAG,OAIpH,GAAI/C,KAAKC,UAAY,UAAYD,KAAKK,KAAM,CAC1CL,KAAKsB,IAAM,EACXtB,KAAKuB,QAAU,EACfvB,KAAKwB,MAAQ,EACbxB,KAAKyB,YAAa,EAClBzB,KAAKwD,SAAW,EAChBxD,KAAKyD,UAAW,EAChBzD,KAAK0D,YAAc1D,KAAKwF,SACxBxF,KAAK2D,QAAU3D,KAAKwF,SACpBxF,KAAK2H,aACL,M,CAKF,GAAI3H,KAAKC,UAAY,WAAaD,KAAKK,KAAM,CAC3C,GAAIL,KAAKc,sBAAwBsE,wBAA0B,YAAa,CAGtEpF,KAAKkB,cAAgB,KACrBlB,KAAKe,YAAc,KACnB,M,CAEFf,KAAK8D,SAAW,EAChB9D,KAAK2H,aACL,M,CAKF,GAAI3H,KAAKc,sBAAwBsE,wBAA0B,YAAa,CACtEpF,KAAKoE,iBACL,M,CAMFpE,KAAK6B,eAAiB7B,KAAKwF,SAC3BxF,KAAK4C,mBAAqB5C,KAAKwF,SAC/BxF,KAAKiD,OAASjD,KAAK4C,mBACnB5C,KAAKkD,QAAU,EACflD,KAAKgD,SAAU,EAEf,GAAIhD,KAAKK,KAAM,CACbL,KAAKsB,IAAM,EACXtB,KAAKwB,MAAQ,EACbxB,KAAKyB,YAAa,EAClBzB,KAAKuB,QAAUvB,KAAKsB,G,CAItB,GAAItB,KAAK4C,oBAAsB,EAAI,KAAM,CACvC5C,KAAKiD,OAAS,EACdjD,KAAK+C,QAAU/C,KAAKK,KAAO,EAAI,C,KAC1B,CACLL,KAAK+C,QAAU,C,CAEjB/C,KAAK2H,Y,CAGC,cAAAvD,GACNpE,KAAKe,YAAc,MACnBf,KAAKkB,cAAgB,MACrBlB,KAAK+C,QAAU,EACf/C,KAAK8D,SAAW,EAGhB,GAAI9D,KAAKC,UAAY,aAAeD,KAAKK,KAAM,CAC7CL,KAAKiB,gBAAkB,I,KAClB,CACLjB,KAAKgB,WAAa,I,CAEpBhB,KAAK+I,WAAWC,M,CAOV,cAAAhC,GACN,MAAMR,EAAIxG,KAAKiG,IAAIjB,MACnB,IAAKwB,EAAG,OACR,MAAMlI,EAAI0B,KAAK0G,kBACfF,EAAEyC,YAAY,eAAgB,GAAG3K,OACjCkI,EAAEyC,YAAY,mBAAoB,GAAGjJ,KAAKK,KAAOL,KAAK6G,iBAAmBvI,OACzE,GAAI0B,KAAKC,UAAY,YAAcD,KAAKS,KAAO,EAAG,CAChD+F,EAAEyC,YAAY,UAAW,GAAGjJ,KAAKuG,iB,KAC5B,CACLC,EAAE0C,eAAe,U,CAGnB,GAAIlJ,KAAKK,MAAQL,KAAKC,UAAY,SAAU,CAC1C,MAAMkJ,EAAKnJ,KAAK0E,mBAChB8B,EAAEyC,YAAY,oBAAqB,GAAGE,OACtC3C,EAAEyC,YAAY,oBAAqB,GAAGE,OAAQnJ,KAAK6G,sBAEnD,MAAMuC,EAAMhK,KAAKG,IAAI,GAAIH,KAAKiK,MAAOF,EAAKnJ,KAAKyE,kBAAqB,MACpE+B,EAAEyC,YAAY,mBAAoB,GAAGG,OACrCpJ,KAAKsJ,kB,KACA,CACL,CAAC,oBAAqB,eAAgB,oBAAqB,oBAAoBC,SAASC,GACtFhD,EAAE0C,eAAeM,I,CAIrBxJ,KAAKyJ,qBAAqBjD,E,CAiBpB,oBAAAiD,CAAqBjD,GAC3B,GAAIxG,KAAKC,UAAY,WAAY,OACjC,MAAMyJ,EAAI1J,KAAK2J,eACf,MAAMC,EAAI,EAAIxK,KAAKuF,GAAK+E,EACxB,MAAMG,EAAID,EAAI,GAAK7M,EAASiD,KAAK4G,oBAAsBgD,EAAI,EAE3D,MAAMZ,EAAO,CAACc,EAAaC,EAAWC,KACpC,MAAMC,EAAI7K,KAAKG,IAAI,KAAQH,KAAKE,IAAI,EAAG,EAAIyK,EAAI,EAAIF,IACnDrD,EAAEyC,YAAY,cAAca,IAAOG,EAAEC,QAAQ,IAC7C1D,EAAEyC,YAAY,eAAea,KAAQ,EAAIG,GAAGC,QAAQ,IACpD1D,EAAEyC,YAAY,cAAca,KAAQE,EAAID,EAAIF,GAAGK,QAAQ,GAAG,EAE5DlB,EAAK,IAAK,IAAM,GAChBA,EAAK,KAAM,IAAK,KAChBA,EAAK,MAAO,KAAM,I,CAIZ,iBAAAJ,GACN,GAAI5I,KAAKwD,SAAW,GAAKxD,KAAK+C,QAAU,EAAG,OAC3C,MAAM6C,EAAS5F,KAAK8G,gBACpB,GAAIlB,IAAW5F,KAAKwB,OAASxB,KAAKyB,WAAa,EAAG,OAClD,GAAImE,IAAW5F,KAAKwB,MAAO,OAC3BxB,KAAKuB,QAAUvB,KAAKsB,IACpBtB,KAAKwB,MAAQoE,EACb5F,KAAK0B,QAAUkE,EAAS5F,KAAKuB,QAAU/B,EAAUC,EACjDO,KAAKyB,YAAa,EAClB,GAAIzB,KAAKc,sBAAwBsE,wBAA0B,YAAa,CAEtEpF,KAAKsB,IAAMsE,EACX5F,KAAKyB,YAAa,EAClBzB,KAAK8F,iBACL,M,CAEF9F,KAAK2H,Y,CAIC,cAAA7B,GACN,GAAI9F,KAAKC,UAAY,SAAU,CAC7B,GAAID,KAAKK,OAASL,KAAKG,cAAeH,KAAKqF,wBACtC,IAAKrF,KAAKK,KAAML,KAAKsJ,kB,KAErB,CACLtJ,KAAKyF,oB,EAKD,aAAAM,GACN,UAAWX,wBAA0B,YAAa,OAAO,MACzD,IAAKpF,KAAK0C,SAAW1C,KAAKc,cAAe,OAAO,MAEhD,GAAId,KAAK+C,QAAU,EAAG,OAAO,KAE7B,GAAI/C,KAAKwD,SAAW,EAAG,OAAO,KAE9B,GAAIxD,KAAKe,aAAef,KAAKC,UAAY,SAAU,OAAO,MAG1D,GAAID,KAAKC,UAAY,YAAcD,KAAKK,KAAM,CAC5C,GAAIL,KAAKG,cAAe,OAAO,KAC/B,OACEH,KAAKsB,IAAM,GACXtB,KAAKsB,MAAQtB,KAAKwB,OAClBpC,KAAKC,IAAIW,KAAK6B,eAAiB7B,KAAKwF,UAAY,I,CAMpD,GAAIxF,KAAKC,UAAY,aAAeD,KAAKK,OAASL,KAAKG,cAAe,CACpE,OAAQH,KAAKiB,iBAAmB7B,KAAKC,IAAIW,KAAK6B,eAAiB7B,KAAKwF,UAAY,I,CAIlF,GAAIxF,KAAKC,UAAY,UAAYD,KAAKK,OAASL,KAAKG,cAAe,CACjE,OAAOH,KAAKsB,IAAM,GAAKtB,KAAKsB,MAAQtB,KAAKwB,OACvCpC,KAAKC,IAAIW,KAAK8B,qBAAuB9B,KAAKwF,UAAY,I,CAG1D,GAAIxF,KAAKC,UAAY,UAAYD,KAAKK,MAAQL,KAAKG,cAAe,OAAO,KAGzE,GAAIH,KAAKC,UAAY,WAAaD,KAAKK,OAASL,KAAKG,cAAe,CAClE,GAAIH,KAAK8D,SAAW,EAAG,OAAO,KAC9B,OAAO1E,KAAKC,IAAIW,KAAK8B,qBAAuB9B,KAAKwF,UAAY,I,CAE/D,OAAO,K,CAGD,UAAAmC,GACN,GAAI3H,KAAK+F,gBAAiB,CACxB,IAAK/F,KAAKmB,IAAKnB,KAAKmB,IAAMiE,sBAAsBpF,KAAKqE,M,MAChD,GAAIrE,KAAKsB,MAAQtB,KAAKwB,MAAO,CAClCxB,KAAK6E,U,EAID,QAAAA,GACN,GAAI7E,KAAKmB,IAAKgJ,qBAAqBnK,KAAKmB,KACxCnB,KAAKmB,IAAM,EACXnB,KAAK2B,QAAS,EAGd3B,KAAK4B,cAAe,C,CA4Md,gBAAAyD,GACN,KAAMrF,KAAKK,MAAQL,KAAKC,UAAY,WAAaD,KAAKG,eAAgB,OACtE,IAAKH,KAAK+B,cAAe,OAGzB,MAAMqI,EAAIpK,KAAKyC,aAAezC,KAAK+H,qBACnC,IAAKqC,EAAG,OAGR,MAAMC,EAAOrK,KAAKwD,SAAW,EAAIxD,KAAK2D,QAAU3D,KAAK8B,qBACrD,MAAMwI,EAAQD,EAAOD,EAKrB,IAAIjL,EAAI,GACR,GAAImL,EAAQ,EAAG,CAGbnL,EAAIa,KAAK2C,IACL3C,KAAKuK,uBAAuBH,EAAIE,EAAOF,EAAGpK,KAAKsB,IAAKtB,KAAKqB,YAAa,MACtErB,KAAKuK,uBAAuB,EAAGD,EAAOtK,KAAKsB,IAAKtB,KAAKqB,YAAa,K,CAExErB,KAAK+B,cAAc+C,aAAa,IAAK3F,GASrC,GAAIa,KAAKiC,mBAAoB,CAC3B,MAAMuI,IAAQH,EAAO,KAAKH,QAAQ,GAClClK,KAAKiC,mBAAmB+C,MAAMiE,YAC5B,iBACAuB,EAAM,EAAI,QAAQA,oBAAwB,I,EAaxC,gBAAA3E,GACN,KAAM7F,KAAKC,UAAY,WAAaD,KAAKK,OAASL,KAAKG,eAAgB,OAGvE,MAAMqK,IAAQxK,KAAK8B,qBAAuB,KAAKoI,QAAQ,GACvDlK,KAAKkC,eAAe8C,MAAMiE,YAAY,gBAAiB,GAAGuB,MAC1DxK,KAAKmC,cAAc6C,MAAMiE,YACvB,iBACAuB,GAAO,IACH,2BACAA,EAAM,EACJ,QAAQA,oBACR,I,CAKF,yBAAA7E,GACN,KAAM3F,KAAKK,MAAQL,KAAKC,UAAY,UAAYD,KAAKG,eAAgB,OACrE,MAAMsK,EAAUzK,KAAKgC,kBAAkBmG,wBACvC,MAAMuC,EAAgBD,GAAWzK,KAAKiG,GAAGkC,wBACzC,MAAMiC,EAAIM,EAActC,MACxB,IAAKgC,EAAG,OAER,MAAMV,EAAI1J,KAAK4G,mBAAqB,EACpC,MAAM+D,EAAqC,GAE3C,MAAMC,EAAU,CAACC,EAA+BC,KAC9C,IAAKD,IAAWC,EAAS,OACzB,MAAMC,EAAKF,EAAO1C,wBAClB,MAAM6C,EAASD,EAAGE,KAAOP,EAAcO,KACvC,MAAMC,EAAOH,EAAGI,MAAQT,EAAcO,KACtC,GAAIC,EAAOF,EAAS,EAAG,CAAEF,EAAQhG,aAAa,IAAK,IAAK,M,CACxDgG,EAAQhG,aAAa,IAAK9E,KAAKuK,uBAAuBS,EAAQE,EAAMlL,KAAKsB,IAAKtB,KAAKqB,cAEnFsJ,EAAUS,KAAK,CAACJ,EAAStB,EAAGwB,EAAOxB,GAAG,EAExCkB,EAAQ5K,KAAKoC,aAAcpC,KAAKsC,eAChCsI,EAAQ5K,KAAKqC,aAAcrC,KAAKuC,eAIhC,GAAIvC,KAAKwC,cAAe,CACtB,MAAM6I,EAAOrL,KAAKsL,eAAeX,EAAWP,GAC5CpK,KAAKwC,cAAcwC,MAAMiE,YAAY,qBAAsBoC,GAC3DrL,KAAKwC,cAAcwC,MAAMiE,YAAY,aAAcoC,E,EAS/C,cAAAC,CAAeC,EAAsCnB,GAC3D,MAAMoB,EAAOD,EACVE,KAAI,EAAEjF,EAAGxC,KAAO,CACf5E,KAAKG,IAAI,EAAGH,KAAKE,IAAI,IAAMkH,EAAI4D,EAAK,MACpChL,KAAKG,IAAI,EAAGH,KAAKE,IAAI,IAAM0E,EAAIoG,EAAK,SAErCsB,QAAO,EAAElF,EAAGxC,KAAOA,EAAIwC,IACvBmF,MAAK,CAACC,EAAGC,IAAMD,EAAE,GAAKC,EAAE,KAE3B,MAAMC,EAAkC,GACxC,IAAK,MAAOtF,EAAGxC,KAAMwH,EAAM,CACzB,MAAMO,EAAOD,EAAOA,EAAOE,OAAS,GACpC,GAAID,GAAQvF,GAAKuF,EAAK,GAAIA,EAAK,GAAK3M,KAAKG,IAAIwM,EAAK,GAAI/H,QACjD8H,EAAOV,KAAK,CAAC5E,EAAGxC,G,CAEvB,IAAK8H,EAAOE,OAAQ,MAAO,OAE3B,MAAMC,EAAkB,GACxB,IAAIC,EAAS,EACb,IAAK,MAAO1F,EAAGxC,KAAM8H,EAAQ,CAC3BG,EAAMb,KACJ,QAAQc,EAAOhC,QAAQ,MACvB,QAAQ1D,EAAE0D,QAAQ,MAClB,eAAe1D,EAAE0D,QAAQ,MACzB,eAAelG,EAAEkG,QAAQ,MACzB,QAAQlG,EAAEkG,QAAQ,OAEpBgC,EAASlI,C,CAEXiI,EAAMb,KAAK,QAAQc,EAAOhC,QAAQ,MAAO,aACzC,MAAO,6BAA6B+B,EAAME,KAAK,Q,CAgBzC,sBAAA5B,CACNS,EACAE,EACA5J,EACAF,EACAgL,EAAQ,OAER,GAAIlB,GAAQF,EAAQ,MAAO,GAC3B,MAAMqB,EAAIrM,KAAK6G,iBACf,MAAMnI,EAAK2N,EAAI,EACf,MAAMlD,EAAKnJ,KAAK0E,mBAChB,MAAMgF,EAAI1J,KAAK4G,mBAAqB,EAIpC,MAAM0F,EAAYF,EAAQpB,EAAStB,EAAIsB,EACvC,MAAMuB,EAAUH,EAAQlB,EAAOxB,EAAIwB,EAKnC,MAAMsB,EAAUpN,KAAKG,IAAI,EAAGgN,EAAUD,GACtC,MAAMG,EAAInL,EAAMtB,KAAKyG,kBAAoBrH,KAAKE,IAAI,EAAGkN,EAAUrD,GAK/D,GAAIiD,GAASG,GAAWD,EAAW,CACjC,MAAM/N,GAAMyM,EAASE,GAAQ,EAC7B,MAAMwB,GAAMxB,EAAOF,GAAU,EAC7B,MACE,MAAMzM,EAAKmO,GAAIxC,QAAQ,MAAMxL,EAAGwL,QAAQ,MACxC,KAAKwC,EAAGxC,QAAQ,MAAMwC,EAAGxC,QAAQ,aAAa,EAAIwC,GAAIxC,QAAQ,QAC9D,KAAKwC,EAAGxC,QAAQ,MAAMwC,EAAGxC,QAAQ,cAAa,EAAKwC,GAAIxC,QAAQ,Q,CAOnE,MAAMyC,EAAQvN,KAAKG,IAAI,EAAGH,KAAKiK,OAAQkD,EAAUD,GAAanD,EAAM3L,IAEpE,MAAMoP,EAA+B,GACrC,MAAMC,EAA+B,GACrC,IAAK,IAAI5N,EAAI,EAAGA,GAAK0N,EAAO1N,IAAK,CAC/B,MAAMD,EAAIsN,GAAcC,EAAUD,GAAarN,EAAK0N,EACpD,MAAMG,EAAKpO,EAAK+N,EAAIrN,KAAK2N,IAAK,EAAI3N,KAAKuF,GAAK3F,EAAKmK,EAAK/H,GACtDwL,EAAIxB,KAAK,CAACpM,EAAG8N,EAAKpD,IAClBmD,EAAIG,QAAQ,CAAChO,EAAG8N,EAAKpD,G,CAGvB,MAAMuD,EAAKvO,EAAK+N,EAAIrN,KAAK2N,IAAK,EAAI3N,KAAKuF,GAAK2H,EAAanD,EAAK/H,GAC9D,MAAM8L,EAAKxO,EAAK+N,EAAIrN,KAAK2N,IAAK,EAAI3N,KAAKuF,GAAK4H,EAAWpD,EAAK/H,GAE5D,MAAM+L,EAAW,KAAKb,EAAUpC,QAAQ,OAAO+C,EAAKvD,GAAGQ,QAAQ,KAC/D,MAAMkD,EAAW,KAAK1D,EAAEQ,QAAQ,MAAMR,EAAEQ,QAAQ,YAAYoC,EAAUpC,QAAQ,OAAO+C,EAAKvD,GAAGQ,QAAQ,KACrG,MAAMmD,EAAWC,EAAWV,GAAKW,QAAQ,cAAe,IACxD,MAAMC,EAAW,KAAK9D,EAAEQ,QAAQ,MAAMR,EAAEQ,QAAQ,YAAYqC,EAAQrC,QAAQ,OAAOgD,EAAKxD,GAAGQ,QAAQ,KACnG,MAAMuD,EAAWH,EAAWT,GAAKU,QAAQ,cAAe,IAExD,MAAO,GAAGJ,KAASC,KAAWC,KAAWG,KAAYC,K,CAI/C,gBAAAnE,GACN,KAAMtJ,KAAKK,MAAQL,KAAKC,UAAY,UAAW,OAC/C,MAAMuG,EAAIxG,KAAKiG,IAAIjB,MACnB,IAAKwB,EAAG,OACRA,EAAEyC,YAAY,eAAgBjJ,KAAK0N,gBAAgB1N,KAAKsB,K,CAGlD,eAAAoM,CAAgBpM,GACtB,MAAM6H,EAAKnJ,KAAK0E,mBAChB,MAAMpG,EAAI0B,KAAK2G,mBACf,MAAM0F,EAAIrM,KAAK6G,iBACf,MAAMnI,EAAK2N,EAAI,EACf,MAAMI,EAAInL,EAAMtB,KAAKyG,kBAMrB,MAAMkG,EAAQvN,KAAKG,IAAI,GAAIH,KAAKiK,MAAMF,EAAK,IAC3C,MAAM0D,EAA+B,GACrC,MAAMD,EAA+B,GACrC,IAAK,IAAI3N,EAAI,EAAGA,GAAK0N,EAAO1N,IAAK,CAC/B,MAAMD,EAAKmK,EAAKlK,EAAK0N,EACrB,MAAMG,EAAKL,EAAIrN,KAAK2N,IAAK,EAAI3N,KAAKuF,GAAK3F,EAAKmK,GAC5C0D,EAAIzB,KAAK,CAACpM,EAAGN,EAAKoO,EAAKxO,EAAI,IAC3BsO,EAAII,QAAQ,CAAChO,EAAGN,EAAKoO,EAAKxO,EAAI,G,CAEhC,MAAMmP,EAAUH,EAAWT,GAE3B,MAAMQ,EAAUC,EAAWV,GAAKW,QAAQ,aAAc,KAAKX,EAAI,GAAG,GAAG1C,QAAQ,MAAM0C,EAAI,GAAG,GAAG1C,QAAQ,MACrG,MAAM/K,EAAI,GAAGsO,KAAWJ,MACxB,MAAMM,EACJ,kDAAkDxE,cAAekD,mBAAmBlD,KAAMkD,MAC1F,YAAYlN,0BACd,MAAO,2BAA2ByO,mBAAmBD,M,CAIvD,kBAAYhE,GAIV,MAAMkE,GAAQ7N,KAAKuG,aAAevG,KAAK4G,oBAAsB,GAAK5G,KAAKK,KAAOL,KAAKyG,kBAAoB,GACvG,OAAOrH,KAAKG,IAAI,GAAKsO,E,CAIvB,oBAAYC,GACV,MAAMpE,EAAI1J,KAAK2J,eACf,MAAMR,EAAKnJ,KAAK0E,mBAChB,OAAOtF,KAAKG,IAAIvB,EAAuBoB,KAAKiK,MAAO,EAAIjK,KAAKuF,GAAK+E,EAAKP,G,CAIhE,WAAA4E,CAAYC,EAAYC,EAAY3M,EAAaF,GACvD,MAAM7C,EAAKyB,KAAKuG,aAAe,EAC/B,MAAM7H,EAAKsB,KAAKuG,aAAe,EAC/B,MAAMmD,EAAI1J,KAAK2J,eACf,MAAMuE,EAAIlO,KAAK8N,iBACf,MAAMrB,EAAInL,EAAMtB,KAAKyG,kBACrB,MAAM0H,EAAOF,EAAKD,EAClB,MAAMrB,EAAQvN,KAAKG,IAAI,EAAGH,KAAKgP,KAAMhP,KAAKC,IAAI8O,IAAS,EAAI/O,KAAKuF,IAAOuJ,EAAI,IAC3E,MAAMG,EAA+B,GACrC,IAAK,IAAIpP,EAAI,EAAGA,GAAK0N,EAAO1N,IAAK,CAC/B,MAAMqP,EAAKN,EAAKG,GAAQlP,EAAI0N,GAC5B,MAAMD,EAAKhD,EAAI+C,EAAIrN,KAAKmP,IAAIL,EAAII,EAAKlN,GACrCiN,EAAIjD,KAAK,CAAC7M,EAAKmO,EAAKtN,KAAKmP,IAAID,GAAK5P,EAAKgO,EAAKtN,KAAK2N,IAAIuB,I,CAEvD,OAAOhB,EAAWe,E,CAIZ,OAAAG,CAAQR,EAAYC,GAC1B,MAAM1P,EAAKyB,KAAKuG,aAAe,EAC/B,MAAM7H,EAAKsB,KAAKuG,aAAe,EAC/B,MAAMmD,EAAI1J,KAAK2J,eACf,MAAM8E,EAAQrP,KAAKC,IAAI4O,EAAKD,GAAM5O,KAAKuF,GAAK,EAAI,EAChD,MAAM+J,EAAQT,EAAKD,EAAK,EAAI,EAC5B,MAAMW,EAAKpQ,EAAKmL,EAAItK,KAAKmP,IAAIP,GAC7B,MAAMY,EAAKlQ,EAAKgL,EAAItK,KAAK2N,IAAIiB,GAC7B,MAAM9P,EAAKK,EAAKmL,EAAItK,KAAKmP,IAAIN,GAC7B,MAAM9P,EAAKO,EAAKgL,EAAItK,KAAK2N,IAAIkB,GAC7B,MAAO,KAAKU,EAAGzE,QAAQ,MAAM0E,EAAG1E,QAAQ,QAAQR,KAAKA,OAAO+E,KAASC,KAASxQ,EAAGgM,QAAQ,MAAM/L,EAAG+L,QAAQ,I,CAQpG,aAAA2E,CACNxE,EACA/I,EACAF,EACAjB,EACAuO,GAEA,MAAMvB,GAAS/N,KAAKuF,GAAK,EACzB,MAAMrG,EAAI0B,KAAK4G,mBACf,MAAM8C,EAAI1J,KAAK2J,eACf,MAAMsE,EAAKd,GAAShN,EAAgBuO,GAAS7Q,EAAqBwM,GAAQ,EAAIjL,KAAKuF,GACnF,MAAMmK,EAASb,EAAKd,EAAQ,KAAO,GAAKnN,KAAK+N,YAAYZ,EAAOc,EAAI3M,EAAKF,GAEzE,IAAI2N,EACJ,IAAK5O,GAAiBkK,EAAO,GAAKA,EAAO,EAAG,CAI1C,MAAM2E,GAAUjS,EAASuB,EAAIgD,EAAMtB,KAAKyG,mBAAqBiD,EAC7D,MAAMuF,EAAahB,EAAKe,EACxB,MAAME,EAAW/B,EAAQ,EAAI/N,KAAKuF,GAAKqK,EAIvCD,EAAQG,EAAWD,EAAajP,KAAKwO,QAAQS,EAAYC,GAAY,E,MAChE,IAAK/O,EAAe,CAEzB4O,EAAQ/O,KAAKwO,QAAQrB,EAAOA,EAAQ,EAAI/N,KAAKuF,GAAK,K,KAC7C,CAILoK,EAAQ,E,CAEV,MAAO,CAAED,SAAQC,Q,CASX,uBAAAnK,GACN,MAAMuI,GAAS/N,KAAKuF,GAAK,EAOzB,MAAMwK,EAAUnP,KAAK+C,UAAY,EACjC,MAAMqM,EAASD,EAAUnP,KAAKkD,QAAU,EACxC,MAAMmM,EAASF,EAAU,EAAInP,KAAKiD,OAClC,MAAMkL,EAAOkB,EAASD,EAKtB,MAAMxF,EAAI,EAAIxK,KAAKuF,GAAK3E,KAAK2J,eAC7B,MAAM2F,EAAW1F,EAAI,EAAI5J,KAAK4G,mBAAqBgD,EAAI,IACvD,MAAM2F,GAAcJ,EAChB,EACAhB,GAAQ,KACN,EACAA,EAAOmB,EACLlQ,KAAKG,IAAI,EAAG4O,EAAOmB,GACnB,EAER,MAAMtB,EAAKb,EAAQiC,EAAS,EAAIhQ,KAAKuF,GACrC,MAAMsJ,EAAKd,EAAQkC,EAAS,EAAIjQ,KAAKuF,GAErC,GAAI3E,KAAKK,KAAM,CACb,MAAMyO,EAASX,EAAO,KAAO,GAAKnO,KAAK+N,YAAYC,EAAIC,EAAIjO,KAAKsB,IAAKtB,KAAKoB,OAC1E,GAAIpB,KAAKwP,UAAW,CAClBxP,KAAKwP,UAAUxK,MAAMC,QAAUsK,GAAc,EAAI,GAAK,GAAGA,IACzDvP,KAAKwP,UAAU1K,aAAa,IAAKgK,E,CAEnC9O,KAAKyP,UAAU3K,aAAa,IAAK,G,KAC5B,CAML,MAAM3F,EAAIgP,EAAO,KAAO,GAAKnO,KAAK+N,YAAYC,EAAIC,EAAI,EAAGjO,KAAKoB,OAC9D,GAAIpB,KAAK8C,wBAAyB,CAChC9C,KAAK8C,wBAAwBkC,MAAMC,QAAUsK,GAAc,EAAI,GAAK,GAAGA,IACvEvP,KAAK8C,wBAAwBgC,aAAa,IAAK3F,E,CAGjD,GAAIa,KAAK+E,gBAAiB/E,KAAK+E,gBAAgBC,MAAMC,QAAU,IAK/D,GAAIjF,KAAK6C,qBAAsB,CAC7B,MAAMqC,EAAKlF,KAAK6C,qBAChBqC,EAAGC,gBAAgB,oBACnBD,EAAGC,gBAAgB,qBACnBD,EAAGF,MAAMC,QAAU,G,GAQzB,mBAAYyK,GACV,GAAI1P,KAAK+C,UAAY,EAAG,MAAO,GAC/B,MAAMoK,GAAS/N,KAAKuF,GAAK,EACzB,MAAMwK,EAAUnP,KAAK+C,UAAY,EACjC,MAAMqM,EAASD,EAAUnP,KAAKkD,QAAU,EACxC,MAAMmM,EAASF,EAAU,EAAInP,KAAKiD,OAClC,GAAIoM,EAASD,EAAS,KAAM,MAAO,GACnC,OAAOpP,KAAK+N,YAAYZ,EAAQiC,EAAS,EAAIhQ,KAAKuF,GAAIwI,EAAQkC,EAAS,EAAIjQ,KAAKuF,GAAI,EAAG3E,KAAKoB,M,CAItF,kBAAAqE,GACN,KAAMzF,KAAKK,MAAQL,KAAKC,UAAY,YAAa,OACjD,MAAMyO,EAAQ1O,KAAKG,cAAgBH,KAAK2P,qBAAuBC,UAC/D,MAAMd,OAAEA,EAAMC,MAAEA,GAAU/O,KAAK6O,cAC7B7O,KAAK6B,eACL7B,KAAKsB,IACLtB,KAAKoB,MACLpB,KAAKG,cACLuO,GAEF1O,KAAKwP,WAAW1K,aAAa,IAAKgK,GAElC,GAAI9O,KAAKG,cAAe,CACtB,MAAM0P,EAAM7P,KAAK8P,wBACjB,MAAMvR,EAAKyB,KAAKuG,aAAe,EAC/BvG,KAAK+P,QAAQjL,aAAa,YAAa,UAAU+K,EAAI3F,QAAQ,MAAM3L,KAAMA,MAKzE,MAAMyR,EAAUH,EAAMzQ,KAAKuF,GAAM,IACjC,MAAM+E,EAAI1J,KAAK2J,eACf,MAAMqF,GAAUjS,EAASiD,KAAK4G,mBAAqB5G,KAAKsB,IAAMtB,KAAKyG,mBAAqBiD,EACxF,MAAMyD,GAAS/N,KAAKuF,GAAK,EACzB,MAAMsL,GAAWvB,GAAS7Q,GAAsB,EAAIuB,KAAKuF,GACzD,MAAMuL,EAAiB/C,EAAQ6C,EAASC,EACxC,MAAME,EAAiBhD,EAAQ6C,EAC/B,MAAMf,EAAaiB,EAAiBlB,EACpC,MAAME,EAAaiB,EAAiB,EAAI/Q,KAAKuF,GAAKqK,EAClDhP,KAAKyP,UAAU3K,aAAa,IAAKoK,EAAWD,EACxCjP,KAAKwO,QAAQS,EAAYC,GACzB,G,KACC,CACLlP,KAAKyP,UAAU3K,aAAa,IAAKiK,E,EAa7B,kBAAArJ,GACN,KAAM1F,KAAKC,UAAY,aAAeD,KAAKK,OAASL,KAAKG,eAAgB,OACzE,GAAIH,KAAK+C,QAAU,GAAK/C,KAAKiB,gBAAiB,OAC9C,MAAMmP,EAAIpQ,KAAK6B,eACf,MAAM6H,EAAI1J,KAAK2J,eACf,MAAMC,EAAI,EAAIxK,KAAKuF,GAAK+E,EACxB,MAAMpL,EAAI0B,KAAK4G,mBACf,MAAMyJ,EAAWzG,EAAI,GAAK7M,EAASuB,GAAKsL,EAAI,EAG5C,MAAMkF,EAAS9O,KAAK+E,gBACpB,GAAI+J,EAAQ,CACV,GAAIsB,GAAK,EAAI,KAAMtB,EAAO3J,gBAAgB,yBACrC2J,EAAOhK,aAAa,mBAAoB,GAAGsL,EAAElG,QAAQ,O,CAM5D,MAAMhF,EAAKlF,KAAK6C,qBAChB,GAAIqC,EAAI,CACN,GAAIkL,GAAK,KAAM,CACblL,EAAGC,gBAAgB,oBACnBD,EAAGC,gBAAgB,qBACnBD,EAAGF,MAAMC,QAAU,E,MACd,GAAImL,GAAK,EAAI,KAAM,CAExBlL,EAAGF,MAAMC,QAAU,G,KACd,CACL,MAAMqL,EAAY,EAAIF,EAAI,EAAIC,EAQ9B,MAAMf,EAAW1F,EAAI,EAAItL,EAAIsL,EAAI,IACjC,GAAI0G,GAAa,KAAM,CACrBpL,EAAGF,MAAMC,QAAU,G,MACd,GAAIqL,EAAYhB,EAAU,CAC/BpK,EAAGF,MAAMC,QAAU7F,KAAKG,IAAI,EAAG+Q,EAAYhB,GAAUpF,QAAQ,GAC7DhF,EAAGJ,aAAa,mBAAoB,GAAGwK,EAASpF,QAAQ,QACxDhF,EAAGJ,aAAa,oBAAqB,MAAM,EAAIuL,EAAWf,IAAWpF,QAAQ,K,KACxE,CACLhF,EAAGF,MAAMC,QAAU,GACnBC,EAAGJ,aAAa,mBAAoB,GAAGwL,EAAUpG,QAAQ,QACzDhF,EAAGJ,aAAa,oBAAqB,MAAMsL,EAAIC,IAAWnG,QAAQ,K,IAOlE,kBAAAyF,GACN,GAAI3P,KAAK4B,aAAe,EAAG5B,KAAK4B,aAAe5B,KAAK2B,OACpD,MAAMrD,GAAM0B,KAAK2B,OAAS3B,KAAK4B,cAAgBhE,EAAwBA,EACvE,MAAM2S,EAAQzS,EAAqBD,EACnC,GAAIS,EAAI,GAAK,OAAOT,EAAqB0S,EAAQ7Q,EAAcpB,EAAI,IACnE,OAAOR,EAAqByS,EAAQ7Q,GAAepB,EAAI,IAAO,G,CAQxD,qBAAAwR,GACN,GAAI9P,KAAK4B,aAAe,EAAG5B,KAAK4B,aAAe5B,KAAK2B,OACpD,MAAM6O,EAAUxQ,KAAK2B,OAAS3B,KAAK4B,aACnC,OAAS7D,EAA2B,MAAQyS,EAAU5S,GAAyB,G,CAKjF,gBAAY6S,GACV,OAAOnK,OAAOoK,SAAS1Q,KAAKT,MAAQS,KAAKT,IAAM,EAAIS,KAAKT,IAAM,C,CAGhE,gBAAYoR,GAGV,GAAI3Q,KAAKG,cAAe,OAAOyP,UAC/B,MAAM1B,EAAI9O,KAAKE,IAAIU,KAAKyQ,aAAcrR,KAAKG,IAAI,EAAGS,KAAKE,QACvD,OAAOoG,OAAOoK,SAASxC,GAAKA,EAAI,C,CAG1B,YAAA0C,GACN,OAAO5Q,KAAKG,cAAgBH,KAAK6Q,4BAA8B7Q,KAAK8Q,yB,CAG9D,uBAAAA,GAKN,MAAMC,EAAW/Q,KAAKkB,eAAiBlB,KAAKe,YAAe,IAAMf,KAAKwF,SAAW,IACjF,MAAMgF,EAAMxK,KAAKwF,SAAW,IAC5B,MAAMwL,EAAcD,EAAU,EAE9B,GAAI/Q,KAAKK,KAAM,CAIb,OACEgM,EAAA,OAAK4E,MAAM,gCAA+B,cAAa,OAAOC,eAAgBlR,KAAKkE,iBAChFsG,EAAM,KACL6B,EAAA,OACE4E,MAAM,+BACNE,KAAK,QACLC,IAAMnL,IAASjG,KAAKiC,mBAAqBgE,CAAoB,EAC7DjB,MAAO,CASL,iBAAkBgM,EACd,QAAQxG,oBACR,OAIV6B,EAAA,OAAK4E,MAAM,8BAA8BE,KAAK,mBAG9C9E,EAAA,OACE4E,MAAM,yCACN7I,MAAM,OAAM,cACA,OACZgJ,IAAMnL,IAASjG,KAAKgC,iBAAmBiE,CAAmB,GAE1DoG,EAAA,QACE4E,MAAM,0CACNE,KAAK,mBACLC,IAAMnL,IAASjG,KAAK+B,cAAgBkE,CAAoB,K,CAOlE,OACEoG,EAAA,OAAK4E,MAAM,gCAA+B,cAAa,OAAOC,eAAgBlR,KAAKkE,iBAKjFmI,EAAA,OACE4E,MAAM,gCACNE,KAAK,mBACLC,IAAMnL,IAASjG,KAAKkC,cAAgB+D,CAAoB,EACxDjB,MAAO,CAAE,gBAAiB,GAAG+L,QAO/B1E,EAAA,OACE4E,MAAM,yEACNE,KAAK,QACLC,IAAMnL,IAASjG,KAAKmC,aAAe8D,CAAoB,EACvDjB,MAAO,CAML,iBAAkB+L,GAAW,IACzB,2BACAC,EACE,QAAQxG,oBACR,OAIV6B,EAAA,OAAK4E,MAAM,8BAA8BE,KAAK,mB,CAK5C,yBAAAN,GACN,GAAI7Q,KAAKK,OAASL,KAAKc,cAAe,CAIpC,OACEuL,EAAA,OAAK4E,MAAM,gCAA+B,cAAa,QAIrD5E,EAAA,OACE4E,MAAM,kEACNE,KAAK,QACLC,IAAMnL,IAASjG,KAAKwC,cAAgByD,CAAoB,IAE1DoG,EAAA,OAAK4E,MAAM,kEACT5E,EAAA,OACE4E,MAAM,2EACNG,IAAMnL,IAASjG,KAAKoC,aAAe6D,CAAoB,KAG3DoG,EAAA,OAAK4E,MAAM,oEACT5E,EAAA,OACE4E,MAAM,2EACNG,IAAMnL,IAASjG,KAAKqC,aAAe4D,CAAoB,KAG3DoG,EAAA,OACE4E,MAAM,yCACN7I,MAAM,OAAM,cACA,OACZgJ,IAAMnL,IAASjG,KAAKgC,iBAAmBiE,CAAmB,GAE1DoG,EAAA,QACE4E,MAAM,0CACNG,IAAMnL,IAASjG,KAAKsC,cAAgB2D,CAAoB,IAE1DoG,EAAA,QACE4E,MAAM,0CACNG,IAAMnL,IAASjG,KAAKuC,cAAgB0D,CAAoB,K,CAQlE,MAAMoL,EAAYC,IAAgB,CAChC,6BAA8B,KAC9B,CAAC,+BAA+BA,KAAa,KAC7C,mCAAoCtR,KAAKK,OAE3C,OACEgM,EAAA,OAAK4E,MAAM,gCAA+B,cAAa,QACrD5E,EAAA,OAAK4E,MAAM,kEAAkEE,KAAK,UAClF9E,EAAA,OAAK4E,MAAOI,EAAS,WAAYF,KAAK,oBACpC9E,EAAA,OAAK4E,MAAM,sCAEb5E,EAAA,OAAK4E,MAAOI,EAAS,cACnBhF,EAAA,OAAK4E,MAAM,sC,CAMX,cAAAM,GACN,OAAOvR,KAAKK,KAAOL,KAAKwR,qBAAuBxR,KAAKyR,oB,CAG9C,kBAAAA,GACN,MAAMC,EAAK1R,KAAKuG,aAChB,MAAMjI,EAAI0B,KAAK4G,mBACf,MAAM8C,EAAI1J,KAAK2J,eACf,MAAMgI,EAASD,EAAK,EACpB,MAAMtB,EAAIpQ,KAAKwF,SACf,MAAMoE,EAAI,EAAIxK,KAAKuF,GAAK+E,EACxB,MAAM2G,EAAWzG,EAAI,GAAK7M,EAASuB,GAAKsL,EAAI,EAC5C,MAAMgI,EAAUxB,EAAI,GAAKA,EAAI,EAQ7B,MAAME,EAAYsB,EAAUxS,KAAKG,IAAI,EAAG,EAAI6Q,EAAI,EAAIC,GAAY,EAChE,MAAMwB,EAAeD,GAAWtB,EAAY,EAE5C,OACEjE,EAAA,OAAK4E,MAAM,kCAAkCa,QAAS,OAAOJ,KAAMA,IAAI,cAAc,QAWlF1R,KAAKG,cACJkM,EAAA,UACEvC,IAAI,aACJmH,MAAM,uFACNE,KAAK,QACL5S,GAAIoT,EACJjT,GAAIiT,EACJjI,EAAGA,EAAC,eACUpL,EACdyT,KAAK,OACLC,WAAY,EAAC,iBACE,QACfC,UAAW,cAAcN,KAAUA,KACnCP,IAAMnL,IAASjG,KAAK6C,qBAAuBoD,CAAsB,IAGnEoG,EAAA,UACEvC,IAAI,aACJmH,MAAM,2FACNE,KAAK,QACL5S,GAAIoT,EACJjT,GAAIiT,EACJjI,EAAGA,EAAC,eACUpL,EACdyT,KAAK,OACLC,WAAY,EAAC,iBACE,QACfC,UAAW,cAAcN,KAAUA,KAAS,mBAC1B3R,KAAKiB,gBAAkB2O,UAAYiC,EAAe,GAAGvB,MAAgBV,UAAS,oBAC7E5P,KAAKiB,gBAAkB2O,UAAYiC,IAAiBzB,EAAIC,GAAYT,UACvF5K,MAGEhF,KAAKiB,gBACD2O,UACA5P,KAAK+C,QAAU,GAAM6O,GAAWtB,GAAa,EAC3C,CAAErL,QAAS,KACX2K,UAERwB,IAAMnL,IAASjG,KAAK6C,qBAAuBoD,CAAsB,IAGrEoG,EAAA,UACEvC,IAAI,cACJmH,MAAM,yCACNE,KAAK,mBACL5S,GAAIoT,EACJjT,GAAIiT,EACJjI,EAAGA,EAAC,eACUpL,EACdyT,KAAK,OACLC,WAAY,EAAC,iBACE,QAAO,mBACJhS,KAAKG,eAAiBiQ,GAAK,EAAIR,UAAY,GAAGQ,KAAK,IAKrEpL,MAAOhF,KAAK+C,QAAU,GAAK/C,KAAKgB,YAAchB,KAAKiB,gBAAkB,CAAEgE,QAAS,KAAQ2K,UACxFqC,UAAW,cAAcN,KAAUA,KACnCP,IAAMnL,IAASjG,KAAK+E,gBAAkBkB,CAAsB,IAM9DoG,EAAA,QACE4E,MAAM,8CAA6C,eACrC3S,EACdyT,KAAK,OAAM,iBACI,QACf5S,EAAGa,KAAK0P,gBACR0B,IAAMnL,IAASjG,KAAK8C,wBAA0BmD,CAAoB,I,CAMlE,kBAAAuL,GACN,MAAME,EAAK1R,KAAKuG,aAChB,MAAMjI,EAAI0B,KAAK4G,mBAGf,MAAMkI,OAAEA,EAAMC,MAAEA,GAAU/O,KAAK6O,cAC7B7O,KAAK6B,eACL7B,KAAKsB,IACLtB,KAAKoB,MACLpB,KAAKG,cACLH,KAAKG,cAAgBtC,EAAqB+R,WAG5C,OACEvD,EAAA,OAAK4E,MAAM,kCAAkCa,QAAS,OAAOJ,KAAMA,IAAI,cAAc,QACnFrF,EAAA,QACE4E,MAAM,wCACNE,KAAK,QACLhS,EAAGa,KAAK+C,QAAU,EAAI,GAAKgM,EAAK,eAClBzQ,EACdyT,KAAK,OAAM,iBACI,QACfX,IAAMpN,GAAOhE,KAAKyP,SAAWzL,IAE/BqI,EAAA,KAAG+E,IAAMpN,GAAOhE,KAAK+P,OAAS/L,GAC5BqI,EAAA,QACE4E,MAAM,yCACNE,KAAK,mBACLhS,EAAG2P,EAAM,eACKxQ,EACdyT,KAAK,OAAM,iBACI,QACfX,IAAMpN,GAAOhE,KAAKwP,UAAYxL,K,CAOxC,MAAAkO,GACE,OACE7F,EAAC8F,EAAI,CAAArI,IAAA,2CACHmH,MAAO,CACL,wBAAyB,KACzB,CAAC,0BAA0BjR,KAAKC,WAAY,KAC5C,uCAAwCD,KAAKG,cAC7C,8BAA+BH,KAAKK,KACpC,oCAAqCL,KAAKU,UAC1C,oCAAqCV,KAAKe,YAC1C,kCAAmCf,KAAKgB,YAE1CoR,KAAK,cAAa,aACNpS,KAAKW,OAASiP,UAAS,gBACpB,EAAC,gBACD5P,KAAKyQ,aAAY,gBACjBzQ,KAAK2Q,cAEnB3Q,KAAKC,UAAY,WAAaD,KAAKuR,iBAAmBvR,KAAK4Q,e,gwCAOpE,SAAStD,EAAWe,GAClB,GAAIA,EAAIrC,OAAS,EAAG,MAAO,GAC3B,MAAM7M,EAAc,CAAC,KAAKkP,EAAI,GAAG,GAAGnE,QAAQ,MAAMmE,EAAI,GAAG,GAAGnE,QAAQ,MACpE,IAAK,IAAIjL,EAAI,EAAGA,EAAIoP,EAAIrC,OAAS,EAAG/M,IAAK,CACvC,MAAMoT,EAAKhE,EAAIpP,EAAI,IAAMoP,EAAIpP,GAC7B,MAAMqT,EAAKjE,EAAIpP,GACf,MAAMsT,EAAKlE,EAAIpP,EAAI,GACnB,MAAMuT,EAAKnE,EAAIpP,EAAI,IAAMsT,EACzB,MAAME,EAAMH,EAAG,IAAMC,EAAG,GAAKF,EAAG,IAAM,EACtC,MAAMK,EAAMJ,EAAG,IAAMC,EAAG,GAAKF,EAAG,IAAM,EACtC,MAAMM,EAAMJ,EAAG,IAAMC,EAAG,GAAKF,EAAG,IAAM,EACtC,MAAMM,EAAML,EAAG,IAAMC,EAAG,GAAKF,EAAG,IAAM,EACtCnT,EAAEiM,KACA,KAAKqH,EAAIvI,QAAQ,MAAMwI,EAAIxI,QAAQ,MAAMyI,EAAIzI,QAAQ,MAAM0I,EAAI1I,QAAQ,MAAMqI,EAAG,GAAGrI,QAAQ,MAAMqI,EAAG,GAAGrI,QAAQ,K,CAGnH,OAAO/K,EAAEgN,KAAK,IAChB,C","ignoreList":[]}
1
+ {"version":3,"names":["mdProgressIndicatorCss","GAP_DP","LINEAR_DET_WAVELENGTH","CIRCULAR_WAVELENGTH","LINEAR_AMPLITUDE","CIRCULAR_AMPLITUDE","CIRCULAR_SIZE_FLAT","CIRCULAR_SIZE_WAVE","CIRCULAR_SIZE_MIN","CIRCULAR_SIZE_MAX","WAVE_SAMPLES_PER_WL","AMP_DURATION","AMP_IN","AMP_OUT","CIRCULAR_INDET_CYCLE","CIRCULAR_INDET_MIN","CIRCULAR_INDET_MAX","CIRCULAR_GLOBAL_ROTATION","MIN_CIRCULAR_VERTICES","bezierEasing","x1","y1","x2","y2","t","cx","bx","ax","cy","by","ay","sampleX","sampleY","slopeX","x","i","xt","d","Math","abs","min","max","EASE_IN","EASE_OUT","EASE_STANDARD","MdProgressIndicator","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","value","indeterminate","thickness","wave","waveAmplitude","waveLength","waveSpeed","size","fourColor","label","complete","density","reducedMotion","_completing","_completed","_completedTrack","_fillComplete","raf","phase","linearPhase","amp","ampFrom","ampTo","ampStartTs","ampEase","lastTs","indetStartTs","renderFraction","linearRenderFraction","linearWaveRef","linearWaveSvgRef","linearWaveTrackRef","flatActiveRef","flatTrackRef","indetBar1Ref","indetBar2Ref","indetPath1Ref","indetPath2Ref","indetTrackRef","linearWidth","visible","rtl","completingFromFrac","circularFlatTrackRef","circularFlatCompleteRef","ccPhase","ccStart","ccFrac","ccErase","CC_FILL_DUR","CC_FLATTEN_DUR","CC_WAIT","CC_ERASE_DUR","CC_TRACK_REVEAL_DUR","wlcPhase","wlcStart","wlcFromFrac","wlcFrac","WLC_FILL_DUR","WLC_FLATTEN_DUR","flcPhase","onReducedMotionChange","e","matches","onLinearAnimEnd","animationName","handleComplete","frame","ts","dt","speedFactor","resolvedWaveSpeed","resolvedWavelength","PI","paintCircularCompletion","stopLoop","setAttribute","activeCircleRef","style","opacity","tr","removeAttribute","requestAnimationFrame","updateLinearPath","k","exp","fraction","updateCircularPath","updateCircularFlat","updateLinearIndeterminate","target","updateLinearFlat","applyAmplitude","shouldAnimate","densityScale","el","v","getComputedStyle","getPropertyValue","trim","Number","resolvedSize","s","resolvedAmplitude","resolvedThickness","resolvedWaveStroke","effectiveThickness","linearWaveHeight","amplitudeTarget","componentWillLoad","syncHostStyles","window","matchMedia","mql","addEventListener","componentDidLoad","IntersectionObserver","io","entries","some","isIntersecting","ensureLoop","observe","ResizeObserver","ro","measureLinearWidth","componentDidRender","computeRtl","w","getBoundingClientRect","width","clientWidth","direction","disconnectedCallback","removeEventListener","disconnect","onDimensionChange","onAmplitudeInputChange","retargetAmplitude","onCompleteChange","next","mdComplete","emit","setProperty","removeProperty","wl","dur","round","updateLinearMask","forEach","p","syncSpinnerTrackVars","r","circularRadius","C","g","key","L","O","T","toFixed","cancelAnimationFrame","W","frac","fillX","buildLinearWaveSVGPath","pct","svgRect","containerRect","intervals","drawBar","barRef","pathRef","br","startX","left","endX","right","push","mask","buildTrackMask","intervalsPx","pcts","map","filter","sort","a","b","merged","last","length","stops","cursor","join","inset","h","bodyStart","bodyEnd","bodyLen","A","rr","steps","bot","top","wy","sin","unshift","lw","rw","start","leftCap","botPath","catmullRom","replace","rightCap","topPath","buildLinearMask","svg","encodeURIComponent","base","circularVertices","wavyArcPath","a0","a1","n","span","ceil","pts","th","cos","arcPath","large","sweep","x0","y0","circularPaths","active","track","gapAng","trackStart","trackEnd","erasing","a0frac","a1frac","fadeSpan","endOpacity","activeRef","trackRef","flatCompletionD","indeterminateSweep","undefined","rot","indeterminateRotation","rotRef","rotRad","arcSpan","arcEndScreen","arcStartScreen","f","idealGap","trackFrac","range","elapsed","ariaValueMax","isFinite","ariaValueNow","renderLinear","renderLinearIndeterminate","renderLinearDeterminate","fillPct","hasProgress","class","onAnimationEnd","part","ref","barClass","modifier","renderCircular","renderCircularWave","renderCircularFlat","sz","center","showGap","trackVisible","viewBox","fill","pathLength","transform","render","Host","role","p0","p1","p2","p3","c1x","c1y","c2x","c2y"],"sources":["src/components/md-progress-indicator/md-progress-indicator.css?tag=md-progress-indicator&encapsulation=shadow","src/components/md-progress-indicator/md-progress-indicator.tsx"],"sourcesContent":["/* ==========================================================\n md-progress-indicator — Material Design 3 Progress Indicator\n (Expressive generation)\n Spec: https://m3.material.io/components/progress-indicators/specs\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-progress-indicator-active-indicator-color Active indicator fill\n --md-progress-indicator-active-indicator-shape Active indicator corner radius\n --md-progress-indicator-track-color Track background\n --md-progress-indicator-track-shape Track corner radius\n --md-progress-indicator-stop-indicator-color Stop dot color\n --md-progress-indicator-stop-indicator-shape Stop dot corner radius\n --md-progress-indicator-stop-indicator-size Stop dot diameter\n --md-progress-indicator-stop-indicator-trailing-space Space past the stop dot to the trailing edge (default 0)\n --md-progress-indicator-track-active-indicator-space Gap between track and active indicator (default 4px)\n --md-progress-indicator-four-color-1..4 Four-color cycle colors\n\n CSS PARTS:\n track Background track (rect or SVG circle/path)\n active-indicator Active progress fill\n stop-indicator Stop dot at track end (linear determinate)\n ========================================================== */\n\n/* ── Host ──────────────────────────────────────────────── */\n\n:host {\n --_active-color: var(--md-progress-indicator-active-indicator-color, var(--md-sys-color-primary, #6750A4));\n --_active-shape: var(--md-progress-indicator-active-indicator-shape, var(--_track-shape));\n --_track-color: var(--md-progress-indicator-track-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_track-shape: var(--md-progress-indicator-track-shape, var(--md-sys-shape-corner-full, 9999px));\n --_stop-color: var(--md-progress-indicator-stop-indicator-color, var(--md-sys-color-primary, #6750A4));\n --_stop-shape: var(--md-progress-indicator-stop-indicator-shape, var(--md-sys-shape-corner-full, 9999px));\n --_stop-size: var(--md-progress-indicator-stop-indicator-size, max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px)));\n\n /* M3 verified four-color order: primary → primary-container → tertiary → tertiary-container */\n --_four-color-1: var(--md-progress-indicator-four-color-1, var(--md-sys-color-primary, #6750A4));\n --_four-color-2: var(--md-progress-indicator-four-color-2, var(--md-sys-color-primary-container, #EADDFF));\n --_four-color-3: var(--md-progress-indicator-four-color-3, var(--md-sys-color-tertiary, #7D5260));\n --_four-color-4: var(--md-progress-indicator-four-color-4, var(--md-sys-color-tertiary-container, #FFD8E4));\n\n /* Linear baseline dimensions (M3): gap between track and active indicator,\n and the space reserved past the stop dot to the trailing edge. */\n --_gap: var(--md-progress-indicator-track-active-indicator-space, max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px)));\n --_stop-trailing-space: var(--md-progress-indicator-stop-indicator-trailing-space, 0px);\n --_thickness: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n --_linear-height: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n --_size: max(28px, calc(40px + var(--md-sys-density-scale, 0) * 3px));\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n/* ── Linear layout ─────────────────────────────────────── */\n\n:host(.md-progress-indicator--linear) {\n display: flex;\n inline-size: 100%;\n block-size: var(--_linear-height, 4px);\n}\n\n.md-progress-indicator__linear {\n position: relative;\n display: flex;\n align-items: center;\n inline-size: 100%;\n block-size: 100%;\n /* Clip the indeterminate bars (translateX from -100% → +80/100%) to the\n track bounds so they don't appear sliding in from outside the component;\n border-radius keeps the clipped ends following the rounded track shape. */\n overflow: hidden;\n border-radius: var(--_track-shape);\n}\n\n/* ── Track (inactive) ──────────────────────────────────── */\n\n.md-progress-indicator__track {\n position: absolute;\n inset-inline-start: var(--_track-start, 0);\n inset-inline-end: 0;\n inset-block: 0;\n margin-block: auto;\n block-size: var(--_thickness, 4px);\n border-radius: var(--_track-shape);\n background-color: var(--_track-color);\n}\n\n.md-progress-indicator__track--full {\n inset-inline-start: 0;\n}\n\n/* Determinate (flat) track: its start edge is rAF-driven per-frame by\n updateLinearFlat() from the same eased fraction as the active fill, so the two\n move in lockstep and the gap stays a constant 4dp. No CSS transition — that\n would re-tween each per-frame write and break the lockstep with the fill. */\n.md-progress-indicator__track--determinate {\n transition: none;\n}\n\n/* ── Active indicator (determinate) ────────────────────── */\n\n.md-progress-indicator__active {\n position: absolute;\n inset-inline-start: 0;\n inset-block: 0;\n margin-block: auto;\n inline-size: var(--_fill-width, 0);\n block-size: var(--_thickness, 4px);\n background-color: var(--_active-color);\n border-radius: var(--_active-shape);\n /* No CSS transition: the fill is rAF-driven per-frame by updateLinearFlat()\n using the SAME eased fraction as the wavy variant, so the flat and wavy\n determinate bars move identically and in lockstep. A CSS transition here\n would re-tween each per-frame write and lag the flat variant behind wavy. */\n transition: none;\n}\n\n/* Wavy active indicator — a band masked to a travelling stroked sine.\n Amplitude (mask geometry) is driven from JS via --_wave-mask;\n the crest travel is GPU-only via mask-position. */\n.md-progress-indicator__active--wave {\n block-size: var(--_linear-height, 10px);\n border-radius: 0;\n background-color: var(--_active-color);\n mask-image: var(--_wave-mask);\n mask-size: var(--_wave-mask-size);\n mask-repeat: repeat-x;\n mask-position: left center;\n animation: md-wave-travel var(--_wave-duration, 1000ms) linear infinite;\n}\n\n/* crests travel toward the leading edge (+x in LTR); tile is exactly one\n wavelength wide so the loop is seamless */\n@keyframes md-wave-travel {\n to {\n mask-position: var(--_wave-length-px, 40px) center;\n }\n}\n\n/* ── Wavy linear determinate SVG path ──────────────────────── */\n\n/* Full-width SVG overlay; the rAF loop writes a closed filled path that\n contains both the wave body and the right-side round cap in one element,\n so there is no coordinate-space mismatch between the two. */\n.md-progress-indicator__linear-wave-svg {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.md-progress-indicator__linear-wave-path {\n fill: var(--_active-color);\n}\n\n/* RTL (determinate) is handled in JS: updateLinearPath() draws the wave at\n [W−fillX, W] so it anchors at the right edge — matching the track and stop dot,\n which flip via CSS logical properties. No CSS transform needed here (transforms\n on <svg> elements have cross-browser transform-origin/transform-box quirks).\n Indeterminate RTL is handled by the .__linear container scaleX(-1) flip below. */\n\n/* ── Stop indicator (linear determinate, all states incl. 0%) ─ */\n\n.md-progress-indicator__stop {\n position: absolute;\n inset-inline-end: var(--_stop-trailing-space, 0);\n inset-block: 0;\n margin-block: auto;\n /* clamp to the track thickness so a thin track never overflows */\n inline-size: min(var(--_stop-size), var(--_thickness, 4px));\n block-size: min(var(--_stop-size), var(--_thickness, 4px));\n border-radius: var(--_stop-shape);\n background-color: var(--_stop-color);\n}\n\n/* ── Linear indeterminate bars (authentic M3 two-bar motion, 2000ms) ─────\n Two phase-offset bars sweep the track. The translate lives on the OUTER\n `.md-progress-indicator__bar` and the width-pulse (scale) on the INNER\n `.md-progress-indicator__bar-inner`, run as separate animations with\n per-keyframe easing — this split is what produces the continuous \"chasing\"\n motion (one bar is always entering while the other exits, so the track is\n never empty → no full stop). The keyframes + the off-screen\n `inset-inline-start` pre-offsets are the verified Material Design values; the\n 0px translate holds are masked because the bar is parked off-screen-left\n during them. translateX is physical %, so the container scaleX(-1) flip\n (below) handles RTL. */\n.md-progress-indicator__bar {\n position: absolute;\n inset-block: 0;\n margin-block: auto;\n inline-size: 100%;\n block-size: var(--_thickness, 4px);\n transform-origin: left center;\n}\n\n.md-progress-indicator__bar-inner {\n position: absolute;\n inset: 0;\n inline-size: 100%;\n block-size: 100%;\n background-color: var(--_active-color);\n border-radius: var(--_active-shape);\n /* scale from the CENTRE (the M3 keyframes assume this): the width pulse keeps\n the band centred in its translating .bar, so the shrinking tail sweeps off\n the right edge instead of pinning a sliver mid-track. */\n transform-origin: center;\n}\n\n/* Two DISTINCT sweeps timed to hand off with minimal gap. The secondary enters\n immediately (secondary visible ~0–1400ms); the primary is phase-shifted by\n -1666ms so it enters visible right as the secondary exits (~1400ms) and itself\n exits right before the cycle wraps (~1940ms) — gap ≈60ms, the minimum\n possible with these two keyframe windows. Both bars start off-screen-left so\n neither pops in mid-track at load. */\n.md-progress-indicator__bar--primary {\n inset-inline-start: -145%;\n animation: md-linear-primary-translate 2000ms linear infinite;\n animation-delay: -1666ms;\n}\n.md-progress-indicator__bar--primary > .md-progress-indicator__bar-inner {\n animation: md-linear-primary-scale 2000ms linear infinite;\n animation-delay: -1666ms;\n}\n.md-progress-indicator__bar--secondary {\n inset-inline-start: -55%;\n animation: md-linear-secondary-translate 2000ms linear infinite;\n}\n.md-progress-indicator__bar--secondary > .md-progress-indicator__bar-inner {\n animation: md-linear-secondary-scale 2000ms linear infinite;\n}\n\n/* Primary: parks off-left, then ACCELERATES across (per-keyframe ease curves). */\n@keyframes md-linear-primary-translate {\n 0% { transform: translateX(0); }\n 20% { animation-timing-function: cubic-bezier(0.5, 0, 0.7017, 0.4958); transform: translateX(0); }\n 59.15% { animation-timing-function: cubic-bezier(0.3024, 0.3814, 0.55, 0.9564); transform: translateX(83.6714%); }\n 100% { transform: translateX(250%); }\n}\n\n/* Primary width: expands as it accelerates, then HOLDS wide through the exit so\n it slides off the end at full width (M3 shrinks here; we keep it wide). */\n@keyframes md-linear-primary-scale {\n 0% { transform: scaleX(0.08); }\n 36.65% { animation-timing-function: cubic-bezier(0.3347, 0.1248, 0.7858, 1); transform: scaleX(0.08); }\n 69.15% { animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1); transform: scaleX(0.58); }\n 100% { transform: scaleX(0.62); }\n}\n\n/* Secondary: enters from the left edge straight away (no park), its own faster\n accelerating sweep — this is what fills the track while the primary is parked,\n so each bar still reads as entering from 0. */\n@keyframes md-linear-secondary-translate {\n 0% { animation-timing-function: cubic-bezier(0.15, 0, 0.5151, 0.4097); transform: translateX(0); }\n 25% { animation-timing-function: cubic-bezier(0.3103, 0.2841, 0.8, 0.7337); transform: translateX(37.6519%); }\n 48.35% { animation-timing-function: cubic-bezier(0.4, 0.627, 0.6, 0.902); transform: translateX(84.3862%); }\n 100% { transform: translateX(160.278%); }\n}\n@keyframes md-linear-secondary-scale {\n 0% { animation-timing-function: cubic-bezier(0.205, 0.0571, 0.5766, 0.454); transform: scaleX(0.08); }\n 19.15% { animation-timing-function: cubic-bezier(0.1523, 0.1964, 0.6484, 1.0043); transform: scaleX(0.4571); }\n 44.15% { animation-timing-function: cubic-bezier(0.2578, -0.0032, 0.2118, 1.3818); transform: scaleX(0.58); }\n 100% { transform: scaleX(0.62); }\n}\n\n/* ── Wavy indeterminate (M3 Expressive) ──────────────────────────────────\n Same continuous two-bar choreography, rendered as bold wavy bands. The OUTER\n bar carries the travelling wave mask: the wave is rigid in the bar's own box\n (so it slides bodily with the bar) plus a gentle crest travel; the INNER\n scale still grows/shrinks the band's length. The bolder stroke makes the\n band tall enough to cover the flat track where it passes. */\n.md-progress-indicator__bar--wave {\n block-size: var(--_linear-height, 10px);\n mask-image: var(--_wave-mask);\n mask-size: var(--_wave-mask-size);\n mask-repeat: repeat-x;\n mask-position: left center;\n}\n.md-progress-indicator__bar--wave > .md-progress-indicator__bar-inner {\n border-radius: 0;\n}\n\n/* Ghost bar-inner: drives CSS animations for position tracking but no visual */\n.md-progress-indicator__bar-inner--ghost {\n background-color: transparent;\n}\n\n/* Add the crest travel alongside each bar's sweep (two animations on the outer;\n the mask-position travel is independent of the transform). These rules\n override the base single-animation sweep, so they must re-declare the sweep\n translate (and the secondary's half-cycle offset) to keep both bars moving. */\n.md-progress-indicator__bar--primary.md-progress-indicator__bar--wave {\n animation:\n md-linear-primary-translate 2000ms linear infinite,\n md-wave-travel var(--_wave-duration, 500ms) linear infinite;\n animation-delay: -1666ms, 0ms;\n}\n.md-progress-indicator__bar--secondary.md-progress-indicator__bar--wave {\n animation:\n md-linear-secondary-translate 2000ms linear infinite,\n md-wave-travel var(--_wave-duration, 500ms) linear infinite;\n}\n\n/* RTL: flip the indeterminate animation (the bars translate with physical %,\n so the container flip reverses their sweep direction). */\n:host-context([dir=\"rtl\"]).md-progress-indicator--indeterminate .md-progress-indicator__linear,\n:host([dir=\"rtl\"]).md-progress-indicator--indeterminate .md-progress-indicator__linear {\n transform: scaleX(-1);\n}\n\n/* ── Circular layout ───────────────────────────────────── */\n\n:host(.md-progress-indicator--circular) {\n inline-size: var(--_size, 40px);\n block-size: var(--_size, 40px);\n}\n\n.md-progress-indicator__circular {\n inline-size: 100%;\n block-size: 100%;\n}\n\n.md-progress-indicator__circular-track {\n stroke: var(--_track-color);\n}\n\n/* Determinate (flat) circular track: rAF-driven per-frame by updateCircularFlat()\n from the eased renderFraction, in lockstep with the active arc, so the 4dp gap\n stays constant and the track recedes exactly as the arc grows (its final sliver\n fades via opacity instead of popping). No CSS transition — that would re-tween\n each per-frame write and reintroduce the lag/pop this fix removes. */\n.md-progress-indicator__circular-track--determinate {\n transition: none;\n}\n\n.md-progress-indicator__circular-active {\n stroke: var(--_active-color);\n /* Flat determinate arc is rAF-driven per-frame by updateCircularFlat() from the\n SAME eased renderFraction (and ease) as its track, so the two move in lockstep.\n No CSS transition — it would re-tween each per-frame write and desync the track.\n (The wavy active is a <path>; the indeterminate active overrides this with\n transition:none plus its own md-circular-dash animation.) */\n transition: none;\n}\n\n/* Flat completion arc: an explicit round-capped <path> used only during the closing\n animation (drawn instead of the dashed circle so the shrinking head stays smooth).\n Empty (d=\"\") at all other times, so it paints nothing in steady state. */\n.md-progress-indicator__circular-active-path {\n stroke: var(--_active-color);\n}\n\n/* ── Circular indeterminate (rotation + arc grow/shrink) ─\n These CSS animations drive the FLAT spinner only — :not(--wave). The wavy\n variant is painted + rotated entirely in JS (rAF); without the guard the\n md-circular-dash dasharray would shatter the JS-drawn wavy <path> (it has no\n pathLength) and md-circular-rotate would double-rotate it on top of the JS\n rotation. Reduced-motion re-adds a slow rotation for the wavy variant below. */\n\n:host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular {\n animation: md-circular-rotate 1568ms linear infinite;\n}\n\n:host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active {\n transition: none;\n animation: md-circular-dash 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite;\n}\n\n/* Indeterminate track follows the active arc as its angular complement, leaving a\n gap on each side. Same keyframe timing as md-circular-dash so the two stay\n complementary at every frame; the dash/offset values are precomputed per\n instance (gap-aware) into --_spin-* vars by syncSpinnerTrackVars(). */\n:host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-track--spinner {\n transition: none;\n animation: md-circular-dash-track 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite;\n}\n\n@keyframes md-circular-rotate {\n 100% { transform: rotate(360deg); }\n}\n\n/* pathLength=1 → dash values are fractions of the circumference */\n@keyframes md-circular-dash {\n 0% { stroke-dasharray: 0.05 1; stroke-dashoffset: 0; }\n 50% { stroke-dasharray: 0.70 1; stroke-dashoffset: -0.18; }\n 100% { stroke-dasharray: 0.05 1; stroke-dashoffset: -0.92; }\n}\n\n/* Complement of md-circular-dash (gap-aware). --_spin-* are resolved numbers.\n The dash is `T (1−T)` so the period equals the path length (1) and a track arc\n crossing the 12-o'clock seam wraps correctly (see syncSpinnerTrackVars). */\n@keyframes md-circular-dash-track {\n 0% { stroke-dasharray: var(--_spin-da-0, 0.81) var(--_spin-gap-0, 0.19); stroke-dashoffset: var(--_spin-do-0, -0.12); }\n 50% { stroke-dasharray: var(--_spin-da-50, 0.16) var(--_spin-gap-50, 0.84); stroke-dashoffset: var(--_spin-do-50, -0.95); }\n 100% { stroke-dasharray: var(--_spin-da-100, 0.81) var(--_spin-gap-100, 0.19); stroke-dashoffset: var(--_spin-do-100, -1.04); }\n}\n\n/* ── Four-color cycle (circular indeterminate) ─────────── */\n\n:host(.md-progress-indicator--four-color.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active {\n animation:\n md-circular-dash 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite,\n md-four-color 5332ms linear infinite;\n}\n\n@keyframes md-four-color {\n 0%, 15% { stroke: var(--_four-color-1); }\n 25%, 40% { stroke: var(--_four-color-2); }\n 50%, 65% { stroke: var(--_four-color-3); }\n 75%, 90% { stroke: var(--_four-color-4); }\n 100% { stroke: var(--_four-color-1); }\n}\n\n/* ── Reduced motion ────────────────────────────────────── */\n/* Wave amplitude is flattened to 0 from JS; here we stop the crest travel\n and slow (never freeze) the looping indeterminate so progress is still\n conveyed. Determinate transitions are made instant. */\n@media (prefers-reduced-motion: reduce) {\n .md-progress-indicator__active,\n .md-progress-indicator__circular-active {\n transition-duration: 0s;\n }\n\n /* Stop crest travel on the determinate wave (amplitude flattened to 0 from\n JS). */\n .md-progress-indicator__active--wave {\n animation: none;\n }\n\n /* Linear indeterminate two-bar motion: slow it down (never freeze) so progress\n is still conveyed, and drop the wavy crest travel (the wave is already flat\n from JS). Re-declare the wavy bars' single (translate-only) animation so the\n base dual-animation rule doesn't reinstate the crest travel; keep both bars'\n translate+scale on the same period so primary/secondary stay in sync. */\n .md-progress-indicator__bar--primary,\n .md-progress-indicator__bar--primary > .md-progress-indicator__bar-inner,\n .md-progress-indicator__bar--secondary,\n .md-progress-indicator__bar--secondary > .md-progress-indicator__bar-inner {\n animation-duration: 6s;\n }\n /* Scale the primary phase-offset proportionally to the slowed duration. */\n .md-progress-indicator__bar--primary,\n .md-progress-indicator__bar--primary > .md-progress-indicator__bar-inner {\n animation-delay: -4998ms;\n }\n .md-progress-indicator__bar--primary.md-progress-indicator__bar--wave {\n animation: md-linear-primary-translate 6s linear infinite;\n animation-delay: -4998ms;\n }\n .md-progress-indicator__bar--secondary.md-progress-indicator__bar--wave {\n animation: md-linear-secondary-translate 6s linear infinite;\n }\n\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular {\n animation-duration: 4s;\n }\n\n /* Keep the active arc and its complement track on the same period so the gap\n stays aligned when slowed for reduced motion. */\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active,\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-track--spinner {\n animation-duration: 3s;\n }\n\n :host(.md-progress-indicator--four-color.md-progress-indicator--circular.md-progress-indicator--indeterminate:not(.md-progress-indicator--wave))\n .md-progress-indicator__circular-active {\n animation-duration: 3s, 16s;\n }\n\n /* Wavy circular indeterminate is JS-driven and its rAF loop is paused under\n reduced motion (shouldAnimate() returns false), which would otherwise leave\n it frozen. Give it a slow CSS rotation of the last-painted wavy arc+track so\n progress is still conveyed (the gap between them was baked in at paint time,\n so they rotate together and stay aligned). */\n :host(.md-progress-indicator--circular.md-progress-indicator--indeterminate.md-progress-indicator--wave)\n .md-progress-indicator__circular {\n animation: md-circular-rotate 4s linear infinite;\n }\n}\n\n/* ── Completion (\"closing TV\") animation ──────────────────\n Linear: the full container collapses vertically from the centre (both the\n top and bottom edges meet at the midline), like a CRT powering off.\n Flat circular: handled via WAAPI in JS (arc retracts from its starting\n point). Wavy circular: handled via the rAF loop tween in JS.\n After any variant finishes, --complete hides the host. */\n\n@keyframes md-linear-complete {\n 0% { transform: scaleY(1); }\n 60% { transform: scaleY(0.1); }\n 100% { transform: scaleY(0); }\n}\n\n:host(.md-progress-indicator--linear.md-progress-indicator--completing) .md-progress-indicator__linear {\n transform-origin: center;\n animation: md-linear-complete 300ms cubic-bezier(0.2, 0, 1, 0.8) forwards;\n}\n\n:host(.md-progress-indicator--complete) {\n visibility: hidden;\n}\n\n/* ── Forced colors (high contrast) ─────────────────────── */\n\n@media (forced-colors: active) {\n .md-progress-indicator__active,\n .md-progress-indicator__active--wave,\n .md-progress-indicator__bar,\n .md-progress-indicator__stop {\n background-color: CanvasText;\n }\n\n .md-progress-indicator__track {\n background-color: GrayText;\n }\n\n .md-progress-indicator__circular-track {\n stroke: GrayText;\n }\n\n .md-progress-indicator__circular-active,\n .md-progress-indicator__circular-active-path {\n stroke: CanvasText;\n }\n\n .md-progress-indicator__linear-wave-path {\n fill: CanvasText;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, Element, Watch, State, Event, EventEmitter } from '@stencil/core';\n\n/* ============================================================================\n * Material Design 3 — Progress Indicator (Expressive generation)\n * Spec: https://m3.material.io/components/progress-indicators/specs\n *\n * Conforms to the 2024+ \"expressive\" generation (the version shown on\n * m3.material.io today): animated wavy waveforms, 4dp indicator↔track gaps,\n * round caps, and the expressive indeterminate motion. Constants below were\n * verified against the Compose Material3 source (the authoritative source for\n * the wavy geometry/motion) and Material Web (baseline CSS/tokens).\n * ==========================================================================*/\n\n/** Indicator↔track gap (dp). Fixed token — NOT coupled to thickness. */\nconst GAP_DP = 4;\n/** Wavelength (dp) for the linear wave (both determinate and indeterminate). */\nconst LINEAR_DET_WAVELENGTH = 40;\nconst CIRCULAR_WAVELENGTH = 15;\n/** Peak amplitudes (dp) at amplitude factor = 1. */\nconst LINEAR_AMPLITUDE = 3;\nconst CIRCULAR_AMPLITUDE = 1.6;\n/** Circular container sizes (dp): non-wavy 40, wavy 48. */\nconst CIRCULAR_SIZE_FLAT = 40;\nconst CIRCULAR_SIZE_WAVE = 48;\n/** M3 circular size range (dp): 24 (min) … 240 (max). Sizes are clamped here. */\nconst CIRCULAR_SIZE_MIN = 24;\nconst CIRCULAR_SIZE_MAX = 240;\n/** Wave path sampling density (control points per wavelength). Catmull-Rom\n * smooths between samples, so ~8 is plenty for a clean sine and keeps the\n * per-frame path rebuild cheap. */\nconst WAVE_SAMPLES_PER_WL = 8;\n/** Amplitude in/out animation: 500ms; in = EasingStandard, out = EmphasizedAccelerate. */\nconst AMP_DURATION = 500;\nconst AMP_IN: Bezier = [0.2, 0, 0, 1];\nconst AMP_OUT: Bezier = [0.3, 0, 0.8, 0.15];\n/** Circular indeterminate choreography (Compose expressive). */\nconst CIRCULAR_INDET_CYCLE = 6000;\nconst CIRCULAR_INDET_MIN = 0.1;\nconst CIRCULAR_INDET_MAX = 0.87;\nconst CIRCULAR_GLOBAL_ROTATION = 1080; // deg per cycle\nconst MIN_CIRCULAR_VERTICES = 5;\n\ntype Bezier = [number, number, number, number];\n\n/* ── cubic-bézier easing solver (maps time fraction → eased fraction) ──────*/\nfunction bezierEasing([x1, y1, x2, y2]: Bezier): (t: number) => number {\n if (x1 === y1 && x2 === y2) return (t) => t; // linear\n const cx = 3 * x1;\n const bx = 3 * (x2 - x1) - cx;\n const ax = 1 - cx - bx;\n const cy = 3 * y1;\n const by = 3 * (y2 - y1) - cy;\n const ay = 1 - cy - by;\n const sampleX = (t: number) => ((ax * t + bx) * t + cx) * t;\n const sampleY = (t: number) => ((ay * t + by) * t + cy) * t;\n const slopeX = (t: number) => (3 * ax * t + 2 * bx) * t + cx;\n return (x) => {\n if (x <= 0) return 0;\n if (x >= 1) return 1;\n let t = x;\n for (let i = 0; i < 8; i++) {\n const xt = sampleX(t) - x;\n const d = slopeX(t);\n if (Math.abs(xt) < 1e-5) break;\n if (Math.abs(d) < 1e-6) break;\n t -= xt / d;\n }\n return sampleY(Math.min(1, Math.max(0, t)));\n };\n}\nconst EASE_IN = bezierEasing(AMP_IN);\nconst EASE_OUT = bezierEasing(AMP_OUT);\nconst EASE_STANDARD = bezierEasing([0.2, 0, 0, 1]);\n\n@Component({\n tag: 'md-progress-indicator',\n styleUrl: 'md-progress-indicator.css',\n shadow: true,\n})\nexport class MdProgressIndicator {\n @Element() el!: HTMLElement;\n\n /** Visual variant: linear (horizontal bar) or circular (ring). */\n @Prop() variant: 'circular' | 'linear' = 'linear';\n\n /** Current progress value (0 to max). */\n @Prop() value: number = 0;\n\n /** Maximum progress value. */\n @Prop() max: number = 100;\n\n /** Indeterminate mode — looping animation when progress is unknown. */\n @Prop({ reflect: true }) indeterminate: boolean = false;\n\n /** Track / stroke thickness in dp. */\n @Prop() thickness: number = 4;\n\n /** Enable the wavy (M3 Expressive) active indicator. */\n @Prop({ reflect: true }) wave: boolean = false;\n\n /**\n * Wave amplitude (center-to-peak) in dp. `0` = auto per M3 spec\n * (linear 3dp, circular 1.6dp).\n */\n @Prop({ attribute: 'wave-amplitude' }) waveAmplitude: number = 0;\n\n /**\n * Wavelength (peak-to-peak) in dp. `0` = auto\n * (linear 40dp for both determinate + indeterminate, circular 15dp).\n */\n @Prop({ attribute: 'wave-length' }) waveLength: number = 0;\n\n /**\n * Wave travel speed in dp/second. `0` = auto (= wavelength, i.e. one\n * wavelength per second per the M3 default).\n */\n @Prop({ attribute: 'wave-speed' }) waveSpeed: number = 0;\n\n /**\n * Circular indicator outer size in dp. `0` = auto (non-wavy 40dp,\n * wavy 48dp per the M3 expressive spec). Clamped to the M3 range 24–240dp.\n */\n @Prop() size: number = 0;\n\n /** Four-color cycling animation (circular indeterminate only). */\n @Prop({ attribute: 'four-color', reflect: true }) fourColor: boolean = false;\n\n /** Accessible label for screen readers. */\n @Prop() label: string = 'Progress';\n\n /**\n * Set to `true` to trigger the completion (\"closing TV\") animation. After it\n * plays, the indicator self-hides (`visibility:hidden`) and emits `mdComplete` —\n * EXCEPT the flat (non-wavy) circular variant, which instead rests showing its\n * empty track ring (the active indicator erases away and the track fades in).\n * No-op on indeterminate indicators.\n */\n @Prop() complete: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fired when the completion animation finishes (and the indicator has hidden\n * itself, or — for flat circular — settled on its empty track ring). */\n @Event() mdComplete!: EventEmitter<void>;\n\n /** Tracks the user's reduced-motion preference (drives the flat wave). */\n @State() private reducedMotion: boolean = false;\n @State() private _completing = false;\n @State() private _completed = false;\n /** Flat circular terminal state: active erased, empty track ring left visible\n * (the variant that does NOT self-hide on completion). */\n @State() private _completedTrack = false;\n @State() private _fillComplete = false;\n\n // ── animation state ──────────────────────────────────────────────────────\n private raf = 0;\n private phase = 0; // circular wave phase (radians)\n private linearPhase = 0; // linear wavy determinate phase (radians)\n private amp = 0; // current animated amplitude factor (0..1)\n private ampFrom = 0;\n private ampTo = 0;\n private ampStartTs = -1;\n private ampEase: (t: number) => number = EASE_IN;\n private lastTs = -1;\n private indetStartTs = -1;\n private renderFraction = 0; // eased sweep for the wavy circular determinate arc\n private linearRenderFraction = 0; // eased fill for the wavy linear determinate path\n private activeRef?: SVGPathElement;\n private trackRef?: SVGPathElement;\n private linearWaveRef: SVGPathElement | null = null;\n private linearWaveSvgRef: SVGSVGElement | null = null;\n private linearWaveTrackRef: HTMLDivElement | null = null;\n private flatActiveRef: HTMLDivElement | null = null;\n private flatTrackRef: HTMLDivElement | null = null;\n private indetBar1Ref: HTMLDivElement | null = null;\n private indetBar2Ref: HTMLDivElement | null = null;\n private indetPath1Ref: SVGPathElement | null = null;\n private indetPath2Ref: SVGPathElement | null = null;\n private indetTrackRef: HTMLDivElement | null = null;\n private rotRef?: SVGGElement;\n private mql?: MediaQueryList;\n private io?: IntersectionObserver;\n private ro?: ResizeObserver;\n private linearWidth = 0; // cached layout width (refreshed on render + resize)\n private visible = true;\n private rtl = false; // cached layout direction (refreshed each render)\n\n // ── completion animation state ────────────────────────────────────────────\n private completingFromFrac = 0;\n private activeCircleRef?: SVGCircleElement;\n private circularFlatTrackRef: SVGCircleElement | null = null;\n // Path used ONLY during the flat completion sequence: the erase/fill arc is drawn\n // here as an explicit round-capped <path> (not the dashed <circle>) so the head\n // doesn't jitter the way an animated stroke-dashoffset on a circle does.\n private circularFlatCompleteRef: SVGPathElement | null = null;\n\n // ── circular completion (unified flat + wavy rAF state machine) ───────────\n // Phase 1: fill the arc from the current fraction → a full circle (one pass).\n // Phase 2: (wavy only) flatten the wave amplitude → 0 so it becomes a ring.\n // Phase 3: after a brief hold, erase the ring from the START point, progressively\n // shrinking it clockwise until nothing is left (no track shown).\n // Phase 4: (flat circular only) the line is gone — fade the empty track ring IN,\n // then settle on it (flat circular rests on its track, doesn't self-hide).\n // Driven entirely by plain fields + rAF (NOT @State) so no Stencil re-render\n // detaches the SVG elements mid-animation — that detach was what produced the\n // \"two passes\" (the CSS stroke-dasharray transition re-drawing the arc while\n // the JS animation was also drawing it).\n private ccPhase: 0 | 1 | 2 | 3 | 4 = 0;\n private ccStart = -1;\n private ccFrac = 0; // animated fill fraction during phase 1\n private ccErase = 0; // erase progress 0..1 during phase 3\n private readonly CC_FILL_DUR = 500; // ms\n private readonly CC_FLATTEN_DUR = 300; // ms (wavy only)\n private readonly CC_WAIT = 150; // ms hold at full circle before erasing\n private readonly CC_ERASE_DUR = 550; // ms\n private readonly CC_TRACK_REVEAL_DUR = 300; // ms (flat circular: fade the empty track ring in after the erase)\n\n // ── wave linear completion (multi-phase rAF sequence) ─────────────────────\n // Phase 1: fill the wave path from current fraction → 1 (WLC_FILL_DUR ms)\n // Phase 2: tween amplitude → 0 so the wave flattens (AMP_DURATION ms)\n // After phase 2: set _completing = true → CSS scaleY collapse plays\n private wlcPhase: 0 | 1 | 2 = 0;\n private wlcStart = -1;\n private wlcFromFrac = 0;\n private wlcFrac = 0;\n private readonly WLC_FILL_DUR = 300; // ms to fill wave path to 100%\n private readonly WLC_FLATTEN_DUR = 300; // ms to flatten wave to a straight line\n\n // ── flat linear completion (rAF fill phase) ───────────────────────────────\n // Phase 1: ease the fill fraction → 1 (sharing the wavy variant's ease), then\n // hand off to the CSS scaleY collapse. Driven by the same linearRenderFraction\n // as the steady-state fill so the flat + wavy variants stay perfectly in sync.\n private flcPhase: 0 | 1 = 0;\n\n // ── derived geometry ──────────────────────────────────────────────────────\n private get fraction(): number {\n if (!this.max) return 0;\n return Math.min(1, Math.max(0, this.value / this.max));\n }\n\n private get densityScale(): number {\n if (!this.el) return 0;\n const v = getComputedStyle(this.el).getPropertyValue('--md-sys-density-scale').trim();\n return v ? Number(v) : 0;\n }\n\n private get resolvedSize(): number {\n const density = this.densityScale;\n const s = this.size > 0 ? this.size : (this.wave ? CIRCULAR_SIZE_WAVE : CIRCULAR_SIZE_FLAT) + density * 3;\n return Math.min(CIRCULAR_SIZE_MAX, Math.max(CIRCULAR_SIZE_MIN, s));\n }\n\n private get resolvedWavelength(): number {\n if (this.waveLength > 0) return this.waveLength;\n if (this.variant === 'circular') return CIRCULAR_WAVELENGTH;\n return LINEAR_DET_WAVELENGTH;\n }\n\n private get resolvedAmplitude(): number {\n if (this.waveAmplitude > 0) return this.waveAmplitude;\n if (this.variant === 'circular') return CIRCULAR_AMPLITUDE;\n return LINEAR_AMPLITUDE;\n }\n\n private get resolvedThickness(): number {\n if (this.thickness !== 4) return this.thickness;\n return Math.max(2, 4 + this.densityScale * 0.5);\n }\n\n /** Stroke width of the wave path — density-scaled like everything else. */\n private get resolvedWaveStroke(): number {\n return this.resolvedThickness;\n }\n\n /** Effective thickness for all geometry. */\n private get effectiveThickness(): number {\n return this.resolvedThickness;\n }\n\n private get resolvedWaveSpeed(): number {\n if (this.waveSpeed > 0) return this.waveSpeed;\n return this.resolvedWavelength;\n }\n\n /** Fixed wavy linear container height (2·amp + wave stroke; 10dp at determinate\n * defaults). Uses the (possibly bolder) wave stroke so the mask viewBox and\n * the band height both contain the round caps. */\n private get linearWaveHeight(): number {\n return 2 * this.resolvedAmplitude + this.resolvedWaveStroke;\n }\n\n /**\n * Amplitude *target* (0..1). Indeterminate is always full; determinate\n * flattens to 0 at the endpoints (≤10% / ≥95%). Reduced motion → flat.\n */\n private get amplitudeTarget(): number {\n if (!this.wave || this.reducedMotion) return 0;\n if (this.indeterminate) return 1;\n // Determinate: fully wavy from the first bit of progress all the way through\n // 100 % (and through the closing animation) — NO endpoint flatten. At the\n // very start the fill is shorter than one wavelength, so it naturally reads\n // as a dot, then progresses DIRECTLY to wavy; at 100 % it stays wavy and the\n // \"closing TV\" animation collapses the wave shape rather than a flat line.\n return this.fraction > 0 ? 1 : 0;\n }\n\n // ── lifecycle ─────────────────────────────────────────────────────────────\n componentWillLoad() {\n this.amp = this.amplitudeTarget;\n this.ampTo = this.amp;\n this.renderFraction = this.fraction;\n this.linearRenderFraction = this.fraction;\n this.syncHostStyles();\n if (typeof window !== 'undefined' && window.matchMedia) {\n this.mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n this.reducedMotion = this.mql.matches;\n this.mql.addEventListener?.('change', this.onReducedMotionChange);\n }\n }\n\n componentDidLoad() {\n if (typeof IntersectionObserver !== 'undefined') {\n this.io = new IntersectionObserver((entries) => {\n this.visible = entries.some((e) => e.isIntersecting);\n this.ensureLoop();\n });\n this.io.observe(this.el);\n }\n // Refresh the cached width (and repaint) only on actual resizes — so the\n // per-frame loop never has to call getBoundingClientRect (which would force\n // a synchronous layout every frame).\n if (typeof ResizeObserver !== 'undefined') {\n this.ro = new ResizeObserver(() => {\n this.measureLinearWidth();\n this.updateLinearPath();\n });\n this.ro.observe(this.el);\n }\n this.ensureLoop();\n }\n\n componentDidRender() {\n this.ensureLoop();\n // Refresh the cached layout direction (inherited from ancestors via dir=rtl).\n this.rtl = this.computeRtl();\n // Keep the SVG path in sync when the fill width changes while the phase\n // loop isn't running (e.g. the wave is flat near 0% / ≥95%).\n if (this.wave && this.variant === 'linear' && !this.indeterminate) {\n this.measureLinearWidth(); // once per render, NOT per animation frame\n // Don't overwrite the path while the rAF loop owns it (wlcPhase > 0)\n // or after completion has frozen it (_completing / _completed).\n if (this.wlcPhase === 0 && !this._completing && !this._completed) {\n // If the rAF loop isn't running (amp=0, reduced motion), snap the eased\n // fraction so the path stays at the actual value with no lag.\n if (!this.raf) this.linearRenderFraction = this.fraction;\n this.updateLinearPath();\n }\n }\n // Flat linear determinate: the fill + track are rAF-driven (same as the wavy\n // variant) so they share its motion exactly. Keep them in sync when the loop\n // isn't running (reduced motion, off-screen, settled) by snapping the value.\n if (!this.wave && this.variant === 'linear' && !this.indeterminate) {\n if (this.flcPhase === 0 && !this._completing && !this._completed) {\n if (!this.raf) this.linearRenderFraction = this.fraction;\n this.updateLinearFlat();\n }\n }\n // Flat circular determinate: active arc + track are rAF-driven (mirrors the wavy\n // variant) so they recede in lockstep. Keep them in sync when the loop isn't\n // running (reduced motion, off-screen, settled) by snapping the eased value.\n if (this.variant === 'circular' && !this.wave && !this.indeterminate) {\n if (this.ccPhase === 0 && !this._completing && !this._completed && !this._completedTrack) {\n if (!this.raf) this.renderFraction = this.fraction;\n this.updateCircularFlat();\n }\n }\n }\n\n /** Measure + cache the linear layout width. Called on render and on resize\n * (never inside the rAF loop) so the per-frame path repaint stays layout-free. */\n private measureLinearWidth(): number {\n const w =\n this.linearWaveSvgRef?.getBoundingClientRect().width ||\n this.el.getBoundingClientRect().width ||\n this.el.clientWidth ||\n 0;\n if (w) this.linearWidth = w;\n return this.linearWidth;\n }\n\n private computeRtl(): boolean {\n if (typeof getComputedStyle === 'undefined' || !this.el) return false;\n return getComputedStyle(this.el).direction === 'rtl';\n }\n\n disconnectedCallback() {\n this.stopLoop();\n this.mql?.removeEventListener?.('change', this.onReducedMotionChange);\n this.io?.disconnect();\n this.ro?.disconnect();\n }\n\n private onReducedMotionChange = (e: MediaQueryListEvent) => {\n this.reducedMotion = e.matches;\n };\n\n @Watch('thickness')\n @Watch('size')\n @Watch('wave')\n @Watch('waveAmplitude')\n @Watch('waveLength')\n @Watch('variant')\n onDimensionChange() {\n this.syncHostStyles();\n }\n\n @Watch('value')\n @Watch('max')\n @Watch('indeterminate')\n @Watch('wave')\n @Watch('reducedMotion')\n onAmplitudeInputChange() {\n if (this.ccPhase > 0) return; // a completion sequence owns the geometry\n this.retargetAmplitude();\n // A value change also needs to wake the loop so the wavy circular sweep\n // can ease toward its new target (renderFraction → fraction).\n this.ensureLoop();\n }\n\n @Watch('complete')\n onCompleteChange(next: boolean) {\n if (!next || this.indeterminate || this._completing || this._completed || this._completedTrack || this.ccPhase > 0) return;\n\n // Wave linear: multi-phase rAF sequence (fill → flatten → scaleY collapse).\n // Snap amp to 1 now so the flatten always starts from a fully visible wave.\n if (this.variant === 'linear' && this.wave) {\n this.amp = 1;\n this.ampFrom = 1;\n this.ampTo = 1;\n this.ampStartTs = -2;\n this.wlcPhase = 1;\n this.wlcStart = -1;\n this.wlcFromFrac = this.fraction;\n this.wlcFrac = this.fraction;\n this.ensureLoop();\n return;\n }\n\n // Flat linear: ease the fill to 100% (driven by the SAME linearRenderFraction\n // + ease as the wavy variant, so both fill identically), then collapse.\n if (this.variant === 'linear' && !this.wave) {\n if (this.reducedMotion || typeof requestAnimationFrame === 'undefined') {\n // No rAF available — snap to full, then collapse (transitions are 0s under\n // reduced motion so the fill jumps and the scaleY collapse plays).\n this._fillComplete = true;\n this._completing = true;\n return;\n }\n this.flcPhase = 1;\n this.ensureLoop();\n return;\n }\n\n // Circular (flat + wavy): unified rAF state machine (fill → flatten → erase).\n // Reduced motion has no rAF loop — snap straight to hidden.\n if (this.reducedMotion || typeof requestAnimationFrame === 'undefined') {\n this.handleComplete();\n return;\n }\n // Snap the eased sweep to its target so the determinate fill that just finished\n // is NOT re-driven from a lagging renderFraction (the wavy \"second pass\" where\n // Phase 1 grew the arc ~93% → 100% again), and so the flat hand-off from the\n // dashed <circle> to the completion <path> starts at exactly the shown arc.\n this.renderFraction = this.fraction;\n this.completingFromFrac = this.fraction;\n this.ccFrac = this.completingFromFrac;\n this.ccErase = 0;\n this.ccStart = -1;\n // Wavy closes on the wave shape: hold full amplitude through fill + flatten.\n if (this.wave) {\n this.amp = 1;\n this.ampTo = 1;\n this.ampStartTs = -2;\n this.ampFrom = this.amp;\n }\n // Already at (or essentially at) 100% — there is nothing to fill, so skip the\n // dead Phase-1 hold and go straight to flatten (wavy) / erase (flat).\n if (this.completingFromFrac >= 1 - 1e-3) {\n this.ccFrac = 1;\n this.ccPhase = this.wave ? 2 : 3;\n } else {\n this.ccPhase = 1;\n }\n this.ensureLoop();\n }\n\n private handleComplete() {\n this._completing = false;\n this._fillComplete = false;\n this.ccPhase = 0;\n this.flcPhase = 0;\n // Flat circular rests on its empty track ring instead of self-hiding; every\n // other variant hides via the --complete host rule.\n if (this.variant === 'circular' && !this.wave) {\n this._completedTrack = true;\n } else {\n this._completed = true;\n }\n this.mdComplete.emit();\n }\n\n private onLinearAnimEnd = (e: AnimationEvent) => {\n if (e.animationName === 'md-linear-complete') this.handleComplete();\n };\n\n private syncHostStyles() {\n const s = this.el?.style;\n if (!s) return;\n const t = this.resolvedThickness;\n s.setProperty('--_thickness', `${t}px`);\n s.setProperty('--_linear-height', `${this.wave ? this.linearWaveHeight : t}px`);\n if (this.variant === 'circular' || this.size > 0) {\n s.setProperty('--_size', `${this.resolvedSize}px`);\n } else {\n s.removeProperty('--_size');\n }\n\n if (this.wave && this.variant === 'linear') {\n const wl = this.resolvedWavelength;\n s.setProperty('--_wave-length-px', `${wl}px`);\n s.setProperty('--_wave-mask-size', `${wl}px ${this.linearWaveHeight}px`);\n // duration (ms) for one wavelength of travel at the resolved speed\n const dur = Math.max(50, Math.round((wl / this.resolvedWaveSpeed) * 1000));\n s.setProperty('--_wave-duration', `${dur}ms`);\n this.updateLinearMask();\n } else {\n ['--_wave-length-px', '--_wave-mask', '--_wave-mask-size', '--_wave-duration'].forEach((p) =>\n s.removeProperty(p),\n );\n }\n\n this.syncSpinnerTrackVars(s);\n }\n\n /**\n * Precompute the flat circular-indeterminate \"complement track\" keyframe values\n * as resolved CSS vars. The active arc (md-circular-dash) occupies path-fraction\n * [k, k+L] with k = −dashoffset; the gap-following track is the complement\n * [k+L+g, k+1−g] → dash length T = (1 − L − 2g), arc start offset = (O − L − g).\n *\n * CRITICAL: the dash is emitted as `T (1−T)` — NOT `T 1` — so the dash PERIOD\n * equals the path length (pathLength=1). Only then does a track arc that crosses\n * the 12-o'clock seam wrap correctly (with `T 1` the period is T+1 > 1, so the\n * wrapped portion lands outside [0,1) and is never painted — the track would\n * vanish for most of the cycle). Both `T (1−T)` endpoints sum to 1, so linear\n * keyframe interpolation keeps the period exactly 1 at every intermediate frame,\n * and the complement (T = 1−L−2g, affine in the same eased L,O) holds throughout.\n */\n private syncSpinnerTrackVars(s: CSSStyleDeclaration) {\n if (this.variant !== 'circular') return;\n const r = this.circularRadius;\n const C = 2 * Math.PI * r;\n const g = C > 0 ? (GAP_DP + this.effectiveThickness) / C : 0;\n // Active keyframes (L, O): 0.05/0 → 0.70/−0.18 → 0.05/−0.92\n const emit = (key: string, L: number, O: number) => {\n const T = Math.max(0.0001, Math.min(1, 1 - L - 2 * g));\n s.setProperty(`--_spin-da-${key}`, T.toFixed(4)); // dash length\n s.setProperty(`--_spin-gap-${key}`, (1 - T).toFixed(4)); // gap → period = 1\n s.setProperty(`--_spin-do-${key}`, (O - L - g).toFixed(4)); // arc-start offset\n };\n emit('0', 0.05, 0);\n emit('50', 0.7, -0.18);\n emit('100', 0.05, -0.92);\n }\n\n // ── amplitude animation (rAF tween shared by linear + circular) ───────────\n private retargetAmplitude() {\n if (this.wlcPhase > 0 || this.ccPhase > 0) return; // completion drives amp directly\n const target = this.amplitudeTarget;\n if (target === this.ampTo && this.ampStartTs < 0) return;\n if (target === this.ampTo) return;\n this.ampFrom = this.amp;\n this.ampTo = target;\n this.ampEase = target > this.ampFrom ? EASE_IN : EASE_OUT;\n this.ampStartTs = -1; // (re)start on next frame\n if (this.reducedMotion || typeof requestAnimationFrame === 'undefined') {\n // No animation available — snap.\n this.amp = target;\n this.ampStartTs = -2;\n this.applyAmplitude();\n return;\n }\n this.ensureLoop();\n }\n\n /** Push the current amplitude into the active renderer (mask or path). */\n private applyAmplitude() {\n if (this.variant === 'linear') {\n if (this.wave && !this.indeterminate) this.updateLinearPath();\n else if (!this.wave) this.updateLinearMask();\n // wave + indeterminate: the rAF loop calls updateLinearIndeterminate() each frame\n } else {\n this.updateCircularPath();\n }\n }\n\n // ── the rAF loop ──────────────────────────────────────────────────────────\n private shouldAnimate(): boolean {\n if (typeof requestAnimationFrame === 'undefined') return false;\n if (!this.visible || this.reducedMotion) return false;\n // Circular completion (flat + wavy) runs its own multi-phase rAF sequence.\n if (this.ccPhase > 0) return true;\n // Wave linear completion runs its own multi-phase rAF sequence.\n if (this.wlcPhase > 0) return true;\n // Linear completion is CSS-driven; no rAF needed while completing.\n if (this._completing && this.variant === 'linear') return false;\n // Circular wavy needs a persistent loop for phase travel (amp > 0), an\n // in-flight amplitude tween, an unsettled sweep, or indeterminate motion.\n if (this.variant === 'circular' && this.wave) {\n if (this.indeterminate) return true;\n return (\n this.amp > 0 ||\n this.amp !== this.ampTo ||\n Math.abs(this.renderFraction - this.fraction) > 1e-3\n );\n }\n // Flat circular determinate: loop while the eased sweep hasn't caught up to the\n // value, so the active arc + track repaint in lockstep (mirrors wavy circular).\n // Once it has settled on its terminal track ring, stay put.\n if (this.variant === 'circular' && !this.wave && !this.indeterminate) {\n return !this._completedTrack && Math.abs(this.renderFraction - this.fraction) > 1e-3;\n }\n // Linear wavy determinate: loop while wave is active, tween in-flight, or\n // the fill fraction hasn't caught up yet (keeps the path in sync with value).\n if (this.variant === 'linear' && this.wave && !this.indeterminate) {\n return this.amp > 0 || this.amp !== this.ampTo ||\n Math.abs(this.linearRenderFraction - this.fraction) > 1e-3;\n }\n // Linear wavy indeterminate: always loop (JS draws both bars each frame).\n if (this.variant === 'linear' && this.wave && this.indeterminate) return true;\n // Flat linear determinate: loop while the fill is easing toward the value (so\n // it moves with the SAME smoothness as the wavy variant) or while completing.\n if (this.variant === 'linear' && !this.wave && !this.indeterminate) {\n if (this.flcPhase > 0) return true;\n return Math.abs(this.linearRenderFraction - this.fraction) > 1e-3;\n }\n return false;\n }\n\n private ensureLoop() {\n if (this.shouldAnimate()) {\n if (!this.raf) this.raf = requestAnimationFrame(this.frame);\n } else if (this.amp === this.ampTo) {\n this.stopLoop();\n }\n }\n\n private stopLoop() {\n if (this.raf) cancelAnimationFrame(this.raf);\n this.raf = 0;\n this.lastTs = -1;\n // Re-anchor the indeterminate choreography on the next resume so it\n // restarts at t=0 instead of jumping by the elapsed wall-clock time.\n this.indetStartTs = -1;\n }\n\n private frame = (ts: number) => {\n this.raf = 0;\n if (this.lastTs < 0) this.lastTs = ts;\n const dt = Math.min(64, ts - this.lastTs); // clamp long gaps\n this.lastTs = ts;\n\n // Circular completion (flat + wavy): fill → (wavy) flatten → hold → erase.\n if (this.ccPhase > 0 && this.variant === 'circular') {\n if (this.ccStart < 0) this.ccStart = ts;\n // Keep the wave travelling for visual continuity through fill + flatten.\n if (this.wave) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.phase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.phase > 1e6) this.phase = this.phase % (2 * Math.PI);\n }\n\n if (this.ccPhase === 1) {\n // Fill: arc grows from the current fraction to a full circle (one pass).\n const t = Math.min(1, (ts - this.ccStart) / this.CC_FILL_DUR);\n this.ccFrac = this.completingFromFrac + (1 - this.completingFromFrac) * EASE_STANDARD(t);\n this.paintCircularCompletion();\n if (t >= 1) {\n this.ccFrac = 1;\n this.ccStart = ts;\n if (this.wave) {\n this.ccPhase = 2;\n this.ampFrom = this.amp;\n } else {\n this.ccPhase = 3;\n }\n }\n } else if (this.ccPhase === 2) {\n // Flatten (wavy only): wave amplitude eases to 0 → a plain ring.\n const t = Math.min(1, (ts - this.ccStart) / this.CC_FLATTEN_DUR);\n this.amp = this.ampFrom * (1 - EASE_IN(t));\n this.paintCircularCompletion();\n if (t >= 1) {\n this.amp = 0;\n this.ccPhase = 3;\n this.ccStart = ts;\n }\n } else if (this.ccPhase === 3) {\n // Erase: after a brief hold, remove the ring from the 12 o'clock start\n // outward (clockwise) until nothing remains. The track stays hidden.\n const t = Math.min(1, (ts - this.ccStart - this.CC_WAIT) / this.CC_ERASE_DUR);\n this.ccErase = t <= 0 ? 0 : EASE_STANDARD(t);\n this.paintCircularCompletion();\n if (t >= 1) {\n if (!this.wave) {\n // Flat circular: line is gone — fade the empty track ring IN (Phase 4).\n this.ccPhase = 4;\n this.ccStart = ts;\n } else {\n // Wavy circular self-hides.\n this.handleComplete();\n this.stopLoop();\n return;\n }\n }\n } else {\n // Phase 4 (flat circular only): the line has fully erased; fade the empty\n // track ring in, then settle on it (handleComplete → _completedTrack).\n const t = Math.min(1, (ts - this.ccStart) / this.CC_TRACK_REVEAL_DUR);\n this.circularFlatCompleteRef?.setAttribute('d', ''); // line gone\n if (this.activeCircleRef) this.activeCircleRef.style.opacity = '0';\n if (this.circularFlatTrackRef) {\n const tr = this.circularFlatTrackRef;\n tr.removeAttribute('stroke-dasharray'); // full ring\n tr.removeAttribute('stroke-dashoffset');\n tr.style.opacity = `${EASE_STANDARD(t)}`;\n }\n if (t >= 1) {\n this.handleComplete();\n this.stopLoop();\n return;\n }\n }\n this.raf = requestAnimationFrame(this.frame);\n return;\n }\n\n // Wave linear completion: phase 1 fills the path to 100%, phase 2 flattens amp to 0.\n if (this.wlcPhase > 0) {\n if (this.wlcStart < 0) this.wlcStart = ts;\n // Keep the wave travelling for visual continuity throughout.\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.linearPhase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.linearPhase > 1e6) this.linearPhase = this.linearPhase % (2 * Math.PI);\n\n if (this.wlcPhase === 1) {\n const t = Math.min(1, (ts - this.wlcStart) / this.WLC_FILL_DUR);\n this.wlcFrac = this.wlcFromFrac + (1 - this.wlcFromFrac) * EASE_STANDARD(t);\n this.updateLinearPath();\n if (t >= 1) {\n this.wlcFrac = 1;\n this.wlcPhase = 2;\n this.wlcStart = ts;\n this.ampFrom = 1; // always flatten from full amplitude\n this.ampTo = 0;\n this.ampEase = EASE_IN; // holds the wave shape longer then snaps flat\n this.ampStartTs = ts;\n }\n } else {\n const t = Math.min(1, (ts - this.ampStartTs) / this.WLC_FLATTEN_DUR);\n this.amp = this.ampFrom * (1 - this.ampEase(t));\n this.updateLinearPath();\n if (t >= 1) {\n this.amp = 0;\n this.wlcPhase = 0;\n this._completing = true; // scaleY collapse plays, then onLinearAnimEnd → handleComplete\n this.stopLoop();\n return;\n }\n }\n this.raf = requestAnimationFrame(this.frame);\n return;\n }\n\n // amplitude tween\n if (this.amp !== this.ampTo) {\n if (this.ampStartTs < 0) this.ampStartTs = ts;\n const t = Math.min(1, (ts - this.ampStartTs) / AMP_DURATION);\n this.amp = this.ampFrom + (this.ampTo - this.ampFrom) * this.ampEase(t);\n if (t >= 1) {\n this.amp = this.ampTo;\n this.ampStartTs = -2;\n }\n }\n\n // circular phase travel + eased determinate sweep\n if (this.variant === 'circular' && this.wave) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength; // waves/sec\n this.phase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.phase > 1e6) this.phase = this.phase % (2 * Math.PI);\n // ease the rendered sweep toward the target (~500ms settle)\n const k = 1 - Math.exp(-dt / 160);\n this.renderFraction += (this.fraction - this.renderFraction) * k;\n if (Math.abs(this.fraction - this.renderFraction) < 1e-3) this.renderFraction = this.fraction;\n this.updateCircularPath();\n } else if (this.variant === 'circular' && !this.wave && !this.indeterminate) {\n // Flat circular determinate: ease the sweep toward the value with the SAME\n // ~500ms (160ms time-constant) settle the wavy circular uses, then repaint the\n // active arc + track in lockstep — the track recedes exactly as the arc grows\n // (no early unmount) and its final sliver fades out (no pop).\n const k = 1 - Math.exp(-dt / 160);\n this.renderFraction += (this.fraction - this.renderFraction) * k;\n if (Math.abs(this.fraction - this.renderFraction) < 1e-3) this.renderFraction = this.fraction;\n this.updateCircularFlat();\n } else if (this.variant === 'linear' && this.wave && !this.indeterminate) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.linearPhase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.linearPhase > 1e6) this.linearPhase = this.linearPhase % (2 * Math.PI);\n // Ease the fill toward the target with the same ~80ms time constant as the\n // flat linear's 250ms CSS transition so both variants move in sync.\n if (this.wlcPhase === 0) {\n const k = 1 - Math.exp(-dt / 80);\n this.linearRenderFraction += (this.fraction - this.linearRenderFraction) * k;\n if (Math.abs(this.fraction - this.linearRenderFraction) < 1e-3)\n this.linearRenderFraction = this.fraction;\n }\n this.updateLinearPath();\n } else if (this.variant === 'linear' && this.wave && this.indeterminate) {\n const speedFactor = this.resolvedWaveSpeed / this.resolvedWavelength;\n this.linearPhase += 2 * Math.PI * speedFactor * (dt / 1000);\n if (this.linearPhase > 1e6) this.linearPhase = this.linearPhase % (2 * Math.PI);\n this.updateLinearIndeterminate();\n } else if (this.variant === 'linear' && !this.wave && !this.indeterminate) {\n // Flat linear determinate: ease the fill toward the value (or → 1 while\n // completing) with the SAME 80ms time-constant the wavy variant uses, so the\n // two move in lockstep and the track recedes with identical smoothness.\n const target = this.flcPhase === 1 ? 1 : this.fraction;\n const k = 1 - Math.exp(-dt / 80);\n this.linearRenderFraction += (target - this.linearRenderFraction) * k;\n if (Math.abs(target - this.linearRenderFraction) < 1e-3) {\n this.linearRenderFraction = target;\n if (this.flcPhase === 1) {\n this.flcPhase = 0;\n this.updateLinearFlat();\n this._completing = true; // scaleY collapse → onLinearAnimEnd → handleComplete\n this.stopLoop();\n return;\n }\n }\n this.updateLinearFlat();\n } else {\n this.applyAmplitude();\n }\n\n if (this.shouldAnimate()) {\n this.raf = requestAnimationFrame(this.frame);\n } else {\n this.stopLoop();\n }\n };\n\n // ── linear wave SVG path (determinate) ───────────────────────────────────\n /**\n * Repaint the filled wave path each frame. The path is a closed filled shape\n * (top edge + right round-cap arc + bottom edge + Z) so the wave body and\n * cap are one continuous element — no coordinate-space mismatch possible.\n */\n private updateLinearPath() {\n if (!(this.wave && this.variant === 'linear' && !this.indeterminate)) return;\n if (!this.linearWaveRef) return;\n // Use the cached width (refreshed on render + resize, not per frame) so the\n // hot loop never forces a synchronous layout. Measure lazily if not set yet.\n const W = this.linearWidth || this.measureLinearWidth();\n if (!W) return;\n // During completion wlcFrac drives the fill; otherwise use the eased\n // linearRenderFraction so the wavy path moves in sync with the flat bar.\n const frac = this.wlcPhase > 0 ? this.wlcFrac : this.linearRenderFraction;\n const fillX = frac * W;\n // RTL: progress fills from the right edge, so draw the wave at [W−fillX, W]\n // (the round leading cap then lands at W−fillX, the growing tip). LTR draws\n // at [0, fillX]. Done in JS — in the same coordinate space as the logical-\n // property track/stop — so there is no CSS transform-origin ambiguity.\n let d = '';\n if (fillX > 0) {\n // inset=true → round caps sit inside [edge, fillX] like the flat bar, so the\n // start (x=0 / RTL x=W) and the leading tip aren't sheared square by the clip.\n d = this.rtl\n ? this.buildLinearWaveSVGPath(W - fillX, W, this.amp, this.linearPhase, true)\n : this.buildLinearWaveSVGPath(0, fillX, this.amp, this.linearPhase, true);\n }\n this.linearWaveRef.setAttribute('d', d);\n\n // Lock the track's leading edge to the SAME eased fraction that drew the wave\n // (NOT the instant `fraction`), so the indicator↔track gap stays a constant\n // 4dp while the value animates. The flat variant achieves this by CSS-\n // transitioning the track in lockstep with the bar; the wave path is repainted\n // per-frame in JS, so its track must be driven per-frame from the same source —\n // otherwise the track jumps to the target while the wave edge eases behind it,\n // stretching the gap mid-animation. Logical `% + gap` works in LTR and RTL.\n if (this.linearWaveTrackRef) {\n const pct = +(frac * 100).toFixed(3);\n this.linearWaveTrackRef.style.setProperty(\n '--_track-start',\n pct > 0 ? `calc(${pct}% + var(--_gap))` : '0',\n );\n }\n }\n\n /**\n * Drive the flat linear determinate fill + track from the eased\n * linearRenderFraction (the SAME source + ease the wavy variant uses), so the\n * flat bar advances and its track recedes with identical smoothness and the two\n * variants stay perfectly in sync. Both elements have their CSS transitions\n * removed — this per-frame write is the sole animator. `% + gap` is logical, so\n * it lands correctly in LTR and RTL.\n */\n private updateLinearFlat() {\n if (!(this.variant === 'linear' && !this.wave && !this.indeterminate)) return;\n // Round to 3dp then drop trailing zeros (unary +) so settled integer values\n // read as e.g. \"60%\" (matching the declarative render) rather than \"60.000%\".\n const pct = +(this.linearRenderFraction * 100).toFixed(3);\n this.flatActiveRef?.style.setProperty('--_fill-width', `${pct}%`);\n this.flatTrackRef?.style.setProperty(\n '--_track-start',\n pct >= 100\n ? 'calc(100% + var(--_gap))'\n : pct > 0\n ? `calc(${pct}% + var(--_gap))`\n : '0',\n );\n }\n\n /** Draw two indeterminate wave bars each frame by reading bar-inner positions. */\n private updateLinearIndeterminate() {\n if (!(this.wave && this.variant === 'linear' && this.indeterminate)) return;\n const svgRect = this.linearWaveSvgRef?.getBoundingClientRect();\n const containerRect = svgRect ?? this.el.getBoundingClientRect();\n const W = containerRect.width;\n if (!W) return;\n\n const r = this.effectiveThickness / 2;\n const intervals: Array<[number, number]> = [];\n\n const drawBar = (barRef: HTMLDivElement | null, pathRef: SVGPathElement | null) => {\n if (!barRef || !pathRef) return;\n const br = barRef.getBoundingClientRect();\n const startX = br.left - containerRect.left;\n const endX = br.right - containerRect.left;\n if (endX - startX < 1) { pathRef.setAttribute('d', ''); return; }\n pathRef.setAttribute('d', this.buildLinearWaveSVGPath(startX, endX, this.amp, this.linearPhase));\n // Widen by r so the round caps don't leave a sliver of track showing.\n intervals.push([startX - r, endX + r]);\n };\n drawBar(this.indetBar1Ref, this.indetPath1Ref);\n drawBar(this.indetBar2Ref, this.indetPath2Ref);\n\n // Punch the bar x-ranges out of the track so it's hidden under each bar\n // but stays visible (track colour) everywhere else.\n if (this.indetTrackRef) {\n const mask = this.buildTrackMask(intervals, W);\n this.indetTrackRef.style.setProperty('-webkit-mask-image', mask);\n this.indetTrackRef.style.setProperty('mask-image', mask);\n }\n }\n\n /**\n * Build a horizontal mask gradient: opaque (track visible) outside the given\n * x-intervals, transparent (track hidden) inside them. Intervals are merged so\n * overlapping bars produce valid, monotonically-increasing gradient stops.\n */\n private buildTrackMask(intervalsPx: Array<[number, number]>, W: number): string {\n const pcts = intervalsPx\n .map(([s, e]) => [\n Math.max(0, Math.min(100, (s / W) * 100)),\n Math.max(0, Math.min(100, (e / W) * 100)),\n ] as [number, number])\n .filter(([s, e]) => e > s)\n .sort((a, b) => a[0] - b[0]);\n\n const merged: Array<[number, number]> = [];\n for (const [s, e] of pcts) {\n const last = merged[merged.length - 1];\n if (last && s <= last[1]) last[1] = Math.max(last[1], e);\n else merged.push([s, e]);\n }\n if (!merged.length) return 'none';\n\n const stops: string[] = [];\n let cursor = 0;\n for (const [s, e] of merged) {\n stops.push(\n `#fff ${cursor.toFixed(2)}%`,\n `#fff ${s.toFixed(2)}%`,\n `transparent ${s.toFixed(2)}%`,\n `transparent ${e.toFixed(2)}%`,\n `#fff ${e.toFixed(2)}%`,\n );\n cursor = e;\n }\n stops.push(`#fff ${cursor.toFixed(2)}%`, `#fff 100%`);\n return `linear-gradient(to right, ${stops.join(', ')})`;\n }\n\n /**\n * Closed filled wave path spanning [startX, endX] with a round cap on each end.\n * Loop: left cap (CCW) → bottom edge L→R → right cap (CCW) → top edge R→L → Z.\n *\n * inset=true (determinate): the caps are pulled INWARD so the rounded ends sit\n * inside the fill bounds — the wave body spans [startX+r, endX−r] and each cap\n * bulges out to reach exactly startX / endX, like the flat bar's border-radius.\n * Without this the caps bulge PAST the edges (to startX−r / endX+r), where the\n * container's overflow:hidden and the SVG's own clip shear them into square ends\n * (most visible at 0 % start and ~100 %, where the ends sit at the viewport edge).\n * inset=false (indeterminate): caps bulge outward from [startX, endX]; the moving\n * bars live mid-track and their cap overhang is hidden by the track mask widening.\n */\n private buildLinearWaveSVGPath(\n startX: number,\n endX: number,\n amp: number,\n phase: number,\n inset = false,\n ): string {\n if (endX <= startX) return '';\n const h = this.linearWaveHeight;\n const cy = h / 2;\n const wl = this.resolvedWavelength;\n const r = this.effectiveThickness / 2;\n\n // Cap centres: inset by r (caps reach the true edges) or at the edges (caps\n // bulge beyond). The wave body is sampled between the cap centres.\n const bodyStart = inset ? startX + r : startX;\n const bodyEnd = inset ? endX - r : endX;\n\n // Scale amplitude to zero when the fill body is shorter than one wavelength so\n // small fills emerge as a flat dot/pill rather than a partial sine comma. The wave\n // grows in naturally as the fill lengthens past one wavelength.\n const bodyLen = Math.max(0, bodyEnd - bodyStart);\n const A = amp * this.resolvedAmplitude * Math.min(1, bodyLen / wl);\n\n // Inset fill shorter than one cap-to-cap band (≤ thickness): the two caps would\n // cross, so render a single growing round dot centred in the fill. Progress then\n // emerges as a dot that grows to full thickness, rather than a clipped nub.\n if (inset && bodyEnd <= bodyStart) {\n const cx = (startX + endX) / 2;\n const rr = (endX - startX) / 2;\n return (\n `M ${(cx - rr).toFixed(2)} ${cy.toFixed(2)} ` +\n `a ${rr.toFixed(2)} ${rr.toFixed(2)} 0 1 0 ${(2 * rr).toFixed(2)} 0 ` +\n `a ${rr.toFixed(2)} ${rr.toFixed(2)} 0 1 0 ${(-2 * rr).toFixed(2)} 0 Z`\n );\n }\n\n // Sample ~8 points per wavelength. Catmull-Rom smooths between them, so this\n // reproduces the sine cleanly while building ~2.5× fewer bézier segments per\n // frame than the previous fixed 1-point-per-2px sampling (a hot-loop cost).\n const steps = Math.max(8, Math.round(((bodyEnd - bodyStart) / wl) * WAVE_SAMPLES_PER_WL));\n\n const bot: Array<[number, number]> = [];\n const top: Array<[number, number]> = [];\n for (let i = 0; i <= steps; i++) {\n const x = bodyStart + ((bodyEnd - bodyStart) * i) / steps;\n const wy = cy - A * Math.sin((2 * Math.PI * x) / wl + phase);\n bot.push([x, wy + r]);\n top.unshift([x, wy - r]);\n }\n\n const lw = cy - A * Math.sin((2 * Math.PI * bodyStart) / wl + phase);\n const rw = cy - A * Math.sin((2 * Math.PI * bodyEnd) / wl + phase);\n\n const start = `M ${bodyStart.toFixed(2)} ${(lw - r).toFixed(2)}`;\n const leftCap = `A ${r.toFixed(2)} ${r.toFixed(2)} 0 0 0 ${bodyStart.toFixed(2)} ${(lw + r).toFixed(2)}`;\n const botPath = catmullRom(bot).replace(/^M \\S+ \\S+ /, '');\n const rightCap = `A ${r.toFixed(2)} ${r.toFixed(2)} 0 0 0 ${bodyEnd.toFixed(2)} ${(rw - r).toFixed(2)}`;\n const topPath = catmullRom(top).replace(/^M \\S+ \\S+ /, '');\n\n return `${start} ${leftCap} ${botPath} ${rightCap} ${topPath} Z`;\n }\n\n // ── linear wave mask (data-URL stroked sine, one wavelength tile) ─────────\n private updateLinearMask() {\n if (!(this.wave && this.variant === 'linear')) return;\n const s = this.el?.style;\n if (!s) return;\n s.setProperty('--_wave-mask', this.buildLinearMask(this.amp));\n }\n\n private buildLinearMask(amp: number): string {\n const wl = this.resolvedWavelength;\n const t = this.resolvedWaveStroke;\n const h = this.linearWaveHeight;\n const cy = h / 2;\n const A = amp * this.resolvedAmplitude;\n // Build a CLOSED FILLED band instead of a stroked open path. A stroked path\n // clips its round caps at the SVG tile boundary, creating visible seams where\n // adjacent tiles meet. A filled closed path has no caps and tiles seamlessly.\n // Top edge (x: 0→wl): y = cy − A·sin(2π·x/wl) − t/2\n // Bottom edge (x: wl→0): y = cy − A·sin(2π·x/wl) + t/2\n const steps = Math.max(16, Math.round(wl / 2));\n const top: Array<[number, number]> = [];\n const bot: Array<[number, number]> = [];\n for (let i = 0; i <= steps; i++) {\n const x = (wl * i) / steps;\n const wy = A * Math.sin((2 * Math.PI * x) / wl);\n top.push([x, cy - wy - t / 2]);\n bot.unshift([x, cy - wy + t / 2]);\n }\n const topPath = catmullRom(top);\n // Continue from the top edge endpoint into the bottom edge (L instead of M).\n const botPath = catmullRom(bot).replace(/^M \\S+ \\S+/, `L ${bot[0][0].toFixed(2)} ${bot[0][1].toFixed(2)}`);\n const d = `${topPath} ${botPath} Z`;\n const svg =\n `<svg xmlns='http://www.w3.org/2000/svg' width='${wl}' height='${h}' viewBox='0 0 ${wl} ${h}'>` +\n `<path d='${d}' fill='black'/></svg>`;\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n }\n\n // ── circular geometry ─────────────────────────────────────────────────────\n private get circularRadius(): number {\n // Reserve the wave amplitude so travelling crests stay inside the viewBox\n // (the non-root SVG clips overflow); floor positive so thickness >= size\n // can't produce a degenerate / NaN geometry.\n const base = (this.resolvedSize - this.effectiveThickness) / 2 - (this.wave ? this.resolvedAmplitude : 0);\n return Math.max(0.5, base);\n }\n\n /** Number of waves around the ring — snapped to an integer so it closes. */\n private get circularVertices(): number {\n const r = this.circularRadius;\n const wl = this.resolvedWavelength;\n return Math.max(MIN_CIRCULAR_VERTICES, Math.round((2 * Math.PI * r) / wl));\n }\n\n /** Build a wavy (or, at amp 0, plain) arc centerline path. */\n private wavyArcPath(a0: number, a1: number, amp: number, phase: number): string {\n const cx = this.resolvedSize / 2;\n const cy = this.resolvedSize / 2;\n const r = this.circularRadius;\n const n = this.circularVertices;\n const A = amp * this.resolvedAmplitude;\n const span = a1 - a0;\n const steps = Math.max(8, Math.ceil((Math.abs(span) / (2 * Math.PI)) * n * 8));\n const pts: Array<[number, number]> = [];\n for (let i = 0; i <= steps; i++) {\n const th = a0 + span * (i / steps);\n const rr = r + A * Math.cos(n * th - phase);\n pts.push([cx + rr * Math.cos(th), cy + rr * Math.sin(th)]);\n }\n return catmullRom(pts);\n }\n\n /** Plain circular arc (used for the track). */\n private arcPath(a0: number, a1: number): string {\n const cx = this.resolvedSize / 2;\n const cy = this.resolvedSize / 2;\n const r = this.circularRadius;\n const large = Math.abs(a1 - a0) > Math.PI ? 1 : 0;\n const sweep = a1 > a0 ? 1 : 0;\n const x0 = cx + r * Math.cos(a0);\n const y0 = cy + r * Math.sin(a0);\n const x1 = cx + r * Math.cos(a1);\n const y1 = cy + r * Math.sin(a1);\n return `M ${x0.toFixed(2)} ${y0.toFixed(2)} A ${r} ${r} 0 ${large} ${sweep} ${x1.toFixed(2)} ${y1.toFixed(2)}`;\n }\n\n /**\n * Compute the wavy active + track arc paths for a given sweep fraction.\n * Shared by the declarative render (initial/SSR paint) and the rAF loop so\n * both stay perfectly in sync as the sweep eases and the wave travels.\n */\n private circularPaths(\n frac: number,\n amp: number,\n phase: number,\n indeterminate: boolean,\n sweep?: number,\n ): { active: string; track: string } {\n const start = -Math.PI / 2; // 12 o'clock\n const t = this.effectiveThickness;\n const r = this.circularRadius;\n const a1 = start + (indeterminate ? sweep ?? CIRCULAR_INDET_MIN : frac) * 2 * Math.PI;\n const active = a1 - start < 1e-4 ? '' : this.wavyArcPath(start, a1, amp, phase);\n\n let track: string;\n if (!indeterminate && frac > 0 && frac < 1) {\n // Determinate mid-progress: arc behind the gap after the active end.\n // Use the current animated amplitude (amp · resolvedAmplitude) so the\n // gap scales with the wave as it tweens in/out, matching indeterminate.\n const gapAng = (GAP_DP + t + amp * this.resolvedAmplitude) / r;\n const trackStart = a1 + gapAng;\n const trackEnd = start + 2 * Math.PI - gapAng;\n // If progress is so high that trackEnd ≤ trackStart, the remaining arc\n // fits entirely inside the gap — hide the track rather than showing the\n // full ring (which would sit flush against the active arc with no gap).\n track = trackEnd > trackStart ? this.arcPath(trackStart, trackEnd) : '';\n } else if (!indeterminate) {\n // 0 % or 100 %: full ring track.\n track = this.arcPath(start, start + 2 * Math.PI - 1e-3);\n } else {\n // Indeterminate: track is computed imperatively each frame in\n // updateCircularPath() after the rotation offset is known, so the track\n // stays as the complement of the rotating arc rather than a static ring.\n track = '';\n }\n return { active, track };\n }\n\n /**\n * Paint a frame of the circular completion sequence (flat or wavy), driven by\n * ccFrac (fill) / ccErase (erase). Sets SVG attributes directly so no Stencil\n * re-render is involved. The track is hidden throughout so the erasing ring is\n * the only thing visible and the indicator ends up completely empty.\n */\n private paintCircularCompletion() {\n const start = -Math.PI / 2; // 12 o'clock\n // Fill grows the arc to [0, ccFrac]. Erase removes it FROM THE BEGINNING: the\n // visible arc is [ccErase, 1], so the 12 o'clock start goes invisible first and\n // the disappearance progresses clockwise — \"starts from the beginning to become\n // progressively invisible\". Round caps are kept throughout so the head/tail stay\n // rounded (the \"restart at ~75%\" was a keyless-reconciliation bug, now keyed —\n // it was never the round cap, so no need for a butt cap here).\n const erasing = this.ccPhase === 3;\n const a0frac = erasing ? this.ccErase : 0;\n const a1frac = erasing ? 1 : this.ccFrac;\n const span = a1frac - a0frac;\n\n // Fade the final sliver out smoothly: once the visible arc is shorter than the\n // stroke width its two round caps merge into an unstable dot at the 12 o'clock\n // seam, so ramp opacity to 0 over that last stretch instead of drawing it.\n const C = 2 * Math.PI * this.circularRadius;\n const fadeSpan = C > 0 ? this.effectiveThickness / C : 0.04;\n const endOpacity = !erasing\n ? 1\n : span <= 1e-4\n ? 0\n : span < fadeSpan\n ? Math.max(0, span / fadeSpan)\n : 1;\n\n const a0 = start + a0frac * 2 * Math.PI;\n const a1 = start + a1frac * 2 * Math.PI;\n\n if (this.wave) {\n const active = span < 1e-4 ? '' : this.wavyArcPath(a0, a1, this.amp, this.phase);\n if (this.activeRef) {\n this.activeRef.style.opacity = endOpacity >= 1 ? '' : `${endOpacity}`;\n this.activeRef.setAttribute('d', active);\n }\n this.trackRef?.setAttribute('d', ''); // hide track during completion\n } else {\n // Flat completion is drawn as an explicit arc <path> (exact endpoint geometry,\n // round caps) — the SAME approach as the wavy variant, just with zero amplitude\n // (a plain arc). Drawing it this way means the shrinking head moves smoothly,\n // instead of the jitter an animated stroke-dashoffset on a <circle> produces as\n // the dash boundary is re-rasterized each frame.\n const d = span < 1e-4 ? '' : this.wavyArcPath(a0, a1, 0, this.phase);\n if (this.circularFlatCompleteRef) {\n this.circularFlatCompleteRef.style.opacity = endOpacity >= 1 ? '' : `${endOpacity}`;\n this.circularFlatCompleteRef.setAttribute('d', d);\n }\n // Hide the dashed determinate active circle; the path is the only active part.\n if (this.activeCircleRef) this.activeCircleRef.style.opacity = '0';\n // Track stays hidden through the whole fill + erase — nothing should show\n // alongside the disappearing line. It is faded in AFTERWARDS, once the line is\n // fully gone, by the Phase-4 reveal in the frame loop. (Kept a full ring, ready\n // to reveal.)\n if (this.circularFlatTrackRef) {\n const tr = this.circularFlatTrackRef;\n tr.removeAttribute('stroke-dasharray');\n tr.removeAttribute('stroke-dashoffset');\n tr.style.opacity = '0';\n }\n }\n }\n\n /** Completion arc `d` for the flat variant's path, computed from the current cc\n * state. Used by the initial completion render so the path is never momentarily\n * empty (which would flash) before the rAF loop takes over the imperative paint. */\n private get flatCompletionD(): string {\n if (this.ccPhase === 0) return '';\n const start = -Math.PI / 2;\n const erasing = this.ccPhase === 3;\n const a0frac = erasing ? this.ccErase : 0;\n const a1frac = erasing ? 1 : this.ccFrac;\n if (a1frac - a0frac < 1e-4) return '';\n return this.wavyArcPath(start + a0frac * 2 * Math.PI, start + a1frac * 2 * Math.PI, 0, this.phase);\n }\n\n /** Imperatively repaint the wavy circular arcs (+ rotation) each frame. */\n private updateCircularPath() {\n if (!(this.wave && this.variant === 'circular')) return;\n const sweep = this.indeterminate ? this.indeterminateSweep() : undefined;\n const { active, track } = this.circularPaths(\n this.renderFraction,\n this.amp,\n this.phase,\n this.indeterminate,\n sweep,\n );\n this.activeRef?.setAttribute('d', active);\n\n if (this.indeterminate) {\n const rot = this.indeterminateRotation();\n const cx = this.resolvedSize / 2;\n this.rotRef?.setAttribute('transform', `rotate(${rot.toFixed(2)} ${cx} ${cx})`);\n\n // The active arc lives inside rotRef and rotates with it. The track is\n // outside rotRef and must be positioned as the angular complement of the\n // arc in SCREEN SPACE, so we offset by the current rotation.\n const rotRad = (rot * Math.PI) / 180;\n const r = this.circularRadius;\n const gapAng = (GAP_DP + this.effectiveThickness + this.amp * this.resolvedAmplitude) / r;\n const start = -Math.PI / 2;\n const arcSpan = (sweep ?? CIRCULAR_INDET_MIN) * 2 * Math.PI;\n const arcEndScreen = start + rotRad + arcSpan;\n const arcStartScreen = start + rotRad;\n const trackStart = arcEndScreen + gapAng;\n const trackEnd = arcStartScreen + 2 * Math.PI - gapAng;\n this.trackRef?.setAttribute('d', trackEnd > trackStart\n ? this.arcPath(trackStart, trackEnd)\n : '');\n } else {\n this.trackRef?.setAttribute('d', track);\n }\n }\n\n /**\n * Drive the flat (non-wave) circular determinate active arc + track from the eased\n * renderFraction (the SAME source the wavy variant uses) so both repaint in\n * lockstep: the track recedes exactly as the active arc grows and disappears the\n * instant the arc catches it — no early unmount — and the final sub-stroke sliver\n * fades via opacity rather than popping (round caps paint a dot at zero dash\n * length). The active + track CSS transitions are removed (transition:none) so\n * this per-frame write is the sole animator (mirrors updateLinearFlat).\n */\n private updateCircularFlat() {\n if (!(this.variant === 'circular' && !this.wave && !this.indeterminate)) return;\n if (this.ccPhase > 0 || this._completedTrack) return; // completion / terminal track ring owns the geometry\n const f = this.renderFraction;\n const r = this.circularRadius;\n const C = 2 * Math.PI * r;\n const t = this.effectiveThickness;\n const idealGap = C > 0 ? (GAP_DP + t) / C : 0;\n\n // Active arc spans [0, f] from 12 o'clock; full ring (no dash) at ≥100%.\n const active = this.activeCircleRef;\n if (active) {\n if (f >= 1 - 1e-4) active.removeAttribute('stroke-dasharray');\n else active.setAttribute('stroke-dasharray', `${f.toFixed(4)} 1`);\n }\n\n // Track: full ring at 0%; a gapped arc [f+gap, 1−gap] mid-progress; hidden once\n // the remaining arc no longer fits both 4dp gaps. The last sliver (shorter than\n // the round-cap dot ≈ one stroke width) fades out via opacity so it never pops.\n const tr = this.circularFlatTrackRef;\n if (tr) {\n if (f <= 1e-4) {\n tr.removeAttribute('stroke-dasharray');\n tr.removeAttribute('stroke-dashoffset');\n tr.style.opacity = '';\n } else if (f >= 1 - 1e-4) {\n // Active is a full ring covering everything — keep the track hidden.\n tr.style.opacity = '0';\n } else {\n const trackFrac = 1 - f - 2 * idealGap;\n // Below ≈one stroke width a dashed round-cap arc renders as an unstable dot\n // that drifts/twitches as the dash shrinks and the offset moves each frame\n // (the \"jumpy tail\" near 12 o'clock). So once the sliver reaches that size,\n // FREEZE its geometry — a fixed-length segment pinned at the tail (the end at\n // 1−gap, nearest 12 o'clock) — and fade ONLY its opacity to 0. The frozen\n // segment is continuous with the normal one at the threshold (both occupy\n // [1−gap−fadeSpan, 1−gap] there), so there's no seam when it locks.\n const fadeSpan = C > 0 ? t / C : 0.04;\n if (trackFrac <= 1e-4) {\n tr.style.opacity = '0';\n } else if (trackFrac < fadeSpan) {\n tr.style.opacity = Math.max(0, trackFrac / fadeSpan).toFixed(3);\n tr.setAttribute('stroke-dasharray', `${fadeSpan.toFixed(4)} 1`);\n tr.setAttribute('stroke-dashoffset', `${(-(1 - idealGap - fadeSpan)).toFixed(4)}`);\n } else {\n tr.style.opacity = '';\n tr.setAttribute('stroke-dasharray', `${trackFrac.toFixed(4)} 1`);\n tr.setAttribute('stroke-dashoffset', `${(-(f + idealGap)).toFixed(4)}`);\n }\n }\n }\n }\n\n /** Compose expressive sweep: 0.1 → 0.87 (at 3s) → 0.1 (at 6s). */\n private indeterminateSweep(): number {\n if (this.indetStartTs < 0) this.indetStartTs = this.lastTs;\n const t = ((this.lastTs - this.indetStartTs) % CIRCULAR_INDET_CYCLE) / CIRCULAR_INDET_CYCLE;\n const range = CIRCULAR_INDET_MAX - CIRCULAR_INDET_MIN;\n if (t < 0.5) return CIRCULAR_INDET_MIN + range * EASE_STANDARD(t / 0.5);\n return CIRCULAR_INDET_MAX - range * EASE_STANDARD((t - 0.5) / 0.5);\n }\n\n /**\n * Smooth, monotonic rotation (~1440°/cycle = the 1080° global rotation plus\n * the +360° stepped accumulation), wrapped to [0,360) so it advances forward\n * and never snaps backward at the cycle boundary.\n */\n private indeterminateRotation(): number {\n if (this.indetStartTs < 0) this.indetStartTs = this.lastTs;\n const elapsed = this.lastTs - this.indetStartTs;\n return ((CIRCULAR_GLOBAL_ROTATION + 360) * (elapsed / CIRCULAR_INDET_CYCLE)) % 360;\n }\n\n // ── render helpers ─────────────────────────────────────────────────────────\n /** Sanitized maximum — always a finite, positive number for valid ARIA. */\n private get ariaValueMax(): number {\n return Number.isFinite(this.max) && this.max > 0 ? this.max : 0;\n }\n\n private get ariaValueNow(): number | undefined {\n // M3 / Material Web report the raw value (not a 0–100 percentage); clamp\n // into [0, max] so the announced value stays a valid ARIA range value.\n if (this.indeterminate) return undefined;\n const n = Math.min(this.ariaValueMax, Math.max(0, this.value));\n return Number.isFinite(n) ? n : 0;\n }\n\n private renderLinear() {\n return this.indeterminate ? this.renderLinearIndeterminate() : this.renderLinearDeterminate();\n }\n\n private renderLinearDeterminate() {\n // fillPct drives --_fill-width: jumps to 100 immediately so the CSS transition\n // animates the bar to full. pct controls track/stop visibility: always uses\n // the real fraction so the track and stop dot stay in place while the bar\n // travels — the scaleY collapse hides everything together.\n const fillPct = (this._fillComplete || this._completing) ? 100 : this.fraction * 100;\n const pct = this.fraction * 100;\n const hasProgress = fillPct > 0;\n\n if (this.wave) {\n // Wave mode: a single SVG filled path covers both the wave body and the\n // round cap — both live in the same coordinate space so there is no\n // pixel-rounding mismatch between the body edge and the cap circle.\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\" onAnimationEnd={this.onLinearAnimEnd}>\n {pct < 100 && (\n <div\n class=\"md-progress-indicator__track\"\n part=\"track\"\n ref={(el) => { this.linearWaveTrackRef = el as HTMLDivElement; }}\n style={{\n // Same formula as the flat linear — gap from the nominal fill edge.\n // Adding thickness/2 on top made the visual gap feel larger than\n // the flat's 4dp because the eye reads the wave end as the last\n // full-height section, not the tapered cap tip.\n // This declarative value is the steady-state / SSR position; while\n // the value animates, updateLinearPath() overrides it per-frame from\n // the eased fraction so the track tracks the wave's leading edge and\n // the gap stays a constant 4dp (see updateLinearPath).\n '--_track-start': hasProgress\n ? `calc(${pct}% + var(--_gap))`\n : '0',\n }}\n />\n )}\n <div class=\"md-progress-indicator__stop\" part=\"stop-indicator\" />\n {/* Always rendered; the path is empty at 0 % and grows with the fill,\n so it emerges from the leading edge rather than popping in as a dot. */}\n <svg\n class=\"md-progress-indicator__linear-wave-svg\"\n width=\"100%\"\n aria-hidden=\"true\"\n ref={(el) => { this.linearWaveSvgRef = el as SVGSVGElement; }}\n >\n <path\n class=\"md-progress-indicator__linear-wave-path\"\n part=\"active-indicator\"\n ref={(el) => { this.linearWaveRef = el as SVGPathElement; }}\n />\n </svg>\n </div>\n );\n }\n\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\" onAnimationEnd={this.onLinearAnimEnd}>\n {/* Always rendered (even at 0 %): the fill grows out of the leading edge\n rather than popping in as a dot. The width is rAF-driven per-frame by\n updateLinearFlat() (shared ease with the wavy variant); these declarative\n values are the steady-state / SSR fallback. */}\n <div\n class=\"md-progress-indicator__active\"\n part=\"active-indicator\"\n ref={(el) => { this.flatActiveRef = el as HTMLDivElement; }}\n style={{ '--_fill-width': `${fillPct}%` }}\n />\n\n {/* Always rendered: as the bar grows, --_track-start follows it (+gap) so\n the track recedes in lockstep and slides off at 100%. updateLinearFlat()\n drives both per-frame from the same eased fraction as the bar, so the\n 4dp gap stays constant and the flat variant moves identically to wavy. */}\n <div\n class=\"md-progress-indicator__track md-progress-indicator__track--determinate\"\n part=\"track\"\n ref={(el) => { this.flatTrackRef = el as HTMLDivElement; }}\n style={{\n // No min() here: a min()/max() inside the calc makes the browser fall\n // back to DISCRETE interpolation of inset-inline-start, so the track\n // jumps each value update (jitter). A plain `% + px` stays in lockstep\n // with the active fill. (Steady-state / SSR fallback; the rAF loop\n // overrides this per-frame while the value animates.)\n '--_track-start': fillPct >= 100\n ? 'calc(100% + var(--_gap))'\n : hasProgress\n ? `calc(${pct}% + var(--_gap))`\n : '0',\n }}\n />\n\n <div class=\"md-progress-indicator__stop\" part=\"stop-indicator\" />\n </div>\n );\n }\n\n private renderLinearIndeterminate() {\n if (this.wave && !this.reducedMotion) {\n // Wave indeterminate: JS draws both bars as filled SVG paths each rAF frame.\n // Ghost bar divs drive the CSS position/scale animations so we can read their\n // bounding rects; the SVG overlay renders the actual wavy shapes with round caps.\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\">\n {/* Track is visible in the gaps; updateLinearIndeterminate() masks out\n the x-range under each bar every frame so the clean wave floats over\n a hidden segment instead of overlapping a straight track line. */}\n <div\n class=\"md-progress-indicator__track md-progress-indicator__track--full\"\n part=\"track\"\n ref={(el) => { this.indetTrackRef = el as HTMLDivElement; }}\n />\n <div class=\"md-progress-indicator__bar md-progress-indicator__bar--primary\">\n <div\n class=\"md-progress-indicator__bar-inner md-progress-indicator__bar-inner--ghost\"\n ref={(el) => { this.indetBar1Ref = el as HTMLDivElement; }}\n />\n </div>\n <div class=\"md-progress-indicator__bar md-progress-indicator__bar--secondary\">\n <div\n class=\"md-progress-indicator__bar-inner md-progress-indicator__bar-inner--ghost\"\n ref={(el) => { this.indetBar2Ref = el as HTMLDivElement; }}\n />\n </div>\n <svg\n class=\"md-progress-indicator__linear-wave-svg\"\n width=\"100%\"\n aria-hidden=\"true\"\n ref={(el) => { this.linearWaveSvgRef = el as SVGSVGElement; }}\n >\n <path\n class=\"md-progress-indicator__linear-wave-path\"\n ref={(el) => { this.indetPath1Ref = el as SVGPathElement; }}\n />\n <path\n class=\"md-progress-indicator__linear-wave-path\"\n ref={(el) => { this.indetPath2Ref = el as SVGPathElement; }}\n />\n </svg>\n </div>\n );\n }\n\n // Flat or reduced-motion indeterminate: standard CSS two-bar motion.\n const barClass = (modifier: string) => ({\n 'md-progress-indicator__bar': true,\n [`md-progress-indicator__bar--${modifier}`]: true,\n 'md-progress-indicator__bar--wave': this.wave,\n });\n return (\n <div class=\"md-progress-indicator__linear\" aria-hidden=\"true\">\n <div class=\"md-progress-indicator__track md-progress-indicator__track--full\" part=\"track\" />\n <div class={barClass('primary')} part=\"active-indicator\">\n <div class=\"md-progress-indicator__bar-inner\" />\n </div>\n <div class={barClass('secondary')}>\n <div class=\"md-progress-indicator__bar-inner\" />\n </div>\n </div>\n );\n }\n\n private renderCircular() {\n return this.wave ? this.renderCircularWave() : this.renderCircularFlat();\n }\n\n private renderCircularFlat() {\n const sz = this.resolvedSize;\n const t = this.effectiveThickness;\n const r = this.circularRadius;\n const center = sz / 2;\n const f = this.fraction;\n const C = 2 * Math.PI * r;\n const idealGap = C > 0 ? (GAP_DP + t) / C : 0;\n const showGap = f > 0 && f < 1;\n // Track = the leftover arc after a constant idealGap is removed at each end:\n // trackFrac = remaining − 2·gap. Constant gap → the active end (f) and the track\n // start (f + gap) move in perfect lockstep, so the 4dp gap never stretches. These\n // are the steady-state / SSR values; while the value animates updateCircularFlat()\n // overrides the dash/offset/opacity per-frame from the eased renderFraction, in\n // lockstep with the active arc (so the track recedes exactly as the arc grows and\n // its final sliver fades out instead of popping — see updateCircularFlat()).\n const trackFrac = showGap ? Math.max(0, 1 - f - 2 * idealGap) : 0;\n const trackVisible = showGap && trackFrac > 0;\n\n return (\n <svg class=\"md-progress-indicator__circular\" viewBox={`0 0 ${sz} ${sz}`} aria-hidden=\"true\">\n {/* Stable key=\"circ-track\" pins element identity so Stencil never repurposes\n the track as the active circle (which would restart the active's dash and\n read as the fill \"starting again\").\n - Indeterminate: a complement arc that follows the spinning active arc,\n animated purely in CSS via md-circular-dash-track.\n - Determinate: a SINGLE always-mounted arc driven per-frame by\n updateCircularFlat() (full ring at 0 %, a gapped arc mid-progress, faded\n out near ≥86 % / 100 %). It stays mounted across the whole range so the\n rAF loop fades it smoothly — rather than the DOM yanking it to null,\n which cut the CSS transition mid-flight and popped (the bug this fixes). */}\n {this.indeterminate ? (\n <circle\n key=\"circ-track\"\n class=\"md-progress-indicator__circular-track md-progress-indicator__circular-track--spinner\"\n part=\"track\"\n cx={center}\n cy={center}\n r={r}\n stroke-width={t}\n fill=\"none\"\n pathLength={1}\n stroke-linecap=\"round\"\n transform={`rotate(-90 ${center} ${center})`}\n ref={(el) => { this.circularFlatTrackRef = el as SVGCircleElement; }}\n />\n ) : (\n <circle\n key=\"circ-track\"\n class=\"md-progress-indicator__circular-track md-progress-indicator__circular-track--determinate\"\n part=\"track\"\n cx={center}\n cy={center}\n r={r}\n stroke-width={t}\n fill=\"none\"\n pathLength={1}\n stroke-linecap=\"round\"\n transform={`rotate(-90 ${center} ${center})`}\n stroke-dasharray={this._completedTrack ? undefined : trackVisible ? `${trackFrac} 1` : undefined}\n stroke-dashoffset={this._completedTrack ? undefined : trackVisible ? -(f + idealGap) : undefined}\n style={\n // _completedTrack: rest on a full, visible track ring (the terminal\n // state). Otherwise hide it while completing / when it no longer fits.\n this._completedTrack\n ? undefined\n : this.ccPhase > 0 || (showGap && trackFrac <= 0)\n ? { opacity: '0' }\n : undefined\n }\n ref={(el) => { this.circularFlatTrackRef = el as SVGCircleElement; }}\n />\n )}\n <circle\n key=\"circ-active\"\n class=\"md-progress-indicator__circular-active\"\n part=\"active-indicator\"\n cx={center}\n cy={center}\n r={r}\n stroke-width={t}\n fill=\"none\"\n pathLength={1}\n stroke-linecap=\"round\"\n stroke-dasharray={this.indeterminate || f >= 1 ? undefined : `${f} ${1}`}\n // During completion the dashed circle is hidden and the completion <path>\n // below draws the arc instead (so the head doesn't jitter). _completed hides\n // it before visibility:hidden lands; _completedTrack hides it for good (the\n // flat circular terminal state shows only the empty track ring).\n style={this.ccPhase > 0 || this._completed || this._completedTrack ? { opacity: '0' } : undefined}\n transform={`rotate(-90 ${center} ${center})`}\n ref={(el) => { this.activeCircleRef = el as SVGCircleElement; }}\n />\n {/* Completion-only arc, drawn as an explicit round-capped <path> (empty\n outside the completion sequence). Painted imperatively by\n paintCircularCompletion(); flatCompletionD seeds the first frame so the\n path is never momentarily empty (no flash) before the rAF loop runs. */}\n <path\n class=\"md-progress-indicator__circular-active-path\"\n stroke-width={t}\n fill=\"none\"\n stroke-linecap=\"round\"\n d={this.flatCompletionD}\n ref={(el) => { this.circularFlatCompleteRef = el as SVGPathElement; }}\n />\n </svg>\n );\n }\n\n private renderCircularWave() {\n const sz = this.resolvedSize;\n const t = this.effectiveThickness;\n // Initial (SSR / pre-rAF) paths from the eased fraction; the rAF loop then\n // repaints both arcs in lockstep.\n const { active, track } = this.circularPaths(\n this.renderFraction,\n this.amp,\n this.phase,\n this.indeterminate,\n this.indeterminate ? CIRCULAR_INDET_MIN : undefined,\n );\n\n return (\n <svg class=\"md-progress-indicator__circular\" viewBox={`0 0 ${sz} ${sz}`} aria-hidden=\"true\">\n <path\n class=\"md-progress-indicator__circular-track\"\n part=\"track\"\n d={this.ccPhase > 0 ? '' : track}\n stroke-width={t}\n fill=\"none\"\n stroke-linecap=\"round\"\n ref={(e) => (this.trackRef = e as SVGPathElement)}\n />\n <g ref={(e) => (this.rotRef = e as SVGGElement)}>\n <path\n class=\"md-progress-indicator__circular-active\"\n part=\"active-indicator\"\n d={active}\n stroke-width={t}\n fill=\"none\"\n stroke-linecap=\"round\"\n ref={(e) => (this.activeRef = e as SVGPathElement)}\n />\n </g>\n </svg>\n );\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-progress-indicator': true,\n [`md-progress-indicator--${this.variant}`]: true,\n 'md-progress-indicator--indeterminate': this.indeterminate,\n 'md-progress-indicator--wave': this.wave,\n 'md-progress-indicator--four-color': this.fourColor,\n 'md-progress-indicator--completing': this._completing,\n 'md-progress-indicator--complete': this._completed,\n }}\n role=\"progressbar\"\n aria-label={this.label || undefined}\n aria-valuemin={0}\n aria-valuemax={this.ariaValueMax}\n aria-valuenow={this.ariaValueNow}\n >\n {this.variant === 'circular' ? this.renderCircular() : this.renderLinear()}\n </Host>\n );\n }\n}\n\n/* ── Catmull-Rom → cubic-bézier smoothing for the wavy ring path ───────────*/\nfunction catmullRom(pts: Array<[number, number]>): string {\n if (pts.length < 2) return '';\n const d: string[] = [`M ${pts[0][0].toFixed(2)} ${pts[0][1].toFixed(2)}`];\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[i - 1] || pts[i];\n const p1 = pts[i];\n const p2 = pts[i + 1];\n const p3 = pts[i + 2] || p2;\n const c1x = p1[0] + (p2[0] - p0[0]) / 6;\n const c1y = p1[1] + (p2[1] - p0[1]) / 6;\n const c2x = p2[0] - (p3[0] - p1[0]) / 6;\n const c2y = p2[1] - (p3[1] - p1[1]) / 6;\n d.push(\n `C ${c1x.toFixed(2)} ${c1y.toFixed(2)} ${c2x.toFixed(2)} ${c2y.toFixed(2)} ${p2[0].toFixed(2)} ${p2[1].toFixed(2)}`,\n );\n }\n return d.join(' ');\n}\n"],"mappings":"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","ignoreList":[]}