dsh-smooth-stream 0.6.0 → 0.6.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.
package/lib/client.js CHANGED
@@ -10,40 +10,40 @@ window.__ModuleLoader__.load({
10
10
  let react_jsx_runtime = require("react/jsx-runtime");
11
11
  let react_dom = require("react-dom");
12
12
  //#region \0dsh-css:/Users/dzlin/work/project/dsh-smooth-stream/src/client/TypewriterAssistantNodeView.module.css.mjs
13
- const css$3 = ".I17U7q_root{min-width:0;color:var(--dsw-alias-label-primary);flex-direction:column;font-size:16px;line-height:28px;display:flex}.I17U7q_body{flex-direction:column;gap:16px;min-width:0;display:flex}.I17U7q_think{flex-direction:column;display:flex}.I17U7q_thinkRow{position:relative;overflow:hidden}.I17U7q_think[data-state=running] .I17U7q_thinkRow:after{content:\"\";inset-block:0;background:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%, transparent 100%);pointer-events:none;width:300px;animation:2.6s ease-out infinite I17U7q_dsh-smooth-stream-think-sweep;position:absolute;left:0}@keyframes I17U7q_dsh-smooth-stream-think-sweep{0%{left:-300px}90%,to{left:100%}}.I17U7q_thinkLeading{flex-shrink:0}.I17U7q_thinkChevron{color:var(--dsw-alias-label-secondary)}.I17U7q_thinkTitle{font-weight:400}.I17U7q_thinkSeparator{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.I17U7q_thinkSummary{min-width:0;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:14px;line-height:24px;overflow:hidden}.I17U7q_thinkSummary[data-follow-end]{text-overflow:clip}.I17U7q_thinkBody{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-word;padding:4px 0 4px 22px;font-size:14px;line-height:24px}.I17U7q_disclosureRoot{flex-direction:column;width:100%;min-width:0;display:flex}.I17U7q_disclosureRow{cursor:pointer;align-items:center;min-width:0;height:24px;display:flex;position:relative;overflow:hidden}.I17U7q_disclosureLeading{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex;position:relative}.I17U7q_disclosureIconIdle{opacity:1;transition:opacity .1s;display:inline-flex}.I17U7q_disclosureChevronHover{opacity:0;margin:auto;transition:opacity .1s;position:absolute;inset:0}.I17U7q_disclosureRow:hover .I17U7q_disclosureIconIdle{opacity:0}.I17U7q_disclosureRow:hover .I17U7q_disclosureChevronHover{opacity:1}.I17U7q_disclosureTitle{color:var(--dsw-alias-label-secondary);flex:none;font-size:14px;line-height:24px}.I17U7q_disclosureContent{visibility:visible;transition:grid-template-rows var(--ds-transition-duration,.2s) var(--ds-ease-in-out,cubic-bezier(.4, 0, .2, 1)), visibility 0s;grid-template-rows:1fr;display:grid}.I17U7q_disclosureContent[data-collapsed]{visibility:hidden;transition:grid-template-rows var(--ds-transition-duration,.2s) var(--ds-ease-in-out,cubic-bezier(.4, 0, .2, 1)), visibility 0s var(--ds-transition-duration,.2s);grid-template-rows:0fr}.I17U7q_disclosureContent[data-no-transition]{transition:none}.I17U7q_disclosureContent>*{min-height:0;overflow:hidden}@media (prefers-reduced-motion:reduce){.I17U7q_think[data-state=running] .I17U7q_thinkRow:after{animation:none}.I17U7q_disclosureContent,.I17U7q_disclosureContent[data-collapsed]{transition:none}}.I17U7q_stopped{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-tertiary);border-radius:6px;align-self:flex-start;padding:0 6px;font-size:11px;line-height:18px}.I17U7q_visuallyHidden{clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.I17U7q_follow{contain:layout style;min-width:0}.I17U7q_root :not(pre)>code{line-height:inherit;white-space:normal;overflow-wrap:anywhere;vertical-align:baseline;display:inline}@supports (text-box-trim:trim-both){.I17U7q_root :is(p,h1,h2,h3,h4,h5,h6,blockquote){text-box-trim:trim-both;text-box-edge:text}}";
14
- const tagId$3 = "dsh-smooth-stream/TypewriterAssistantNodeView.module.css";
13
+ const css$4 = ".I17U7q_root{min-width:0;color:var(--dsw-alias-label-primary);flex-direction:column;font-size:16px;line-height:28px;display:flex}.I17U7q_body{flex-direction:column;gap:16px;min-width:0;display:flex}.I17U7q_think{flex-direction:column;display:flex}.I17U7q_thinkRow{position:relative;overflow:hidden}.I17U7q_think[data-state=running] .I17U7q_thinkRow:after{content:\"\";inset-block:0;background:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%, transparent 100%);pointer-events:none;width:300px;animation:2.6s ease-out infinite I17U7q_dsh-smooth-stream-think-sweep;position:absolute;left:0}@keyframes I17U7q_dsh-smooth-stream-think-sweep{0%{left:-300px}90%,to{left:100%}}.I17U7q_thinkLeading{flex-shrink:0}.I17U7q_thinkChevron{color:var(--dsw-alias-label-secondary)}.I17U7q_thinkTitle{font-weight:400}.I17U7q_thinkSeparator{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.I17U7q_thinkSummary{min-width:0;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:14px;line-height:24px;overflow:hidden}.I17U7q_thinkSummary[data-follow-end]{text-overflow:clip}.I17U7q_thinkBody{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-word;padding:4px 0 4px 22px;font-size:14px;line-height:24px}.I17U7q_disclosureRoot{flex-direction:column;width:100%;min-width:0;display:flex}.I17U7q_disclosureRow{cursor:pointer;align-items:center;min-width:0;height:24px;display:flex;position:relative;overflow:hidden}.I17U7q_disclosureLeading{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex;position:relative}.I17U7q_disclosureIconIdle{opacity:1;transition:opacity .1s;display:inline-flex}.I17U7q_disclosureChevronHover{opacity:0;margin:auto;transition:opacity .1s;position:absolute;inset:0}.I17U7q_disclosureRow:hover .I17U7q_disclosureIconIdle{opacity:0}.I17U7q_disclosureRow:hover .I17U7q_disclosureChevronHover{opacity:1}.I17U7q_disclosureTitle{color:var(--dsw-alias-label-secondary);flex:none;font-size:14px;line-height:24px}.I17U7q_disclosureContent{visibility:visible;transition:grid-template-rows var(--ds-transition-duration,.2s) var(--ds-ease-in-out,cubic-bezier(.4, 0, .2, 1)), visibility 0s;grid-template-rows:1fr;display:grid}.I17U7q_disclosureContent[data-collapsed]{visibility:hidden;transition:grid-template-rows var(--ds-transition-duration,.2s) var(--ds-ease-in-out,cubic-bezier(.4, 0, .2, 1)), visibility 0s var(--ds-transition-duration,.2s);grid-template-rows:0fr}.I17U7q_disclosureContent[data-no-transition]{transition:none}.I17U7q_disclosureContent>*{min-height:0;overflow:hidden}@media (prefers-reduced-motion:reduce){.I17U7q_think[data-state=running] .I17U7q_thinkRow:after{animation:none}.I17U7q_disclosureContent,.I17U7q_disclosureContent[data-collapsed]{transition:none}}.I17U7q_stopped{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-tertiary);border-radius:6px;align-self:flex-start;padding:0 6px;font-size:11px;line-height:18px}.I17U7q_visuallyHidden{clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.I17U7q_follow{contain:layout style;min-width:0}.I17U7q_root :not(pre)>code{line-height:inherit;white-space:normal;overflow-wrap:anywhere;vertical-align:baseline;display:inline}@supports (text-box-trim:trim-both){.I17U7q_root :is(p,h1,h2,h3,h4,h5,h6,blockquote){text-box-trim:trim-both;text-box-edge:text}}";
14
+ const tagId$4 = "dsh-smooth-stream/TypewriterAssistantNodeView.module.css";
15
15
  if (typeof document !== "undefined") {
16
- let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]");
16
+ let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]");
17
17
  if (tag === null) {
18
18
  tag = document.createElement("style");
19
19
  tag.dataset.plugin = "dsh-smooth-stream";
20
- tag.dataset.pluginCss = tagId$3;
20
+ tag.dataset.pluginCss = tagId$4;
21
21
  document.head.appendChild(tag);
22
22
  }
23
- tag.textContent = css$3;
23
+ tag.textContent = css$4;
24
24
  }
25
25
  var TypewriterAssistantNodeView_module_css_default = {
26
- "stopped": "I17U7q_stopped",
27
- "thinkChevron": "I17U7q_thinkChevron",
28
26
  "thinkTitle": "I17U7q_thinkTitle",
29
- "thinkLeading": "I17U7q_thinkLeading",
30
- "thinkSeparator": "I17U7q_thinkSeparator",
31
- "body": "I17U7q_body",
32
- "thinkBody": "I17U7q_thinkBody",
33
27
  "disclosureContent": "I17U7q_disclosureContent",
28
+ "disclosureLeading": "I17U7q_disclosureLeading",
29
+ "thinkSummary": "I17U7q_thinkSummary",
30
+ "thinkRow": "I17U7q_thinkRow",
34
31
  "visuallyHidden": "I17U7q_visuallyHidden",
35
- "disclosureTitle": "I17U7q_disclosureTitle",
32
+ "disclosureRoot": "I17U7q_disclosureRoot",
33
+ "body": "I17U7q_body",
36
34
  "dsh-smooth-stream-think-sweep": "I17U7q_dsh-smooth-stream-think-sweep",
37
35
  "disclosureIconIdle": "I17U7q_disclosureIconIdle",
38
- "follow": "I17U7q_follow",
39
- "think": "I17U7q_think",
40
- "thinkSummary": "I17U7q_thinkSummary",
41
- "disclosureRow": "I17U7q_disclosureRow",
42
36
  "root": "I17U7q_root",
43
- "disclosureLeading": "I17U7q_disclosureLeading",
44
- "thinkRow": "I17U7q_thinkRow",
45
37
  "disclosureChevronHover": "I17U7q_disclosureChevronHover",
46
- "disclosureRoot": "I17U7q_disclosureRoot"
38
+ "stopped": "I17U7q_stopped",
39
+ "think": "I17U7q_think",
40
+ "thinkChevron": "I17U7q_thinkChevron",
41
+ "thinkBody": "I17U7q_thinkBody",
42
+ "follow": "I17U7q_follow",
43
+ "thinkSeparator": "I17U7q_thinkSeparator",
44
+ "thinkLeading": "I17U7q_thinkLeading",
45
+ "disclosureRow": "I17U7q_disclosureRow",
46
+ "disclosureTitle": "I17U7q_disclosureTitle"
47
47
  };
48
48
  //#endregion
49
49
  //#region src/client/AnimatedDisclosure.tsx
@@ -128,6 +128,7 @@ window.__ModuleLoader__.load({
128
128
  controlScroll: true,
129
129
  motionPreference: "auto",
130
130
  thinkAutoExpand: true,
131
+ logarithmicFade: true,
131
132
  debugEnabled: false,
132
133
  debugTuning: DEFAULT_STREAM_DEBUG_TUNING
133
134
  };
@@ -858,7 +859,8 @@ window.__ModuleLoader__.load({
858
859
  });
859
860
  return null;
860
861
  }
861
- const delta = top - stored.top - (shift - stored.shift) + (pad - stored.pad);
862
+ const scrollDelta = scrollTop - stored.scrollTop;
863
+ const delta = top - stored.top + scrollDelta - (shift - stored.shift) + (pad - stored.pad);
862
864
  if (stored.element === anchor) {
863
865
  followGuardAnchors.set(port, {
864
866
  element: anchor,
@@ -1935,18 +1937,18 @@ window.__ModuleLoader__.load({
1935
1937
  }
1936
1938
  let settleQuietMs = 0;
1937
1939
  let settleSig = "";
1938
- const lagBeforeCompletionPaint = Math.max(0, host.scrollHeight - animatedH - runwayOffsetOf(host));
1939
- const currentRunway = runwayOffsetOf(host);
1940
- const currentShift = Math.abs(currentShiftOf(shiftSurfacesOf(host).at(-1) ?? host));
1941
- if (!activeRef.current && lagBeforeCompletionPaint <= 25 && currentRunway <= .25 && currentShift <= .25 && flowPadOf(host) <= .25) {
1940
+ if (!activeRef.current) {
1942
1941
  followTraceUntilMs = Math.max(followTraceUntilMs, performance.now() + 1e4);
1943
1942
  followTrace("fast-gate", {
1944
1943
  sh: host.scrollHeight,
1945
1944
  st: Math.round(host.scrollTop),
1946
1945
  pad: Math.round(flowPadOf(host))
1947
1946
  });
1948
- finishAtNaturalFloor(host, !startedAsEntrance);
1947
+ restoreRunway(host);
1948
+ setFlowPad(host, 0);
1949
+ finishAtNaturalFloor(host, !startedAsEntrance, true);
1949
1950
  followLeaders.delete(host);
1951
+ followCompletionSettle.delete(host);
1950
1952
  releaseRevealScale();
1951
1953
  debugRuntime.reportFollow(host, null);
1952
1954
  return;
@@ -2605,6 +2607,293 @@ window.__ModuleLoader__.load({
2605
2607
  };
2606
2608
  }
2607
2609
  //#endregion
2610
+ //#region \0dsh-css:/Users/dzlin/work/project/dsh-smooth-stream/src/client/LogarithmicFade.module.css.mjs
2611
+ const css$3 = ".g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-0),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-0){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 0.0%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-1),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-1){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 3.22581%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-2),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-2){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 6.45161%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-3),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-3){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 9.67742%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-4),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-4){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 12.9032%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-5),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-5){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 16.129%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-6),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-6){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 19.3548%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-7),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-7){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 22.5807%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-8),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-8){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 25.8065%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-9),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-9){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 29.0323%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-10),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-10){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 32.2581%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-11),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-11){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 35.4839%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-12),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-12){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 38.7097%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-13),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-13){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 41.9355%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-14),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-14){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 45.1613%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-15),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-15){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 48.3871%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-16),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-16){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 51.6129%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-17),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-17){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 54.8387%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-18),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-18){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 58.0645%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-19),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-19){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 61.2903%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-20),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-20){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 64.5161%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-21),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-21){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 67.7419%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-22),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-22){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 70.9677%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-23),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-23){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 74.1936%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-24),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-24){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 77.4194%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-25),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-25){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 80.6452%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-26),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-26){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 83.871%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-27),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-27){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 87.0968%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-28),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-28){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 90.3226%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-29),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-29){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 93.5484%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-30),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-30){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 96.7742%, transparent)}.g268Pa_scope::highlight(g268Pa_dsh-smooth-stream-log-fade-31),.g268Pa_scope ::highlight(g268Pa_dsh-smooth-stream-log-fade-31){color:color-mix(in srgb, var(--dsh-smooth-stream-fade-color,currentColor) 100.0%, transparent)}";
2612
+ const tagId$3 = "dsh-smooth-stream/LogarithmicFade.module.css";
2613
+ if (typeof document !== "undefined") {
2614
+ let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]");
2615
+ if (tag === null) {
2616
+ tag = document.createElement("style");
2617
+ tag.dataset.plugin = "dsh-smooth-stream";
2618
+ tag.dataset.pluginCss = tagId$3;
2619
+ document.head.appendChild(tag);
2620
+ }
2621
+ tag.textContent = css$3;
2622
+ }
2623
+ var LogarithmicFade_module_css_default = {
2624
+ "dsh-smooth-stream-log-fade-0": "g268Pa_dsh-smooth-stream-log-fade-0",
2625
+ "dsh-smooth-stream-log-fade-30": "g268Pa_dsh-smooth-stream-log-fade-30",
2626
+ "dsh-smooth-stream-log-fade-4": "g268Pa_dsh-smooth-stream-log-fade-4",
2627
+ "dsh-smooth-stream-log-fade-31": "g268Pa_dsh-smooth-stream-log-fade-31",
2628
+ "dsh-smooth-stream-log-fade-9": "g268Pa_dsh-smooth-stream-log-fade-9",
2629
+ "dsh-smooth-stream-log-fade-17": "g268Pa_dsh-smooth-stream-log-fade-17",
2630
+ "dsh-smooth-stream-log-fade-18": "g268Pa_dsh-smooth-stream-log-fade-18",
2631
+ "dsh-smooth-stream-log-fade-19": "g268Pa_dsh-smooth-stream-log-fade-19",
2632
+ "dsh-smooth-stream-log-fade-21": "g268Pa_dsh-smooth-stream-log-fade-21",
2633
+ "dsh-smooth-stream-log-fade-12": "g268Pa_dsh-smooth-stream-log-fade-12",
2634
+ "dsh-smooth-stream-log-fade-8": "g268Pa_dsh-smooth-stream-log-fade-8",
2635
+ "dsh-smooth-stream-log-fade-22": "g268Pa_dsh-smooth-stream-log-fade-22",
2636
+ "dsh-smooth-stream-log-fade-29": "g268Pa_dsh-smooth-stream-log-fade-29",
2637
+ "dsh-smooth-stream-log-fade-1": "g268Pa_dsh-smooth-stream-log-fade-1",
2638
+ "dsh-smooth-stream-log-fade-25": "g268Pa_dsh-smooth-stream-log-fade-25",
2639
+ "dsh-smooth-stream-log-fade-23": "g268Pa_dsh-smooth-stream-log-fade-23",
2640
+ "dsh-smooth-stream-log-fade-26": "g268Pa_dsh-smooth-stream-log-fade-26",
2641
+ "dsh-smooth-stream-log-fade-28": "g268Pa_dsh-smooth-stream-log-fade-28",
2642
+ "dsh-smooth-stream-log-fade-6": "g268Pa_dsh-smooth-stream-log-fade-6",
2643
+ "dsh-smooth-stream-log-fade-20": "g268Pa_dsh-smooth-stream-log-fade-20",
2644
+ "dsh-smooth-stream-log-fade-10": "g268Pa_dsh-smooth-stream-log-fade-10",
2645
+ "dsh-smooth-stream-log-fade-14": "g268Pa_dsh-smooth-stream-log-fade-14",
2646
+ "dsh-smooth-stream-log-fade-24": "g268Pa_dsh-smooth-stream-log-fade-24",
2647
+ "dsh-smooth-stream-log-fade-2": "g268Pa_dsh-smooth-stream-log-fade-2",
2648
+ "dsh-smooth-stream-log-fade-13": "g268Pa_dsh-smooth-stream-log-fade-13",
2649
+ "dsh-smooth-stream-log-fade-16": "g268Pa_dsh-smooth-stream-log-fade-16",
2650
+ "dsh-smooth-stream-log-fade-5": "g268Pa_dsh-smooth-stream-log-fade-5",
2651
+ "dsh-smooth-stream-log-fade-27": "g268Pa_dsh-smooth-stream-log-fade-27",
2652
+ "scope": "g268Pa_scope",
2653
+ "dsh-smooth-stream-log-fade-7": "g268Pa_dsh-smooth-stream-log-fade-7",
2654
+ "dsh-smooth-stream-log-fade-15": "g268Pa_dsh-smooth-stream-log-fade-15",
2655
+ "dsh-smooth-stream-log-fade-3": "g268Pa_dsh-smooth-stream-log-fade-3",
2656
+ "dsh-smooth-stream-log-fade-11": "g268Pa_dsh-smooth-stream-log-fade-11"
2657
+ };
2658
+ const FADE_STEPS = 32;
2659
+ const PREFIX = "dsh-smooth-stream-log-fade-";
2660
+ const COLOR_PROPERTY = "--dsh-smooth-stream-fade-color";
2661
+ const highlightName = (index) => LogarithmicFade_module_css_default[`${PREFIX}${index}`] ?? `${PREFIX}${index}`;
2662
+ const EXCLUDED = "pre,code,math,.katex,.katex-display,mjx-container,svg,script,style,textarea,input,button,select,[role=\"button\"],[contenteditable],[hidden],[aria-hidden=\"true\"],[aria-live]";
2663
+ function logarithmicOpacity(progress) {
2664
+ return 0 + 1 * (1 - Math.log1p(5 * (1 - (Number.isFinite(progress) ? Math.max(0, Math.min(1, progress)) : 1))) / Math.log(6));
2665
+ }
2666
+ function fadeTailSize(speedCps) {
2667
+ return Math.min(160, Math.max(24, Math.ceil((Number.isFinite(speedCps) ? Math.max(0, speedCps) : 0) * 240 / 1e3)));
2668
+ }
2669
+ const schedulers = /* @__PURE__ */ new WeakMap();
2670
+ const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
2671
+ function schedule(scheduler) {
2672
+ if (scheduler.frame !== 0 || scheduler.pending.size === 0) return;
2673
+ scheduler.frame = scheduler.window.requestAnimationFrame((now) => {
2674
+ scheduler.frame = 0;
2675
+ for (const client of scheduler.pending) if (!client.paint(now)) scheduler.pending.delete(client);
2676
+ schedule(scheduler);
2677
+ });
2678
+ }
2679
+ function schedulerFor(root) {
2680
+ const doc = root.ownerDocument;
2681
+ const win = doc.defaultView;
2682
+ if (win === null) return null;
2683
+ const realm = win;
2684
+ if (typeof realm.Highlight !== "function" || !realm.CSS?.highlights || !realm.CSS.supports("color", "color-mix(in srgb, currentColor 15%, transparent)")) return null;
2685
+ let scheduler = schedulers.get(doc);
2686
+ if (scheduler === void 0) {
2687
+ const highlights = Array.from({ length: FADE_STEPS }, () => new realm.Highlight());
2688
+ for (const [index, highlight] of highlights.entries()) realm.CSS.highlights.set(highlightName(index), highlight);
2689
+ scheduler = {
2690
+ highlights,
2691
+ clients: /* @__PURE__ */ new Set(),
2692
+ pending: /* @__PURE__ */ new Set(),
2693
+ frame: 0,
2694
+ registry: realm.CSS.highlights,
2695
+ window: win
2696
+ };
2697
+ schedulers.set(doc, scheduler);
2698
+ }
2699
+ return scheduler;
2700
+ }
2701
+ /** Owns ranges only: React retains ownership of every element and Text node. */
2702
+ var LogarithmicFadeController = class LogarithmicFadeController {
2703
+ root;
2704
+ scheduler;
2705
+ previous = "";
2706
+ characters = [];
2707
+ colors = /* @__PURE__ */ new Map();
2708
+ enabled = false;
2709
+ active = false;
2710
+ speedCps = 100;
2711
+ pausedAt = null;
2712
+ disposed = false;
2713
+ observer;
2714
+ constructor(root, scheduler) {
2715
+ this.root = root;
2716
+ this.scheduler = scheduler;
2717
+ scheduler.clients.add(this);
2718
+ const win = root.ownerDocument.defaultView;
2719
+ this.observer = new win.MutationObserver(() => {
2720
+ this.reconcile();
2721
+ });
2722
+ this.observer.observe(root, {
2723
+ subtree: true,
2724
+ childList: true,
2725
+ characterData: true
2726
+ });
2727
+ }
2728
+ static create(root) {
2729
+ const scheduler = schedulerFor(root);
2730
+ return scheduler === null ? null : new LogarithmicFadeController(root, scheduler);
2731
+ }
2732
+ update(enabled, active, speedCps = 100, paused = false) {
2733
+ const now = this.scheduler.window.performance.now();
2734
+ if (paused && this.pausedAt === null) this.pausedAt = now;
2735
+ if (!paused && this.pausedAt !== null) {
2736
+ const pauseDuration = now - this.pausedAt;
2737
+ for (const character of this.characters) character.born += pauseDuration;
2738
+ this.pausedAt = null;
2739
+ }
2740
+ this.enabled = enabled;
2741
+ this.active = active;
2742
+ this.speedCps = speedCps;
2743
+ this.reconcile();
2744
+ }
2745
+ clearRanges() {
2746
+ for (const character of this.characters) this.scheduler.highlights[character.bucket]?.delete(character.range);
2747
+ this.characters = [];
2748
+ this.restoreColors();
2749
+ }
2750
+ restoreColors() {
2751
+ for (const [element, original] of this.colors) if (original.value === "") element.style.removeProperty(COLOR_PROPERTY);
2752
+ else element.style.setProperty(COLOR_PROPERTY, original.value, original.priority);
2753
+ this.colors.clear();
2754
+ }
2755
+ preserveColor(element) {
2756
+ if (this.colors.has(element)) return;
2757
+ const color = this.scheduler.window.getComputedStyle(element).color;
2758
+ this.colors.set(element, {
2759
+ value: element.style.getPropertyValue(COLOR_PROPERTY),
2760
+ priority: element.style.getPropertyPriority(COLOR_PROPERTY)
2761
+ });
2762
+ element.style.setProperty(COLOR_PROPERTY, color);
2763
+ }
2764
+ reconcile() {
2765
+ if (this.disposed) return;
2766
+ const text = this.root.textContent ?? "";
2767
+ const previous = this.previous;
2768
+ this.previous = text;
2769
+ const old = this.characters;
2770
+ this.clearRanges();
2771
+ if (!this.enabled) {
2772
+ this.root.classList.remove(LogarithmicFade_module_css_default.scope);
2773
+ this.scheduler.pending.delete(this);
2774
+ this.stopIfIdle();
2775
+ return;
2776
+ }
2777
+ this.root.classList.add(LogarithmicFade_module_css_default.scope);
2778
+ const now = this.pausedAt ?? this.scheduler.window.performance.now();
2779
+ let prefix = 0;
2780
+ while (prefix < previous.length && prefix < text.length && previous[prefix] === text[prefix]) prefix += 1;
2781
+ const appended = text.startsWith(previous);
2782
+ const nodes = [];
2783
+ const walker = this.root.ownerDocument.createTreeWalker(this.root, NodeFilter.SHOW_TEXT);
2784
+ let offset = 0;
2785
+ for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
2786
+ const end = offset + (node.textContent?.length ?? 0);
2787
+ nodes.push({
2788
+ node,
2789
+ start: offset,
2790
+ end,
2791
+ eligible: node.parentElement?.closest(EXCLUDED) === null
2792
+ });
2793
+ offset = end;
2794
+ }
2795
+ const segments = segmenter.segment(text);
2796
+ const tailSize = fadeTailSize(this.speedCps);
2797
+ const oldestLiveStart = old.reduce((start, character) => now - character.born < 240 && character.end <= prefix ? Math.min(start, character.start) : start, Infinity);
2798
+ let end = text.length;
2799
+ for (let count = 0; count < 160 && end > 0 && (count < tailSize || end > oldestLiveStart); count += 1) {
2800
+ const segment = segments.containing(end - 1);
2801
+ if (segment === void 0) break;
2802
+ const start = segment.index;
2803
+ const parts = nodes.filter((node) => node.end > start && node.start < end);
2804
+ const born = old.find((character) => character.start === start && character.end === end && end <= prefix)?.born ?? (this.active && appended && start >= previous.length ? now : null);
2805
+ if (born !== null && now - born < 240 && segment.segment.trim() !== "" && parts.length > 0 && parts.every((part) => part.eligible)) {
2806
+ const first = parts[0];
2807
+ const last = parts[parts.length - 1];
2808
+ const range = this.root.ownerDocument.createRange();
2809
+ range.setStart(first.node, start - first.start);
2810
+ range.setEnd(last.node, end - last.start);
2811
+ for (const part of parts) this.preserveColor(part.node.parentElement);
2812
+ this.characters.push({
2813
+ start,
2814
+ end,
2815
+ born,
2816
+ range,
2817
+ bucket: -1
2818
+ });
2819
+ }
2820
+ end = start;
2821
+ }
2822
+ if (this.paint(now)) {
2823
+ if (this.pausedAt === null) {
2824
+ this.scheduler.pending.add(this);
2825
+ schedule(this.scheduler);
2826
+ } else {
2827
+ this.scheduler.pending.delete(this);
2828
+ this.stopIfIdle();
2829
+ }
2830
+ } else {
2831
+ this.scheduler.pending.delete(this);
2832
+ this.stopIfIdle();
2833
+ }
2834
+ }
2835
+ paint(now) {
2836
+ this.characters = this.characters.filter((character) => {
2837
+ const progress = (now - character.born) / 240;
2838
+ if (progress >= 1 || !this.root.isConnected || !this.root.contains(character.range.startContainer)) {
2839
+ this.scheduler.highlights[character.bucket]?.delete(character.range);
2840
+ return false;
2841
+ }
2842
+ const bucket = Math.min(31, Math.round((logarithmicOpacity(progress) - 0) / 1 * 31));
2843
+ if (bucket !== character.bucket) {
2844
+ this.scheduler.highlights[character.bucket]?.delete(character.range);
2845
+ this.scheduler.highlights[bucket].add(character.range);
2846
+ character.bucket = bucket;
2847
+ }
2848
+ return true;
2849
+ });
2850
+ if (this.characters.length === 0) this.restoreColors();
2851
+ return this.characters.length > 0;
2852
+ }
2853
+ stopIfIdle() {
2854
+ if (this.scheduler.pending.size !== 0) return;
2855
+ this.scheduler.window.cancelAnimationFrame(this.scheduler.frame);
2856
+ this.scheduler.frame = 0;
2857
+ }
2858
+ dispose() {
2859
+ if (this.disposed) return;
2860
+ this.disposed = true;
2861
+ this.observer.disconnect();
2862
+ this.clearRanges();
2863
+ this.root.classList.remove(LogarithmicFade_module_css_default.scope);
2864
+ this.scheduler.pending.delete(this);
2865
+ this.scheduler.clients.delete(this);
2866
+ this.stopIfIdle();
2867
+ if (this.scheduler.clients.size === 0) {
2868
+ for (const [index, highlight] of this.scheduler.highlights.entries()) {
2869
+ const name = highlightName(index);
2870
+ if (this.scheduler.registry.get(name) === highlight) this.scheduler.registry.delete(name);
2871
+ }
2872
+ schedulers.delete(this.root.ownerDocument);
2873
+ }
2874
+ }
2875
+ };
2876
+ /** active admits new characters; enabled=false also cancels completion linger. */
2877
+ function useLogarithmicFade(rootRef, enabled, active, speedCpsRef, paused = false) {
2878
+ const controller = (0, react.useRef)(null);
2879
+ const committed = (0, react.useRef)(false);
2880
+ (0, react.useLayoutEffect)(() => {
2881
+ return () => {
2882
+ controller.current?.dispose();
2883
+ controller.current = null;
2884
+ };
2885
+ }, [rootRef]);
2886
+ (0, react.useLayoutEffect)(() => {
2887
+ const root = rootRef.current;
2888
+ if (controller.current === null && root !== null && enabled && active) {
2889
+ controller.current = LogarithmicFadeController.create(root);
2890
+ if (committed.current) controller.current?.update(false, false);
2891
+ }
2892
+ controller.current?.update(enabled, active, speedCpsRef?.current, paused);
2893
+ committed.current = true;
2894
+ });
2895
+ }
2896
+ //#endregion
2608
2897
  //#region src/client/FollowHost.tsx
2609
2898
  /**
2610
2899
  * Document-flow host that owns conversation-port follow while `active`.
@@ -2901,7 +3190,7 @@ window.__ModuleLoader__.load({
2901
3190
  * drains, the settled full parse (KaTeX math, fence highlighting, file
2902
3191
  * mentions) swaps in exactly once.
2903
3192
  */
2904
- function AnimatedMarkdownText({ text, labels, fileMentions, streaming, motionReduced, ownFollow, followSpeedCpsRef, followRevealedCharsRef, followRevealScaleRef, onPredictiveChange, preset, shouldHoldBack, controlScroll = true }) {
3193
+ function AnimatedMarkdownText({ text, labels, fileMentions, streaming, logarithmicFade, motionReduced, ownFollow, followSpeedCpsRef, followRevealedCharsRef, followRevealScaleRef, onPredictiveChange, preset, shouldHoldBack, controlScroll = true }) {
2905
3194
  const reduced = motionReduced;
2906
3195
  const [typing, setTyping] = (0, react.useState)(streaming);
2907
3196
  const localSpeedCpsRef = (0, react.useRef)(35);
@@ -2924,6 +3213,7 @@ window.__ModuleLoader__.load({
2924
3213
  });
2925
3214
  const shown = reduced ? text : displayed;
2926
3215
  const live = typing && !reduced;
3216
+ useLogarithmicFade(followRootRef, logarithmicFade && !reduced, live, speedCpsRef);
2927
3217
  (0, react.useEffect)(() => {
2928
3218
  const root = followRootRef.current;
2929
3219
  if (root === null || typeof ResizeObserver === "undefined") return;
@@ -3052,17 +3342,20 @@ window.__ModuleLoader__.load({
3052
3342
  * or the assistant node settling — not when the rest of the reply is
3053
3343
  * still streaming.
3054
3344
  */
3055
- function AnimatedReasoning({ text, running, preset, thinkAutoExpand, motionReduced, shouldHoldBack, followSpeedCpsRef, followRevealScaleRef, t }) {
3345
+ function AnimatedReasoning({ text, running, preset, thinkAutoExpand, motionReduced, logarithmicFade, shouldHoldBack, followSpeedCpsRef, followRevealScaleRef, t }) {
3056
3346
  const reduced = motionReduced;
3057
3347
  const [expanded, setExpanded] = (0, react.useState)(running && thinkAutoExpand);
3058
3348
  const [autoClosed, setAutoClosed] = (0, react.useState)(false);
3059
3349
  const summaryRef = (0, react.useRef)(null);
3350
+ const fadeRootRef = (0, react.useRef)(null);
3351
+ const localFadeSpeedRef = (0, react.useRef)(35);
3352
+ const fadeSpeedRef = followSpeedCpsRef ?? localFadeSpeedRef;
3060
3353
  const commitAnchorRef = (0, react.useRef)(null);
3061
3354
  const displayed = useSmoothStreamContent(text, {
3062
3355
  enabled: running && !reduced,
3063
3356
  preset,
3064
3357
  shouldHoldBack,
3065
- speedCpsRef: followSpeedCpsRef,
3358
+ speedCpsRef: fadeSpeedRef,
3066
3359
  revealScaleRef: followRevealScaleRef,
3067
3360
  onRevealCommit: () => {
3068
3361
  notifyFollowCommit(commitAnchorRef.current);
@@ -3070,6 +3363,7 @@ window.__ModuleLoader__.load({
3070
3363
  });
3071
3364
  const shown = running && !reduced ? displayed : text;
3072
3365
  const summary = running ? latestLine(shown) : firstLine(text);
3366
+ useLogarithmicFade(fadeRootRef, logarithmicFade && !reduced && expanded, running, fadeSpeedRef);
3073
3367
  (0, react.useLayoutEffect)(() => {
3074
3368
  if (thinkAutoExpand) {
3075
3369
  setExpanded(running);
@@ -3115,6 +3409,7 @@ window.__ModuleLoader__.load({
3115
3409
  children: summary
3116
3410
  })] }),
3117
3411
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3412
+ ref: fadeRootRef,
3118
3413
  className: TypewriterAssistantNodeView_module_css_default.thinkBody,
3119
3414
  children: shown
3120
3415
  })
@@ -3132,7 +3427,7 @@ window.__ModuleLoader__.load({
3132
3427
  * holds offscreen reveals when the frame rate is degraded. Settled text
3133
3428
  * renders with the full Markdown pipeline.
3134
3429
  */
3135
- const TypewriterAssistantNodeView = (0, react.memo)(function TypewriterAssistantNodeView({ mode: _mode = DEFAULT_STREAM_CONFIG.mode, preset = DEFAULT_STREAM_CONFIG.preset, revealCharsPerSec: _revealCharsPerSec = DEFAULT_STREAM_CONFIG.revealCharsPerSec, scrollSpeedPxPerSec: _scrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.scrollSpeedPxPerSec, maxScrollSpeedPxPerSec: _maxScrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.maxScrollSpeedPxPerSec, thinkAutoExpand = DEFAULT_STREAM_SETTINGS.thinkAutoExpand, controlScroll = true, motionPreference = DEFAULT_STREAM_SETTINGS.motionPreference, node, useTurnData, openFile, loadImage, fileMentions, turnProcess, t }) {
3430
+ const TypewriterAssistantNodeView = (0, react.memo)(function TypewriterAssistantNodeView({ mode: _mode = DEFAULT_STREAM_CONFIG.mode, preset = DEFAULT_STREAM_CONFIG.preset, revealCharsPerSec: _revealCharsPerSec = DEFAULT_STREAM_CONFIG.revealCharsPerSec, scrollSpeedPxPerSec: _scrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.scrollSpeedPxPerSec, maxScrollSpeedPxPerSec: _maxScrollSpeedPxPerSec = DEFAULT_STREAM_CONFIG.maxScrollSpeedPxPerSec, thinkAutoExpand = DEFAULT_STREAM_SETTINGS.thinkAutoExpand, logarithmicFade = DEFAULT_STREAM_SETTINGS.logarithmicFade, controlScroll = true, motionPreference = DEFAULT_STREAM_SETTINGS.motionPreference, node, useTurnData, openFile, loadImage, fileMentions, turnProcess, t }) {
3136
3431
  const data = node.data;
3137
3432
  const streaming = data.status === "running";
3138
3433
  const reduced = useMotionReduced(motionPreference);
@@ -3202,6 +3497,7 @@ window.__ModuleLoader__.load({
3202
3497
  labels: markdownLabels,
3203
3498
  fileMentions: mentions,
3204
3499
  streaming,
3500
+ logarithmicFade: logarithmicFade && data.status !== "interrupted",
3205
3501
  motionReduced: reduced,
3206
3502
  ownFollow: !streaming && index === lastFollow,
3207
3503
  followSpeedCpsRef: index === lastFollow ? rootSpeedRef : void 0,
@@ -3222,6 +3518,7 @@ window.__ModuleLoader__.load({
3222
3518
  running: streaming && index === last,
3223
3519
  preset,
3224
3520
  thinkAutoExpand,
3521
+ logarithmicFade: logarithmicFade && data.status !== "interrupted",
3225
3522
  motionReduced: reduced,
3226
3523
  shouldHoldBack,
3227
3524
  followSpeedCpsRef: reasoningOwnsSpeed && index === last ? rootSpeedRef : void 0,
@@ -3747,35 +4044,35 @@ window.__ModuleLoader__.load({
3747
4044
  tag.textContent = css$1;
3748
4045
  }
3749
4046
  var SmoothStreamCard_module_css_default = {
4047
+ "save": "XNGeRG_save",
4048
+ "updateCopy": "XNGeRG_updateCopy",
4049
+ "hint": "XNGeRG_hint",
4050
+ "version": "XNGeRG_version",
4051
+ "update": "XNGeRG_update",
4052
+ "card": "XNGeRG_card",
4053
+ "choiceRow": "XNGeRG_choiceRow",
4054
+ "chevron": "XNGeRG_chevron",
4055
+ "failure": "XNGeRG_failure",
4056
+ "discard": "XNGeRG_discard",
4057
+ "updateRow": "XNGeRG_updateRow",
4058
+ "footer": "XNGeRG_footer",
3750
4059
  "body": "XNGeRG_body",
3751
- "fieldDisabled": "XNGeRG_fieldDisabled",
3752
- "readOnly": "XNGeRG_readOnly",
3753
4060
  "field": "XNGeRG_field",
3754
- "choiceInput": "XNGeRG_choiceInput",
3755
- "headText": "XNGeRG_headText",
3756
- "version": "XNGeRG_version",
4061
+ "failed": "XNGeRG_failed",
4062
+ "name": "XNGeRG_name",
4063
+ "readOnly": "XNGeRG_readOnly",
4064
+ "chevronOpen": "XNGeRG_chevronOpen",
4065
+ "toggle": "XNGeRG_toggle",
3757
4066
  "choice": "XNGeRG_choice",
4067
+ "choiceInput": "XNGeRG_choiceInput",
3758
4068
  "description": "XNGeRG_description",
3759
4069
  "pending": "XNGeRG_pending",
4070
+ "fieldDisabled": "XNGeRG_fieldDisabled",
4071
+ "headText": "XNGeRG_headText",
3760
4072
  "fieldHead": "XNGeRG_fieldHead",
3761
4073
  "label": "XNGeRG_label",
3762
- "toggle": "XNGeRG_toggle",
3763
- "hint": "XNGeRG_hint",
3764
- "save": "XNGeRG_save",
3765
- "updateRow": "XNGeRG_updateRow",
3766
- "chevron": "XNGeRG_chevron",
3767
4074
  "cardOpen": "XNGeRG_cardOpen",
3768
- "card": "XNGeRG_card",
3769
- "header": "XNGeRG_header",
3770
- "failure": "XNGeRG_failure",
3771
- "failed": "XNGeRG_failed",
3772
- "chevronOpen": "XNGeRG_chevronOpen",
3773
- "discard": "XNGeRG_discard",
3774
- "updateCopy": "XNGeRG_updateCopy",
3775
- "update": "XNGeRG_update",
3776
- "footer": "XNGeRG_footer",
3777
- "name": "XNGeRG_name",
3778
- "choiceRow": "XNGeRG_choiceRow"
4075
+ "header": "XNGeRG_header"
3779
4076
  };
3780
4077
  //#endregion
3781
4078
  //#region src/client/SmoothStreamCard.tsx
@@ -3891,6 +4188,27 @@ window.__ModuleLoader__.load({
3891
4188
  children: t("controlScrollHint")
3892
4189
  })]
3893
4190
  }),
4191
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
4192
+ className: state.enabled ? SmoothStreamCard_module_css_default.field : `${SmoothStreamCard_module_css_default.field} ${SmoothStreamCard_module_css_default.fieldDisabled}`,
4193
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4194
+ className: SmoothStreamCard_module_css_default.fieldHead,
4195
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4196
+ className: SmoothStreamCard_module_css_default.label,
4197
+ children: t("logarithmicFade")
4198
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4199
+ type: "checkbox",
4200
+ className: SmoothStreamCard_module_css_default.toggle,
4201
+ checked: state.logarithmicFade,
4202
+ disabled: !state.writable || state.saving || !state.enabled,
4203
+ onChange: (event) => {
4204
+ props.edit({ logarithmicFade: event.target.checked });
4205
+ }
4206
+ })]
4207
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4208
+ className: SmoothStreamCard_module_css_default.hint,
4209
+ children: t("logarithmicFadeHint")
4210
+ })]
4211
+ }),
3894
4212
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3895
4213
  className: state.enabled ? SmoothStreamCard_module_css_default.field : `${SmoothStreamCard_module_css_default.field} ${SmoothStreamCard_module_css_default.fieldDisabled}`,
3896
4214
  children: [
@@ -4084,12 +4402,13 @@ window.__ModuleLoader__.load({
4084
4402
  hooks: { smoothStreamCard: this.store },
4085
4403
  edit: (patch) => {
4086
4404
  if (this.saving) return;
4087
- if (patch.enabled !== void 0 || patch.controlScroll !== void 0 || patch.motionPreference !== void 0 || patch.thinkAutoExpand !== void 0) this.stagedBase = {
4405
+ if (patch.enabled !== void 0 || patch.controlScroll !== void 0 || patch.motionPreference !== void 0 || patch.thinkAutoExpand !== void 0 || patch.logarithmicFade !== void 0) this.stagedBase = {
4088
4406
  ...this.baseValues(),
4089
4407
  ...patch.enabled === void 0 ? {} : { enabled: patch.enabled },
4090
4408
  ...patch.controlScroll === void 0 ? {} : { controlScroll: patch.controlScroll },
4091
4409
  ...patch.motionPreference === void 0 ? {} : { motionPreference: patch.motionPreference },
4092
- ...patch.thinkAutoExpand === void 0 ? {} : { thinkAutoExpand: patch.thinkAutoExpand }
4410
+ ...patch.thinkAutoExpand === void 0 ? {} : { thinkAutoExpand: patch.thinkAutoExpand },
4411
+ ...patch.logarithmicFade === void 0 ? {} : { logarithmicFade: patch.logarithmicFade }
4093
4412
  };
4094
4413
  if (this.loadedDebug !== void 0 && (patch.debugEnabled !== void 0 || patch.debugTuning !== void 0)) this.stagedDebug = {
4095
4414
  ...this.debugValues(),
@@ -4143,7 +4462,8 @@ window.__ModuleLoader__.load({
4143
4462
  enabled: this.loaded?.enabled ?? DEFAULT_STREAM_SETTINGS.enabled,
4144
4463
  controlScroll: this.loaded?.controlScroll ?? DEFAULT_STREAM_SETTINGS.controlScroll,
4145
4464
  motionPreference: this.loaded?.motionPreference ?? DEFAULT_STREAM_SETTINGS.motionPreference,
4146
- thinkAutoExpand: this.loaded?.thinkAutoExpand ?? DEFAULT_STREAM_SETTINGS.thinkAutoExpand
4465
+ thinkAutoExpand: this.loaded?.thinkAutoExpand ?? DEFAULT_STREAM_SETTINGS.thinkAutoExpand,
4466
+ logarithmicFade: this.loaded?.logarithmicFade ?? DEFAULT_STREAM_SETTINGS.logarithmicFade
4147
4467
  };
4148
4468
  }
4149
4469
  debugValues() {
@@ -4267,8 +4587,11 @@ window.__ModuleLoader__.load({
4267
4587
  "auto",
4268
4588
  "force-smooth",
4269
4589
  "force-reduced"
4270
- ].includes(data.motionPreference) || typeof data.thinkAutoExpand !== "boolean" || typeof data.canUpgrade !== "boolean") throw new Error("dsh-smooth-stream: malformed settings response");
4271
- return data;
4590
+ ].includes(data.motionPreference) || typeof data.thinkAutoExpand !== "boolean" || data.logarithmicFade !== void 0 && typeof data.logarithmicFade !== "boolean" || typeof data.canUpgrade !== "boolean") throw new Error("dsh-smooth-stream: malformed settings response");
4591
+ return {
4592
+ ...data,
4593
+ logarithmicFade: data.logarithmicFade ?? true
4594
+ };
4272
4595
  }
4273
4596
  function upgradeView(value) {
4274
4597
  if (record(value)?.restartRequired !== true) throw new Error("dsh-smooth-stream: malformed update response");
@@ -4299,6 +4622,7 @@ window.__ModuleLoader__.load({
4299
4622
  controlScroll: settings.controlScroll,
4300
4623
  motionPreference: settings.motionPreference,
4301
4624
  thinkAutoExpand: settings.thinkAutoExpand,
4625
+ logarithmicFade: settings.logarithmicFade,
4302
4626
  ...settings.debugEnabled === void 0 || settings.debugTuning === void 0 ? {} : {
4303
4627
  debugEnabled: settings.debugEnabled,
4304
4628
  debugTuning: settings.debugTuning
@@ -4334,34 +4658,34 @@ window.__ModuleLoader__.load({
4334
4658
  tag.textContent = css;
4335
4659
  }
4336
4660
  var DebugPanel_module_css_default = {
4337
- "iconButton": "m4_tdG_iconButton",
4338
- "triggerActive": "m4_tdG_triggerActive",
4339
- "controlHead": "m4_tdG_controlHead",
4340
- "number": "m4_tdG_number",
4341
- "range": "m4_tdG_range",
4661
+ "section": "m4_tdG_section",
4662
+ "guide": "m4_tdG_guide",
4663
+ "metrics": "m4_tdG_metrics",
4664
+ "numberWrap": "m4_tdG_numberWrap",
4342
4665
  "statusLive": "m4_tdG_statusLive",
4343
- "title": "m4_tdG_title",
4666
+ "visuallyHidden": "m4_tdG_visuallyHidden",
4667
+ "statusDot": "m4_tdG_statusDot",
4668
+ "secondaryButton": "m4_tdG_secondaryButton",
4344
4669
  "controlLabel": "m4_tdG_controlLabel",
4345
- "guide": "m4_tdG_guide",
4670
+ "title": "m4_tdG_title",
4671
+ "control": "m4_tdG_control",
4672
+ "trigger": "m4_tdG_trigger",
4673
+ "triggerActive": "m4_tdG_triggerActive",
4346
4674
  "infoButton": "m4_tdG_infoButton",
4347
- "numberWrap": "m4_tdG_numberWrap",
4675
+ "footerSpacer": "m4_tdG_footerSpacer",
4676
+ "primaryButton": "m4_tdG_primaryButton",
4348
4677
  "footer": "m4_tdG_footer",
4349
- "control": "m4_tdG_control",
4350
- "secondaryButton": "m4_tdG_secondaryButton",
4351
- "unsaved": "m4_tdG_unsaved",
4352
- "metrics": "m4_tdG_metrics",
4353
- "scrollArea": "m4_tdG_scrollArea",
4354
4678
  "state": "m4_tdG_state",
4355
- "metric": "m4_tdG_metric",
4679
+ "range": "m4_tdG_range",
4680
+ "number": "m4_tdG_number",
4356
4681
  "panel": "m4_tdG_panel",
4357
- "trigger": "m4_tdG_trigger",
4358
- "statusDot": "m4_tdG_statusDot",
4359
- "section": "m4_tdG_section",
4682
+ "scrollArea": "m4_tdG_scrollArea",
4683
+ "metric": "m4_tdG_metric",
4684
+ "panelHeader": "m4_tdG_panelHeader",
4360
4685
  "unit": "m4_tdG_unit",
4361
- "footerSpacer": "m4_tdG_footerSpacer",
4362
- "visuallyHidden": "m4_tdG_visuallyHidden",
4363
- "primaryButton": "m4_tdG_primaryButton",
4364
- "panelHeader": "m4_tdG_panelHeader"
4686
+ "controlHead": "m4_tdG_controlHead",
4687
+ "iconButton": "m4_tdG_iconButton",
4688
+ "unsaved": "m4_tdG_unsaved"
4365
4689
  };
4366
4690
  //#endregion
4367
4691
  //#region src/client/DebugPanel.tsx
@@ -4768,6 +5092,8 @@ window.__ModuleLoader__.load({
4768
5092
  motionForceReduced: "Always raw",
4769
5093
  motionForceReducedHint: "Render raw text even when the system allows motion.",
4770
5094
  thinkAutoExpand: "Auto-expand thinking",
5095
+ logarithmicFade: "Logarithmic fade",
5096
+ logarithmicFadeHint: "Fade new answer and expanded thinking text into view. Follows the motion preference.",
4771
5097
  thinkAutoExpandHint: "Open the thinking block while it streams. Turn off to keep it collapsed.",
4772
5098
  debugEnabled: "Show render diagnostics",
4773
5099
  debugEnabledHint: "Show live streaming and scroll metrics on the right side of the chat. Tune values there, then save them here.",
@@ -4855,6 +5181,8 @@ window.__ModuleLoader__.load({
4855
5181
  motionForceReduced: "始终原始",
4856
5182
  motionForceReducedHint: "即使系统允许动效,也直接呈现原始文本。",
4857
5183
  thinkAutoExpand: "自动展开思考",
5184
+ logarithmicFade: "对数淡入",
5185
+ logarithmicFadeHint: "让回答正文和展开的思考文字由淡变实,遵循动效偏好。",
4858
5186
  thinkAutoExpandHint: "思考块在流式时自动展开;关闭后保持折叠,可手动展开。",
4859
5187
  debugEnabled: "显示渲染调试面板",
4860
5188
  debugEnabledHint: "在聊天右侧显示流式渲染和滚动的实时参数,可在面板中调节并在这里保存。",
@@ -5048,7 +5376,7 @@ window.__ModuleLoader__.load({
5048
5376
  refresh() {
5049
5377
  const next = this.read();
5050
5378
  const pending = this.card?.getSnapshot().status === "loading";
5051
- if (pending === this.pending && next.enabled === this.value.enabled && next.controlScroll === this.value.controlScroll && next.motionPreference === this.value.motionPreference && next.thinkAutoExpand === this.value.thinkAutoExpand && next.debugEnabled === this.value.debugEnabled && next.debugTuning === this.value.debugTuning) return;
5379
+ if (pending === this.pending && next.enabled === this.value.enabled && next.controlScroll === this.value.controlScroll && next.motionPreference === this.value.motionPreference && next.thinkAutoExpand === this.value.thinkAutoExpand && next.logarithmicFade === this.value.logarithmicFade && next.debugEnabled === this.value.debugEnabled && next.debugTuning === this.value.debugTuning) return;
5052
5380
  this.pending = pending;
5053
5381
  this.value = next;
5054
5382
  for (const listener of this.listeners) listener();
@@ -5148,6 +5476,7 @@ window.__ModuleLoader__.load({
5148
5476
  scrollSpeedPxPerSec: config.scrollSpeedPxPerSec,
5149
5477
  maxScrollSpeedPxPerSec: config.maxScrollSpeedPxPerSec,
5150
5478
  thinkAutoExpand: preferences.thinkAutoExpand,
5479
+ logarithmicFade: preferences.logarithmicFade,
5151
5480
  controlScroll: preferences.controlScroll,
5152
5481
  motionPreference: preferences.motionPreference
5153
5482
  });