pilotswarm 0.5.75 → 0.5.77
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/package.json +2 -2
- package/ui/core/src/controller.js +4 -1
- package/ui/core/src/history.js +26 -10
- package/ui/react/src/web-app.js +103 -39
- package/web/dist/assets/{abnfDiagram-VRR7QNED-CRN_CPXb.js → abnfDiagram-VRR7QNED-CKO_DwJV.js} +1 -1
- package/web/dist/assets/{arc-CXqBVBpG.js → arc-DNYWrpvl.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-DOA41VEX.js → architectureDiagram-ZJ3FMSHR-BuYVWnLH.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-BCa9kQVE.js → blockDiagram-677ZJIJ3-Cl_IMZqi.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-CccO5uAf.js → c4Diagram-LMCZKHZV-Dp8EWK6S.js} +1 -1
- package/web/dist/assets/channel-DTKy7mHi.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-BOzOMW0c.js → chunk-2Q5K7J3B-Dja0nryh.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-DyeNS6EA.js → chunk-32BRIVSS-BfmHxlTO.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-Cl2puolj.js → chunk-5VM5RSS4-DJ3zmwrq.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-CU792nsG.js → chunk-EX3LRPZG-B6SN8xEo.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-DI-c4Jvn.js → chunk-JWPE2WC7-Dlgqhr3G.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-CVuPn9RU.js → chunk-MOJQB5TN-Dn-J2ayj.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-CD34aFNh.js → chunk-RYQCIY6F-Af9a3V0M.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-BwQU46DX.js → chunk-V7JOEXUC-M3md4NxL.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-CL1JK1sJ.js → chunk-VR4S4FIN-ee4UcZX-.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-UOxFbxIp.js → chunk-XXDRQBXY-C1o9OH3_.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-MfqAYpCn.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-MfqAYpCn.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-CfQP19CB.js → cose-bilkent-JH36ORCC-CRxjVQDN.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-C9ifcKtK.js → cynefin-VYW2F7L2-MSAXYGkZ.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-IwcrpJT3.js → cynefinDiagram-TSTJHNR4-BPutBNN1.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-BzTGLYBP.js → dagre-VKFMJZFB-_W1WeW3E.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-D9X1NgQz.js → diagram-FQU43EPY-DT_0zQl9.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-BkdiUvXU.js → diagram-G47NLZAW-HBy_Ck1W.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-nCeiDJLN.js → diagram-NH7WQ7WH-DyQQlTUp.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-CXdSE6QP.js → diagram-OA4YK3LP-LJ7WYOVk.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-BNDoTBRl.js → diagram-WEI45ONY-B83fa0oq.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-BSsQ9Do8.js → ebnfDiagram-CCIWWBDH-ZbAvBv6c.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-BTkFSkJi.js → erDiagram-Q63AITRT-BNe1kdom.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-BGEZ9wur.js → flowDiagram-23GEKE2U-DDlbRR4H.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-WUAUhEpP.js → ganttDiagram-NO4QXBWP-DRvGvhmv.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-BQZQl2ZR.js → gitGraphDiagram-IHSO6WYX-Bj5CkOw6.js} +1 -1
- package/web/dist/assets/index-CVQyeZNA.js +24 -0
- package/web/dist/assets/index-mtWlthKI.css +1 -0
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-BP9xJx0Z.js → infoDiagram-FWYZ7A6U-BB-pO5BG.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-Kz3l0pEF.js → ishikawaDiagram-FXEZZL3T-fplKz6J9.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-KA8zfX2j.js → journeyDiagram-5HDEW3XC-CZXJ9si6.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-Cvy5U2tj.js → kanban-definition-HUTT4EX6-CL9u5Pmv.js} +1 -1
- package/web/dist/assets/{linear-DQ0Ynwre.js → linear-WwQWwN2U.js} +1 -1
- package/web/dist/assets/{mermaid.core-C_2W6ze2.js → mermaid.core-1gBc6FeB.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-CPkdv3pS.js → mindmap-definition-LN4V7U3C-CtKgb3BP.js} +1 -1
- package/web/dist/assets/{papaparse.min-gRC4B4xh.js → papaparse.min-Dk5F4KnO.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-BEmzoVBF.js → pegDiagram-2B236MQR-rkKhqRQO.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-Cs-r2GVr.js → pieDiagram-ENE6RG2P-VfaXje3o.js} +1 -1
- package/web/dist/assets/pilotswarm-BvFGjArK.js +109 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-D1SNNoOk.js → quadrantDiagram-ABIIQ3AL-Cw6aMTCy.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-BH9sxNL4.js → railroadDiagram-RFXS5EU6-Dju0kwmP.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-ucbqSBch.js → requirementDiagram-TGXJPOKE-BbyvxgRb.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-9LzvC1Q9.js → sankeyDiagram-HTMAVEWB-Do_VdVhS.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-yVbJ1mbs.js → sequenceDiagram-DBY2YBRQ-CKqDjXwf.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-aH-owuq8.js → sizeCapture-X5ZJPWSS-sVG1J5D7.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-eNxPWwbu.js → stateDiagram-2N3HPSRC-CfjQilyb.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CYw2jLW6.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-CUOaCY_Z.js → swimlanes-5IMT3BWC-Csum4YeF.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-CbG-9P20.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-CP6SzyRW.js → timeline-definition-FHXFAJF6-Cw6UCQjz.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-ByPylANx.js → vennDiagram-L72KCM5P-b_571af9.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-QfPO6uUo.js → wardleyDiagram-EHGQE667-DL_0-lVh.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-CNvueYN7.js → xychartDiagram-FW5EYKEG-BqKYzu8y.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/dist/assets/channel-Df1De1np.js +0 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-ee52oYsq.js +0 -1
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-ee52oYsq.js +0 -1
- package/web/dist/assets/index-CSMHeAhZ.css +0 -1
- package/web/dist/assets/index-DQFBdVYX.js +0 -24
- package/web/dist/assets/pilotswarm-qQVUkWws.js +0 -109
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-B5tcxao1.js +0 -1
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-Dz8gcrTg.js +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pilotswarm",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.77",
|
|
4
4
|
"description": "PilotSwarm application package: terminal UI, browser portal + Web API server, and MCP server — one install, three bins.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"ink": "^6.8.0",
|
|
82
82
|
"jose": "^6.2.2",
|
|
83
83
|
"mermaid": "^11.16.0",
|
|
84
|
-
"pilotswarm-sdk": "0.5.
|
|
84
|
+
"pilotswarm-sdk": "0.5.77",
|
|
85
85
|
"react": "^19.2.4",
|
|
86
86
|
"react-dom": "^19.2.4",
|
|
87
87
|
"ws": "^8.18.2"
|
|
@@ -9698,6 +9698,7 @@ export class PilotSwarmUiController {
|
|
|
9698
9698
|
await this.maybeAutoExpandActiveHistory(requestedScrollOffset, {
|
|
9699
9699
|
pages: AUTO_HISTORY_SCROLL_PAGE_COUNT,
|
|
9700
9700
|
preserveDomAnchor: options.preserveDomAnchor === true,
|
|
9701
|
+
onLoadStarted: options.onLoadStarted,
|
|
9701
9702
|
// Always bypass the offset gate. Every caller of this method fires
|
|
9702
9703
|
// only when the DOM scroller is already AT the top — a direct
|
|
9703
9704
|
// measurement. The gate is a second, weaker guess that compares a
|
|
@@ -10035,7 +10036,7 @@ export class PilotSwarmUiController {
|
|
|
10035
10036
|
if (targetOffset < maxOffset) return;
|
|
10036
10037
|
}
|
|
10037
10038
|
|
|
10038
|
-
|
|
10039
|
+
const load = this.expandSessionHistory(sessionId, {
|
|
10039
10040
|
requestedScrollOffset: targetOffset,
|
|
10040
10041
|
autoTriggered: true,
|
|
10041
10042
|
pages: options.pages,
|
|
@@ -10044,6 +10045,8 @@ export class PilotSwarmUiController {
|
|
|
10044
10045
|
// only, so each page is transcript instead of raw event noise.
|
|
10045
10046
|
eventTypes: CHAT_HISTORY_EVENT_TYPES,
|
|
10046
10047
|
});
|
|
10048
|
+
options.onLoadStarted?.();
|
|
10049
|
+
await load;
|
|
10047
10050
|
}
|
|
10048
10051
|
|
|
10049
10052
|
async expandSessionHistory(sessionId, options = {}) {
|
package/ui/core/src/history.js
CHANGED
|
@@ -630,6 +630,16 @@ function buildChatMessage(event, role) {
|
|
|
630
630
|
? event.data.messageId
|
|
631
631
|
: null;
|
|
632
632
|
const chatRole = deriveChatRole(event, role, text);
|
|
633
|
+
// Model commentary is a durable user-facing progress update. Once it has
|
|
634
|
+
// been recorded as assistant.message it belongs in the transcript like
|
|
635
|
+
// any other agent message; only transient live-turn output and an
|
|
636
|
+
// unclassified/final response use the preview shell. Treating commentary
|
|
637
|
+
// as a preview hid milestone updates behind a collapsed "Agent update"
|
|
638
|
+
// disclosure even though the model had explicitly sent them to the user.
|
|
639
|
+
const assistantPhase = chatRole === "assistant"
|
|
640
|
+
? String(event?.data?.phase || "").trim().toLowerCase()
|
|
641
|
+
: "";
|
|
642
|
+
const isAssistantCommentary = assistantPhase === "commentary";
|
|
633
643
|
return {
|
|
634
644
|
id: `${event.sessionId}:${event.seq}`,
|
|
635
645
|
role: chatRole,
|
|
@@ -640,14 +650,16 @@ function buildChatMessage(event, role) {
|
|
|
640
650
|
...(sender ? { sender } : {}),
|
|
641
651
|
...(attachments.length > 0 ? { attachments } : {}),
|
|
642
652
|
...(messageId ? { messageId } : {}),
|
|
643
|
-
...(chatRole === "assistant" ? {
|
|
653
|
+
...(chatRole === "assistant" ? (isAssistantCommentary ? {
|
|
654
|
+
assistantCommentary: true,
|
|
655
|
+
} : {
|
|
644
656
|
assistantPreview: true,
|
|
645
657
|
responsePending: true,
|
|
646
658
|
responseFinal: false,
|
|
647
659
|
responseCanFinalize: !event?.data?.parentToolCallId && !event?.data?.toolRequests?.length,
|
|
648
660
|
...(typeof event?.data?.reasoningText === "string" && event.data.reasoningText
|
|
649
661
|
? { liveReasoningText: event.data.reasoningText } : {}),
|
|
650
|
-
} : {}),
|
|
662
|
+
}) : {}),
|
|
651
663
|
};
|
|
652
664
|
}
|
|
653
665
|
|
|
@@ -1487,14 +1499,18 @@ export function appendEventToHistory(history, event) {
|
|
|
1487
1499
|
if (liveIndex >= 0) {
|
|
1488
1500
|
const settledAt = Date.now();
|
|
1489
1501
|
const liveStartedAt = Number(liveItem?.liveStartedAt || liveItem?.createdAt) || settledAt;
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1502
|
+
if (!message.assistantCommentary) {
|
|
1503
|
+
// Keep the disclosure identity even for short streams.
|
|
1504
|
+
// Committing an answer must not reset expansion or its scroll
|
|
1505
|
+
// box. Durable commentary deliberately leaves this shell and
|
|
1506
|
+
// becomes an ordinary visible transcript message.
|
|
1507
|
+
Object.assign(message, {
|
|
1508
|
+
streamSettling: true,
|
|
1509
|
+
liveKey: liveItem?.liveKey || message.messageId,
|
|
1510
|
+
liveStartedAt,
|
|
1511
|
+
liveReasoningText: message.liveReasoningText || liveItem?.reasoningText || "",
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1498
1514
|
next.chat.splice(Math.min(liveIndex, next.chat.length), 0, message);
|
|
1499
1515
|
}
|
|
1500
1516
|
else next.chat.push(message);
|
package/ui/react/src/web-app.js
CHANGED
|
@@ -94,7 +94,8 @@ const SCROLL_BOTTOM_EPSILON_PX = 0.5;
|
|
|
94
94
|
const PROGRAMMATIC_SCROLL_TOLERANCE_PX = SCROLL_BOTTOM_EPSILON_PX;
|
|
95
95
|
// Minimum downward finger travel (px) while at the top of the chat pane before
|
|
96
96
|
// a touch pull counts as a load-older-history request.
|
|
97
|
-
const TOUCH_TOP_PULL_THRESHOLD_PX =
|
|
97
|
+
const TOUCH_TOP_PULL_THRESHOLD_PX = 56;
|
|
98
|
+
const TOUCH_TOP_PULL_MAX_PX = 84;
|
|
98
99
|
// How long after the last user-driven scroll event the pane still counts as
|
|
99
100
|
// momentum-scrolling (native flick glide), during which programmatic scrollTop
|
|
100
101
|
// restores are suppressed so they don't kill the glide.
|
|
@@ -1107,7 +1108,11 @@ function scrollBoundaryIdentity(lines, fromEnd = false) {
|
|
|
1107
1108
|
return boundary.map(scrollLineIdentity).join("\u241e");
|
|
1108
1109
|
}
|
|
1109
1110
|
|
|
1110
|
-
function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller, {
|
|
1111
|
+
function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller, {
|
|
1112
|
+
stickyBottom = false,
|
|
1113
|
+
historyPullEnabled = false,
|
|
1114
|
+
historySessionId = null,
|
|
1115
|
+
} = {}) {
|
|
1111
1116
|
const normalizedLines = React.useMemo(() => normalizeLines(lines), [lines]);
|
|
1112
1117
|
// Programmatic scrollTop assignments fire a 'scroll' event that would
|
|
1113
1118
|
// otherwise call onScroll → dispatch ui/scroll → clobber the user's
|
|
@@ -1122,6 +1127,9 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1122
1127
|
const previousContentRef = React.useRef(null);
|
|
1123
1128
|
const historyScrollRef = React.useRef(null);
|
|
1124
1129
|
React.useEffect(() => () => { historyScrollRef.current = null; }, []);
|
|
1130
|
+
const [topPullDistance, setTopPullDistance] = React.useState(0);
|
|
1131
|
+
const [loadingHistorySessionId, setLoadingHistorySessionId] = React.useState(null);
|
|
1132
|
+
React.useEffect(() => { setTopPullDistance(0); }, [historySessionId]);
|
|
1125
1133
|
// Touch scrolling relies on native momentum for speed: a hard flick keeps
|
|
1126
1134
|
// scrolling long after the finger lifts. Re-asserting scrollTop from state
|
|
1127
1135
|
// on every render (live events, status updates) kills that momentum at the
|
|
@@ -1309,7 +1317,7 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1309
1317
|
const node = ref.current;
|
|
1310
1318
|
const state = controller.getState();
|
|
1311
1319
|
const sessionId = state.sessions.activeSessionId;
|
|
1312
|
-
if (!node || !sessionId || historyScrollRef.current) return;
|
|
1320
|
+
if (!node || !sessionId || !historyPullEnabled || historyScrollRef.current) return;
|
|
1313
1321
|
const top = node.getBoundingClientRect().top;
|
|
1314
1322
|
const element = [...node.children].find(child => child.textContent?.trim() && child.getBoundingClientRect().bottom > top + 6);
|
|
1315
1323
|
const pending = {
|
|
@@ -1320,15 +1328,17 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1320
1328
|
historyScrollRef.current = pending;
|
|
1321
1329
|
const load = controller.handleChatTopHistoryScrollIntent?.(
|
|
1322
1330
|
(node.scrollHeight - node.clientHeight) / SCROLL_ROW_HEIGHT,
|
|
1323
|
-
{ force: true, preserveDomAnchor: true
|
|
1331
|
+
{ force: true, preserveDomAnchor: true,
|
|
1332
|
+
onLoadStarted: () => setLoadingHistorySessionId(sessionId) },
|
|
1324
1333
|
);
|
|
1325
1334
|
Promise.resolve(load).catch(() => {}).finally(() => {
|
|
1335
|
+
setLoadingHistorySessionId(current => current === sessionId ? null : current);
|
|
1326
1336
|
if (historyScrollRef.current !== pending) return;
|
|
1327
1337
|
const oldest = controller.getState().history.bySessionId.get(sessionId)?.events?.[0]?.seq;
|
|
1328
1338
|
if (!(oldest < pending.oldestSeq)) historyScrollRef.current = null;
|
|
1329
1339
|
else setViewportRevision(revision => revision + 1);
|
|
1330
1340
|
});
|
|
1331
|
-
}, [controller, ref]);
|
|
1341
|
+
}, [controller, historyPullEnabled, ref]);
|
|
1332
1342
|
|
|
1333
1343
|
const onWheel = React.useCallback((event) => {
|
|
1334
1344
|
const node = ref.current;
|
|
@@ -1354,13 +1364,18 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1354
1364
|
// scroll events either — so mobile had no way to request older history.
|
|
1355
1365
|
// A downward pull that starts while the pane is at (or near) the top fires
|
|
1356
1366
|
// the same top-history intent, once per gesture.
|
|
1357
|
-
const touchPullRef = React.useRef({ startY: null,
|
|
1367
|
+
const touchPullRef = React.useRef({ startY: null, distance: 0 });
|
|
1358
1368
|
const onTouchStart = React.useCallback((event) => {
|
|
1359
1369
|
userScrollRef.current.touching = true;
|
|
1360
1370
|
if (historyScrollRef.current?.applied) historyScrollRef.current = null;
|
|
1361
|
-
|
|
1362
|
-
touchPullRef.current = {
|
|
1363
|
-
|
|
1371
|
+
const node = ref.current;
|
|
1372
|
+
touchPullRef.current = {
|
|
1373
|
+
startY: historyPullEnabled && loadingHistorySessionId !== historySessionId
|
|
1374
|
+
&& paneKey === "chat" && node?.scrollTop <= PROGRAMMATIC_SCROLL_TOLERANCE_PX
|
|
1375
|
+
? event.touches?.[0]?.clientY ?? null : null,
|
|
1376
|
+
distance: 0,
|
|
1377
|
+
};
|
|
1378
|
+
}, [historyPullEnabled, historySessionId, loadingHistorySessionId, paneKey, ref]);
|
|
1364
1379
|
const onTouchEnd = React.useCallback(() => {
|
|
1365
1380
|
userScrollRef.current.touching = false;
|
|
1366
1381
|
// Momentum continues past the finger lift; onScroll keeps refreshing
|
|
@@ -1369,6 +1384,16 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1369
1384
|
if (historyScrollRef.current?.applied) {
|
|
1370
1385
|
historyScrollRef.current.releaseAt = performance.now() + HISTORY_SCROLL_GESTURE_GAP_MS;
|
|
1371
1386
|
}
|
|
1387
|
+
const distance = touchPullRef.current.distance;
|
|
1388
|
+
touchPullRef.current = { startY: null, distance: 0 };
|
|
1389
|
+
setTopPullDistance(0);
|
|
1390
|
+
if (distance >= TOUCH_TOP_PULL_THRESHOLD_PX
|
|
1391
|
+
&& ref.current?.scrollTop <= PROGRAMMATIC_SCROLL_TOLERANCE_PX) requestHistoryPage();
|
|
1392
|
+
}, [ref, requestHistoryPage]);
|
|
1393
|
+
const onTouchCancel = React.useCallback(() => {
|
|
1394
|
+
userScrollRef.current.touching = false;
|
|
1395
|
+
touchPullRef.current = { startY: null, distance: 0 };
|
|
1396
|
+
setTopPullDistance(0);
|
|
1372
1397
|
}, []);
|
|
1373
1398
|
const onTouchMove = React.useCallback((event) => {
|
|
1374
1399
|
const node = ref.current;
|
|
@@ -1379,17 +1404,14 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1379
1404
|
event.preventDefault();
|
|
1380
1405
|
return;
|
|
1381
1406
|
}
|
|
1382
|
-
if (pull.
|
|
1407
|
+
if (pull.startY == null) return;
|
|
1383
1408
|
if (node.scrollTop > PROGRAMMATIC_SCROLL_TOLERANCE_PX) return;
|
|
1384
1409
|
const y = event.touches?.[0]?.clientY;
|
|
1385
|
-
if (y == null
|
|
1386
|
-
pull.
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
event.preventDefault();
|
|
1391
|
-
requestHistoryPage();
|
|
1392
|
-
}, [paneKey, ref, requestHistoryPage]);
|
|
1410
|
+
if (y == null) return;
|
|
1411
|
+
pull.distance = Math.min(TOUCH_TOP_PULL_MAX_PX, Math.max(0, y - pull.startY));
|
|
1412
|
+
setTopPullDistance(pull.distance);
|
|
1413
|
+
if (pull.distance > 0) event.preventDefault();
|
|
1414
|
+
}, [paneKey, ref]);
|
|
1393
1415
|
|
|
1394
1416
|
React.useEffect(() => {
|
|
1395
1417
|
const node = ref.current;
|
|
@@ -1404,7 +1426,8 @@ function useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller
|
|
|
1404
1426
|
};
|
|
1405
1427
|
}, [ref, onWheel, onTouchMove]);
|
|
1406
1428
|
|
|
1407
|
-
return { normalizedLines, onScroll, onTouchStart, onTouchEnd
|
|
1429
|
+
return { normalizedLines, onScroll, onTouchStart, onTouchEnd, onTouchCancel,
|
|
1430
|
+
topPullDistance, loadingOlderHistory: loadingHistorySessionId === historySessionId };
|
|
1408
1431
|
}
|
|
1409
1432
|
|
|
1410
1433
|
function Runs({ runs, theme }) {
|
|
@@ -3785,7 +3808,9 @@ const PreviewMessageContent = React.memo(function PreviewMessageContent({ conten
|
|
|
3785
3808
|
});
|
|
3786
3809
|
|
|
3787
3810
|
const AssistantPreviewCard = React.memo(function AssistantPreviewCard({ line, theme, controller }) {
|
|
3788
|
-
|
|
3811
|
+
// Saved updates should be readable immediately. The viewport below keeps
|
|
3812
|
+
// long updates scrollable without taking over the whole chat pane.
|
|
3813
|
+
const [open, setOpen] = React.useState(line.text === "Agent update");
|
|
3789
3814
|
const [revealed, setRevealed] = React.useState(
|
|
3790
3815
|
!line.liveStartedAt || Date.now() - line.liveStartedAt >= 200,
|
|
3791
3816
|
);
|
|
@@ -3794,6 +3819,10 @@ const AssistantPreviewCard = React.memo(function AssistantPreviewCard({ line, th
|
|
|
3794
3819
|
const followRef = React.useRef(true);
|
|
3795
3820
|
const snapshotRef = React.useRef(null);
|
|
3796
3821
|
const expanded = open || line.final;
|
|
3822
|
+
React.useLayoutEffect(() => {
|
|
3823
|
+
// A live preview can become a saved update in the same card.
|
|
3824
|
+
if (line.text === "Agent update") setOpen(true);
|
|
3825
|
+
}, [line.text]);
|
|
3797
3826
|
// Keep already-mounted markdown/disclosures when closed, but don't parse
|
|
3798
3827
|
// new hidden deltas. Reopening catches up in a single render.
|
|
3799
3828
|
if (expanded) snapshotRef.current = line;
|
|
@@ -4224,7 +4253,7 @@ function focusRegionForPaneKey(paneKey, override = null) {
|
|
|
4224
4253
|
return PANE_KEY_FOCUS_REGIONS[String(paneKey || "")] || null;
|
|
4225
4254
|
}
|
|
4226
4255
|
|
|
4227
|
-
function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, lines, stickyLines = [], bottomStickyLines = [], reserveBottomSticky = false, scrollOffset = 0, scrollMode = "top", paneKey, controller, className = "", panelClassName = "", topContent = null, bottomContent = null, structuredBlocks = false, stickyBottom = false, renderBody = null, focusRegion = null, panelRef = null, ariaLive = null }) {
|
|
4256
|
+
function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, lines, stickyLines = [], bottomStickyLines = [], reserveBottomSticky = false, scrollOffset = 0, scrollMode = "top", paneKey, controller, className = "", panelClassName = "", topContent = null, bottomContent = null, structuredBlocks = false, stickyBottom = false, historyPullEnabled = false, historySessionId = null, renderBody = null, focusRegion = null, panelRef = null, ariaLive = null }) {
|
|
4228
4257
|
const themeId = useControllerSelector(controller, (state) => state.ui.themeId);
|
|
4229
4258
|
const theme = getTheme(themeId);
|
|
4230
4259
|
const ref = React.useRef(null);
|
|
@@ -4237,7 +4266,7 @@ function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, l
|
|
|
4237
4266
|
}, [panelRef]);
|
|
4238
4267
|
const stickyRef = React.useRef(null);
|
|
4239
4268
|
const syncingHorizontalRef = React.useRef(false);
|
|
4240
|
-
const { normalizedLines, onScroll, onTouchStart, onTouchEnd } = useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller, { stickyBottom });
|
|
4269
|
+
const { normalizedLines, onScroll, onTouchStart, onTouchEnd, onTouchCancel, topPullDistance, loadingOlderHistory } = useScrollSync(ref, lines, scrollOffset, scrollMode, paneKey, controller, { stickyBottom, historyPullEnabled, historySessionId });
|
|
4241
4270
|
const normalizedSticky = React.useMemo(() => normalizeLines(stickyLines), [stickyLines]);
|
|
4242
4271
|
const normalizedBottomSticky = React.useMemo(() => normalizeLines(bottomStickyLines), [bottomStickyLines]);
|
|
4243
4272
|
const preserveHorizontalScroll = className.includes("is-preserve") && panelClassName.includes("has-preserved-sticky");
|
|
@@ -4326,7 +4355,7 @@ function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, l
|
|
|
4326
4355
|
}, [preserveHorizontalScroll, syncScrollLeft]);
|
|
4327
4356
|
|
|
4328
4357
|
return React.createElement(Panel, { title, titleRight, color, focused, actions, theme, className: panelClassName },
|
|
4329
|
-
topContent,
|
|
4358
|
+
typeof topContent === "function" ? topContent({ topPullDistance, loadingOlderHistory }) : topContent,
|
|
4330
4359
|
normalizedSticky.length > 0
|
|
4331
4360
|
? React.createElement("div", {
|
|
4332
4361
|
ref: stickyRef,
|
|
@@ -4336,7 +4365,7 @@ function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, l
|
|
|
4336
4365
|
normalizedSticky.map((line, index) => React.createElement(Line, { key: `sticky:${index}`, line, theme })),
|
|
4337
4366
|
)
|
|
4338
4367
|
: null,
|
|
4339
|
-
React.createElement("div", { ref: setPanelNode, className: `ps-scroll-panel ${className}${scrollShadow.down ? " is-scrolled-down" : ""}${scrollShadow.up ? " is-scrolled-up" : ""}`.trim(), "data-session-scroll": focusRegion === "sessions" ? "1" : undefined, "aria-live": ariaLive || undefined, "aria-atomic": ariaLive ? "false" : undefined, onScroll: handleBodyScroll, onMouseDown: claimFocus, onTouchStart, onTouchEnd, onTouchCancel
|
|
4368
|
+
React.createElement("div", { ref: setPanelNode, className: `ps-scroll-panel ${className}${scrollShadow.down ? " is-scrolled-down" : ""}${scrollShadow.up ? " is-scrolled-up" : ""}`.trim(), "data-session-scroll": focusRegion === "sessions" ? "1" : undefined, "aria-live": ariaLive || undefined, "aria-atomic": ariaLive ? "false" : undefined, onScroll: handleBodyScroll, onMouseDown: claimFocus, onTouchStart, onTouchEnd, onTouchCancel },
|
|
4340
4369
|
typeof renderBody === "function"
|
|
4341
4370
|
? renderBody(normalizedLines, theme)
|
|
4342
4371
|
: structuredBlocks
|
|
@@ -6898,6 +6927,39 @@ function SessionHeaderStatus({ controller }) {
|
|
|
6898
6927
|
queue ? React.createElement("span", { className: "ps-mobile-queue", title: queue }, queue) : null);
|
|
6899
6928
|
}
|
|
6900
6929
|
|
|
6930
|
+
function HistoryUpGlyph() {
|
|
6931
|
+
return React.createElement(Glyph, null,
|
|
6932
|
+
React.createElement("path", { d: "M12 19V5m-5 5 5-5 5 5" }));
|
|
6933
|
+
}
|
|
6934
|
+
|
|
6935
|
+
function HistorySpinnerGlyph() {
|
|
6936
|
+
return React.createElement(Glyph, null,
|
|
6937
|
+
React.createElement("path", { d: "M20.5 12a8.5 8.5 0 1 1-8.5-8.5" }));
|
|
6938
|
+
}
|
|
6939
|
+
|
|
6940
|
+
function HistoryLoadIndicator({ loading, manual, pullDistance, onManualLoad }) {
|
|
6941
|
+
const ready = pullDistance >= TOUCH_TOP_PULL_THRESHOLD_PX;
|
|
6942
|
+
const label = loading ? "Loading earlier messages…"
|
|
6943
|
+
: manual ? "Load older messages"
|
|
6944
|
+
: ready ? "Release to load earlier messages"
|
|
6945
|
+
: "Pull for earlier messages";
|
|
6946
|
+
return React.createElement("div", {
|
|
6947
|
+
className: `ps-history-load${loading ? " is-loading" : ""}${manual ? " is-manual" : ""}${ready ? " is-ready" : ""}`,
|
|
6948
|
+
style: pullDistance > 0 ? { "--ps-history-pull": `${Math.min(pullDistance, TOUCH_TOP_PULL_MAX_PX)}px` } : undefined,
|
|
6949
|
+
role: "status", "aria-live": "polite",
|
|
6950
|
+
},
|
|
6951
|
+
React.createElement("span", { className: "ps-history-track", "aria-hidden": "true" },
|
|
6952
|
+
React.createElement("span", { className: "ps-history-tick is-first" }),
|
|
6953
|
+
React.createElement("span", { className: "ps-history-tick is-second" }),
|
|
6954
|
+
React.createElement("span", { className: "ps-history-marker" },
|
|
6955
|
+
loading ? React.createElement(HistorySpinnerGlyph) : React.createElement(HistoryUpGlyph),
|
|
6956
|
+
loading ? React.createElement("span", { className: "ps-history-text-spinner" },
|
|
6957
|
+
["|", "/", "—", "\\"].map((frame, index) => React.createElement("span", { key: index }, frame))) : null)),
|
|
6958
|
+
manual && !loading
|
|
6959
|
+
? React.createElement("button", { type: "button", className: "ps-mini-button ps-load-older-button", onClick: onManualLoad }, label)
|
|
6960
|
+
: React.createElement("span", { className: "ps-history-label" }, label));
|
|
6961
|
+
}
|
|
6962
|
+
|
|
6901
6963
|
function ChatPane({ controller, mobile = false, fullWidth = false, showComposer = true, onEnterZen = null, activityInHeader = false }) {
|
|
6902
6964
|
const themeId = useControllerSelector(controller, (state) => state.ui.themeId);
|
|
6903
6965
|
const theme = getTheme(themeId);
|
|
@@ -6980,7 +7042,7 @@ function ChatPane({ controller, mobile = false, fullWidth = false, showComposer
|
|
|
6980
7042
|
() => appendAnimatedDotsToRuns(chrome.titleRight, chrome.animateTitleRight ? animatedDots : ""),
|
|
6981
7043
|
[animatedDots, chrome.animateTitleRight, chrome.titleRight],
|
|
6982
7044
|
);
|
|
6983
|
-
const [
|
|
7045
|
+
const [manualLoadingSessionId, setManualLoadingSessionId] = React.useState(null);
|
|
6984
7046
|
// Scroll-up expands the transcript automatically until the soft cap, then
|
|
6985
7047
|
// refuses — and the portal had no control to ask for more, so a busy
|
|
6986
7048
|
// session's history became unreachable from the browser. Surface the
|
|
@@ -7079,25 +7141,27 @@ function ChatPane({ controller, mobile = false, fullWidth = false, showComposer
|
|
|
7079
7141
|
scrollMode: viewState.followBottom ? "bottom" : "top",
|
|
7080
7142
|
stickyBottom: true,
|
|
7081
7143
|
paneKey: "chat",
|
|
7144
|
+
historySessionId: viewState.activeSessionId,
|
|
7145
|
+
historyPullEnabled: Boolean(viewState.activeHistory?.hasOlderEvents && !showLoadOlder),
|
|
7082
7146
|
ariaLive: "polite",
|
|
7083
7147
|
className: "is-wrapped",
|
|
7084
7148
|
panelClassName: "ps-chat-panel",
|
|
7085
7149
|
panelRef,
|
|
7086
7150
|
bottomContent: composer,
|
|
7087
|
-
topContent:
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7151
|
+
topContent: ({ topPullDistance, loadingOlderHistory }) => {
|
|
7152
|
+
const loading = loadingOlderHistory || manualLoadingSessionId === viewState.activeSessionId;
|
|
7153
|
+
if (!showLoadOlder && topPullDistance <= 0 && !loading) return null;
|
|
7154
|
+
return React.createElement(HistoryLoadIndicator, {
|
|
7155
|
+
loading, manual: showLoadOlder, pullDistance: loading ? 0 : topPullDistance,
|
|
7156
|
+
onManualLoad: () => {
|
|
7157
|
+
const sessionId = viewState.activeSessionId;
|
|
7158
|
+
setManualLoadingSessionId(sessionId);
|
|
7159
|
+
controller.handleCommand(UI_COMMANDS.EXPAND_HISTORY)
|
|
7160
|
+
.catch(() => {})
|
|
7161
|
+
.finally(() => setManualLoadingSessionId(current => current === sessionId ? null : current));
|
|
7162
|
+
},
|
|
7163
|
+
});
|
|
7164
|
+
},
|
|
7101
7165
|
structuredBlocks: true,
|
|
7102
7166
|
renderBody: null,
|
|
7103
7167
|
});
|
package/web/dist/assets/{abnfDiagram-VRR7QNED-CRN_CPXb.js → abnfDiagram-VRR7QNED-CKO_DwJV.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-Dn-J2ayj.js";import{p as f}from"./chunk-JWPE2WC7-Dlgqhr3G.js";import{_ as n,l as o}from"./mermaid.core-1gBc6FeB.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-MSAXYGkZ.js";import"./pilotswarm-BvFGjArK.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-1gBc6FeB.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|