{"version":3,"file":"useSmoothStreamContent.mjs","names":[],"sources":["../../../src/Markdown/SyntaxMarkdown/useSmoothStreamContent.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useStreamdownProfiler } from '@/Markdown/streamProfiler';\nimport { type StreamSmoothingPreset } from '@/Markdown/type';\n\ninterface StreamSmoothingPresetConfig {\n  activeInputWindowMs: number;\n  defaultCps: number;\n  emaAlpha: number;\n  flushCps: number;\n  largeAppendChars: number;\n  maxActiveCps: number;\n  maxCps: number;\n  maxFlushCps: number;\n  minCps: number;\n  settleAfterMs: number;\n  settleDrainMaxMs: number;\n  settleDrainMinMs: number;\n  targetBufferMs: number;\n}\n\nconst PRESET_CONFIG: Record<StreamSmoothingPreset, StreamSmoothingPresetConfig> = {\n  balanced: {\n    activeInputWindowMs: 220,\n    defaultCps: 38,\n    emaAlpha: 0.2,\n    flushCps: 120,\n    largeAppendChars: 120,\n    maxActiveCps: 132,\n    maxCps: 72,\n    maxFlushCps: 280,\n    minCps: 18,\n    settleAfterMs: 360,\n    settleDrainMaxMs: 520,\n    settleDrainMinMs: 180,\n    targetBufferMs: 120,\n  },\n  realtime: {\n    activeInputWindowMs: 140,\n    defaultCps: 50,\n    emaAlpha: 0.3,\n    flushCps: 170,\n    largeAppendChars: 180,\n    maxActiveCps: 180,\n    maxCps: 96,\n    maxFlushCps: 360,\n    minCps: 24,\n    settleAfterMs: 260,\n    settleDrainMaxMs: 360,\n    settleDrainMinMs: 140,\n    targetBufferMs: 40,\n  },\n  silky: {\n    activeInputWindowMs: 320,\n    defaultCps: 28,\n    emaAlpha: 0.14,\n    flushCps: 96,\n    largeAppendChars: 100,\n    maxActiveCps: 102,\n    maxCps: 56,\n    maxFlushCps: 220,\n    minCps: 14,\n    settleAfterMs: 460,\n    settleDrainMaxMs: 680,\n    settleDrainMinMs: 240,\n    targetBufferMs: 170,\n  },\n};\n\nconst clamp = (value: number, min: number, max: number): number => {\n  return Math.min(max, Math.max(min, value));\n};\n\nconst getNow = () => {\n  return typeof performance === 'undefined' ? Date.now() : performance.now();\n};\n\nexport const countChars = (text: string): number => {\n  return [...text].length;\n};\n\ninterface UseSmoothStreamContentOptions {\n  enabled?: boolean;\n  preset?: StreamSmoothingPreset;\n}\n\nexport const useSmoothStreamContent = (\n  content: string,\n  { enabled = true, preset = 'balanced' }: UseSmoothStreamContentOptions = {},\n): string => {\n  const config = PRESET_CONFIG[preset];\n  const profiler = useStreamdownProfiler();\n  const [displayedContent, setDisplayedContent] = useState(content);\n\n  const displayedContentRef = useRef(content);\n  const displayedCountRef = useRef(countChars(content));\n\n  const targetContentRef = useRef(content);\n  const targetCharsRef = useRef([...content]);\n  const targetCountRef = useRef(targetCharsRef.current.length);\n\n  const emaCpsRef = useRef(config.defaultCps);\n  const lastInputTsRef = useRef(0);\n  const lastInputCountRef = useRef(targetCountRef.current);\n  const chunkSizeEmaRef = useRef(1);\n  const arrivalCpsEmaRef = useRef(config.defaultCps);\n\n  const rafRef = useRef<number | null>(null);\n  const lastFrameTsRef = useRef<number | null>(null);\n  const wakeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  const clearWakeTimer = useCallback(() => {\n    if (wakeTimerRef.current !== null) {\n      clearTimeout(wakeTimerRef.current);\n      wakeTimerRef.current = null;\n    }\n  }, []);\n\n  const stopFrameLoop = useCallback(() => {\n    if (rafRef.current !== null) {\n      cancelAnimationFrame(rafRef.current);\n      rafRef.current = null;\n    }\n    lastFrameTsRef.current = null;\n  }, []);\n\n  const stopScheduling = useCallback(() => {\n    stopFrameLoop();\n    clearWakeTimer();\n  }, [clearWakeTimer, stopFrameLoop]);\n\n  const startFrameLoopRef = useRef<() => void>(() => {});\n\n  const scheduleFrameWake = useCallback(\n    (delayMs: number) => {\n      clearWakeTimer();\n\n      wakeTimerRef.current = setTimeout(\n        () => {\n          wakeTimerRef.current = null;\n          startFrameLoopRef.current();\n        },\n        Math.max(1, Math.ceil(delayMs)),\n      );\n    },\n    [clearWakeTimer],\n  );\n\n  const syncImmediate = useCallback(\n    (nextContent: string) => {\n      stopScheduling();\n\n      const chars = [...nextContent];\n      const now = getNow();\n\n      targetContentRef.current = nextContent;\n      targetCharsRef.current = chars;\n      targetCountRef.current = chars.length;\n\n      displayedContentRef.current = nextContent;\n      displayedCountRef.current = chars.length;\n      setDisplayedContent(nextContent);\n\n      emaCpsRef.current = config.defaultCps;\n      chunkSizeEmaRef.current = 1;\n      arrivalCpsEmaRef.current = config.defaultCps;\n      lastInputTsRef.current = now;\n      lastInputCountRef.current = chars.length;\n    },\n    [config.defaultCps, stopScheduling],\n  );\n\n  const startFrameLoop = useCallback(() => {\n    clearWakeTimer();\n    if (rafRef.current !== null) return;\n\n    const tick = (ts: number) => {\n      const frameStart = getNow();\n\n      if (lastFrameTsRef.current === null) {\n        lastFrameTsRef.current = ts;\n        rafRef.current = requestAnimationFrame(tick);\n        return;\n      }\n\n      const frameIntervalMs = Math.max(0, ts - lastFrameTsRef.current);\n      const dtSeconds = Math.max(0.001, Math.min(frameIntervalMs / 1000, 0.05));\n      lastFrameTsRef.current = ts;\n\n      const targetCount = targetCountRef.current;\n      const displayedCount = displayedCountRef.current;\n      const backlog = targetCount - displayedCount;\n\n      if (backlog <= 0) {\n        stopFrameLoop();\n        return;\n      }\n\n      const now = getNow();\n      const idleMs = now - lastInputTsRef.current;\n      const inputActive = idleMs <= config.activeInputWindowMs;\n      const settling = !inputActive && idleMs >= config.settleAfterMs;\n\n      const baseCps = clamp(emaCpsRef.current, config.minCps, config.maxCps);\n      const baseLagChars = Math.max(1, Math.round((baseCps * config.targetBufferMs) / 1000));\n      const lagUpperBound = Math.max(baseLagChars + 2, baseLagChars * 3);\n      const targetLagChars = inputActive\n        ? Math.round(\n            clamp(baseLagChars + chunkSizeEmaRef.current * 0.35, baseLagChars, lagUpperBound),\n          )\n        : 0;\n      const desiredDisplayed = Math.max(0, targetCount - targetLagChars);\n\n      let currentCps: number;\n      if (inputActive) {\n        const backlogPressure = targetLagChars > 0 ? backlog / targetLagChars : 1;\n        const chunkPressure = targetLagChars > 0 ? chunkSizeEmaRef.current / targetLagChars : 1;\n        const arrivalPressure = arrivalCpsEmaRef.current / Math.max(baseCps, 1);\n        const combinedPressure = clamp(\n          backlogPressure * 0.6 + chunkPressure * 0.25 + arrivalPressure * 0.15,\n          1,\n          4.5,\n        );\n        const activeCap = clamp(\n          config.maxActiveCps + chunkSizeEmaRef.current * 6,\n          config.maxActiveCps,\n          config.maxFlushCps,\n        );\n        currentCps = clamp(baseCps * combinedPressure, config.minCps, activeCap);\n      } else if (settling) {\n        // If upstream likely ended, cap the remaining tail duration so\n        // we do not keep replaying old backlog for seconds.\n        const drainTargetMs = clamp(backlog * 8, config.settleDrainMinMs, config.settleDrainMaxMs);\n        const settleCps = (backlog * 1000) / drainTargetMs;\n        currentCps = clamp(settleCps, config.flushCps, config.maxFlushCps);\n      } else {\n        const idleFlushCps = Math.max(\n          config.flushCps,\n          baseCps * 1.8,\n          arrivalCpsEmaRef.current * 0.8,\n        );\n        currentCps = clamp(idleFlushCps, config.flushCps, config.maxFlushCps);\n      }\n\n      const urgentBacklog = inputActive && targetLagChars > 0 && backlog > targetLagChars * 2.2;\n      const burstyInput = inputActive && chunkSizeEmaRef.current >= targetLagChars * 0.9;\n      const minRevealChars = inputActive ? (urgentBacklog || burstyInput ? 2 : 1) : 2;\n      let revealChars = Math.max(minRevealChars, Math.round(currentCps * dtSeconds));\n\n      if (inputActive) {\n        const shortfall = desiredDisplayed - displayedCount;\n        if (shortfall <= 0) {\n          stopFrameLoop();\n          scheduleFrameWake(config.activeInputWindowMs - idleMs);\n\n          profiler?.recordAnimationFrame({\n            backlog,\n            durationMs: getNow() - frameStart,\n            frameIntervalMs,\n            inputActive,\n            revealChars: 0,\n            settling,\n          });\n          return;\n        }\n        revealChars = Math.min(revealChars, shortfall, backlog);\n      } else {\n        revealChars = Math.min(revealChars, backlog);\n      }\n\n      const nextCount = displayedCount + revealChars;\n      const segment = targetCharsRef.current.slice(displayedCount, nextCount).join('');\n\n      if (segment) {\n        const nextDisplayed = displayedContentRef.current + segment;\n        displayedContentRef.current = nextDisplayed;\n        displayedCountRef.current = nextCount;\n        setDisplayedContent(nextDisplayed);\n      } else {\n        displayedContentRef.current = targetContentRef.current;\n        displayedCountRef.current = targetCount;\n        setDisplayedContent(targetContentRef.current);\n      }\n\n      profiler?.recordAnimationFrame({\n        backlog,\n        durationMs: getNow() - frameStart,\n        frameIntervalMs,\n        inputActive,\n        revealChars: segment ? revealChars : backlog,\n        settling,\n      });\n\n      rafRef.current = requestAnimationFrame(tick);\n    };\n\n    rafRef.current = requestAnimationFrame(tick);\n  }, [\n    clearWakeTimer,\n    config.activeInputWindowMs,\n    config.flushCps,\n    config.maxActiveCps,\n    config.maxCps,\n    config.maxFlushCps,\n    config.minCps,\n    config.settleAfterMs,\n    config.settleDrainMaxMs,\n    config.settleDrainMinMs,\n    config.targetBufferMs,\n    scheduleFrameWake,\n    stopFrameLoop,\n  ]);\n  startFrameLoopRef.current = startFrameLoop;\n\n  useEffect(() => {\n    if (!enabled) {\n      syncImmediate(content);\n      return;\n    }\n\n    const prevTargetContent = targetContentRef.current;\n    if (content === prevTargetContent) return;\n\n    const now = getNow();\n    const appendOnly = content.startsWith(prevTargetContent);\n\n    if (!appendOnly) {\n      syncImmediate(content);\n      return;\n    }\n\n    const appended = content.slice(prevTargetContent.length);\n    const appendedChars = [...appended];\n    const appendedCount = appendedChars.length;\n\n    profiler?.recordInputAppend({\n      appendedChars: appendedCount,\n      contentLength: countChars(content),\n    });\n\n    if (appendedCount > config.largeAppendChars) {\n      syncImmediate(content);\n      return;\n    }\n\n    targetContentRef.current = content;\n    targetCharsRef.current = [...targetCharsRef.current, ...appendedChars];\n    targetCountRef.current += appendedCount;\n\n    const deltaChars = targetCountRef.current - lastInputCountRef.current;\n    const deltaMs = Math.max(1, now - lastInputTsRef.current);\n\n    if (deltaChars > 0) {\n      const instantCps = (deltaChars * 1000) / deltaMs;\n      const normalizedInstantCps = clamp(instantCps, config.minCps, config.maxFlushCps * 2);\n      const chunkEmaAlpha = 0.35;\n      chunkSizeEmaRef.current =\n        chunkSizeEmaRef.current * (1 - chunkEmaAlpha) + appendedCount * chunkEmaAlpha;\n      arrivalCpsEmaRef.current =\n        arrivalCpsEmaRef.current * (1 - chunkEmaAlpha) + normalizedInstantCps * chunkEmaAlpha;\n\n      const clampedCps = clamp(instantCps, config.minCps, config.maxActiveCps);\n      emaCpsRef.current = emaCpsRef.current * (1 - config.emaAlpha) + clampedCps * config.emaAlpha;\n    }\n\n    lastInputTsRef.current = now;\n    lastInputCountRef.current = targetCountRef.current;\n\n    startFrameLoop();\n  }, [\n    config.emaAlpha,\n    config.largeAppendChars,\n    config.maxActiveCps,\n    config.maxCps,\n    config.maxFlushCps,\n    config.minCps,\n    content,\n    enabled,\n    startFrameLoop,\n    syncImmediate,\n    profiler,\n  ]);\n\n  useEffect(() => {\n    return () => {\n      stopScheduling();\n    };\n  }, [stopScheduling]);\n\n  return displayedContent;\n};\n"],"mappings":";;;AAqBA,MAAM,gBAA4E;CAChF,UAAU;EACR,qBAAqB;EACrB,YAAY;EACZ,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,cAAc;EACd,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,gBAAgB;EACjB;CACD,UAAU;EACR,qBAAqB;EACrB,YAAY;EACZ,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,cAAc;EACd,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,gBAAgB;EACjB;CACD,OAAO;EACL,qBAAqB;EACrB,YAAY;EACZ,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,cAAc;EACd,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,gBAAgB;EACjB;CACF;AAED,MAAM,SAAS,OAAe,KAAa,QAAwB;AACjE,QAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,MAAM,CAAC;;AAG5C,MAAM,eAAe;AACnB,QAAO,OAAO,gBAAgB,cAAc,KAAK,KAAK,GAAG,YAAY,KAAK;;AAG5E,MAAa,cAAc,SAAyB;AAClD,QAAO,CAAC,GAAG,KAAK,CAAC;;AAQnB,MAAa,0BACX,SACA,EAAE,UAAU,MAAM,SAAS,eAA8C,EAAE,KAChE;CACX,MAAM,SAAS,cAAc;CAC7B,MAAM,WAAW,uBAAuB;CACxC,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,QAAQ;CAEjE,MAAM,sBAAsB,OAAO,QAAQ;CAC3C,MAAM,oBAAoB,OAAO,WAAW,QAAQ,CAAC;CAErD,MAAM,mBAAmB,OAAO,QAAQ;CACxC,MAAM,iBAAiB,OAAO,CAAC,GAAG,QAAQ,CAAC;CAC3C,MAAM,iBAAiB,OAAO,eAAe,QAAQ,OAAO;CAE5D,MAAM,YAAY,OAAO,OAAO,WAAW;CAC3C,MAAM,iBAAiB,OAAO,EAAE;CAChC,MAAM,oBAAoB,OAAO,eAAe,QAAQ;CACxD,MAAM,kBAAkB,OAAO,EAAE;CACjC,MAAM,mBAAmB,OAAO,OAAO,WAAW;CAElD,MAAM,SAAS,OAAsB,KAAK;CAC1C,MAAM,iBAAiB,OAAsB,KAAK;CAClD,MAAM,eAAe,OAA6C,KAAK;CAEvE,MAAM,iBAAiB,kBAAkB;AACvC,MAAI,aAAa,YAAY,MAAM;AACjC,gBAAa,aAAa,QAAQ;AAClC,gBAAa,UAAU;;IAExB,EAAE,CAAC;CAEN,MAAM,gBAAgB,kBAAkB;AACtC,MAAI,OAAO,YAAY,MAAM;AAC3B,wBAAqB,OAAO,QAAQ;AACpC,UAAO,UAAU;;AAEnB,iBAAe,UAAU;IACxB,EAAE,CAAC;CAEN,MAAM,iBAAiB,kBAAkB;AACvC,iBAAe;AACf,kBAAgB;IACf,CAAC,gBAAgB,cAAc,CAAC;CAEnC,MAAM,oBAAoB,aAAyB,GAAG;CAEtD,MAAM,oBAAoB,aACvB,YAAoB;AACnB,kBAAgB;AAEhB,eAAa,UAAU,iBACf;AACJ,gBAAa,UAAU;AACvB,qBAAkB,SAAS;KAE7B,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,CAAC,CAChC;IAEH,CAAC,eAAe,CACjB;CAED,MAAM,gBAAgB,aACnB,gBAAwB;AACvB,kBAAgB;EAEhB,MAAM,QAAQ,CAAC,GAAG,YAAY;EAC9B,MAAM,MAAM,QAAQ;AAEpB,mBAAiB,UAAU;AAC3B,iBAAe,UAAU;AACzB,iBAAe,UAAU,MAAM;AAE/B,sBAAoB,UAAU;AAC9B,oBAAkB,UAAU,MAAM;AAClC,sBAAoB,YAAY;AAEhC,YAAU,UAAU,OAAO;AAC3B,kBAAgB,UAAU;AAC1B,mBAAiB,UAAU,OAAO;AAClC,iBAAe,UAAU;AACzB,oBAAkB,UAAU,MAAM;IAEpC,CAAC,OAAO,YAAY,eAAe,CACpC;CAED,MAAM,iBAAiB,kBAAkB;AACvC,kBAAgB;AAChB,MAAI,OAAO,YAAY,KAAM;EAE7B,MAAM,QAAQ,OAAe;GAC3B,MAAM,aAAa,QAAQ;AAE3B,OAAI,eAAe,YAAY,MAAM;AACnC,mBAAe,UAAU;AACzB,WAAO,UAAU,sBAAsB,KAAK;AAC5C;;GAGF,MAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,eAAe,QAAQ;GAChE,MAAM,YAAY,KAAK,IAAI,MAAO,KAAK,IAAI,kBAAkB,KAAM,IAAK,CAAC;AACzE,kBAAe,UAAU;GAEzB,MAAM,cAAc,eAAe;GACnC,MAAM,iBAAiB,kBAAkB;GACzC,MAAM,UAAU,cAAc;AAE9B,OAAI,WAAW,GAAG;AAChB,mBAAe;AACf;;GAIF,MAAM,SADM,QAAQ,GACC,eAAe;GACpC,MAAM,cAAc,UAAU,OAAO;GACrC,MAAM,WAAW,CAAC,eAAe,UAAU,OAAO;GAElD,MAAM,UAAU,MAAM,UAAU,SAAS,OAAO,QAAQ,OAAO,OAAO;GACtE,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAO,UAAU,OAAO,iBAAkB,IAAK,CAAC;GACtF,MAAM,gBAAgB,KAAK,IAAI,eAAe,GAAG,eAAe,EAAE;GAClE,MAAM,iBAAiB,cACnB,KAAK,MACH,MAAM,eAAe,gBAAgB,UAAU,KAAM,cAAc,cAAc,CAClF,GACD;GACJ,MAAM,mBAAmB,KAAK,IAAI,GAAG,cAAc,eAAe;GAElE,IAAI;AACJ,OAAI,aAAa;IACf,MAAM,kBAAkB,iBAAiB,IAAI,UAAU,iBAAiB;IACxE,MAAM,gBAAgB,iBAAiB,IAAI,gBAAgB,UAAU,iBAAiB;IACtF,MAAM,kBAAkB,iBAAiB,UAAU,KAAK,IAAI,SAAS,EAAE;IACvE,MAAM,mBAAmB,MACvB,kBAAkB,KAAM,gBAAgB,MAAO,kBAAkB,KACjE,GACA,IACD;IACD,MAAM,YAAY,MAChB,OAAO,eAAe,gBAAgB,UAAU,GAChD,OAAO,cACP,OAAO,YACR;AACD,iBAAa,MAAM,UAAU,kBAAkB,OAAO,QAAQ,UAAU;cAC/D,UAAU;IAGnB,MAAM,gBAAgB,MAAM,UAAU,GAAG,OAAO,kBAAkB,OAAO,iBAAiB;AAE1F,iBAAa,MADM,UAAU,MAAQ,eACP,OAAO,UAAU,OAAO,YAAY;SAOlE,cAAa,MALQ,KAAK,IACxB,OAAO,UACP,UAAU,KACV,iBAAiB,UAAU,GAC5B,EACgC,OAAO,UAAU,OAAO,YAAY;GAGvE,MAAM,gBAAgB,eAAe,iBAAiB,KAAK,UAAU,iBAAiB;GACtF,MAAM,cAAc,eAAe,gBAAgB,WAAW,iBAAiB;GAE/E,IAAI,cAAc,KAAK,IADA,cAAe,iBAAiB,cAAc,IAAI,IAAK,GACnC,KAAK,MAAM,aAAa,UAAU,CAAC;AAE9E,OAAI,aAAa;IACf,MAAM,YAAY,mBAAmB;AACrC,QAAI,aAAa,GAAG;AAClB,oBAAe;AACf,uBAAkB,OAAO,sBAAsB,OAAO;AAEtD,eAAU,qBAAqB;MAC7B;MACA,YAAY,QAAQ,GAAG;MACvB;MACA;MACA,aAAa;MACb;MACD,CAAC;AACF;;AAEF,kBAAc,KAAK,IAAI,aAAa,WAAW,QAAQ;SAEvD,eAAc,KAAK,IAAI,aAAa,QAAQ;GAG9C,MAAM,YAAY,iBAAiB;GACnC,MAAM,UAAU,eAAe,QAAQ,MAAM,gBAAgB,UAAU,CAAC,KAAK,GAAG;AAEhF,OAAI,SAAS;IACX,MAAM,gBAAgB,oBAAoB,UAAU;AACpD,wBAAoB,UAAU;AAC9B,sBAAkB,UAAU;AAC5B,wBAAoB,cAAc;UAC7B;AACL,wBAAoB,UAAU,iBAAiB;AAC/C,sBAAkB,UAAU;AAC5B,wBAAoB,iBAAiB,QAAQ;;AAG/C,aAAU,qBAAqB;IAC7B;IACA,YAAY,QAAQ,GAAG;IACvB;IACA;IACA,aAAa,UAAU,cAAc;IACrC;IACD,CAAC;AAEF,UAAO,UAAU,sBAAsB,KAAK;;AAG9C,SAAO,UAAU,sBAAsB,KAAK;IAC3C;EACD;EACA,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP;EACA;EACD,CAAC;AACF,mBAAkB,UAAU;AAE5B,iBAAgB;AACd,MAAI,CAAC,SAAS;AACZ,iBAAc,QAAQ;AACtB;;EAGF,MAAM,oBAAoB,iBAAiB;AAC3C,MAAI,YAAY,kBAAmB;EAEnC,MAAM,MAAM,QAAQ;AAGpB,MAAI,CAFe,QAAQ,WAAW,kBAAkB,EAEvC;AACf,iBAAc,QAAQ;AACtB;;EAIF,MAAM,gBAAgB,CAAC,GADN,QAAQ,MAAM,kBAAkB,OAAO,CACrB;EACnC,MAAM,gBAAgB,cAAc;AAEpC,YAAU,kBAAkB;GAC1B,eAAe;GACf,eAAe,WAAW,QAAQ;GACnC,CAAC;AAEF,MAAI,gBAAgB,OAAO,kBAAkB;AAC3C,iBAAc,QAAQ;AACtB;;AAGF,mBAAiB,UAAU;AAC3B,iBAAe,UAAU,CAAC,GAAG,eAAe,SAAS,GAAG,cAAc;AACtE,iBAAe,WAAW;EAE1B,MAAM,aAAa,eAAe,UAAU,kBAAkB;EAC9D,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM,eAAe,QAAQ;AAEzD,MAAI,aAAa,GAAG;GAClB,MAAM,aAAc,aAAa,MAAQ;GACzC,MAAM,uBAAuB,MAAM,YAAY,OAAO,QAAQ,OAAO,cAAc,EAAE;GACrF,MAAM,gBAAgB;AACtB,mBAAgB,UACd,gBAAgB,WAAW,IAAI,iBAAiB,gBAAgB;AAClE,oBAAiB,UACf,iBAAiB,WAAW,IAAI,iBAAiB,uBAAuB;GAE1E,MAAM,aAAa,MAAM,YAAY,OAAO,QAAQ,OAAO,aAAa;AACxE,aAAU,UAAU,UAAU,WAAW,IAAI,OAAO,YAAY,aAAa,OAAO;;AAGtF,iBAAe,UAAU;AACzB,oBAAkB,UAAU,eAAe;AAE3C,kBAAgB;IACf;EACD,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,iBAAgB;AACd,eAAa;AACX,mBAAgB;;IAEjB,CAAC,eAAe,CAAC;AAEpB,QAAO"}